-
Notifications
You must be signed in to change notification settings - Fork 4
/
law2json.ls
104 lines (88 loc) · 3.6 KB
/
law2json.ls
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
require! {optimist, fs, mkdirp, path}
require! './lib/parse'
fixup = -> it.replace / /g, ' '
fixBr = -> it - /\s*<br>\s*/ig - /\s+$/
zhnumber = <[○ 一 二 三 四 五 六 七 八 九 十]>
zhmap = {[c, i] for c, i in zhnumber}
parseZHNumber = ->
it .= replace /零/g, '○'
it .= replace /百$/g, '○○'
it .= replace /百/, ''
if it.0 is \十
l = it.length
return 10 if l is 1
return 10 + parseZHNumber it.slice 1
if it[*-1] is \十
return 10 * parseZHNumber it.slice 0, it.length-1
res = 0
for c in it when c isnt \十
res *= 10
res += zhmap[c]
res
parseDate = ->
m = it.match /(.*)年(.*)月(.*)日/
return [parseZHNumber(m.1) + 1911, parseZHNumber(m.2), parseZHNumber(m.3)] * \.
lawStatus = (dir) ->
for basename in <[ 廢止 停止適用 ]>
if fs.existsSync "#dir/#basename.html"
return basename
return if fs.existsSync "#dir/全文.html" then \實施 else \未知
objToSortedArray = (obj) ->
keys = for key, _ of obj
key
keys.sort (a, b) -> a - b
x = for key in keys
obj[key]
return x
parseHTML = (lawdir, changes_by_date) ->
law_history = {status: lawStatus lawdir}
html = fixup fs.readFileSync "#lawdir/修正沿革.html", \utf8
for line in html / '\n'
match line
| /<TR><TD COLSPAN=5><FONT COLOR=teal SIZE=4><b>(.*)<\/b>/ =>
law_history.name = that.1
| /<TR><TD COLSPAN=5><B>(.*)<\/B>/ =>
law_history.revision ||= []
date = parseDate(that.1)
law_history.revision.push {date: date, content: {}, reference: changes_by_date[date]}
| /<FONT COLOR=8000FF SIZE=4>([^<]*)/ =>
zh = that.1 - /\s/g;
if zh == ''
zh = \前言
last = 0
else
m = zh.match /第(.*)條(?:之(.*))?/
last = if m.2 then "#{parseZHNumber m.1}.#{parseZHNumber m.2}"
else parseZHNumber m.1
# Store in Object for data integrity. It will be reformed by objToSortedArray.
law_history.revision[*-1].content[last] ||= {}
law_history.revision[*-1].content[last]
..num = last
..zh = zh
| /<FONT COLOR=C000FF><\/FONT><TD>前言:\s*(.*)/ =>
law_history.revision[*-1].content[last].article = fixBr that.1
| /<FONT COLOR=C000FF>條文<\/FONT><TD>\s*(.*)/ =>
law_history.revision[*-1].content[last].article = fixBr that.1
| /<FONT COLOR=C000FF>理由<\/FONT><TD>\s*(.*)/ =>
law_history.revision[*-1].content[last].reason = fixBr that.1
law_history.revision.sort (a, b) -> a.date.localeCompare b.date
law = name: law_history.name, status: law_history.status, content: {}
for rev, i in law_history.revision
for num, item of rev.content
law.content[num] = item
law.content = objToSortedArray law.content
return {law, law_history}
{outdir} = optimist.argv
for lawdir in optimist.argv._
try
m = lawdir.match /([^/]+\/[^/]+)\/?$/
dir = "#outdir/#{m.1}"
console.log "Generating #dir/{law,law_history}.json"
mkdirp.sync dir
changes_by_date = parse.parseChanges lawdir
{law, law_history} = parseHTML lawdir, changes_by_date
fs.writeFileSync "#dir/law_history.json", JSON.stringify law_history, '', 2
fs.writeFileSync "#dir/law.json", JSON.stringify law, '', 2
fs.writeFileSync "#dir/changes.json", JSON.stringify changes_by_date, '', 2
catch
console.error "ERROR: #lawdir (#e)"