# encoding: utf-8 =begin * Name: SiSU * Description: a framework for document structuring, publishing and search * Author: Ralph Amissah * Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Ralph Amissah, All Rights Reserved. * License: GPL 3 or later: SiSU, a framework for document structuring, publishing and search Copyright (C) Ralph Amissah This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . If you have Internet connection, the latest version of the GPL should be available at these locations: * SiSU uses: * Standard SiSU markup syntax, * Standard SiSU meta-markup syntax, and the * Standard SiSU object citation numbering and system * Hompages: * Download: * Git * Ralph Amissah ** Description: document abstraction =end module SiSU_DAL_DocumentStructureExtract class Instantiate < SiSU_Param::Parameters::Instructions @@flag={} #Beware!! def initialize @@flag['table_to']=false @@counter=@@column=@@columns=0 @@line_mode='' end end class Build @@flag={} #Beware!! def initialize(md,data) @md,@data=md,data SiSU_DAL_DocumentStructureExtract::Instantiate.new @pb=SiSU_DAL_DocumentStructure::ObjectLayout.new.break(Hx[:br_page]) @pbn=SiSU_DAL_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_new]) @pbl=SiSU_DAL_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_line]) end def ln_get(lv) ln=case lv when /A/; 1 when /B/; 2 when /C/; 3 when /1/; 4 when /2/; 5 when /3/; 6 when /4/; 7 when /5/; 8 when /6/; 9 end end def image_test(str) boolean=(str=~/\{\s*\S+?\.png.+?\}https?:\/\/\S+/ ? true : false) end def bullet_test(str) bool=((str=~/\*/) ? true : false) end def hang_and_indent_test(str) hang_indent=if str=~/^_([1-9])[^_]/ [$1,$1] elsif str=~/^__([1-9])/ [0,$1] elsif str=~/^_([0-9])_([0-9])/ [$1,$2] else [0,0] end hang,indent=hang_indent[0],hang_indent[1] [hang,indent] end def hang_and_indent_def_test(str1,str2) hang_indent=if str1=~/^_([1-9])[^_]/ [$1,$1] elsif str1=~/^__([1-9])/ [0,$1] elsif str1=~/^_([0-9])_([0-9])/ [$1,$2] else [0,0] end obj=if str2 =~/^(.+?)\s+\\\\(?:\s+|\n)/ str2.gsub(/^(.+?)(\s+\\\\(?:\s+|\n))/,"#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\\2") else str2.gsub(/^(.+?)\n/,"#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\n") end hang,indent=hang_indent[0],hang_indent[1] [hang,indent,obj] end def endnote_test?(str) bool=((str=~/~\{.+?\}~|~\[.+?\]~/) ? true : false) end def extract_tags(str,nametag=nil) tags=[] if str.nil? else if str =~/(?:^|[ ])\*~([a-z0-9._-]+)(?=[ #{Mx[:br_nl]}]|$)/ str=str.gsub(/(^|[ ])\*~([a-z0-9._-]+)(?=[ #{Mx[:br_nl]}]|$)/i, "\\1#{Mx[:tag_o]}\\2#{Mx[:tag_c]}"). gsub(/ [ ]+/i,' ') tags=str.scan(/#{Mx[:tag_o]}(\S+?)#{Mx[:tag_c]}/).flatten str=str.gsub(/[ ]?#{Mx[:tag_o]}\S+?#{Mx[:tag_c]}[ ]?/,' ') #may be issues with spaces would leave one, but "code" blocks? end tags=nametag ? (tags << nametag) : tags end [str,tags] end def identify_parts data=@data tuned_file=[] @tuned_block,@tuned_code=[],[] @@counter,@verse_count=0,0 @metadata={} @data.each do |t_o| t_o=t_o.gsub(/(?:\n\s*\n)+/m,"\n") unless @@flag['code'] if t_o !~/^(?:code|poem|alt|group|block)\{|^\}(?:code|poem|alt|group|block)|^(?:table\{|\{table)[ ~]/ \ and not @@flag['code'] \ and not @@flag['poem'] \ and not @@flag['group'] \ and not @@flag['block'] \ and not @@flag['alt'] \ and not @@flag['table'] unless t_o =~/^(?:@\S+?:|%+)\s/ # extract book index for paragraph if any idx=if t_o=~/^=\{(.+)\}\s*$\Z/m; m=$1 t_o=t_o.gsub(/\n=\{.+\}\s*$\Z/m,'') m else nil end end t_o=case t_o when /^#{Mx[:meta_o]}\S+?#{Mx[:meta_c]}/ #metadata, header if t_o=~/^#{Mx[:meta_o]}(\S+?)#{Mx[:meta_c]}\s*(.+)/m tag,obj=$1,$2 @metadata[tag]=obj end t_o=nil when /^%+\s/ #comment t_o=if t_o=~/^%+\s+(.+)/ h={obj: $1} SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) else nil end when /^:?([A-C1-6])\~/ #heading / lv lv=$1 ln=ln_get(lv) t_o=if t_o=~/^:?[A-C1-6]\~\s+(.+)/m obj=$1 note=endnote_test?(obj) obj,tags=extract_tags(obj) h={ lv: lv, ln: ln, obj: obj, idx: idx, tags: tags } SiSU_DAL_DocumentStructure::ObjectHeading.new.heading(h) elsif t_o=~/^:?[A-C1-6]\~(\S+?)-\s+(.+)/m name,obj=$1,$2 note=endnote_test?(obj) obj,tags=extract_tags(obj) h={ lv: lv, name: name, obj: obj, idx: idx, autonum_: false, tags: tags} SiSU_DAL_DocumentStructure::ObjectHeading.new.heading(h) elsif t_o=~/^:?[A-C1-6]\~(\S+)\s+(.+)/m name,obj=$1,$2 note=endnote_test?(obj) obj,tags=extract_tags(obj,name) h={ lv: lv, name: name, obj: obj, idx: idx, tags: tags } SiSU_DAL_DocumentStructure::ObjectHeading.new.heading(h) else nil end when /^_(?:[1-9]!?|[1-9]?\*)\s+/ #indented and/or bullet paragraph t_o=if t_o=~/^(_(?:[1-9]?\*|[1-9]!?)\s+)(.+)/m tst,obj=$1,$2 if t_o=~/^_[1-9]!\s+.+/m hang,indent,obj=hang_and_indent_def_test(tst,obj) else hang,indent=hang_and_indent_test(tst) end bullet=bullet_test(tst) image=image_test(obj) note=endnote_test?(obj) obj,tags=extract_tags(obj) unless obj=~/\A\s*\Z/m h={ bullet_: bullet, hang: hang, indent: indent, obj: obj, idx: idx, note_: note, image_: image, tags: tags } SiSU_DAL_DocumentStructure::ObjectPara.new.paragraph(h) end else nil end when /^_[0-9]?_[0-9]!?\s+/ #hanging indent paragraph t_o=if t_o=~/^(_[0-9]?_[0-9]!?\s+)(.+)/m tst,obj=$1,$2 if t_o=~/^_[0-9]?_[0-9]!\s+.+/m hang,indent,obj=hang_and_indent_def_test(tst,obj) else hang,indent=hang_and_indent_test(tst) end image=image_test(obj) note=endnote_test?(obj) obj,tags=extract_tags(obj) unless obj=~/\A\s*\Z/m h={ hang: hang, indent: indent, obj: obj, idx: idx, note_: note, image_: image, tags: tags } SiSU_DAL_DocumentStructure::ObjectPara.new.paragraph(h) end else nil end when /^<(?:br)?:(?:pa?r|o(?:bj|---)?)>\s*$/ #[br:par] #[br:obj] SiSU_DAL_DocumentStructure::ObjectLayout.new.break(Hx[:br_obj]) when /^(?:-\\\\-|<:pb>)\s*$/ #[br:pg] SiSU_DAL_DocumentStructure::ObjectLayout.new.break(Hx[:br_page],:markup) when /^(?:=\\\\=|<:pn>)\s*$/ #[br:pgn] SiSU_DAL_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_new],:markup) when /^-\.\.-\s*$/ #[br:pgl] SiSU_DAL_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_line],:markup) else #paragraph image=image_test(t_o) note=endnote_test?(t_o) obj,tags=extract_tags(t_o) unless obj=~/\A\s*\Z/m h={ bullet_: false, indent: 0, hang: 0, obj: obj, idx: idx, note_: note, image_: image, tags: tags } SiSU_DAL_DocumentStructure::ObjectPara.new.paragraph(h) end end elsif not @@flag['code'] if t_o =~/^code\{/ @@flag['code']=true @@counter=1 @codeblock_numbered=(t_o =~/^code\{#/) ? true : false h={ obj: 'code block start' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) #t_o=SiSU_DAL_DocumentStructure::ObjectLayout.new.insert(h) elsif t_o =~/^poem\{/ @@flag['poem']=true h={ obj: 'poem start' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) #t_o=SiSU_DAL_DocumentStructure::ObjectLayout.new.insert(h) tuned_file << t_o elsif t_o =~/^group\{/ @@flag['group']=true h={ obj: 'group text start' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) #t_o=SiSU_DAL_DocumentStructure::ObjectLayout.new.insert(h) tuned_file << t_o elsif t_o =~/^block\{/ @@flag['block']=true h={ obj: 'block text start' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) #t_o=SiSU_DAL_DocumentStructure::ObjectLayout.new.insert(h) tuned_file << t_o elsif t_o =~/^alt\{/ @@flag['alt']=true h={ obj: 'alt text start' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) #t_o=SiSU_DAL_DocumentStructure::ObjectLayout.new.insert(h) tuned_file << t_o elsif t_o =~/^(?:table\{|\{table)[ ~]/ h={ obj: 'table start' } #introduce a counter ins=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) #ins=SiSU_DAL_DocumentStructure::ObjectLayout.new.insert(h) tuned_file << ins if t_o=~/^table\{(?:~h)?\s+/ @@flag['table']=true @rows='' case t_o when /table\{~h\s+c(\d+);\s+(.+)/ cols=$1 col=$2.scan(/\d+/) heading=true when /table\{\s+c(\d+);\s+(.+)/ cols=$1 col=$2.scan(/\d+/) heading=false end @h={ head_: heading, cols: cols, widths: col, idx: idx } elsif t_o=~/^\{table(?:~h)?(?:\s+\d+;?)?\}\n.+\Z/m m1,m2,hd=nil,nil,nil tbl=/^\{table(?:~h)?(?:\s+\d+;?)?\}\n(.+)\Z/m.match(t_o)[1] #two table representations should be consolidated as one hd=((t_o =~/^\{table~h/) ? true : false) tbl,tags=extract_tags(tbl) rws=tbl.split(/\n/) rows='' cols=nil rws.each do |r| cols=(cols ? cols : (r.scan('|').length) +1) r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}") #r.gsub!(/\|/m,"#{Mx[:tc_p]}") rows += r + Mx[:tc_c] end col=[] if t_o =~/^\{table(?:~h)?\s+(\d+);?\}/ #width of col 1 given as %, usually when wider than rest that are even c1=$1.to_i width=(100 - c1)/(cols - 1) col=[ c1 ] (cols - 1).times { col << width } else #all columns of equal width width=100.00/cols cols.times { col << width } end h={ head_: hd, cols: cols, widths: col, obj: rows, idx: idx, tags: tags } t_o=SiSU_DAL_DocumentStructure::ObjectTable.new.table(h) unless h.nil? tuned_file << t_o h={ obj: 'table end' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) t_o elsif t_o=~/^\{table(?:~h)?\s+/ m1,m2,hd=nil,nil,nil h=case t_o when /\{table~h\s+(.+?)\}\n(.+)\Z/m #two table representations should be consolidated as one m1,tbl,hd=$1,$2,true when /\{table\s+(.+?)\}\n(.+)\Z/m #two table representations should be consolidated as one m1,tbl,hd=$1,$2,false else nil end tbl,tags=extract_tags(tbl) col=m1.scan(/\d+/) rws=tbl.split(/\n/) rows='' rws.each do |r| r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}") #r.gsub!(/\|/m,"#{Mx[:tc_p]}") rows += r + Mx[:tc_c] end h={ head_: hd, cols: col.length, widths: col, obj: rows, idx: idx, tags: tags } t_o=SiSU_DAL_DocumentStructure::ObjectTable.new.table(h) unless h.nil? tuned_file << t_o h={ obj: 'table end' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) t_o end end t_o end if @@flag['table'] if @@flag['table'] \ and t_o =~/^\}table/ #two table representations should be consolidated as one @@flag['table']=false headings,columns,widths,idx=@h[:head_],@h[:cols],@h[:widths],@h[:idx] @h={ head_: headings, cols: columns, widths: widths, idx: idx, obj: @rows } t_o=SiSU_DAL_DocumentStructure::ObjectTable.new.table(@h) tuned_file << t_o @h,@rows=nil,'' t_o h={ obj: 'table end' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) #t_o=SiSU_DAL_DocumentStructure::ObjectLayout.new.insert(h) t_o else if t_o.is_a?(String) \ and t_o !~/^table\{/ t_o=t_o.gsub(/^\n+/m,''). #check added for ruby 1.9.2 not needed in 1.8 series (tested in v2) gsub(/\n+/m,"#{Mx[:tc_p]}") @rows += t_o + Mx[:tc_c] end t_o=nil end end if @@flag['code'] if t_o =~/^\}code/ @@flag['code']=false obj=@tuned_code.join("\n") tags=[] h={ obj: obj, tags: tags, number_: @codeblock_numbered } t_o=SiSU_DAL_DocumentStructure::ObjectBlockTxt.new.code(h) @tuned_code=[] tuned_file << t_o h={ obj: 'code block end' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) #t_o=SiSU_DAL_DocumentStructure::ObjectLayout.new.insert(h) end if @@flag['code'] \ and t_o.is_a?(String) sub_array=t_o.dup + "#{Mx[:br_nl]}" @line_mode=sub_array.scan(/.+/) @line_mode=[] sub_array.scan(/.+/) {|w| @line_mode << w if w =~/[\S]+/} t_o=SiSU_DAL_DocumentStructureExtract::Build.new(@md,@line_mode).build_lines('code').join @tuned_code << t_o t_o=nil end elsif @@flag['poem'] \ or @@flag['group'] \ or @@flag['block'] \ or @@flag['alt'] if @@flag['poem'] \ and t_o =~/^\}poem/ @@flag['poem']=false h={ obj: 'poem end' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) #t_o=SiSU_DAL_DocumentStructure::ObjectLayout.new.insert(h) elsif ( @@flag['group'] \ and t_o =~/^\}group/ ) @@flag['group']=false obj,tags=extract_tags(@tuned_block.join("\n")) h={ obj: obj, tags: tags } @tuned_block=[] t_o=SiSU_DAL_DocumentStructure::ObjectBlockTxt.new.group(h) tuned_file << t_o h={ obj: 'group text end' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) #t_o=SiSU_DAL_DocumentStructure::ObjectLayout.new.insert(h) elsif ( @@flag['block'] \ and t_o =~/^\}block/ ) @@flag['block']=false obj,tags=extract_tags(@tuned_block.join("\n")) h={ obj: obj, tags: tags } @tuned_block=[] t_o=SiSU_DAL_DocumentStructure::ObjectBlockTxt.new.block(h) tuned_file << t_o h={ obj: 'block text end' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) #t_o=SiSU_DAL_DocumentStructure::ObjectLayout.new.insert(h) elsif ( @@flag['alt'] \ and t_o =~/^\}alt/ ) @@flag['alt']=false obj,tags=extract_tags(@tuned_block.join("\n")) h={ obj: obj, tags: tags } t_o=SiSU_DAL_DocumentStructure::ObjectBlockTxt.new.alt(h) @tuned_block=[] tuned_file << t_o h={ obj: 'alt text end' } #introduce a counter t_o=SiSU_DAL_DocumentStructure::ObjectComment.new.comment(h) #t_o=SiSU_DAL_DocumentStructure::ObjectLayout.new.insert(h) end if @@flag['poem'] \ or @@flag['group'] \ or @@flag['alt'] \ and t_o =~/\S/ \ and t_o !~/^(?:\}(?:verse|code|alt|group|block)|(?:verse|code|alt|group|block)\{)/ # fix logic sub_array=t_o.dup @line_mode=sub_array.scan(/.+/) type=if @@flag['poem']; 'poem' t_o=SiSU_DAL_DocumentStructureExtract::Build.new(@md,@line_mode).build_lines(type).join poem=t_o.split(/\n\n/) poem.each do |v| v=v.gsub(/\n/m,"#{Mx[:br_nl]}\n") obj,tags=extract_tags(v) h={ obj: obj, tags: tags } t_o=SiSU_DAL_DocumentStructure::ObjectBlockTxt.new.verse(h) tuned_file << t_o end else 'group' end @verse_count+=1 if @@flag['poem'] end end if not @@flag['code'] if @@flag['poem'] \ or @@flag['group'] \ or @@flag['alt'] if t_o.is_a?(String) t_o=t_o.gsub(/\n/m,"#{Mx[:br_nl]}"). gsub(/[ ][ ]/m,"#{Mx[:nbsp]*2}"). gsub(/#{Mx[:nbsp]}\s/,"#{Mx[:nbsp]*2}") t_o=t_o + Mx[:br_nl] if t_o =~/\S+/ elsif t_o.is==:group \ || t_o.is==:block \ || t_o.is==:alt \ || t_o.is==:verse t_o.obj=t_o.obj.gsub(/\n/m,"#{Mx[:br_nl]}"). gsub(/[ ][ ]/m,"#{Mx[:nbsp]*2}"). gsub(/#{Mx[:nbsp]}\s/,"#{Mx[:nbsp]*2}") end @tuned_block << t_o if t_o =~/\S+/ else tuned_file << t_o end else tuned_file << t_o end end if @md.flag_endnotes tuned_file << @pb h={ ln: 2, obj: 'Endnotes', autonum_: false } tuned_file << SiSU_DAL_DocumentStructure::ObjectHeading.new.heading_insert(h) h={ ln: 4, obj: 'Endnotes', name: 'endnotes', autonum_: false } tuned_file << SiSU_DAL_DocumentStructure::ObjectHeading.new.heading_insert(h) h={ obj: 'Endnotes' } end if @md.book_idx tuned_file << @pb h={ ln: 2, obj: 'Index', autonum_: false } tuned_file << SiSU_DAL_DocumentStructure::ObjectHeading.new.heading_insert(h) h={ ln: 4, obj: 'Index', name: 'book_index', autonum_: false } tuned_file << SiSU_DAL_DocumentStructure::ObjectHeading.new.heading_insert(h) h={ obj: 'Index' } end tuned_file << @pb h={ ln: 2, obj: 'Metadata', autonum_: false, ocn_: false } tuned_file << SiSU_DAL_DocumentStructure::ObjectHeading.new.heading_insert(h) h={ ln: 4, obj: 'SiSU Metadata, document information', name: 'metadata', autonum_: false, ocn_: false } tuned_file << SiSU_DAL_DocumentStructure::ObjectHeading.new.heading_insert(h) tuned_file h={ obj: 'eof' } meta=SiSU_DAL_DocumentStructure::ObjectMetadata.new.metadata(@metadata) [tuned_file,meta] end def table_rows_and_columns_array(table_str) table=[] table_str.split(/#{Mx[:tc_c]}/).each do |table_row| table_row_with_columns=table_row.split(/#{Mx[:tc_p]}/) table << table_row_with_columns end table end def meta_heading(h) h={ lv: h[:lv], ln: h[:ln], name: h[:name], obj: h[:obj], ocn: '0' } SiSU_DAL_DocumentStructure::ObjectHeading.new.heading(h) end def meta_para(str) h={ obj: str, ocn_: false } SiSU_DAL_DocumentStructure::ObjectPara.new.paragraph(h) end def build_lines(type='') lines,lines_new=@data,[] lines.each do |line| line=if line =~/\S/ \ and line !~/^code\{|^\}code/ \ and not line.is_a?(Hash) @@counter+=1 if @@flag['code'] line=line.gsub(/\s\s/,"#{Mx[:nbsp]*2}"). gsub(/#{Mx[:nbsp]}\s/,"#{Mx[:nbsp]*2}") line=line.gsub(/^/,"#{Mx[:gr_o]}codeline#{Mx[:gr_c]}") if type=='code' # REMOVE try sort for texpdf special case line=if line =~/(?:https?|file|ftp):\/\/\S+$/ line.gsub(/\s*$/," #{Mx[:br_nl]}") else line.gsub(/\s*$/,"#{Mx[:br_nl]}") #unless type=='code' end elsif line =~/^\s*$/ line.gsub(/\s*$/,"#{Mx[:br_nl]}") else line end lines_new << line end lines_new end end class Structure # this must happen early def initialize(md,dob) @md,@dob=md,dob end def structure structure_markup @dob end def structure_markup #build structure where structure provided only in meta header @dob=if @dob.is ==:para \ && (((@dob.hang !~/[1-9]/) && (@dob.indent !~/[1-9]/)) \ || (@dob.hang != @dob.indent)) \ and not @dob.bullet_ @dob=case @dob.obj when /^#{@md.lv1}/ h={ lv: 'A', ln: 1 } SiSU_DAL_DocumentStructure::ObjectHeading.new.heading(h,@dob) when /^#{@md.lv2}/ h={ lv: 'B', ln: 2 } SiSU_DAL_DocumentStructure::ObjectHeading.new.heading(h,@dob) when /^#{@md.lv3}/ h={ lv: 'C', ln: 3 } SiSU_DAL_DocumentStructure::ObjectHeading.new.heading(h,@dob) when /^#{@md.lv4}/ h={ lv: '1', ln: 4 } SiSU_DAL_DocumentStructure::ObjectHeading.new.heading(h,@dob) when /^#{@md.lv5}/ h={ lv: '2', ln: 5 } SiSU_DAL_DocumentStructure::ObjectHeading.new.heading(h,@dob) when /^#{@md.lv6}/ h={ lv: '3', ln: 6 } SiSU_DAL_DocumentStructure::ObjectHeading.new.heading(h,@dob) else @dob end else @dob end @dob end end class OCN def initialize(md,data) @md,@data=md,data end def ocn #and auto segment numbering increment data=@data @o_array=[] node=ocn=ocn_dv=ocn_sp=ocnh=ocnh1=ocnh2=ocnh3=ocnh4=ocnh5=ocnh6=ocno=ocnp=ocnt=ocnc=ocng=ocni=ocnm=ocnu=ocnk=nm=0 # h heading, o other, t table, g group, i image node_count_flag=false regex_exclude_ocn_and_node = /#{Rx[:meta]}|^@\S+?:\s|^4~endnotes|^#{Mx[:lv_o]}4:endnotes#{Mx[:lv_c]}|^\^~ |<:e[:_]\d+?>|^<:\#|<:- |<[:!]!4|
if dob.is==:heading ln=case dob.lv when 'A'; 1 when 'B'; 2 when 'C'; 3 when '1'; 4 when '2'; 5 when '3'; 6 when '4'; 7 when '5'; 8 when '6'; 9 end end if not dob.obj =~/<:#>|~#|-#/ \ or not dob.toc_ # fix this no longer in dob.obj ocn+=1 if dob.is==:heading \ and (ln.to_s =~/^[1-9]/ \ or ln.to_s =~@md.lv1 \ or ln.to_s =~@md.lv2 \ or ln.to_s =~@md.lv3 \ or ln.to_s =~@md.lv4 \ or ln.to_s =~@md.lv5 \ or ln.to_s =~@md.lv6) ocnh+=1 if ln==1 \ or ln=~@md.lv1; ocnh1+=1 #heading node1="1:#{ocnh1};#{ocn}" node,ocn_sp,parent=node1,"h#{ocnh}",0 #FIX elsif ln==2 \ or ln=~@md.lv2; ocnh2+=1 node2="2:#{ocnh2};#{ocn}" node,ocn_sp,parent=node2,"h#{ocnh}",node1 elsif ln==3 \ or ln=~@md.lv3; ocnh3+=1 node3="3:#{ocnh3};#{ocn}" node,ocn_sp,parent=node3,"h#{ocnh}",node2 elsif ln==4 \ or ln=~@md.lv4; ocnh4+=1 node4="4:#{ocnh4};#{ocn}" node,ocn_sp,parent=node4,"h#{ocnh}",node3 elsif ln==5 \ or ln=~@md.lv5; ocnh5+=1 node5="5:#{ocnh5};#{ocn}" node,ocn_sp,parent=node5,"h#{ocnh}",node4 elsif ln==6 \ or ln=~@md.lv6; ocnh6+=1 node6="6:#{ocnh6};#{ocn}" node,ocn_sp,parent=node6,"h#{ocnh}",node5 end else ocno+=1 if dob.is==:table ocnt+=1 ocn_sp,parent="t#{ocnt}",node elsif dob.is==:code ocnc+=1 ocn_sp,parent="c#{ocnc}",node elsif dob.is==:group \ || dob.is==:block \ || dob.is==:alt \ || dob.is==:verse ocng+=1 #group, poem ocn_sp,parent="g#{ocng}",node elsif dob.is==:image #check ocni+=1 ocn_sp,parent="i#{ocni}",node else ocnp+=1 #paragraph ocn_sp,parent="p#{ocnp}",node end end if dob.is==:heading dob.ln,dob.node,dob.ocn,dob.odv,dob.osp,dob.parent=ln,node,ocn,ocn_dv,ocn_sp,parent else if dob.of !=:meta \ && dob.of !=:comment \ && dob.of !=:layout dob.ocn,dob.odv,dob.osp,dob.parent=ocn,ocn_dv,ocn_sp,parent end end else ocnu+=1 dob.obj=dob.obj.gsub(/#{Mx[:fa_o]}~##{Mx[:fa_c]}/,'') if dob.obj ocn_dv,ocn_sp="u#{ocnu}","u#{ocnu}" dob.ocn,dob.odv,dob.osp=ocn,ocn_dv,ocn_sp end h elsif dob.obj=~/#{Mx[:pa_non_object_no_heading]}/ dob.obj=dob.obj.gsub(/#{Mx[:pa_non_object_no_heading]}/,'') if dob.is==:para h={ obj: dob.obj, ocn_: false, ocn: nil, hang: dob.hang, indent: dob.indent, bullet_: dob.bullet_, tags: dob.tags, parent: dob.parent } dob=SiSU_DAL_DocumentStructure::ObjectPara.new.paragraph(h,dob) elsif dob.is==:heading h={ obj: dob.obj, ocn_: false, ocn: nil, toc_: true, parent: dob.parent } dob=SiSU_DAL_DocumentStructure::ObjectHeading.new.heading(h,dob) end elsif dob.obj=~/#{Mx[:pa_non_object_dummy_heading]}/ dob.obj=dob.obj.gsub(/#{Mx[:pa_non_object_dummy_heading]}/,'') if dob.is==:para h={ obj: dob.obj, ocn_: false, ocn: nil, hang: dob.hang, indent: dob.indent, bullet_: dob.bullet_, tags: dob.tags, parent: dob.parent } dob=SiSU_DAL_DocumentStructure::ObjectPara.new.paragraph(h,dob) elsif dob.is==:heading h={ obj: dob.obj, ocn_: false, ocn: nil, toc_: false, parent: dob.parent } dob=SiSU_DAL_DocumentStructure::ObjectHeading.new.heading(h,dob) end else dob end if dob.is==:code \ || dob.is==:verse \ || dob.is==:alt \ || dob.is==:group \ || dob.is==:block dob.obj=dob.obj.gsub(/\n\n/,"\n") #newlines taken out end @o_array << dob end @o_array end end class XML def initialize(md,data) @data,@md=data,md end def dom @s=['0', 'A', 'B', 'C', '1', '2', '3' ] @sp=' ' tuned_file=structure_build tuned_file end def structure_build data=@data tuned_file=[] hs=[0,false,false,false] t={ lv: @s[0], status: 'open' } tuned_file << tags(t) if @md.opt.cmd =~/V/ puts "\nXML sisu structure outline --->\n" puts "<#{@s[0]}>" end data.each_with_index do |o,i| if o.is ==:heading \ || o.is ==:heading_insert case o.ln when 1 tuned_file << tag_close(o.ln,hs) tuned_file << tag_open(o,@s) if @md.opt.cmd =~/V/ puts_tag_close(o.ln,hs) puts_tag_open(o,@s) end hs=[1,true,false,false] when 2 tuned_file << tag_close(o.ln,hs) tuned_file << tag_open(o,@s) if @md.opt.cmd =~/V/ puts_tag_close(o.ln,hs) puts_tag_open(o,@s) end hs=[2,true,true,false] when 3 tuned_file << tag_close(o.ln,hs) tuned_file << tag_open(o,@s) if @md.opt.cmd =~/V/ puts_tag_close(o.ln,hs) puts_tag_open(o,@s) end hs=[3,true,true,true] when 4 tuned_file << tag_close(o.ln,hs) tuned_file << tag_open(o,@s) if @md.opt.cmd =~/V/ puts_tag_close(o.ln,hs) puts_tag_open(o,@s) end hs[0]=4 when 5 tuned_file << tag_close(o.ln,hs) tuned_file << tag_open(o,@s) if @md.opt.cmd =~/V/ puts_tag_close(o.ln,hs) puts_tag_open(o,@s) end hs[0]=5 when 6 tuned_file << tag_close(o.ln,hs) tuned_file << tag_open(o,@s) if @md.opt.cmd =~/V/ puts_tag_close(o.ln,hs) puts_tag_open(o,@s) end hs[0]=6 end end tuned_file << o end puts_tag_close(0,hs) if @md.opt.cmd =~/V/ tuned_file << tag_close(0,hs) tuned_file=tuned_file.flatten end def tags(o) tag=(o[:status]=='open') \ ? %{<#{o[:lv]} id="#{o[:node]}">} : "" ln=case o[:lv] when 'A'; 1 when 'B'; 2 when 'C'; 3 when '1'; 4 when '2'; 5 when '3'; 6 when '4'; 7 when '5'; 8 when '6'; 9 end h={ tag: tag, node: o[:node], lv: o[:lv], ln: ln, status: o[:status] } SiSU_DAL_DocumentStructure::ObjectStructure.new.xml_dom(h) #downstream code utilise else ignore like comments end def tag_open(o,tag) t={ lv: tag[o.ln], node: o.node, status: 'open' } t_o=tags(t) t_o end def tag_close(lev,hs) ary=[] case hs[0] when 1 if (lev <= 1) and hs[1] t={ lv: @s[1], status: 'close' } ary << tags(t) end if (lev==0) t={ lv: @s[0], status: 'close' } ary << tags(t) end when 2 if (lev <= 2) and hs[2] t={ lv: @s[2], status: 'close' } ary << tags(t) end if (lev <= 1) and hs[1] t={ lv: @s[1], status: 'close' } ary << tags(t) end if (lev==0) t={ lv: @s[0], status: 'close' } ary << tags(t) end when 3 if (lev <= 3) and hs[3] t={ lv: @s[3], status: 'close' } ary << tags(t) end if (lev <= 2) and hs[2] t={ lv: @s[2], status: 'close' } ary << tags(t) end if (lev <= 1) and hs[1] t={ lv: @s[1], status: 'close' } ary << tags(t) end if (lev==0) t={ lv: @s[0], status: 'close' } ary << tags(t) end when 4 if (lev <= 4) t={ lv: @s[4], status: 'close' } ary << tags(t) end if (lev <= 3) and hs[3] t={ lv: @s[3], status: 'close' } ary << tags(t) end if (lev <= 2) and hs[2] t={ lv: @s[2], status: 'close' } ary << tags(t) end if (lev <= 1) and hs[1] t={ lv: @s[1], status: 'close' } ary << tags(t) end if (lev==0) t={ lv: @s[0], status: 'close' } ary << tags(t) end when 5 if (lev <= 5) t={ lv: @s[5], status: 'close' } ary << tags(t) end if (lev <= 4) t={ lv: @s[4], status: 'close' } ary << tags(t) end if (lev <= 3) and hs[3] t={ lv: @s[3], status: 'close' } ary << tags(t) end if (lev <= 2) and hs[2] t={ lv: @s[2], status: 'close' } ary << tags(t) end if (lev <= 1) and hs[1] t={ lv: @s[1], status: 'close' } ary << tags(t) end if (lev==0) t={ lv: @s[0], status: 'close' } ary << tags(t) end when 6 if (lev <= 6) t={ lv: @s[6], status: 'close' } ary << tags(t) end if (lev <= 5) t={ lv: @s[5], status: 'close' } ary << tags(t) end if (lev <= 4) t={ lv: @s[4], status: 'close' } ary << tags(t) end if (lev <= 3) and hs[3] t={ lv: @s[3], status: 'close' } ary << tags(t) end if (lev <= 2) and hs[2] t={ lv: @s[2], status: 'close' } ary << tags(t) end if (lev <= 1) and hs[1] t={ lv: @s[1], status: 'close' } ary << tags(t) end if (lev==0) t={ lv: @s[0], status: 'close' } ary << tags(t) end end ary end def puts_tag_open(o,tag) puts %{#{@sp*o.ln}<#{tag[o.ln]} id="#{o.node}">} end def puts_tag_close(lev,hs) case hs[0] when 1 puts "#{@sp*1}" if (lev <= 1) and hs[1] puts "" if (lev==0) when 2 puts "#{@sp*2}" if (lev <= 2) and hs[2] puts "#{@sp*1}" if (lev <= 1) and hs[1] puts "" if (lev==0) when 3 puts "#{@sp*3}" if (lev <= 3) and hs[3] puts "#{@sp*2}" if (lev <= 2) and hs[2] puts "#{@sp*1}" if (lev <= 1) and hs[1] puts "" if (lev==0) when 4 puts "#{@sp*4}" if (lev <= 4) puts "#{@sp*3}" if (lev <= 3) and hs[3] puts "#{@sp*2}" if (lev <= 2) and hs[2] puts "#{@sp*1}" if (lev <= 1) and hs[1] puts "" if (lev==0) when 5 puts "#{@sp*5}" if (lev <= 5) puts "#{@sp*4}" if (lev <= 4) puts "#{@sp*3}" if (lev <= 3) and hs[3] puts "#{@sp*2}" if (lev <= 2) and hs[2] puts "#{@sp*1}" if (lev <= 1) and hs[1] puts "" if (lev==0) when 6 puts "#{@sp*6}" if (lev <= 6) puts "#{@sp*5}" if (lev <= 5) puts "#{@sp*4}" if (lev <= 4) puts "#{@sp*3}" if (lev <= 3) and hs[3] puts "#{@sp*2}" if (lev <= 2) and hs[2] puts "#{@sp*1}" if (lev <= 1) and hs[1] puts "" if (lev==0) end end end end __END__