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