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