-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshtml2html.civet
More file actions
134 lines (122 loc) · 4.16 KB
/
shtml2html.civet
File metadata and controls
134 lines (122 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env node
"civet coffeeNot"
fs from fs
path from path
strftime from strftime
url from url
class Convert
// Maintains state of converter, including configuration and variables.
// Make a new instance for each top-level file conversion
// (or use `convertFile`).
config: Record<string, string>
vars: Record<string, string | (() => string)>
rootFilename: string
@(@rootFilename: string, outFilename: string)
@config =
echomsg: '(none)'
errormsg: '[an error occurred while processing this directive]'
sizefmt: 'bytes'
timefmt: "%A, %d-%b-%Y %H:%M:%S %Z"
@vars =
DOCUMENT_NAME: outFilename
LAST_MODIFIED: => @flastmod @rootFilename
flastmod(filename: string): string
try
strftime @config.timefmt, fs.statSync(filename).mtime
catch error
console.log `!! flastmod error: ${error}`
@config.errormsg
fsize(filename: string): string
try
size := fs.statSync(filename).size
switch @config.sizefmt
when 'bytes'
`${size}`
when 'abbrev'
if size < 973
`${size}`
else if size < 973 * 1024
`${(size / 1024).toFixed 1}K`
else
`${(size / (1024 * 1024)).toFixed 1}M`
else
console.log `!! Invalid sizefmt: ${@config.sizefmt}`
@config.errormsg
catch error
console.log `!! fsize error: ${error}`
@config.errormsg
convertToString(filename: string = @rootFilename): string
fs.readFileSync filename, encoding: 'utf8'
.replace ///
<!--\#(include|flastmod|fsize|config|echo)\b(.*?)-->
///g, (match: string, command: string, rest: string) =>
// #comment can have arbitrary content
return '' if command == 'comment'
// Parse arguments
args: [string, string][] := []
rest = rest.replace /\s*([\w\-]+)\s*=\s*"([^"]*)"\s*/g,
(match: string, key: string, value: string) =>
args.push [key, value]
''
if rest
console.log `!! Invalid #${command} directive: ${rest}`
return @config.errormsg
function getArg(desired: string): string | undefined
for [key, value] of args
return value if key == desired
undefined
fileCommand := (func: (filename: string) => string, multi?: boolean): string =>
done .= false
(for [key, value] of args
break if done and not multi
switch key
when 'file'
if value.includes('../') or path.isAbsolute value
console.log `!! Invalid file argument: ${value}`
@config.errormsg
else
done = true
func path.join path.dirname(filename), value
when 'virtual'
done = true
func path.join path.dirname(filename), value
else
continue
).join ''
switch command
when 'include'
fileCommand @@convertToString, true
when 'flastmod'
fileCommand @@flastmod
when 'fsize'
fileCommand @@fsize
when 'config'
for [key, value] of args
@config[key] = value
''
when 'echo'
varName := getArg 'var'
if varName?
val .= @vars[varName] ?? @config.echomsg
val = val() if val instanceof Function
val
else
console.log `!! #echo directive missing var: ${rest}`
@config.errormsg
else
@config.errormsg // should never happen; to satisfy TypeScript
function convertFile(filename: string, outFilename?: string)
// Top-level file conversion
outFilename ?= filename.replace(/\.shtml$/, '') + '.html'
console.log filename, '->', outFilename
convert := new Convert filename, outFilename
fs.writeFileSync outFilename, """
<!--This file is automatically generated by shtml2html. DO NOT EDIT.-->
#{convert.convertToString()}
""", encoding: 'utf8'
function main()
for arg of process.argv[2..]
convertFile arg
main() if import.meta.url.startsWith('file:') and
fs.realpathSync(process.argv[1]) ==
fs.realpathSync url.fileURLToPath import.meta.url