# encoding: utf-8
=begin

 * Name: SiSU

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

 * Author: Ralph Amissah

 * Copyright: (C) 1997 - 2012, Ralph Amissah, All Rights Reserved.

 * License: GPL 3 or later:

   SiSU, a framework for document structuring, publishing and search

   Copyright (C) Ralph Amissah

   This program is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the Free
   Software Foundation, either version 3 of the License, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
   more details.

   You should have received a copy of the GNU General Public License along with
   this program. If not, see <http://www.gnu.org/licenses/>.

   If you have Internet connection, the latest version of the GPL should be
   available at these locations:
   <http://www.fsf.org/licensing/licenses/gpl.html>
   <http://www.gnu.org/licenses/gpl.html>

   <http://www.jus.uio.no/sisu/gpl.fsf/toc.html>
   <http://www.jus.uio.no/sisu/gpl.fsf/doc.html>
   <http://www.jus.uio.no/sisu/gpl.fsf/plain.txt>

 * SiSU uses:
   * Standard SiSU markup syntax,
   * Standard SiSU meta-markup syntax, and the
   * Standard SiSU object citation numbering and system

 * Hompages:
   <http://www.jus.uio.no/sisu>
   <http://www.sisudoc.org>

 * Download:
   <http://www.jus.uio.no/sisu/SiSU/download.html>

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

 ** Description: A conversion script for canned substitutions, a fairly generic
    simple tool that can be used to store other canned conversions, used here for
    altering SiSU markup

