diff options
Diffstat (limited to 'lib/sisu/v3dv/xml_dom.rb')
| -rw-r--r-- | lib/sisu/v3dv/xml_dom.rb | 542 | 
1 files changed, 542 insertions, 0 deletions
diff --git a/lib/sisu/v3dv/xml_dom.rb b/lib/sisu/v3dv/xml_dom.rb new file mode 100644 index 00000000..53c60bf8 --- /dev/null +++ b/lib/sisu/v3dv/xml_dom.rb @@ -0,0 +1,542 @@ +# encoding: utf-8 +=begin + + * Name: SiSU + + * Description: a framework for document structuring, publishing and search + + * Author: Ralph Amissah + + * Copyright: (C) 1997 - 2012, 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 <http://www.gnu.org/licenses/>. + +   If you have Internet connection, the latest version of the GPL should be +   available at these locations: +   <http://www.fsf.org/licenses/gpl.html> +   <http://www.gnu.org/licenses/gpl.html> +   <http://www.jus.uio.no/sisu/gpl.fsf> + + * SiSU uses: +   * Standard SiSU markup syntax, +   * Standard SiSU meta-markup syntax, and the +   * Standard SiSU object citation numbering and system + + * Hompages: +   <http://www.jus.uio.no/sisu> +   <http://www.sisudoc.org> + + * Download: +   <http://www.jus.uio.no/sisu/SiSU/download.html> + + * Ralph Amissah +   <ralph@amissah.com> +   <ralph.amissah@gmail.com> + + ** Description: xml (dom style) output processing +   ** Notes: tidy -xml dom.xml >> index.tidy +=end +module SiSU_XML_DOM +  require_relative 'defaults'                           # defaults.rb +    include SiSU_Viz +  require_relative 'particulars'                        # particulars.rb +    include SiSU_Particulars +  require_relative 'sysenv'                             # sysenv.rb +    include SiSU_Env +  require_relative 'dal'                                # dal.rb +  require_relative 'shared_xml'                         # shared_xml.rb +    include SiSU_XML_munge +  require_relative 'xml_format'                         # xml_format.rb +    include SiSU_XML_format +  require_relative 'rexml'                              # rexml.rb +    include SiSU_Rexml +  require_relative 'shared_metadata'                    # shared_metadata.rb +  @@alt_id_count,@@tablehead,@@number_of_cols=0,0,0 +  @@tablefoot='' +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::Combined_singleton.instance.get_all(opt) +    end +    def read +      begin +        @env,@md,@dal_array=@particulars.env,@particulars.md,@particulars.dal_array +        unless @opt.cmd =~/q/ +          path=@env.path.output_tell +          loc=@env.url.output_tell +          tool=if @opt.cmd =~/[MV]/; "#{@env.program.web_browser}  file://#{@md.file.output_path.xml_dom.dir}/#{@md.file.base_filename.xml_dom}\n\t#{@env.program.xml_viewer} file://#{@md.file.output_path.xml_dom.dir}/#{@md.file.base_filename.xml_dom}" +          elsif @opt.cmd =~/v/; "#{@env.program.web_browser} file://#{@md.file.output_path.xml_dom.dir}/#{@md.file.base_filename.xml_dom}" +          else "[#{@opt.f_pth[:lng_is]}] #{@opt.fns}" +          end +          @opt.cmd=~/[MVvz]/ \ +          ? SiSU_Screen::Ansi.new(@opt.cmd,'invert','XML DOM',tool).colorize +          : SiSU_Screen::Ansi.new(@opt.cmd,'XML DOM',tool).green_title_hi +          SiSU_Screen::Ansi.new(@opt.cmd,@opt.fns,"file://#{@md.file.output_path.xml_dom.dir}/#{@md.file.base_filename.xml_dom}").flow if @opt.cmd =~/[MV]/ +        end +        SiSU_XML_DOM::Source::Songsheet.new(@particulars).songsheet +      rescue; SiSU_Errors::Info_error.new($!,$@,@opt.cmd,@opt.fns).error +      ensure +      end +    end +    private +    class Songsheet +      def initialize(particulars) +        @env,@md,@dal_array,@particulars=particulars.env,particulars.md,particulars.dal_array,particulars +        @file=SiSU_Env::SiSU_file.new(@md) +      end +      def songsheet +        begin +          SiSU_XML_DOM::Source::Scroll.new(@particulars).songsheet +          SiSU_XML_DOM::Source::Tidy.new(@md,@file.place_file.xml_dom.dir).xml if @md.opt.cmd =~/[vVM]/ # test wellformedness, comment out when not in use +          SiSU_Rexml::Rexml.new(@md,@file.place_file.xml_dom.dir).xml if @md.opt.cmd =~/M/ # test rexml parsing, comment out when not in use #debug +        rescue; SiSU_Errors::Info_error.new($!,$@,@md.opt.cmd,@md.fns).error +        ensure +        end +      end +    end +    class Scroll +      require_relative 'shared_txt'                     # shared_txt.rb +        include SiSU_text_utils +      require_relative 'shared_xhtml'                   # decide use, whether xml rather than xhtml +      @@xml={ body: [], open: [], close: [], head: [], sc: [] } +      def initialize(particulars) +        @env,@md,@dal_array=particulars.env,particulars.md,particulars.dal_array +        @vz=SiSU_Env::Get_init.instance.skin +        @trans=SiSU_XML_munge::Trans.new(@md) +        @sys=SiSU_Env::System_call.new +      end +      def songsheet +        pre +        @data=markup(@dal_array) +        post +        publish +      end +    protected +      def xml_markup(dob='') +        dob.obj.gsub!(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/, +          '<endnote><number>\1</number><note>\2</note></endnote> ') +        dob.obj.gsub!(/#{Mx[:en_b_o]}([*+]\d+)\s+(.+?)#{Mx[:en_b_c]}/, +          '<endnote><symbol>\1</symbol><note>\2</note></endnote> ') +        dob.obj.gsub!(/#{Mx[:en_a_o]}([*+]+)\s+(.+?)#{Mx[:en_a_c]}/, +          '<endnote><symbol>\1</symbol><note>\2</note></endnote> ') +      end +      def xml_head +        metadata=Metadata::Summary.new(@md).xml_dom.metadata +        @@xml[:head] << metadata +      end +      def xml_sc(md='') +        sc=if @md.sc_info +          <<WOK +    <source_control> +      <meta>filename:</meta> +      <sc class="sourcefile"> +        #{@md.sc_filename} +      </sc><br /> +      <meta>version number:</meta> +      <sc class="number"> +        #{@md.sc_number} +      </sc><br /> +      <meta>version date:</meta> +      <sc class="date"> +        #{@md.sc_date} +      </sc><br /> +    </source_control> +WOK +        else '' +        end +        @@xml[:sc]=sc +      end +      def xml_element(dob,xml_el='',xml_content='',type='norm') +        n=n1=n2=n3=0 +        if dob.is=='heading' +          lv=dob.ln +          n=dob.ln - 1 +          n1=dob.ln +          n2=dob.ln + 1 +          n3=dob.ln + 2 +          v=dob.ln - 3 +        else lv=nil +        end +        tag=if defined? dob.name and dob.name=~/\S+/ +          "\n#{Ax[:tab]*n3}<nametag>#{dob.name}</nametag>" +        else '' +        end +        xml_el ||='' +        @@xml[:body] <<<<WOK +#{Ax[:tab]*n}#{xml_el} +#{Ax[:tab]*n1}<heading> +#{Ax[:tab]*n2}<object id="#{dob.ocn}"> +#{Ax[:tab]*n3}<ocn>#{dob.ocn}</ocn>#{tag} +#{Ax[:tab]*n3}<text class="#{type}">#{dob.obj}</text> +#{Ax[:tab]*n2}</object> +#{Ax[:tab]*n1}</heading>#{xml_content} +WOK +        if lv==4 +          @copen[1]=true +          @copen[2]=@copen[3]=false +        elsif lv==5 +          @copen[2]=true +          @copen[3]=false +        elsif lv==6 +          @copen[3]=true +        end +      end +      def xml_structure(dob,type='norm') +        n=n1=n2=n3=0 +        if dob.is=='heading' +          lv=dob.ln +          n=dob.ln - 1 +          n1=dob.ln +          n2=dob.ln + 1 +          n3=dob.ln + 2 +          v=dob.ln - 3 +        else lv=nil +        end +        tag=if defined? dob.name and dob.name=~/\S+/ +          "\n#{Ax[:tab]*n3}<nametag>#{dob.name}</nametag>" +        else '' +        end +        case lv +        when 1..3 +          xml_el="<heading#{lv}>" +          3.downto(lv) do |x| +            y=x - 1 +            if @cont[1] \ +            or @cont[2] \ +            or @cont[3] +              @@xml[:body] << "#{Ax[:tab]*5}</content>" +            end +            @cont[1]=false if @cont[1] +            @cont[2]=false if @cont[2] +            @cont[3]=false if @cont[3] +            ####### attempt to close contents +            if @copen[3] # 6~ +              [3,2,1].each { |v| @@xml[:body] << "#{Ax[:tab]*n}</contents#{v}>" } +              @copen[1]=@copen[2]=@copen[3]=false +            elsif @copen[2] # 5~ +              [2,1].each { |v| @@xml[:body] << "#{Ax[:tab]*n}</contents#{v}>" } +              @copen[1]=@copen[2]=@copen[3]=false +            elsif @copen[1] # 4~ +              [1].each { |v| @@xml[:body] << "#{Ax[:tab]*n}</contents#{v}>" } +              @copen[1]=@copen[2]=@copen[3]=false +            end +            @@xml[:body] << "#{Ax[:tab]*y}</heading#{x}>" if @level[x] +            @level[x]=false +          end +        when 4..6 +          6.downto(lv) do |x| +            y=x - 1 +            if @level[x]==true +              u=x - 3; +              @xml_contents_close[x]='' +            end +          end +          cv=lv - 3 +          xml_el="<contents#{cv}>" +          xml_content="\n#{Ax[:tab]*5}<content>" +          case lv +          when 4 +            @@xml[:body] << "#{Ax[:tab]*5}</content>" if @cont[1] +            if @copen[3]==true # 6~ +              [3,2,1].each { |v| @@xml[:body] << "#{Ax[:tab]*n}</contents#{v}>" } +            elsif @copen[2]==true # 5~ +              [2,1].each { |v| @@xml[:body] << "#{Ax[:tab]*n}</contents#{v}>" } +            elsif @copen[1]==true # 4~ +              [1].each { |v| @@xml[:body] << "#{Ax[:tab]*n}</contents#{v}>" } +            end +            @cont[1]=true +          when 5 +            if @cont[2] \ +            or @cont[1] +              @@xml[:body] << "#{Ax[:tab]*5}</content>" +            end +            if @copen[3]==true  #6~ +              [3,2].each { |v| @@xml[:body] << "#{Ax[:tab]*n}</contents#{v}>" } +            elsif @copen[2]==true #5~ +              [2].each { |v| @@xml[:body] << "#{Ax[:tab]*n}</contents#{v}>" } +            end +            @cont[2]=true +          when 6 +            if @cont[3] \ +            or @cont[2] \ +            or @cont[1] +              @@xml[:body] << "#{Ax[:tab]*5}</content>" +            end +            if @copen[3] #6{ +              [3].each { |v| @@xml[:body] << "#{Ax[:tab]*n}</contents#{v}>" } +            end +            @cont[3]=true +          end +        end +        xml_el ||='' +        xml_element(dob,xml_el,xml_content,type) +        if lv +          @level[lv]=true +          ((lv+1)..6).each { |x| @level[x]=false } +        end +      end +      def add_to_body(dob,type='norm') +        if defined? dob.obj # main text, contents, body KEEP +          if defined? dob.ocn \ +          and dob.ocn +            @@xml[:body] << %{#{Ax[:tab]*6}<object id="#{dob.ocn}">} +            @@xml[:body] << %{#{Ax[:tab]*7}<ocn>#{dob.ocn}</ocn>} if defined? dob.ocn +          end +          #@@xml[:body] << %{#{Ax[:tab]*7}<text class="#{type}">#{dob.obj}</text>} +          #@@xml[:body] << %{#{Ax[:tab]*7}<text class="#{dob.is}">#{Ax[:tab]*1}} +          @@xml[:body] << %{#{Ax[:tab]*7}<text class="#{type}">#{Ax[:tab]*1}} +          @@xml[:body] << %{#{Ax[:tab]*8}#{dob.obj}#{Ax[:tab]*1}} +          @@xml[:body] << %{#{Ax[:tab]*7}</text>} +          @@xml[:body] << %{#{Ax[:tab]*6}</object>} +        end +      end +      def block_structure(dob) +        dob=@trans.markup_block(dob) #decide check & FIX +        dob.obj.gsub!(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/m, +          '<endnote><number>\1</number><note>\2</note></endnote> ') +        dob.obj.strip! +        dob +      end +      def group_structure(dob) +        dob=@trans.markup_group(dob) #decide check & FIX +        dob.obj.gsub!(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/m, +          '<endnote><number>\1</number><note>\2</note></endnote> ') +        dob.obj.strip! +        dob +      end +      def poem_structure(dob) +        dob=@trans.markup_group(dob) #decide check & FIX +        dob.obj.strip! +        dob +      end +      def code_structure(dob) +        dob=@trans.markup_group(dob) #decide check & FIX +        dob.obj.gsub!(/\s\s/,'  ') +        dob.obj.strip! +        dob +      end +      def table_structure(dob) #tables +        table=SiSU_XHTML_shared::Table_xhtml.new(dob) +      end +      def markup(data) +        xml_sc(@md) +        @level,@cont,@copen,@xml_contents_close=[],[],[],[] +        @rcdc=false +        type='norm' +        (0..6).each { |x| @cont[x]=@level[x]=false } +        (4..6).each { |x| @xml_contents_close[x]='' } +        xml_head +        data.each do |dob| +          @trans.char_enc.utf8(dob) if @sys.locale =~/utf-?8/i #% utf8 +          dob=@trans.markup(dob) +          if @rcdc==false \ +          and (dob.is =~/^meta/ \ +          and dob.obj =~/Document Information/) +            @rcdc=true +          end +          if dob !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +            @p_num=SiSU_XML_format::Paragraph_number.new(@md,dob.ocn) if defined? dob.ocn +            if not @rcdc +              if defined? dob.ocn \ +              and dob.ocn.to_s =~/\d+/ +                format_scroll=SiSU_XML_format::Format_scroll.new(@md,dob) if dob.is=='para' and dob.indent ##FIX +                x=SiSU_XML_format::Format_seg.new(@md,dob) +                if dob.is=='heading' +                  if dob.ln==1 +                    type="heading_section_#{dob.ln.to_s}" +                    xml_markup(dob) +                    xml_structure(dob,type) +                    dob.obj=x.heading_body1 +                  elsif dob.ln==2 +                    type="heading_section_#{dob.ln.to_s}" +                    xml_markup(dob) +                    xml_structure(dob,type) +                    dob.obj=x.heading_body2 +                  elsif dob.ln==3 +                    type="heading_section_#{dob.ln.to_s}" +                    xml_markup(dob) +                    xml_structure(dob,type) +                    dob.obj=x.heading_body3 +                  elsif dob.ln==4 +                    type="heading_content_#{dob.lv}" +                    xml_markup(dob) +                    xml_structure(dob,type) +                    dob.obj=x.heading_body4 +                  elsif dob.ln==5 +                    type="heading_content_#{dob.lv}" +                    xml_markup(dob) +                    xml_structure(dob,type) +                    dob.obj=x.heading_body5 +                  elsif dob.ln==6 +                    type="heading_content_#{dob.lv}" +                    xml_structure(dob,type) +                    dob.obj=x.heading_body6 +                  end +                else +                  ocn=dob.ocn +                  if dob.is=='verse' +                    type='verse' +                    poem_structure(dob) #redo +                  elsif dob.is=='group' +                    type='group' +                    group_structure(dob) #redo +                  elsif dob.is=='block' +                    type='block' +                    block_structure(dob) #redo +                  elsif dob.is=='code' +                    type='code' +                    code_structure(dob) #redo +                  elsif dob.is=='table' # tables come as single block #work area 2005w13 +                    type='table' +                    table_structure(dob) +                  elsif dob.is=='para' \ +                  and dob.indent.to_s =~/[1-9]/ \ +                  and dob.bullet_ +                    type="indent_bullet#{dob.indent.to_s}" +                    xml_markup(dob) +                  elsif dob.is=='para' \ +                  and dob.indent.to_s =~/[1-9]/ \ +                  and dob.indent == dob.hang +                    type="indent#{dob.indent.to_s}" +                    xml_markup(dob) +                  elsif dob.is=='para' \ +                  and dob.hang.to_s =~/[0-9]/ \ +                  and dob.indent != dob.hang +                    type="hang#{dob.hang.to_s}_indent#{dob.indent.to_s}" +                    xml_markup(dob) +                  else +                    type='norm' +                    xml_markup(dob) +                  end +                  add_to_body(dob,type) +                end +              elsif dob.obj =~/(#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +              elsif dob.obj =~/(MetaData)/ +                txt_obj={ txt: '<br /><a name="metadata">MetaData</a>' } +                format_scroll=Format_scroll.new(@md,txt_obj) +                dob.obj=format_scroll.bold_para +              elsif dob.obj =~/(Owner Details)/ +                dob.obj='' +              end +              if dob.obj =~/<a name="n\d+">/ \ +              and dob.obj =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/ # -endnote +                dob.obj='' +              end +              if dob.obj =~/.*<:#>.*$/ +                dob.obj=if dob.obj =~ /#{Mx[:pa_o]}:i[1-9]#{Mx[:pa_c]}/ +                  txt_obj={ txt: dob.obj } +                  format_text=Format_text_object.new(@md,txt_obj) +                  format_text.scr_inden_ocn_e_no_paranum +                end +              end +              if dob.obj !~/#{@vz.margin_txt_0}|#{@vz.margin_txt_1}|#{@vz.margin_txt_2}/ +              end +            else # +            end +            dob.obj.gsub!(/#{Mx[:pa_o]}:\S+#{Mx[:pa_c]}/,'') if dob.obj +          end +        end +        @content_flag=true +        6.downto(4) do |x| +          y=x - 1; v=x - 3 +          if @level[x]==true #2004w36 bug fix? watch/test previous logic broke on free.for.all @coontent_flag introduced +            if @content_flag==true +              @@xml[:body] << "#{Ax[:tab]*5}</content>\n#{Ax[:tab]*y}</contents#{v}>" +              @content_flag=false +            else +              @@xml[:body] << "\n#{Ax[:tab]*y}</contents#{v}>" +            end +          end +        end +        3.downto(1) do |x| +          y=x - 1 +          @@xml[:body] << "#{Ax[:tab]*y}</heading#{x}>" if @level[x]==true +        end +      end +      def pre +        rdf=SiSU_XML_tags::RDF.new(@md) +        dir=SiSU_Env::Info_env.new +        css=SiSU_Env::CSS_stylesheet.new(@md) +        encoding=if @sys.locale =~/utf-?8/i; '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +        else                                 '<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>' +        end +        @@xml[:open] =<<WOK +#{encoding} +#{css.xml_dom} +#{rdf.comment_xml} +<document> +WOK +        @@xml[:head] << '<head>' +        @@xml[:body] << '<body>' +      end +      def post +        @@xml[:head] << @@xml[:sc] +        @@xml[:head] << '</head>' +        @@xml[:body] << '</body>' +        @@xml[:close] = '</document>' +      end +      def publish +        content=[] +        content << @@xml[:open] << @@xml[:head] << @@xml[:body] << @@xml[:metadata] +        content << @@xml[:owner_details] if @md.stmp =~/\w\w/ +        content << @@xml[:tail] << @@xml[:close] +        content.flatten!.compact! +        Output.new(content,@md).xml +        @@xml[:head],@@xml[:body],@@xml[:tail]=[],[],[] # check whether should be nil +      end +    end +    class Output +      include SiSU_Param +      def initialize(data,md) +        @data,@md=data,md +        @file=SiSU_Env::SiSU_file.new(@md) +      end +      def xml +        SiSU_Env::SiSU_file.new(@md).mkdir +        filename_xml=@file.write_file.xml_dom +        @data.each do |str| +          str.gsub!(/#{Mx[:pa_o]}:\S+#{Mx[:pa_c]}/,'') +          filename_xml.puts str unless str.empty? +        end +        filename_xml.close +      end +    end +    class Tidy +      def initialize(md,file) +        @md,@file=md,file +        @prog=SiSU_Env::Info_program.new +      end +      def xml +        if @prog.tidy !=false +          if @md.opt.cmd =~/[VM]/ +            SiSU_Screen::Ansi.new(@md.opt.cmd,'invert','Using XML Tidy','check document structure').colorize unless @md.opt.cmd =~/q/ +            tell=SiSU_Screen::Ansi.new(@md.opt.cmd,'invert','','') +            tell.grey_open unless @md.opt.cmd =~/q/ +            tidyfile='/dev/null' #don't want one or screen output, check for alternative flags +            tidy=SiSU_Env::System_call.new(@file,tidyfile) +            tidy.well_formed? +            tell.p_off unless @md.opt.cmd =~/q/ +          end +        end +      end +    end +  end +end +__END__  | 
