json, an output representation, first pass
authorRalph Amissah <ralph@amissah.com>
Thu, 25 Feb 2016 04:21:06 +0000 (23:21 -0500)
committerRalph Amissah <ralph@amissah.com>
Thu, 25 Feb 2016 04:54:58 +0000 (23:54 -0500)
13 files changed:
data/doc/sisu/CHANGELOG_v7
lib/sisu/constants.rb
lib/sisu/hub.rb
lib/sisu/hub_actions.rb
lib/sisu/hub_options.rb
lib/sisu/json.rb [new file with mode: 0644]
lib/sisu/json_format.rb [new file with mode: 0644]
lib/sisu/json_parts.rb [new file with mode: 0644]
lib/sisu/json_persist.rb [new file with mode: 0644]
lib/sisu/json_shared.rb [new file with mode: 0644]
lib/sisu/se_file_op.rb
lib/sisu/shared_metadata.rb
lib/sisu/urls.rb

index aa982a51015cb088e9e486376e2f14288eeeebcb..016ff83fdea427771611c29d8e80d808a9a401b7 100644 (file)
@@ -18,6 +18,8 @@ v2 branch removed; available in sisu =< 3.3.2
 
 Reverse Chronological:
 
+--- HEAD ---
+
 * sisu_7.1.8.orig.tar.xz (Open commit window: 2016-02-09; Pre-Release)
   http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=log;h=refs/tags/sisu_7.1.8
 
@@ -32,6 +34,8 @@ Reverse Chronological:
 
   * txt_orgmode, update (dp add email header field)
 
+  * json, an output representation, first pass
+
 * sisu_7.1.7.orig.tar.xz (Open commit window: 2015-12-29; Pre-Release)
   http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=log;h=refs/tags/sisu_7.1.7
 
index 363bab77d783d85804d1310b2c8eef24ba17788b..1c126201303bbb5cc0610a794f98d6c4706275fe 100644 (file)
@@ -76,6 +76,7 @@ Sfx={
   epub:                      '.epub',
   epub_xhtml:                '.xhtml',
   odt:                       '.odt',
+  json:                      '.json',
   pdf:                       '.pdf',
   manpage:                   '.1',
   info:                      '.info',
index c5bd0ced8523e3bd0bad3a14f907707007cf2ca7..49d569a5b1874e1fdc715055c0c709db053f8521 100644 (file)
@@ -129,6 +129,7 @@ module SiSU
       actions.outputs.each_file.html?
       actions.outputs.each_file.xhtml?
       actions.outputs.each_file.xml?
+      actions.outputs.each_file.json?
       actions.outputs.each_file.pdf?
       actions.outputs.each_file.man_or_info?
       actions.outputs.each_file.po4a_make?
@@ -260,7 +261,7 @@ module SiSU
       ensure
         if FileTest.directory?(env.processing_path.processing) \
         and FileTest.directory?(env.processing_path.processing_base_tmp) \
-        and env.processing_path.processing_base_tmp =~/#{env.processing_path.processing}/ \
+        and env.processing_path.processing_base_tmp =~ /#{env.processing_path.processing}/ \
         and env.processing_path.processing_base_tmp =~/^\/tmp\/\S+/ \
         and not argv.inspect =~/"--maintenance"|"-M"/
           FileUtils::cd(env.processing_path.processing_base_tmp) do
index 52ad9da66ac6f76c573cd168d136281a760f7fe9..a946591d21ee1cf7dec5f29d19660961b9f9282f 100644 (file)
@@ -382,6 +382,22 @@ module SiSU_Hub_Actions
             end
           end
         end
+        def json?
+          if @opt.act[:json][:set]==:on                 #% --js, -J
+            if @opt.f_pths.length > 0
+              require_relative 'json'                   # json.rb
+              SiSU_JSON::Source.new(@opt).read
+            else
+              msg='json request requires sisu markup files'
+              if (@opt.act[:verbose_plus][:set]==:on \
+              || @opt.act[:maintenance][:set]==:on)
+                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).
+                  mark(msg)
+              else puts msg
+              end
+            end
+          end
+        end
         def xhtml?
           if @opt.act[:xhtml][:set]==:on                 #% --xhtml, -b
             if @opt.f_pths.length > 0
index 0794dffbb08eb2c94bbf4c53156f260bf21cd9b0..e0832553b7654a30da648176a115df55032b4641 100644 (file)
@@ -636,6 +636,9 @@ module SiSU_Commandline
           if ch =~/j/ then select_arr << '--images'
             ch=ch.gsub(/[j]/,'')
           end
+          if ch =~/J/ then select_arr << '--json'
+            ch=ch.gsub(/[J]/,'')
+          end
           if ch =~/N/ then select_arr << '--digests'
             ch=ch.gsub(/[N]/,'')
           end
@@ -1022,6 +1025,10 @@ module SiSU_Commandline
         =~/"--images"/) \
         ? { bool: true, set: :on }
         : { bool: false, set: :na }
+        act[:json]=(select_arr.inspect \
+        =~/"--json"/) \
+        ? { bool: true, set: :on }
+        : { bool: false, set: :na }
         if select_arr.inspect \
         =~/"--pdf"/
           if select_arr.inspect \
@@ -1488,6 +1495,7 @@ module SiSU_Commandline
         || act[:html][:set]==:on \
         || act[:html_seg][:set]==:on \
         || act[:html_scroll][:set]==:on \
+        || act[:json][:set]==:on \
         || act[:texinfo][:set]==:on \
         || act[:manpage][:set]==:on \
         || act[:hash_digests][:set]==:on \
@@ -1538,6 +1546,7 @@ module SiSU_Commandline
         || act[:html][:set]==:on \
         || act[:html_seg][:set]==:on \
         || act[:html_scroll][:set]==:on \
+        || act[:json][:set]==:on \
         || act[:texinfo][:set]==:on \
         || act[:manpage][:set]==:on \
         || act[:hash_digests][:set]==:on \
