legal_markdown 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/legal_markdown.gemspec +1 -0
- data/lib/legal_markdown/legal_to_markdown/json_builder.rb +75 -0
- data/lib/legal_markdown/legal_to_markdown/leaders.rb +186 -84
- data/lib/legal_markdown/legal_to_markdown/load_source.rb +2 -2
- data/lib/legal_markdown/legal_to_markdown/mixins.rb +1 -0
- data/lib/legal_markdown/legal_to_markdown/writer.rb +1 -1
- data/lib/legal_markdown/legal_to_markdown.rb +13 -1
- data/lib/legal_markdown/version.rb +1 -1
- data/lib/legal_markdown.rb +1 -1
- data/test/test_legal_markdown_to_markdown.rb +13 -4
- data/test/tests/23.block_part_indents.lmd +33 -0
- data/test/tests/23.block_part_indents.md +40 -0
- data/test/tests/24.block_no_closing_ticks.lmd +32 -0
- data/test/tests/24.block_no_closing_ticks.md +39 -0
- metadata +15 -15
- data/test/tests/11.mixins_in_today_function.lmd +0 -4
- data/test/tests/11.mixins_in_today_function.md +0 -1
- data/test/tests/23.block_all_indents.md +0 -40
- data/test/tests/24.block_part_indents.lmd +0 -40
- data/test/tests/24.block_part_indents.md +0 -52
data/legal_markdown.gemspec
CHANGED
@@ -0,0 +1,75 @@
|
|
1
|
+
module LegalToMarkdown
|
2
|
+
extend self
|
3
|
+
|
4
|
+
module JasonBuilder
|
5
|
+
require 'securerandom'
|
6
|
+
# this method will build a hash which we will use to build the structured JSON.
|
7
|
+
# roughly the hash / json will break down like this ....
|
8
|
+
# "id"
|
9
|
+
# "nodes"
|
10
|
+
# "document"
|
11
|
+
# "title" => ""
|
12
|
+
# "abstract" => ""
|
13
|
+
# "views" => ["content"]
|
14
|
+
# "provision:SHA32"
|
15
|
+
# "id" => "provision:SHA32"
|
16
|
+
# "type" => "provision"
|
17
|
+
# "data"
|
18
|
+
# "level" => "level"
|
19
|
+
# "provision_reference" => "assembled leader"
|
20
|
+
# "provision_text" => "line - leader" #gaurd italics
|
21
|
+
# "citation" => "citation"
|
22
|
+
# "annotation:SHA32"
|
23
|
+
# "id" => "annotation:SHA32"
|
24
|
+
# "type" => "citation"
|
25
|
+
# "data"
|
26
|
+
# "pos" => [start_column, stop_column]
|
27
|
+
# "citation_type" => "internal" | "external"
|
28
|
+
# "cite_of" => #todo
|
29
|
+
# "content" => "nodes" => ["provision:SHA32", ...]
|
30
|
+
|
31
|
+
def build_jason
|
32
|
+
if @content.is_a?(Array)
|
33
|
+
@content[0] = build_header_and_text_hashs @content[0] unless @content[0].empty?
|
34
|
+
@content[2] = build_header_and_text_hashs @content[2] unless @content[2].empty?
|
35
|
+
@content = @content[0].merge(@content[1]).merge(@content[2])
|
36
|
+
else
|
37
|
+
@content = build_header_and_text_hashs @content
|
38
|
+
end
|
39
|
+
@content = {
|
40
|
+
"id" => sha,
|
41
|
+
"nodes" => build_front_portion.merge( @content ).merge( build_back_portion( @content ) )
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def build_front_portion
|
46
|
+
document_hash = { "document" => { "title" => "", "abstract" => "", "views" => ["content"] }}
|
47
|
+
end
|
48
|
+
|
49
|
+
def build_header_and_text_hashs( text_block )
|
50
|
+
text_hash = text_block.each_line.inject({}) do |hash, line|
|
51
|
+
h2 ={}
|
52
|
+
if line[/^\#+\s+/]
|
53
|
+
h2["id"]= "heading:" + sha
|
54
|
+
h2["type"]= "heading"
|
55
|
+
h2["data"]= { "content" => line.gsub($1, "") }
|
56
|
+
elsif line[/^\S/]
|
57
|
+
h2["id"]= "text:" + sha
|
58
|
+
h2["type"]= "text"
|
59
|
+
h2["data"]= { "content" => line }
|
60
|
+
end
|
61
|
+
hash.merge( { h2["id"] => h2 } )
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def build_back_portion( content_hash )
|
66
|
+
back_hash = content_hash.each_value.collect{|h| h["id"]}
|
67
|
+
back_hash = { "content" => "nodes" => back_hash }
|
68
|
+
back_hash
|
69
|
+
end
|
70
|
+
|
71
|
+
def sha
|
72
|
+
return SecureRandom.hex
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -6,8 +6,10 @@ module LegalToMarkdown
|
|
6
6
|
def run_leaders
|
7
7
|
get_the_substitutions
|
8
8
|
find_the_block
|
9
|
-
@block
|
10
|
-
|
9
|
+
if @block
|
10
|
+
chew_on_the_block
|
11
|
+
clean_up_leaders
|
12
|
+
end
|
11
13
|
end
|
12
14
|
|
13
15
|
def get_the_substitutions
|
@@ -23,20 +25,68 @@ module LegalToMarkdown
|
|
23
25
|
# {"ll." || "l2."=>[:type8, "Article ", "(", "1", ")", :no_reset || nil, " ", :preval || :pre || nil]}
|
24
26
|
|
25
27
|
@substitutions = {}
|
28
|
+
get_level_style
|
29
|
+
get_the_indents
|
30
|
+
get_the_levels
|
31
|
+
get_the_resets
|
32
|
+
end
|
33
|
+
|
34
|
+
def find_the_block
|
35
|
+
block_pattern = /(^```+\s*\n?)(.*?\n?)(^```+\s*\n?|\z)/m
|
36
|
+
parts = @content.partition( block_pattern )
|
37
|
+
if parts[1] != ""
|
38
|
+
@block = $2.chomp
|
39
|
+
@content = parts[0] + "{{block}}" + parts[2]
|
40
|
+
else
|
41
|
+
@block = nil
|
42
|
+
@content = @content
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def chew_on_the_block
|
47
|
+
# @substitutions hash example
|
48
|
+
# {"ll."OR "l2."=>[:type8, "Article ", "(", "1", ")", :no_reset || nil, :no_indent || nil, :preval || :pre || nil],}
|
49
|
+
@cross_references = {}
|
50
|
+
arrayed_block = []
|
51
|
+
@block.each_line do |line|
|
52
|
+
next if line[/^\s+$/]
|
53
|
+
line[/(^l+\.|^l\d\.)\s*(\|.*?\|)*\s*(.*)$/] ? arrayed_block << [$1, $3, $2] : arrayed_block.last[1] << ("\n" + line.rstrip)
|
54
|
+
end
|
55
|
+
@block = build_the_block_for_markdown arrayed_block if @writer == :markdown
|
56
|
+
@block = build_the_block_for_jason arrayed_block if @writer == :jason
|
57
|
+
end
|
58
|
+
|
59
|
+
def clean_up_leaders
|
60
|
+
@content.gsub!("{{block}}", @block ) if @writer == :markdown
|
61
|
+
if @writer == :jason
|
62
|
+
@content = @content.partition( /\{\{block\}\}/ )
|
63
|
+
@content[1] = @block
|
64
|
+
end
|
65
|
+
@block = ""
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
26
69
|
|
70
|
+
def get_level_style
|
27
71
|
if @headers.has_key?("level-style")
|
28
72
|
@headers["level-style"] =~ /l1/ ? @deep_leaders = true : @deep_leaders = false
|
73
|
+
@headers.delete("level-style")
|
29
74
|
else
|
30
75
|
@deep_leaders = false
|
31
76
|
end
|
77
|
+
end
|
32
78
|
|
79
|
+
def get_the_indents
|
33
80
|
if @headers.has_key?("no-indent") && @headers["no-indent"]
|
34
81
|
no_indent_array = @headers["no-indent"].split(", ")
|
35
82
|
no_indent_array.include?("l." || "l1.") ? @offset = no_indent_array.size : @offset = no_indent_array.size + 1
|
36
83
|
else
|
37
84
|
@offset = 1
|
38
85
|
end
|
86
|
+
@headers.delete("no-indent")
|
87
|
+
end
|
39
88
|
|
89
|
+
def get_the_levels
|
40
90
|
@headers.each do | header, value |
|
41
91
|
if @deep_leaders
|
42
92
|
search = "l" + header[-1] + "." if header =~ /level-\d/
|
@@ -56,108 +106,40 @@ module LegalToMarkdown
|
|
56
106
|
@substitutions[search][1].gsub!(/pre\s*/, "")
|
57
107
|
@substitutions[search][7] = :pre
|
58
108
|
end
|
109
|
+
@headers.delete(header)
|
59
110
|
end
|
60
111
|
end
|
112
|
+
end
|
61
113
|
|
114
|
+
def get_the_resets
|
62
115
|
if @headers["no-reset"]
|
63
116
|
no_subs_array = @headers["no-reset"].split(", ")
|
64
117
|
no_subs_array.each{ |e| @substitutions[e][5] = :no_reset unless e == "l." || e == "l1."}
|
65
118
|
end
|
66
|
-
|
67
|
-
|
68
|
-
def find_the_block
|
69
|
-
block_pattern = /(^```+\s*\n?)(.*?\n?)(^```+\s*\n?)/m
|
70
|
-
parts = @content.partition( block_pattern )
|
71
|
-
if parts[1] != ""
|
72
|
-
@block = $2.chomp
|
73
|
-
@content = parts[0] + "{{block}}" + parts[2]
|
74
|
-
else
|
75
|
-
@block = nil
|
76
|
-
@content = @content
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def chew_on_the_block
|
81
|
-
# takes a hash of substitutions to make from the #get_the_substitutions method
|
82
|
-
# and a block of text returned from the #find_the_block method
|
83
|
-
# iterates over the block to make the appropriate substitutions
|
84
|
-
# returns a block of text
|
85
|
-
|
86
|
-
# method will take the old_block and iterate through the lines.
|
87
|
-
# First it will find the leading indicator. Then it will
|
88
|
-
# find the appropriate substitution from the @substitutions
|
89
|
-
# hash. After that it will rebuild the leading matter from the
|
90
|
-
# sub hash. It will drop markers if it is going down the tree.
|
91
|
-
# It will reset the branches if it is going up the tree.
|
92
|
-
# sub_it is an array w/ type[0] & lead_string[1] & id's[2..4]
|
93
|
-
|
94
|
-
# @substitutions hash example
|
95
|
-
# {"ll."OR "l2."=>[:type8, "Article ", "(", "1", ")", :no_reset || nil, :no_indent || nil, :preval || :pre || nil],}
|
96
|
-
|
97
|
-
cross_references = {}
|
98
|
-
arrayed_block = []
|
99
|
-
@block.each_line do |line|
|
100
|
-
next if line[/^\s*\n/]
|
101
|
-
line[/(^l+\.|^l\d\.)\s*(\|.*?\|)*\s*(.*)$/] ? arrayed_block << [$1, $3, $2] : arrayed_block.last[1] << ("\n" + line.rstrip)
|
102
|
-
end
|
103
|
-
|
104
|
-
new_block = arrayed_block.inject("") do |block, arrayed_line|
|
105
|
-
|
106
|
-
selector = arrayed_line[0]
|
107
|
-
next_selector = ( arrayed_block[arrayed_block.index(arrayed_line)+1] || arrayed_block.last ).first
|
108
|
-
sub_it = @substitutions[selector]
|
109
|
-
|
110
|
-
if arrayed_line[1] =~ /\n/
|
111
|
-
arrayed_line[1].gsub!("\n", "\n\n" + sub_it[6])
|
112
|
-
end
|
113
|
-
|
114
|
-
if sub_it[7] == :preval
|
115
|
-
sub_it = preval_substitution(sub_it, selector)
|
116
|
-
reference = sub_it.last
|
117
|
-
elsif sub_it[7] == :pre
|
118
|
-
sub_it = pre_substitution(sub_it, selector)
|
119
|
-
reference = sub_it.last
|
120
|
-
else
|
121
|
-
reference = sub_it[2..4].join
|
122
|
-
end
|
123
|
-
|
124
|
-
block << sub_it[6] + sub_it[1] + reference + " " + arrayed_line[1] + "\n\n"
|
125
|
-
if arrayed_line[2]
|
126
|
-
cross_references[arrayed_line[2]]= sub_it[1] + reference
|
127
|
-
cross_references[arrayed_line[2]].gsub!(/\A\*|\#+ |\.\z/, "") #guard against formatting of headers into txt
|
128
|
-
end
|
129
|
-
@substitutions[selector]= increment_the_branch(sub_it, selector, next_selector)
|
130
|
-
block
|
131
|
-
end
|
132
|
-
|
133
|
-
cross_references.each_key{|k| new_block.gsub!(k, cross_references[k]) }
|
134
|
-
return new_block
|
135
|
-
end
|
136
|
-
|
137
|
-
def clean_up_leaders
|
138
|
-
@content.gsub!("{{block}}", @block )
|
119
|
+
@headers.delete("no-reset")
|
139
120
|
end
|
140
121
|
|
141
122
|
def set_the_subs_arrays( value )
|
142
123
|
# takes a core value from the hash pulled from the yaml
|
143
124
|
# returns an array with a type symbol and a precursor string
|
144
|
-
|
125
|
+
case
|
126
|
+
when value =~ /([IVXLCDM]+)\.\z/ # type1 : {{ I. }}
|
145
127
|
return[:type1, value.delete($1 + "."), "", $1, "."]
|
146
|
-
|
128
|
+
when value =~ /\(([IVXLCDM]+)\)\z/ # type2 : {{ (I) }}
|
147
129
|
return[:type2, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
148
|
-
|
130
|
+
when value =~ /([ivxlcdm]+)\.\z/ # type3 : {{ i. }}
|
149
131
|
return[:type3, value.delete($1 + "."), "", $1, "."]
|
150
|
-
|
132
|
+
when value =~ /\(([ivxlcdm]+)\)\z/ # type4 : {{ (i) }}
|
151
133
|
return[:type4, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
152
|
-
|
134
|
+
when value =~ /([A-Z]+)\.\z/ # type5 : {{ A. }}
|
153
135
|
return[:type5, value.delete($1 + "."), "", $1, "."]
|
154
|
-
|
136
|
+
when value =~ /\(([A-Z]+)\)\z/ # type6 : {{ (A) }}
|
155
137
|
return[:type6, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
156
|
-
|
138
|
+
when value =~ /([a-z]+)\.\z/ # type7 : {{ a. }}
|
157
139
|
return[:type7, value.delete($1 + "."), "", $1, "."]
|
158
|
-
|
140
|
+
when value =~ /\(([a-z]+)\)\z/ # type8 : {{ (a) }}
|
159
141
|
return[:type8, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
160
|
-
|
142
|
+
when value =~ /\((\d+)\)\z/ # type9 : {{ (1) }}
|
161
143
|
return[:type9, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
162
144
|
else value =~ /(\d+)\.\z/ # type0 : {{ 1. }} ... also default
|
163
145
|
return[:type0, value.delete($1 + "."), "", $1, "."]
|
@@ -255,5 +237,125 @@ module LegalToMarkdown
|
|
255
237
|
array_to_sub.last.gsub!($1, "(") if array_to_sub.last[/(\.\()/]
|
256
238
|
return array_to_sub
|
257
239
|
end
|
240
|
+
|
241
|
+
def log_the_line( block, sub_it, reference, arrayed_line )
|
242
|
+
arrayed_line[1].gsub!("\n", "\n\n" + sub_it[6]) if arrayed_line[1] =~ /\n/
|
243
|
+
block << sub_it[6] + sub_it[1] + reference + " " + arrayed_line[1] + "\n\n"
|
244
|
+
end
|
245
|
+
|
246
|
+
def log_the_key( block, sub_it, reference, selector, arrayed_line, arrayed_block )
|
247
|
+
# this method will build a hash which we will use to build the structured JSON.
|
248
|
+
# roughly the hash / json will break down like this ....
|
249
|
+
# "id"
|
250
|
+
# "nodes"
|
251
|
+
# "document"
|
252
|
+
# "title" => ""
|
253
|
+
# "abstract" => ""
|
254
|
+
# "views" => ["content"]
|
255
|
+
# "provision:SHA32"
|
256
|
+
# "id" => "provision:SHA32"
|
257
|
+
# "type" => "provision"
|
258
|
+
# "data"
|
259
|
+
# "level" => "level"
|
260
|
+
# "provision_reference" => "assembled leader"
|
261
|
+
# "provision_text" => "text" #gaurd italics
|
262
|
+
# "citation" => "citation" #todo
|
263
|
+
# "substitution" => sub_it array #for json=>lmd reversion
|
264
|
+
# "annotation:SHA32"
|
265
|
+
# "id" => "annotation:SHA32"
|
266
|
+
# "type" => "citation"
|
267
|
+
# "data"
|
268
|
+
# "pos" => [start_column, stop_column]
|
269
|
+
# "citation_type" => "internal" | "external"
|
270
|
+
# "cite_of" => #todo
|
271
|
+
# "node" => "id" ... if internal
|
272
|
+
# "substitution" => for json=>reversion
|
273
|
+
# "content" => "nodes" => ["provision:SHA32", ...]
|
274
|
+
# but this method is only chewing on the middle bits where it says provision || annotation.
|
275
|
+
# the json_builder module will handle the rest.
|
276
|
+
provision = { "id" => "provision:" + SecureRandom.hex, "type" => "provision" }
|
277
|
+
provision["data"]= {
|
278
|
+
"level" => @deep_leaders ? selector[-1] : (selector.length - 1).to_s,
|
279
|
+
"provision_reference" => sub_it[1] + reference,
|
280
|
+
"provision_text" => arrayed_line[1].count("*") % 2 != 0 ? arrayed_line[1].sub("*", "") : arrayed_line[1],
|
281
|
+
"citation" => "",
|
282
|
+
"substitution" => sub_it
|
283
|
+
}
|
284
|
+
return provision
|
285
|
+
end
|
286
|
+
|
287
|
+
def build_an_annotation( start, stop, cite, parent, substitution )
|
288
|
+
annotation = { "id" => "annotation:" + SecureRandom.hex, "type" => "citation"}
|
289
|
+
annotation["data"]= {
|
290
|
+
"pos" => [start, stop],
|
291
|
+
"citation_type" => "internal",
|
292
|
+
"cite_of" => cite,
|
293
|
+
"node" => parent,
|
294
|
+
"substitution" => substitution
|
295
|
+
}
|
296
|
+
return annotation
|
297
|
+
end
|
298
|
+
|
299
|
+
def block_builder( arrayed_line )
|
300
|
+
selector = arrayed_line.first
|
301
|
+
sub_it = @substitutions[selector]
|
302
|
+
if sub_it[7] == :preval
|
303
|
+
sub_it = preval_substitution( sub_it, selector )
|
304
|
+
reference = sub_it.last
|
305
|
+
elsif sub_it[7] == :pre
|
306
|
+
sub_it = pre_substitution( sub_it, selector )
|
307
|
+
reference = sub_it.last
|
308
|
+
else
|
309
|
+
reference = sub_it[2..4].join
|
310
|
+
end
|
311
|
+
@cross_references[arrayed_line[2]]= sub_it[1].gsub(/\A\* *|\#+ */, "") + reference.chomp(".") if arrayed_line[2]
|
312
|
+
return [sub_it, reference, selector, arrayed_line]
|
313
|
+
end
|
314
|
+
|
315
|
+
def block_incrementer( arrayed_line, arrayed_block, selector, sub_it )
|
316
|
+
unless arrayed_line == arrayed_block.last
|
317
|
+
next_selector = arrayed_block[arrayed_block.index(arrayed_line)+1].first
|
318
|
+
@substitutions[selector]= increment_the_branch(sub_it, selector, next_selector)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
def build_the_block_for_markdown( arrayed_block )
|
323
|
+
new_block = arrayed_block.inject("") do |block, arrayed_line|
|
324
|
+
(sub_it, reference, selector, arrayed_line) = block_builder arrayed_line
|
325
|
+
log_the_line block, sub_it, reference, arrayed_line
|
326
|
+
block_incrementer arrayed_line, arrayed_block, selector, sub_it
|
327
|
+
block
|
328
|
+
end
|
329
|
+
@cross_references.each_key{|k| new_block.gsub!(k, @cross_references[k]) }
|
330
|
+
new_block
|
331
|
+
end
|
332
|
+
|
333
|
+
def build_the_block_for_jason( arrayed_block )
|
334
|
+
require 'securerandom'
|
335
|
+
annotations_hash = {}
|
336
|
+
provisions_hash = arrayed_block.inject({}) do |block, arrayed_line|
|
337
|
+
(sub_it, reference, selector, arrayed_line) = block_builder arrayed_line
|
338
|
+
provision = log_the_key block, sub_it, reference, selector, arrayed_line, arrayed_block
|
339
|
+
block_incrementer arrayed_line, arrayed_block, selector, sub_it
|
340
|
+
block[provision["id"]]= provision
|
341
|
+
block
|
342
|
+
end
|
343
|
+
provisions_hash.each_value do |h|
|
344
|
+
if h["data"]["provision_text"][/(\|.*?\|)/]
|
345
|
+
ref = @cross_references[$1]
|
346
|
+
h["data"]["provision_text"].gsub!($1, ref)
|
347
|
+
start = h["data"]["provision_text"].index(ref) + 1
|
348
|
+
stop = start + ref.length
|
349
|
+
cite = provisions_hash.each_value{|h| return h["id"] if h["data"]["provision_reference"] == ref}
|
350
|
+
parent = h["id"]
|
351
|
+
substitution = $1
|
352
|
+
annotation = build_an_annotation start, stop, cite, parent, substitution
|
353
|
+
annotations_hash[annotation["id"]]= annotation
|
354
|
+
else
|
355
|
+
next
|
356
|
+
end
|
357
|
+
end
|
358
|
+
provisions_hash.merge(annotations_hash)
|
359
|
+
end
|
258
360
|
end
|
259
361
|
end
|
@@ -3,10 +3,10 @@ module LegalToMarkdown
|
|
3
3
|
|
4
4
|
class FileToParse
|
5
5
|
|
6
|
-
attr_accessor :headers, :content, :mixins, :leaders
|
6
|
+
attr_accessor :headers, :content, :mixins, :leaders, :writer
|
7
7
|
|
8
8
|
def initialize(file)
|
9
|
-
@input_file = file; @headers = nil; @content = ""
|
9
|
+
@input_file = file; @headers = nil; @content = ""; @writer = :markdown
|
10
10
|
load; get_the_partials; parse; set_the_parsers
|
11
11
|
end
|
12
12
|
|
@@ -4,7 +4,7 @@ module LegalToMarkdown
|
|
4
4
|
def write_it( final_content )
|
5
5
|
final_content = final_content.gsub(/ +\n/, "\n")
|
6
6
|
if @output_file && @output_file != "-"
|
7
|
-
File.open(@output_file, "w") {|f| f.write( final_content ) }
|
7
|
+
File.open(@output_file, "w") {|f| f.write( final_content ); f.close }
|
8
8
|
else
|
9
9
|
STDOUT.write final_content
|
10
10
|
end
|
@@ -6,12 +6,24 @@ require File.dirname(__FILE__) + '/roman_numerals'
|
|
6
6
|
|
7
7
|
module LegalToMarkdown
|
8
8
|
|
9
|
-
def
|
9
|
+
def parse_markdown(args)
|
10
|
+
@input_file = args[-2] ? args[-2] : args[-1]
|
10
11
|
@output_file = args[-1]
|
12
|
+
source = FileToParse.new(@input_file)
|
13
|
+
source.run_mixins if source.mixins
|
14
|
+
source.run_leaders if source.leaders
|
15
|
+
write_it(source.content)
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse_jason(arg)
|
11
19
|
@input_file = args[-2] ? args[-2] : args[-1]
|
20
|
+
@output_file = args[-1]
|
12
21
|
source = FileToParse.new(@input_file)
|
22
|
+
source.writer = :jason
|
13
23
|
source.run_mixins if source.mixins
|
14
24
|
source.run_leaders if source.leaders
|
25
|
+
source.extend LegalToMarkdown::JasonBuilder
|
26
|
+
source.build_jason
|
15
27
|
write_it(source.content)
|
16
28
|
end
|
17
29
|
end
|
data/lib/legal_markdown.rb
CHANGED
@@ -17,8 +17,17 @@ class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def get_file ( filename )
|
20
|
-
|
21
|
-
|
20
|
+
begin
|
21
|
+
contents = File::read( filename ) if File::exists?(filename) && File::readable?(filename)
|
22
|
+
rescue => e
|
23
|
+
raise "Could not find file #{filename}: #{e.message}."
|
24
|
+
contents = ""
|
25
|
+
end
|
26
|
+
if contents && contents != ""
|
27
|
+
return contents.rstrip
|
28
|
+
else
|
29
|
+
return ""
|
30
|
+
end
|
22
31
|
end
|
23
32
|
|
24
33
|
def create_temp
|
@@ -35,8 +44,8 @@ class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
|
|
35
44
|
puts "Testing => #{lmd_file}"
|
36
45
|
temp_file = create_temp
|
37
46
|
benchmark_file = File.basename(lmd_file, ".lmd") + ".md"
|
38
|
-
LegalToMarkdown.
|
39
|
-
assert_equal(get_file(benchmark_file)
|
47
|
+
LegalToMarkdown.parse_markdown( [ lmd_file, temp_file ] )
|
48
|
+
assert_equal(get_file(benchmark_file), get_file(temp_file), "This file threw an exception => #{benchmark_file}")
|
40
49
|
destroy_temp temp_file
|
41
50
|
end
|
42
51
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
---
|
2
|
+
|
3
|
+
# Structured Headers
|
4
|
+
level-1: "Article 1."
|
5
|
+
level-2: "Section 1."
|
6
|
+
level-3: "1."
|
7
|
+
no-indent: l., ll.
|
8
|
+
|
9
|
+
---
|
10
|
+
|
11
|
+
# TEST 4
|
12
|
+
|
13
|
+
```
|
14
|
+
l. Provision for Article 1.
|
15
|
+
ll. Provision for Section 1.1.
|
16
|
+
ll. Provision for 1.1.1.
|
17
|
+
lll. Provision for 1.1.2.
|
18
|
+
lll. Provision for Section 1.2.
|
19
|
+
lll. Provision for 1.2.1.
|
20
|
+
l. Provision for 1.2.2.
|
21
|
+
ll. Profivis asl;jksfd;lg; lkshflksjdh
|
22
|
+
ll. asd;flkajsdf;lkj
|
23
|
+
lll. ;alsdkfjasd;flkajsd
|
24
|
+
ll. as;dlfkjasd;flakjsdll.
|
25
|
+
lll. a;lsdfkjasd;lfkj
|
26
|
+
lll. a;sdlfkajsd;flk
|
27
|
+
l. as;dlfkajsd;flkj
|
28
|
+
ll. a;sldfkajsd;
|
29
|
+
lll. a;sldfkjasd;flkajs
|
30
|
+
lll. a;lsdfkajsd;lfkj
|
31
|
+
lll. a;sdlfkajsd;flkajs
|
32
|
+
lll. as;dlfkjasd;lfkjs
|
33
|
+
```
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# TEST 4
|
2
|
+
|
3
|
+
Article 1. Provision for Article 1.
|
4
|
+
|
5
|
+
Section 1. Provision for Section 1.1.
|
6
|
+
|
7
|
+
Section 2. Provision for 1.1.1.
|
8
|
+
|
9
|
+
1. Provision for 1.1.2.
|
10
|
+
|
11
|
+
2. Provision for Section 1.2.
|
12
|
+
|
13
|
+
3. Provision for 1.2.1.
|
14
|
+
|
15
|
+
Article 2. Provision for 1.2.2.
|
16
|
+
|
17
|
+
Section 1. Profivis asl;jksfd;lg; lkshflksjdh
|
18
|
+
|
19
|
+
Section 2. asd;flkajsdf;lkj
|
20
|
+
|
21
|
+
1. ;alsdkfjasd;flkajsd
|
22
|
+
|
23
|
+
Section 3. as;dlfkjasd;flakjsdll.
|
24
|
+
|
25
|
+
1. a;lsdfkjasd;lfkj
|
26
|
+
|
27
|
+
2. a;sdlfkajsd;flk
|
28
|
+
|
29
|
+
Article 3. as;dlfkajsd;flkj
|
30
|
+
|
31
|
+
Section 1. a;sldfkajsd;
|
32
|
+
|
33
|
+
1. a;sldfkjasd;flkajs
|
34
|
+
|
35
|
+
2. a;lsdfkajsd;lfkj
|
36
|
+
|
37
|
+
3. a;sdlfkajsd;flkajs
|
38
|
+
|
39
|
+
4. as;dlfkjasd;lfkjs
|
40
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
---
|
2
|
+
|
3
|
+
# Structured Headers
|
4
|
+
level-1: "Article 1."
|
5
|
+
level-2: "Section 1."
|
6
|
+
level-3: "1."
|
7
|
+
no-indent: l., ll., lll.
|
8
|
+
|
9
|
+
---
|
10
|
+
|
11
|
+
# TEST 4
|
12
|
+
|
13
|
+
```
|
14
|
+
l. Provision for Article 1.
|
15
|
+
ll. Provision for Section 1.1.
|
16
|
+
ll. Provision for 1.1.1.
|
17
|
+
lll. Provision for 1.1.2.
|
18
|
+
lll. Provision for Section 1.2.
|
19
|
+
lll. Provision for 1.2.1.
|
20
|
+
l. Provision for 1.2.2.
|
21
|
+
ll. Profivis asl;jksfd;lg; lkshflksjdh
|
22
|
+
ll. asd;flkajsdf;lkj
|
23
|
+
lll. ;alsdkfjasd;flkajsd
|
24
|
+
ll. as;dlfkjasd;flakjsdll.
|
25
|
+
lll. a;lsdfkjasd;lfkj
|
26
|
+
lll. a;sdlfkajsd;flk
|
27
|
+
l. as;dlfkajsd;flkj
|
28
|
+
ll. a;sldfkajsd;
|
29
|
+
lll. a;sldfkjasd;flkajs
|
30
|
+
lll. a;lsdfkajsd;lfkj
|
31
|
+
lll. a;sdlfkajsd;flkajs
|
32
|
+
lll. as;dlfkjasd;lfkjs
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# TEST 4
|
2
|
+
|
3
|
+
Article 1. Provision for Article 1.
|
4
|
+
|
5
|
+
Section 1. Provision for Section 1.1.
|
6
|
+
|
7
|
+
Section 2. Provision for 1.1.1.
|
8
|
+
|
9
|
+
1. Provision for 1.1.2.
|
10
|
+
|
11
|
+
2. Provision for Section 1.2.
|
12
|
+
|
13
|
+
3. Provision for 1.2.1.
|
14
|
+
|
15
|
+
Article 2. Provision for 1.2.2.
|
16
|
+
|
17
|
+
Section 1. Profivis asl;jksfd;lg; lkshflksjdh
|
18
|
+
|
19
|
+
Section 2. asd;flkajsdf;lkj
|
20
|
+
|
21
|
+
1. ;alsdkfjasd;flkajsd
|
22
|
+
|
23
|
+
Section 3. as;dlfkjasd;flakjsdll.
|
24
|
+
|
25
|
+
1. a;lsdfkjasd;lfkj
|
26
|
+
|
27
|
+
2. a;sdlfkajsd;flk
|
28
|
+
|
29
|
+
Article 3. as;dlfkajsd;flkj
|
30
|
+
|
31
|
+
Section 1. a;sldfkajsd;
|
32
|
+
|
33
|
+
1. a;sldfkjasd;flkajs
|
34
|
+
|
35
|
+
2. a;lsdfkajsd;lfkj
|
36
|
+
|
37
|
+
3. a;sdlfkajsd;flkajs
|
38
|
+
|
39
|
+
4. as;dlfkjasd;lfkjs
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: legal_markdown
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-07-
|
12
|
+
date: 2013-07-13 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! ' This gem will parse YAML Front Matter of Markdown Documents. Typically,
|
15
15
|
this gem would be called with a md renderer, such as Pandoc, that would turn the
|
@@ -36,6 +36,7 @@ files:
|
|
36
36
|
- legal_markdown.gemspec
|
37
37
|
- lib/legal_markdown.rb
|
38
38
|
- lib/legal_markdown/legal_to_markdown.rb
|
39
|
+
- lib/legal_markdown/legal_to_markdown/json_builder.rb
|
39
40
|
- lib/legal_markdown/legal_to_markdown/leaders.rb
|
40
41
|
- lib/legal_markdown/legal_to_markdown/load_source.rb
|
41
42
|
- lib/legal_markdown/legal_to_markdown/mixins.rb
|
@@ -52,8 +53,6 @@ files:
|
|
52
53
|
- test/tests/02.load_partials_no_action.md
|
53
54
|
- test/tests/10.mixins_in_headers_and_text.lmd
|
54
55
|
- test/tests/10.mixins_in_headers_and_text.md
|
55
|
-
- test/tests/11.mixins_in_today_function.lmd
|
56
|
-
- test/tests/11.mixins_in_today_function.md
|
57
56
|
- test/tests/12.opt_clauses_no_subs.lmd
|
58
57
|
- test/tests/12.opt_clauses_no_subs.md
|
59
58
|
- test/tests/13.opt_clauses_subs.lmd
|
@@ -66,9 +65,10 @@ files:
|
|
66
65
|
- test/tests/21.block_no_indents.md
|
67
66
|
- test/tests/22.block_all_indents.lmd
|
68
67
|
- test/tests/22.block_all_indents.md
|
69
|
-
- test/tests/23.
|
70
|
-
- test/tests/
|
71
|
-
- test/tests/24.
|
68
|
+
- test/tests/23.block_part_indents.lmd
|
69
|
+
- test/tests/23.block_part_indents.md
|
70
|
+
- test/tests/24.block_no_closing_ticks.lmd
|
71
|
+
- test/tests/24.block_no_closing_ticks.md
|
72
72
|
- test/tests/25.block_no_resets.lmd
|
73
73
|
- test/tests/25.block_no_resets.md
|
74
74
|
- test/tests/26.block_all_resets.lmd
|
@@ -104,7 +104,8 @@ files:
|
|
104
104
|
- test/tests/partials/z.partial1
|
105
105
|
- test/tests/partials/z.partial2
|
106
106
|
homepage: http://github.com/compleatang/legal-markdown
|
107
|
-
licenses:
|
107
|
+
licenses:
|
108
|
+
- MIT
|
108
109
|
post_install_message:
|
109
110
|
rdoc_options: []
|
110
111
|
require_paths:
|
@@ -117,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
117
118
|
version: '0'
|
118
119
|
segments:
|
119
120
|
- 0
|
120
|
-
hash:
|
121
|
+
hash: -4168501592412035307
|
121
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
123
|
none: false
|
123
124
|
requirements:
|
@@ -126,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
127
|
version: '0'
|
127
128
|
segments:
|
128
129
|
- 0
|
129
|
-
hash:
|
130
|
+
hash: -4168501592412035307
|
130
131
|
requirements: []
|
131
132
|
rubyforge_project:
|
132
133
|
rubygems_version: 1.8.25
|
@@ -144,8 +145,6 @@ test_files:
|
|
144
145
|
- test/tests/02.load_partials_no_action.md
|
145
146
|
- test/tests/10.mixins_in_headers_and_text.lmd
|
146
147
|
- test/tests/10.mixins_in_headers_and_text.md
|
147
|
-
- test/tests/11.mixins_in_today_function.lmd
|
148
|
-
- test/tests/11.mixins_in_today_function.md
|
149
148
|
- test/tests/12.opt_clauses_no_subs.lmd
|
150
149
|
- test/tests/12.opt_clauses_no_subs.md
|
151
150
|
- test/tests/13.opt_clauses_subs.lmd
|
@@ -158,9 +157,10 @@ test_files:
|
|
158
157
|
- test/tests/21.block_no_indents.md
|
159
158
|
- test/tests/22.block_all_indents.lmd
|
160
159
|
- test/tests/22.block_all_indents.md
|
161
|
-
- test/tests/23.
|
162
|
-
- test/tests/
|
163
|
-
- test/tests/24.
|
160
|
+
- test/tests/23.block_part_indents.lmd
|
161
|
+
- test/tests/23.block_part_indents.md
|
162
|
+
- test/tests/24.block_no_closing_ticks.lmd
|
163
|
+
- test/tests/24.block_no_closing_ticks.md
|
164
164
|
- test/tests/25.block_no_resets.lmd
|
165
165
|
- test/tests/25.block_no_resets.md
|
166
166
|
- test/tests/26.block_all_resets.lmd
|
@@ -1 +0,0 @@
|
|
1
|
-
12 July, 2013
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# TEST 4
|
2
|
-
|
3
|
-
Article 1. Provision for Article 1.
|
4
|
-
|
5
|
-
Section 1. Provision for Section 1.1.
|
6
|
-
|
7
|
-
Section 2. Provision for 1.1.1.
|
8
|
-
|
9
|
-
1. Provision for 1.1.2.
|
10
|
-
|
11
|
-
2. Provision for Section 1.2.
|
12
|
-
|
13
|
-
3. Provision for 1.2.1.
|
14
|
-
|
15
|
-
Article 2. Provision for 1.2.2.
|
16
|
-
|
17
|
-
Section 1. Profivis asl;jksfd;lg; lkshflksjdh
|
18
|
-
|
19
|
-
Section 2. asd;flkajsdf;lkj
|
20
|
-
|
21
|
-
1. ;alsdkfjasd;flkajsd
|
22
|
-
|
23
|
-
Section 3. as;dlfkjasd;flakjsdll.
|
24
|
-
|
25
|
-
1. a;lsdfkjasd;lfkj
|
26
|
-
|
27
|
-
2. a;sdlfkajsd;flk
|
28
|
-
|
29
|
-
Article 3. as;dlfkajsd;flkj
|
30
|
-
|
31
|
-
Section 1. a;sldfkajsd;
|
32
|
-
|
33
|
-
1. a;sldfkjasd;flkajs
|
34
|
-
|
35
|
-
2. a;lsdfkajsd;lfkj
|
36
|
-
|
37
|
-
3. a;sdlfkajsd;flkajs
|
38
|
-
|
39
|
-
4. as;dlfkjasd;lfkjs
|
40
|
-
|
@@ -1,40 +0,0 @@
|
|
1
|
-
---
|
2
|
-
|
3
|
-
# Structured Headers
|
4
|
-
level-1: "Article 1."
|
5
|
-
level-2: "Section 1."
|
6
|
-
level-3: "1."
|
7
|
-
level-4: "a."
|
8
|
-
no-indent: ll., lll.
|
9
|
-
|
10
|
-
---
|
11
|
-
|
12
|
-
# TEST 4
|
13
|
-
|
14
|
-
```
|
15
|
-
l. Provision for Article 1.
|
16
|
-
ll. Provision for Section 1.1.
|
17
|
-
lll. Provision for 1.1.1.
|
18
|
-
lll. Provision for 1.1.2.
|
19
|
-
ll. Provision for Section 1.2.
|
20
|
-
lll. Provision for 1.2.1.
|
21
|
-
l. Provision for 1.2.2.
|
22
|
-
ll. Profivis asl;jksfd;lg; lkshflksjdh
|
23
|
-
l. asd;flkajsdf;lkj
|
24
|
-
ll. ;alsdkfjasd;flkajsd
|
25
|
-
lll. as;dlfkjasd;flakjsdll.
|
26
|
-
llll. a;lsdfkjasd;lfkj
|
27
|
-
ll. a;sdlfkajsd;flk
|
28
|
-
l. as;dlfkajsd;flkj
|
29
|
-
lll. a;sldfkajsd;
|
30
|
-
ll. a;sldfkjasd;flkajs
|
31
|
-
llll. a;lsdfkajsd;lfkj
|
32
|
-
ll. a;sdlfkajsd;flkajs
|
33
|
-
lll. as;dlfkjasd;lfkjs
|
34
|
-
llll. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
35
|
-
llll. tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
36
|
-
ll. quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
37
|
-
llll. consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
38
|
-
l. cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
39
|
-
ll. proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
40
|
-
```
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# TEST 4
|
2
|
-
|
3
|
-
Article 1. Provision for Article 1.
|
4
|
-
|
5
|
-
Section 1. Provision for Section 1.1.
|
6
|
-
|
7
|
-
1. Provision for 1.1.1.
|
8
|
-
|
9
|
-
2. Provision for 1.1.2.
|
10
|
-
|
11
|
-
Section 2. Provision for Section 1.2.
|
12
|
-
|
13
|
-
1. Provision for 1.2.1.
|
14
|
-
|
15
|
-
Article 2. Provision for 1.2.2.
|
16
|
-
|
17
|
-
Section 1. Profivis asl;jksfd;lg; lkshflksjdh
|
18
|
-
|
19
|
-
Article 3. asd;flkajsdf;lkj
|
20
|
-
|
21
|
-
Section 1. ;alsdkfjasd;flkajsd
|
22
|
-
|
23
|
-
1. as;dlfkjasd;flakjsdll.
|
24
|
-
|
25
|
-
a. a;lsdfkjasd;lfkj
|
26
|
-
|
27
|
-
Section 2. a;sdlfkajsd;flk
|
28
|
-
|
29
|
-
Article 4. as;dlfkajsd;flkj
|
30
|
-
|
31
|
-
1. a;sldfkajsd;
|
32
|
-
|
33
|
-
Section 1. a;sldfkjasd;flkajs
|
34
|
-
|
35
|
-
a. a;lsdfkajsd;lfkj
|
36
|
-
|
37
|
-
Section 2. a;sdlfkajsd;flkajs
|
38
|
-
|
39
|
-
1. as;dlfkjasd;lfkjs
|
40
|
-
|
41
|
-
a. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
42
|
-
|
43
|
-
b. tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
44
|
-
|
45
|
-
Section 3. quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
46
|
-
|
47
|
-
a. consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
48
|
-
|
49
|
-
Article 5. cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
50
|
-
|
51
|
-
Section 1. proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
52
|
-
|