bf7716dc5c0cda379e82648e8f7aa22dba2c5de7
[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)
1237 @md,@data=md,data
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 unless (defined? @md.title \
1298 and @md.title.full)
1299 STDERR.puts %{required header missing:
1300
1301 @title:
1302 SKIPPED processing file:
1303 [#{@md.opt.lng}] "#{@md.fns}"
1304 }
1305 if @md.opt.act[:no_stop][:set]==:on
1306 $process_document = :skip
1307 else exit
1308 end
1309 end
1310 unless (defined? @md.creator.author \
1311 and @md.creator.author)
1312 STDERR.puts %{required header missing:
1313
1314 @creator:
1315 :author: anonymous?
1316 SKIPPED processing file:
1317 [#{@md.opt.lng}] "#{@md.fns}"
1318 }
1319 if @md.opt.act[:no_stop][:set]==:on
1320 $process_document = :skip
1321 else exit
1322 end
1323 end
1324 end
1325 def ocn #and auto segment numbering increment
1326 required_headers_present?
1327 data=@data
1328 @o_array=[]
1329 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
1330 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 #ยก
1331 parent=node1=node2=node3=node4=node5=node6=node7=nil
1332 node0='0:0;0'
1333 @collapsed_lv0=0
1334 @lev_occurences={ a: 0, b: 0, c: 0, d: 0, l1: 0, l2: 0, l3: 0, l4: 0 }
1335 data.each do |dob|
1336 h={}
1337 if (dob.obj !~ regex_exclude_ocn_and_node || dob.is==:code) \
1338 && (dob.of !=:comment \
1339 && dob.of !=:layout \
1340 && dob.of !=:meta) \
1341 && dob.ocn_
1342 #dob.ln now is determined, and set earlier, check how best to remove this -->
1343 if dob.is==:heading
1344 @ln=ln=case dob.lv
1345 when 'A' then 0
1346 when 'B' then 1
1347 when 'C' then 2
1348 when 'D' then 3
1349 when '1' then 4
1350 when '2' then 5
1351 when '3' then 6
1352 when '4' then 7
1353 when '5' then 8
1354 when '6' then 9
1355 end
1356 end
1357 if not dob.obj =~/~#|-#/
1358 ocn+=1
1359 end
1360 if dob.is==:heading \
1361 and (ln.to_s =~/^[0-9]/ \
1362 or ln.to_s =~@md.lv0 \
1363 or ln.to_s =~@md.lv1 \
1364 or ln.to_s =~@md.lv2 \
1365 or ln.to_s =~@md.lv3 \
1366 or ln.to_s =~@md.lv4 \
1367 or ln.to_s =~@md.lv5 \
1368 or ln.to_s =~@md.lv6 \
1369 or ln.to_s =~@md.lv7)
1370 if not dob.obj =~/~#|-#/
1371 ocnh+=1
1372 end
1373 if ln==0 \
1374 or ln=~@md.lv0
1375 @lev_occurences[:a] += 1
1376 if not dob.obj =~/~#|-#/
1377 ocn_flag=true
1378 ocnh0+=1 #heading
1379 node0="0:#{ocnh0};#{ocn}"
1380 else
1381 #document_structure_check_info(node0,node0,:error) #fix
1382 ocn_flag=false
1383 node0="0:0;0"
1384 end
1385 document_structure_check_info(node0,node0)
1386 @collapsed_lv0=0
1387 collapsed_level=@collapsed_lv0
1388 node,ocn_sp,parent=node0,"h#{ocnh}",'ROOT'
1389 elsif ln==1 \
1390 or ln=~@md.lv1
1391 @lev_occurences[:b] += 1
1392 if not dob.obj =~/~#|-#/
1393 ocn_flag=true
1394 ocnh1+=1 #heading
1395 node1="1:#{ocnh1};#{ocn}"
1396 else
1397 #document_structure_check_info(node0,node0,:error) #fix
1398 ocn_flag=false
1399 node1="1:0;0"
1400 end
1401 parent=if node0
1402 document_structure_check_info(node1,node0)
1403 @collapsed_lv1=@collapsed_lv0+1
1404 node0
1405 else
1406 warning_incorrect_parent_level_or_level(dob.obj)
1407 document_structure_check_info(node0,node0,:error)
1408 node0
1409 end
1410 collapsed_level=@collapsed_lv1
1411 node,ocn_sp,parent=node1,"h#{ocnh}",node0 #FIX
1412 elsif ln==2 \
1413 or ln=~@md.lv2
1414 @lev_occurences[:c] += 1
1415 if not dob.obj =~/~#|-#/
1416 ocn_flag=true
1417 ocnh2+=1
1418 node2="2:#{ocnh2};#{ocn}"
1419 else
1420 #document_structure_check_info(node0,node0,:error) #fix
1421 ocn_flag=false
1422 node2="2:0;0"
1423 end
1424 parent=if node1
1425 document_structure_check_info(node2,node1)
1426 @collapsed_lv2=@collapsed_lv1+1
1427 node1
1428 else
1429 warning_incorrect_parent_level_or_level(dob.obj)
1430 document_structure_check_info(node2,node0,:error)
1431 node0
1432 end
1433 collapsed_level=@collapsed_lv2
1434 node,ocn_sp=node2,"h#{ocnh}"
1435 elsif ln==3 \
1436 or ln=~@md.lv3
1437 @lev_occurences[:d] += 1
1438 if not dob.obj =~/~#|-#/
1439 ocn_flag=true
1440 ocnh3+=1
1441 node3="3:#{ocnh3};#{ocn}"
1442 else
1443 #document_structure_check_info(node0,node0,:error) #fix
1444 ocn_flag=false
1445 node3="3:0;0"
1446 end
1447 parent=if node2
1448 document_structure_check_info(node3,node2)
1449 @collapsed_lv3=@collapsed_lv2+1
1450 node2
1451 elsif node1
1452 warning_incorrect_parent_level_or_level(dob.obj)
1453 puts %{parent is :A~ & this level #{dob.lv}
1454 either parent should be level :B~
1455 or this level should be level :B~ rather than #{dob.lv}}
1456 document_structure_check_info(node3,node1,:error)
1457 @collapsed_lv3=@collapsed_lv1+1
1458 node1
1459 else
1460 document_structure_check_info(node3,node0,:error)
1461 warning_incorrect_parent_level_or_level(dob.obj)
1462 node0
1463 end
1464 collapsed_level=@collapsed_lv3
1465 node,ocn_sp=node3,"h#{ocnh}"
1466 elsif ln==4 \
1467 or ln=~@md.lv4
1468 @lev_occurences[:l1] += 1
1469 if not dob.obj =~/~#|-#/
1470 ocn_flag=true
1471 ocnh4+=1
1472 node4="4:#{ocnh4};#{ocn}"
1473 else
1474 ocn_flag=false
1475 node4="4:0;0"
1476 end
1477 parent=if node3
1478 document_structure_check_info(node4,node3)
1479 @collapsed_lv4=@collapsed_lv3+1
1480 node3
1481 elsif node2
1482 document_structure_check_info(node4,node2)
1483 @collapsed_lv4=@collapsed_lv2+1
1484 node2
1485 elsif node1
1486 document_structure_check_info(node4,node1)
1487 @collapsed_lv4=@collapsed_lv1+1
1488 node1
1489 elsif node0
1490 document_structure_check_info(node4,node0)
1491 @collapsed_lv4=@collapsed_lv0+1
1492 node0
1493 else
1494 warning_incorrect_parent_level_or_level(dob.obj)
1495 document_structure_check_info(node4,node0,:error)
1496 node0
1497 end
1498 collapsed_level=@collapsed_lv4
1499 node,ocn_sp=node4,"h#{ocnh}"
1500 elsif ln==5 \
1501 or ln=~@md.lv5
1502 @lev_occurences[:l2] += 1
1503 if not dob.obj =~/~#|-#/
1504 ocn_flag=true
1505 ocnh5+=1
1506 node5="5:#{ocnh5};#{ocn}"
1507 else
1508 ocn_flag=false
1509 node5="5:0;0"
1510 end
1511 parent=if node4
1512 document_structure_check_info(node5,node4)
1513 @collapsed_lv5=@collapsed_lv4+1
1514 node4
1515 elsif node3
1516 warning_incorrect_parent_level_or_level(dob.obj)
1517 document_structure_check_info(node5,node3,:error)
1518 @collapsed_lv5=@collapsed_lv3+1
1519 node3
1520 elsif node2
1521 warning_incorrect_parent_level_or_level(dob.obj)
1522 document_structure_check_info(node5,node2,:error)
1523 @collapsed_lv5=@collapsed_lv2+1
1524 node2
1525 elsif node1
1526 warning_incorrect_parent_level_or_level(dob.obj)
1527 document_structure_check_info(node5,node1,:error)
1528 @collapsed_lv5=@collapsed_lv1+1
1529 node1
1530 else
1531 warning_incorrect_parent_level_or_level(dob.obj)
1532 document_structure_check_info(node5,node0,:error)
1533 node0
1534 end
1535 collapsed_level=@collapsed_lv5
1536 node,ocn_sp=node5,"h#{ocnh}"
1537 elsif ln==6 \
1538 or ln=~@md.lv6
1539 @lev_occurences[:l3] += 1
1540 if not dob.obj =~/~#|-#/
1541 ocn_flag=true
1542 ocnh6+=1
1543 node6="6:#{ocnh6};#{ocn}"
1544 else
1545 ocn_flag=false
1546 node6="6:0;0"
1547 end
1548 parent=if node5
1549 document_structure_check_info(node6,node5)
1550 @collapsed_lv6=@collapsed_lv5+1
1551 node5
1552 elsif node4
1553 warning_incorrect_parent_level_or_level(dob.obj)
1554 puts "parent is level #4 (1~) & this level ##{dob.ln} (#{dob.lv}~)
1555 either parent should be level #5 (2~)
1556 or this level should be #5 (2~) rather ##{dob.ln} (#{dob.lv}~)"
1557 document_structure_check_info(node6,node4,:error)
1558 @collapsed_lv6=@collapsed_lv4+1
1559 node4
1560 elsif node3
1561 warning_incorrect_parent_level_or_level(dob.obj)
1562 document_structure_check_info(node6,node3,:error)
1563 @collapsed_lv6=@collapsed_lv3+1
1564 node3
1565 elsif node2
1566 warning_incorrect_parent_level_or_level(dob.obj)
1567 document_structure_check_info(node6,node2,:error)
1568 @collapsed_lv6=@collapsed_lv2+1
1569 node2
1570 elsif node1
1571 warning_incorrect_parent_level_or_level(dob.obj)
1572 document_structure_check_info(node6,node1,:error)
1573 @collapsed_lv6=@collapsed_lv1+1
1574 node1
1575 else
1576 warning_incorrect_parent_level_or_level(dob.obj)
1577 document_structure_check_info(node6,node0,:error)
1578 node0
1579 end
1580 collapsed_level=@collapsed_lv6
1581 node,ocn_sp=node6,"h#{ocnh}"
1582 elsif ln==7 \
1583 or ln=~@md.lv7
1584 @lev_occurences[:l4] += 1
1585 if not dob.obj =~/~#|-#/
1586 ocn_flag=true
1587 ocnh7+=1
1588 node7="7:#{ocnh7};#{ocn}"
1589 else
1590 ocn_flag=false
1591 node7="7:0;0"
1592 end
1593 parent=if node6
1594 document_structure_check_info(node7,node6)
1595 @collapsed_lv7=@collapsed_lv6+1
1596 node5
1597 elsif node5
1598 warning_incorrect_parent_level_or_level(dob.obj)
1599 puts "parent is level #5 (2~) & this level ##{dob.ln} (#{dob.lv}~)
1600 either parent should be level #6 (3~)
1601 or this level should be #6 (3~) rather ##{dob.ln} (#{dob.lv}~)"
1602 document_structure_check_info(node7,node5,:error)
1603 @collapsed_lv6=@collapsed_lv5+1
1604 node5
1605 elsif node4
1606 warning_incorrect_parent_level_or_level(dob.obj)
1607 puts "parent is level #4 (1~) & this level ##{dob.ln} (#{dob.lv}~)
1608 either parent should be level 6~
1609 or this level should be #6 (3~) rather ##{dob.ln} (#{dob.lv}~)"
1610 document_structure_check_info(node7,node4,:error)
1611 @collapsed_lv6=@collapsed_lv4+1
1612 node4
1613 elsif node3
1614 warning_incorrect_parent_level_or_level(dob.obj)
1615 document_structure_check_info(node7,node3,:error)
1616 @collapsed_lv6=@collapsed_lv3+1
1617 node3
1618 elsif node2
1619 warning_incorrect_parent_level_or_level(dob.obj)
1620 document_structure_check_info(node7,node2,:error)
1621 @collapsed_lv6=@collapsed_lv2+1
1622 node2
1623 elsif node1
1624 warning_incorrect_parent_level_or_level(dob.obj)
1625 document_structure_check_info(node7,node1,:error)
1626 @collapsed_lv6=@collapsed_lv1+1
1627 node1
1628 else
1629 warning_incorrect_parent_level_or_level(dob.obj)
1630 document_structure_check_info(node7,node0,:error)
1631 node0
1632 end
1633 collapsed_level=@collapsed_lv7
1634 node,ocn_sp=node7,"h#{ocnh}"
1635 end
1636 else
1637 unless @lev_occurences[:l1] > 0
1638 STDERR.puts %{Substantive text objects must follow a level 1~ heading and there are none at this point in processing: #{@lev_occurences[:l1]}
1639 SKIPPED processing file:
1640 [#{@md.opt.lng}] "#{@md.fns}"}
1641 puts dob.obj #.gsub(/^(.{1,80})/,'"\1"')
1642 exit
1643 end
1644 unless @ln >= 4
1645 lev=case @ln
1646 when 0 then 'A'
1647 when 1 then 'B'
1648 when 2 then 'C'
1649 when 3 then 'D'
1650 when 4 then '1'
1651 when 5 then '2'
1652 when 6 then '3'
1653 when 7 then '4'
1654 when 8 then '5'
1655 when 9 then '6'
1656 end
1657 STDERR.puts %{Substantive text objects must follow a level 1~ 2~ or 3~ heading: #{lev}~
1658 SKIPPED processing file:
1659 [#{@md.opt.lng}] "#{@md.fns}"}
1660 puts dob.obj.gsub(/^(.{1,80})/,'"\1"')
1661 if @md.opt.act[:no_stop][:set]==:on
1662 $process_document = :skip
1663 break
1664 else exit
1665 end
1666 end
1667 if not dob.obj =~/~#|-#/
1668 ocn_flag=true
1669 else
1670 ocn_flag=false
1671 end
1672 ocno+=1
1673 if dob.is==:table
1674 ocnt+=1
1675 ocn_sp,parent="t#{ocnt}",node
1676 elsif dob.is==:code
1677 ocnc+=1
1678 ocn_sp,parent="c#{ocnc}",node
1679 elsif dob.is==:group \
1680 || dob.is==:box \
1681 || dob.is==:block \
1682 || dob.is==:alt \
1683 || dob.is==:verse
1684 ocng+=1 #group, poem
1685 ocn_sp,parent="g#{ocng}",node
1686 elsif dob.is==:image #check
1687 ocni+=1
1688 ocn_sp,parent="i#{ocni}",node
1689 else ocnp+=1 #paragraph
1690 ocn_sp,parent="p#{ocnp}",node
1691 end
1692 end
1693 if dob.is==:heading
1694 if ocn_flag==true
1695 dob.ln,dob.node,dob.ocn,dob.ocn_,dob.odv,dob.osp,dob.parent,dob.lc=
1696 ln, node, ocn, ocn_flag, ocn_dv,ocn_sp, parent, collapsed_level
1697 else
1698 ocnu+=1
1699 heading_use=:ok
1700 if dob.obj=~/#{Mx[:pa_non_object_no_heading]}/
1701 dob.obj=dob.obj.gsub(/#{Mx[:pa_non_object_no_heading]}/,'')
1702 heading_use=:ok
1703 elsif dob.obj=~/#{Mx[:pa_non_object_dummy_heading]}/
1704 dob.obj=dob.obj.gsub(/#{Mx[:pa_non_object_dummy_heading]}/,'')
1705 heading_use=:dummy
1706 end
1707 dob.ln,dob.node,dob.ocn,dob.ocn_,dob.use_, dob.odv,dob.osp,dob.parent,dob.lc=
1708 ln, node, nil, ocn_flag,heading_use,ocn_dv, ocn_sp, parent, collapsed_level
1709 end
1710 else
1711 if dob.of !=:meta \
1712 && dob.of !=:comment \
1713 && dob.of !=:layout
1714 if ocn_flag == true
1715 dob.ocn,dob.ocn_,dob.odv,dob.osp,dob.parent=
1716 ocn, ocn_flag,ocn_dv, ocn_sp, parent
1717 else
1718 ocnu+=1
1719 dob.obj=dob.obj.gsub(/#{Mx[:fa_o]}[~-]##{Mx[:fa_c]}/,'') if dob.obj
1720 ocn_dv,ocn_sp="u#{ocnu}","u#{ocnu}"
1721 dob.ocn,dob.ocn_,dob.odv,dob.osp,dob.parent=
1722 nil, ocn_flag,ocn_dv, ocn_sp, parent
1723 end
1724 end
1725 end
1726 h
1727 else dob
1728 end
1729 if dob.is==:code \
1730 || dob.is==:verse \
1731 || dob.is==:alt \
1732 || dob.is==:box \
1733 || dob.is==:group \
1734 || dob.is==:block
1735 dob.obj=dob.obj.gsub(/\n+/,"\n") #newlines taken out
1736 end
1737 @o_array << dob
1738 end
1739 unless @lev_occurences[:a] == 1
1740 STDERR.puts %{The number of level A~ in this document: #{@lev_occurences[:a]}
1741 There must be one level A~ (no more and no less)
1742 SKIPPED processing file:
1743 [#{@md.opt.lng}] "#{@md.fns}"}
1744 if @md.opt.act[:no_stop][:set]==:on
1745 $process_document = :skip
1746 else exit
1747 end
1748 end
1749 unless @lev_occurences[:l1] > 0
1750 STDERR.puts %{The number of level 1~ in this document: #{@lev_occurences[:l1]}
1751 There must be at least one level 1~ (and as many as required)
1752 SKIPPED processing file:
1753 [#{@md.opt.lng}] "#{@md.fns}"}
1754 if @md.opt.act[:no_stop][:set]==:on
1755 $process_document = :skip
1756 else exit
1757 end
1758 end
1759 @o_array
1760 end
1761 end
1762 class XML
1763 def initialize(md,data)
1764 @data,@md=data,md
1765 end
1766 def dom
1767 @s=[ 'A', 'B', 'C', 'D', '1', '2', '3' ]
1768 tuned_file=structure_build
1769 tuned_file
1770 end
1771 def spaces
1772 Ax[:spaces]
1773 end
1774 def structure_build
1775 data=@data
1776 tuned_file=[]
1777 hs=[0,false,false,false]
1778 t={
1779 lv: @s[0],
1780 status: :open,
1781 }
1782 tuned_file << tags(t)
1783 if @md.opt.act[:verbose_plus][:set]==:on
1784 puts "\nXML sisu structure outline --->\n"
1785 puts "<#{@s[0]}>"
1786 end
1787 data.each_with_index do |o,i|
1788 if o.is==:heading \
1789 || o.is==:heading_insert
1790 case o.ln
1791 when 0
1792 tuned_file << tag_close(o.ln,hs)
1793 tuned_file << tag_open(o,@s)
1794 if @md.opt.act[:verbose_plus][:set]==:on
1795 puts_tag_close(o.ln,hs)
1796 puts_tag_open(o,@s)
1797 end
1798 hs=[0,true,false,false,false]
1799 when 1
1800 tuned_file << tag_close(o.ln,hs)
1801 tuned_file << tag_open(o,@s)
1802 if @md.opt.act[:verbose_plus][:set]==:on
1803 puts_tag_close(o.ln,hs)
1804 puts_tag_open(o,@s)
1805 end
1806 hs=[1,true,true,false,false]
1807 when 2
1808 tuned_file << tag_close(o.ln,hs)
1809 tuned_file << tag_open(o,@s)
1810 if @md.opt.act[:verbose_plus][:set]==:on
1811 puts_tag_close(o.ln,hs)
1812 puts_tag_open(o,@s)
1813 end
1814 hs=[2,true,true,true,false]
1815 when 3
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=[3,true,true,true,true]
1823 when 4
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[0]=4
1831 when 5
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[0]=5
1839 when 6
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[0]=6
1847 end
1848 end
1849 tuned_file << o
1850 end
1851 if @md.opt.act[:verbose_plus][:set]==:on
1852 puts_tag_close(0,hs)
1853 end
1854 tuned_file << tag_close(0,hs)
1855 tuned_file=tuned_file.flatten
1856 end
1857 def tags(o)
1858 tag=(o[:status]==:open) \
1859 ? %{<#{o[:lv]} id="#{o[:node]}">}
1860 : "</#{o[:lv]}>"
1861 ln=case o[:lv]
1862 when 'A' then 0
1863 when 'B' then 1
1864 when 'C' then 2
1865 when 'D' then 3
1866 when '1' then 4
1867 when '2' then 5
1868 when '3' then 6
1869 when '4' then 7
1870 when '5' then 8
1871 when '6' then 9
1872 end
1873 h={
1874 tag: tag,
1875 node: o[:node],
1876 lv: o[:lv],
1877 ln: ln,
1878 status: o[:status],
1879 }
1880 SiSU_AO_DocumentStructure::ObjectStructure.new.xml_dom(h) #downstream code utilise else ignore like comments
1881 end
1882 def tag_open(o,tag)
1883 t={ lv: tag[o.ln], node: o.node, status: :open }
1884 t_o=tags(t)
1885 t_o
1886 end
1887 def tag_close(lev,hs)
1888 ary=[]
1889 case hs[0]
1890 when 0
1891 if (lev <= 0) and hs[0]
1892 t={
1893 lv: @s[0],
1894 status: :close,
1895 }
1896 ary << tags(t)
1897 end
1898 when 1
1899 if (lev <= 1) and hs[1]
1900 t={
1901 lv: @s[1],
1902 status: :close,
1903 }
1904 ary << tags(t)
1905 end
1906 if (lev==0)
1907 t={
1908 lv: @s[0],
1909 status: :close,
1910 }
1911 ary << tags(t)
1912 end
1913 when 2
1914 if (lev <= 2) and hs[2]
1915 t={
1916 lv: @s[2],
1917 status: :close,
1918 }
1919 ary << tags(t)
1920 end
1921 if (lev <= 1) and hs[1]
1922 t={
1923 lv: @s[1],
1924 status: :close,
1925 }
1926 ary << tags(t)
1927 end
1928 if (lev==0)
1929 t={
1930 lv: @s[0],
1931 status: :close,
1932 }
1933 ary << tags(t)
1934 end
1935 when 3
1936 if (lev <= 3) and hs[3]
1937 t={
1938 lv: @s[3],
1939 status: :close,
1940 }
1941 ary << tags(t)
1942 end
1943 if (lev <= 2) and hs[2]
1944 t={
1945 lv: @s[2],
1946 status: :close,
1947 }
1948 ary << tags(t)
1949 end
1950 if (lev <= 1) and hs[1]
1951 t={
1952 lv: @s[1],
1953 status: :close,
1954 }
1955 ary << tags(t)
1956 end
1957 if (lev==0)
1958 t={
1959 lv: @s[0],
1960 status: :close,
1961 }
1962 ary << tags(t)
1963 end
1964 when 4
1965 if (lev <= 4)
1966 t={
1967 lv: @s[4],
1968 status: :close,
1969 }
1970 ary << tags(t)
1971 end
1972 if (lev <= 3) and hs[3]
1973 t={
1974 lv: @s[3],
1975 status: :close,
1976 }
1977 ary << tags(t)
1978 end
1979 if (lev <= 2) and hs[2]
1980 t={
1981 lv: @s[2],
1982 status: :close,
1983 }
1984 ary << tags(t)
1985 end
1986 if (lev <= 1) and hs[1]
1987 t={
1988 lv: @s[1],
1989 status: :close,
1990 }
1991 ary << tags(t)
1992 end
1993 if (lev==0)
1994 t={
1995 lv: @s[0],
1996 status: :close,
1997 }
1998 ary << tags(t)
1999 end
2000 when 5
2001 if (lev <= 5)
2002 t={
2003 lv: @s[5],
2004 status: :close,
2005 }
2006 ary << tags(t)
2007 end
2008 if (lev <= 4)
2009 t={
2010 lv: @s[4],
2011 status: :close,
2012 }
2013 ary << tags(t)
2014 end
2015 if (lev <= 3) and hs[3]
2016 t={
2017 lv: @s[3],
2018 status: :close,
2019 }
2020 ary << tags(t)
2021 end
2022 if (lev <= 2) and hs[2]
2023 t={
2024 lv: @s[2],
2025 status: :close,
2026 }
2027 ary << tags(t)
2028 end
2029 if (lev <= 1) and hs[1]
2030 t={
2031 lv: @s[1],
2032 status: :close,
2033 }
2034 ary << tags(t)
2035 end
2036 if (lev==0)
2037 t={
2038 lv: @s[0],
2039 status: :close,
2040 }
2041 ary << tags(t)
2042 end
2043 when 6
2044 if (lev <= 6)
2045 t={
2046 lv: @s[6],
2047 status: :close,
2048 }
2049 ary << tags(t)
2050 end
2051 if (lev <= 5)
2052 t={
2053 lv: @s[5],
2054 status: :close,
2055 }
2056 ary << tags(t)
2057 end
2058 if (lev <= 4)
2059 t={
2060 lv: @s[4],
2061 status: :close,
2062 }
2063 ary << tags(t)
2064 end
2065 if (lev <= 3) and hs[3]
2066 t={
2067 lv: @s[3],
2068 status: :close,
2069 }
2070 ary << tags(t)
2071 end
2072 if (lev <= 2) and hs[2]
2073 t={
2074 lv: @s[2],
2075 status: :close,
2076 }
2077 ary << tags(t)
2078 end
2079 if (lev <= 1) and hs[1]
2080 t={
2081 lv: @s[1],
2082 status: :close,
2083 }
2084 ary << tags(t)
2085 end
2086 if (lev==0)
2087 t={
2088 lv: @s[0],
2089 status: :close,
2090 }
2091 ary << tags(t)
2092 end
2093 end
2094 ary
2095 end
2096 def puts_tag_open(o,tag)
2097 puts %{#{spaces*o.ln}<#{tag[o.ln]} id="#{o.node}">}
2098 end
2099 def puts_tag_close(lev,hs)
2100 case hs[0]
2101 when 0
2102 #puts "#{spaces*0}</#{@s[0]}>" if (lev <= 0) and hs[0]
2103 puts "</#{@s[0]}>" if (lev==0)
2104 when 1
2105 puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1]
2106 puts "</#{@s[0]}>" if (lev==0)
2107 when 2
2108 puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2]
2109 puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1]
2110 puts "</#{@s[0]}>" if (lev==0)
2111 when 3
2112 puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3]
2113 puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2]
2114 puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1]
2115 puts "</#{@s[0]}>" if (lev==0)
2116 when 4
2117 puts "#{spaces*4}</#{@s[4]}>" if (lev <= 4)
2118 puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3]
2119 puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2]
2120 puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1]
2121 puts "</#{@s[0]}>" if (lev==0)
2122 when 5
2123 puts "#{spaces*5}</#{@s[5]}>" if (lev <= 5)
2124 puts "#{spaces*4}</#{@s[4]}>" if (lev <= 4)
2125 puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3]
2126 puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2]
2127 puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1]
2128 puts "</#{@s[0]}>" if (lev==0)
2129 when 6
2130 puts "#{spaces*6}</#{@s[6]}>" if (lev <= 6)
2131 puts "#{spaces*5}</#{@s[5]}>" if (lev <= 5)
2132 puts "#{spaces*4}</#{@s[4]}>" if (lev <= 4)
2133 puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3]
2134 puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2]
2135 puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1]
2136 puts "</#{@s[0]}>" if (lev==0)
2137 end
2138 end
2139 end
2140 end
2141 __END__