# encoding: utf-8
=begin

 * Name: SiSU

 * Description: a framework for document structuring, publishing and search

 * Author: Ralph Amissah

 * Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
   2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 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>

   <http://www.sisudoc.org/sisu/en/manifest/gpl.fsf.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>

 * Download:
   <http://www.sisudoc.org/sisu/en/SiSU/download.html>

 * Git
   <http://sources.sisudoc.org/gitweb/?p=code/sisu.git;a=summary>
   <http://sources.sisudoc.org/?p=code/sisu.git;a=blob;f=lib/sisu/v6/html_lite_shared.rb;hb=HEAD>

 * Ralph Amissah
   <ralph@amissah.com>
   <ralph.amissah@gmail.com>

 ** Description: modules shared by db and flatfile output generators, mostly
    xml/xhtml/html formatting

=end
module SiSU_FormatShared
  require_relative 'defaults'                           # defaults.rb
    include SiSU_Viz
  class CSS_Format
    require_relative 'defaults'                         # defaults.rb
    require_relative 'particulars'                      # particulars.rb
    @@fns=nil
    def initialize(md,t_o)
      @md,@t_o=md,t_o
      @txt=@t_o.obj
      @id=@ocn=@t_o.ocn if defined? @t_o.ocn
      @lv=@t_o.lv.to_s if @t_o.is==:heading
      if @md.fns != @@fns
        @@fns,@@hname=@md.fns,''
      end
      @hname=if defined? @t_o.name \
      and not @t_o.name.to_s.empty?
        @@hname=@t_o.name
      else @@hname
      end
      @tab="\t"
      @brace_url=SiSU_Viz::Defaults.new.url_decoration
      @ocn_html_identifier=SiSU_Env::ProcessingSettings.new(@md).ocn_html_identifier
      @@tablehead,@@tablefoot=[],[]
      @vz=SiSU_Viz::Defaults.new
      @env=SiSU_Env::InfoEnv.new(@md.fns)
      @base_url="#{@env.url.root}/#{@md.fnb}/#{@hname}.html"
    end
    def urls(data)
      @words=[]
      map_nametags=SiSU_Particulars::CombinedSingleton.instance.get_map_nametags(@md).nametags_map
      data.each do |word|
        @words << if word=~/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}(#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/
          if word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/
            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/.match(word).captures
          elsif word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/
            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}(\S+?)#{Mx[:rel_c]}/.match(word).captures
          elsif word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}image/
            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}(image)/.match(word).captures
          end
          word=case m
          when /\.png|\.jpg|\.gif|c=|\d+x\d+/
            w,h=/(\d+)x(\d+)/.match(m).captures if m =~/\d+x\d+/
            w=%{width="#{w}"} if w
            h=%{height="#{h}"} if h
            c=m[/"(.+?)"/m,1]
            caption=%{<br /><p class="caption">#{c}</p>} if c
            png=m.scan(/\S+/)[0]
            ins=if u \
            and u.strip !~/^image$/
              %{<a href="#{u}">[#{png}]</a>#{caption}}
            else %{[#{png}] #{caption}}
            end
            word=word.gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/,ins)
          else
            u=case u
            when /^https?:\/\//
              u
            when /^:/
              u=u.gsub(/^:/,'')
              "#{@env.url.root}/#{u}"
            when /^\.\.\// # can remove
              u=u.gsub(/^\.\.\//,'')
              "#{@env.url.root}/#{u}"
            else
              "#{@env.url.root}/#{@md.fnb}/#{map_nametags[u][:segname]}#{Sfx[:html]}##{u}"
            end
            link=m[/(.+)/m]
            png=m.scan(/\S+/)[0].strip
            link=link.strip
            ins=%{<a href="#{u}">#{link}</a>}
            word=word.gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,ins).
              gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/,ins)
            word
          end
          word
        else word
        end
        word
      end
      @words=@words.join(' ')
    end
    def markup_generic(s)
      s=s.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_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'"\1"').
        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'+{\1}+').
        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strke_c]}/,'-{\1}-').
        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_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>'). # tt, kbd
        gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/i,'~')
    end
    def markup_object(t_o)
      s=t_o.obj
      s=if t_o.is !=:code
        s=markup_generic(s)
        if s =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/
          wm=s.scan(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)|\S+/)
          words=urls(wm)
          s=s.gsub(/.+/m,words)
        end
        s.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;').
          gsub(/#{Mx[:url_o]}[_\\](\S+?)#{Mx[:url_c]}/,'<a href="\1" target="_top">\1</a>'). #http ftp matches escaped, no decoration
          gsub(/(#{Mx[:lnk_c]})#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1<a href="\2" target="_top">\2</a>'). #special case \{ e.g. \}http://url
          gsub(/(^|#{Mx[:gl_c]}|\s)#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,%{\\1#{@brace_url.xml_open}<a href="\\2" target="_top">\\2</a>#{@brace_url.xml_close}\\3}) #http ftp matches with decoration
      else
        s.gsub(/</m,'&lt;').
          gsub(/>/m,'&gt;')
      end
      s
    end
    def markup_note(s)
      s=markup_generic(s)
      if s =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/
        wm=s.scan(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)|\S+/)
        words=urls(wm)
        s=s.gsub(/.+/m,words)
      end
      s=s.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;').
        gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'<a href="\1" target="_top">\1</a>\2'). #http ftp matches escaped, no decoration
        gsub(/(#{Mx[:lnk_c]})#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1<a href="\2" target="_top">\2</a>'). #special case \{ e.g. \}http://url
        gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,%{#{@brace_url.xml_open}<a href="\\1" target="_top">\\1</a>#{@brace_url.xml_close}}) #http ftp matches with decoration
    end
    def paragraph
      %{<p class="h#{@lv}" type="substantive" header="#{@hname}">#{@txt}</p>\n} # << "\n"
    end
    def endnote(nr,en) #used only by db
      txt=markup_note(en)
      <<GSUB
<p class="endnote" name="note_#{nr}" from="#{@t_o.ocn}">
<a href="#{@base_url}#-#{nr}" name="_#{nr}">#{nr}.</a> <note>#{txt}</note>
</p>
GSUB
    end
    def tag_header(h)
      %{<p class="#{h[:class]}" type="#{h[:type]}" header="#{h[:header]}">#{h[:txt]}</a></p>\n} # << "\n"
    end
    def tag_para(h)
      %{<p class="#{h[:class]}" type="#{h[:type]}">#{h[:txt]}</a></p>\n}  << "\n"
    end
    def lev_toc_hname
      %{<p class="toc#{@lv}" header="#{@hname}"><a href="##{@ocn_html_identifier}#{@ocn}">#{@txt}</a></p>\n}  #<< "\n"
    end
    def lev_toc
      h={ txt: txt, class: "toc#{@lv}", type: 'toc' }
      tag_para(h)
    end
    def lev4_plus
      txt=markup_object(@t_o)
      h={ txt: txt, class: "h#{@lv}", type: 'substantive', id: @ocn, header: @hname }
      tag_header(h)
    end
    def lev4_minus
      txt=markup_object(@t_o)
      h={ txt: txt, class: "h#{@t_o.ln}", type: 'substantive', id: @ocn }
      tag_para(h)
    end
    def norm_comment
      h={ txt: @t_o.obj, class: 'norm', type: 'comment' }
      tag_para(h)
    end
    def norm
      txt=markup_object(@t_o)
      h={ txt: txt, class: 'norm', type: 'substantive', id: @ocn }
      tag_para(h)
    end
    def code
      txt=markup_object(@t_o)
      h={ txt: "<tt>#{txt}</tt>", class: 'code', type: 'substantive', id: @ocn }
      tag_para(h)
    end
    def indent(t)
      txt=markup_object(@t_o)
      h={ txt: txt, class: "indent#{t}", type: 'substantive', id: @ocn }
      tag_para(h)
    end
    def hang_indent(f,t)
      txt=markup_object(@t_o)
      h={ txt: txt, class: "hang#{f}indent#{t}", type: 'substantive', id: @ocn }
      #h={ txt: txt, class: "h#{f}i#{t}", type: 'substantive', id: @ocn }
      tag_para(h)
    end
    def para_table
      %{<p class="norm" align="left"><font #{@vz.font_small} #{@vz.font_color} #{@vz.font_face}>}
    end
    def ocn
      %{<label class="ocn">#{@ocn}</label>} << "\n"
    end
    def html_table # get rid of use html_table
      @new_content=[]
      @txt.split(/\n/).each do |parablock|
        m=parablock[/<!f(.+?)!>/,1]
        @@tablefoot << m if m
        parablock=parablock.gsub(/<!f.+?!>/,'')
        @@tablehead=1 if parablock =~/#{Mx[:gr_o]}Th#{Mx[:tc_p]}/u
        parablock=parablock.gsub(/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}.+?#{Mx[:tc_p]}~(\d+)#{Mx[:gr_c]}/,
          %{<table summary="normal text css" width="100%" border="0" bgcolor="white" cellpadding="2" align="center">})
        if parablock =~/#{Mx[:gr_o]}TZ#{Mx[:gr_c]}/
          tablefoot=[]
          @@tablefoot.each {|x| tablefoot << %{<p align="center"><font size=2><i>#{x}</i></font></p>\n}}
          @@tablefoot=[]
          parablock=parablock.gsub(/#{Mx[:gr_o]}TZ#{Mx[:gr_c]}/,
            %{#{@vz.table_close}\n}) # +
        end
        if @@tablehead==1
          if parablock =~/#{Mx[:tc_p]}#{Mx[:tc_p]}/u
            parablock=parablock.gsub(/#{Mx[:tc_o]}#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u,
                %{\n<tr>} +
                %{\n<td width="\\1%" valign="top">} +
                %{#{para_table}<b>}).
              gsub(/#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u,
                %{</b></td><td width="\\1%" valign="top">} +
                %{#{para_table}<b>}).
              gsub(/#{Mx[:tc_c]}/, '</b></td></tr>')
            @@tablehead=0
          end
          parablock
        else
          parablock=parablock.gsub(/#{Mx[:tc_o]}#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u,
              %{\n<tr>} +
              %{\n<td width="\\1%" valign="top">} +
              %{#{para_table}}).
            gsub(/#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u,
              %{</td><td width="\\1%" valign="top">} +
              %{#{para_table}}).
            gsub(/#{Mx[:tc_c]}/, '</td></tr>')
          parablock
        end
        @new_content << parablock
      end
      @new_content.join
    end
  end
  class CSS_FormatGeneric #does CSS_Format in one definition, needs to be told about attrib, despite brevity of generic, easier to see structure with CSS_Format
    def initialize(attrib='',txt='',id=nil,ocnd=nil,ocns=nil,lv='',hname=nil)
      @tab="\t"
      @attrib=attrib
      @txt=txt
      @lv=lv.to_s
      @hname=hname.to_s
      @id=@ocn=id
    end
    def paragraph
      attrib=%{class="#{@attrib}" }
      if @ocn
        id=%{id="#{Mx[:ocn_id_char]}#{@ocn}" }
        type=%{type="substantive" }
      else
        id=''
        type=%{type="comment" }
      end
      header=%{header="#{@hname}" } if @hname
      %{<p #{attrib}#{type}#{header}>#{@txt}</p>\n} #<< "\n"
    end
    def para
      paragraph
    end
  end
end
__END__
