# 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 .
If you have Internet connection, the latest version of the GPL should be
available at these locations:
* SiSU uses:
* Standard SiSU markup syntax,
* Standard SiSU meta-markup syntax, and the
* Standard SiSU object citation numbering and system
* Hompages:
* Download:
* Git
* Ralph Amissah
** Description: LaTeX generation
=end
module SiSU_TeX
begin
require 'pstore'
rescue LoadError
SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).error('pstore NOT FOUND (LoadError)')
end
require_relative 'defaults' # defaults.rb
include SiSU_Viz
require_relative 'se_hub_particulars' # se_hub_particulars.rb
include SiSU_Particulars
require_relative 'texpdf_format' # texpdf_format.rb
include SiSU_TeX_Pdf
require_relative 'shared_metadata' # shared_metadata.rb
require_relative 'prog_text_translation' # prog_text_translation.rb
@tex_file=@@tex_footnote_array=@@tex_col_w=[]
@@tabular="{tabular}"
@@column_instruct=@@squigle_close=@@tex_line_mode=@@tex_word_mode=@@line_mode=''
@@tex_debug_counter=@@table_pagebreak_counter=@@tex_footnote_call_counter=@@tex_table_flag=@@tex_counter=@@tex_column=@@tex_columns=@@tex_columns=@@counting=0
@@tex_pattern_margin_number=/\\\\begin\\\{tiny\\\}\\\\hspace\\\{0mm\\\}\\\\end\\\{tiny\\\}\\\{\\\\marginpar.+?\s+/
@@n=@@tableheader=@@rights=nil
@@date ||=SiSU_Env::InfoDate.new
class Source
begin
require 'pstore'
rescue LoadError
SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).error('pstore NOT FOUND (LoadError)')
end
require_relative 'se' # se.rb
include SiSU_Env
include SiSU_Viz
require_relative 'ao' # ao.rb
include SiSU_AO
include SiSU_TeX
def initialize(opt)
@opt=opt
@particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt)
@md=@particulars.md
@env=SiSU_Env::InfoEnv.new(@md.fns) #@env=@particulars.env
end
def directories
begin
case @opt.fns
when /\.(?:-|ssm\.)?sst$/
SiSU_Env::FileOp.new(@md).mkdir
Dir.mkdir(@env.processing_path.tex) unless FileTest.directory?(@env.processing_path.tex)
end
rescue
SiSU_Errors::Rescued.new($!,$@,@opt.cmd,@opt.fns).location do
__LINE__.to_s + ':' + __FILE__
end
ensure
end
end
def read
begin
song
ensure
Dir.chdir(@opt.f_pth[:pth])
end
end
def song
begin
@md=@particulars.md
SiSU_Screen::Ansi.new(
@opt.act[:color_state][:set],
'LaTeX/PDF',
"[#{@opt.f_pth[:lng_is]}] #{@opt.fno}"
).green_title_hi unless @opt.act[:quiet][:set]==:on
if (@opt.act[:verbose][:set]==:on \
|| @opt.act[:verbose_plus][:set]==:on \
|| @opt.act[:maintenance][:set]==:on)
@env.url.output_tell
if @md.opt.act[:pdf_l][:set]==:on
SiSU_Screen::Ansi.new(
@opt.act[:color_state][:set],
@opt.fns,
"#{@env.program.pdf_viewer} #{@md.file.output_path.pdf.dir}/#{@md.file.base_filename.pdf_l}#{@md.papersize_array[0]}.pdf"
).flow
end
if @md.opt.act[:pdf_p][:set]==:on
SiSU_Screen::Ansi.new(
@opt.act[:color_state][:set],
@opt.fns,
"#{@opt.fns} #{@env.program.pdf_viewer} #{@md.file.output_path.pdf.dir}/#{@md.file.base_filename.pdf_p}#{@md.papersize_array[0]}.pdf"
).flow
end
end
@md=@particulars.md
$flag=@md.opt.cmd #introduced to pass 0 for no object citation numbers... to texpdf_format
directories
#% needed needs to be reprogrammed !!!
ao_array=SiSU_AO::Source.new(@opt).get # ao file drawn here
SiSU_TeX::Source::LaTeXcreate.new(@particulars).songsheet
ao_array=''
pwd=Dir.pwd
SiSU_TeX::Source::LaTeXtoPdf.new(@md,@particulars.env).latexrun_selective
Dir.chdir(pwd)
rescue
SiSU_Errors::Rescued.new($!,$@,@opt.cmd,@opt.fns).location do
__LINE__.to_s + ':' + __FILE__
end
ensure
unless (@opt.act[:verbose_plus][:set]==:on \
|| @opt.act[:maintenance][:set]==:on)
texfiles=Dir["#{@env.processing_path.tex}/#{@opt.fns}*"]
texfiles.each do |f|
if FileTest.file?(f)
File.unlink(f)
end
end
end
@tex_file=@@tex_footnote_array=[]
@@column_instruct=''
@@squigle_close=@@tex_line_mode=@@tex_word_mode=@@line_mode=''
@@tex_debug_counter=@@table_pagebreak_counter=@@tex_footnote_call_counter=@@tex_table_flag=@@tex_counter=@@tex_column=@@tex_columns=@@tex_columns=@@counting=0
@@tex_col_w=[]
@@n=@@tableheader=@@rights=nil
@@date=SiSU_Env::InfoDate.new
@@flag={}
$flag=1 #remove at some stage
SiSU_Env::Clear.new(@opt.cmd,@opt.fns).param_instantiate
end
end
private
class LaTeXtoPdf
@@n_lpdf||=0 #change
def initialize(md,env)
@md,@env=md,env
@f=SiSU_Env::FileOp.new(@md).base_filename
end
def latex_do(texfilename,papersize)
@texfilename=texfilename
@@n_lpdf=@@n_lpdf+1
tex_fn_base=@texfilename.gsub(/\.tex$/,'')
tell=SiSU_Screen::Ansi.new(@md.opt.cmd)
if @md.opt.act[:pdf_p][:set]==:on
if (@md.opt.act[:verbose][:set]==:on \
|| @md.opt.act[:verbose_plus][:set]==:on \
|| @md.opt.act[:maintenance][:set]==:on)
SiSU_Screen::Ansi.new(
@md.opt.act[:color_state][:set],
"#{papersize} portrait ->"
).dark_grey_title_hi
end
cmd=SiSU_Env::SystemCall.new("#{tex_fn_base}.tex",'',@md.opt.cmd)
tell.grey_open if @md.opt.cmd =~/[MVv]/
if "#{tex_fn_base}" =~/\w+/ \
and "#{papersize}" =~/\w+/
2.times { |i| cmd.latex2pdf(@md,papersize) } #comment out to skip processing of latex portrait
end
tell.p_off if @md.opt.cmd =~/[MVv]/
end
if @md.opt.act[:pdf_l][:set]==:on
if (@md.opt.act[:verbose][:set]==:on \
|| @md.opt.act[:verbose_plus][:set]==:on \
|| @md.opt.act[:maintenance][:set]==:on)
SiSU_Screen::Ansi.new(
@md.opt.act[:color_state][:set],
"#{papersize} landscape ->"
).dark_grey_title_hi
end
cmd=SiSU_Env::SystemCall.new("#{tex_fn_base}.landscape.tex",'',@md.opt.cmd)
if (@md.opt.act[:verbose][:set]==:on \
|| @md.opt.act[:verbose_plus][:set]==:on \
|| @md.opt.act[:maintenance][:set]==:on)
tell.grey_open
end
if "#{tex_fn_base}" =~/\w+/ \
and "#{papersize}" =~/\w+/
2.times { |i| cmd.latex2pdf(@md,papersize) } #comment out to skip processing of latex landscape
end
if (@md.opt.act[:verbose][:set]==:on \
|| @md.opt.act[:verbose_plus][:set]==:on \
|| @md.opt.act[:maintenance][:set]==:on)
tell.p_off
end
end
pwd=Dir.pwd
if @md.opt.act[:pdf_p][:set]==:on
portrait_pdf="#{pwd}/#{tex_fn_base}.pdf"
end
if @md.opt.act[:pdf_l][:set]==:on
landscape_pdf="#{pwd}/#{tex_fn_base}.landscape.pdf"
end
case papersize
when /a4/ then pdf_p=@f.pdf_p_a4; pdf_l=@f.pdf_l_a4
when /a5/ then pdf_p=@f.pdf_p_a5; pdf_l=@f.pdf_l_a5
when /b5/ then pdf_p=@f.pdf_p_b5; pdf_l=@f.pdf_l_b5
when /letter/ then pdf_p=@f.pdf_p_letter; pdf_l=@f.pdf_l_letter
when /legal/ then pdf_p=@f.pdf_p_legal; pdf_l=@f.pdf_l_legal
else pdf_p=@f.pdf_p_a4; pdf_l=@f.pdf_l_a4
end
FileUtils::mkdir_p(@md.file.output_path.pdf.dir) unless FileTest.directory?(@md.file.output_path.pdf.dir)
cX=SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set]).cX
if @md.opt.act[:pdf_p][:set]==:on
if FileTest.file?(portrait_pdf)
FileUtils::cp(portrait_pdf,"#{@md.file.output_path.pdf.dir}/#{pdf_p}")
FileUtils::rm(portrait_pdf)
else
STDERR.puts "#{cX.fuchsia}pdf file not generated#{cX.off} <#{cX.blue}#{portrait_pdf.gsub(/.+?([^\/]+?\.pdf)$/,'\1')}#{cX.off}> (check texlive dependencies)"
STDERR.puts "#{__FILE__}:#{__LINE__} NOT FOUND: #{portrait_pdf}" if @md.opt.act[:maintenance][:set]==:on
end
end
if @md.opt.act[:pdf_l][:set]==:on
if FileTest.file?(landscape_pdf)
FileUtils::cp(landscape_pdf,"#{@md.file.output_path.pdf.dir}/#{pdf_l}")
FileUtils::rm(landscape_pdf)
else
STDERR.puts "#{cX.fuchsia}pdf file not generated#{cX.off} <#{cX.blue}#{landscape_pdf.gsub(/.+?([^\/]+?\.pdf)$/,'\1')}#{cX.off}> (check texlive dependencies)"
STDERR.puts "#{__FILE__}:#{__LINE__} NOT FOUND: #{landscape_pdf}" if @md.opt.act[:maintenance][:set]==:on
end
end
if (@md.opt.act[:verbose][:set]==:on \
|| @md.opt.act[:verbose_plus][:set]==:on \
|| @md.opt.act[:maintenance][:set]==:on)
SiSU_Screen::Ansi.new(
@md.opt.act[:color_state][:set],
@@n_lpdf,
'processed (SiSU LaTeX to pdf - using pdfetex aka. pdftex or pdflatex)'
).generic_number
end
end
def latexrun_selective
begin
pwd=Dir.pwd
Dir.chdir(pwd) #watch
@tex_f_no=0
if FileTest.file?(@env.source_file_with_path)
@md.papersize_array.each do |ps|
if @md.fns =~/\.(?:-|ssm\.)?sst$/
case @md.fns
when /\.(?:-|ssm\.)?sst$/
if FileTest.directory?(@env.processing_path.tex)==true
Dir.chdir(@env.processing_path.tex)
texfile=@md.fns.gsub(/$/,".#{ps}.tex").
gsub(/~/,'-')
if @md.opt.act[:pdf_p][:set]==:on \
or @md.opt.act[:pdf_l][:set]==:on
latex_do(texfile,ps)
if @md.opt.act[:pdf_p][:set]==:on
if File.exist?(texfile) \
and File.size(texfile) > 0
#@tex_f_no+=1
else
SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).error("\tzero file size #{@env.processing_path.tex}/#{texfile}")
end
end
end
end
end
end
end
case @md.papersize_array[0] #default pdf
when /a4/ then pdf_p=@f.pdf_p_a4; pdf_l=@f.pdf_l_a4
when /a5/ then pdf_p=@f.pdf_p_a5; pdf_l=@f.pdf_l_a5
when /b5/ then pdf_p=@f.pdf_p_b5; pdf_l=@f.pdf_l_b5
when /letter/ then pdf_p=@f.pdf_p_letter; pdf_l=@f.pdf_l_letter
when /legal/ then pdf_p=@f.pdf_p_legal; pdf_l=@f.pdf_l_legal
else pdf_p=@f.pdf_p_a4; pdf_l=@f.pdf_l_a4
end
if @md.opt.act[:pdf_p][:set]==:on
if FileTest.file?("#{@md.file.output_path.pdf.dir}/#{pdf_p}")
mklnk=((@md.file.output_dir_structure.by_language_code?) \
|| (@md.file.output_dir_structure.by_filetype?)) \
? "#{@md.fnb}.portrait.pdf"
: 'portrait.pdf'
if FileTest.directory?(@md.file.output_path.pdf.dir)
pwd=Dir.pwd
Dir.chdir(@md.file.output_path.pdf.dir)
FileUtils::rm_f(mklnk)
FileUtils::ln_s(pdf_p, mklnk)
Dir.chdir(pwd)
end
end
end
if @md.opt.act[:pdf_l][:set]==:on
if FileTest.file?("#{@md.file.output_path.pdf.dir}/#{pdf_l}")
mklnk=((@md.file.output_dir_structure.by_language_code?) \
|| (@md.file.output_dir_structure.by_filetype?)) \
? "#{@md.fnb}.landscape.pdf"
: 'landscape.pdf'
pwd_set=Dir.pwd
Dir.chdir(@md.file.output_path.pdf.dir)
FileUtils::rm_f(mklnk)
FileUtils::ln_s(pdf_l, mklnk)
Dir.chdir(pwd_set)
end
end
else
SiSU_Screen::Ansi.new(
@md.opt.act[:color_state][:set],
"*WARN* FILE NOT FOUND: << #{@md.fns} >> - requested latex system processing skipped"
).warn
end
lst=Dir["*.{aux,log,out}"]
lst.each {|file| File.unlink(file)} if lst
rescue
SiSU_Errors::Rescued.new($!,$@,@md.opt.cmd,@md.fns).location do
__LINE__.to_s + ':' + __FILE__
end
end
end
end
class LaTeXcreate
@@tex_head={
'a4'=> { p: nil, l: nil },
'a5'=> { p: nil, l: nil },
'b5'=> { p: nil, l: nil },
'letter'=>{ p: nil, l: nil },
'legal'=> { p: nil, l: nil },
'book'=> { p: nil, l: nil }
}
@@prefix_b=nil
def initialize(particulars)
@particulars=particulars
@md=@particulars.md
@env=SiSU_Env::InfoEnv.new(@md.fns) #@env=@particulars.env
@data=@particulars.ao_array # ao file drawn here
@st={ tex: {} }
@tex_ml=SiSU_TeX_Pdf::UseTeX.new(@md)
@vz=SiSU_Viz::Defaults.new
@dp=@@dp ||=SiSU_Env::InfoEnv.new.digest.pattern
@brace_url=SiSU_Viz::Defaults.new.url_decoration
l=SiSU_Env::StandardiseLanguage.new(@md.opt.lng).language
@language=l[:n]
@translate=SiSU_Translate::Source.new(@md,@language)
@codeblock_box='listings' #alternative 'boites'
@make ||=SiSU_Env::ProcessingSettings.new(@md)
end
def songsheet
begin
data=@data
@@tex_footnote_array=[]
@@rights=nil
txt_gen=if @md.opt.act[:pdf_l][:set]==:on \
and @md.opt.act[:pdf_p][:set]==:on
'pdfTex portrait & landscape'
elsif @md.opt.act[:pdf_l][:set]==:on
'pdfTex landscape'
elsif @md.opt.act[:pdf_p][:set]==:on
'pdfTex portrait'
else
SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).error('error: neither landscape nor portrait')
end
if (@md.opt.act[:verbose][:set]==:on \
|| @md.opt.act[:verbose_plus][:set]==:on \
|| @md.opt.act[:maintenance][:set]==:on)
SiSU_Screen::Ansi.new(
@md.opt.act[:color_state][:set],
txt_gen
).txt_grey
end
if defined? @md.rights.all \
and not @md.rights.all.empty?
rght=@md.rights #.author.dup #dup is necessary, else contents of :rights changed
sp_char=SiSU_TeX_Pdf::SpecialCharacters.new(@md,rght.copyright.all)
copymark=@md.author_copymark \
? '{\begin{small}\copyright\end{small}} '
: ''
copymark='Copyright {\begin{small}\copyright\end{small}} '
copyright=sp_char.special_characters_safe.gsub(/^\s*Copyright \(C\)/, copymark)
@@rights||="\n #{Tex[:backslash]*2}[3]\\ \\linebreak #{copyright}"
end
if defined? @md.notes.prefix_b \
and not @md.notes.prefix_b.empty?
sp_char=SiSU_TeX_Pdf::SpecialCharacters.new(@md,@md.notes.prefix_b)
prefix_b=sp_char.special_characters_safe
@@prefix_b="\n #{Tex[:backslash]*2}[3]\\ \\linebreak \\ #{prefix_b}\n" unless @@prefix_b
end
data=pre(data)
data=footnote(data)
if @md.flag_tables #WORK ON 2009
data=tables(data) #uncomment to start experimenting with tables
end
data=number_paras(data)
data=markup(data)
output(data)
rescue
SiSU_Errors::Rescued.new($!,$@,@md.opt.cmd,@md.fns).location do
__LINE__.to_s + ':' + __FILE__
end
ensure
end
end
protected
def pre(data)
@tex_file=[]
data.each do |dob|
# DEBUG 2003w16 this is a kludge, because i could not get parameters
# from param, Sort out ... revert to more elegant solution
# even more of a kludge as had to insert newlines where code is used not satisfactory, think about
dob.tmp=dob.obj #.dup
if dob.is==:para \
|| dob.is==:heading
dob.tmp=dob.tmp.gsub(/#{Mx[:mk_o]}:name#\S+?#{Mx[:mk_c]}/,'')
dob.tmp=SiSU_TeX_Pdf::SpecialCharacters.new(@md,dob.tmp).special_characters
if dob.tmp =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/
dob.tmp=SiSU_TeX_Pdf::FormatTextObject.new(@md,dob.tmp).url_str_internal(dob.tmp)
end
elsif dob.is ==:code
dob.tmp=if @codeblock_box=='listings'
dob.tmp
else
SiSU_TeX_Pdf::SpecialCharacters.new(@md,dob.tmp).special_characters_code
end
elsif dob.is ==:break
if dob.obj==Mx[:br_page]; dob.tmp='\newpage'
elsif dob.obj==Mx[:br_page_new]; dob.tmp='\clearpage'
elsif dob.obj==Mx[:br_page_line]; dob.tmp=' \\ \hline \\ '
elsif dob.obj==Mx[:br_obj]; dob.tmp='\parasep'
end
elsif dob.is==:comment \
|| dob.is==:meta
dob.tmp='' #dob.tmp=nil
end
end
data
end
def footnote(data)
data.each do |dob|
# EMBEDDED FOOTNOTES / ENDNOTES should be straightforward but not quite a synch.
if dob.tmp =~/#{Mx[:en_a_o]}[\d*+]+\s|#{Mx[:en_b_o]}([*+]\d+)\s/
dob.tmp=dob.tmp.gsub(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/m,"\\footnote[\\1]{%\n \\2} ").
gsub(/#{Mx[:en_b_o]}([*+]\d+)\s+(.+?)#{Mx[:en_b_c]}/m,"\\FootnoteA{\\1}{%\n \\2} ").
gsub(/#{Mx[:en_a_o]}([*+]+)\s+(.+?)#{Mx[:en_a_c]}/m,"\\FootnoteA{\\1}{%\n \\2} ")
end
end
data
end
def tables_hash(md,dob)
@block={}
@dob=dob
@md.papersize_array.each do |ps|
@@tableheader={ ps => { p: 0, l: 0 } }
dob.tmp={ tmp: dob.tmp, paper_size: ps }
format_l=SiSU_TeX_Pdf::FormatTextObject.new(md,dob)
dob.tmp={ tmp: dob.tmp, paper_size: ps }
format_p=SiSU_TeX_Pdf::FormatTextObject.new(md,dob)
@block[ps]={
l: format_l.longtable_landscape,
p: format_p.longtable_portrait
}
end
@dob.tmp=@block
@dob
end
def tables(data)
@tex_file=[]
data.each do |dob|
@tex_file << if dob.is_a?(String) \
or dob.is_a?(Hash)
dob
elsif dob.is==:table
tables_hash(@md,dob) #Hash result
else dob
end
end
@tex_file
end
def enclose(dob)
dob
end
def box_boites(dob,ocn)
sp_char=SiSU_TeX_Pdf::SpecialCharacters.new(@md,dob.tmp,dob.is)
dob.tmp=sp_char.special_characters_safe
dob.tmp=dob.tmp.gsub(/(#{Mx[:nbsp]})/m,'{\color{mywhite}\1}').
#dob.tmp.gsub(/#{Mx[:nbsp]}/m,'{~}') # dob.tmp.gsub(/#{Mx[:nbsp]}\s*/m,'{~}')
gsub(/#{Mx[:vline]}/m,'\vline').
gsub(/ \\( |#{Mx[:br_nl]})/,' {\textbackslash}\1').
gsub(/#{Mx[:br_nl]}\s*\Z/m,'').
gsub(/#{Mx[:br_nl]}{2}/,'\newline \\\\\\ ').
gsub(/#{Mx[:br_nl]}/,' \\\\\\ ').
gsub(/\n\n\n/m," \\newline\n\n")
ocn=SiSU_TeX_Pdf::FormatTextObject.new(@md).ocn_display(dob)
dob.tmp = ocn \
+ @tex_ml.paraskip_small \
+ '\begin{Codeblock}' \
+ '\begin{codeblockboitebox} \hardspace \newline ' \
+ dob.tmp \
+ '\end{codeblockboitebox}' \
+ '\end{Codeblock}' \
+ "\n" \
+ @tex_ml.paraskip_normal
dob
end
def box_listings(dob,ocn)
sp_char=SiSU_TeX_Pdf::SpecialCharacters.new(@md,dob.tmp,dob.is)
dob.tmp=sp_char.characters_code_listings
dob.tmp=dob.tmp.gsub(/^\s+/m,''). #bug, fix earlier, should be made unecessary
gsub(/#{Mx[:nbsp]}/m,' ').
gsub(/#{Mx[:vline]}/m,'|').
gsub(/#{Mx[:br_nl]}(?:\s?\n)?/m,"\n").
gsub(/\n\n\n/m," \n\n")
ocn=SiSU_TeX_Pdf::FormatTextObject.new(@md).ocn_display(dob)
dob.tmp = ocn \
+ @tex_ml.paraskip_small \
+ '\begin{Codeblock}' \
+ "\n" \
+ '\begin{lstlisting} ' \
+ "\n" \
+ dob.tmp \
+ "\n" \
+ '\end{lstlisting} ' \
+ "\n" \
+ '\end{Codeblock}' \
+ "\n" \
+ @tex_ml.paraskip_normal
dob
end
def markup_common(dob)
if dob.of==:block
@lineone=if dob.is==:block \
|| dob.is==:group \
|| dob.is==:alt \
|| dob.is==:verse
dob.tmp=dob.tmp.gsub(/#{Mx[:nbsp]}/m,' \hardspace ').
gsub(/#{Mx[:gl_bullet]}/m,'\txtbullet \hardspace '). #Bullet environment not used for grouped text, no hanging indent here
gsub(/#{Mx[:br_nl]}+/m,"\n\n") #match not ideal, but currently not inserting extra newlines anyway
ocn=SiSU_TeX_Pdf::FormatTextObject.new(@md).ocn_display(dob)
dob.tmp=if dob.is==:group \
|| dob.is==:block \
|| dob.is==:alt
dob.tmp=SiSU_TeX_Pdf::SpecialCharacters.new(@md,dob.tmp).special_characters_safe
ocn \
+ @tex_ml.paraskip_small \
+ "\n" \
+ ' \\begin{footnotesize}' \
+ "\n\n" \
+ dob.tmp \
+ '\\end{footnotesize}' \
+ "\n" \
+ @tex_ml.paraskip_normal
elsif dob.is==:verse
dob.tmp=dob.tmp.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/m,'\begin{bfseries}\1 \end{bfseries}').
gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/m,'\emph{\1}').
gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/m,'\uline{\1}')
ocn \
+ @tex_ml.paraskip_tiny \
+ "\n" \
+ ' \\begin{footnotesize}' \
+ "\n\n" \
+ dob.tmp \
+ '\\end{footnotesize}' \
+ "\n" \
+ @tex_ml.paraskip_normal \
+ "\n\\linebreak\n"
end
dob
elsif dob.is ==:code
dob=if @codeblock_box == 'listings'
box_listings(dob,ocn)
elsif @codeblock_box == 'boites'
box_boites(dob,ocn)
else
box_boites(dob,ocn)
end
dob
else 'error' #should never occur
end
dob=enclose(dob) unless dob.tmp =~/^$/
dob
else
tst=SiSU_TeX_Pdf::FormatTextObject.new(@md,dob)
case dob.is
when :heading
case dob.ln
when 0
tst.title_level_A
when 1
tst.section_heading_level_B
when 2
tst.section_heading_level_C
when 3
tst.section_heading_level_D
when 4
tst.heading_level_1
when 5
tst.heading_level_2
when 6
tst.heading_level_3
else dob
end
when :heading_insert
br="\n\\\\\n"
if dob.name=='book_index'
h=tst.section_heading_level_B
heading="\\clearpage\n" + h.tmp
idx_arr=[]
idx=SiSU_Particulars::CombinedSingleton.instance.get_idx_raw(@md.opt).raw_idx
idx.each do |x|
x=if x.is_a?(String)
x=SiSU_TeX_Pdf::SpecialCharacters.new(@md,x).special_characters
x=SiSU_TeX_Pdf::FormatTextObject.new(@md,x).url_str_internal(x,true)
else x=nil
end
idx_arr << x.sub(/,$/,'') if x.is_a?(String)
end
idx_str=idx_arr.join(br)
l=heading + br + idx_str
p=heading + br +
'\begin{multicols}{2}' + br +
idx_str + br +
'\end{multicols}'
dob.tmp={ l: l, p: p }
elsif dob.ln==2 \
and dob.obj=~/Metadata\b/
tst.section_heading_level_B
elsif dob.ln==4 \
and dob.obj=~/Metadata\b/
h=tst.heading_level_1
metadata=SiSU_Metadata::TeX_Metadata.new(@md).metadata_tex
dob.tmp=h.tmp + ' ' + '\begin{scriptsize}' + metadata.join(br) + '\end{scriptsize}'
else dob.tmp='' # dob.tmp={ l: '', p: '' }
end
when :para
if dob.bullet_
dob.tmp=tst.bullet
elsif dob.indent \
and dob.hang \
and dob.indent =~/[1-9]/ \
and dob.indent == dob.hang
dob.tmp=tst.indent
elsif dob.hang \
and dob.hang =~/[0-9]/ \
and (dob.indent != dob.hang or dob.indent =~/[1-9]/)
dob.tmp=tst.hang
else
dob.tmp=dob.tmp.strip
dob=enclose(dob) unless dob.tmp =~/^$/
end
else
dob.tmp=dob.tmp.strip unless dob.is==:code
dob=enclose(dob) unless dob.tmp =~/^$/
end
if dob.is_a?(String)
dob.tmp=dob.tmp.gsub(/\s*(?:#{Mx[:br_line]}|#{Mx[:br_nl]})\s*/,' \newline '). #% tread with care
gsub(/(\.#{Tex[:tilde]}\S*\s*|<:\S+>|#{Mx[:fa_o]}.*?#{Mx[:fa_c]}|#{Mx[:gr_o]}.*?#{Mx[:gr_c]}||)/,' ') #% tread with care
end
dob
end
if dob.tmp =~/(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image\b)/m \
&& dob.is !=:code
dob=SiSU_TeX_Pdf::BareUrls.new(@md,dob).bare_urls
tst=SiSU_TeX_Pdf::FormatTextObject.new(@md,dob)
dob=tst.urls_txt_and_images
dob
elsif dob.tmp =~/https?:\/\/\S+\b/m \
&& dob.is ==:code \
&& @codeblock_box !='listings'
dob=SiSU_TeX_Pdf::BareUrls.new(@md,dob).bare_urls_in_code
dob
end
if dob.class !=Hash \
&& dob.tmp =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}image\b/ \
&& dob.is !=:code
tst=SiSU_TeX_Pdf::FormatTextObject.new(@md,dob)
end
dob
end
def tex_box_listings
<<-WOK
\\definecolor{listinggray}{gray}{0.9}
\\definecolor{lbcolor}{rgb}{0.9,0.9,0.9}
\\lstset{
backgroundcolor=\\color{lbcolor},
tabsize=4,
rulecolor=,
language=,
basicstyle=\\scriptsize,
upquote=true,
aboveskip={1.5\\baselineskip},
columns=fixed,
showstringspaces=false,
extendedchars=true,
breaklines=true,
prebreak = \\raisebox{0ex}[0ex][0ex]{\\ensuremath{\\hookleftarrow}},
frame=single,
showtabs=false,
showspaces=false,
showstringspaces=false,
identifierstyle=\\ttfamily,
keywordstyle=\\color[rgb]{0,0,1},
commentstyle=\\color[rgb]{0.133,0.545,0.133},
stringstyle=\\color[rgb]{0.627,0.126,0.941},
}
WOK
end
def tex_box_boites
<<-WOK
\\def\\codeblockboitebox{%
\\def\\bkvz@before@breakbox{\\ifhmode\\par\\fi\\vskip\\breakboxskip\\relax}%
\\def\\bkvz@set@linewidth{\\advance\\linewidth -2\\fboxrule
\\advance\\linewidth -2\\fboxsep} %
\\def\\bk@line{\\hbox to \\linewidth{%
\\ifbkcount\\smash{\\llap{\\the\\bk@lcnt\\ }}\\fi
\\psframebox*[framesep=0pt,linewidth=0pt]{%
\\vrule\\@width\\fboxrule \\hskip\\fboxsep
\\box\\bk@bxa
\\hskip\\fboxsep \\vrule\\@width\\fboxrule
}%
}}%
%\\def\\bkvz@top{\\hrule\\@height\\fboxrule}
\\def\\bkvz@top{\\hrule height .6pt}%
\\def\\bkvz@bottom{\\hrule\\@height\\fboxrule}%
\\breakbox}
\\def\\endcodeblockboitebox{\\endbreakbox}
WOK
end
def tex_codeblock
codeblock_box=if @codeblock_box=='listings'
tex_box_listings
elsif @codeblock_box=='boites'
tex_box_boites
else
tex_box_boites
end
codeblock_box
end
def markup(data)
@tex_file=[]
home=@vz.txt_home.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}|#{Mx[:br_paragraph]}|\\\\/,' - ') #no line splitting in heading neither html nor latex
title=@md.title.full.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}|#{Mx[:br_paragraph]}|\\\\/,' - ') #no line splitting in heading neither html nor latex
@md.papersize_array.each do |ps|
if @md.opt.act[:pdf_p][:set]==:on
txt_obj={ txt: "#{home}: - #{title}", paper_size: ps, orientation: :portrait }
orient_portrait=SiSU_TeX_Pdf::FormatHead.new(@md,txt_obj)
@@tex_head[ps][:p]=orient_portrait.document_head_with_orientation(@codeblock_box)
end
if @md.opt.act[:pdf_l][:set]==:on
txt_obj={ txt: "#{home}: - #{title}", paper_size: ps, orientation: :landscape }
orient_landscape=SiSU_TeX_Pdf::FormatHead.new(@md,txt_obj)
@@tex_head[ps][:l]=orient_landscape.document_head_with_orientation(@codeblock_box)
end
end
@tex_file << <<-WOK
#{@tex_ml.header}#{@tex_ml.footer}
\\tolerance=300
\\clubpenalty=300
\\widowpenalty=300
\\makeatother
\\makeatother
\\chardef\\txtbullet="2022
\\chardef\\tilde="7E
%\\chardef\\asterisk="2A
\\def\\asterisk{{\\rm \\char42} }
\\definecolor{Light}{gray}{.92}
\\newcommand{\\Codeblock}[1]{\\normaltext\\raggedright\\small\\ttfamily\\texbackslash#1}
\\newcommand{\\monosp}[1]{\\normaltext\\ttfamily\\texbackslash#1}
\\newcommand{\\parasep}{\\\\ \\begin{center}*\\hspace{2em}*\\hspace{2em}*\\end{center} \\\\}
\\newcommand{\\hardspace}{{~}}
%\\newcommand{\\hardspace}{\\hspace{.5em}}
\\newcommand{\\caret}{{\\^{~}}}
\\newcommand{\\pipe}{{\\textbar}}
\\newcommand{\\curlyopen}{\{}
\\newcommand{\\curlyclose}{\}}
\\newcommand{\\lt}{{\UseTextSymbol{OML}{<}}}
\\newcommand{\\gt}{{\UseTextSymbol{OML}{>}}}
\\newcommand{\\slash}{{/}}
\\newcommand{\\underscore}{\\_}
\\newcommand{\\exclaim}{\\Verbatim{!}}
#{tex_codeblock}
% (tilde hash amp affected by http)
% \\sloppy
\\begin{document}
WOK
@copymark='' #check and remove as now is superflous
x={}
txt_obj={ title: @md.title.full }
if @md.opt.act[:pdf_l][:set]==:on
x[:l]=SiSU_TeX_Pdf::FormatTextObject.new(@md,txt_obj).title_landscape
end
if @md.opt.act[:pdf_p][:set]==:on
x[:p]=SiSU_TeX_Pdf::FormatTextObject.new(@md,txt_obj).title_portrait
end
@tex_file << x
x=nil
if defined? @md.creator.author \
and @md.creator.author
sp_char=SiSU_TeX_Pdf::SpecialCharacters.new(@md,@md.creator.author)
author=sp_char.special_characters
@tex_file << if @md.author_home
<<-WOK
\\author{\\href{#{@md.author_home}}{#{@copymark} \\textnormal{#{author}}}}
WOK
else "\n\\author{#{@copymark} \\textnormal{#{author}}}"
end
end
if defined? @md.make.cover_image \
and not @md.make.cover_image.nil? \
and @md.make.cover_image[:cover] =~/\S+/
x={}
dir=SiSU_Env::InfoEnv.new(@md.fns)
x[:l] =<<-WOK
\\titlepic{\\includegraphics[width=0.3\\textwidth]{#{dir.path.image_source_include}/#{@md.make.cover_image[:cover]}}}
WOK
x[:p] =<<-WOK
\\titlepic{\\includegraphics[width=0.6\\textwidth]{#{dir.path.image_source_include}/#{@md.make.cover_image[:cover]}}}
WOK
@tex_file << x
x=nil
end
@tex_file << unless @md.fnb =~/^mail\s*$/ then @tex_ml.site
else '\date'
end
@tex_file << <<-WOK
\\pagenumbering{roman}\\maketitle
\\pagestyle{fancy}
WOK
if defined? @md.rights.all \
and @md.rights.all
@tex_file << "\\newpage\n"
@tex_file << @@rights
@tex_file << @@prefix_b if defined? @md.creator.prefix_b and @md.creator.prefix_b
end
x={}
if (@make.build.toc?)
toc=<<-WOK
\\renewcommand{\\contentsname}{#{@translate.contents}}
\\tableofcontents
WOK
toc_pb={ l: @tex_ml.newpage(:landscape), p: @tex_ml.newpage(:portrait) }
else
toc=''
toc_pb={ l: '', p: '' }
end
if @md.opt.act[:pdf_l][:set]==:on
x[:l] =<<-WOK
#{@tex_ml.newpage(:landscape)}
\\pagestyle{fancy}
#{toc}#{toc_pb[:l]}
\\pagenumbering{arabic}
#{@tex_ml.paraskip_normal}
#{@tex_ml.newpage(:landscape)}
WOK
end
if @md.opt.act[:pdf_p][:set]==:on
x[:p] =<<-WOK
#{@tex_ml.newpage(:portrait)}
\\pagestyle{fancy}
#{toc}#{toc_pb[:p]}
#{@tex_ml.newpage(:portrait)}
\\pagenumbering{arabic}
#{@tex_ml.paraskip_normal}
#{@tex_ml.newpage(:portrait)}
WOK
end
@tex_file << x
x=nil
data.each do |dob| #% case follows with levels 1-6 indents & graphics
if dob.is_a?(Hash)
elsif dob.of==:para \
|| dob.of==:block #GATEWAY FIX FIX stuff
dob=markup_common(dob)
elsif dob.is==:table
if ( dob.tmp['a4'] \
or dob.tmp['a5'] \
or dob.tmp['b5'] \
or dob.tmp['letter'] \
or dob.tmp['legal'])
@md.papersize_array.each do |ps|
if dob.tmp[ps]
if (dob.tmp[ps][:p] and dob.tmp[ps][:l])
dob.tmp[ps]={
p: markup_common(dob.tmp[ps][:p]),
l: markup_common(dob.tmp[ps][:l])
}
else p "#{__FILE__}:#{__LINE__}" if @md.opt.act[:maintenance][:set]==:on
end
end
end
elsif dob.tmp.is_a?(Hash) \
and (dob.tmp[:p] and dob.tmp[:l])
dob = {
p: markup_common(dob.tmp[:p]),
l: markup_common(dob.tmp[:l])
}
else p "#{__FILE__}:#{__LINE__}" if @md.opt.act[:maintenance][:set]==:on
end
end
@tex_file << dob
end
@st[:tex][:stmp]||=@md.stmpd
stamp=@st[:tex][:stmp] if @st[:tex][:stmp]
if stamp
use=stamp.gsub(/\n/,"#{Tex[:backslash]*2}\n")
@tex_file << "\n\\newpage\n"
@tex_file << "\\section*" +
"{#{@tex_ml.owner_chapter}}\n" +
"\\addcontentsline{toc}" +
"{section}{#{@tex_ml.owner_chapter}}\n"
@tex_file << "#{use}\n"
@tex_file << @@rights if @@rights
end
@tex_file << "\n\\end{document}"
end
def number_paras_numbering(dob) # need tables and other types of object
if dob.of ==:para
paranum=dob.ocn ? dob.ocn : ''
paranum = '' if paranum.to_i==0
paranumber_display=if @make.build.ocn?
tags=''
#[keep] code that follows inserts "name tags" as hypertargets, currently using ocn (converting nametags to ocn) for internal linking, related code: |texpdf_format.rb|@|uses nametags directly|
#if dob.tags.length > 0 # insert tags "hypertargets"
# dob.tags.each do |t|
# tags=tags +"\\hspace{0mm}\\hypertarget{#{t}}{\\hspace{0mm}}"
# end
#end
"\\begin{tiny}\\hspace{0mm}\\end{tiny}{\\marginpar{\\begin{tiny}\\hspace{0mm}\\hypertarget{#{dob.ocn}}{#{dob.ocn}}#{tags}\\end{tiny}}}" #ocn object citation numbering
else ''
end
dob.tmp = paranumber_display + dob.tmp
end
dob
end
def number_paras(data)
data.each do |dob|
dob=if dob.is_a?(Hash)
if ( dob['a4'] \
or dob['a5'] \
or dob['b5'] \
or dob['letter'] \
or dob['legal'])
para_hash={}
@md.papersize_array.each do |ps|
if defined? dob.tmp and dob.tmp[ps]
if (dob.tmp[ps][:p] and dob.tmp[ps][:l])
para_hash[ps]={
p: number_paras_numbering(dob.tmp[ps][:p]),
l: number_paras_numbering(dob.tmp[ps][:l])
}
dob.tmp=para_hash
else p "#{__FILE__}:#{__LINE__}" if @md.opt.act[:maintenance][:set]==:on
end
end
end
elsif (dob.tmp[:p] and dob.tmp[:l])
dob.tmp = {
p: number_paras_numbering(dob.tmp[:p]),
l: number_paras_numbering(dob.tmp[:l])
}
else p "#{__FILE__}:#{__LINE__}" if @md.opt.act[:maintenance][:set]==:on
end
else
dob=if dob.of !=:comment \
|| dob.of !=:meta \
|| dob.of !=:layout
number_paras_numbering(dob)
else dob
end
end
end
data
end
def output_morph_hash(o)
ps,h,fn=o[:ps],o[:h],o[:filename]
if h[ps] \
and (h[ps][:p] or h[ps][:l])
if @md.opt.act[:pdf_p][:set]==:on
if h[ps][:p]
h[ps][:p]=h[ps][:p].gsub(/[ ]+$/m,'').
gsub(/\n\n\n+/m,"\n\n")
end
if h[ps][:p] !~/\A\s*\Z/
fn[:portrait].puts h[ps][:p],"\n"
end
end
if @md.opt.act[:pdf_l][:set]==:on
if h[ps][:l]
h[ps][:l]=h[ps][:l].gsub(/[ ]+$/m,'').
gsub(/\n\n\n+/m,"\n\n")
end
if h[ps][:l] !~/\A\s*\Z/
fn[:landscape].puts h[ps][:l],"\n"
end
end
elsif (h[:p] or h[:l])
if @md.opt.act[:pdf_p][:set]==:on
if h[:p]
h[:p]=h[:p].gsub(/[ ]+$/m,'').
gsub(/\n\n\n+/m,"\n\n")
end
if h[:p] !~/\A\s*\Z/
fn[:portrait].puts h[:p],"\n"
end
end
if @md.opt.act[:pdf_l][:set]==:on
if h[:l]
h[:l]=h[:l].gsub(/[ ]+$/m,'').
gsub(/\n\n\n+/m,"\n\n")
end
if h[:l] !~/\A\s*\Z/
fn[:landscape].puts h[:l],"\n"
end
end
else p "#{__FILE__}:#{__LINE__}" if @md.opt.act[:maintenance][:set]==:on
end
end
def output(array)
@array=array=array.flatten.compact
fns=@md.fns.gsub(/~/,'-') #this is a sorry fix, but necessary as it appears latex programs like not ~
@md.papersize_array.each do |ps|
texfile_landscape=(@md.opt.act[:pdf_l][:set]==:on) \
? (File.new("#{@env.processing_path.tex}/#{fns}.#{ps}.landscape.tex",'w+'))
: nil
texfile_portrait=(@md.opt.act[:pdf_p][:set]==:on) \
? (File.new("#{@env.processing_path.tex}/#{fns}.#{ps}.tex",'w+'))
: nil
file={
landscape: texfile_landscape,
portrait: texfile_portrait
}
if @md.opt.act[:pdf_p][:set]==:on
file[:portrait] << @@tex_head[ps][:p]
end
if @md.opt.act[:pdf_l][:set]==:on
file[:landscape] << @@tex_head[ps][:l]
end
array.each do |morph|
if morph.is_a?(String)
#morph.gsub!(/^\s+/,'')
if morph !~/\A\s*\Z/
if @md.opt.act[:pdf_p][:set]==:on
file[:portrait].puts morph,"\n"
end
if @md.opt.act[:pdf_l][:set]==:on
file[:landscape].puts morph,"\n"
end
end
elsif morph.class.inspect =~ /SiSU_AO_DocumentStructure/ \
and morph.tmp \
and morph.tmp.is_a?(String)
if morph.is !=:code \
&& morph.of !=:block
morph.tmp=morph.tmp.gsub(/^\s+/,'')
else morph.tmp
end
if (morph.tmp !~/\A\s*\Z/) \
|| morph.is==:code
if @md.opt.act[:pdf_p][:set]==:on
file[:portrait].puts morph.tmp,"\n"
end
if @md.opt.act[:pdf_l][:set]==:on
file[:landscape].puts morph.tmp,"\n"
end
end
elsif morph.is_a?(Hash) #inserted headers and the like, only
h={ ps: ps, h: morph, filename: file }
output_morph_hash(h)
elsif morph.tmp.is_a?(Hash) #tables & images?
h={ ps: ps, h: morph.tmp, filename: file }
output_morph_hash(h)
end
end
array=@array
if @md.opt.act[:pdf_p][:set]==:on
file[:portrait].close
end
if @md.opt.act[:pdf_l][:set]==:on
file[:landscape].close
end
end
@@tex_head={
'a4'=> { p: nil, l: nil },
'a5'=> { p: nil, l: nil },
'b5'=> { p: nil, l: nil },
'letter'=>{ p: nil, l: nil },
'legal'=> { p: nil, l: nil },
'book'=> { p: nil, l: nil }
}
array=[]
end
end
end
end
__END__