=end
module SiSU_Modify
  require_relative 'sst_identify_markup'                # sst_identify_markup.rb
  require_relative 'sst_from_xml'                       # sst_from_xml.rb
  require_relative 'response'                           # response.rb
  class ConvertMarkup
    def initialize(opt)
      @opt=opt
      @description='This is a script that contains canned text conversions for reuse'
      @response=SiSU_Response::Response.new
      @ask=SiSU_Response::Response.new
      @warn='WARNING, PROCEED AT YOUR OWN RISK, will make file changes.'
    end
    def current_match_and_replace
      convert_37_to_38
    end
    def message(text)
      response=''
      unless @opt.cmd=~/QQ/ \
      or @opt.cmd=~/q/
        response=@ask.response?(%{#{  text}\nProceed? })
      end
    end
    def help
    print <<WOK

#{@description}

sisu --convert --to38 [filename/wildcard]
  converts pre 0.37 sisu markup to 0.38 experimental
  [--37to38]

sisu --convert --to37 [filename/wildcard]
  converts pre 0.37 sisu markup to 0.38 experimental
  [--38to37]

sisu --convert --36to37 [filename/wildcard]
  converts pre 0.36 file-name, to 0.37 file-name
  [--36to37]

sisu --identify [filename]
  attempts to identify markup version used in file

sisu --query [version number]
  gives short summary of distinguishing characteristic
  of that version of markup

WOK
      exit
    end
    #%% substitutions to be made
    def convert_37_to_38
      message("#{@warn}\nConvert sisu markup from 0.37 to 0.38")
      [
        [/^0~(\S+?)([+-])\s+/,    '@\1:\2 ',               //],
        [/^0~(\S+)\s+/,           '@\1: ',                 //],
        [/^@toc:\s+/,             '@structure: ',          //],
        [/^1~/,                   ':A~',                   //],
        [/^2~/,                   ':B~',                   //],
        [/^3~/,                   ':C~',                   //],
        [/^4~/,                   '1~',                    //],
        [/^5~/,                   '2~',                    //],
        [/^6~/,                   '3~',                    //],
        [/^7~/,                   '4~',                    //],
        [/^8~/,                   '5~',                    //],
        [/^9~/,                   '6~',                    //],
        [/1/,                     ':A',                    /^@(?:level|markup):\s/],
        [/2/,                     ':B',                    /^@(?:level|markup):\s/],
        [/3/,                     ':C',                    /^@(?:level|markup):\s/],
        [/4/,                     '1',                     /^@(?:level|markup):\s/],
        [/5/,                     '2',                     /^@(?:level|markup):\s/],
        [/6/,                     '3',                     /^@(?:level|markup):\s/]
      ]
    end
    def convert_38_to_37
      message("#{@warn}\nConvert sisu markup from 0.38 to 0.37")
      [
        [/^@(\S+?):([+-])\s+/,    '0~\1\2 ',               //],
        [/^@(\S+?):\s+/,          '0~\1 ',                 //],
        [/^0~structure\s+/,       '0~toc ',                //],
        [/^1~/,                   '4~',                    //],
        [/^2~/,                   '5~',                    //],
        [/^3~/,                   '6~',                    //],
        [/^4~/,                   '7~',                    //],
        [/^5~/,                   '8~',                    //],
        [/^6~/,                   '9~',                    //],
        [/^:?A~/,                 '1~',                    //],
        [/^:?B~/,                 '2~',                    //],
        [/^:?C~/,                 '3~',                    //],
        [/1/,                     '4',                     /^0~(?:level|markup)\s/],
        [/2/,                     '5',                     /^0~(?:level|markup)\s/],
        [/3/,                     '6',                     /^0~(?:level|markup)\s/],
        [/:?A/,                   '1',                     /^0~(?:level|markup)\s/],
        [/:?B/,                   '2',                     /^0~(?:level|markup)\s/],
        [/:?C/,                   '3',                     /^0~(?:level|markup)\s/]
      ]
    end
    def convert_filename_36_to_37
      @opt.files.each do |f|
        s=case f
        when /(\.s[1-3])$/; f.sub($1,'.sst')
        when /(\.r[1-3])$/; f.sub($1,'.ssm')
        when /(\.ri)$/; f.sub($1,'.ssi')
        else f
        end
        pwd=Dir.pwd
        unless f==s
          unless File.exist?("#{pwd}/#{s}")
            puts "./#{f} -> ./#{s}"
            FileUtils::cp("#{pwd}/#{f}","#{pwd}/#{s}")
          else "File already exists, < #{s} >  will not overwrite"
          end
        end
      end
    end
    def convert_to_simple_xml_model_sax
      SiSU_SimpleXML_ModelSax::Convert.new(@opt).read
    end
    def convert_to_simple_xml_model_dom
      SiSU_simple_xml_model_dom::Convert.new(@opt).read
    end
    def convert_to_simple_xml_model_node
      SiSU_simple_xml_model_node::Convert.new(@opt).read
    end
    def convert_kdi_to_sst
      SiSU_Kdissert::Convert.new(@opt).read
    end
    def convert_s_xml_to_sst
      SiSU_sstFromXML::Convert.new(@opt).read
    end
    def convert_footnotes
      require_relative 'sst_do_inline_footnotes'
      SiSU_ConvertFootnotes::Source.new(@opt).read
    end
    def conversion
      #%% do it                                   -------------------------->
      if @opt.files \
      and @opt.files.length > 0
        mr=nil
        #%% changes to make m match, r replace      -------------------------->
        if @opt.mod.inspect =~/--help/; help
        elsif @opt.mod.inspect =~/(?:convert|to)[=-](?:xml |sxs|sax|sxd|dom|sxn|node)/
          ext=case @opt.mod.inspect
          when /(?:convert|to)[=-](?:xml|sxs|sax)/; '.sxs.xml'
          when /(?:convert|to)[=-](?:sxd|dom)/;     '.sxd.xml'
          when /(?:convert|to)[=-](?:sxn|node)/;    '.sxn.xml'
          end
          message("#{@opt.files.inspect}\n\nWARNING, PROCEED AT YOUR OWN RISK,\noverwriting any equivalent file with the extension #{ext}")
          mr=case @opt.mod.inspect
          when /(?:convert|to)[=-](?:sxs|sax|xml )/; convert_to_simple_xml_model_sax
          when /(?:convert|to)[=-](?:sxd|dom)/;      convert_to_simple_xml_model_dom
          when /(?:convert|to)[=-](?:sxn|node)/;     convert_to_simple_xml_model_node
          else help
          end
        else
          mr=case @opt.mod.inspect
          when /(?:(?:37)?to-?38|--(?:convert|to)[=-](?:current|0.38))/;           convert_37_to_38
          when /(?:(?:38)?to-?37|--(?:convert|to)[=-](?:0.37))/;                   convert_38_to_37
          when /(?:36to37)/;                                                       convert_filename_36_to_37
          when /(?:convert|from)[=-]kdi/;                                          convert_kdi_to_sst
          when /(?:(?:convert|from)[=-])?(?:xml_to_sst|xml2sst|sxml|sxs|sxd|sxd)/; convert_s_xml_to_sst
          when /(?:convert|to)[=-]footnotes/;                                      convert_footnotes
          when /convert|default/;                                                  current_match_and_replace
          else help
          end
        end
        unless @opt.mod.inspect =~/kdi/
          match_and_replace=mr
          #start_processing =/not used in this example/i
          end_processing =/END\s+OF\s+FILE/
          i=@opt.fns
          if i =~/(?:\.sst|\.ssm|\.ssi)$/
            @new,@matched,@flag_start,@flag_end,@empty1,@empty2=true,false,false,false,false,false
            o="#{i}.bk" #o is for old
            markup_version=SiSU_Markup::MarkupIdentify.new(@opt).markup_version?
            if (@opt.mod.inspect=~/37/ and markup_version=~/0.38/) \
            or (@opt.mod.inspect=~/current|38/ and markup_version=~/0.37/)
              puts "#{i} #{markup_version}"
              file=File.open(i,'r')
              cont=file.readlines
              file.close
              cont.each do |y|
                match_and_replace.each do |m,r,w|
                  if y =~m \
                  and y =~w
                    if @new
                      @new=false
                      File.unlink(o) if File.exist?(o)
                      File.rename(i,o)
                      File.unlink(i) if File.exist?(i)
                      @file=File.new(i,'w')
                      @matched=true
                      break
                    end
                  end
                end
              end
              if @matched
                puts "conversion match in #{i}" unless @opt.cmd=~/q/
                @flag_start=true
                cont.each do |y|
                  if y =~end_processing
                    @flag_end=true
                  end
                  if @flag_start \
                  and not @flag_end
                    match_and_replace.each do |m,r,w|
                      if y =~m \
                      and y =~w
                        puts m.inspect + ' -> ' + r unless @opt.cmd=~/q/
                        puts "in:  #{y}" if @opt.cmd=~/[vVM]/
                        y.gsub!(m,r) if m and r
                        puts "out: #{y}" if @opt.cmd=~/[vVM]/
                      end
                    end
                  end
                  if y=~/^\s*$/; @empty1=true
                  else           @empty1=false
                  end
                  @file.puts y unless (@empty1==true and @empty2==true)
                  if y=~/^\s*$/; @empty2=true
                  else           @empty2=false
                  end
                end
                @file.close
              else puts "NO conversion match in #{i}" unless @opt.cmd=~/q/
              end
            else puts "Requested conversion #{@opt.mod.inspect} markup #{markup_version} identified in #{i}" if @opt.cmd=~/[vVM]/
            end
          end
        end
      else puts 'this routine makes permanent changes to the contents of the files matched, as instructed within [no matches]'
      end
    end
  end
end
#%% files to match for this conversion set  ------------------------->
require_relative 'options'                              # options.rb
argv=$*
@opt=SiSU_Commandline::Options.new(argv)
case @opt.mod.inspect
when /=kdi/
  SiSU_Modify::ConvertMarkup.new(@opt).conversion
when /(?:36|37|38)?to-?(?:37|38)|--convert|--to|--from|default/
@opt.files.each do |fns|
  @opt.fns=fns
  SiSU_Modify::ConvertMarkup.new(@opt).conversion
end
else
  @opt.mod='--help'
 SiSU_Modify::ConvertMarkup.new(@opt).help
end
__END__
