legal_markdown 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +6 -0
- data/README.md +4 -0
- data/Rakefile +8 -0
- data/bin/legal2md +1 -1
- data/lib/legal_markdown.rb +8 -429
- data/lib/legal_markdown/legal_to_markdown.rb +17 -0
- data/lib/legal_markdown/legal_to_markdown/leaders.rb +259 -0
- data/lib/legal_markdown/legal_to_markdown/load_source.rb +74 -0
- data/lib/legal_markdown/legal_to_markdown/mixins.rb +74 -0
- data/lib/legal_markdown/legal_to_markdown/writer.rb +12 -0
- data/lib/legal_markdown/{roman-numerals.rb → roman_numerals.rb} +0 -0
- data/lib/legal_markdown/version.rb +1 -1
- data/test/test_legal_markdown_to_markdown.rb +4 -4
- metadata +10 -6
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# Status
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/compleatang/legal-markdown.png)](https://travis-ci.org/compleatang/legal-markdown)[![Code Climate](https://codeclimate.com/github/compleatang/legal-markdown.png)](https://codeclimate.com/github/compleatang/legal-markdown)[![Dependency Status](https://gemnasium.com/compleatang/legal-markdown.png)](https://gemnasium.com/compleatang/legal-markdown)
|
4
|
+
|
1
5
|
# Introduction
|
2
6
|
|
3
7
|
This gem will parse YAML Front Matter of Markdown Documents. Typically, this gem would be called with a md renderer, such as [Pandoc](http://johnmacfarlane.net/pandoc/), that would turn the md into a document such as a .pdf file or a .docx file. By combining this pre-processing with a markdown renderer, you can ensure that both the structured content and the structured styles necessary for your firm or organization are more strictly enforced. Plus you won't have to deal with Word any longer, and every lawyer should welcome that. Why? Because Word is awful.
|
data/Rakefile
CHANGED
data/bin/legal2md
CHANGED
data/lib/legal_markdown.rb
CHANGED
@@ -1,440 +1,19 @@
|
|
1
1
|
#! ruby
|
2
|
-
require 'yaml'
|
3
|
-
require File.dirname(__FILE__) + '/legal_markdown/roman-numerals'
|
4
2
|
require File.dirname(__FILE__) + '/legal_markdown/version'
|
5
3
|
require File.dirname(__FILE__) + '/legal_markdown/make_yaml_frontmatter.rb'
|
4
|
+
require File.dirname(__FILE__) + '/legal_markdown/legal_to_markdown.rb'
|
6
5
|
|
7
|
-
|
6
|
+
module LegalMarkdown
|
8
7
|
|
9
|
-
def self.
|
10
|
-
|
8
|
+
def self.parse(*args)
|
9
|
+
args = ARGV.dup
|
10
|
+
if(!args[0])
|
11
11
|
STDERR.puts "Sorry, I didn't understand that. Please give me your legal_markdown filenames or \"-\" for stdin."
|
12
12
|
exit 0
|
13
|
-
elsif
|
14
|
-
MakeYamlFrontMatter.new(
|
13
|
+
elsif args.include?("--headers")
|
14
|
+
LegalMarkdown::MakeYamlFrontMatter.new(args)
|
15
15
|
else
|
16
|
-
args
|
17
|
-
LegalToMarkdown.new(args)
|
18
|
-
end
|
19
|
-
end # main
|
20
|
-
|
21
|
-
def initialize(args)
|
22
|
-
data = load(args) # Get the Content
|
23
|
-
parsed_content = parse_file(data) # Load the YAML front matter
|
24
|
-
mixed_content = mixing_in(parsed_content[0], parsed_content[1]) # Run the Mixins
|
25
|
-
headed_content = headers_on(mixed_content[0], mixed_content[1]) # Run the Headers
|
26
|
-
file = write_it( headed_content ) # Write the file
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
# ----------------------
|
31
|
-
# | Step 1 |
|
32
|
-
# ----------------------
|
33
|
-
# Parse Options & Load File
|
34
|
-
def load(args)
|
35
|
-
@output_file = args[-1]
|
36
|
-
@input_file = args[-2] ? args[-2] : args[-1]
|
37
|
-
begin
|
38
|
-
if @input_file != "-"
|
39
|
-
source_file = File::read(@input_file) if File::exists?(@input_file) && File::readable?(@input_file)
|
40
|
-
elsif @input_file == "-"
|
41
|
-
source_file = STDIN.read
|
42
|
-
end
|
43
|
-
source_file.scan(/(@include (.+)$)/).each do |set|
|
44
|
-
partial_file = set[1]
|
45
|
-
to_replace = set[0]
|
46
|
-
partial_contents = File::read(partial_file) if File::exists?(partial_file) && File::readable?(partial_file)
|
47
|
-
source_file.gsub!(to_replace, partial_contents)
|
48
|
-
end
|
49
|
-
return source_file
|
50
|
-
rescue => e
|
51
|
-
puts "Sorry, I could not read the input file #{@input_file}: #{e.message}."
|
52
|
-
exit 0
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# ----------------------
|
57
|
-
# | Step 2 |
|
58
|
-
# ----------------------
|
59
|
-
# Load YAML Front-matter
|
60
|
-
|
61
|
-
def parse_file(source)
|
62
|
-
begin
|
63
|
-
if source[/@today/]
|
64
|
-
require 'date'
|
65
|
-
d = Date.today.strftime("%-d %B, %Y")
|
66
|
-
source.gsub!($&, d)
|
67
|
-
end
|
68
|
-
yaml_pattern = /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
69
|
-
parts = source.partition( yaml_pattern )
|
70
|
-
if parts[1] != ""
|
71
|
-
headers = YAML.load(parts[1])
|
72
|
-
content = parts[2]
|
73
|
-
else
|
74
|
-
headers = {}
|
75
|
-
content = source
|
76
|
-
end
|
77
|
-
rescue => e
|
78
|
-
puts "Sorry, something went wrong when I was loading the YAML front matter: #{e.message}."
|
79
|
-
end
|
80
|
-
return [headers, content]
|
81
|
-
end
|
82
|
-
|
83
|
-
# ----------------------
|
84
|
-
# | Step 3 |
|
85
|
-
# ----------------------
|
86
|
-
# Mixins
|
87
|
-
|
88
|
-
def mixing_in( mixins, content )
|
89
|
-
|
90
|
-
def clauses_mixins( mixins, content )
|
91
|
-
clauses_to_delete = []
|
92
|
-
clauses_to_mixin = []
|
93
|
-
|
94
|
-
mixins.each do | mixin, replacer |
|
95
|
-
replacer = replacer.to_s.downcase
|
96
|
-
clauses_to_delete << mixin if replacer == "false"
|
97
|
-
clauses_to_mixin << mixin if replacer == "true"
|
98
|
-
end
|
99
|
-
|
100
|
-
clauses_to_delete.each { |m| mixins.delete(m) }
|
101
|
-
clauses_to_mixin.each { |m| mixins.delete(m) }
|
102
|
-
|
103
|
-
until clauses_to_delete.size == 0
|
104
|
-
clauses_to_delete.each do | mixin |
|
105
|
-
pattern = /(\[{{#{mixin}}}\s*?)(.*?\n*?)(\])/m
|
106
|
-
sub_pattern = /\[{{(\S+?)}}\s*?/
|
107
|
-
content[pattern]
|
108
|
-
get_it_all = $& || ""
|
109
|
-
sub_clause = $2 || ""
|
110
|
-
if sub_clause[sub_pattern] && clauses_to_delete.include?($1)
|
111
|
-
next
|
112
|
-
elsif sub_clause[sub_pattern]
|
113
|
-
pattern = /\[{{#{mixin}}}\s*?.*?\n*?\].*?\n*?\]/m
|
114
|
-
content[pattern]; get_it_all = $& || ""
|
115
|
-
end
|
116
|
-
content = content.gsub( get_it_all, "" )
|
117
|
-
clauses_to_delete.delete( mixin ) unless content[pattern]
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
until clauses_to_mixin.size == 0
|
122
|
-
clauses_to_mixin.each do | mixin |
|
123
|
-
pattern = /(\[{{#{mixin}}}\s*?)(.*?\n*?)(\])/m
|
124
|
-
sub_pattern = /\[{{(\S+?)}}\s*?/
|
125
|
-
content[pattern]
|
126
|
-
get_it_all = $& || ""
|
127
|
-
sub_clause = $2 || ""
|
128
|
-
next if sub_clause[sub_pattern] && clauses_to_mixin.include?($1)
|
129
|
-
content = content.gsub( get_it_all, sub_clause.lstrip )
|
130
|
-
clauses_to_mixin.delete( mixin ) unless content[pattern]
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
return [ mixins, content ]
|
135
|
-
end
|
136
|
-
|
137
|
-
def text_mixins( mixins, content )
|
138
|
-
mixins.each do | mixin, replacer |
|
139
|
-
unless mixin =~ /level-\d/ or mixin =~ /no-reset/ or mixin =~ /no-indent/ or mixin =~ /level-style/
|
140
|
-
replacer = replacer.to_s
|
141
|
-
mixin_pattern = /({{#{mixin}}})/
|
142
|
-
content = content.gsub( $1, replacer ) if content =~ mixin_pattern
|
143
|
-
mixins.delete( mixin )
|
144
|
-
end
|
145
|
-
end
|
146
|
-
return [ mixins, content ]
|
147
|
-
end
|
148
|
-
|
149
|
-
clauses_mixed = clauses_mixins( mixins, content )
|
150
|
-
fully_mixed = text_mixins( clauses_mixed[0], clauses_mixed[1] )
|
151
|
-
fully_mixed[1].gsub!(/(\n\n+)/, "\n\n")
|
152
|
-
fully_mixed[1].squeeze!(" ")
|
153
|
-
return [ fully_mixed[0], fully_mixed[1] ]
|
154
|
-
end
|
155
|
-
|
156
|
-
# ----------------------
|
157
|
-
# | Step 4 |
|
158
|
-
# ----------------------
|
159
|
-
# Headers
|
160
|
-
|
161
|
-
def headers_on( headers, content )
|
162
|
-
|
163
|
-
def set_the_subs_arrays( value )
|
164
|
-
# takes a core value from the hash pulled from the yaml
|
165
|
-
# returns an array with a type symbol and a precursor string
|
166
|
-
if value =~ /([IVXLCDM]+)\.\z/ # type1 : {{ I. }}
|
167
|
-
return[:type1, value.delete($1 + "."), "", $1, "."]
|
168
|
-
elsif value =~ /\(([IVXLCDM]+)\)\z/ # type2 : {{ (I) }}
|
169
|
-
return[:type2, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
170
|
-
elsif value =~ /([ivxlcdm]+)\.\z/ # type3 : {{ i. }}
|
171
|
-
return[:type3, value.delete($1 + "."), "", $1, "."]
|
172
|
-
elsif value =~ /\(([ivxlcdm]+)\)\z/ # type4 : {{ (i) }}
|
173
|
-
return[:type4, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
174
|
-
elsif value =~ /([A-Z]+)\.\z/ # type5 : {{ A. }}
|
175
|
-
return[:type5, value.delete($1 + "."), "", $1, "."]
|
176
|
-
elsif value =~ /\(([A-Z]+)\)\z/ # type6 : {{ (A) }}
|
177
|
-
return[:type6, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
178
|
-
elsif value =~ /([a-z]+)\.\z/ # type7 : {{ a. }}
|
179
|
-
return[:type7, value.delete($1 + "."), "", $1, "."]
|
180
|
-
elsif value =~ /\(([a-z]+)\)\z/ # type8 : {{ (a) }}
|
181
|
-
return[:type8, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
182
|
-
elsif value =~ /\((\d+)\)\z/ # type9 : {{ (1) }}
|
183
|
-
return[:type9, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
184
|
-
else value =~ /(\d+)\.\z/ # type0 : {{ 1. }} ... also default
|
185
|
-
return[:type0, value.delete($1 + "."), "", $1, "."]
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
def get_the_substitutions( headers )
|
190
|
-
# find the headers in the remaining YAML
|
191
|
-
# parse out the headers into level-X and pre-X headers
|
192
|
-
# then combine them into a coherent package
|
193
|
-
# returns a hash with the keys as the l., ll. searches
|
194
|
-
# and the values as the replacements in the form of
|
195
|
-
# an array where the first value is a symbol and the
|
196
|
-
# second value is the precursor
|
197
|
-
|
198
|
-
# @substitutions hash example
|
199
|
-
# {"ll." || "l2."=>[:type8, "Article ", "(", "1", ")", :no_reset || nil, " ", :preval || :pre || nil]}
|
200
|
-
|
201
|
-
@substitutions = {}
|
202
|
-
|
203
|
-
if headers.has_key?("level-style")
|
204
|
-
headers["level-style"] =~ /l1/ ? @deep_leaders = true : @deep_leaders = false
|
205
|
-
else
|
206
|
-
@deep_leaders = false
|
207
|
-
end
|
208
|
-
|
209
|
-
if headers.has_key?("no-indent") && headers["no-indent"]
|
210
|
-
no_indent_array = headers["no-indent"].split(", ")
|
211
|
-
no_indent_array.include?("l." || "l1.") ? @offset = no_indent_array.size : @offset = no_indent_array.size + 1
|
212
|
-
else
|
213
|
-
@offset = 1
|
214
|
-
end
|
215
|
-
|
216
|
-
headers.each do | header, value |
|
217
|
-
if @deep_leaders
|
218
|
-
search = "l" + header[-1] + "." if header =~ /level-\d/
|
219
|
-
else
|
220
|
-
search = "l" * header[-1].to_i + "." if header =~ /level-\d/
|
221
|
-
end
|
222
|
-
|
223
|
-
if header =~ /level-\d/
|
224
|
-
@substitutions[search]= set_the_subs_arrays(value.to_s)
|
225
|
-
@deep_leaders ? spaces = (search[1].to_i - @offset) : spaces = (search.size - @offset - 1)
|
226
|
-
spaces < 0 ? spaces = 0 : spaces = spaces * 2
|
227
|
-
@substitutions[search][6] = " " * spaces
|
228
|
-
if value =~ /\s*preval\s*/
|
229
|
-
@substitutions[search][1].gsub!(/preval\s*/, "")
|
230
|
-
@substitutions[search][7] = :preval
|
231
|
-
elsif value =~ /\s*pre\s*/
|
232
|
-
@substitutions[search][1].gsub!(/pre\s*/, "")
|
233
|
-
@substitutions[search][7] = :pre
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
if headers["no-reset"]
|
239
|
-
no_subs_array = headers["no-reset"].split(", ")
|
240
|
-
no_subs_array.each{ |e| @substitutions[e][5] = :no_reset unless e == "l." || e == "l1."}
|
241
|
-
end
|
242
|
-
|
243
|
-
return @substitutions
|
244
|
-
end
|
245
|
-
|
246
|
-
def find_the_block( content )
|
247
|
-
block_pattern = /(^```+\s*\n?)(.*?\n?)(^```+\s*\n?)/m
|
248
|
-
parts = content.partition( block_pattern )
|
249
|
-
if parts[1] != ""
|
250
|
-
block = $2.chomp
|
251
|
-
content = parts[0] + "{{block}}" + parts[2]
|
252
|
-
else
|
253
|
-
block = ""
|
254
|
-
content = content
|
255
|
-
end
|
256
|
-
return [ block, content ]
|
257
|
-
end
|
258
|
-
|
259
|
-
def chew_on_the_block( old_block )
|
260
|
-
# takes a hash of substitutions to make from the #get_the_substitutions method
|
261
|
-
# and a block of text returned from the #find_the_block method
|
262
|
-
# iterates over the block to make the appropriate substitutions
|
263
|
-
# returns a block of text
|
264
|
-
|
265
|
-
# method will take the old_block and iterate through the lines.
|
266
|
-
# First it will find the leading indicator. Then it will
|
267
|
-
# find the appropriate substitution from the @substitutions
|
268
|
-
# hash. After that it will rebuild the leading matter from the
|
269
|
-
# sub hash. It will drop markers if it is going down the tree.
|
270
|
-
# It will reset the branches if it is going up the tree.
|
271
|
-
# sub_it is an array w/ type[0] & lead_string[1] & id's[2..4]
|
272
|
-
|
273
|
-
# @substitutions hash example
|
274
|
-
# {"ll."OR "l2."=>[:type8, "Article ", "(", "1", ")", :no_reset || nil, :no_indent || nil, :preval || :pre || nil],}
|
275
|
-
|
276
|
-
def romans_takedown( array_to_sub )
|
277
|
-
if array_to_sub[0] == :type1 || array_to_sub[0] == :type2
|
278
|
-
@r_u = true
|
279
|
-
elsif array_to_sub[0] == :type3 || array_to_sub[0] == :type4
|
280
|
-
@r_l = true
|
281
|
-
end
|
282
|
-
if @r_l || @r_u
|
283
|
-
array_to_sub[3] = RomanNumerals.to_decimal_string(array_to_sub[3])
|
284
|
-
end
|
285
|
-
return array_to_sub
|
286
|
-
end
|
287
|
-
|
288
|
-
def romans_setup( array_to_sub )
|
289
|
-
if @r_l || @r_u
|
290
|
-
array_to_sub[3] = RomanNumerals.to_roman_upper(array_to_sub[3]) if @r_u
|
291
|
-
array_to_sub[3] = RomanNumerals.to_roman_lower(array_to_sub[3]) if @r_l
|
292
|
-
end
|
293
|
-
@r_l = false; @r_u = false
|
294
|
-
return array_to_sub
|
295
|
-
end
|
296
|
-
|
297
|
-
def increment_the_branch( array_to_sub, selector, next_selector )
|
298
|
-
if selector > next_selector #going up the tree and reset
|
299
|
-
selectors_to_reset = @substitutions.inject([]){ |m,(k,v)| m << k if k > next_selector; m }
|
300
|
-
selectors_to_reset.each do | this_selector |
|
301
|
-
substitutor = @substitutions[this_selector]
|
302
|
-
substitutor = romans_takedown( substitutor )
|
303
|
-
substitutor[3].next! if this_selector == selector
|
304
|
-
if substitutor[0] == :type5 || substitutor[0] == :type6
|
305
|
-
substitutor[3] = "A" unless substitutor[5] == :no_reset
|
306
|
-
elsif substitutor[0] == :type7 || substitutor[0] == :type8
|
307
|
-
substitutor[3] = "a" unless substitutor[5] == :no_reset
|
308
|
-
else
|
309
|
-
substitutor[3] = "1" unless substitutor[5] == :no_reset
|
310
|
-
end
|
311
|
-
substitutor = romans_setup( substitutor )
|
312
|
-
@substitutions[this_selector]= substitutor
|
313
|
-
end
|
314
|
-
array_to_sub = @substitutions[selector]
|
315
|
-
else #not going up tree
|
316
|
-
array_to_sub = romans_takedown( array_to_sub )
|
317
|
-
array_to_sub[3].next!
|
318
|
-
array_to_sub = romans_setup( array_to_sub )
|
319
|
-
end
|
320
|
-
|
321
|
-
return array_to_sub
|
322
|
-
end
|
323
|
-
|
324
|
-
def get_selector_above( selector )
|
325
|
-
if @deep_leaders
|
326
|
-
selector_above = "l" + (selector[1].to_i-1).to_s + "."
|
327
|
-
selector_above = "l1." if selector_above == "l0."
|
328
|
-
else
|
329
|
-
selector_above = selector[1..-1]
|
330
|
-
selector_above = "l." if selector_above == "."
|
331
|
-
end
|
332
|
-
return selector_above
|
333
|
-
end
|
334
|
-
|
335
|
-
def find_parent_reference( selector_above )
|
336
|
-
leading_prov = @substitutions[selector_above].clone
|
337
|
-
leading_prov = romans_takedown( leading_prov )
|
338
|
-
if leading_prov[0] == :type5 || leading_prov[0] == :type6
|
339
|
-
leading_prov[3] = leading_prov[3][0..-2] + (leading_prov[3][-1].ord-1).chr
|
340
|
-
elsif leading_prov[0] == :type7 || leading_prov[0] == :type8
|
341
|
-
leading_prov[3] = leading_prov[3][0..-2] + (leading_prov[3][-1].ord-1).chr
|
342
|
-
else
|
343
|
-
leading_prov[3] = (leading_prov[3].to_i-1).to_s
|
344
|
-
end
|
345
|
-
leading_prov = romans_setup( leading_prov )
|
346
|
-
return leading_prov
|
347
|
-
end
|
348
|
-
|
349
|
-
def preval_substitution( array_to_sub, selector )
|
350
|
-
array_to_sub.pop unless array_to_sub.last == :preval
|
351
|
-
selector_above = get_selector_above( selector )
|
352
|
-
leading_prov = find_parent_reference( selector_above )[3]
|
353
|
-
trailing_prov = array_to_sub[3].clone
|
354
|
-
trailing_prov.prepend("0") if trailing_prov.size == 1
|
355
|
-
array_to_sub << array_to_sub[2] + leading_prov.to_s + trailing_prov.to_s + array_to_sub[4]
|
356
|
-
array_to_sub.last.gsub!($1, "(") if array_to_sub.last[/(\.\()/]
|
357
|
-
return array_to_sub
|
358
|
-
end
|
359
|
-
|
360
|
-
def pre_substitution( array_to_sub, selector )
|
361
|
-
array_to_sub.pop unless array_to_sub.last == :pre
|
362
|
-
selector_above = get_selector_above( selector )
|
363
|
-
leading_prov = @substitutions[selector_above][8] || find_parent_reference( selector_above )[2..4].join
|
364
|
-
trailing_prov = array_to_sub[2..4].join
|
365
|
-
array_to_sub << leading_prov + trailing_prov
|
366
|
-
array_to_sub.last.gsub!($1, "(") if array_to_sub.last[/(\.\()/]
|
367
|
-
return array_to_sub
|
368
|
-
end
|
369
|
-
|
370
|
-
cross_references = {}
|
371
|
-
arrayed_block = []
|
372
|
-
old_block.each_line do |line|
|
373
|
-
next if line[/^\s*\n/]
|
374
|
-
line[/(^l+\.|^l\d\.)\s*(\|.*?\|)*\s*(.*)$/] ? arrayed_block << [$1, $3, $2] : arrayed_block.last[1] << ("\n" + line.rstrip)
|
375
|
-
end
|
376
|
-
old_block = "" # for large files
|
377
|
-
|
378
|
-
new_block = arrayed_block.inject("") do |block, arrayed_line|
|
379
|
-
|
380
|
-
selector = arrayed_line[0]
|
381
|
-
next_selector = ( arrayed_block[arrayed_block.index(arrayed_line)+1] || arrayed_block.last ).first
|
382
|
-
sub_it = @substitutions[selector]
|
383
|
-
|
384
|
-
if arrayed_line[1] =~ /\n/
|
385
|
-
arrayed_line[1].gsub!("\n", "\n\n" + sub_it[6])
|
386
|
-
end
|
387
|
-
|
388
|
-
if sub_it[7] == :preval
|
389
|
-
sub_it = preval_substitution(sub_it, selector)
|
390
|
-
reference = sub_it.last
|
391
|
-
elsif sub_it[7] == :pre
|
392
|
-
sub_it = pre_substitution(sub_it, selector)
|
393
|
-
reference = sub_it.last
|
394
|
-
else
|
395
|
-
reference = sub_it[2..4].join
|
396
|
-
end
|
397
|
-
|
398
|
-
block << sub_it[6] + sub_it[1] + reference + " " + arrayed_line[1] + "\n\n"
|
399
|
-
if arrayed_line[2]
|
400
|
-
cross_references[arrayed_line[2]]= sub_it[1] + reference
|
401
|
-
cross_references[arrayed_line[2]].gsub!(/\A\*|\#+ |\.\z/, "") #guard against formatting of headers into txt
|
402
|
-
end
|
403
|
-
@substitutions[selector]= increment_the_branch(sub_it, selector, next_selector)
|
404
|
-
|
405
|
-
block
|
406
|
-
end
|
407
|
-
|
408
|
-
cross_references.each_key{|k| new_block.gsub!(k, cross_references[k]) }
|
409
|
-
return new_block
|
410
|
-
end
|
411
|
-
|
412
|
-
headers = get_the_substitutions( headers )
|
413
|
-
block_found = find_the_block( content )
|
414
|
-
block = block_found[0]
|
415
|
-
not_the_block = block_found[1]
|
416
|
-
block_found = "" # for long documents
|
417
|
-
|
418
|
-
if block == ""
|
419
|
-
block_redux = ""
|
420
|
-
elsif headers == {}
|
421
|
-
block_redux = block
|
422
|
-
else
|
423
|
-
block_redux = chew_on_the_block( block )
|
424
|
-
end
|
425
|
-
headed = not_the_block.gsub("{{block}}", block_redux )
|
426
|
-
end
|
427
|
-
|
428
|
-
# ----------------------
|
429
|
-
# | Step 6 |
|
430
|
-
# ----------------------
|
431
|
-
# Write the file
|
432
|
-
def write_it( final_content )
|
433
|
-
final_content = final_content.gsub(/ +\n/, "\n")
|
434
|
-
if @output_file && @output_file != "-"
|
435
|
-
File.open(@output_file, "w") {|f| f.write( final_content ) }
|
436
|
-
else
|
437
|
-
STDOUT.write final_content
|
16
|
+
LegalMarkdown::LegalToMarkdown.parse(args)
|
438
17
|
end
|
439
18
|
end
|
440
19
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/legal_to_markdown/load_source.rb'
|
2
|
+
require File.dirname(__FILE__) + '/legal_to_markdown/mixins.rb'
|
3
|
+
require File.dirname(__FILE__) + '/legal_to_markdown/leaders.rb'
|
4
|
+
require File.dirname(__FILE__) + '/legal_to_markdown/writer.rb'
|
5
|
+
require File.dirname(__FILE__) + '/roman_numerals'
|
6
|
+
|
7
|
+
module LegalToMarkdown
|
8
|
+
|
9
|
+
def parse(args)
|
10
|
+
@output_file = args[-1]
|
11
|
+
@input_file = args[-2] ? args[-2] : 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
|
+
end
|
@@ -0,0 +1,259 @@
|
|
1
|
+
module LegalToMarkdown
|
2
|
+
extend self
|
3
|
+
|
4
|
+
module Leaders
|
5
|
+
|
6
|
+
def run_leaders
|
7
|
+
get_the_substitutions
|
8
|
+
find_the_block
|
9
|
+
@block = chew_on_the_block
|
10
|
+
clean_up_leaders
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_the_substitutions
|
14
|
+
# find the headers in the remaining YAML
|
15
|
+
# parse out the headers into level-X and pre-X headers
|
16
|
+
# then combine them into a coherent package
|
17
|
+
# returns a hash with the keys as the l., ll. searches
|
18
|
+
# and the values as the replacements in the form of
|
19
|
+
# an array where the first value is a symbol and the
|
20
|
+
# second value is the precursor
|
21
|
+
#
|
22
|
+
# @substitutions hash example
|
23
|
+
# {"ll." || "l2."=>[:type8, "Article ", "(", "1", ")", :no_reset || nil, " ", :preval || :pre || nil]}
|
24
|
+
|
25
|
+
@substitutions = {}
|
26
|
+
|
27
|
+
if @headers.has_key?("level-style")
|
28
|
+
@headers["level-style"] =~ /l1/ ? @deep_leaders = true : @deep_leaders = false
|
29
|
+
else
|
30
|
+
@deep_leaders = false
|
31
|
+
end
|
32
|
+
|
33
|
+
if @headers.has_key?("no-indent") && @headers["no-indent"]
|
34
|
+
no_indent_array = @headers["no-indent"].split(", ")
|
35
|
+
no_indent_array.include?("l." || "l1.") ? @offset = no_indent_array.size : @offset = no_indent_array.size + 1
|
36
|
+
else
|
37
|
+
@offset = 1
|
38
|
+
end
|
39
|
+
|
40
|
+
@headers.each do | header, value |
|
41
|
+
if @deep_leaders
|
42
|
+
search = "l" + header[-1] + "." if header =~ /level-\d/
|
43
|
+
else
|
44
|
+
search = "l" * header[-1].to_i + "." if header =~ /level-\d/
|
45
|
+
end
|
46
|
+
|
47
|
+
if header =~ /level-\d/
|
48
|
+
@substitutions[search]= set_the_subs_arrays(value.to_s)
|
49
|
+
@deep_leaders ? spaces = (search[1].to_i - @offset) : spaces = (search.size - @offset - 1)
|
50
|
+
spaces < 0 ? spaces = 0 : spaces = spaces * 2
|
51
|
+
@substitutions[search][6] = " " * spaces
|
52
|
+
if value =~ /\s*preval\s*/
|
53
|
+
@substitutions[search][1].gsub!(/preval\s*/, "")
|
54
|
+
@substitutions[search][7] = :preval
|
55
|
+
elsif value =~ /\s*pre\s*/
|
56
|
+
@substitutions[search][1].gsub!(/pre\s*/, "")
|
57
|
+
@substitutions[search][7] = :pre
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if @headers["no-reset"]
|
63
|
+
no_subs_array = @headers["no-reset"].split(", ")
|
64
|
+
no_subs_array.each{ |e| @substitutions[e][5] = :no_reset unless e == "l." || e == "l1."}
|
65
|
+
end
|
66
|
+
end
|
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 )
|
139
|
+
end
|
140
|
+
|
141
|
+
def set_the_subs_arrays( value )
|
142
|
+
# takes a core value from the hash pulled from the yaml
|
143
|
+
# returns an array with a type symbol and a precursor string
|
144
|
+
if value =~ /([IVXLCDM]+)\.\z/ # type1 : {{ I. }}
|
145
|
+
return[:type1, value.delete($1 + "."), "", $1, "."]
|
146
|
+
elsif value =~ /\(([IVXLCDM]+)\)\z/ # type2 : {{ (I) }}
|
147
|
+
return[:type2, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
148
|
+
elsif value =~ /([ivxlcdm]+)\.\z/ # type3 : {{ i. }}
|
149
|
+
return[:type3, value.delete($1 + "."), "", $1, "."]
|
150
|
+
elsif value =~ /\(([ivxlcdm]+)\)\z/ # type4 : {{ (i) }}
|
151
|
+
return[:type4, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
152
|
+
elsif value =~ /([A-Z]+)\.\z/ # type5 : {{ A. }}
|
153
|
+
return[:type5, value.delete($1 + "."), "", $1, "."]
|
154
|
+
elsif value =~ /\(([A-Z]+)\)\z/ # type6 : {{ (A) }}
|
155
|
+
return[:type6, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
156
|
+
elsif value =~ /([a-z]+)\.\z/ # type7 : {{ a. }}
|
157
|
+
return[:type7, value.delete($1 + "."), "", $1, "."]
|
158
|
+
elsif value =~ /\(([a-z]+)\)\z/ # type8 : {{ (a) }}
|
159
|
+
return[:type8, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
160
|
+
elsif value =~ /\((\d+)\)\z/ # type9 : {{ (1) }}
|
161
|
+
return[:type9, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
162
|
+
else value =~ /(\d+)\.\z/ # type0 : {{ 1. }} ... also default
|
163
|
+
return[:type0, value.delete($1 + "."), "", $1, "."]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def romans_takedown( array_to_sub )
|
168
|
+
if array_to_sub[0] == :type1 || array_to_sub[0] == :type2
|
169
|
+
@r_u = true
|
170
|
+
elsif array_to_sub[0] == :type3 || array_to_sub[0] == :type4
|
171
|
+
@r_l = true
|
172
|
+
end
|
173
|
+
if @r_l || @r_u
|
174
|
+
array_to_sub[3] = RomanNumerals.to_decimal_string(array_to_sub[3])
|
175
|
+
end
|
176
|
+
return array_to_sub
|
177
|
+
end
|
178
|
+
|
179
|
+
def romans_setup( array_to_sub )
|
180
|
+
if @r_l || @r_u
|
181
|
+
array_to_sub[3] = RomanNumerals.to_roman_upper(array_to_sub[3]) if @r_u
|
182
|
+
array_to_sub[3] = RomanNumerals.to_roman_lower(array_to_sub[3]) if @r_l
|
183
|
+
end
|
184
|
+
@r_l = false; @r_u = false
|
185
|
+
return array_to_sub
|
186
|
+
end
|
187
|
+
|
188
|
+
def increment_the_branch( array_to_sub, selector, next_selector )
|
189
|
+
if selector > next_selector #going up the tree and reset
|
190
|
+
selectors_to_reset = @substitutions.inject([]){ |m,(k,v)| m << k if k > next_selector; m }
|
191
|
+
selectors_to_reset.each do | this_selector |
|
192
|
+
substitutor = @substitutions[this_selector]
|
193
|
+
substitutor = romans_takedown( substitutor )
|
194
|
+
substitutor[3].next! if this_selector == selector
|
195
|
+
if substitutor[0] == :type5 || substitutor[0] == :type6
|
196
|
+
substitutor[3] = "A" unless substitutor[5] == :no_reset
|
197
|
+
elsif substitutor[0] == :type7 || substitutor[0] == :type8
|
198
|
+
substitutor[3] = "a" unless substitutor[5] == :no_reset
|
199
|
+
else
|
200
|
+
substitutor[3] = "1" unless substitutor[5] == :no_reset
|
201
|
+
end
|
202
|
+
substitutor = romans_setup( substitutor )
|
203
|
+
@substitutions[this_selector]= substitutor
|
204
|
+
end
|
205
|
+
array_to_sub = @substitutions[selector]
|
206
|
+
else #not going up tree
|
207
|
+
array_to_sub = romans_takedown( array_to_sub )
|
208
|
+
array_to_sub[3].next!
|
209
|
+
array_to_sub = romans_setup( array_to_sub )
|
210
|
+
end
|
211
|
+
|
212
|
+
return array_to_sub
|
213
|
+
end
|
214
|
+
|
215
|
+
def get_selector_above( selector )
|
216
|
+
if @deep_leaders
|
217
|
+
selector_above = "l" + (selector[1].to_i-1).to_s + "."
|
218
|
+
selector_above = "l1." if selector_above == "l0."
|
219
|
+
else
|
220
|
+
selector_above = selector[1..-1]
|
221
|
+
selector_above = "l." if selector_above == "."
|
222
|
+
end
|
223
|
+
return selector_above
|
224
|
+
end
|
225
|
+
|
226
|
+
def find_parent_reference( selector_above )
|
227
|
+
leading_prov = @substitutions[selector_above].clone
|
228
|
+
leading_prov = romans_takedown( leading_prov )
|
229
|
+
if leading_prov[0] == ( :type5 || :type6 || :type7 || :type8 )
|
230
|
+
leading_prov[3] = leading_prov[3][0..-2] + (leading_prov[3][-1].ord-1).chr
|
231
|
+
else
|
232
|
+
leading_prov[3] = (leading_prov[3].to_i-1).to_s
|
233
|
+
end
|
234
|
+
leading_prov = romans_setup( leading_prov )
|
235
|
+
return leading_prov
|
236
|
+
end
|
237
|
+
|
238
|
+
def preval_substitution( array_to_sub, selector )
|
239
|
+
array_to_sub.pop unless array_to_sub.last == :preval
|
240
|
+
selector_above = get_selector_above( selector )
|
241
|
+
leading_prov = find_parent_reference( selector_above )[3]
|
242
|
+
trailing_prov = array_to_sub[3].clone
|
243
|
+
trailing_prov = "0" + trailing_prov if trailing_prov.size == 1
|
244
|
+
array_to_sub << array_to_sub[2] + leading_prov.to_s + trailing_prov.to_s + array_to_sub[4]
|
245
|
+
array_to_sub.last.gsub!($1, "(") if array_to_sub.last[/(\.\()/]
|
246
|
+
return array_to_sub
|
247
|
+
end
|
248
|
+
|
249
|
+
def pre_substitution( array_to_sub, selector )
|
250
|
+
array_to_sub.pop unless array_to_sub.last == :pre
|
251
|
+
selector_above = get_selector_above( selector )
|
252
|
+
leading_prov = @substitutions[selector_above][8] || find_parent_reference( selector_above )[2..4].join
|
253
|
+
trailing_prov = array_to_sub[2..4].join
|
254
|
+
array_to_sub << leading_prov + trailing_prov
|
255
|
+
array_to_sub.last.gsub!($1, "(") if array_to_sub.last[/(\.\()/]
|
256
|
+
return array_to_sub
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module LegalToMarkdown
|
2
|
+
extend self
|
3
|
+
|
4
|
+
class FileToParse
|
5
|
+
|
6
|
+
attr_accessor :headers, :content, :mixins, :leaders
|
7
|
+
|
8
|
+
def initialize(file)
|
9
|
+
@input_file = file; @headers = nil; @content = ""
|
10
|
+
load; get_the_partials; parse; set_the_parsers
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def load
|
16
|
+
if @input_file != "-"
|
17
|
+
@content = get_file(@input_file)
|
18
|
+
elsif @input_file == "-"
|
19
|
+
@content = STDIN.read
|
20
|
+
else
|
21
|
+
raise "No input file or stdin specified. Please specify a file or \"-\" for stdin."
|
22
|
+
exit 0
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_the_partials
|
27
|
+
if @content[/^@include/]
|
28
|
+
@content.scan(/^(@include (.+)$)/).each do |set|
|
29
|
+
partial_file = set[1]
|
30
|
+
to_replace = set[0]
|
31
|
+
partial_contents = get_file partial_file
|
32
|
+
@content.gsub!(to_replace, partial_contents)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse
|
38
|
+
require 'yaml'
|
39
|
+
today_is_the_day if @content[/@today/]
|
40
|
+
yaml_pattern = /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
41
|
+
parts = @content.partition yaml_pattern
|
42
|
+
if parts[1] != ""
|
43
|
+
@headers = YAML.load parts[1]
|
44
|
+
@content = parts[2]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_the_parsers
|
49
|
+
if @content[/\{\{/] && @headers
|
50
|
+
self.extend LegalToMarkdown::Mixins
|
51
|
+
@mixins = true
|
52
|
+
end
|
53
|
+
if @content[/^```/] && @headers
|
54
|
+
self.extend LegalToMarkdown::Leaders
|
55
|
+
@leaders = true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_file( file )
|
60
|
+
begin
|
61
|
+
f = File::read(file) if File::exists?(file) && File::readable?(file)
|
62
|
+
rescue => e
|
63
|
+
puts "Sorry, I could not read the file #{file}: #{e.message}."
|
64
|
+
exit 0
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def today_is_the_day
|
69
|
+
require 'date'
|
70
|
+
d = Date.today.strftime("%-d %B, %Y")
|
71
|
+
@content.gsub!(/@today/, d)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module LegalToMarkdown
|
2
|
+
extend self
|
3
|
+
|
4
|
+
module Mixins
|
5
|
+
|
6
|
+
def run_mixins
|
7
|
+
clauses_mixins
|
8
|
+
text_mixins
|
9
|
+
clean_up_mixins
|
10
|
+
end
|
11
|
+
|
12
|
+
def clauses_mixins
|
13
|
+
clauses_to_delete = []
|
14
|
+
clauses_to_mixin = []
|
15
|
+
|
16
|
+
@headers.each do | mixin, replacer |
|
17
|
+
replacer = replacer.to_s.downcase
|
18
|
+
clauses_to_delete << mixin if replacer == "false"
|
19
|
+
clauses_to_mixin << mixin if replacer == "true"
|
20
|
+
end
|
21
|
+
|
22
|
+
clauses_to_delete.each { |m| @headers.delete(m) }
|
23
|
+
clauses_to_mixin.each { |m| @headers.delete(m) }
|
24
|
+
|
25
|
+
until clauses_to_delete.size == 0
|
26
|
+
clauses_to_delete.each do | mixin |
|
27
|
+
pattern = /(\[\{\{#{mixin}\}\}\s*?)(.*?\n*?)(\])/m
|
28
|
+
sub_pattern = /\[\{\{(\S+?)\}\}\s*?/
|
29
|
+
@content[pattern]
|
30
|
+
get_it_all = $& || ""
|
31
|
+
sub_clause = $2 || ""
|
32
|
+
if sub_clause[sub_pattern] && clauses_to_delete.include?($1)
|
33
|
+
next
|
34
|
+
elsif sub_clause[sub_pattern]
|
35
|
+
pattern = /\[\{\{#{mixin}\}\}\s*?.*?\n*?\].*?\n*?\]/m
|
36
|
+
@content[pattern]; get_it_all = $& || ""
|
37
|
+
end
|
38
|
+
@content = @content.gsub( get_it_all, "" )
|
39
|
+
clauses_to_delete.delete( mixin ) unless @content[pattern]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
until clauses_to_mixin.size == 0
|
44
|
+
clauses_to_mixin.each do | mixin |
|
45
|
+
pattern = /(\[\{\{#{mixin}\}\}\s*?)(.*?\n*?)(\])/m
|
46
|
+
sub_pattern = /\[\{\{(\S+?)\}\}\s*?/
|
47
|
+
@content[pattern]
|
48
|
+
get_it_all = $& || ""
|
49
|
+
sub_clause = $2 || ""
|
50
|
+
next if sub_clause[sub_pattern] && clauses_to_mixin.include?($1)
|
51
|
+
@content = @content.gsub( get_it_all, sub_clause.lstrip )
|
52
|
+
clauses_to_mixin.delete( mixin ) unless @content[pattern]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def text_mixins
|
58
|
+
@headers.each do | mixin, replacer |
|
59
|
+
unless mixin =~ /level-\d/ or mixin =~ /no-reset/ or mixin =~ /no-indent/ or mixin =~ /level-style/
|
60
|
+
replacer = replacer.to_s
|
61
|
+
mixin_pattern = /(\{\{#{mixin}\}\})/
|
62
|
+
@content = @content.gsub( $1, replacer ) if @content =~ mixin_pattern
|
63
|
+
@headers.delete( mixin )
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def clean_up_mixins
|
69
|
+
@content.gsub!(/(\n\n+)/, "\n\n")
|
70
|
+
@content.squeeze!(" ")
|
71
|
+
@headers = nil if @headers.empty?
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module LegalToMarkdown
|
2
|
+
extend self
|
3
|
+
|
4
|
+
def write_it( final_content )
|
5
|
+
final_content = final_content.gsub(/ +\n/, "\n")
|
6
|
+
if @output_file && @output_file != "-"
|
7
|
+
File.open(@output_file, "w") {|f| f.write( final_content ) }
|
8
|
+
else
|
9
|
+
STDOUT.write final_content
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
File without changes
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#! ruby
|
2
2
|
require 'test/unit'
|
3
3
|
require 'tempfile'
|
4
|
-
|
4
|
+
require 'legal_markdown'
|
5
5
|
|
6
6
|
class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
|
7
7
|
# load all the .lmd files in the tests folder into an array
|
@@ -11,8 +11,8 @@ class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
|
|
11
11
|
# if assert_equal is false then stop....
|
12
12
|
|
13
13
|
def setup
|
14
|
-
Dir.chdir "
|
15
|
-
@lmdfiles = Dir.glob"*.lmd"
|
14
|
+
Dir.chdir File.dirname(__FILE__) + "/tests"
|
15
|
+
@lmdfiles = Dir.glob "*.lmd"
|
16
16
|
@lmdfiles.sort!
|
17
17
|
end
|
18
18
|
|
@@ -35,7 +35,7 @@ class TestLegalMarkdownToMarkdown < Test::Unit::TestCase
|
|
35
35
|
puts "Testing => #{lmd_file}"
|
36
36
|
temp_file = create_temp
|
37
37
|
benchmark_file = File.basename(lmd_file, ".lmd") + ".md"
|
38
|
-
LegalToMarkdown.
|
38
|
+
LegalToMarkdown.parse( [ lmd_file, temp_file ] )
|
39
39
|
assert_equal(get_file(benchmark_file).chomp, get_file(temp_file).chomp, "This file through an error => #{benchmark_file}")
|
40
40
|
destroy_temp temp_file
|
41
41
|
end
|
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.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -27,8 +27,7 @@ extensions: []
|
|
27
27
|
extra_rdoc_files: []
|
28
28
|
files:
|
29
29
|
- .gitignore
|
30
|
-
- .
|
31
|
-
- .ruby-version
|
30
|
+
- .travis.yml
|
32
31
|
- Gemfile
|
33
32
|
- LICENSE
|
34
33
|
- README.md
|
@@ -36,8 +35,13 @@ files:
|
|
36
35
|
- bin/legal2md
|
37
36
|
- legal_markdown.gemspec
|
38
37
|
- lib/legal_markdown.rb
|
38
|
+
- lib/legal_markdown/legal_to_markdown.rb
|
39
|
+
- lib/legal_markdown/legal_to_markdown/leaders.rb
|
40
|
+
- lib/legal_markdown/legal_to_markdown/load_source.rb
|
41
|
+
- lib/legal_markdown/legal_to_markdown/mixins.rb
|
42
|
+
- lib/legal_markdown/legal_to_markdown/writer.rb
|
39
43
|
- lib/legal_markdown/make_yaml_frontmatter.rb
|
40
|
-
- lib/legal_markdown/
|
44
|
+
- lib/legal_markdown/roman_numerals.rb
|
41
45
|
- lib/legal_markdown/version.rb
|
42
46
|
- test/test_legal_markdown_to_markdown.rb
|
43
47
|
- test/tests/00.load_write_no_action.lmd
|
@@ -113,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
117
|
version: '0'
|
114
118
|
segments:
|
115
119
|
- 0
|
116
|
-
hash:
|
120
|
+
hash: 366661756436547466
|
117
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
122
|
none: false
|
119
123
|
requirements:
|
@@ -122,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
126
|
version: '0'
|
123
127
|
segments:
|
124
128
|
- 0
|
125
|
-
hash:
|
129
|
+
hash: 366661756436547466
|
126
130
|
requirements: []
|
127
131
|
rubyforge_project:
|
128
132
|
rubygems_version: 1.8.25
|
data/.ruby-gemset
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
legalmd
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
ruby-1.9.3-p429
|