# encoding: utf-8
=begin

* Name: SiSU

** Description: documents, structuring, processing, publishing, search
*** system environment, resource control and configuration details

** 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 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>

** 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/develop/ao_misc_arrange.rb;hb=HEAD>

=end
module SiSU_AO_MiscArrangeText
  class SI
    def initialize(md,data)
      @md,@data=md,data
    end
    def conditional_headings(para)
      para=para.gsub(/^(:?A~)\s*$/,'\1~ @title @author').            #conditional header
        gsub(/^((?:[1-9]|:?[A-D])~\S*)\s*$/,
          '\1~ [Note: heading marker::required title missing]~#')    #conditional header for incorporated document 2004w12
      if para =~/^@\S+?:/
        para=para.gsub(/^@(\S+?):(\s+|$)/,
            "#{Mx[:meta_o]}\\1#{Mx[:meta_c]}\\2").
          gsub(/^@(\S+?):([+-])(\s+|$)/,
            "#{Mx[:meta_o]}\\1\\2#{Mx[:meta_c]}\\3")
      end
      para
    end
    def markup_blocks(para)
      def ticks(para)
        block_open,block_close,text=nil,nil,nil
        if para =~/\A```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table).*?\n.+?\n```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*\Z/m
          @flag=:close
          block_open,text,block_close=
            /\A(```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table).*?)\n(.+?)\n(```([ ]+[~-][#]|\s+\~\{.+?\}\~)?)\s*\Z/m.
            match(para)[1..3]
          ((para=~/^```[ ]+table(?:~h)?\s+/) \
          and (para !~/^```[ ]+table(?:~h)?\s+c\d+/)) \
          ? para
          : (para=[]; para << block_open << text << block_close)
        elsif para =~/\A```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table).*?\n.*?\Z/m #look at, study
          @flag=:open
          block_open,text=/\A(```(?:[ ]+.+?))\n(.*?)\Z/m.match(para)[1,2]
          para=[]
          if not text.to_s.empty?
            para << block_open << text
          else
            para << block_open
          end
        elsif para =~/\A.+?\n```(?:\s+\~\{.+?\}\~)?(?:\s+[~-][#])?(\s*=\{.+?\})?\s*\Z/m \
        and @flag==:open
          @flag=:close
          text,block_close=
            /\A(.+?)\n(```(?:\s+\~\{.+?\}\~)?(?:\s+[~-][#])?(?:\s+=\{.+?\})?)\s*\Z/m.match(para)[1,2]
          para=[]
          if not text.to_s.empty?
            para << text.to_s << block_close
          else
            para << block_close
          end
        else para
        end
        para
      end
      def ticks_remove(para)
        unless @md.opt.act[:quiet][:set] ==:on
          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).
           mark("ticks not recognized, ticks removed from pargraph\n#{para}")
        end
        para=para.gsub(/```[ ]+\S+[ ]*/m,'').
          gsub(/```\s*/m,'').
          strip
      end
      def ticks_quote(para)
        @flag=:quote_open
        text=para
        para=[]
        if text =~ /```[ ]+quote/m
          para << '`:quote_open`'
          text=text.gsub(/```[ ]+quote/m,'')
        end
        text=if text =~/(?:\n|\A)=\{.+?\}/m                               #exclude book index from indent markup
          txt,bkidx,tail=/(.+?)((?:\n|\A)=\{.+?\}$)(.*)/m.match(text).captures
          txt=txt.gsub(/(?:\n|\A)([^`\n]+)/m,'_1 \1')
          txt + bkidx + tail
        else text.gsub(/(?:\n|\A)([^`\n]+)/m,'_1 \1')
        end
        para << text.gsub(/```/m,'')
        if text =~/```/m
          @flag=:quote_close
          para << '`:quote_close`'
        end
        para
      end
      def curly_braces(para)
        block_open,block_close,text=nil,nil,nil
        para=if para =~/\A(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{ .+?\n.+?\n\}(?:code|box|poem|alt|group|block|table)(?: [~-][#])?\s*\Z/m
          block_open,text,block_close=
            /\A((?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{ .+?)\n(.+?)\n(\}(?:code|box|poem|alt|group|block|table)(?: [~-][#])?)\s*\Z/m.
            match(para)[1..3]
          para=[]
          para << block_open << text << block_close
        elsif para =~/\A(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{ .+?\n.+?\Z/m
          block_open,text=
            /\A((?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{ .+?)\n(.+?)\Z/m.
            match(para)[1,2]
          para=[]
          if not text.to_s.empty?
            para << block_open << text
          else
            para << block_open
          end
        elsif para =~/\A.+?\n\}(?:code|box|poem|alt|group|block|table)(?: [~-][#])?\s*\Z/m
          text,block_close=
            /\A(.+?)\n(\}(?:code|box|poem|alt|group|block|table)(?: [~-][#])?)\s*\Z/m.
            match(para)[1,2]
          para=[]
          if not text.to_s.empty?
            para << text.to_s << block_close
          else
            para << block_close
          end
        else para
        end
        para
      end
      para=if (para =~/\A```[ ]+quote/m \
      and @flag !=:open) \
      or @flag==:quote_open
        ticks_quote(para)
      elsif para =~/\A```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table).*?\n.*?\Z/m \
      or @flag==:open
        ticks(para)
      elsif para =~/```/m
        ticks_remove(para)
      else
        para
      end
      para=if para =~/^(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{|^\}(?:code|box|poem|alt|group|block|table)/m
        curly_braces(para)
      else
        para
      end
    end
    def prepare_text
      data=@data
      if data[0] =~ /^#!\s*(?:\/usr\/bin\/env sisu|\/usr\/bin\/sisu)/ # remove bang from top #! (however file is stripped, so will be removed provided no content precedes it)
        data[0]=data[0].gsub(/^#!\s*\/usr\/bin\/sisu/,'').
          gsub(/^#!\s*\/usr\/bin\/env sisu/,'')
      end
      if data[0] =~ /^(SiSU\s+[\d.]*|sisu-[\d.]+)$/ # SiSU identifier
        data[0]=data[0].gsub(/^(SiSU\s*[\d.]*)$/,'% \1').
          gsub(/^(sisu-[\d.]+)$/,'% \1')
      end
      data.each.map do |para|
        para=conditional_headings(para)
        markup_blocks(para)
      end.flatten
    end
  end
end
__END__