diff --git a/lib/sisu/json.rb b/lib/sisu/json.rb
new file mode 100644 (file)
index 0000000..d491a9e
--- /dev/null
@@ -0,0 +1,415 @@
+# encoding: utf-8
+=begin
+
+* Name: SiSU
+
+** Description: documents, structuring, processing, publishing, search
+*** Description: json output logic, flow
+
+** Author: Ralph Amissah
+  [ralph@amissah.com]
+  [ralph.amissah@gmail.com]
+
+** Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+  2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 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/licensing/licenses/gpl.html]
+  [http://www.gnu.org/licenses/gpl.html]
+
+** 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]
+
+** Git
+  [http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=summary]
+  [http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=blob;f=lib/sisu/json.rb;hb=HEAD]
+
+=end
+module SiSU_JSON
+  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb
+    include SiSU_Particulars
+  require_relative 'se'                                 # se.rb
+    include SiSU_Env
+  require_relative 'json_shared'                        # json_shared.rb
+    include SiSU_JSON_Munge
+  require_relative 'json_format'                        # json_format.rb
+    include SiSU_JSON_Format
+  require_relative 'json_persist'                       # json_persist.rb
+  require_relative 'shared_metadata'                    # shared_metadata.rb
+  @@alt_id_count=0
+  @@tablefoot=''
+  class Source
+    def initialize(opt)
+      @opt=opt
+      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt)
+    end
+    def read
+      begin
+        @env,@md,@ao_array=@particulars.env,@particulars.md,@particulars.ao_array
+        unless @opt.act[:quiet][:set]==:on
+          tool=if (@opt.act[:verbose_plus][:set]==:on \
+          || @opt.act[:maintenance][:set]==:on)
+            @env.program.web_browser +
+            ' file://' +
+            @md.file.output_path.json.dir + '/' +
+            @md.file.base_filename.json
+          elsif @opt.act[:verbose][:set]==:on
+            @env.program.web_browser +
+            ' file://' +
+            @md.file.output_path.json.dir + '/' +
+            @md.file.base_filename.json
+          else "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}"
+          end
+          (@opt.act[:verbose][:set]==:on \
+          || @opt.act[:verbose_plus][:set]==:on \
+          || @opt.act[:maintenance][:set]==:on) \
+          ? SiSU_Screen::Ansi.new(
+              @opt.act[:color_state][:set],
+              'JSON',
+              tool
+            ).green_hi_blue
+          : SiSU_Screen::Ansi.new(
+              @opt.act[:color_state][:set],
+              'JSON',
+              tool
+            ).green_title_hi
+          if (@opt.act[:verbose_plus][:set]==:on \
+          || @opt.act[:maintenance][:set]==:on)
+            SiSU_Screen::Ansi.new(
+              @opt.act[:color_state][:set],
+              @opt.fns,
+                '/' + @md.file.output_path.json.dir +
+                '/' + @md.file.base_filename.json
+            ).flow
+          end
+        end
+        SiSU_JSON::Source::Songsheet.new(@particulars).song
+      rescue
+        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do
+          __LINE__.to_s + ':' + __FILE__
+        end
+      ensure
+        SiSU_Env::CreateSite.new(@opt).cp_css
+        Dir.chdir(@opt.f_pth[:pth])
+      end
+    end
+    private
+    class Songsheet
+      def initialize(particulars)
+        @env,@md,@ao_array,@particulars=
+          particulars.env,particulars.md,particulars.ao_array,particulars
+        @file=SiSU_Env::FileOp.new(@md)
+      end
+      def song
+        begin
+          SiSU_JSON::Source::Scroll.new(@particulars).songsheet
+        rescue
+          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do
+            __LINE__.to_s + ':' + __FILE__
+          end
+        ensure
+        end
+      end
+    end
+    class Scroll
+      require_relative 'json_shared'                   # json_shared.rb #check already called
+      require_relative 'txt_shared'                     # txt_shared.rb
+        include SiSU_TextUtils
+      require_relative 'css'                            # css.rb
+      def initialize(particulars)
+        @env,@md,@ao_array=particulars.env,particulars.md,particulars.ao_array
+        @tab="\t"
+        @trans=SiSU_JSON_Munge::Trans.new(@md)
+        @sys=SiSU_Env::SystemCall.new
+        @per=SiSU_JSON_Persist::Persist.new
+      end
+      def songsheet
+        begin
+          pre
+          @data=markup(@ao_array)
+          post
+          publish
+        ensure
+          SiSU_JSON_Persist::Persist.new.persist_init
+        end
+      end
+    protected
+      def embedded_endnotes(dob='')
+        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/,
+            '<endnote><number>\1</number><note>\2</note></endnote> ').
+          gsub(/#{Mx[:en_b_o]}([*+]\d+)\s+(.+?)#{Mx[:en_b_c]}/,
+            '<endnote><symbol>\1</symbol><note>\2</note></endnote> ').
+          gsub(/#{Mx[:en_a_o]}([*+]+)\s+(.+?)#{Mx[:en_a_c]}/,
+            '<endnote><symbol>\1</symbol><note>\2</note></endnote> ')
+      end
+      def extract_endnotes(dob='')
+        notes=dob.obj.scan(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+\s+.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/)
+        notes.flatten.each do |e|
+          s=e.to_s
+          util=SiSU_JSONutils::Clean.new(s)
+          wrap=util.line_json_clean
+          wrap=wrap.gsub(/^(\d+)\s+(.+?)\s*\Z/m, <<-WOK
+\\n[\\1.] \\2
+              WOK
+            ).
+            gsub(/^([*+]\d+)\s+(.+?)\s*\Z/m, <<-WOK
+\\n[\\1.] \\2
+              WOK
+            ).
+            gsub(/^([*+]+)\s+(.+?)\s*\Z/m, <<-WOK
+\\n[\\1.] \\2
+              WOK
+            ).strip
+#KEEP alternative presentation of endnotes
+#        wrap=wrap.gsub(/^(\d+)\s+(.+?)\s*\Z/m, <<WOK
+##{Ax[:tab]*1}<p class="endnote" notenumber="\\1">
+##{Ax[:tab]*2}\\1. \\2
+##{Ax[:tab]*1}</p>
+#WOK
+#)
+          @endnotes << wrap
+        end
+      end
+      def json_head
+        #metadata=SiSU_Metadata::Summary.new(@md).json.metadata
+        #@per.head << metadata
+      end
+      def name_tags(dob)
+        tags=''
+        if defined? dob.tags \
+        and dob.tags.length > 0 # insert tags "hypertargets"
+          dob.tags.each do |t|
+            tags=tags << %{<named id="#{t}" />}
+          end
+        end
+        tags
+      end
+      def json_structure(dob,attrib=nil)
+        if dob.is ==:para \
+        || dob.is ==:heading
+          if dob.is==:heading
+            lv=dob.ln
+            dob.ln + 2
+          else lv=nil
+          end
+          extract_endnotes(dob)
+          dob.obj=dob.obj.
+            gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'<en>\1</en>'). #footnote/endnote clean
+            gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'<en>\1</en>')
+          util=SiSU_JSONutils::Clean.new(dob.obj)
+          wrapped=util.line_json_clean
+          @per.body << Ax[:tab]*1 + '{'
+          if defined? dob.ocn and dob.ocn
+            @per.body << Ax[:tab]*2 + '"ocn": ' + dob.ocn.to_s + '",'
+          end
+          if lv                                                                 # main text, contents, body KEEP
+            @per.body <<
+              Ax[:tab]*2 + %{"object": "<h#{lv}>} + wrapped + %{</h#{lv}>} +
+              ((@endnotes.length > 0) ? '",' : '"')
+          else
+            @per.body <<
+              Ax[:tab]*2 + '"object": "' + wrapped +
+              ((@endnotes.length > 0) ? '",' : '"')
+          end
+          if @endnotes.length > 0                                               # main text, endnotes KEEP
+            @per.body <<
+              Ax[:tab]*2 + '"endnotes": "' +
+              @endnotes.compact.join.strip + '"'
+          end
+          @per.body << Ax[:tab]*1 + '},' # unless is last object then '}'
+          @endnotes=[]
+        end
+      end
+      def block_structure(dob)
+        dob=@trans.markup_block(dob)
+        dob.obj=dob.obj.strip.
+          gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'<en>\1</en>'). #footnote/endnote clean
+          gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'<en>\1</en>') #footnote/endnote clean
+        @per.body << Ax[:tab]*1 + '{'
+        if defined? dob.ocn and dob.ocn
+          @per.body << Ax[:tab]*2 + '"ocn": ' + dob.ocn.to_s + '",'
+        end
+        @per.body <<
+          Ax[:tab]*2 + '"object": "' + dob.obj + '"'
+          #((@endnotes.length > 0) ? '",' : '"')
+        @per.body << Ax[:tab]*1 + '},' # unless is last object then '}'
+      end
+      def group_structure(dob)
+        dob=@trans.markup_group(dob)
+        dob.obj=dob.obj.strip.
+          gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'<en>\1</en>'). #footnote/endnote clean
+          gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'<en>\1</en>') #footnote/endnote clean
+        @per.body << Ax[:tab]*1 + '{'
+        if defined? dob.ocn and dob.ocn
+          @per.body << Ax[:tab]*2 + '"ocn": ' + dob.ocn.to_s + '",'
+        end
+        @per.body <<
+          Ax[:tab]*2 + '"object": "' + dob.obj + '"'
+          #((@endnotes.length > 0) ? '",' : '"')
+        @per.body << Ax[:tab]*1 + '},' # unless is last object then '}'
+      end
+      def poem_structure(dob)
+        dob=@trans.markup_group(dob)
+        dob.obj=dob.obj.strip
+        @per.body << Ax[:tab]*1 + '{'
+        if defined? dob.ocn and dob.ocn
+          @per.body << Ax[:tab]*2 + '"ocn": ' + dob.ocn.to_s + '",'
+        end
+        @per.body <<
+          Ax[:tab]*2 + '"object": "' + dob.obj + '"'
+          #((@endnotes.length > 0) ? '",' : '"')
+        @per.body << Ax[:tab]*1 + '},' # unless is last object then '}'
+      end
+      def code_structure(dob)
+        dob=@trans.markup_group(dob)
+        dob.obj=dob.obj.gsub(/\s\s/,'&#160;&#160;').strip
+        @per.body << Ax[:tab]*1 + '{'
+        if defined? dob.ocn and dob.ocn
+          @per.body << Ax[:tab]*2 + '"ocn": ' + dob.ocn.to_s + '",'
+        end
+        @per.body <<
+          Ax[:tab]*2 + '"object": "' + dob.obj + '"'
+          #((@endnotes.length > 0) ? '",' : '"')
+        @per.body << Ax[:tab]*1 + '},' # unless is last object then '}'
+      end
+      def table_structure(dob)
+        table=SiSU_JSON_Shared::TableJSON.new(dob)
+        @per.body << Ax[:tab]*1 + '{'
+        if defined? dob.ocn and dob.ocn
+          @per.body << Ax[:tab]*2 + '"ocn": ' + dob.ocn.to_s + '",'
+        end
+        @per.body <<
+          Ax[:tab]*2 + '"object": "' + table.table.obj + '"'
+        #((@endnotes.length > 0) ? '",' : '"')
+        @per.body << Ax[:tab]*1 + '},' # unless is last object then '}'
+      end
+      def markup(data)
+        @endnotes=[]
+        @rcdc=false
+        @level,@cont,@copen,@json_contents_close=[],[],[],[]
+        json_head
+        (0..7).each { |x| @cont[x]=@level[x]=false }
+        (4..7).each { |x| @json_contents_close[x]='' }
+        data.each_with_index do |dob,i|
+          dob=@trans.char_enc.utf8(dob) if @sys.locale =~/utf-?8/i #% utf8
+          dob=@trans.markup(dob)
+          if @rcdc==false \
+          and (dob.obj =~/~meta/ \
+          and dob.obj =~/Document Information/)
+            @rcdc=true
+          end
+          if dob.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/
+            if not @rcdc
+              x=SiSU_JSON_Format::FormatTextObject.new(@md,dob)
+              if dob.is==:heading
+                json_structure(dob)
+                dob.obj=case dob.ln
+                when 0 then x.heading_body0
+                when 1 then x.heading_body1
+                when 2 then x.heading_body2
+                when 3 then x.heading_body3
+                when 4 then x.heading_body4
+                when 5 then x.heading_body5
+                when 6 then x.heading_body6
+                when 7 then x.heading_body7
+                end
+              else
+                if dob.is ==:verse
+                  poem_structure(dob)
+                elsif dob.is ==:group
+                  group_structure(dob)
+                elsif dob.is ==:block
+                  block_structure(dob)
+                elsif dob.is ==:code
+                  code_structure(dob)
+                elsif dob.is ==:table
+                  table_structure(dob)
+                elsif dob.is ==:para \
+                and dob.indent.to_s =~/[1-9]/ \
+                and dob.bullet_==true
+                  json_structure(dob,"indent_bullet#{dob.indent}")
+                elsif dob.is ==:para \
+                and dob.indent.to_s =~/[1-9]/ \
+                and dob.indent == dob.hang
+                  json_structure(dob,"indent#{dob.indent}")
+                elsif dob.is==:para \
+                and dob.hang.to_s =~/[0-9]/ \
+                and dob.indent != dob.hang
+                  json_structure(dob,"hang#{dob.hang.to_s}_indent#{dob.indent.to_s}")
+                else json_structure(dob)
+                end
+              end
+            end
+            dob.obj=dob.obj.gsub(/#{Mx[:pa_o]}:\S+#{Mx[:pa_c]}/,'') if dob.obj
+          end
+        end
+        6.downto(4) do |x|
+          y=x - 1; v=x - 3
+          @per.body << "#{Ax[:tab]*5}</content>\n#{Ax[:tab]*y}</contents#{v}>" if @level[x]==true
+        end
+        3.downto(1) do |x|
+          y=x - 1
+          @per.body << "#{Ax[:tab]*y}</heading#{x}>" if @level[x]==true
+        end
+      end
+      def pre
+        @per.head,@per.body=[],[]
+        @per.open = '{'
+      end
+      def post
+        @per.close = '}'
+      end
+      def publish
+        content=[]
+        @per.body[-1] = @per.body[-1].gsub(/,$/, '') #= Ax[:tab]*1 + '}'
+        content << @per.open << @per.head << @per.body << @per.metadata
+        content << @per.tail << @per.close
+        content=content.flatten.compact
+        Output.new(content,@md).json
+      end
+    end
+    class Output
+      def initialize(data,md)
+        @data,@md=data,md
+        @file=SiSU_Env::FileOp.new(@md)
+      end
+      def json
+        SiSU_Env::FileOp.new(@md).mkdir
+        filename_json=@file.write_file.json
+        @data.each do |str|
+          str=str.gsub(/\A\s+\Z/m,'') #str.gsub(/^\s+$/,'')
+          filename_json.puts str unless str.empty?
+        end
+        filename_json.close
+      end
+    end
+  end
+end
+__END__
diff --git a/lib/sisu/json_format.rb b/lib/sisu/json_format.rb
new file mode 100644 (file)
index 0000000..fd1d47f
--- /dev/null
@@ -0,0 +1,478 @@
+# encoding: utf-8
+=begin
+
+* Name: SiSU
+
+** Description: documents, structuring, processing, publishing, search
+*** Description: json output logic, flow
+
+** Author: Ralph Amissah
+  [ralph@amissah.com]
+  [ralph.amissah@gmail.com]
+
+** Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+  2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 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/licensing/licenses/gpl.html]
+  [http://www.gnu.org/licenses/gpl.html]
+
+** 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]
+
+** Git
+  [http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=summary]
+  [http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=blob;f=lib/sisu/json_format.rb;hb=HEAD]
+
+=end
+module SiSU_JSON_Format
+  require_relative 'dp'                                 # dp.rb
+  require_relative 'json_parts'                         # json_parts.rb
+  include SiSU_Param
+  class ParagraphNumber
+    def initialize(md,paranum)
+      @md=md
+      @paranum=(paranum \
+      ? (/(\d+)/m.match(paranum)[1])
+      : nil)
+    end
+    def display
+      p_num_display=if @paranum
+        @paranum.gsub(/(\d+)/,
+        '<font size="1" color="#777777">' +
+        '&nbsp;&nbsp;\1</font>')
+      else ''
+      end
+      p_num_display
+    end
+    def name
+      p_num_name=@paranum.gsub(/(\d+)/,'<a name="\1"></a>')
+      p_num_name
+    end
+    def goto
+      p_num_goto=@paranum.gsub(/(\d+)/,'<a href="#\1">')
+      p_num_goto
+    end
+  end
+  class HeadInformation
+    include SiSU_Parts_JSON
+    def initialize #dc rdf
+      @full_title=@subtitle=@author=@subject=@description=@publisher=@contributor=@date=@type=@format=@identifier=@source=@language=@relation=@coverage=@rights=@copyright=@owner=@keywords=''
+      @md=@@md
+      # DublinCore 1 - title
+      @rdfurl=%{  rdf:about="http://www.jus.uio.no/lm/toc"\n}
+      if defined? @md.title.full \
+      and @md.title.full                                                      # DublinCore 1 - title
+        @rdf_title=%{    dc.title="#{seg_name}#{@md.title.full}"\n}
+        @full_title=%{<meta name="dc.title" content="#{seg_name}#{@md.title.full}" />\n}
+      end
+      if defined? @md.creator.author \
+      and @md.creator.author                                                  # DublinCore 2 - creator/author (author)
+        @rdf_author=%{    dc.author="#{@md.creator.author}"\n}
+        @author=%{<meta name="dc.author" content="#{@md.creator.author}" />\n}
+      end
+      if defined? @md.classify.subject \
+      and @md.classify.subject=~/\S+/                                          # DublinCore 3 - subject (us library of congress, eric or udc, or schema???)
+        @rdf_subject=%{    dc.subject="#{@md.classify.subject}"\n}
+        @subject=%{<meta name="dc.subject" content="#{@md.classify.subject}" />\n}
+      end
+      if defined? @md.notes.description \
+      and @md.notes.description=~/\S+/                                        # DublinCore 4 - description
+        @rdf_description=%{    dc.description="#{@md.notes.description}"\n}
+        @description=%{<meta name="dc.description" content="#{@md.notes.description}" />\n}
+      end
+      if defined? @md.publisher \
+      and @md.publisher=~/\S+/                                                # DublinCore 5 - publisher (current copy published by)
+        @rdf_publisher=%{    dc.publisher="#{@md.publisher}"\n}
+        @publisher=%{<meta name="dc.publisher" content="#{@md.publisher}" />\n}
+      end
+      if defined? @md.creator.contributor \
+      and @md.creator.contributor=~/\S+/                                      # DublinCore 6 - contributor
+        @rdf_contributor=%{    dc.contributor="#{@md.creator.contributor}"\n}
+        @contributor=%{<meta name="dc.contributor" content="#{@md.creator.contributor}" />\n}
+      end
+      if defined? @md.date.published \
+      and @md.date.published                                                  # DublinCore 7 - date year-mm-dd
+        @rdf_date=%{    dc.date="#{@md.date.published}"\n}
+        @date=%{<meta name="dc.date" content="#{@md.date.published}" #{@md.date_scheme} />\n}
+      end
+      if defined? @md.date.created \
+      and @md.date.created                                                    # DublinCore 7 - date.created year-mm-dd
+        @rdf_date_created=%{    dc.date.created="#{@md.date.created}"\n}
+        @date_created=%{<meta name="dc.date.created" content="#{@md.date.created}" #{@md.date_created_scheme} />\n}
+      end
+      if defined? @md.date.issued \
+      and @md.date.issued                                                      # DublinCore 7 - date.issued year-mm-dd
+        @rdf_date_issued=%{    dc.date.issued="#{@md.date.issued}"\n}
+        @date_issued=%{<meta name="dc.date.issued" content="#{@md.date.issued}" #{@md.date_issued_scheme} />\n}
+      end
+      if defined? @md.date.available \
+      and @md.date.available                                                  # DublinCore 7 - date.available year-mm-dd
+        @rdf_date_available=%{    dc.date.available="#{@md.date.available}"\n}
+        @date_available=%{<meta name="dc.date.available" content="#{@md.date.available}" #{@md.date_available_scheme} />\n}
+      end
+      if defined? @md.date.valid \
+      and @md.date.valid                                                      # DublinCore 7 - date.valid year-mm-dd
+        @rdf_date_valid=%{    dc.date.valid="#{@md.date.valid}"\n}
+        @date_valid=%{<meta name="dc.date.valid" content="#{@md.date.valid}" #{@md.date_valid_scheme} />\n}
+      end
+      if defined? @md.date.modified \
+      and @md.date.modified                                                   # DublinCore 7 - date.modified year-mm-dd
+        @rdf_date_modified=%{    dc.date.modified="#{@md.date.modified}"\n}
+        @date_modified=%{<meta name="dc.date.modified" content="#{@md.date.modified}" #{@md.date_modified_scheme} />\n}
+      end
+      if defined? @md.notes.coverage \
+      and @md.notes.coverage=~/\S+/                                        # DublinCore 14 - coverage
+        @rdf_coverage=%{    dc.coverage="#{@md.notes.coverage}"\n}
+        @coverage=%{<meta name="dc.coverage" content="#{@md.notes.coverage}" />\n}
+      end
+      if defined? @md.notes.relation \
+      and @md.notes.relation=~/\S+/                                         # DublinCore 13 - relation
+        @rdf_relation=%{    dc.relation="#{@md.notes.relation}"\n}
+        @relation=%{<meta name="dc.relation" content="#{@md.notes.relation}" />\n}
+      end
+      if defined? @md.notes.type \
+      and @md.notes.type                                                            # DublinCore 8 - type (genre eg. report, convention etc)
+        @rdf_type=%{    dc.type="#{@md.notes.type}"\n}
+        @type=%{<meta name="dc.type" content="#{@md.notes.type}" />\n}
+      end
+      if defined? @md.notes.format \
+      and @md.notes.format=~/\S+/                                              # DublinCore 9 - format (use your mime type)
+        @rdf_format=%{    dc.format="#{@md.notes.format}"\n}
+        @format=%{<meta name="dc.format" content="#{@md.notes.format}" />\n}
+      end
+      #if defined? @md.identifier.sisupod \
+      #and @md.identifier.sisupod=~/\S+/                                       # DublinCore 10 - identifier (your identifier, could use urn which is free)
+      #  @rdf_identifier=%{    dc.identifier="#{@md.identifier.sisupod}"\n}
+      #  @identifier=%{<meta name="dc.identifier" content="#{@md.identifier.sisupod}" />\n}
+      #end
+      if defined? @md.original.source \
+      and @md.original.source=~/\S+/                                           # DublinCore 11 - source (document source)
+        @rdf_source=%{    dc.source="#{@md.original.source}"\n}
+        @source=%{<meta name="dc.source" content="#{@md.source}" />\n}
+      end
+      if defined? @md.original.language \
+      and @md.original.language=~/\S+/                                         # DublinCore 12 - language (English)
+        @rdf_language=%{    dc.language="#{@md.original.title}"\n}
+        @language=%{<meta name="dc.language" content="#{@md.language[:name]}" />\n}
+      end
+      if defined? @md.rights.all \
+      and @md.rights.all=~/\S+/                                               # DublinCore 15 - rights
+        rights=meta_content_clean(@md.rights.all)
+        copyright=meta_content_clean(@md.rights.copyright.all)
+        @rdf_rights=%{    dc.rights="#{rights}"\n}
+        @rights=%{<meta name="dc.rights" content="#{rights}" />\n}
+      end
+      @copyright=%{<meta name="copyright" content="#{copyright}" />\n} \
+        if @md.rights.copyright.all # possibly redundant see dc.rights
+      @owner=%{<meta name="owner" content="#{@md.owner}" />\n} if @md.owner
+      @keywords=%{<meta name="keywords" content="#{@md.keywords}" />\n} if @md.keywords
+      @index='index'
+    end
+    def meta_content_clean(content='')
+      content=if not content.nil?
+        content=content.tr('"',"'").
+           gsub(/&/,'&amp;')
+        content=SiSU_XML_Munge::Trans.new(@md).char_enc.utf8(content)
+      else content
+      end
+    end
+    def table_close
+      '</font> </td></tr></table>'
+    end
+    def toc_head
+      <<WOK
+<html>
+<head>
+<title>#{@md.html_title}</title>
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+         xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <rdf:Description
+#{@rdfurl}
+#{@rdf_title}
+#{@rdf_subtitle}
+#{@rdf_author}
+#{@rdf_subject}
+#{@rdf_description}
+#{@rdf_publisher}
+#{@rdf_contributor}
+#{@rdf_date}
+#{@rdf_date_created}
+#{@rdf_date_issued}
+#{@rdf_date_available}
+#{@rdf_date_valid}
+#{@rdf_date_modified}
+#{@rdf_type}
+#{@rdf_format}
+#{@rdf_identifier}
+#{@rdf_source}
+#{@rdf_language}
+#{@rdf_relation}
+#{@rdf_coverage}
+#{@rdf_rights}
+  />
+</rdf:RDF>
+#{@full_title}
+#{@author}
+#{@subject}
+#{@description}
+#{@publisher}
+#{@contributor}
+#{@date}
+#{@date_created}
+#{@date_issued}
+#{@date_available}
+#{@date_valid}
+#{@date_modified}
+#{@type}
+#{@format}
+#{@identifier}
+#{@source}
+#{@language}
+#{@relation}
+#{@coverage}
+#{@rights}
+#{@copyright}
+#{@owner}
+#{@png.ico}
+#{@txt.generator}
+#{@js.head}
+\n</head>
+#{@color.body}
+#{@font.css_table_file}
+<a name="top"></a>
+<a name="up"></a>
+<a name="start"></a>
+#{@js.top}
+WOK
+    end
+  end
+  class ParagraphNumber
+    def initialize(md,ocn)
+      @md,@ocn=md,ocn.to_s
+      @ocn ||=''
+    end
+    def ocn_display
+      @make=SiSU_Env::ProcessingSettings.new(@md)
+      if @make.build.ocn?
+        ocn_class='ocn'
+        if @ocn.to_i==0
+          @ocn.gsub(/^(\d+|)$/,
+            %{<label class="#{ocn_class}"><a name="#{@ocn}">&nbsp;</a></label>})
+        else
+          @ocn.gsub(/^(\d+|)$/,
+            %{<label class="#{ocn_class}"><a name="#{@ocn}">\\1</a></label>})
+        end
+      else
+        ocn_class='ocn_off'
+        @ocn.gsub(/^(\d+|)$/,
+          %{<label class="#{ocn_class}">&nbsp;</label>})
+      end
+    end
+    def name
+      %{<a name="#{@ocn}"></a>}
+    end
+    def id #w3c? "tidy" complains about numbers as identifiers ! annoying
+      %{id="o#{@ocn}"}
+    end
+    def goto
+      %{<a href="##{@ocn}">}
+    end
+  end
+  class FormatTextObject
+    include SiSU_Parts_JSON
+    attr_accessor :md,:dob,:txt,:ocn,:format,:table,:link,:linkname,:paranum,:p_num,:headname,:banner,:url
+    def initialize(md,t_o)
+      @md,@t_o=md,t_o
+      if t_o.class.inspect =~/Object/
+        @txt=if defined? t_o.obj; t_o.obj
+        else nil
+        end
+        @ocn=if defined? t_o.ocn; t_o.ocn.to_s
+        else nil
+        end
+        @headname=if t_o.is==:heading and defined? t_o.name; t_o.name
+        else nil
+        end
+      else
+        if @md.opt.act[:maintenance][:set]==:on
+          p __FILE__ << ':' << __LINE__.to_s
+          p t_o.class
+          p caller
+        end
+      end
+      if defined? @t_o.ocn
+        ocn=((@t_o.ocn.to_s =~/\d+/) ? @t_o.ocn : nil)
+        @p_num=ParagraphNumber.new(@md,ocn)
+      end
+      if @format and not @format.empty?
+        if @format=~/^\d:(\S+)/ #need more reliable marker #if @format =~ /#{Rx[:lv]}/
+          headname=$1 #format[/\d~(\S+)/m,1]
+          @headname=if headname =~/^[a-zA-Z]/; %{<a name="#{headname}" id="#{headname}"></a>} #consider: h_#{headname}
+          else %{<a name="h#{headname}" id="h#{headname}"></a>}
+          end
+        end
+      end
+      @dob=t_o if defined? t_o.is
+    end
+    def para
+      para_form_css('p','norm')
+    end
+    def code
+      para_form_css('p','code')
+    end
+    def center
+      para_form_css('p','center')
+    end
+    def bold
+      para_form_css('p','bold')
+    end
+    def bullet
+      para_form_css('li','bullet')
+    end
+    def format(tag,attrib)
+      para_form_css(tag,attrib)
+    end
+    def heading_normal(tag,attrib)
+      %{
+<div class="substance">
+  #{@p_num.ocn_display}
+  <#{tag} class="#{attrib}" #{@p_num.id}>#{@p_num.name}
+    #{@headname}#{@txt}
+  </#{tag}>
+</div>
+}
+    end
+    def heading_body
+      heading_normal('p','norm')
+    end
+    def heading_body0
+      heading_normal('h1','norm')
+    end
+    def heading_body1
+      heading_normal('h1','norm')
+    end
+    def heading_body2
+      heading_normal('h2','norm')
+    end
+    def heading_body3
+      heading_normal('h3','norm')
+    end
+    def heading_body4
+      heading_normal('h4','norm')
+    end
+    def heading_body5
+      heading_normal('h5','norm')
+    end
+    def heading_body6
+      heading_normal('h6','norm')
+    end
+    def heading_body7
+      heading_normal('h7','norm')
+    end
+    def title_header(tag,attrib)
+      %{
+<div class="content">
+<#{tag} class="#{attrib}">
+    #{@txt}
+  </#{tag}>
+</div>
+}
+    end
+    def title_header1
+      title_header('h1','tiny')
+    end
+    def title_header2
+      title_header('h2','tiny')
+    end
+    def title_header3
+      title_header('h3','tiny')
+    end
+    def title_header4
+      ''
+    end
+    def dl #check :trailer
+      "<dl><b>#{@txt}</b> #{@trailer}</dl>"
+    end
+    def table_css_end      #<!TZ!>
+      '</table>
+    </p>
+  </div>'
+    end
+    def gsub_body
+#fix
+      @txt=case @txt
+      when /^\s*\((i+|iv|v|vi+|ix|x|xi+)\)/
+        @txt.gsub(/^\((i+|iv|v|vi+|ix|x|xi+)\)/,'<b>(\1)</b>').
+          gsub(/^(#{Mx[:pa_o]}i[1-9]#{Mx[:pa_c]})\s*\((i+|iv|v|vi+|ix|x|xi+)\)/,'\1<b>(\2)</b>')
+      when /^\s*\(?(\d|[a-z])+\)/
+        @txt.gsub(/^\((\d+|[a-z])+\)/,'<b>(\1)</b>').
+          gsub(/^(#{Mx[:pa_o]}i[1-9]#{Mx[:pa_c]})\s*\((\d+|[a-z])+\)/,'\1<b>(\2)</b>')
+      when /^\s*\d{1,3}\.\s/
+        @txt.gsub(/^\s*(\d+\.)/,'<b>\1</b>')
+      when /^\s*[A-Z]\.\s/
+        @txt.gsub(/^\s*([A-Z]\.)/,'<b>\1</b>')
+      else @txt
+      end
+    end
+    def bold_para
+      %{#{the_margin.txt_0}
+  <p class="bold">
+    #{@txt}
+  </p>
+#{the_margin.num_css}
+  &nbsp;&nbsp;&nbsp;
+#{the_table_close}}
+    end
+    def bold_header
+      @txt=@txt.gsub(/[1-9]~(\S+)/,'<a name="\1"></a>').
+        gsub(/[1-9]~/,'')
+      %{<p class="bold">
+    #{@txt}
+  </p>
+#{the_margin.num_css}
+  &nbsp;&nbsp;&nbsp;
+#{the_table_close}}
+    end
+    def toc_head_copy_at
+      %{<p class="center">#{@txt}</p>\n}
+    end
+    def center
+      %{<p class="center">#{@txt}</p>\n}
+    end
+    def bold
+      %{<p class="bold">#{@txt}</p>\n}
+    end
+    def center_bold
+      %{<p class="centerbold">#{@txt}</p>\n}
+    end
+  end
+end
+__END__
diff --git a/lib/sisu/json_parts.rb b/lib/sisu/json_parts.rb
new file mode 100644 (file)
index 0000000..e53c993
--- /dev/null
@@ -0,0 +1,88 @@
+# encoding: utf-8
+=begin
+
+* Name: SiSU
+
+** Description: documents, structuring, processing, publishing, search
+*** shared xml parts
+
+** Author: Ralph Amissah
+  [ralph@amissah.com]
+  [ralph.amissah@gmail.com]
+
+** Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+  2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 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/licensing/licenses/gpl.html]
+  [http://www.gnu.org/licenses/gpl.html]
+
+** 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]
+
+** Git
+  [http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=summary]
+  [http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=blob;f=lib/sisu/json_parts.rb;hb=HEAD]
+
+=end
+module SiSU_Parts_JSON
+  require_relative 'generic_parts'                       # generic_parts.rb
+  include SiSU_Parts_Generic
+  def the_line_break
+    '<br>'
+  end
+  def the_table_close
+    '</td></tr>
+</table>'
+  end
+  def the_url_decoration
+    def xml_open                     #'&lt;'
+      Dx[:url_o]
+    end
+    def xml_close                    #'&gt;'
+      Dx[:url_c]
+    end
+    def txt_open
+      '['
+    end
+    def txt_close
+      ']'
+    end
+    self
+  end
+end
+module SiSU_Proj_XML
+  require_relative 'html_parts'                         # html_parts.rb
+  require_relative 'se'                                 # se.rb
+  include SiSU_Env
+  class Bits < SiSU_Proj_HTML::Bits
+  end
+end
+__END__
diff --git a/lib/sisu/json_persist.rb b/lib/sisu/json_persist.rb
new file mode 100644 (file)
index 0000000..47c3f66
--- /dev/null
@@ -0,0 +1,124 @@
+# encoding: utf-8
+=begin
+
+* Name: SiSU
+
+** Description: documents, structuring, processing, publishing, search
+*** html segment generation, processing
+
+** Author: Ralph Amissah
+  [ralph@amissah.com]
+  [ralph.amissah@gmail.com]
+
+** Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+  2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 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/licensing/licenses/gpl.html]
+  [http://www.gnu.org/licenses/gpl.html]
+
+** 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]
+
+** Git
+  [http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=summary]
+  [http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=blob;f=lib/sisu/json_persist.rb;hb=HEAD]
+
+=end
+module SiSU_JSON_Persist
+  class Persist
+    @@persist=nil
+    attr_accessor :head,:toc,:body,:tail,:open,:close,:sc,:endnotes,:book_idx,:metadata
+    #attr_accessor :head,:body,:tail,:open,:close,:sc
+#@@odf={ body: [], head: [], toc: [],  metadata: [], tail: [], book_idx: [], endnotes: [] }
+    def initialize(args=nil)
+      @@persist=args=(args ? args : (@@persist || persist_init_hash_values))
+      @head=args[:head]
+      @toc=args[:toc]
+      @body=args[:body]
+      @tail=args[:tail]
+      @open=args[:open]
+      @close=args[:close]
+      @sc=args[:sc]
+      @endnotes=args[:endnotes]
+      @book_idx=args[:book_idx]
+      @metadata=args[:metadata]
+    end
+    def head
+      @head
+    end
+    def toc
+      @toc
+    end
+    def body
+      @body
+    end
+    def tail
+      @tail
+    end
+    def open
+      @open
+    end
+    def close
+      @close
+    end
+    def sc
+      @sc
+    end
+    def endnotes
+      @endnotes
+    end
+    def book_idx
+      @book_idx
+    end
+    def metadata
+      @metadata
+    end
+    def persist_init_hash_values
+      {
+        head: [],
+        toc: [],
+        body: [],
+        tail: [],
+        open: [],
+        close: [],
+        sc: [],
+        endnotes: [],
+        book_idx: [],
+        metadata: [],
+      }
+    end
+    def persist_init
+      @@persist=nil
+      Persist.new(persist_init_hash_values)
+    end
+  end
+end
+__END__
diff --git a/lib/sisu/json_shared.rb b/lib/sisu/json_shared.rb
new file mode 100644 (file)
index 0000000..28bb0ad
--- /dev/null
@@ -0,0 +1,681 @@
+# encoding: utf-8
+=begin
+
+* Name: SiSU
+
+** Description: documents, structuring, processing, publishing, search
+*** Description: json output logic, flow
+
+** Author: Ralph Amissah
+  [ralph@amissah.com]
+  [ralph.amissah@gmail.com]
+
+** Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+  2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 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/licensing/licenses/gpl.html]
+  [http://www.gnu.org/licenses/gpl.html]
+
+** 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]
+
+** Git
+  [http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=summary]
+  [http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=blob;f=lib/sisu/json_shared.rb;hb=HEAD]
+
+=end
+module SiSU_JSONutils
+  require_relative 'generic_parts'                      # generic_parts.rb
+  class Clean
+    def initialize(para='')
+      @para=para
+      #@para,@n_char_max,@n_indent,@post,=para,n_char_max,n_indent,post
+      #@n_char_max_extend = n_char_max
+      #@n_hang=n_hang ? n_hang : @n_indent
+    end
+    def line_json_clean
+      @para=@para.gsub(/<br>/,' \\ ').
+        gsub(/#{Mx[:br_nl]}/,"\n\n").
+        gsub(/"/,'\"').
+        gsub(/'/,"\\\\'")
+      @para
+    end
+  end
+end
+module SiSU_JSON_Munge
+  require_relative 'json_parts'                         # json_parts.rb
+  class Trans
+    include SiSU_Parts_JSON
+    def initialize(md)
+      @md=md
+      @sys=SiSU_Env::SystemCall.new
+      @dir=SiSU_Env::InfoEnv.new(@md.fns)
+      if @md.sem_tag
+        @ab ||=semantic_tags.default
+      end
+    end
+    def semantic_tags
+      def default
+        {
+          pub:   'publication',
+          conv:  'convention',
+          vol:   'volume',
+          pg:    'page',
+          cty:   'city',
+          org:   'organization',
+          uni:   'university',
+          dept:  'department',
+          fac:   'faculty',
+          inst:  'institute',
+          co:    'company',
+          com:   'company',
+          conv:  'convention',
+          dt:    'date',
+          y:     'year',
+          m:     'month',
+          d:     'day',
+          ti:    'title',
+          au:    'author',
+          ed:    'editor', #editor?
+          v:     'version', #edition
+          n:     'name',
+          fn:    'firstname',
+          mn:    'middlename',
+          ln:    'lastname',
+          in:    'initials',
+          qt:    'quote',
+          ct:    'cite',
+          ref:   'reference',
+          ab:    'abreviation',
+          def:   'define',
+          desc:  'description',
+          trans: 'translate',
+        }
+      end
+      self
+    end
+    def char_enc #character encode
+      def utf8(dob='')
+        if @sys.locale =~/utf-?8/i # instead ucs for utf8 # String#encode Iñtërnâtiônàlizætiøn
+          str=if defined? dob.obj then dob.obj
+          elsif dob.is_a?(String) then dob
+          end
+          if str
+            #¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûü
+            #¢£¥§©ª«®°±²³µ¶¹º»¼½¾×÷
+            str=str.gsub(/</um,'&#60;').    # '&lt;'     # &#060;
+              gsub(/>/um,'&#62;').    # '&gt;'     # &#062;
+              gsub(/¢/um,'&#162;').   # '&cent;'   # &#162;
+              gsub(/£/um,'&#163;').   # '&pound;'  # &#163;
+              gsub(/¥/um,'&#165;').   # '&yen;'    # &#165;
+              gsub(/§/um,'&#167;').   # '&sect;'   # &#167;
+              gsub(/©/um,'&#169;').   # '&copy;'   # &#169;
+              gsub(/ª/um,'&#170;').   # '&ordf;'   # &#170;
+              gsub(/«/um,'&#171;').   # '&laquo;'  # &#171;
+              gsub(/®/um,'&#174;').   # '&reg;'    # &#174;
+              gsub(/°/um,'&#176;').   # '&deg;'    # &#176;
+              gsub(/±/um,'&#177;').   # '&plusmn;' # &#177;
+              gsub(/²/um,'&#178;').   # '&sup2;'   # &#178;
+              gsub(/³/um,'&#179;').   # '&sup3;'   # &#179;
+              gsub(/µ/um,'&#181;').   # '&micro;'  # &#181;
+              gsub(/¶/um,'&#182;').   # '&para;'   # &#182;
+              gsub(/¹/um,'&#185;').   # '&sup1;'   # &#185;
+              gsub(/º/um,'&#186;').   # '&ordm;'   # &#186;
+              gsub(/»/um,'&#187;').   # '&raquo;'  # &#187;
+              gsub(/¼/um,'&#188;').   # '&frac14;' # &#188;
+              gsub(/½/um,'&#189;').   # '&frac12;' # &#189;
+              gsub(/¾/um,'&#190;').   # '&frac34;' # &#190;
+              gsub(/×/um,'&#215;').   # '&times;'  # &#215;
+              gsub(/÷/um,'&#247;').   # '&divide;' # &#247;
+              gsub(/¿/um,'&#191;').   # '&iquest;' # &#191;
+              gsub(/À/um,'&#192;').   # '&Agrave;' # &#192;
+              gsub(/Á/um,'&#193;').   # '&Aacute;' # &#193;
+              gsub(/Â/um,'&#194;').   # '&Acirc;'  # &#194;
+              gsub(/Ã/um,'&#195;').   # '&Atilde;' # &#195;
+              gsub(/Ä/um,'&#196;').   # '&Auml;'   # &#196;
+              gsub(/Å/um,'&#197;').   # '&Aring;'  # &#197;
+              gsub(/Æ/um,'&#198;').   # '&AElig;'  # &#198;
+              gsub(/Ç/um,'&#199;').   # '&Ccedil;' # &#199;
+              gsub(/È/um,'&#200;').   # '&Egrave;' # &#200;
+              gsub(/É/um,'&#201;').   # '&Eacute;' # &#201;
+              gsub(/Ê/um,'&#202;').   # '&Ecirc;'  # &#202;
+              gsub(/Ë/um,'&#203;').   # '&Euml;'   # &#203;
+              gsub(/Ì/um,'&#204;').   # '&Igrave;' # &#204;
+              gsub(/Í/um,'&#205;').   # '&Iacute;' # &#205;
+              gsub(/Î/um,'&#206;').   # '&Icirc;'  # &#206;
+              gsub(/Ï/um,'&#207;').   # '&Iuml;'   # &#207;
+              gsub(/Ð/um,'&#208;').   # '&ETH;'    # &#208;
+              gsub(/Ñ/um,'&#209;').   # '&Ntilde;' # &#209;
+              gsub(/Ò/um,'&#210;').   # '&Ograve;' # &#210;
+              gsub(/Ó/um,'&#211;').   # '&Oacute;' # &#211;
+              gsub(/Ô/um,'&#212;').   # '&Ocirc;'  # &#212;
+              gsub(/Õ/um,'&#213;').   # '&Otilde;' # &#213;
+              gsub(/Ö/um,'&#214;').   # '&Ouml;'   # &#214;
+              gsub(/Ø/um,'&#216;').   # '&Oslash;' # &#216;
+              gsub(/Ù/um,'&#217;').   # '&Ugrave;' # &#217;
+              gsub(/Ú/um,'&#218;').   # '&Uacute;' # &#218;
+              gsub(/Û/um,'&#219;').   # '&Ucirc;'  # &#219;
+              gsub(/Ü/um,'&#220;').   # '&Uuml;'   # &#220;
+              gsub(/Ý/um,'&#221;').   # '&Yacute;' # &#221;
+              gsub(/Þ/um,'&#222;').   # '&THORN;'  # &#222;
+              gsub(/ß/um,'&#223;').   # '&szlig;'  # &#223;
+              gsub(/à/um,'&#224;').   # '&agrave;' # &#224;
+              gsub(/á/um,'&#225;').   # '&aacute;' # &#225;
+              gsub(/â/um,'&#226;').   # '&acirc;'  # &#226;
+              gsub(/ã/um,'&#227;').   # '&atilde;' # &#227;
+              gsub(/ä/um,'&#228;').   # '&auml;'   # &#228;
+              gsub(/å/um,'&#229;').   # '&aring;'  # &#229;
+              gsub(/æ/um,'&#230;').   # '&aelig;'  # &#230;
+              gsub(/ç/um,'&#231;').   # '&ccedil;' # &#231;
+              gsub(/è/um,'&#232;').   # '&egrave;' # &#232;
+              gsub(/é/um,'&#233;').   # '&acute;'  # &#233;
+              gsub(/ê/um,'&#234;').   # '&circ;'   # &#234;
+              gsub(/ë/um,'&#235;').   # '&euml;'   # &#235;
+              gsub(/ì/um,'&#236;').   # '&igrave;' # &#236;
+              gsub(/í/um,'&#237;').   # '&acute;'  # &#237;
+              gsub(/î/um,'&#238;').   # '&icirc;'  # &#238;
+              gsub(/ï/um,'&#239;').   # '&iuml;'   # &#239;
+              gsub(/ð/um,'&#240;').   # '&eth;'    # &#240;
+              gsub(/ñ/um,'&#241;').   # '&ntilde;' # &#241;
+              gsub(/ò/um,'&#242;').   # '&ograve;' # &#242;
+              gsub(/ó/um,'&#243;').   # '&oacute;' # &#243;
+              gsub(/ô/um,'&#244;').   # '&ocirc;'  # &#244;
+              gsub(/õ/um,'&#245;').   # '&otilde;' # &#245;
+              gsub(/ö/um,'&#246;').   # '&ouml;'   # &#246;
+              gsub(/ø/um,'&#248;').   # '&oslash;' # &#248;
+              gsub(/ù/um,'&#250;').   # '&ugrave;' # &#250;
+              gsub(/ú/um,'&#251;').   # '&uacute;' # &#251;
+              gsub(/û/um,'&#252;').   # '&ucirc;'  # &#252;
+              gsub(/ü/um,'&#253;').   # '&uuml;'   # &#253;
+              gsub(/þ/um,'&#254;').   # '&thorn;'  # &#254;
+              gsub(/ÿ/um,'&#255;').   # '&yuml;'   # &#255;
+              gsub(/‘/um,'&#8216;').  # '&lsquo;'  # &#8216;
+              gsub(/’/um,'&#8217;').  # '&rsquo;'  # &#8217;
+              gsub(/“/um,'&#8220;').  # &ldquo;    # &#8220;
+              gsub(/”/um,'&#8221;').  # &rdquo;    # &#8221;
+              gsub(/–/um,'&#8211;').  # &ndash;    # &#8211;
+              gsub(/—/um,'&#8212;').  # &mdash;    # &#8212;
+              gsub(/∝/um,'&#8733;').  # &prop;     # &#8733;
+              gsub(/∞/um,'&#8734;').  # &infin;    # &#8734;
+              gsub(/™/um,'&#8482;').  # &trade;    # &#8482;
+              gsub(/✠/um,'&#10016;'). # &cross;    # &#10016;
+              gsub(/ /um,' ').       # space identify
+              gsub(/ /um,' ')       # space identify
+          end
+          dob=if defined? dob.obj
+            dob.obj=str
+            dob
+          elsif dob.is_a?(String)
+            str
+          end
+          dob
+        end
+      end
+      def html(dob='')
+        if @sys.locale =~/utf-?8/i # instead ucs for utf8 # String#encode Iñtërnâtiônàlizætiøn
+          dob.obj=dob.obj.gsub(/ /u,' ').           # space identify
+            gsub(/ /u,' ')           # space identify
+        end
+      end
+      self
+    end
+    def tidywords(wordlist)
+      wordlist_new=[]
+      wordlist.each do |x|
+        #imperfect solution will not catch all possible cases
+        x=x.gsub(/&/,'&amp;') unless x =~/&\S+;/
+        x=x.gsub(/&([A-Z])/,'&amp;\1')
+        wordlist_new << x
+      end
+      wordlist_new
+    end
+    def markup(dob='')
+      wordlist=dob.obj.scan(/&[#0-9a-z]+;|\S+|\n/) #\n needed for tables, check though added 2005w17
+      dob.obj=tidywords(wordlist).join(' ').strip
+      unless dob.is==:table
+        dob.obj=dob.obj.gsub(/#{Mx[:br_line]}/u,'<br>').
+          gsub(/#{Mx[:br_paragraph]}/u,'<br>').
+          gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br>')
+      end
+      dob.obj=dob.obj.gsub(/#{Mx[:mk_o]}:name#\S+?#{Mx[:mk_c]}/,'').
+        gsub(/#{Mx[:mk_o]}#([a-zA-Z]+)#{Mx[:mk_c]}/,'&\1;').
+        gsub(/#{Mx[:mk_o]}(#[0-9]+)#{Mx[:mk_c]}/,'&\1;').
+        gsub(/(^|#{Mx[:gl_c]}|\s+)<\s+/,'\1&lt; ').gsub(/\s+>(\s+|$)/,' &gt;\1').
+        #gsub(/#{Mx[:fa_emphasis_o]}(.+?)#{Mx[:fa_emphasis_c]}/,'<em>\1</em>'). #reinstate
+        gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/m,'<b>\1</b>').
+        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/m,'<i>\1</i>').
+        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>').
+        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>').
+        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>').
+        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'<ins>\1</ins>').
+        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'<cite>\1</cite>').
+        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>').
+        gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>').
+        gsub(/<:pb>\s*/,''). #Fix
+        gsub(/<+[-~]#>+/,'')
+      if dob.is !=:code
+        #embeds a red-bullet image -->
+        dob.obj=dob.obj.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>').
+          gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>').
+          gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>').
+          gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>')
+        dob.obj=dob.obj.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br>') unless dob.is==:table
+        dob.obj=dob.obj.gsub(/#{Mx[:br_page]}\s*/,'').
+          gsub(/#{Mx[:br_page_new]}\s*/,'').
+          gsub(/#{Mx[:br_page_line]}\s*/,'').
+          gsub(/#{Mx[:pa_non_object_no_heading]}|#{Mx[:pa_non_object_dummy_heading]}/,'').
+          gsub(/<[-~]#>/,'').
+          gsub(/href="#{Xx[:segment]}/m,'href="').
+          gsub(/#{Mx[:lnk_o]}([^#{Mx[:lnk_o]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{Mx[:rel_c]}]+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}(\.\.\/\S+?)#{Mx[:rel_c]}/,
+            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="\2">\1</link>').
+          gsub(/#{Mx[:lnk_o]}([^#{Mx[:lnk_o]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{Mx[:rel_c]}]+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}:(\S+?)#{Mx[:rel_c]}/,
+            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="../\2">\1</link>').
+          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}(\S+?)#{Mx[:rel_c]}/,
+            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="#\2">\1</link>').
+          gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}[ ]*(\S+?\.(?:jpg|png|gif))[ ]+(\d+)x(\d+)(\s+[^}]+)?#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,
+            %{<image xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:actuate="onLoad" xl:show="embed" xl:href="#{@md.file.output_path.xml.rel_image}/\\1" width="\\2" height="\\3" />[\\1] \\4}).
+          gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}[ ]*(\S+?\.(?:jpg|png|gif))([ ]+[^}]+)?#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,
+            %{<image xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:actuate="onLoad" xl:show="embed" xl:href="#{@md.file.output_path.xml.rel_image}/\\1"/>\\1}).
+          gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}[ ]*(\S+?\.(?:jpg|png|gif))[ ]+(\d+)x(\d+)(\s+[^}]+)?#{Mx[:lnk_c]}image/,
+            %{<image xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:actuate="onLoad" xl:show="embed" xl:href="#{@md.file.output_path.xml.rel_image}/\\1" width="\\2" height="\\3" />[\\1] \\4}).
+          gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}[ ]*(\S+?\.(?:jpg|png|gif))([ ]+[^}]+)?#{Mx[:lnk_c]}image/,
+            %{<image xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:actuate="onLoad" xl:show="embed" xl:href="#{@md.file.output_path.xml.rel_image}/\\1"/>\\1}).
+          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,
+            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="\2">\1</link>'). #watch, compare html_tune
+          gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,
+            %{#{the_url_decoration.xml_open}<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="\\1">\\1</link>#{the_url_decoration.xml_close}}).
+          gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,
+            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="\1">\1</link>') #escaped urls not linked, deal with later
+      else
+        dob.obj=dob.obj.gsub(/</m,'&lt;').gsub(/>/m,'&gt;')
+      end
+      if dob.of==:block
+        dob.obj=dob.obj.gsub(/#{Mx[:gl_bullet]}/,'● ')
+      end
+      dob.obj=dob.obj.gsub(/#{Mx[:url_o]}([a-zA-Z0-9._-]+\@\S+?\.[a-zA-Z0-9._-]+)#{Mx[:url_c]}/,
+          %{#{the_url_decoration.xml_open}\\1#{the_url_decoration.xml_close}}).
+        gsub(/#{Dx[:url_o]}/,"#{Dx[:url_o_xml]}").
+        gsub(/#{Dx[:url_c]}/,"#{Dx[:url_c_xml]}").
+        gsub(/&nbsp;|#{Mx[:nbsp]}/m,'&#160;').
+        gsub(/;&([^#]|(?:[^gl][^t]|[^a][^m][^p]|[^n][^b][^s][^p])[^;])/,';&amp;\1') # pattern not to match
+      dob
+    end
+    def markup_light(dob='')
+      dob.obj=dob.obj.gsub(/\/\{(.+?)\}\//,'<i>\1</i>').
+        gsub(/[*!]\{(.+?)\}[*!]/,'<b>\1</b>').
+        gsub(/_\{(.+?)\}_/,'<u>\1</u>').
+        gsub(/-\{(.+?)\}-/,'<del>\1</del>').
+        gsub(/<br(\s*\/)?>/,'<br>').
+        gsub(/<:pb>\s*/,'').
+        gsub(/<[-~]#>/,'').
+        gsub(/(^|#{Mx[:gl_c]}|\s)&\s+/,'\1&amp; '). #sort
+        gsub(/&([^;]{1,5})/,'&amp;\1'). #sort, rough estimate, revisit #WATCH found in node not sax
+        gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif))[ ]+.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/,
+          "<image.path>#{@md.file.output_path.xml.rel_image}\/\\1</image.path>").
+        gsub(/&nbsp;|#{Mx[:nbsp]}/,'&#160;').
+        gsub(/;&([^#]|(?:[^gl][^t]|[^a][^m][^p]|[^n][^b][^s][^p])[^;])/,';&amp;\1') # pattern not to match
+      wordlist=dob.obj.scan(/&[#0-9a-z]+;|\S+|\n/) #\n needed for tables, check though added 2005w17
+      dob.obj=tidywords(wordlist).join(' ').strip
+      dob
+    end
+    def clean(str)
+      str=str.gsub(/#{Mx[:gl_o]}(#[0-9]{3})#{Mx[:gl_c]}/u,'&\1;').
+        gsub(/#{Mx[:gl_o]}#([a-z]{2,4})#{Mx[:gl_c]}/u,'&\1;')
+    end
+    def markup_fictionbook(str='',is='')
+      str=str.gsub(/#{Mx[:en_a_o]}([\d+*]+).+?#{Mx[:en_a_c]}/m,'<a xl:href="#footnote\1" type="note">[\1]</a>').
+        gsub(/&/,'&amp;'). #sort
+        gsub(/#{Mx[:mk_o]}#([a-zA-Z]+)#{Mx[:mk_c]}/,'&\1;').
+        gsub(/(^|#{Mx[:gl_c]}|\s)&\s+/,'\1&amp; '). #sort
+        gsub(/#{Mx[:mk_o]}(#[0-9]+)#{Mx[:mk_c]}/,'&\1;')
+      str=str.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br>') unless is==:table
+      str=str.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>').
+        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>').
+        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>').
+        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>').
+        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>').
+        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'<ins>\1</ins>').
+        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'<cite>\1</cite>').
+        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>').
+        gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>'). # tt, kbd
+        gsub(/#{Mx[:lnk_o]}\s*(\S+?\.(?:png|jpg|gif)).+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/m,'<image xl:href="#\1" />').
+        gsub(/#{Mx[:url_o]}(.+?)#{Mx[:url_c]}/,"#{Dx[:url_o]}\\1#{Dx[:url_c]}").
+        gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'<a name="\1"></a>').
+        gsub(/#{Mx[:gl_bullet]}/m,'● '). #&nbsp; not available
+        gsub(/#{Mx[:nbsp]}/,' '). #&nbsp; not available
+        gsub(/<(p|br)>/,'<\1 />')
+      clean(str)
+    end
+    def markup_docbook(dob='')                                  # work on, initially a copy of fictionbook!
+      if dob.is !=:code
+        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}(\d+)\s*(.+?)#{Mx[:en_a_c]}/m,'<footnote><para><!-- fn\1 -->\2</para></footnote>').
+          gsub(/\\\\/,'</para><para>').
+          gsub(/&/,'&amp;'). #sort
+          gsub(/#{Mx[:mk_o]}#([a-zA-Z]+)#{Mx[:mk_c]}/,'&\1;').
+          gsub(/(^|#{Mx[:gl_c]}|\s)&\s+/,'\1&amp; '). #sort
+          gsub(/#{Mx[:mk_o]}(#[0-9]+)#{Mx[:mk_c]}/,'&\1;')
+        dob.obj=dob.obj.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br>') unless dob.is==:table
+        dob.obj=dob.obj.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>').
+          gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>').
+          gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>').
+          gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>').
+          gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>').
+          gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'<ins>\1</ins>').
+          gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'<cite>\1</cite>').
+          gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>').
+          gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>'). # tt, kbd
+          gsub(/#{Mx[:lnk_o]}\s*(\S+?)\.(png|jpg|gif).+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/m,
+            %{#{Xx[:split]}:spaces0:<figure id="fig-\\1">\n:spaces1:<title></title>\n:spaces1:<graphic fileref="../../_sisu/image/\\1.\\2" align="center" width="50%"></graphic>\n:spaces0:</figure>#{Xx[:split]}}). # common image location, else use ./images
+          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(.+?)#{Mx[:url_c]}/,
+            '<ulink url="\2">\1</ulink>').
+          gsub(/#{Mx[:url_o]}(.+?)#{Mx[:url_c]}/,
+            '<ulink url="\1">\1</ulink>').
+          gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'<a name="\1"></a>').
+          gsub(/#{Mx[:gl_bullet]}/m,'● '). #&nbsp; not available
+          gsub(/#{Mx[:nbsp]}/,' '). #&nbsp; not available
+          gsub(/<(p|br)>/,'<\1 />')
+        dob.obj=clean(dob.obj)
+      elsif dob.is == :code
+        dob.obj=dob.obj.gsub(/&/m,'&amp;'). #sort
+          gsub(/</,'&lt;').gsub(/>/,'&gt;')
+      else # p dob.is ??
+      end
+      dob
+    end
+    def markup_group(dob='')
+      dob.obj=dob.obj.gsub(/</,'&lt;').gsub(/>/,'&gt;').
+        gsub(/&lt;:?br(?:\s+\/)?&gt;/,'<br>').
+        gsub(/&lt;(link xmlns:xl=".+?")&gt;/,'<\1>').
+        gsub(/&lt;(\/link)&gt;/,'<\1>').
+        gsub(/&lt;(\/?en)&gt;/,'<\1>')
+      dob
+    end
+    def markup_block(dob='')
+      dob.obj=dob.obj.gsub(/</,'&lt;').gsub(/>/,'&gt;').
+        gsub(/&lt;:?br(?:\s+\/)?&gt;/,'<br>').
+        gsub(/&lt;(link xmlns:xl=".+?")&gt;/,'<\1>').
+        gsub(/&lt;(\/link)&gt;/,'<\1>').
+        gsub(/&lt;(\/?en)&gt;/,'<\1>')
+      dob
+    end
+    def xml_sem_block_paired(matched) # colon depth: many, recurs
+      matched=matched.gsub(/\b(au):\{(.+?)\}:\1\b/m,  %{<sem:#{@ab[:au]} depth="many">\\2</sem:#{@ab[:au]}>}).
+        gsub(/\b(vol):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:vol]} depth="many">\\2</sem:#{@ab[:vol]}>}).
+        gsub(/\b(pub):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:pub]} depth="many">\\2</sem:#{@ab[:pub]}>}).
+        gsub(/\b(ref):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:ref]} depth="many">\\2</sem:#{@ab[:ref]}>}).
+        gsub(/\b(desc):\{(.+?)\}:\1\b/m,%{<sem:#{@ab[:desc]} depth="many">\\2</sem:#{@ab[:desc]}>}).
+        gsub(/\b(conv):\{(.+?)\}:\1\b/m,%{<sem:#{@ab[:conv]} depth="many">\\2</sem:#{@ab[:conv]}>}).
+        gsub(/\b(ct):\{(.+?)\}:\1\b/m,  %{<sem:#{@ab[:ct]} depth="many">\\2</sem:#{@ab[:ct]}>}).
+        gsub(/\b(cty):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:cty]} depth="many">\\2</sem:#{@ab[:cty]}>}).
+        gsub(/\b(org):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:org]} depth="many">\\2</sem:#{@ab[:org]}>}).
+        gsub(/\b(dt):\{(.+?)\}:\1\b/m,  %{<sem:#{@ab[:dt]} depth="many">\\2</sem:#{@ab[:dt]}>}).
+        gsub(/\b(n):\{(.+?)\}:\1\b/m,   %{<sem:#{@ab[:n]} depth="many">\\2</sem:#{@ab[:n]}>}).
+        gsub(/([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\1)/m,'<sem:\1 depth="many">\2</sem:\1>')
+    end
+    def xml_semantic_tags(dob)
+      if @md.sem_tag
+        dob.obj.gsub!(/([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\1)/m) {|c| xml_sem_block_paired(c) }
+        dob.obj.gsub!(/([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\1)/m) {|c| xml_sem_block_paired(c) }
+        dob.obj.gsub!(/([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\1)/m) {|c| xml_sem_block_paired(c) }
+        dob.obj=dob.obj.gsub(/:\{(.+?)\}:au\b/m,             %{<sem:#{@ab[:au]} depth="one">\\1</sem:#{@ab[:au]}>}).
+          gsub(/:\{(.+?)\}:n\b/m,              %{<sem:#{@ab[:n]} depth="one">\\1</sem:#{@ab[:n]}>}).
+          gsub(/:\{(.+?)\}:ti\b/m,             %{<sem:#{@ab[:ti]} depth="one">\\1</sem:#{@ab[:ti]}>}).
+          gsub(/:\{(.+?)\}:ref\b/m,            %{<sem:#{@ab[:ref]} depth="one">\\1</sem:#{@ab[:ref]}>}).
+          gsub(/:\{(.+?)\}:desc\b/m,           %{<sem:#{@ab[:desc]} depth="one">\\1</sem:#{@ab[:desc]}>}).
+          gsub(/:\{(.+?)\}:cty\b/m,            %{<sem:#{@ab[:cty]} depth="one">\\1</sem:#{@ab[:cty]}>}).
+          gsub(/:\{(.+?)\}:org\b/m,            %{<sem:#{@ab[:org]} depth="one">\\1</sem:#{@ab[:org]}>}).
+          gsub(/:\{(.+?)\}:([a-z]+(?:[_:.][a-z]+)*)/m,'<sem:\2 depth="one">\1</sem:\2>').
+          gsub(/;\{([^}]+(?![;]))\};ti\b/m,    %{<sem:#{@ab[:ti]} depth="zero">\\1</sem:#{@ab[:ti]}>}).
+          gsub(/;\{([^}]+(?![;]))\};qt\b/m,    %{<sem:#{@ab[:qt]} depth="zero">\\1</sem:#{@ab[:qt]}>}).
+          gsub(/;\{([^}]+(?![;]))\};ref\b/m,   %{<sem:#{@ab[:ref]} depth="zero">\\1</sem:#{@ab[:ref]}>}).
+          gsub(/;\{([^}]+(?![;]))\};ed\b/m,    %{<sem:#{@ab[:ed]} depth="zero">\\1</sem:#{@ab[:ed]}>}).
+          gsub(/;\{([^}]+(?![;]))\};v\b/m,     %{<sem:#{@ab[:v]} depth="zero">\\1</sem:#{@ab[:v]}>}).
+          gsub(/;\{([^}]+(?![;]))\};desc\b/m,  %{<sem:#{@ab[:desc]} depth="zero">\\1</sem:#{@ab[:desc]}>}).
+          gsub(/;\{([^}]+(?![;]))\};def\b/m,   %{<sem:#{@ab[:def]} depth="zero">\\1</sem:#{@ab[:def]}>}).
+          gsub(/;\{([^}]+(?![;]))\};trans\b/m, %{<sem:#{@ab[:trans]} depth="zero">\\1</sem:#{@ab[:trans]}>}).
+          gsub(/;\{([^}]+(?![;]))\};y\b/m,     %{<sem:#{@ab[:y]} depth="zero">\\1</sem:#{@ab[:y]}>}).
+          gsub(/;\{([^}]+(?![;]))\};ab\b/m,    %{<sem:#{@ab[:ab]} depth="zero">\\1</sem:#{@ab[:ab]}>}).
+          gsub(/;\{([^}]+(?![;]))\};pg\b/m,    %{<sem:#{@ab[:pg]} depth="zero">\\1</sem:#{@ab[:pg]}>}).
+          gsub(/;\{([^}]+(?![;]))\};fn?\b/m,   %{<sem:#{@ab[:fn]} depth="zero">\\1</sem:#{@ab[:fn]}>}).
+          gsub(/;\{([^}]+(?![;]))\};mn?\b/m,   %{<sem:#{@ab[:mn]} depth="zero">\\1</sem:#{@ab[:mn]}>}).
+          gsub(/;\{([^}]+(?![;]))\};ln?\b/m,   %{<sem:#{@ab[:ln]} depth="zero">\\1</sem:#{@ab[:ln]}>}).
+          gsub(/;\{([^}]+(?![;]))\};in\b/m,    %{<sem:#{@ab[:in]} depth="zero">\\1</sem:#{@ab[:in]}>}).
+          gsub(/;\{([^}]+(?![;]))\};uni\b/m,   %{<sem:#{@ab[:uni]} depth="zero">\\1</sem:#{@ab[:uni]}>}).
+          gsub(/;\{([^}]+(?![;]))\};fac\b/m,   %{<sem:#{@ab[:fac]} depth="zero">\\1</sem:#{@ab[:fac]}>}).
+          gsub(/;\{([^}]+(?![;]))\};inst\b/m,  %{<sem:#{@ab[:inst]} depth="zero">\\1</sem:#{@ab[:inst]}>}).
+          gsub(/;\{([^}]+(?![;]))\};dept\b/m,  %{<sem:#{@ab[:dpt]} depth="zero">\\1</sem:#{@ab[:dept]}>}).
+          gsub(/;\{([^}]+(?![;]))\};org\b/m,   %{<sem:#{@ab[:org]} depth="zero">\\1</sem:#{@ab[:org]}>}).
+          gsub(/;\{([^}]+(?![;]))\};com?\b/m,  %{<sem:#{@ab[:com]} depth="zero">\\1</sem:#{@ab[:com]}>}).
+          gsub(/;\{([^}]+(?![;]))\};cty\b/m,   %{<sem:#{@ab[:cty]} depth="zero">\\1</sem:#{@ab[:cty]}>}).
+          gsub(/;\{([^}]+(?![;]))\};([a-z]+(?:[_:.][a-z]+)*)/m,'<sem:\2 depth="zero">\1</sem:\2>')
+      end
+      dob
+    end
+  end
+end
+module SiSU_XML_Tags #Format
+  require_relative 'dp'                                 # dp.rb
+    include SiSU_Param
+  class RDF
+    include SiSU_Parts_JSON
+    def initialize(md='',seg_name=[],tracker=0)
+      @full_title=@subtitle=@author=@subject=@description=@publisher=@contributor=@date=@date_created=@date_issued=@date_available=@date_valid=@date_modified=@type=@format=@identifier=@source=@language=@relation=@coverage=@rights=@copyright=@owner=@keywords=''
+      @md=md
+      @rdfurl=%{  rdf:about="http://www.jus.uio.no/lm/toc"\n}
+      if defined? @md.title.full \
+      and @md.title.full                          # DublinCore 1 - title
+        @rdf_title=%{    dc.title="#{seg_name}#{@md.title.full}"\n}
+        @full_title=%{  <meta name="dc.title" content="#{@md.title.full}" />\n}
+      end
+      if defined? @md.creator.author \
+      and @md.creator.author=~/\S+/                                            # DublinCore 2 - creator/author (author)
+        @rdf_author=%{    dc.author="#{@md.creator.author}"\n}
+        content=meta_content_clean(@md.creator.author)
+        @author=%{  <meta name="dc.author" content="#{content}" />\n}
+      end
+      if defined? @md.publisher \
+      and @md.publisher                                                        # DublinCore 5 - publisher (current copy published by)
+        @rdf_publisher=%{    dc.publisher="#{@md.publisher}"\n}
+        content=meta_content_clean(@md.publisher)
+        @publisher=%{  <meta name="dc.publisher" content="#{content}" />\n}
+      end
+      if defined? @md.creator.contributor \
+      and @md.creator.contributor=~/\S+/                                      # DublinCore 6 - contributor
+        @rdf_contributor=%{    dc.contributor="#{@md.creator.contributor}"\n}
+        content=meta_content_clean(@md.creator.contributor)
+        @contributor=%{  <meta name="dc.contributor" content="#{content}" />\n}
+      end
+      if defined? @md.date.published \
+      and @md.date.published=~/\S+/                                           # DublinCore 7 - date year-mm-dd
+        @rdf_date=%{    dc.date="#{@md.date.published}"\n}
+        @date=%{  <meta name="dc.date" content="#{@md.date.published}" #{@md.date_scheme} />\n} # fix @md.date_scheme
+      end
+      if defined? @md.date.created \
+      and @md.date.created=~/\S+/                                             # DublinCore 7 - date.created year-mm-dd
+        @rdf_date_created=%{    dc.date.created="#{@md.date.created}"\n}
+        @date_created=%{  <meta name="dc.date.created" content="#{@md.date.created}" #{@md.date_scheme} />\n}
+      end
+      if defined? @md.date.issued \
+      and @md.date.issued=~/\S+/                                              # DublinCore 7 - date.issued year-mm-dd
+        @rdf_date_issued=%{    dc.date.issued="#{@md.date.issued}"\n}
+        @date_issued=%{  <meta name="dc.date.issued" content="#{@md.date.issued}" #{@md.date_scheme} />\n}
+      end
+      if defined? @md.date.available \
+      and @md.date.available=~/\S+/                                           # DublinCore 7 - date.available year-mm-dd
+        @rdf_date_available=%{    dc.date.available="#{@md.date.available}"\n}
+        @date_available=%{  <meta name="dc.date.available" content="#{@md.date.available}" #{@md.date_scheme} />\n}
+      end
+      if defined? @md.date.valid \
+      and @md.date.valid=~/\S+/                                               # DublinCore 7 - date.valid year-mm-dd
+        @rdf_date_valid=%{    dc.date.valid="#{@md.date.valid}"\n}
+        @date_valid=%{  <meta name="dc.date.valid" content="#{@md.date.valid}" #{@md.date_scheme} />\n}
+      end
+      if defined? @md.date.modified \
+      and @md.date.modified=~/\S+/                                            # DublinCore 7 - date.modified year-mm-dd
+        @rdf_date_modified=%{    dc.date.modified="#{@md.date.modified}"\n}
+        @date_modified=%{  <meta name="dc.date.modified" content="#{@md.date.modified}" #{@md.date_scheme} />\n}
+      end
+      if defined? @md.rights.all \
+      and @md.rights.all                                                      # DublinCore 15 - rights
+        @rdf_rights=%{    dc.rights="#{@md.rights.all}"\n}
+        content=meta_content_clean(@md.rights.all)
+        @rights=%{  <meta name="dc.rights" content="#{content}" />\n}
+      end
+      if defined? @md.classify.subject \
+      and @md.classify.subject=~/\S+/                                          # DublinCore 3 - subject (us library of congress, eric or udc, or schema???)
+        @rdf_subject=%{    dc.subject="#{@md.classify.subject}"\n}
+        content=meta_content_clean(@md.classify.subject)
+        @subject=%{  <meta name="dc.subject" content="#{content}" />\n}
+      end
+      if defined? @md.notes.description \
+      and @md.notes.description=~/\S+/                                         # DublinCore 4 - description
+        @rdf_description=%{    dc.description="#{@md.notes.description}"\n}
+        content=meta_content_clean(@md.notes.description)
+        @description=%{  <meta name="dc.description" content="#{content}" />\n}
+      end
+      if defined? @md.notes.coverage \
+      and @md.notes.coverage=~/\S+/                                            # DublinCore 14 - coverage
+        @rdf_coverage=%{    dc.coverage="#{@md.notes.coverage}"\n}
+        content=meta_content_clean(@md.notes.coverage)
+        @coverage=%{  <meta name="dc.coverage" content="#{content}" />\n}
+      end
+      if defined? @md.notes.relation \
+      and @md.notes.relation=~/\S+/                                            # DublinCore 13 - relation
+        @rdf_relation=%{    dc.relation="#{@md.notes.relation}"\n}
+        content=meta_content_clean(@md.notes.relation)
+        @relation=%{  <meta name="dc.relation" content="#{content}" />\n}
+      end
+      if defined? @md.notes.type \
+      and @md.notes.type                                                       # DublinCore 8 - type (genre eg. report, convention etc)
+        @rdf_type=%{    dc.type="#{@md.notes.type}"\n}
+        content=meta_content_clean(@md.notes.type)
+        @type=%{  <meta name="dc.type" content="#{content}" />\n}
+      end
+      if defined? @md.notes.format \
+      and @md.notes.format=~/\S+/                                              # DublinCore 9 - format (use your mime type)
+        @rdf_format=%{    dc.format="#{@md.notes.format}"\n}
+        content=meta_content_clean(@md.notes.format)
+        @format=%{  <meta name="dc.format" content="#{content}" />\n}
+      end
+      #if defined? @md.identifier.sisupod \
+      #and @md.identifier.sisupod=~/\S+/                                       # DublinCore 10 - identifier (your identifier, could use urn which is free)
+      #  @rdf_identifier=%{    dc.identifier="#{@md.identifier.sisupod}"\n}
+      #  content=meta_content_clean(@md.identifier.sisupod)
+      #  @identifier=%{  <meta name="dc.identifier" content="#{content}" />\n}
+      #end
+      if defined? @md.original.source \
+      and @md.original.source=~/\S+/                                           # DublinCore 11 - source (document source)
+        @rdf_source=%{    dc.source="#{@md.original.source}"\n}
+        content=meta_content_clean(@md.original.source)
+        @source=%{  <meta name="dc.source" content="#{content}" />\n}
+      end
+      if defined? @md.title.language \
+      and @md.title.language=~/\S+/                                            # DublinCore 12 - language (English)
+        @rdf_language=%{    dc.language="#{@md.title.language}"\n}
+        @language=%{  <meta name="dc.language" content="#{@md.title.language}" />\n}
+      end
+      if defined? @md.original.language \
+      and @md.original.language=~/\S+/
+        @rdf_language_original=%{    dc.language="#{@md.original.language}"\n}
+        @language_original=%{  <meta name="dc.language" content="#{@md.original.language}" />\n}
+      end
+      content=meta_content_clean(@md.keywords)
+      @keywords=%{  <meta name="keywords" content="#{content}" />\n} if @md.keywords
+    end
+    def meta_content_clean(content='')
+      content=if not content.nil?
+        content=content.tr('"',"'").
+           gsub(/&/,'&amp;')
+        content=SiSU_XML_Munge::Trans.new(@md).char_enc.utf8(content)
+      else content
+      end
+    end
+    def rdfseg #segHead
+      rdftoc
+    end
+    def comment_xml(extra='')
+      generator="Generated by: #{@md.project_details.project} #{@md.project_details.version} of #{@md.project_details.date_stamp} (#{@md.project_details.date})"  if @md.project_details.version
+      lastdone="Last Generated on: #{Time.now}"
+      rubyv="Ruby version: #{@md.ruby_version}"
+      sc=if @md.sc_info
+        "Source file: #{@md.sc_filename} version: #{@md.sc_number} of: #{@md.sc_date}"
+      else ''
+      end
+      if extra.empty?
+<<WOK
+<!-- Document processing information:
+     * #{generator}
+     * #{rubyv}
+     * #{sc}
+     * #{lastdone}
+     * SiSU http://www.jus.uio.no/sisu
+-->
+WOK
+     else
+<<WOK
+<!-- Document processing information:
+     * #{extra}
+     * #{generator}
+     * #{rubyv}
+     * #{sc}
+     * #{lastdone}
+     * SiSU http://www.jus.uio.no/sisu
+-->
+WOK
+      end
+    end
+    def comment_xml_sax
+      desc='SiSU XML, SAX type representation'
+      comment_xml(desc)
+    end
+    def comment_xml_node
+      desc='SiSU XML, Node type representation'
+      comment_xml(desc)
+    end
+    def comment_xml_dom
+      desc='SiSU XML, DOM type representation'
+      comment_xml(desc)
+    end
+    def metatag_html #values strung together, because some empty, and resulting output (line breaks) is much better
+<<WOK
+#{@full_title}#{@subtitle}#{@author}#{@subject}#{@description}#{@publisher}#{@contributor}#{@date}#{@date_created}#{@date_issued}#{@date_available}#{@date_valid}#{@date_modified}#{@type}#{@format}#{@identifier}#{@source}#{@language}#{@relation}#{@coverage}#{@rights}#{@copyright}#{@owner}
+#{SiSU_Proj_XML::Bits.new.txt_generator}
+#{the_png.ico}
+WOK
+    end
+  end
+end
+module SiSU_JSON_Shared
+  require_relative 'xhtml_table'                        # xhtml_table.rb
+  class TableJSON < SiSU_XHTML_Table::TableXHTML
+  end
+end
+__END__
index 8a47b1cdb6556266f46287d640681a5447f0b050..9a95baa5b45ea6917df7dd8cde07943d821257d3 100644 (file)
@@ -418,6 +418,12 @@ module SiSU_File_Op
         fn=base_filename.xml_scaffold_structure_collapse
         make_file(path,fn)
       end
+      def json
+        path=output_path.json.dir
+        make_path(path)
+        fn=base_filename.json
+        make_file(path,fn)
+      end
       def manpage
         path=output_path.manpage.dir
         make_path(path)
@@ -713,6 +719,17 @@ module SiSU_File_Op
         end
         self
       end
+      def json
+        def dir
+          output_path.json.dir + '/' \
+          + base_filename.json
+        end
+        def rel
+          output_path.json.rel + '/' \
+          + base_filename.json
+        end
+        self
+      end
       def sqlite_discrete
         def dir
           output_path.sqlite_discrete.dir + '/' \
@@ -1241,6 +1258,24 @@ module SiSU_File_Op
         end
         i18n(fnh)
       end
+      def json(fh=nil)
+        fh=default_hash_build(fh,Sfx[:json])
+        fh[:lng]=lang_code?(fh[:lng])
+        fnh=if output_dir_structure.by_filename?
+          {
+            fn: 'scroll',
+            ft: fh[:ft],
+            lng: fh[:lng],
+          }
+        else
+          {
+            fn: fh[:fn],
+            ft: fh[:ft],
+            lng: fh[:lng],
+          }
+        end
+        i18n(fnh)
+      end
       def pdf_p(fh=nil)
         fh=default_hash_build(fh,Sfx[:pdf])
         fh[:lng]=lang_code?(fh[:lng])
@@ -2330,6 +2365,30 @@ module SiSU_File_Op
         end
         self
       end
+      def json
+        def ft
+          'json'
+        end
+        def dir
+          set_path(ft).dir.abc
+        end
+        def url
+          set_path(ft).url.abc
+        end
+        def rel
+          set_path(ft).rel.abc
+        end
+        def rcp
+          set_path(ft).rcp.abc
+        end
+        def rel_sm
+          set_path(ft).rel_sm.ab
+        end
+        def rel_image
+          '../../_sisu/image'
+        end
+        self
+      end
       def pdf
         def ft
           'pdf'
index fe4813a6ab8e7779a7dfd1b22a97b047cbbb90e3..c69aa7598164676bab59ea1796d46ed1d78d6e11 100644 (file)
@@ -944,6 +944,18 @@ WOK
         end
         <<WOK
 <text:p text:style-name="P1">#{@tag.capitalize}: #{@inf}</text:p>
+WOK
+      end
+      def metadata
+        SiSU_Metadata::Summary.new(@md).metadata_base
+      end
+      self
+    end
+    def json
+      def meta_para
+        <<WOK
+
+#{@tag.capitalize}: #{@inf}
 WOK
       end
       def metadata
index 86eb2e33a801c6b4ae821458b1a2ea8ed1575b5a..b2674fc4fa842d115d0f7f523d61fc0c28949f69 100644 (file)
@@ -335,6 +335,15 @@ module SiSU_Urls
         end
         self
       end
+      def json
+        {
+          cmd: '--js (json)',
+          viewer: @prog.web_browser,
+          f_pth: @md.file.output_path.json.dir + '/' \
+          + @md.file.base_filename.json,
+          fn: @fn[:json],
+        }
+      end
       def pdf
         def landscape
           {
@@ -620,6 +629,10 @@ module SiSU_Urls
               show.report(report_info.xml.scaffold_collapse)
               #show.maintenance(report_info.xml.scaffold_collapse)
             end
+            if @opt.act[:json][:set]==:on
+              show.report(report_info.json)
+              #show.maintenance(report_info.json)
+            end
             if (@opt.act[:pdf][:set]==:on \
             or @opt.act[:pdf_p][:set]==:on \
             or @opt.act[:pdf_l][:set]==:on)