legal_markdown 0.1.5 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -2
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/README.md +186 -86
- data/bin/legal2md +7 -0
- data/legal_markdown.gemspec +2 -2
- data/lib/legal_markdown/make_yaml_frontmatter.rb +115 -0
- data/lib/legal_markdown/roman-numerals.rb +77 -0
- data/lib/legal_markdown/version.rb +1 -1
- data/lib/legal_markdown.rb +272 -276
- metadata +16 -26
- data/bin/md2legal +0 -7
data/lib/legal_markdown.rb
CHANGED
@@ -1,60 +1,55 @@
|
|
1
1
|
#! ruby
|
2
2
|
require 'yaml'
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
require
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
3
|
+
require File.dirname(__FILE__) + '/legal_markdown/roman-numerals'
|
4
|
+
require File.dirname(__FILE__) + '/legal_markdown/version'
|
5
|
+
require File.dirname(__FILE__) + '/legal_markdown/make_yaml_frontmatter.rb'
|
6
|
+
|
7
|
+
class LegalToMarkdown
|
8
|
+
|
9
|
+
def self.main(*args)
|
10
|
+
if(!ARGV[0])
|
11
|
+
STDERR.puts "Sorry, I didn't understand that. Please give me your legal_markdown filenames or \"-\" for stdin."
|
12
|
+
exit 0
|
13
|
+
elsif ARGV.include?("--headers")
|
14
|
+
MakeYamlFrontMatter.new(ARGV)
|
15
|
+
else
|
16
|
+
LegalToMarkdown.new(ARGV)
|
17
|
+
end
|
18
|
+
end # main
|
19
|
+
|
20
|
+
def initialize(*args)
|
21
|
+
data = load(*args) # Get the Content
|
22
|
+
parsed_content = parse_file(data) # Load the YAML front matter
|
23
|
+
mixed_content = mixing_in(parsed_content[0], parsed_content[1]) # Run the Mixins
|
24
|
+
headed_content = headers_on(mixed_content[0], mixed_content[1]) # Run the Headers
|
25
|
+
file = write_it( headed_content ) # Write the file
|
22
26
|
end
|
23
27
|
|
24
28
|
private
|
25
29
|
# ----------------------
|
26
30
|
# | Step 1 |
|
27
31
|
# ----------------------
|
28
|
-
# Parse Options & Load File
|
32
|
+
# Parse Options & Load File
|
29
33
|
def load(*args)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
# op.parse!(ARGV)
|
50
|
-
|
51
|
-
# # Example code for dealing with multiple filenames -- but don't think we want to do this.
|
52
|
-
# ARGV.each{ |fn| output_file(OPTS, fn) }
|
53
|
-
|
54
|
-
# Load Source File
|
55
|
-
@filename = ARGV[-1]
|
56
|
-
source_file = File::read(@filename) if File::exists?(@filename) && File::readable?(@filename)
|
57
|
-
return [source_file, '']
|
34
|
+
@output_file = ARGV[-1]
|
35
|
+
@input_file = ARGV[-2] ? ARGV[-2] : ARGV[-1]
|
36
|
+
begin
|
37
|
+
if @output_file != "-" && @input_file != "-"
|
38
|
+
source_file = File::read(@input_file) if File::exists?(@input_file) && File::readable?(@input_file)
|
39
|
+
elsif @input_file == "-"
|
40
|
+
source_file = STDIN.read
|
41
|
+
end
|
42
|
+
source_file.scan(/(@include (.+)$)/).each do |set|
|
43
|
+
partial_file = set[1]
|
44
|
+
to_replace = set[0]
|
45
|
+
partial_contents = File::read(partial_file) if File::exists?(partial_file) && File::readable?(partial_file)
|
46
|
+
source_file.gsub!(to_replace, partial_contents)
|
47
|
+
end
|
48
|
+
return source_file
|
49
|
+
rescue => e
|
50
|
+
puts "Sorry, I could not read the input file #{@input_file}: #{e.message}."
|
51
|
+
exit 0
|
52
|
+
end
|
58
53
|
end
|
59
54
|
|
60
55
|
# ----------------------
|
@@ -65,17 +60,18 @@ module LegalMarkdown
|
|
65
60
|
def parse_file(source)
|
66
61
|
begin
|
67
62
|
yaml_pattern = /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
68
|
-
|
69
|
-
|
70
|
-
|
63
|
+
parts = source.partition( yaml_pattern )
|
64
|
+
if parts[1] != ""
|
65
|
+
headers = YAML.load(parts[1])
|
66
|
+
content = parts[2]
|
71
67
|
else
|
72
|
-
|
68
|
+
headers = {}
|
73
69
|
content = source
|
74
70
|
end
|
75
|
-
rescue => e
|
76
|
-
puts "
|
71
|
+
rescue => e
|
72
|
+
puts "Sorry, something went wrong when I was loading the YAML front matter: #{e.message}."
|
77
73
|
end
|
78
|
-
return [
|
74
|
+
return [headers, content]
|
79
75
|
end
|
80
76
|
|
81
77
|
# ----------------------
|
@@ -88,20 +84,20 @@ module LegalMarkdown
|
|
88
84
|
def clauses_mixins( mixins, content )
|
89
85
|
clauses_to_delete = []
|
90
86
|
clauses_to_mixin = []
|
91
|
-
|
87
|
+
|
92
88
|
mixins.each do | mixin, replacer |
|
93
89
|
replacer = replacer.to_s.downcase
|
94
90
|
clauses_to_delete << mixin if replacer == "false"
|
95
91
|
clauses_to_mixin << mixin if replacer == "true"
|
96
92
|
end
|
97
|
-
|
93
|
+
|
98
94
|
clauses_to_delete.each { |m| mixins.delete(m) }
|
99
95
|
clauses_to_mixin.each { |m| mixins.delete(m) }
|
100
96
|
|
101
97
|
until clauses_to_delete.size == 0
|
102
98
|
clauses_to_delete.each do | mixin |
|
103
|
-
pattern = /(\[{{#{mixin}}}\s
|
104
|
-
sub_pattern = /\[{{(\S
|
99
|
+
pattern = /(\[{{#{mixin}}}\s*?)(.*?\n*?)(\])/m
|
100
|
+
sub_pattern = /\[{{(\S+?)}}\s*?/
|
105
101
|
content[pattern]
|
106
102
|
get_it_all = $& || ""
|
107
103
|
sub_clause = $2 || ""
|
@@ -113,8 +109,8 @@ module LegalMarkdown
|
|
113
109
|
|
114
110
|
until clauses_to_mixin.size == 0
|
115
111
|
clauses_to_mixin.each do | mixin |
|
116
|
-
pattern = /(\[{{#{mixin}}}\s
|
117
|
-
sub_pattern =
|
112
|
+
pattern = /(\[{{#{mixin}}}\s*?)(.*?\n*?)(\])/m
|
113
|
+
sub_pattern = /\[{{(\S+?)}}\s*?/
|
118
114
|
content[pattern]
|
119
115
|
get_it_all = $& || ""
|
120
116
|
sub_clause = $2 || ""
|
@@ -124,297 +120,297 @@ module LegalMarkdown
|
|
124
120
|
end
|
125
121
|
end
|
126
122
|
|
127
|
-
return [
|
123
|
+
return [ mixins, content ]
|
128
124
|
end
|
129
125
|
|
130
|
-
def
|
126
|
+
def text_mixins( mixins, content )
|
131
127
|
mixins.each do | mixin, replacer |
|
132
128
|
unless mixin =~ /level-\d/ or mixin =~ /no-reset/ or mixin =~ /no-indent/
|
133
129
|
replacer = replacer.to_s
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
content = content.gsub( $1, replacer )
|
138
|
-
mixins.delete( mixin ) unless safe_words.any?{ |s| s.casecmp(mixin) == 0 }
|
139
|
-
end
|
130
|
+
mixin_pattern = /({{#{mixin}}})/
|
131
|
+
content = content.gsub( $1, replacer ) if content =~ mixin_pattern
|
132
|
+
mixins.delete( mixin )
|
140
133
|
end
|
141
134
|
end
|
142
|
-
return [
|
135
|
+
return [ mixins, content ]
|
143
136
|
end
|
144
137
|
|
145
138
|
clauses_mixed = clauses_mixins( mixins, content )
|
146
|
-
|
147
|
-
|
139
|
+
fully_mixed = text_mixins( clauses_mixed[0], clauses_mixed[1] )
|
140
|
+
fully_mixed[1].gsub!(/(\n\n+)/, "\n\n")
|
141
|
+
return [ fully_mixed[0], fully_mixed[1] ]
|
148
142
|
end
|
149
143
|
|
150
144
|
# ----------------------
|
151
145
|
# | Step 4 |
|
152
146
|
# ----------------------
|
153
|
-
# Special YAML fields
|
154
|
-
|
155
|
-
def pandoc_title_block( headers )
|
156
|
-
title_block = ""
|
157
|
-
headers.each do | header |
|
158
|
-
if header[0].casecmp("title") == 0
|
159
|
-
title_block << "% " + header[1] + "\n"
|
160
|
-
headers.delete( header )
|
161
|
-
elsif header[0].casecmp("author") == 0
|
162
|
-
title_block << "% " + header[1] + "\n"
|
163
|
-
headers.delete( header )
|
164
|
-
elsif header[0].casecmp("date") == 0
|
165
|
-
title_block << "% " + header[1] + "\n\n"
|
166
|
-
headers.delete( header )
|
167
|
-
end
|
168
|
-
end
|
169
|
-
return title_block
|
170
|
-
end
|
171
|
-
|
172
|
-
# ----------------------
|
173
|
-
# | Step 5 |
|
174
|
-
# ----------------------
|
175
147
|
# Headers
|
176
148
|
|
177
149
|
def headers_on( headers, content )
|
178
150
|
|
151
|
+
def set_the_subs_arrays( value )
|
152
|
+
# takes a core value from the hash pulled from the yaml
|
153
|
+
# returns an array with a type symbol and a precursor string
|
154
|
+
if value =~ /([IVXLCDM]+)\.\z/ # type1 : {{ I. }}
|
155
|
+
return[:type1, value.delete($1 + "."), "", $1, "."]
|
156
|
+
elsif value =~ /\(([IVXLCDM]+)\)\z/ # type2 : {{ (I) }}
|
157
|
+
return[:type2, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
158
|
+
elsif value =~ /([ivxlcdm]+)\.\z/ # type3 : {{ i. }}
|
159
|
+
return[:type3, value.delete($1 + "."), "", $1, "."]
|
160
|
+
elsif value =~ /\(([ivxlcdm]+)\)\z/ # type4 : {{ (i) }}
|
161
|
+
return[:type4, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
162
|
+
elsif value =~ /([A-Z]+)\.\z/ # type5 : {{ A. }}
|
163
|
+
return[:type5, value.delete($1 + "."), "", $1, "."]
|
164
|
+
elsif value =~ /\(([A-Z]+)\)\z/ # type6 : {{ (A) }}
|
165
|
+
return[:type6, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
166
|
+
elsif value =~ /([a-z]+)\.\z/ # type7 : {{ a. }}
|
167
|
+
return[:type7, value.delete($1 + "."), "", $1, "."]
|
168
|
+
elsif value =~ /\(([a-z]+)\)\z/ # type8 : {{ (a) }}
|
169
|
+
return[:type8, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
170
|
+
elsif value =~ /\((\d+)\)\z/ # type9 : {{ (1) }}
|
171
|
+
return[:type9, value.delete("(" + $1 + ")"), "(", $1, ")"]
|
172
|
+
else value =~ /(\d+)\.\z/ # type0 : {{ 1. }} ... also default
|
173
|
+
return[:type0, value.delete($1 + "."), "", $1, "."]
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
179
177
|
def get_the_substitutions( headers )
|
180
|
-
# find the headers in the remaining YAML
|
178
|
+
# find the headers in the remaining YAML
|
181
179
|
# parse out the headers into level-X and pre-X headers
|
182
180
|
# then combine them into a coherent package
|
183
181
|
# returns a hash with the keys as the l., ll. searches
|
184
|
-
# and the values as the replacements in the form of
|
185
|
-
# an array where the first value is a symbol and the
|
182
|
+
# and the values as the replacements in the form of
|
183
|
+
# an array where the first value is a symbol and the
|
186
184
|
# second value is the precursor
|
187
185
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
return[:type4, value[0..-4]]
|
199
|
-
elsif value =~ /[A-Z]\.\z/ # type5 : {{ A. }}
|
200
|
-
return[:type5, value[0..-3]]
|
201
|
-
elsif value =~ /\([A-Z]\)\z/ # type6 : {{ (A) }}
|
202
|
-
return[:type6, value[0..-4]]
|
203
|
-
elsif value =~ /[a-z]\.\z/ # type7 : {{ a. }}
|
204
|
-
return[:type7, value[0..-3]]
|
205
|
-
elsif value =~ /\([a-z]\)\z/ # type8 : {{ (a) }}
|
206
|
-
return[:type8, value[0..-4]]
|
207
|
-
elsif value =~ /\(\d\)\z/ # type9 : {{ (1) }}
|
208
|
-
return[:type9, value[0..-4]]
|
209
|
-
else value =~ /\d\.\z/ # type0 : {{ 1. }} ... also default
|
210
|
-
return[:type0, value[0..-3]]
|
211
|
-
end
|
186
|
+
# @substitutions hash example
|
187
|
+
# {"ll." || "l2."=>[:type8, "Article ", "(", "1", ")", :no_reset || nil, " ", :preval || :pre || nil]}
|
188
|
+
|
189
|
+
@substitutions = {}
|
190
|
+
headers["level-style"] == "l1." ? @deep_leaders = true : @deep_leaders = false
|
191
|
+
if headers.has_key?("no-indent")
|
192
|
+
no_indent_array = headers["no-indent"].split(", ")
|
193
|
+
no_indent_array.include?("l." || "l1.") ? @offset = no_indent_array.size : @offset = no_indent_array.size + 1
|
194
|
+
else
|
195
|
+
@offset = 1
|
212
196
|
end
|
213
197
|
|
214
|
-
substitutions = {}
|
215
198
|
headers.each do | header, value |
|
216
|
-
if
|
217
|
-
|
218
|
-
|
219
|
-
search =
|
220
|
-
# substitutions hash example {"ll."=>[:type8,"Article"],}
|
221
|
-
substitutions[search]= set_the_subs_arrays(value.to_s)
|
199
|
+
if @deep_leaders
|
200
|
+
search = "l" + header[-1] + "." if header =~ /level-\d/
|
201
|
+
else
|
202
|
+
search = "l" * header[-1].to_i + "." if header =~ /level-\d/
|
222
203
|
end
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
204
|
+
|
205
|
+
if header =~ /level-\d/
|
206
|
+
@substitutions[search]= set_the_subs_arrays(value.to_s)
|
207
|
+
@deep_leaders ? spaces = (search[1].to_i - @offset) : spaces = (search.size - @offset - 1)
|
208
|
+
spaces < 0 ? spaces = 0 : spaces = spaces * 2
|
209
|
+
@substitutions[search][6] = " " * spaces
|
210
|
+
if value =~ /\s*preval\s*/
|
211
|
+
@substitutions[search][1].gsub!(/preval\s*/, "")
|
212
|
+
@substitutions[search][7] = :preval
|
213
|
+
elsif value =~ /\s*pre\s*/
|
214
|
+
@substitutions[search][1].gsub!(/pre\s*/, "")
|
215
|
+
@substitutions[search][7] = :pre
|
216
|
+
end
|
230
217
|
end
|
231
218
|
end
|
232
219
|
|
233
|
-
|
220
|
+
no_subs_array = headers["no-reset"].split(", ")
|
221
|
+
no_subs_array.each{ |e| @substitutions[e][5] = :no_reset unless e == "l." || e == "l1."}
|
222
|
+
|
223
|
+
return @substitutions
|
234
224
|
end
|
235
225
|
|
236
226
|
def find_the_block( content )
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
227
|
+
block_pattern = /(^```+\s*\n?)(.*?\n?)(^```+\s*\n?)/m
|
228
|
+
parts = content.partition( block_pattern )
|
229
|
+
if parts[1] != ""
|
230
|
+
block = $2.chomp
|
231
|
+
content = parts[0] + "{{block}}" + parts[2]
|
232
|
+
else
|
233
|
+
block = ""
|
234
|
+
content = content
|
243
235
|
end
|
244
|
-
return[ block, content ]
|
236
|
+
return [ block, content ]
|
245
237
|
end
|
246
238
|
|
247
|
-
def chew_on_the_block(
|
239
|
+
def chew_on_the_block( old_block )
|
248
240
|
# takes a hash of substitutions to make from the #get_the_substitutions method
|
249
241
|
# and a block of text returned from the #find_the_block method
|
250
242
|
# iterates over the block to make the appropriate substitutions
|
251
243
|
# returns a block of text
|
252
244
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
elsif
|
268
|
-
|
269
|
-
return value
|
270
|
-
elsif value[0] == :type6 # :type6 : {{ (A) }}
|
271
|
-
value[2..4] = [ "(", "A", ")"]
|
272
|
-
return value
|
273
|
-
elsif value[0] == :type7 # :type7 : {{ a. }}
|
274
|
-
value[2..4] = [ "", "a", "."]
|
275
|
-
return value
|
276
|
-
elsif value[0] == :type8 # :type8 : {{ (a) }}
|
277
|
-
value[2..4] = [ "(", "a", ")"]
|
278
|
-
return value
|
279
|
-
elsif value[0] == :type9 # :type9 : {{ (1) }}
|
280
|
-
value[2..4] = [ "(", "1", ")"]
|
281
|
-
return value
|
282
|
-
else value[0] == :type0 # :type0 : {{ 1. }} ... also default
|
283
|
-
value[2..4] = [ "", 1, "."]
|
284
|
-
return value
|
245
|
+
# method will take the old_block and iterate through the lines.
|
246
|
+
# First it will find the leading indicator. Then it will
|
247
|
+
# find the appropriate substitution from the @substitutions
|
248
|
+
# hash. After that it will rebuild the leading matter from the
|
249
|
+
# sub hash. It will drop markers if it is going down the tree.
|
250
|
+
# It will reset the branches if it is going up the tree.
|
251
|
+
# sub_it is an array w/ type[0] & lead_string[1] & id's[2..4]
|
252
|
+
|
253
|
+
# @substitutions hash example
|
254
|
+
# {"ll."OR "l2."=>[:type8, "Article ", "(", "1", ")", :no_reset || nil, :no_indent || nil, :preval || :pre || nil],}
|
255
|
+
|
256
|
+
def romans_takedown( array_to_sub )
|
257
|
+
if array_to_sub[0] == :type1 || array_to_sub[0] == :type2
|
258
|
+
@r_u = true
|
259
|
+
elsif array_to_sub[0] == :type3 || array_to_sub[0] == :type4
|
260
|
+
@r_l = true
|
285
261
|
end
|
262
|
+
if @r_l || @r_u
|
263
|
+
array_to_sub[3] = RomanNumerals.to_decimal_string(array_to_sub[3])
|
264
|
+
end
|
265
|
+
return array_to_sub
|
286
266
|
end
|
287
267
|
|
288
|
-
def
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
downgrade_spaces = @no_indt_array.include?("l.") ? @no_indt_array.size - 1 : @no_indt_array.size
|
293
|
-
spaces = ( " " * ( (selector.size) - 2 - downgrade_spaces ) * 4 )
|
268
|
+
def romans_setup( array_to_sub )
|
269
|
+
if @r_l || @r_u
|
270
|
+
array_to_sub[3] = RomanNumerals.to_roman_upper(array_to_sub[3]) if @r_u
|
271
|
+
array_to_sub[3] = RomanNumerals.to_roman_lower(array_to_sub[3]) if @r_l
|
294
272
|
end
|
295
|
-
|
273
|
+
@r_l = false; @r_u = false
|
274
|
+
return array_to_sub
|
296
275
|
end
|
297
276
|
|
298
|
-
def increment_the_branch(
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
277
|
+
def increment_the_branch( array_to_sub, selector, next_selector )
|
278
|
+
if selector > next_selector #going up the tree and reset
|
279
|
+
selectors_to_reset = @substitutions.inject([]){ |m,(k,v)| m << k if k > next_selector; m }
|
280
|
+
selectors_to_reset.each do | this_selector |
|
281
|
+
substitutor = @substitutions[this_selector]
|
282
|
+
substitutor = romans_takedown( substitutor )
|
283
|
+
substitutor[3].next! if this_selector == selector
|
284
|
+
if substitutor[0] == :type5 || substitutor[0] == :type6
|
285
|
+
substitutor[3] = "A" unless substitutor[5] == :no_reset
|
286
|
+
elsif substitutor[0] == :type7 || substitutor[0] == :type8
|
287
|
+
substitutor[3] = "a" unless substitutor[5] == :no_reset
|
288
|
+
else
|
289
|
+
substitutor[3] = "1" unless substitutor[5] == :no_reset
|
290
|
+
end
|
291
|
+
substitutor = romans_setup( substitutor )
|
292
|
+
@substitutions[this_selector]= substitutor
|
307
293
|
end
|
294
|
+
array_to_sub = @substitutions[selector]
|
295
|
+
else #not going up tree
|
296
|
+
array_to_sub = romans_takedown( array_to_sub )
|
297
|
+
array_to_sub[3].next!
|
298
|
+
array_to_sub = romans_setup( array_to_sub )
|
308
299
|
end
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
array_to_sub[3] = array_to_sub[3].downcase
|
300
|
+
|
301
|
+
return array_to_sub
|
302
|
+
end
|
303
|
+
|
304
|
+
def get_selector_above( selector )
|
305
|
+
if @deep_leaders
|
306
|
+
selector_above = "l" + (selector[1].to_i-1).to_s + "."
|
307
|
+
selector_above = "l1." if selector_above == "l0."
|
308
|
+
else
|
309
|
+
selector_above = selector[1..-1]
|
310
|
+
selector_above = "l." if selector_above == "."
|
321
311
|
end
|
322
|
-
|
323
|
-
return hash_of_subs
|
312
|
+
return selector_above
|
324
313
|
end
|
325
314
|
|
326
|
-
def
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
hash_of_subs[leader]= get_the_subs_arrays(hash_of_subs[leader])
|
336
|
-
hash_of_subs[leader]= pre_setup(hash_of_subs[leader])
|
337
|
-
end
|
338
|
-
end
|
315
|
+
def find_parent_reference( selector_above )
|
316
|
+
leading_prov = @substitutions[selector_above].clone
|
317
|
+
leading_prov = romans_takedown( leading_prov )
|
318
|
+
if leading_prov[0] == :type5 || leading_prov[0] == :type6
|
319
|
+
leading_prov[3] = leading_prov[3][0..-2] + (leading_prov[3][-1].ord-1).chr
|
320
|
+
elsif leading_prov[0] == :type7 || leading_prov[0] == :type8
|
321
|
+
leading_prov[3] = leading_prov[3][0..-2] + (leading_prov[3][-1].ord-1).chr
|
322
|
+
else
|
323
|
+
leading_prov[3] = (leading_prov[3].to_i-1).to_s
|
339
324
|
end
|
340
|
-
|
325
|
+
leading_prov = romans_setup( leading_prov )
|
326
|
+
return leading_prov
|
341
327
|
end
|
342
328
|
|
343
|
-
def
|
344
|
-
array_to_sub
|
345
|
-
|
329
|
+
def preval_substitution( array_to_sub, selector )
|
330
|
+
array_to_sub.pop unless array_to_sub.last == :preval
|
331
|
+
selector_above = get_selector_above( selector )
|
332
|
+
leading_prov = find_parent_reference( selector_above )[3]
|
333
|
+
trailing_prov = array_to_sub[3].clone
|
334
|
+
trailing_prov.prepend("0") if trailing_prov.size == 1
|
335
|
+
array_to_sub << array_to_sub[2] + leading_prov.to_s + trailing_prov.to_s + array_to_sub[4]
|
336
|
+
array_to_sub.last.gsub!($1, "(") if array_to_sub.last[/(\.\()/]
|
346
337
|
return array_to_sub
|
347
338
|
end
|
348
339
|
|
349
|
-
def
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
log_the_line( new_block, selector, line, sub_it )
|
376
|
-
leader_before = sub_it[1..4].join
|
377
|
-
if selector_before > selector # We are going up the tree.
|
378
|
-
substitutions = reset_the_sub_branches(substitutions, sub_it, selector)
|
379
|
-
else # We are at the same level.
|
380
|
-
substitutions = increment_the_branch(substitutions, sub_it, selector)
|
381
|
-
end
|
382
|
-
selector_before = selector
|
340
|
+
def pre_substitution( array_to_sub, selector )
|
341
|
+
array_to_sub.pop unless array_to_sub.last == :pre
|
342
|
+
selector_above = get_selector_above( selector )
|
343
|
+
leading_prov = @substitutions[selector_above][8] || find_parent_reference( selector_above )[2..4].join
|
344
|
+
trailing_prov = array_to_sub[2..4].join
|
345
|
+
array_to_sub << leading_prov + trailing_prov
|
346
|
+
array_to_sub.last.gsub!($1, "(") if array_to_sub.last[/(\.\()/]
|
347
|
+
return array_to_sub
|
348
|
+
end
|
349
|
+
|
350
|
+
cross_references = {}
|
351
|
+
arrayed_block = []
|
352
|
+
old_block.each_line do |line|
|
353
|
+
next if line[/^\s*\n/]
|
354
|
+
line[/(^l+\.)\s*(\|.*?\|)*\s*(.*)$/] ? arrayed_block << [$1, $3, $2] : arrayed_block.last[1] << ("\n" + line.rstrip)
|
355
|
+
end
|
356
|
+
old_block = "" # for large files
|
357
|
+
|
358
|
+
new_block = arrayed_block.inject("") do |block, arrayed_line|
|
359
|
+
|
360
|
+
selector = arrayed_line[0]
|
361
|
+
next_selector = ( arrayed_block[arrayed_block.index(arrayed_line)+1] || arrayed_block.last ).first
|
362
|
+
sub_it = @substitutions[selector]
|
363
|
+
|
364
|
+
if arrayed_line[1] =~ /\n/
|
365
|
+
arrayed_line[1].gsub!("\n", "\n\n" + sub_it[6])
|
383
366
|
end
|
384
|
-
|
367
|
+
|
368
|
+
if sub_it[7] == :preval
|
369
|
+
sub_it = preval_substitution(sub_it, selector)
|
370
|
+
reference = sub_it.last
|
371
|
+
elsif sub_it[7] == :pre
|
372
|
+
sub_it = pre_substitution(sub_it, selector)
|
373
|
+
reference = sub_it.last
|
374
|
+
else
|
375
|
+
reference = sub_it[2..4].join
|
376
|
+
end
|
377
|
+
|
378
|
+
block << sub_it[6] + sub_it[1] + reference + " " + arrayed_line[1] + "\n\n"
|
379
|
+
cross_references[arrayed_line[2]]= sub_it[1] + reference if arrayed_line[2]
|
380
|
+
@substitutions[selector]= increment_the_branch(sub_it, selector, next_selector)
|
381
|
+
|
382
|
+
block
|
385
383
|
end
|
386
384
|
|
387
|
-
|
388
|
-
new_block
|
385
|
+
cross_references.each_key{|k| new_block.gsub!(k, cross_references[k]) }
|
386
|
+
return new_block
|
389
387
|
end
|
390
388
|
|
391
389
|
headers = get_the_substitutions( headers )
|
392
|
-
|
393
|
-
block =
|
394
|
-
not_the_block =
|
395
|
-
|
390
|
+
block_found = find_the_block( content )
|
391
|
+
block = block_found[0]
|
392
|
+
not_the_block = block_found[1]
|
393
|
+
block_found = "" # for long documents
|
396
394
|
|
397
|
-
if block ==
|
395
|
+
if block == ""
|
398
396
|
block_redux = ""
|
399
|
-
elsif headers == {}
|
397
|
+
elsif headers == {}
|
400
398
|
block_redux = block
|
401
399
|
else
|
402
|
-
block_redux = chew_on_the_block(
|
400
|
+
block_redux = chew_on_the_block( block )
|
403
401
|
end
|
404
|
-
|
405
|
-
headed = not_the_block.gsub("{{block}}", block_redux )
|
402
|
+
headed = not_the_block.gsub("{{block}}", block_redux )
|
406
403
|
end
|
407
404
|
|
408
405
|
# ----------------------
|
409
406
|
# | Step 6 |
|
410
407
|
# ----------------------
|
411
|
-
# Write the file
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
end
|
408
|
+
# Write the file
|
409
|
+
def write_it( final_content )
|
410
|
+
if @output_file && @output_file != "-"
|
411
|
+
File.open(@output_file, "w") {|f| f.write( final_content ) }
|
412
|
+
else
|
413
|
+
STDOUT.write final_content
|
418
414
|
end
|
419
415
|
end
|
420
416
|
end
|