5b1f8f614981ef871e05822e78913fd1c4080ae3
[software/sisu] / lib / sisu / ao_doc_str.rb
1 # encoding: utf-8
2 =begin
3
4 * Name: SiSU
5
6 ** Description: documents, structuring, processing, publishing, search
7 *** document abstraction
8
9 ** Author: Ralph Amissah
10 [ralph@amissah.com]
11 [ralph.amissah@gmail.com]
12
13 ** Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
14 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Ralph Amissah,
15 All Rights Reserved.
16
17 ** License: GPL 3 or later:
18
19 SiSU, a framework for document structuring, publishing and search
20
21 Copyright (C) Ralph Amissah
22
23 This program is free software: you can redistribute it and/or modify it
24 under the terms of the GNU General Public License as published by the Free
25 Software Foundation, either version 3 of the License, or (at your option)
26 any later version.
27
28 This program is distributed in the hope that it will be useful, but WITHOUT
29 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
30 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
31 more details.
32
33 You should have received a copy of the GNU General Public License along with
34 this program. If not, see [http://www.gnu.org/licenses/].
35
36 If you have Internet connection, the latest version of the GPL should be
37 available at these locations:
38 [http://www.fsf.org/licensing/licenses/gpl.html]
39 [http://www.gnu.org/licenses/gpl.html]
40
41 ** SiSU uses:
42 * Standard SiSU markup syntax,
43 * Standard SiSU meta-markup syntax, and the
44 * Standard SiSU object citation numbering and system
45
46 ** Hompages:
47 [http://www.jus.uio.no/sisu]
48 [http://www.sisudoc.org]
49
50 ** Git
51 [http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=summary]
52 [http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=blob;f=lib/sisu/ao_doc_str.rb;hb=HEAD]
53
54 =end
55 module SiSU_AO_DocumentStructureExtract
56 require_relative 'ao_persist' # ao_persist.rb
57 class Instantiate < SiSU_Param::Parameters::Instructions
58 def initialize
59 @@counter=@@column=@@columns=0
60 @@line_mode=''
61 end
62 end
63 class Build
64 def initialize(md,data)
65 @md,@data=md,data
66 SiSU_AO_DocumentStructureExtract::Instantiate.new
67 @pb=SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page])
68 @pbn=SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_new])
69 @pbl=SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_line])
70 @per=SiSU_AO_Persist::PersistDocStructExt.new
71 @make=SiSU_Env::ProcessingSettings.new(@md)
72 end
73 def ln_get(lv)
74 case lv
75 when /A/ then 0
76 when /B/ then 1
77 when /C/ then 2
78 when /D/ then 3
79 when /1/ then 4
80 when /2/ then 5
81 when /3/ then 6
82 when /4/ then 7
83 when /5/ then 8
84 when /6/ then 9
85 end
86 end
87 def image_test(str)
88 str=~/\{\s*\S+?\.png.+?\}https?:\/\/\S+/ \
89 ? true
90 : false
91 end
92 def bullet_test(str)
93 (str=~/\*/) \
94 ? true
95 : false
96 end
97 def quotes?
98 @per.quote==:open \
99 ? true
100 : false
101 end
102 def hang_and_indent_test(str)
103 hang_indent=if str=~/^_([1-9])[^_]/
104 [$1,$1]
105 elsif str=~/^__([1-9])/
106 [0,$1]
107 elsif str=~/^_([0-9])_([0-9])/
108 [$1,$2]
109 else
110 [0,0]
111 end
112 hang,indent=hang_indent[0],hang_indent[1]
113 [hang,indent]
114 end
115 def hang_and_indent_def_test(str1,str2)
116 hang_indent=if str1=~/^_([1-9])[^_]/
117 [$1,$1]
118 elsif str1=~/^__([1-9])/
119 [0,$1]
120 elsif str1=~/^_([0-9])_([0-9])/
121 [$1,$2]
122 else
123 [0,0]
124 end
125 obj=if str2 =~/^(.+?)\s+\\\\(?:\s+|\n)/
126 str2.gsub(/^(.+?)(\s+\\\\(?:\s+|\n))/,
127 "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\\2")
128 else
129 str2.gsub(/^(.+?)\n/,
130 "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\n")
131 end
132 hang,indent=hang_indent[0],hang_indent[1]
133 [
134 hang,
135 indent,
136 obj,
137 ]
138 end
139 def endnote_test?(str)
140 (str=~/~\{.+?\}~|~\[.+?\]~/) \
141 ? true
142 : false
143 end
144 def extract_tags(str,nametag=nil)
145 tags=[]
146 if str.nil?
147 else
148 if str =~/(?:^|[ ])\*~([a-z0-9._-]+)(?=[ #{Mx[:br_nl]}]|$)/
149 str=str.gsub(/(^|[ ])\*~([a-z0-9._-]+)(?=[ #{Mx[:br_nl]}]|$)/i,
150 "\\1#{Mx[:tag_o]}\\2#{Mx[:tag_c]}").
151 gsub(/ [ ]+/i,' ')
152 tags=str.scan(/#{Mx[:tag_o]}(\S+?)#{Mx[:tag_c]}/).flatten.uniq
153 str=str.gsub(/[ ]?#{Mx[:tag_o]}\S+?#{Mx[:tag_c]}[ ]?/,' ') #may be issues with spaces would leave one, but "code" blocks?
154 end
155 tags=nametag ? (tags << nametag) : tags
156 tags.each do |t|
157 t.gsub!(/[^a-z0-9._-]/,'')
158 end
159 end
160 [
161 str,
162 tags,
163 ]
164 end
165 def rgx_idx_ocn_seg
166 @rgx_idx_ocn_seg=/(.+?)\s*[+](\d+)/
167 end
168 def construct_idx_array_and_hash(idxraw)
169 idx_array_raw=idxraw.scan(/[^;]+/)
170 idx_hash,idx_array,idx_lst={},[],[]
171 idx_array_raw.each do |idx|
172 idx=idx.strip
173 idx_lst=case idx
174 when /\S+?\s*:/
175 idx_couplet_tmp=[]
176 idx_couplet=idx.scan(/\s*[^:]+\s*/)
177 if idx_couplet[1] =~/[|]/
178 idx_couplet_tmp <<
179 idx_couplet[0] <<
180 idx_couplet[1].scan(/\s*[^|]+\s*/)
181 else
182 idx_couplet_tmp <<
183 idx_couplet[0] <<
184 [idx_couplet[1]]
185 end
186 idx_couplet=idx_couplet_tmp
187 else [idx]
188 end
189 term_nodes=[]
190 idx_lst.each do |term_node|
191 case term_node
192 when String
193 term_node=
194 term_node[0].chr.capitalize +
195 term_node[1,term_node.length]
196 term_node=(term_node =~/.+?[+]\d+/) \
197 ? term_node
198 : (term_node + '+0')
199 term_nodes << term_node
200 use,plus=rgx_idx_ocn_seg.match(term_node)[1,2]
201 @use=use.strip
202 unless idx_hash[@use] \
203 and defined? idx_hash[@use]
204 idx_hash[@use]=
205 { sub: [], plus: plus }
206 end
207 when Array
208 subterm_nodes=[]
209 term_node.each do |subterm_node|
210 subterm_node=(subterm_node =~/.+?[+]\d+/) \
211 ? subterm_node
212 : (subterm_node + '+0')
213 subterm_nodes << subterm_node
214 sub,sub_plus=rgx_idx_ocn_seg.match(subterm_node)[1,2]
215 unless idx_hash[@use] \
216 and defined? idx_hash[@use]
217 idx_hash[@use]=
218 { sub: [], plus: 0 }
219 end
220 idx_hash[@use][:sub] <<
221 { sub.strip => { plus: sub_plus } }
222 end
223 term_nodes << subterm_nodes
224 end
225 end
226 idx_array << term_nodes
227 end
228 {
229 hash: idx_hash,
230 array: idx_array,
231 }
232 end
233 def extract_structure_loop(data,tuned_file)
234 data.each do |t_o|
235 if t_o =~/^--([+~-])[#]$/
236 h=case $1
237 when /[+]/
238 @per.ocn=:on
239 {
240 flag: :ocn_on,
241 }
242 when /[~]/
243 @per.ocn=:ocn_off_headings_keep
244 {
245 flag: :ocn_off,
246 mod: :headings_keep,
247 }
248 when /[-]/ #of particular relevance with level 1~ which is required to precede substantive text & used e.g. in html segmented text
249 @per.ocn=:ocn_off_headings_dummy_lev1
250 {
251 flag: :ocn_off,
252 mod: :headings_exclude,
253 }
254 else
255 @per.ocn=:on
256 {
257 flag: :ocn_on,
258 }
259 end
260 t_o=SiSU_AO_DocumentStructure::ObjectFlag.new.flag_ocn(h)
261 next
262 end
263 if t_o =~/^:[~](#{SiSU_is.language_list_regex?}|-)$/ # work with for identifying language of objects
264 lng=$1
265 h=case lng
266 when /(?:#{SiSU_is.language_list_regex?})/
267 @per.lng=:on
268 @per.lng_is=lng.to_sym
269 {
270 flag: :lng_on,
271 act: lng.to_sym,
272 }
273 else # ^:~-
274 if @per.lng==:on
275 @per.lng=:off
276 @per.lng_is=:doc_default
277 {
278 flag: :lng_off,
279 act: :doc_default,
280 }
281 end
282 end
283 t_o=SiSU_AO_DocumentStructure::ObjectFlag.new.flag_lng(h)
284 next
285 end
286 t_o=t_o.gsub(/(?:\n\s*\n)+/m,"\n") if @per.code==:off
287 unless t_o =~/^(?:@\S+?:|%+)\s/ # extract book index for paragraph if any
288 idx=if t_o=~/^=\{\s*(.+)\s*\}\s*$\Z/m
289 m=$1
290 m=m.split(/[ ]*\n/).join(' ').
291 gsub(/\s+([|:;])\s+/,'\1').
292 gsub(/\s+([+]\d+)\s+/,'\1')
293 t_o=t_o.gsub(/\n=\{.+?\}\s*$/m,'')
294 idx_array_and_hash=construct_idx_array_and_hash(m)
295 idx_array_and_hash[:hash]
296 else nil
297 end
298 end
299 if t_o !~/^(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block)\{|^\}(?:code|poem|alt|group|block)|^(?:table\(.+?\)\{|\{table\()/ \
300 and t_o !~/^```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)|^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$|^`:quote_(?:open|close)`/ \
301 and @per.code==:off \
302 and @per.poem==:off \
303 and @per.group==:off \
304 and @per.block==:off \
305 and @per.alt==:off \
306 and @per.box==:off \
307 and @per.table==:off
308 t_o=case t_o
309 when /^#{Mx[:meta_o]}\S+?#{Mx[:meta_c]}/ #metadata, header
310 if t_o=~/^#{Mx[:meta_o]}(\S+?)#{Mx[:meta_c]}\s*(.+)/m
311 tag,obj=$1,$2
312 @metadata[tag]=obj
313 end
314 t_o=nil
315 when /^%+\s/ #comment
316 t_o=if t_o=~/^%+\s+(.+)/
317 h={ obj: $1 }
318 SiSU_AO_DocumentStructure::ObjectComment.new.comment(h)
319 else nil
320 end
321 when /^:?([A-D1-6])\~/ #heading / lv
322 lv=$1
323 ln=ln_get(lv)
324 t_o=if t_o=~/^:?[A-D1-6]\~\s+(.+)/m
325 obj=$1
326 note=endnote_test?(obj)
327 obj,tags=extract_tags(obj)
328 if @per.ocn==:ocn_off_headings_dummy_lev1 \
329 or @per.ocn==:ocn_off_headings_keep
330 unless obj =~ /[~-][#]\s*$/
331 if @per.ocn==:ocn_off_headings_dummy_lev1 \
332 and t_o =~/^1\~\S*\s+/m
333 obj << ' -#'
334 elsif @per.ocn==:ocn_off_headings_dummy_lev1 \
335 or @per.ocn==:ocn_off_headings_keep
336 obj << ' ~#'
337 end
338 end
339 end
340 h={
341 lv: lv,
342 ln: ln,
343 obj: obj,
344 idx: idx,
345 tags: tags,
346 }
347 SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h)
348 elsif t_o=~/^:?[A-D1-6]\~(\S+?)-\s+(.+)/m
349 name,obj=$1,$2
350 note=endnote_test?(obj)
351 obj,tags=extract_tags(obj)
352 if @per.ocn==:ocn_off_headings_dummy_lev1 \
353 or @per.ocn==:ocn_off_headings_keep
354 unless obj =~ /[~-][#]\s*$/
355 if @per.ocn==:ocn_off_headings_dummy_lev1 \
356 and t_o =~/^1\~\S*\s+/m
357 obj << ' -#'
358 elsif @per.ocn==:ocn_off_headings_dummy_lev1 \
359 or @per.ocn==:ocn_off_headings_keep
360 obj << ' ~#'
361 end
362 end
363 end
364 h={
365 lv: lv,
366 name: name,
367 obj: obj,
368 idx: idx,
369 autonum_: false,
370 tags: tags,
371 }
372 SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h)
373 elsif t_o=~/^:?[A-D1-6]\~(\S+)\s+(.+)/m
374 name,obj=$1,$2
375 note=endnote_test?(obj)
376 obj,tags=extract_tags(obj,name)
377 if @per.ocn==:ocn_off_headings_dummy_lev1 \
378 or @per.ocn==:ocn_off_headings_keep
379 unless obj =~ /[~-][#]\s*$/
380 if @per.ocn==:ocn_off_headings_dummy_lev1 \
381 and t_o =~/^1\~\S*\s+/m
382 obj << ' -#'
383 elsif @per.ocn==:ocn_off_headings_dummy_lev1 \
384 or @per.ocn==:ocn_off_headings_keep
385 obj << ' ~#'
386 end
387 end
388 end
389 h={
390 lv: lv,
391 name: name,
392 obj: obj,
393 idx: idx,
394 tags: tags,
395 }
396 SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h)
397 else nil
398 end
399 when /^_(?:[1-9]!?|[1-9]?\*)\s+/ #indented and/or bullet paragraph
400 t_o=if t_o=~/^(_(?:[1-9]?\*|[1-9]!?)\s+)(.+)/m
401 tst,obj=$1,$2
402 if t_o=~/^_[1-9]!\s+.+/m
403 hang,indent,obj=hang_and_indent_def_test(tst,obj)
404 else
405 hang,indent=hang_and_indent_test(tst)
406 end
407 bullet=bullet_test(tst)
408 image=image_test(obj)
409 note=endnote_test?(obj)
410 obj,tags=extract_tags(obj)
411 unless obj=~/\A\s*\Z/m
412 if @per.ocn==:ocn_off_headings_dummy_lev1 \
413 or @per.ocn==:ocn_off_headings_keep
414 unless obj =~ /[~-][#]\s*$/
415 obj << ' ~#'
416 end
417 end
418 h={
419 bullet_: bullet,
420 hang: hang,
421 indent: indent,
422 obj: obj,
423 idx: idx,
424 note_: note,
425 image_: image,
426 tags: tags,
427 quote: quotes?,
428 }
429 SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h)
430 end
431 else nil
432 end
433 when /^_[0-9]?_[0-9]!?\s+/ #hanging indent paragraph
434 t_o=if t_o=~/^(_[0-9]?_[0-9]!?\s+)(.+)/m
435 tst,obj=$1,$2
436 if t_o=~/^_[0-9]?_[0-9]!\s+.+/m
437 hang,indent,obj=hang_and_indent_def_test(tst,obj)
438 else
439 hang,indent=hang_and_indent_test(tst)
440 end
441 image=image_test(obj)
442 note=endnote_test?(obj)
443 obj,tags=extract_tags(obj)
444 unless obj=~/\A\s*\Z/m
445 if @per.ocn==:ocn_off_headings_dummy_lev1 \
446 or @per.ocn==:ocn_off_headings_keep
447 unless obj =~ /[~-][#]\s*$/
448 obj << ' ~#'
449 end
450 end
451 h={
452 hang: hang,
453 indent: indent,
454 obj: obj,
455 idx: idx,
456 note_: note,
457 image_: image,
458 tags: tags,
459 quote: quotes?,
460 }
461 SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h)
462 end
463 else nil
464 end
465 when /^<(?:br)?:(?:pa?r|o(?:bj|---)?)>\s*$/ #[br:par] #[br:obj]
466 SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_obj])
467 when /^(?:-\\\\-|<:pb>)\s*$/ #[br:pg]
468 SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page],:markup)
469 when /^(?:=\\\\=|<:pn>)\s*$/ #[br:pgn]
470 SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_new],:markup)
471 when /^-\.\.-\s*$/ #[br:pgl]
472 SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_line],:markup)
473 else #paragraph
474 image=image_test(t_o)
475 note=endnote_test?(t_o)
476 obj,tags=extract_tags(t_o)
477 if @per.ocn==:ocn_off_headings_dummy_lev1 \
478 or @per.ocn==:ocn_off_headings_keep
479 unless obj =~ /[~-][#]\s*$/
480 obj << ' ~#'
481 end
482 end
483 unless obj=~/\A\s*\Z/m
484 h={
485 bullet_: false,
486 indent: 0,
487 hang: 0,
488 obj: obj,
489 idx: idx,
490 note_: note,
491 image_: image,
492 tags: tags,
493 quote: quotes?,
494 }
495 t_o=SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h)
496 end
497 t_o=SiSU_AO_DocumentStructureExtract::Structure.new(@md).structure_markup(t_o) #must happen earlier, node info etc. require
498 end
499 elsif @per.code==:off
500 if t_o =~/^(?:code(?:\.[a-z][0-9a-z_]+)?\{|```[ ]+code(?:\.[a-z][0-9a-z_]+)?)/
501 @per.code=case t_o
502 when /^code(?:\.[a-z][0-9a-z_]+)?\{/ then :curls
503 when /^```[ ]+code/ then :tics
504 else @per.code #error
505 end
506 @per.lngsyn=if t_o =~/^(?:code\.[a-z][0-9a-z_]+\{|```[ ]+code\.[a-z_]+)/
507 case t_o
508 when /^code\.([a-z][0-9a-z_]+)\{/
509 :"#{$1}"
510 when /^```[ ]+code\.([a-z][0-9a-z_]+)/
511 :"#{$1}"
512 else :txt
513 end
514 else :txt
515 end
516 @@counter=1
517 @codeblock_numbered=
518 (t_o =~/^(?:code(?:\.[a-z][0-9a-z_]+)?\{#|```[ ]+code(?:\.[a-z][0-9a-z_]+)?\s[#])/) \
519 ? true
520 : false
521 @num_id[:code_block] +=1
522 h={
523 is_for: :code,
524 obj: '',
525 sym: :code_block_open,
526 num: @num_id[:code_block],
527 syntax: @per.lngsyn,
528 }
529 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
530 elsif t_o =~/^(?:poem\{|```[ ]+poem)/
531 @per.poem=case t_o
532 when /^poem\{/ then :curls
533 when /^```[ ]+poem/ then :tics
534 else @per.poem #error
535 end
536 @num_id[:poem] +=1
537 h={
538 is_for: :poem,
539 obj: '',
540 sym: :poem_open,
541 num: @num_id[:poem],
542 }
543 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
544 tuned_file << t_o
545 elsif t_o =~/^(?:box(?:\.[a-z_]+)?\{|```[ ]+box(?:\.[a-z_]+)?)/
546 @per.box=case t_o
547 when /^box\{/ then :curls
548 when /^```[ ]+box/ then :tics
549 else @per.box #error
550 end
551 @num_id[:box] +=1
552 h={
553 is_for: :box,
554 obj: '',
555 sym: :box_open,
556 num: @num_id[:box],
557 }
558 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
559 tuned_file << t_o
560 elsif t_o =~/^(?:group\{|```[ ]+group)/
561 @per.group=case t_o
562 when /^group\{/ then :curls
563 when /^```[ ]+group/ then :tics
564 else @per.group #error
565 end
566 @num_id[:group] +=1
567 h={
568 is_for: :group,
569 obj: '',
570 sym: :group_open,
571 num: @num_id[:group],
572 }
573 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
574 tuned_file << t_o
575 elsif t_o =~/^(?:block\{|```[ ]+block)/
576 @per.block=case t_o
577 when /^block\{/ then :curls
578 when /^```[ ]+block/ then :tics
579 else @per.block #error
580 end
581 @num_id[:block] +=1
582 h={
583 is_for: :block,
584 obj: '',
585 sym: :block_open,
586 num: @num_id[:block],
587 }
588 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
589 tuned_file << t_o
590 elsif t_o =~/^(?:alt\{|```[ ]+alt)/
591 @per.alt=case t_o
592 when /^alt\{/ then :curls
593 when /^```[ ]+alt/ then :tics
594 else @per.alt #error
595 end
596 @num_id[:alt] +=1
597 h={
598 is_for: :alt,
599 obj: '',
600 sym: :alt_open,
601 num: @num_id[:alt],
602 }
603 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
604 tuned_file << t_o
605 elsif t_o =~/^`:quote_open`/
606 @per.quote=:open
607 @num_id[:quote] +=1
608 h={
609 is_for: :quote,
610 obj: '',
611 sym: :quote_open,
612 num: @num_id[:quote],
613 }
614 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
615 #tuned_file << t_o #% find second source, entered twice, should be once so closed off here
616 elsif t_o =~/^(?:table\(.+?\)\{|```[ ]+table\(.+?\)|\{table\(.+?\))/
617 @num_id[:table] +=1
618 h={
619 is_for: :table,
620 obj: '',
621 sym: :table_open,
622 num: @num_id[:table],
623 }
624 ins_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
625 tuned_file << ins_o
626 if t_o=~/^table\((?:.*?\bh;\s+)?.+?\)\{/
627 @per.table=:curls
628 @rows=''
629 case t_o
630 when /table\(.*?\bh;\s+c(\d+):\s+(.+?)\)\{/
631 cols=$1
632 col=$2.scan(/\d+/)
633 heading=true
634 when /table\(.*?c(\d+):\s+(.+?)\)\{/
635 cols=$1
636 col=$2.scan(/\d+/)
637 heading=false
638 end
639 @h={
640 head_: heading,
641 cols: cols,
642 widths: col,
643 idx: idx,
644 }
645 elsif t_o=~/^```[ ]+table\((?:.*?\bh;)?\s+c\d+:/
646 @per.table=:tics
647 @rows=''
648 case t_o
649 when /^```[ ]+table\(.*?\bh;\s+c(\d+):\s+(.+?)\)/
650 cols=$1
651 col=$2.scan(/\d+/)
652 heading=true
653 when /^```[ ]+table\(\s*c(\d+):\s+(.+?)\)/
654 cols=$1
655 col=$2.scan(/\d+/)
656 heading=false
657 end
658 @h={
659 head_: heading,
660 cols: cols,
661 widths: col,
662 idx: idx,
663 }
664 elsif t_o=~/^\{table\((?:.*?\bh;\s+)?(?:\s+\d+,?)?\)\s*\}\n.+\Z/m
665 m1,m2,hd=nil,nil,nil
666 tbl=/^\{table\((?:.*?\bh;\s+)?(?:\s+\d+,?)*\)\s*\}\n(.+)\Z/m.match(t_o)[1] # fix
667 hd=((t_o =~/^\{table\(.*?\bh;\s+/) ? true : false)
668 tbl,tags=extract_tags(tbl)
669 rws=tbl.split(/\n/)
670 rows=''
671 cols=nil
672 rws.each do |r|
673 cols=(cols ? cols : (r.scan('|').length) +1)
674 r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}") #r.gsub!(/\|/m,"#{Mx[:tc_p]}")
675 rows += r + Mx[:tc_c]
676 end
677 col=[]
678 if t_o =~/^\{table\((?:.*?\bh;\s+)?\s+c(\d+):.*?\)\s*\}/ #width of col 1 given as %, usually when wider than rest that are even
679 c1=$1.to_i
680 width=(100 - c1)/(cols - 1)
681 col=[ c1 ]
682 (cols - 1).times { col << width }
683 else #all columns of equal width
684 width=100.00/cols
685 cols.times { col << width }
686 end
687 h={
688 head_: hd,
689 cols: cols,
690 widths: col,
691 obj: rows,
692 idx: idx,
693 tags: tags,
694 num: @num_id[:table],
695 }
696 t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \
697 unless h.nil?
698 tuned_file << t_o
699 h={
700 is_for: :table,
701 obj: '',
702 sym: :table_close,
703 num: @num_id[:table],
704 }
705 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
706 t_o
707 elsif t_o=~/^```[ ]+table\((?:.*?\bh;)?\s+/
708 m1,m2,hd=nil,nil,nil
709 h=case t_o
710 when /^```[ ]+table\(.*?\bh;\s+(.+?)\)\n(.+)\Z/m #two table representations should be consolidated as one
711 m1,tbl,hd=$1,$2,true
712 when /^```[ ]+table\((.+?)\)\n(.+)\Z/m #two table representations should be consolidated as one
713 m1,tbl,hd=$1,$2,false
714 else nil
715 end
716 tbl,tags=extract_tags(tbl)
717 col=m1.scan(/\d+/)
718 rws=tbl.split(/\n/)
719 rows=''
720 rws.each do |r|
721 r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}") #r.gsub!(/\|/m,"#{Mx[:tc_p]}")
722 rows += r + Mx[:tc_c]
723 end
724 h={
725 head_: hd,
726 cols: col.length,
727 widths: col,
728 obj: rows,
729 idx: idx,
730 tags: tags,
731 num: @num_id[:table],
732 }
733 t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \
734 unless h.nil?
735 tuned_file << t_o
736 h={
737 is_for: :table,
738 obj: '',
739 sym: :table_close,
740 num: @num_id[:table],
741 }
742 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
743 t_o
744 elsif t_o=~/^\{table\((?:.*?\bh;)?/
745 m1,m2,hd=nil,nil,nil
746 h=case t_o
747 when /\{table\(.*?\bh;\s+(.+?)\)\s*\}\n(.+)\Z/m #two table representations should be consolidated as one
748 m1,tbl,hd=$1,$2,true
749 when /\{table\((.+?)\)\s*\}\n(.+)\Z/m #two table representations should be consolidated as one
750 m1,tbl,hd=$1,$2,false
751 else nil
752 end
753 tbl,tags=extract_tags(tbl)
754 col=m1.scan(/\d+/)
755 rws=tbl.split(/\n/)
756 rows=''
757 rws.each do |r|
758 r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}") #r.gsub!(/\|/m,"#{Mx[:tc_p]}")
759 rows += r + Mx[:tc_c]
760 end
761 h={
762 head_: hd,
763 cols: col.length,
764 widths: col,
765 obj: rows,
766 idx: idx,
767 tags: tags,
768 num: @num_id[:table],
769 }
770 t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \
771 unless h.nil?
772 tuned_file << t_o
773 h={
774 is_for: :table,
775 obj: '',
776 sym: :table_close,
777 num: @num_id[:table],
778 }
779 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
780 t_o
781 end
782 end
783 t_o
784 end
785 if @per.table==:curls or @per.table==:tics
786 if (@per.table==:curls \
787 and t_o =~/^\}table/) \
788 or (@per.table==:tics \
789 and t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)
790 @per.table=:off
791 headings,columns,widths,idx=@h[:head_],@h[:cols],@h[:widths],@h[:idx]
792 @h={
793 head_: headings,
794 cols: columns,
795 widths: widths,
796 idx: idx,
797 obj: @rows,
798 }
799 t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(@h)
800 tuned_file << t_o
801 @h,@rows=nil,''
802 h={
803 is_for: :table,
804 obj: '',
805 sym: :table_close,
806 num: @num_id[:table],
807 }
808 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
809 t_o
810 else
811 if t_o.is_a?(String) \
812 and t_o !~/^(?:table\{|```[ ]+table)/
813 t_o=t_o.gsub(/^\n+/m,'').
814 gsub(/\n+/m,"#{Mx[:tc_p]}")
815 @rows += t_o + Mx[:tc_c]
816 end
817 t_o=nil
818 end
819 end
820 if @per.code==:curls \
821 or @per.code==:tics
822 if (@per.code==:curls \
823 && t_o =~/^\}code/) \
824 or (@per.code==:tics \
825 && t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/m)
826 @per.code=:off
827 if @tuned_code[-1]
828 @tuned_code[-1].
829 gsub!(/\s*(?:#{Mx[:br_line]}|#{Mx[:br_nl]})\s*\Z/m,'')
830 end
831 obj=@tuned_code.join("\n")
832 tags=[]
833 h={
834 obj: obj,
835 idx: idx,
836 syntax: @per.lngsyn,
837 tags: tags,
838 num: @num_id[:code_block],
839 number_: @codeblock_numbered,
840 }
841 @per.lngsyn=:txt
842 t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.code(h)
843 @tuned_code=[]
844 tuned_file << t_o
845 h={
846 is_for: :code,
847 obj: '',
848 sym: :code_close,
849 num: @num_id[:code_block],
850 }
851 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
852 end
853 if (@per.code==:curls \
854 || @per.code==:tics) \
855 and t_o.is_a?(String)
856 sub_array=t_o.dup + "#{Mx[:br_nl]}"
857 @line_mode=[]
858 sub_array.scan(/.+/) {|w| @line_mode << w if w =~/[\S]+/}
859 t_o=SiSU_AO_DocumentStructureExtract::Build.new(@md,@line_mode).build_lines(:code).join
860 @tuned_code << t_o
861 t_o=nil
862 end
863 elsif (@per.poem==:curls \
864 || @per.poem==:tics) \
865 or (@per.box==:curls \
866 || @per.box==:tics) \
867 or (@per.group==:curls \
868 || @per.group==:tics) \
869 or (@per.block==:curls \
870 || @per.block==:tics) \
871 or (@per.alt==:curls \
872 || @per.alt==:tics) \
873 or (@per.quote==:open \
874 && t_o =~/`:quote_close`/m) #not
875 if (@per.poem==:curls \
876 && t_o =~/^\}poem$/m) \
877 or (@per.poem==:tics \
878 && t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)
879 @per.poem=:off
880 h={
881 is_for: :poem,
882 obj: '',
883 idx: idx,
884 sym: :poem_close,
885 num: @num_id[:poem],
886 }
887 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
888 elsif (@per.box==:curls \
889 && t_o =~/^\}box/) \
890 or (@per.box==:tics \
891 && t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)
892 @per.box=:off
893 obj,tags=extract_tags(@tuned_block.join("\n"))
894 h={
895 obj: obj,
896 idx: idx,
897 tags: tags,
898 num: @num_id[:box],
899 }
900 @tuned_block=[]
901 t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.box(h)
902 tuned_file << t_o
903 h={
904 is_for: :box,
905 obj: '',
906 idx: idx,
907 sym: :box_close,
908 num: @num_id[:box],
909 }
910 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
911 elsif (@per.group==:curls \
912 && t_o =~/^\}group/) \
913 or (@per.group==:tics \
914 && t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)
915 @per.group=:off
916 obj,tags=extract_tags(@tuned_block.join("\n"))
917 h={
918 obj: obj,
919 idx: idx,
920 tags: tags,
921 num: @num_id[:group],
922 }
923 @tuned_block=[]
924 t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.group(h)
925 tuned_file << t_o
926 h={
927 is_for: :group,
928 obj: '',
929 sym: :group_close,
930 num: @num_id[:group],
931 }
932 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
933 elsif (@per.block==:curls \
934 && t_o =~/^\}block/) \
935 or (@per.block==:tics \
936 && t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)
937 @per.block=:off
938 obj,tags=extract_tags(@tuned_block.join("\n"))
939 h={
940 obj: obj,
941 idx: idx,
942 tags: tags,
943 num: @num_id[:block],
944 }
945 @tuned_block=[]
946 t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.block(h)
947 tuned_file << t_o
948 h={
949 is_for: :block,
950 obj: '',
951 sym: :block_close,
952 num: @num_id[:block],
953 }
954 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
955 elsif (@per.alt==:curls \
956 && t_o =~/^\}alt/) \
957 or (@per.alt==:tics \
958 && t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)
959 @per.alt=:off
960 obj,tags=extract_tags(@tuned_block.join("\n"))
961 h={
962 obj: obj,
963 idx: idx,
964 tags: tags,
965 num: @num_id[:alt],
966 }
967 t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.alt(h)
968 @tuned_block=[]
969 tuned_file << t_o
970 h={
971 is_for: :alt,
972 obj: '',
973 sym: :alt_close,
974 num: @num_id[:alt],
975 }
976 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
977 elsif @per.quote==:open \
978 and t_o =~/`:quote_close`/m
979 @per.quote=:off
980 h={
981 is_for: :quote,
982 idx: idx,
983 obj: '',
984 sym: :quote_close,
985 num: @num_id[:quote],
986 }
987 t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h)
988 elsif @per.quote==:open
989 t_o,tags=extract_tags(t_o)
990 h={
991 indent: 1,
992 obj: t_o,
993 idx: idx,
994 note_: note,
995 image_: image,
996 tags: tags,
997 quote: quotes?,
998 }
999 SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h)
1000 end
1001 if (@per.poem==:curls \
1002 || @per.poem==:tics) \
1003 or (@per.group==:curls \
1004 || @per.group==:tics) \
1005 or (@per.block==:curls \
1006 || @per.block==:tics) \
1007 or (@per.alt==:curls \
1008 || @per.alt==:tics) \
1009 and t_o =~/\S/ \
1010 and t_o !~/^(?:\}(?:verse|code|box|alt|group|block)|(?:verse|code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|alt|group|block)\{)/ \
1011 and t_o !~/^```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block)|^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/ # fix logic
1012 sub_array=t_o.dup
1013 @line_mode=sub_array.scan(/.+/)
1014 type=if @per.poem==:curls or @per.poem==:tics
1015 t_o=SiSU_AO_DocumentStructureExtract::Build.new(@md,@line_mode).build_lines(type).join
1016 poem=t_o.split(/\n\n/)
1017 poem.each do |v|
1018 v=v.gsub(/\n/m,"#{Mx[:br_nl]}\n")
1019 obj,tags=extract_tags(v)
1020 h={
1021 obj: obj,
1022 tags: tags,
1023 num: @num_id[:poem],
1024 }
1025 t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.verse(h)
1026 tuned_file << t_o
1027 end
1028 :poem
1029 else :group
1030 end
1031 end
1032 @verse_count+=1 if @per.poem==:curls or @per.poem==:tics
1033 end
1034 if @per.code==:off
1035 if @per.poem==:curls or @per.poem==:tics \
1036 or @per.box==:curls or @per.box==:tics \
1037 or @per.group==:curls or @per.group==:tics \
1038 or @per.block==:curls or @per.block==:tics \
1039 or @per.alt==:curls or @per.alt==:tics \
1040 or (@per.quote==:open and t_o =~/`:quote_close`/m)
1041 if t_o.is_a?(String)
1042 t_o=t_o.gsub(/\n/m,"#{Mx[:br_nl]}").
1043 gsub(/[ ][ ]/m,"#{Mx[:nbsp]*2}").
1044 gsub(/#{Mx[:nbsp]}\s/,"#{Mx[:nbsp]*2}")
1045 t_o=t_o + Mx[:br_nl] if t_o =~/\S+/
1046 elsif t_o.is==:group \
1047 || t_o.is==:block \
1048 || t_o.is==:alt \
1049 || t_o.is==:box \
1050 || t_o.is==:verse
1051 t_o.obj=t_o.obj.gsub(/\n/m,"#{Mx[:br_nl]}").
1052 gsub(/[ ][ ]/m,"#{Mx[:nbsp]*2}").
1053 gsub(/#{Mx[:nbsp]}\s/,"#{Mx[:nbsp]*2}")
1054 end
1055 @tuned_block << t_o if t_o =~/\S+/
1056 else tuned_file << t_o
1057 end
1058 else tuned_file << t_o
1059 end
1060 end
1061 tuned_file
1062 end
1063 def identify_parts
1064 tuned_file=[]
1065 @tuned_block,@tuned_code=[],[]
1066 @@counter,@verse_count=0,0
1067 @num_id={
1068 code_block: 0,
1069 poem: 0,
1070 box: 0,
1071 block: 0,
1072 group: 0,
1073 alt: 0,
1074 quote: 0,
1075 table: 0,
1076 }
1077 @metadata={}
1078 if @md.flag_auto_biblio \
1079 or @md.flag_biblio
1080 @data,bibliography=SiSU_AO_Appendices::Bibliography.new(@md,@data).biblio_extraction
1081 end
1082 if @md.flag_glossary
1083 @data,glossary=SiSU_AO_Appendices::Glossary.new(@md,@data).glossary_extraction
1084 end
1085 tuned_file=extract_structure_loop(@data,tuned_file)
1086 if @md.flag_endnotes
1087 tuned_file << @pb
1088 h={
1089 ln: 1,
1090 lc: 1,
1091 obj: 'Endnotes',
1092 autonum_: false,
1093 }
1094 tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h)
1095 h={
1096 ln: 4,
1097 lc: 2,
1098 obj: 'Endnotes',
1099 name: 'endnotes',
1100 autonum_: false,
1101 }
1102 tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h)
1103 h={
1104 obj: 'Endnotes'
1105 }
1106 end
1107 if @md.flag_glossary
1108 tuned_file << @pb
1109 h={
1110 ln: 1,
1111 lc: 1,
1112 obj: 'Glossary',
1113 autonum_: false,
1114 }
1115 tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h)
1116 h={
1117 ln: 4,
1118 lc: 2,
1119 obj: 'Glossary',
1120 name: 'glossary',
1121 autonum_: false,
1122 }
1123 tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h)
1124 h={
1125 obj: 'Glossary'
1126 }
1127 if glossary.length > 0
1128 tuned_file=extract_structure_loop(glossary,tuned_file)
1129 end
1130 end
1131 if @md.flag_auto_biblio
1132 tuned_file << @pb
1133 h={
1134 ln: 1,
1135 lc: 1,
1136 obj: 'References',
1137 autonum_: false,
1138 }
1139 tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h)
1140 h={
1141 ln: 4,
1142 lc: 2,
1143 obj: 'Bibliography',
1144 name: 'biblio',
1145 autonum_: false,
1146 }
1147 tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h)
1148 h={
1149 obj: 'Bibliography'
1150 }
1151 citenumber=0
1152 bibliography.each do |cite|
1153 citenumber +=1 if cite.is_a?(Hash)
1154 h={
1155 obj: cite[:obj],
1156 #obj: %{[#{citenumber}] } + cite[:obj],
1157 tags: [cite[:id]],
1158 hang: 0,
1159 indent: 2,
1160 ocn_: false,
1161 }
1162 tuned_file << SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h)
1163 end
1164 elsif @md.flag_biblio
1165 tuned_file << @pb
1166 h={
1167 ln: 1,
1168 lc: 1,
1169 obj: 'References',
1170 autonum_: false,
1171 }
1172 tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h)
1173 h={
1174 ln: 4,
1175 lc: 2,
1176 obj: 'Bibliography',
1177 name: 'biblio',
1178 autonum_: false,
1179 }
1180 tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h)
1181 h={
1182 obj: 'Bibliography'
1183 }
1184 if not bibliography.nil? \
1185 and bibliography.length > 0
1186 tuned_file=extract_structure_loop(bibliography,tuned_file)
1187 else
1188 tuned_file, citations =
1189 SiSU_AO_Appendices::Citations.new(@md,tuned_file).songsheet # ao_appendices.rb
1190 citenumber=0
1191 citations.compact.each do |c|
1192 citenumber +=1 if c.is_a?(Hash)
1193 if c[:is]==:book
1194 h={
1195 obj: %{#{c[:author]}. /{#{c[:publication]}}/ (#{c[:year]})},
1196 #obj: %{[#{citenumber}] *{#{c[:author]}}* /{#{c[:publication]}}/ (#{c[:year]})},
1197 hang: 0,
1198 indent: 2,
1199 ocn_: false,
1200 }
1201 tuned_file << SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h)
1202 elsif c[:is]==:article
1203 h={
1204 obj: %{#{c[:author]}. /{"#{c[:title]}"}/ #{c[:publication]} editor #{c[:editor]} (#{c[:year]})},
1205 #obj: %{[#{citenumber}] *{#{c[:author]}}* /{"#{c[:title]}"}/ #{c[:publication]} editor #{c[:editor]} (#{c[:year]})},
1206 hang: 0,
1207 indent: 2,
1208 ocn_: false,
1209 }
1210 tuned_file << SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h)
1211 end
1212 end
1213 end
1214 end
1215 if @md.book_idx
1216 tuned_file << @pb
1217 h={
1218 ln: 1,
1219 lc: 1,
1220 obj: 'Index',
1221 autonum_: false,
1222 }
1223 tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h)
1224 h={
1225 ln: 4,
1226 lc: 2,
1227 obj: 'Index',
1228 name: 'book_index',
1229 autonum_: false,
1230 }
1231 tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h)
1232 h={
1233 obj: 'Index'
1234 }
1235 end
1236 tuned_file << @pb
1237 if @make.build.metadata?
1238 h={
1239 ln: 1,
1240 lc: 1,
1241 obj: 'Metadata',
1242 autonum_: false,
1243 ocn_: false,
1244 }
1245 tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h)
1246 h={
1247 ln: 4,
1248 lc: 2,
1249 obj: 'SiSU Metadata, document information',
1250 name: 'metadata',
1251 autonum_: false,
1252 ocn_: false,
1253 }
1254 tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h)
1255 end
1256 h={
1257 obj: 'eof',
1258 }
1259 meta=SiSU_AO_DocumentStructure::ObjectMetadata.new.metadata(@metadata)
1260 [tuned_file,meta,bibliography,glossary]
1261 end
1262 def table_rows_and_columns_array(table_str)
1263 table=[]
1264 table_str.split(/#{Mx[:tc_c]}/).each do |table_row|
1265 table_row_with_columns=table_row.split(/#{Mx[:tc_p]}/)
1266 table << table_row_with_columns
1267 end
1268 table
1269 end
1270 def meta_heading(h)
1271 h={
1272 lv: h[:lv],
1273 ln: h[:ln],
1274 name: h[:name],
1275 obj: h[:obj],
1276 ocn: '0',
1277 }
1278 SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h)
1279 end
1280 def meta_para(str)
1281 h={
1282 obj: str,
1283 ocn_: false,
1284 }
1285 SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h)
1286 end
1287 def build_lines(type=:none)
1288 lines=@data
1289 lines.each.map do |line|
1290 line=if line =~/\S/ \
1291 and line !~/^(?:code(?:\.[a-z][0-9a-z_]+)?\{|\}code)/ \
1292 and line !~/^(?:```[ ]+code(?:\.[a-z][0-9a-z_]+)?|```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$)/ \
1293 and not line.is_a?(Hash) #watch
1294 @@counter+=1 if @per.code==:curls or @per.code==:tics
1295 line=line.gsub(/\s\s/,"#{Mx[:nbsp]*2}").
1296 gsub(/#{Mx[:nbsp]}\s/,"#{Mx[:nbsp]*2}")
1297 line=line.gsub(/^/,"#{Mx[:gr_o]}codeline#{Mx[:gr_c]}") if type==:code # REMOVE try sort for texpdf special case
1298 line=if line =~/(?:https?|file|ftp):\/\/\S+$/
1299 line.gsub(/\s*$/," #{Mx[:br_nl]}")
1300 else line.gsub(/\s*$/,"#{Mx[:br_nl]}") #unless type=='code'
1301 end
1302 elsif line =~/^\s*$/
1303 line.gsub(/\s*$/,"#{Mx[:br_nl]}")
1304 else line
1305 end
1306 line
1307 end
1308 end
1309 end
1310 class Structure # this must happen early
1311 def initialize(md)
1312 @md=md
1313 end
1314 def structure(data)
1315 data.compact.each do |dob|
1316 structure_markup(dob)
1317 end
1318 end
1319 def structure_markup(dob) #build structure where structure provided only in meta header
1320 dob=if dob.is==:para \
1321 && (((dob.hang !~/[1-9]/) && (dob.indent !~/[1-9]/)) \
1322 || (dob.hang != dob.indent)) \
1323 and not dob.bullet_
1324 dob=case dob.obj
1325 when /^#{@md.lv0}/
1326 h={
1327 is: :heading,
1328 lv: 'A',
1329 ln: 0,
1330 }
1331 SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob)
1332 when /^#{@md.lv1}/
1333 h={
1334 is: :heading,
1335 lv: 'B',
1336 ln: 1,
1337 }
1338 SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob)
1339 when /^#{@md.lv2}/
1340 h={
1341 is: :heading,
1342 lv: 'C',
1343 ln: 2,
1344 }
1345 SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob)
1346 when /^#{@md.lv3}/
1347 h={
1348 is: :heading,
1349 lv: 'D',
1350 ln: 3,
1351 }
1352 SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob)
1353 when /^#{@md.lv4}/
1354 h={
1355 is: :heading,
1356 lv: '1',
1357 ln: 4,
1358 }
1359 SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob)
1360 when /^#{@md.lv5}/
1361 h={
1362 is: :heading,
1363 lv: '2',
1364 ln: 5,
1365 }
1366 SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob)
1367 when /^#{@md.lv6}/
1368 h={
1369 is: :heading,
1370 lv: '3',
1371 ln: 6,
1372 }
1373 SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob)
1374 else dob
1375 end
1376 else dob
1377 end
1378 dob
1379 end
1380 end
1381 class OCN
1382 def initialize(md,data,fnx,process)
1383 @md,@data,@fnx,@process=md,data,fnx,process
1384 end
1385 def structure_info
1386 def lv
1387 %w[A~ B~ C~ D~ 1 2 3 4]
1388 end
1389 def possible_parents(child)
1390 case child
1391 when /A~/ then 'none'
1392 when /B~/ then 'A~'
1393 when /C~/ then 'B~'
1394 when /D~/ then 'C~'
1395 when /1/ then 'A~, B~, C~, D~'
1396 when /2/ then '1'
1397 when /3/ then '2'
1398 when /4/ then '3'
1399 end
1400 end
1401 def possible_children(parent)
1402 case parent
1403 when /A~/ then 'B~, 1'
1404 when /B~/ then 'C~, 1'
1405 when /C~/ then 'D~, 1'
1406 when /D~/ then '1'
1407 when /1/ then '2'
1408 when /2/ then '3'
1409 when /3/ then '4'
1410 when /4/ then 'none'
1411 end
1412 end
1413 self
1414 end
1415 def document_structure_check_info(node,node_parent,status=:ok)
1416 node_ln=/^([0-7])/.match(node)[1].to_i
1417 node_parent_ln=/^([0-7])/.match(node_parent)[1].to_i
1418 if status==:error \
1419 or @md.opt.act[:maintenance][:set]==:on
1420 puts %{node: #{node}, parent node: #{node_parent} #{status.upcase}}
1421 if status==:error
1422 node_ln=/^([0-7])/.match(node)[1].to_i
1423 node_parent_ln=/^([0-7])/.match(node_parent)[1].to_i
1424 STDERR.puts %{current level: #{structure_info.lv[node_ln]} (possible parent levels: #{structure_info.possible_parents(structure_info.lv[node_ln])})
1425 parent level: #{structure_info.lv[node_parent_ln]} (possible child levels: #{structure_info.possible_children(structure_info.lv[node_parent_ln])})
1426 SKIPPED processing file:
1427 [#{@md.opt.lng}] "#{@md.fns}"}
1428 if @md.opt.act[:no_stop][:set]==:on
1429 $process_document = :skip
1430 else exit
1431 end
1432 end
1433 end
1434 end
1435 def warning_incorrect_parent_level_or_level(txt)
1436 puts %{ERROR. There is an error in markup of heading levels either here or in the parent heading.
1437 The current header reads:
1438 "#{txt}"
1439 has incorrect level and/or parent level
1440 --}
1441 end
1442 def required_headers_present?
1443 if @process == :complete
1444 unless (defined? @md.title \
1445 and @md.title.full)
1446 STDERR.puts %{required header missing:
1447
1448 @title:
1449 SKIPPED processing file:
1450 [#{@md.opt.lng}] "#{@md.fns}"
1451 }
1452 if @md.opt.act[:no_stop][:set]==:on
1453 $process_document = :skip
1454 else exit
1455 end
1456 end
1457 unless (defined? @md.creator.author \
1458 and @md.creator.author)
1459 STDERR.puts %{required header missing:
1460
1461 @creator:
1462 :author: anonymous?
1463 SKIPPED processing file:
1464 [#{@md.opt.lng}] "#{@md.fns}"
1465 }
1466 if @md.opt.act[:no_stop][:set]==:on
1467 $process_document = :skip
1468 else exit
1469 end
1470 end
1471 end
1472 end
1473 def ocn #and auto segment numbering increment
1474 required_headers_present?
1475 data=@data
1476 @o_array=[]
1477 node=ocn=ocn_dv=ocn_sp=ocnh=ocnh0=ocnh1=ocnh2=ocnh3=ocnh4=ocnh5=ocnh6=ocnh7=ocno=ocnp=ocnt=ocnc=ocng=ocni=ocnu=0 # h heading, o other, t table, g group, i image
1478 regex_exclude_ocn_and_node = /#{Rx[:meta]}|^@\S+?:\s|^4~endnotes|^#{Mx[:lv_o]}4:endnotes#{Mx[:lv_c]}|^\^~ |<:e[:_]\d+?>|^<:\#|<:- |<[:!]!4|<hr width|#{Mx[:br_endnotes]}|\A\s*\Z/mi #ocn here #&nbsp; added with Tune.code #ยก
1479 parent=node1=node2=node3=node4=node5=node6=node7=nil
1480 node0='0:0;0'
1481 @collapsed_lv0=0
1482 @lev_occurences={ a: 0, b: 0, c: 0, d: 0, l1: 0, l2: 0, l3: 0, l4: 0 }
1483 data.each do |dob|
1484 h={}
1485 if (dob.obj !~ regex_exclude_ocn_and_node || dob.is==:code) \
1486 && (dob.of !=:comment \
1487 && dob.of !=:layout \
1488 && dob.of !=:meta) \
1489 && dob.ocn_
1490 #dob.ln now is determined, and set earlier, check how best to remove this -->
1491 if dob.is==:heading
1492 @ln=ln=case dob.lv
1493 when 'A' then 0
1494 when 'B' then 1
1495 when 'C' then 2
1496 when 'D' then 3
1497 when '1' then 4
1498 when '2' then 5
1499 when '3' then 6
1500 when '4' then 7
1501 when '5' then 8
1502 when '6' then 9
1503 end
1504 end
1505 if not dob.obj =~/~#|-#/
1506 ocn+=1
1507 end
1508 if @process == :complete \
1509 or (@fnx == @md.opt.fns \
1510 && @md.opt.fns =~/.sst$/)
1511 if dob.is==:heading \
1512 and (ln.to_s =~/^[0-9]/ \
1513 or ln.to_s =~@md.lv0 \
1514 or ln.to_s =~@md.lv1 \
1515 or ln.to_s =~@md.lv2 \
1516 or ln.to_s =~@md.lv3 \
1517 or ln.to_s =~@md.lv4 \
1518 or ln.to_s =~@md.lv5 \
1519 or ln.to_s =~@md.lv6 \
1520 or ln.to_s =~@md.lv7)
1521 if not dob.obj =~/~#|-#/
1522 ocnh+=1
1523 end
1524 if ln==0 \
1525 or ln=~@md.lv0
1526 @lev_occurences[:a] += 1
1527 if not dob.obj =~/~#|-#/
1528 ocn_flag=true
1529 ocnh0+=1 #heading
1530 node0="0:#{ocnh0};#{ocn}"
1531 else
1532 #document_structure_check_info(node0,node0,:error) #fix
1533 ocn_flag=false
1534 node0="0:0;0"
1535 end
1536 document_structure_check_info(node0,node0)
1537 @collapsed_lv0=0
1538 collapsed_level=@collapsed_lv0
1539 node,ocn_sp,parent=node0,"h#{ocnh}",'ROOT'
1540 elsif ln==1 \
1541 or ln=~@md.lv1
1542 @lev_occurences[:b] += 1
1543 if not dob.obj =~/~#|-#/
1544 ocn_flag=true
1545 ocnh1+=1 #heading
1546 node1="1:#{ocnh1};#{ocn}"
1547 else
1548 #document_structure_check_info(node0,node0,:error) #fix
1549 ocn_flag=false
1550 node1="1:0;0"
1551 end
1552 parent=if node0
1553 document_structure_check_info(node1,node0)
1554 @collapsed_lv1=@collapsed_lv0+1
1555 node0
1556 else
1557 warning_incorrect_parent_level_or_level(dob.obj)
1558 document_structure_check_info(node0,node0,:error)
1559 node0
1560 end
1561 collapsed_level=@collapsed_lv1
1562 node,ocn_sp,parent=node1,"h#{ocnh}",node0 #FIX
1563 elsif ln==2 \
1564 or ln=~@md.lv2
1565 @lev_occurences[:c] += 1
1566 if not dob.obj =~/~#|-#/
1567 ocn_flag=true
1568 ocnh2+=1
1569 node2="2:#{ocnh2};#{ocn}"
1570 else
1571 #document_structure_check_info(node0,node0,:error) #fix
1572 ocn_flag=false
1573 node2="2:0;0"
1574 end
1575 parent=if node1
1576 document_structure_check_info(node2,node1)
1577 @collapsed_lv2=@collapsed_lv1+1
1578 node1
1579 else
1580 warning_incorrect_parent_level_or_level(dob.obj)
1581 document_structure_check_info(node2,node0,:error)
1582 node0
1583 end
1584 collapsed_level=@collapsed_lv2
1585 node,ocn_sp=node2,"h#{ocnh}"
1586 elsif ln==3 \
1587 or ln=~@md.lv3
1588 @lev_occurences[:d] += 1
1589 if not dob.obj =~/~#|-#/
1590 ocn_flag=true
1591 ocnh3+=1
1592 node3="3:#{ocnh3};#{ocn}"
1593 else
1594 #document_structure_check_info(node0,node0,:error) #fix
1595 ocn_flag=false
1596 node3="3:0;0"
1597 end
1598 parent=if node2
1599 document_structure_check_info(node3,node2)
1600 @collapsed_lv3=@collapsed_lv2+1
1601 node2
1602 elsif node1
1603 warning_incorrect_parent_level_or_level(dob.obj)
1604 puts %{parent is :A~ & this level #{dob.lv}
1605 either parent should be level :B~
1606 or this level should be level :B~ rather than #{dob.lv}}
1607 document_structure_check_info(node3,node1,:error)
1608 @collapsed_lv3=@collapsed_lv1+1
1609 node1
1610 else
1611 document_structure_check_info(node3,node0,:error)
1612 warning_incorrect_parent_level_or_level(dob.obj)
1613 node0
1614 end
1615 collapsed_level=@collapsed_lv3
1616 node,ocn_sp=node3,"h#{ocnh}"
1617 elsif ln==4 \
1618 or ln=~@md.lv4
1619 @lev_occurences[:l1] += 1
1620 if not dob.obj =~/~#|-#/
1621 ocn_flag=true
1622 ocnh4+=1
1623 node4="4:#{ocnh4};#{ocn}"
1624 else
1625 ocn_flag=false
1626 node4="4:0;0"
1627 end
1628 parent=if node3
1629 document_structure_check_info(node4,node3)
1630 @collapsed_lv4=@collapsed_lv3+1
1631 node3
1632 elsif node2
1633 document_structure_check_info(node4,node2)
1634 @collapsed_lv4=@collapsed_lv2+1
1635 node2
1636 elsif node1
1637 document_structure_check_info(node4,node1)
1638 @collapsed_lv4=@collapsed_lv1+1
1639 node1
1640 elsif node0
1641 document_structure_check_info(node4,node0)
1642 @collapsed_lv4=@collapsed_lv0+1
1643 node0
1644 else
1645 warning_incorrect_parent_level_or_level(dob.obj)
1646 document_structure_check_info(node4,node0,:error)
1647 node0
1648 end
1649 collapsed_level=@collapsed_lv4
1650 node,ocn_sp=node4,"h#{ocnh}"
1651 elsif ln==5 \
1652 or ln=~@md.lv5
1653 @lev_occurences[:l2] += 1
1654 if not dob.obj =~/~#|-#/
1655 ocn_flag=true
1656 ocnh5+=1
1657 node5="5:#{ocnh5};#{ocn}"
1658 else
1659 ocn_flag=false
1660 node5="5:0;0"
1661 end
1662 parent=if node4
1663 document_structure_check_info(node5,node4)
1664 @collapsed_lv5=@collapsed_lv4+1
1665 node4
1666 elsif node3
1667 warning_incorrect_parent_level_or_level(dob.obj)
1668 document_structure_check_info(node5,node3,:error)
1669 @collapsed_lv5=@collapsed_lv3+1
1670 node3
1671 elsif node2
1672 warning_incorrect_parent_level_or_level(dob.obj)
1673 document_structure_check_info(node5,node2,:error)
1674 @collapsed_lv5=@collapsed_lv2+1
1675 node2
1676 elsif node1
1677 warning_incorrect_parent_level_or_level(dob.obj)
1678 document_structure_check_info(node5,node1,:error)
1679 @collapsed_lv5=@collapsed_lv1+1
1680 node1
1681 else
1682 warning_incorrect_parent_level_or_level(dob.obj)
1683 document_structure_check_info(node5,node0,:error)
1684 node0
1685 end
1686 collapsed_level=@collapsed_lv5
1687 node,ocn_sp=node5,"h#{ocnh}"
1688 elsif ln==6 \
1689 or ln=~@md.lv6
1690 @lev_occurences[:l3] += 1
1691 if not dob.obj =~/~#|-#/
1692 ocn_flag=true
1693 ocnh6+=1
1694 node6="6:#{ocnh6};#{ocn}"
1695 else
1696 ocn_flag=false
1697 node6="6:0;0"
1698 end
1699 parent=if node5
1700 document_structure_check_info(node6,node5)
1701 @collapsed_lv6=@collapsed_lv5+1
1702 node5
1703 elsif node4
1704 warning_incorrect_parent_level_or_level(dob.obj)
1705 puts "parent is level #4 (1~) & this level ##{dob.ln} (#{dob.lv}~)
1706 either parent should be level #5 (2~)
1707 or this level should be #5 (2~) rather ##{dob.ln} (#{dob.lv}~)"
1708 document_structure_check_info(node6,node4,:error)
1709 @collapsed_lv6=@collapsed_lv4+1
1710 node4
1711 elsif node3
1712 warning_incorrect_parent_level_or_level(dob.obj)
1713 document_structure_check_info(node6,node3,:error)
1714 @collapsed_lv6=@collapsed_lv3+1
1715 node3
1716 elsif node2
1717 warning_incorrect_parent_level_or_level(dob.obj)
1718 document_structure_check_info(node6,node2,:error)
1719 @collapsed_lv6=@collapsed_lv2+1
1720 node2
1721 elsif node1
1722 warning_incorrect_parent_level_or_level(dob.obj)
1723 document_structure_check_info(node6,node1,:error)
1724 @collapsed_lv6=@collapsed_lv1+1
1725 node1
1726 else
1727 warning_incorrect_parent_level_or_level(dob.obj)
1728 document_structure_check_info(node6,node0,:error)
1729 node0
1730 end
1731 collapsed_level=@collapsed_lv6
1732 node,ocn_sp=node6,"h#{ocnh}"
1733 elsif ln==7 \
1734 or ln=~@md.lv7
1735 @lev_occurences[:l4] += 1
1736 if not dob.obj =~/~#|-#/
1737 ocn_flag=true
1738 ocnh7+=1
1739 node7="7:#{ocnh7};#{ocn}"
1740 else
1741 ocn_flag=false
1742 node7="7:0;0"
1743 end
1744 parent=if node6
1745 document_structure_check_info(node7,node6)
1746 @collapsed_lv7=@collapsed_lv6+1
1747 node5
1748 elsif node5
1749 warning_incorrect_parent_level_or_level(dob.obj)
1750 puts "parent is level #5 (2~) & this level ##{dob.ln} (#{dob.lv}~)
1751 either parent should be level #6 (3~)
1752 or this level should be #6 (3~) rather ##{dob.ln} (#{dob.lv}~)"
1753 document_structure_check_info(node7,node5,:error)
1754 @collapsed_lv6=@collapsed_lv5+1
1755 node5
1756 elsif node4
1757 warning_incorrect_parent_level_or_level(dob.obj)
1758 puts "parent is level #4 (1~) & this level ##{dob.ln} (#{dob.lv}~)
1759 either parent should be level 6~
1760 or this level should be #6 (3~) rather ##{dob.ln} (#{dob.lv}~)"
1761 document_structure_check_info(node7,node4,:error)
1762 @collapsed_lv6=@collapsed_lv4+1
1763 node4
1764 elsif node3
1765 warning_incorrect_parent_level_or_level(dob.obj)
1766 document_structure_check_info(node7,node3,:error)
1767 @collapsed_lv6=@collapsed_lv3+1
1768 node3
1769 elsif node2
1770 warning_incorrect_parent_level_or_level(dob.obj)
1771 document_structure_check_info(node7,node2,:error)
1772 @collapsed_lv6=@collapsed_lv2+1
1773 node2
1774 elsif node1
1775 warning_incorrect_parent_level_or_level(dob.obj)
1776 document_structure_check_info(node7,node1,:error)
1777 @collapsed_lv6=@collapsed_lv1+1
1778 node1
1779 else
1780 warning_incorrect_parent_level_or_level(dob.obj)
1781 document_structure_check_info(node7,node0,:error)
1782 node0
1783 end
1784 collapsed_level=@collapsed_lv7
1785 node,ocn_sp=node7,"h#{ocnh}"
1786 end
1787 else
1788 unless @lev_occurences[:l1] > 0
1789 STDERR.puts %{Substantive text objects must follow a level 1~ heading and there are none at this point in processing: #{@lev_occurences[:l1]}
1790 SKIPPED processing file:
1791 [#{@md.opt.lng}] "#{@md.fns}"}
1792 puts dob.obj #.gsub(/^(.{1,80})/,'"\1"')
1793 exit
1794 end
1795 unless @ln >= 4
1796 lev=case @ln
1797 when 0 then 'A'
1798 when 1 then 'B'
1799 when 2 then 'C'
1800 when 3 then 'D'
1801 when 4 then '1'
1802 when 5 then '2'
1803 when 6 then '3'
1804 when 7 then '4'
1805 when 8 then '5'
1806 when 9 then '6'
1807 end
1808 STDERR.puts %{Substantive text objects must follow a level 1~ 2~ or 3~ heading: #{lev}~
1809 SKIPPED processing file:
1810 [#{@md.opt.lng}] "#{@md.fns}"}
1811 puts dob.obj.gsub(/^(.{1,80})/,'"\1"')
1812 if @md.opt.act[:no_stop][:set]==:on
1813 $process_document = :skip
1814 break
1815 else exit
1816 end
1817 end
1818 if not dob.obj =~/~#|-#/
1819 ocn_flag=true
1820 else
1821 ocn_flag=false
1822 end
1823 ocno+=1
1824 if dob.is==:table
1825 ocnt+=1
1826 ocn_sp,parent="t#{ocnt}",node
1827 elsif dob.is==:code
1828 ocnc+=1
1829 ocn_sp,parent="c#{ocnc}",node
1830 elsif dob.is==:group \
1831 || dob.is==:box \
1832 || dob.is==:block \
1833 || dob.is==:alt \
1834 || dob.is==:verse
1835 ocng+=1 #group, poem
1836 ocn_sp,parent="g#{ocng}",node
1837 elsif dob.is==:image #check
1838 ocni+=1
1839 ocn_sp,parent="i#{ocni}",node
1840 else ocnp+=1 #paragraph
1841 ocn_sp,parent="p#{ocnp}",node
1842 end
1843 end
1844 end
1845 if dob.is==:heading
1846 if ocn_flag==true
1847 dob.ln,dob.node,dob.ocn,dob.ocn_,dob.odv,dob.osp,dob.parent,dob.lc=
1848 ln, node, ocn, ocn_flag, ocn_dv,ocn_sp, parent, collapsed_level
1849 else
1850 ocnu+=1
1851 heading_use=:ok
1852 if dob.obj=~/#{Mx[:pa_non_object_no_heading]}/
1853 dob.obj=dob.obj.gsub(/#{Mx[:pa_non_object_no_heading]}/,'')
1854 heading_use=:ok
1855 elsif dob.obj=~/#{Mx[:pa_non_object_dummy_heading]}/
1856 dob.obj=dob.obj.gsub(/#{Mx[:pa_non_object_dummy_heading]}/,'')
1857 heading_use=:dummy
1858 end
1859 dob.ln,dob.node,dob.ocn,dob.ocn_,dob.use_, dob.odv,dob.osp,dob.parent,dob.lc=
1860 ln, node, nil, ocn_flag,heading_use,ocn_dv, ocn_sp, parent, collapsed_level
1861 end
1862 else
1863 if dob.of !=:meta \
1864 && dob.of !=:comment \
1865 && dob.of !=:layout
1866 if ocn_flag == true
1867 dob.ocn,dob.ocn_,dob.odv,dob.osp,dob.parent=
1868 ocn, ocn_flag,ocn_dv, ocn_sp, parent
1869 else
1870 ocnu+=1
1871 dob.obj=dob.obj.gsub(/#{Mx[:fa_o]}[~-]##{Mx[:fa_c]}/,'') if dob.obj
1872 ocn_dv,ocn_sp="u#{ocnu}","u#{ocnu}"
1873 dob.ocn,dob.ocn_,dob.odv,dob.osp,dob.parent=
1874 nil, ocn_flag,ocn_dv, ocn_sp, parent
1875 end
1876 end
1877 end
1878 h
1879 else dob
1880 end
1881 if dob.is==:code \
1882 || dob.is==:verse \
1883 || dob.is==:alt \
1884 || dob.is==:box \
1885 || dob.is==:group \
1886 || dob.is==:block
1887 dob.obj=dob.obj.gsub(/\n+/,"\n") #newlines taken out
1888 end
1889 @o_array << dob
1890 end
1891 if @process == :complete \
1892 or (@fnx == @md.opt.fns \
1893 && @md.opt.fns =~/.sst$/)
1894 unless @lev_occurences[:a] == 1
1895 STDERR.puts %{The number of level A~ in this document: #{@lev_occurences[:a]}
1896 There must be one level A~ (no more and no less)
1897 SKIPPED processing file:
1898 [#{@md.opt.lng}] "#{@md.fns}"}
1899 if @md.opt.act[:no_stop][:set]==:on
1900 $process_document = :skip
1901 else exit
1902 end
1903 end
1904 unless @lev_occurences[:l1] > 0
1905 STDERR.puts %{The number of level 1~ in this document: #{@lev_occurences[:l1]}
1906 There must be at least one level 1~ (and as many as required)
1907 SKIPPED processing file:
1908 [#{@md.opt.lng}] "#{@md.fns}"}
1909 if @md.opt.act[:no_stop][:set]==:on
1910 $process_document = :skip
1911 else exit
1912 end
1913 end
1914 end
1915 @o_array
1916 end
1917 end
1918 class XML
1919 def initialize(md,data)
1920 @data,@md=data,md
1921 end
1922 def dom
1923 @s=[ 'A', 'B', 'C', 'D', '1', '2', '3' ]
1924 tuned_file=structure_build
1925 tuned_file
1926 end
1927 def spaces
1928 Ax[:spaces]
1929 end
1930 def structure_build
1931 data=@data
1932 tuned_file=[]
1933 hs=[0,false,false,false]
1934 t={
1935 lv: @s[0],
1936 status: :open,
1937 }
1938 tuned_file << tags(t)
1939 if @md.opt.act[:verbose_plus][:set]==:on
1940 puts "\nXML sisu structure outline --->\n"
1941 puts "<#{@s[0]}>"
1942 end
1943 data.each_with_index do |o,i|
1944 if o.is==:heading \
1945 || o.is==:heading_insert
1946 case o.ln
1947 when 0
1948 tuned_file << tag_close(o.ln,hs)
1949 tuned_file << tag_open(o,@s)
1950 if @md.opt.act[:verbose_plus][:set]==:on
1951 puts_tag_close(o.ln,hs)
1952 puts_tag_open(o,@s)
1953 end
1954 hs=[0,true,false,false,false]
1955 when 1
1956 tuned_file << tag_close(o.ln,hs)
1957 tuned_file << tag_open(o,@s)
1958 if @md.opt.act[:verbose_plus][:set]==:on
1959 puts_tag_close(o.ln,hs)
1960 puts_tag_open(o,@s)
1961 end
1962 hs=[1,true,true,false,false]
1963 when 2
1964 tuned_file << tag_close(o.ln,hs)
1965 tuned_file << tag_open(o,@s)
1966 if @md.opt.act[:verbose_plus][:set]==:on
1967 puts_tag_close(o.ln,hs)
1968 puts_tag_open(o,@s)
1969 end
1970 hs=[2,true,true,true,false]
1971 when 3
1972 tuned_file << tag_close(o.ln,hs)
1973 tuned_file << tag_open(o,@s)
1974 if @md.opt.act[:verbose_plus][:set]==:on
1975 puts_tag_close(o.ln,hs)
1976 puts_tag_open(o,@s)
1977 end
1978 hs=[3,true,true,true,true]
1979 when 4
1980 tuned_file << tag_close(o.ln,hs)
1981 tuned_file << tag_open(o,@s)
1982 if @md.opt.act[:verbose_plus][:set]==:on
1983 puts_tag_close(o.ln,hs)
1984 puts_tag_open(o,@s)
1985 end
1986 hs[0]=4
1987 when 5
1988 tuned_file << tag_close(o.ln,hs)
1989 tuned_file << tag_open(o,@s)
1990 if @md.opt.act[:verbose_plus][:set]==:on
1991 puts_tag_close(o.ln,hs)
1992 puts_tag_open(o,@s)
1993 end
1994 hs[0]=5
1995 when 6
1996 tuned_file << tag_close(o.ln,hs)
1997 tuned_file << tag_open(o,@s)
1998 if @md.opt.act[:verbose_plus][:set]==:on
1999 puts_tag_close(o.ln,hs)
2000 puts_tag_open(o,@s)
2001 end
2002 hs[0]=6
2003 end
2004 end
2005 tuned_file << o
2006 end
2007 if @md.opt.act[:verbose_plus][:set]==:on
2008 puts_tag_close(0,hs)
2009 end
2010 tuned_file << tag_close(0,hs)
2011 tuned_file=tuned_file.flatten
2012 end
2013 def tags(o)
2014 tag=(o[:status]==:open) \
2015 ? %{<#{o[:lv]} id="#{o[:node]}">}
2016 : "</#{o[:lv]}>"
2017 ln=case o[:lv]
2018 when 'A' then 0
2019 when 'B' then 1
2020 when 'C' then 2
2021 when 'D' then 3
2022 when '1' then 4
2023 when '2' then 5
2024 when '3' then 6
2025 when '4' then 7
2026 when '5' then 8
2027 when '6' then 9
2028 end
2029 h={
2030 tag: tag,
2031 node: o[:node],
2032 lv: o[:lv],
2033 ln: ln,
2034 status: o[:status],
2035 }
2036 SiSU_AO_DocumentStructure::ObjectStructure.new.xml_dom(h) #downstream code utilise else ignore like comments
2037 end
2038 def tag_open(o,tag)
2039 t={ lv: tag[o.ln], node: o.node, status: :open }
2040 t_o=tags(t)
2041 t_o
2042 end
2043 def tag_close(lev,hs)
2044 ary=[]
2045 case hs[0]
2046 when 0
2047 if (lev <= 0) and hs[0]
2048 t={
2049 lv: @s[0],
2050 status: :close,
2051 }
2052 ary << tags(t)
2053 end
2054 when 1
2055 if (lev <= 1) and hs[1]
2056 t={
2057 lv: @s[1],
2058 status: :close,
2059 }
2060 ary << tags(t)
2061 end
2062 if (lev==0)
2063 t={
2064 lv: @s[0],
2065 status: :close,
2066 }
2067 ary << tags(t)
2068 end
2069 when 2
2070 if (lev <= 2) and hs[2]
2071 t={
2072 lv: @s[2],
2073 status: :close,
2074 }
2075 ary << tags(t)
2076 end
2077 if (lev <= 1) and hs[1]
2078 t={
2079 lv: @s[1],
2080 status: :close,
2081 }
2082 ary << tags(t)
2083 end
2084 if (lev==0)
2085 t={
2086 lv: @s[0],
2087 status: :close,
2088 }
2089 ary << tags(t)
2090 end
2091 when 3
2092 if (lev <= 3) and hs[3]
2093 t={
2094 lv: @s[3],
2095 status: :close,
2096 }
2097 ary << tags(t)
2098 end
2099 if (lev <= 2) and hs[2]
2100 t={
2101 lv: @s[2],
2102 status: :close,
2103 }
2104 ary << tags(t)
2105 end
2106 if (lev <= 1) and hs[1]
2107 t={
2108 lv: @s[1],
2109 status: :close,
2110 }
2111 ary << tags(t)
2112 end
2113 if (lev==0)
2114 t={
2115 lv: @s[0],
2116 status: :close,
2117 }
2118 ary << tags(t)
2119 end
2120 when 4
2121 if (lev <= 4)
2122 t={
2123 lv: @s[4],
2124 status: :close,
2125 }
2126 ary << tags(t)
2127 end
2128 if (lev <= 3) and hs[3]
2129 t={
2130 lv: @s[3],
2131 status: :close,
2132 }
2133 ary << tags(t)
2134 end
2135 if (lev <= 2) and hs[2]
2136 t={
2137 lv: @s[2],
2138 status: :close,
2139 }
2140 ary << tags(t)
2141 end
2142 if (lev <= 1) and hs[1]
2143 t={
2144 lv: @s[1],
2145 status: :close,
2146 }
2147 ary << tags(t)
2148 end
2149 if (lev==0)
2150 t={
2151 lv: @s[0],
2152 status: :close,
2153 }
2154 ary << tags(t)
2155 end
2156 when 5
2157 if (lev <= 5)
2158 t={
2159 lv: @s[5],
2160 status: :close,
2161 }
2162 ary << tags(t)
2163 end
2164 if (lev <= 4)
2165 t={
2166 lv: @s[4],
2167 status: :close,
2168 }
2169 ary << tags(t)
2170 end
2171 if (lev <= 3) and hs[3]
2172 t={
2173 lv: @s[3],
2174 status: :close,
2175 }
2176 ary << tags(t)
2177 end
2178 if (lev <= 2) and hs[2]
2179 t={
2180 lv: @s[2],
2181 status: :close,
2182 }
2183 ary << tags(t)
2184 end
2185 if (lev <= 1) and hs[1]
2186 t={
2187 lv: @s[1],
2188 status: :close,
2189 }
2190 ary << tags(t)
2191 end
2192 if (lev==0)
2193 t={
2194 lv: @s[0],
2195 status: :close,
2196 }
2197 ary << tags(t)
2198 end
2199 when 6
2200 if (lev <= 6)
2201 t={
2202 lv: @s[6],
2203 status: :close,
2204 }
2205 ary << tags(t)
2206 end
2207 if (lev <= 5)
2208 t={
2209 lv: @s[5],
2210 status: :close,
2211 }
2212 ary << tags(t)
2213 end
2214 if (lev <= 4)
2215 t={
2216 lv: @s[4],
2217 status: :close,
2218 }
2219 ary << tags(t)
2220 end
2221 if (lev <= 3) and hs[3]
2222 t={
2223 lv: @s[3],
2224 status: :close,
2225 }
2226 ary << tags(t)
2227 end
2228 if (lev <= 2) and hs[2]
2229 t={
2230 lv: @s[2],
2231 status: :close,
2232 }
2233 ary << tags(t)
2234 end
2235 if (lev <= 1) and hs[1]
2236 t={
2237 lv: @s[1],
2238 status: :close,
2239 }
2240 ary << tags(t)
2241 end
2242 if (lev==0)
2243 t={
2244 lv: @s[0],
2245 status: :close,
2246 }
2247 ary << tags(t)
2248 end
2249 end
2250 ary
2251 end
2252 def puts_tag_open(o,tag)
2253 puts %{#{spaces*o.ln}<#{tag[o.ln]} id="#{o.node}">}
2254 end
2255 def puts_tag_close(lev,hs)
2256 case hs[0]
2257 when 0
2258 #puts "#{spaces*0}</#{@s[0]}>" if (lev <= 0) and hs[0]
2259 puts "</#{@s[0]}>" if (lev==0)
2260 when 1
2261 puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1]
2262 puts "</#{@s[0]}>" if (lev==0)
2263 when 2
2264 puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2]
2265 puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1]
2266 puts "</#{@s[0]}>" if (lev==0)
2267 when 3
2268 puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3]
2269 puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2]
2270 puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1]
2271 puts "</#{@s[0]}>" if (lev==0)
2272 when 4
2273 puts "#{spaces*4}</#{@s[4]}>" if (lev <= 4)
2274 puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3]
2275 puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2]
2276 puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1]
2277 puts "</#{@s[0]}>" if (lev==0)
2278 when 5
2279 puts "#{spaces*5}</#{@s[5]}>" if (lev <= 5)
2280 puts "#{spaces*4}</#{@s[4]}>" if (lev <= 4)
2281 puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3]
2282 puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2]
2283 puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1]
2284 puts "</#{@s[0]}>" if (lev==0)
2285 when 6
2286 puts "#{spaces*6}</#{@s[6]}>" if (lev <= 6)
2287 puts "#{spaces*5}</#{@s[5]}>" if (lev <= 5)
2288 puts "#{spaces*4}</#{@s[4]}>" if (lev <= 4)
2289 puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3]
2290 puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2]
2291 puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1]
2292 puts "</#{@s[0]}>" if (lev==0)
2293 end
2294 end
2295 end
2296 end
2297 __END__