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