legal_markdown 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|