# encoding: utf-8 =begin * Name: SiSU ** Description: documents, structuring, processing, publishing, search *** pot file generation ** 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/src_po4a_shelf.rb;hb=HEAD> =end module SiSU_Po4a require_relative 'ao' # ao.rb require_relative 'se' # se.rb include SiSU_Env require_relative 'ao_composite' # ao_composite.rb require_relative 'shared_metadata' # shared_metadata.rb require_relative 'src_po4a_shelf_set' # src_po4a_shelf_set.rb include SiSU_Param require_relative 'object_munge' # object_munge.rb require_relative 'utils_composite' # utils_composite.rb class Source include SiSU_Object_Munge @@opt_src,@@opt_trn,@@opt_src_,@@opt_trn_,@@md_src,@@md_trn= nil, nil, nil, nil, nil, nil @@auto_translation_ = :go def initialize(opt,fn=nil) @opt,@fn=opt,fn #unless @opt.fns =~/(.+?\.(?:-|ssm\.)?sst)$/ # puts "#{@opt.fns} not a processed file type" #end file_arr=SiSU_Info_Env::InfoEnv.new.source_file_processing_array(@opt.fns) SiSU_Param::Parameters::Instructions.new(file_arr,@opt).extract r=Px[:lng_lst_rgx].gsub(/\|en\|/,'|') @lang_regx=%r{(?:#{r})} if opt.fns =~/\S+?~#{@lang_regx}\.ss[mti]/ \ and opt.f_pth[:lng]!=@opt.lng_base @@opt_src_=false @@opt_trn=opt @@md_trn=SiSU_Param::Parameters.new(opt).get else @@opt_src_=true @@opt_src=opt @@md_src=SiSU_Param::Parameters.new(opt).get end end def wrap_width_set(md,env) if defined? md.make.plaintext_wrap \ and md.make.plaintext_wrap md.make.plaintext_wrap elsif defined? env.plaintext_wrap \ and env.plaintext_wrap env.plaintext_wrap else 78 end end def process_file(md,env,file,wrap_width,fn) unless @opt.act[:quiet][:set]==:on tool=(@opt.act[:verbose][:set]==:on \ || @opt.act[:verbose_plus][:set]==:on \ || @opt.act[:maintenance][:set]==:on) \ ? "#{env.program.text_editor} #{file.output_path.pot.dir}/" : @opt.fns (@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], 'Pot po4a', tool ).green_hi_blue : SiSU_Screen::Ansi.new( @opt.act[:color_state][:set], 'Pot po4a', tool ).green_title_hi if (@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], @opt.fns, file.output_path.pot.dir ).flow end end if @opt.fns =~/\S+?~#{@lang_regx}\.ss[mti]/ \ or @opt.f_pth[:lng] !=@opt.lng_base opt_lang_trn_fn=fn @ao_arr_lang_trans= SiSU_AO::Source.new(@opt,opt_lang_trn_fn,:po4a).get # ao file drawn here opt_lang_src_fn=(fn =~/\S+?~\S{2}(?:_\S{2})?\.ss[mti]/) \ ? (fn.gsub(/(\S+?)~\S{2}(?:_\S{2})?(\.ss[mti])/,'\1\2')) #check i : fn transdir,srcdir=Dir.pwd,Dir.pwd if Dir.pwd.to_s =~/\/#{@lang_regx}$/ transdir=Dir.pwd srcdir=transdir. gsub(/\/#{@lang_regx}$/, "/#{@opt.lng_base}") if FileTest.directory?(srcdir) Dir.chdir(srcdir) end else nil end if FileTest.file?("#{srcdir}/#{opt_lang_src_fn}") @ao_arr_lang_src= SiSU_AO::Source.new( @@opt_src, opt_lang_src_fn, :po4a ).get # ao file drawn here else puts "no identified source document" exit end Dir.chdir(transdir) if transdir else @ao_arr_lang_src= SiSU_AO::Source.new( @opt, fn, :po4a ).get # ao file drawn here @ao_arr_lang_trans=nil end SiSU_Po4a::Source::Scroll.new( fn, @ao_arr_lang_src, @ao_arr_lang_trans, @@md_src, @@md_trn, wrap_width ).songsheet end def read begin src={} src[:pth]=@opt.f_pth[:pth] src[:files]=if @opt.fns =~ /\.(?:(?:-|ssm\.)sst|ssm)$/ @opt.fns=@opt.fns.gsub(/\.ssm\.sst$/,'.ssm') SiSU_Assemble::CompositeFileList.new(@opt).read else [@opt.fns] end md=SiSU_Param::Parameters.new(@opt).get env=SiSU_Env::InfoEnv.new(@opt.fns) file=SiSU_Env::FileOp.new(md) Po4aCfg.new(@opt,file).po4a_cfg wrap_width=wrap_width_set(md,env) src[:files].each do |fn| process_file(md,env,file,wrap_width,fn) end rescue SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do __LINE__.to_s + ':' + __FILE__ end ensure end end private class Scroll <Source include SiSU_Po4aUtils @@endnotes={ para: [], end: [] } def initialize(fn,data_src,data_trn,md_src,md_trn,wrap_width) @fn,@data_src,@data_trn,@md_src,@md_trn,@wrap_width= fn, data_src, data_trn, md_src, md_trn, wrap_width @md=(md_trn.nil?) \ ? md_src : md_trn @tab="\t" @@endnotes_=(@md.opt.selections.str =~/--endnote/) \ ? true : false # --footnote @pot={ body: [], open: [], close: [], head: [], metadata: [], tail: [] } end def br (@md.opt.selections.str =~/--dos/) ? "\r\n" : "\n" # --unix end def songsheet fn=@fn pot=pot_markup(@data_src,@data_trn) publish(fn,pot) end def pot_structure_wrap(desc,orig,trans,indent=0,hang=0) SiSU_Po4aUtils::Wrap.new( @md, orig, trans, desc, @wrap_width, indent, hang ) end def wrap_endnotes(orig_notes='',trn_notes='') nt=@@endnotes_ ? 'endnote' : 'footnote' @fn=0 a_l=orig_notes.length 0.upto(a_l-1) do |i| @fn=if orig_notes[i].to_s =~/^\^~([\d*+]+)/ # provides endnote number within paragraph @fn += 1 else @fn end d="#{nt} #{@fn}" mark="^~ " instruct=s_mark='' if @md.opt.act[:maintenance][:set]==:on instruct=%{\n# footnotes, the preferred sisu markup for a footnote is~{this is a footnote}~ } \ + %{however, for translation a footnote reference marker in the text~^ } \ + %{with a set of notes following the paragraph starting on a newline with "^~ this is a footnote", } \ + %{is easier to deal with, if possible these should be converted back to~{inline notes}~} s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} end desc="#{d}#{s_mark}#{instruct}" orig=(orig_notes[i].to_s =~/^\^~[\d*+]+/) \ ? (orig_notes[i].to_s.gsub(/^\^~[\d*+]+/,'^~')) : orig_notes[i].to_s trans=if trn_notes.is_a?(Array) \ and trn_notes.length==orig_notes.length (trn_notes[i].to_s =~/^\^~[\d*+]+/) \ ? (trn_notes[i].to_s.gsub(/^\^~[\d*+]+/,'^~')) : trn_notes[i].to_s else '' end util=pot_structure_wrap(desc,orig,trans) wrap=util.line_wrap wrap=if wrap =~ /^\s*\^~[\d*+]+\s+.+?\s*\Z/m wrap.gsub(/^\s*(\^~[\d*+]+)\s+(.+?)\s*\Z/m, <<GSUB \\1 \\2 GSUB ) else wrap.gsub(/^(.+)\Z/m, <<GSUB \\1 GSUB ) end @@endnotes[:para] << wrap @@endnotes[:end] << '' << wrap end @@endnotes[:para].each {|e| @pot[:body] << e << br} @@endnotes[:para]=[] @@endnotes end def pot_metadata_src @po4a_identify_type='type: SiSU doc' #'type: Plain text' meta_src=SiSU_Metadata::Summary.new(@md_src) w=[] w << [ "#. #{@po4a_identify_type} - metadata: title", "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", 'msgid ""', meta_src.metadata_tags.title.main, meta_src.metadata_tags.title.sub, meta_src.metadata_tags.title.edition, meta_src.metadata_tags.title.note, meta_src.metadata_tags.title.short, meta_src.metadata_tags.title.language, meta_src.metadata_tags.title.language_char, 'msgstr ""', ] w << [ "#. #{@po4a_identify_type} - metadata: creator", "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", 'msgid ""', meta_src.metadata_tags.creator.head, meta_src.metadata_tags.creator.author, meta_src.metadata_tags.creator.contributor, meta_src.metadata_tags.creator.illustrator, meta_src.metadata_tags.creator.photographer, meta_src.metadata_tags.creator.translator, meta_src.metadata_tags.creator.audio, meta_src.metadata_tags.creator.digitized_by, meta_src.metadata_tags.creator.prepared_by, 'msgstr ""', ] w << [ "#. #{@po4a_identify_type} - metadata: rights", "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", 'msgid ""', meta_src.metadata_tags.rights.head, meta_src.metadata_tags.rights.copyright.text, meta_src.metadata_tags.rights.copyright.translation, meta_src.metadata_tags.rights.copyright.illustrations, meta_src.metadata_tags.rights.copyright.photographs, meta_src.metadata_tags.rights.copyright.digitization, meta_src.metadata_tags.rights.copyright.audio, meta_src.metadata_tags.rights.license, 'msgstr ""', ] w << [ "#. #{@po4a_identify_type} - metadata: classify", "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", 'msgid ""', meta_src.metadata_tags.classify.head, meta_src.metadata_tags.classify.subject, meta_src.metadata_tags.classify.topic_register, meta_src.metadata_tags.classify.loc, meta_src.metadata_tags.classify.dewey, #meta_src.metadata_tags.notes.relation, #meta_src.metadata_tags.notes.type, #meta_src.metadata_tags.identifier.oclc, #meta_src.metadata_tags.identifier.isbn, 'msgstr ""', ] w << [ "#. #{@po4a_identify_type} - metadata: date", "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", 'msgid ""', meta_src.metadata_tags.date.head, meta_src.metadata_tags.date.added_to_site, meta_src.metadata_tags.date.available, meta_src.metadata_tags.date.created, meta_src.metadata_tags.date.issued, meta_src.metadata_tags.date.modified, meta_src.metadata_tags.date.published, meta_src.metadata_tags.date.valid, 'msgstr ""', ] w << [ "#. #{@po4a_identify_type} - processing, make instruction", "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", 'msgid ""', meta_src.processing_tags.make.language, meta_src.processing_tags.make.headings, meta_src.processing_tags.make.num_top, meta_src.processing_tags.make.breaks, meta_src.processing_tags.make.emphasis, meta_src.processing_tags.make.bold, meta_src.processing_tags.make.italics, meta_src.processing_tags.make.texpdf_font, 'msgstr ""', ] w.each do |y| z='' y.each do |x| if x z += x + "\n" if x =~/^#|^msg(?:id|str)/ z += %{"#{x}"\n} if x =~/^@\S+?:(?: |$)/ z += %{"#{x}"\n} if x =~/^\s+:\S+?: / end end @pot[:metadata] << z << br #puts z unless z.empty? end end def pot_metadata_src_trn @po4a_identify_type='type: SiSU doc' #@po4a_identify_type='type: Plain text' meta_src=SiSU_Metadata::Summary.new(@md_src) meta_trn=SiSU_Metadata::Summary.new(@md_trn) w=[] w << [ "#. #{@po4a_identify_type} - metadata: title", "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", 'msgid ""', meta_src.metadata_tags.title.main, meta_src.metadata_tags.title.sub, meta_src.metadata_tags.title.edition, meta_src.metadata_tags.title.note, meta_src.metadata_tags.title.short, meta_src.metadata_tags.title.language, meta_src.metadata_tags.title.language_char, 'msgstr ""', meta_trn.metadata_tags.title.main, meta_trn.metadata_tags.title.sub, meta_trn.metadata_tags.title.edition, meta_trn.metadata_tags.title.note, meta_trn.metadata_tags.title.short, meta_trn.metadata_tags.title.language, meta_trn.metadata_tags.title.language_char, ] w << [ "#. #{@po4a_identify_type} - metadata: creator", "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", 'msgid ""', meta_src.metadata_tags.creator.head, meta_src.metadata_tags.creator.author, meta_src.metadata_tags.creator.contributor, meta_src.metadata_tags.creator.illustrator, meta_src.metadata_tags.creator.photographer, meta_src.metadata_tags.creator.translator, meta_src.metadata_tags.creator.audio, meta_src.metadata_tags.creator.digitized_by, meta_src.metadata_tags.creator.prepared_by, 'msgstr ""', meta_trn.metadata_tags.creator.head, meta_trn.metadata_tags.creator.author, meta_trn.metadata_tags.creator.contributor, meta_trn.metadata_tags.creator.illustrator, meta_trn.metadata_tags.creator.photographer, meta_trn.metadata_tags.creator.translator, meta_trn.metadata_tags.creator.audio, meta_trn.metadata_tags.creator.digitized_by, meta_trn.metadata_tags.creator.prepared_by, ] w << [ "#. #{@po4a_identify_type} - metadata: rights", "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", 'msgid ""', meta_src.metadata_tags.rights.head, meta_src.metadata_tags.rights.copyright.text, meta_src.metadata_tags.rights.copyright.translation, meta_src.metadata_tags.rights.copyright.illustrations, meta_src.metadata_tags.rights.copyright.photographs, meta_src.metadata_tags.rights.copyright.digitization, meta_src.metadata_tags.rights.copyright.audio, meta_src.metadata_tags.rights.license, 'msgstr ""', meta_trn.metadata_tags.rights.head, meta_trn.metadata_tags.rights.copyright.text, meta_trn.metadata_tags.rights.copyright.translation, meta_trn.metadata_tags.rights.copyright.illustrations, meta_trn.metadata_tags.rights.copyright.photographs, meta_trn.metadata_tags.rights.copyright.digitization, meta_trn.metadata_tags.rights.copyright.audio, meta_trn.metadata_tags.rights.license, ] w << [ "#. #{@po4a_identify_type} - metadata: classify", "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", 'msgid ""', meta_src.metadata_tags.classify.head, meta_src.metadata_tags.classify.subject, meta_src.metadata_tags.classify.topic_register, meta_src.metadata_tags.classify.loc, meta_src.metadata_tags.classify.dewey, #meta_src.metadata_tags.notes.relation, #meta_src.metadata_tags.notes.type, #meta_src.metadata_tags.identifier.oclc, #meta_src.metadata_tags.identifier.isbn, 'msgstr ""', meta_trn.metadata_tags.classify.head, meta_trn.metadata_tags.classify.subject, meta_trn.metadata_tags.classify.topic_register, meta_trn.metadata_tags.classify.loc, meta_trn.metadata_tags.classify.dewey, #meta_trn.metadata_tags.notes.relation, #meta_trn.metadata_tags.notes.type, #meta_trn.metadata_tags.identifier.oclc, #meta_trn.metadata_tags.identifier.isbn, ] w << [ "#. #{@po4a_identify_type} - metadata: date", "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", 'msgid ""', meta_src.metadata_tags.date.head, meta_src.metadata_tags.date.added_to_site, meta_src.metadata_tags.date.available, meta_src.metadata_tags.date.created, meta_src.metadata_tags.date.issued, meta_src.metadata_tags.date.modified, meta_src.metadata_tags.date.published, meta_src.metadata_tags.date.valid, 'msgstr ""', meta_trn.metadata_tags.date.head, meta_trn.metadata_tags.date.added_to_site, meta_trn.metadata_tags.date.available, meta_trn.metadata_tags.date.created, meta_trn.metadata_tags.date.issued, meta_trn.metadata_tags.date.modified, meta_trn.metadata_tags.date.published, meta_trn.metadata_tags.date.valid, ] w << [ "#. #{@po4a_identify_type} - processing, make instruction", "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", 'msgid ""', meta_src.processing_tags.make.language, meta_src.processing_tags.make.headings, meta_src.processing_tags.make.num_top, meta_src.processing_tags.make.breaks, meta_src.processing_tags.make.emphasis, meta_src.processing_tags.make.bold, meta_src.processing_tags.make.italics, meta_src.processing_tags.make.texpdf_font, 'msgstr ""', meta_trn.processing_tags.make.language, meta_trn.processing_tags.make.headings, meta_trn.processing_tags.make.num_top, meta_trn.processing_tags.make.breaks, meta_trn.processing_tags.make.emphasis, meta_trn.processing_tags.make.bold, meta_trn.processing_tags.make.italics, meta_trn.processing_tags.make.texpdf_font, ] w.each do |y| z='' y.each do |x| if x z += x + "\n" if x =~/^#|^msg(?:id|str)/ z += %{"#{x}"\n} if x =~/^@\S+?:(?: |$)/ z += %{"#{x}"\n} if x =~/^\s+:\S+?: / end end @pot[:metadata] << z << br #puts z unless z.empty? end end def auto_translate?(set_to=nil) @@auto_translation_= if @md.opt.act[:po4a_lang_trans][:set]==:on set_to \ ? set_to : @@auto_translation_ else :skip end end def auto_translation(src_txt,markup=:src) # check for an appropriate request flag auto_translate?(:skip) begin src_txt_clean=clean_text(src_txt,markup) src_txt_clean=src_txt_clean. gsub(/\n/,' '). gsub(/"/,'\"'). gsub(/([()])/,'\\\\\1') trans='' unless auto_translate? == :skip require 'timeout' Timeout::timeout(60) { trans=`trans -b -no-ansi en:#{@md.opt.f_pth[:lng_is]} #{src_txt_clean}`.strip unless trans.empty? trans + ' {[G.Tr]}http://translate.google.com' end } end trans rescue auto_translate?(:skip) p 'timeout issues with translation, skip remaining' end end def pot_structure def heading(dob_src='',notes_s='',dob_trn='',notes_t='') #% used to extract the structure of a document lv=n=n3=nil lv=dob_src.ln n=lv - 1 n3=lv + 2 util=nil fn=(dob_src.name=~/[a-z\d]/i) ? dob_src.name : '' mark="#{dob_src.lv}~#{fn} " d="#{dob_src.is.to_s} (level #{dob_src.lv})" instruct=s_mark='' if @md.opt.act[:maintenance][:set]==:on instruct=%{\n# markup for headings is marker at the start of the line/object, } \ + %{indicating the heading level, and if provided an associated name tag, } \ + %{this heading is "#{mark}"} s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} end desc="#{d}#{s_mark}#{instruct}" orig="#{s_mark}#{dob_src.obj}" trans=((dob_trn=='') \ || (dob_src.obj == dob_trn.obj)) \ ? '' : "#{s_mark}#{dob_trn.obj}" if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ and trans.empty? \ and auto_translate? trans=auto_translation(dob_src.obj,:src) end util=pot_structure_wrap(desc,orig,trans) wrapped=util.line_wrap @pot[:body] << wrapped << br # main text, contents, body KEEP if @@endnotes[:para] \ and notes_s.length > 0 \ and not @@endnotes_ @pot[:body] << br wrap_endnotes(notes_s,notes_t) elsif @@endnotes[:para] \ and @@endnotes_ @pot[:body] << br*2 end end def para(dob_src='',notes_s='',dob_trn='',notes_t='') #% used to extract the structure of a document util=nil wrapped=if dob_src.indent =~/[1-9]/ \ and dob_src.indent == dob_src.hang s_mark=desc=orig=trans='' if dob_src.bullet_ mark="_#{dob_src.indent}* " d="#{dob_src.is.to_s}: indent #{dob_src.indent}, bullet" instruct=s_mark='' if @md.opt.act[:maintenance][:set]==:on instruct=%{\n# markup for indented bullet text is at the start of the line/object, } \ + %{an underscore followed by the indent level and an asterisk "#{mark}"} s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} end desc="#{d}#{s_mark}#{instruct}" else mark="_#{dob_src.indent} " d="#{dob_src.is.to_s}: indent #{dob_src.indent}" instruct=s_mark='' if @md.opt.act[:maintenance][:set]==:on instruct=%{\n# markup for indented text is at the start of the line/object, } \ + %{an underscore followed by the indent level "#{mark}"} s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} end desc="#{d}#{s_mark}#{instruct}" end orig="#{s_mark}#{dob_src.obj}" trans=((dob_trn=='') \ || (dob_src.obj == dob_trn.obj)) \ ? '' : "#{s_mark}#{dob_trn.obj}" if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ and trans.empty? \ and auto_translate? trans=auto_translation(dob_src.obj,:src) end util=pot_structure_wrap(desc,orig,trans) elsif dob_src.hang =~/[0-9]/ \ and dob_src.indent != dob_src.hang s_mark=desc=orig=trans='' mark="_#{dob_src.hang}_#{dob_src.indent} " d="#{dob_src.is.to_s}: hang #{dob_src.hang} indent #{dob_src.indent}" instruct=s_mark='' if @md.opt.act[:maintenance][:set]==:on instruct=%{\n# markup for indented text with a first line indented } \ + %{to a different level from the rest of the paragraph, } \ + %{is at the start of the line/object, } \ + %{an underscore and the first indent level } \ + %{a second underscore and the indent level for the rest of the paragraph, "#{mark1}"} s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} end desc="#{d}#{s_mark}#{instruct}" orig="#{s_mark}#{dob_src.obj}" trans=((dob_trn=='') \ || (dob_src.obj == dob_trn.obj)) \ ? '' : "#{s_mark}#{dob_trn.obj}" if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ and trans.empty? \ and auto_translate? trans=auto_translation(dob_src.obj,:src) end util=pot_structure_wrap(desc,orig,trans) else s_mark=desc=orig=trans='' if dob_src.bullet_ mark='_* ' d="#{dob_src.is.to_s}: bullet" instruct=s_mark='' if @md.opt.act[:maintenance][:set]==:on instruct=%{\n# markup for indented text is at the start of the line/object, } \ + %{an underscore followed by an asterisk "#{mark}"} s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} end desc="#{d}#{s_mark}#{instruct}" orig="#{s_mark}#{dob_src.obj}" trans=((dob_trn=='') \ || (dob_src.obj == dob_trn.obj)) \ ? '' : "#{s_mark}#{dob_trn.obj}" if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ and trans.empty? \ and auto_translate? trans=auto_translation(dob_src.obj,:src) end else mark='' d=dob_src.is.to_s instruct=%{\n# regular paragraph, no special markup} if @md.opt.act[:maintenance][:set]==:on instruct="\n# " s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} end desc="#{d}#{s_mark}#{instruct}" orig=dob_src.obj trans=((dob_trn=='') \ || (dob_src.obj == dob_trn.obj)) \ ? '' : "#{s_mark}#{dob_trn.obj}" if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ and trans.empty? \ and auto_translate? trans=auto_translation(dob_src.obj,:src) end end util=pot_structure_wrap(desc,orig,trans) end wrapped=util.line_wrap @pot[:body] << wrapped << br # main text, contents, body KEEP if @@endnotes[:para] \ and notes_s.length > 0 \ and not @@endnotes_ @pot[:body] << br wrap_endnotes(notes_s,notes_t) elsif @@endnotes[:para] \ and @@endnotes_ @pot[:body] << br*2 end end def block(dob_src='',notes_s='',dob_trn='',notes_t='') #% used to extract the structure of a document mark="block{\\n\\n...\\n\\n}block" d=dob_src.is.to_s instruct=s_mark='' if @md.opt.act[:maintenance][:set]==:on instruct=%{\n# block text is a text block with an opening and closing marker, } \ + %{the content of which may be wrapped} s_mark="\n# " + %{"\\n\\n#{mark}\\n\\n"} end desc="#{d}#{s_mark}#{instruct}" orig=dob_src.obj trans=((dob_trn=='') \ || (dob_src.obj == dob_trn.obj)) \ ? '' : "#{s_mark}#{dob_trn.obj}" if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ and trans.empty? \ and auto_translate? trans=auto_translation(dob_src.obj,:src) end util=pot_structure_wrap(desc,orig,trans) unwrapped=util.no_line_wrap_block @pot[:body] << unwrapped << br end def group(dob_src='',notes_s='',dob_trn='',notes_t='') #% used to extract the structure of a document mark="group{\\n\\n...\\n\\n}group" d=dob_src.is.to_s instruct=s_mark='' if @md.opt.act[:maintenance][:set]==:on instruct=%{\n# group text is a text block with an opening and closing marker, } \ + %{the content of which may be wrapped} s_mark="\n# " + %{"\\n\\n#{mark}\\n\\n"} end desc="#{d}#{s_mark}#{instruct}" orig=dob_src.obj trans=((dob_trn=='') \ || (dob_src.obj == dob_trn.obj)) \ ? '' : "#{s_mark}#{dob_trn.obj}" if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ and trans.empty? \ and auto_translate? trans=auto_translation(dob_src.obj,:src) end util=pot_structure_wrap(desc,orig,trans) unwrapped=util.no_line_wrap_block @pot[:body] << unwrapped << br end def verse(dob_src='',notes_s='',dob_trn='',notes_t='') #% used to extract the structure of a document mark="poem{\n\nverse\n\nverse\n\n...\n\n}poem" d=dob_src.is.to_s instruct=s_mark='' if @md.opt.act[:maintenance][:set]==:on instruct=%{\n# verse are part of the text block described as a poem, } \ + %{the first verse is preceeded by an opening marker, } \ + %{and the last verse by a closing marker, } \ + %{the content of which should remain unwrapped} s_mark="\n# " + %{"\\n\\n#{mark}\\n\\n"} end desc="#{d}#{s_mark}#{instruct}" orig=dob_src.obj trans=(dob_trn=='') ? '' : dob_trn.obj util=pot_structure_wrap(desc,orig,trans) unwrapped=util.no_line_wrap_block @pot[:body] << unwrapped << br end def code(dob_src='',notes_s='',dob_trn='',notes_t='') #% used to extract the structure of a document mark="code{\\n\\n...\\n\\n}code" d=dob_src.is.to_s instruct=s_mark='' if @md.opt.act[:maintenance][:set]==:on instruct=%{\n# codeblocks are a text block with an opening and closing marker, } \ + %{the content of which should remain unwrapped} s_mark="\n# " + %{"\\n\\n#{mark}\\n\\n"} end desc="#{d}#{s_mark}#{instruct}" orig=dob_src.obj trans=(dob_trn=='') ? '' : dob_trn.obj util=pot_structure_wrap(desc,orig,trans) unwrapped=util.no_line_wrap_block @pot[:body] << unwrapped << br end def table(dob_src='',notes_s='',dob_trn='',notes_t='') #% used to extract the structure of a document mark="table{\\n\\n...\\n\\n}table" d=dob_src.is.to_s instruct=s_mark='' if @md.opt.act[:maintenance][:set]==:on instruct=%{\n# tables are a text block with an opening and closing marker, } \ + %{the content of which should remain unwrapped} s_mark="\n# " + %{"\\n\\n#{mark}\\n\\n"} end desc="#{d}#{s_mark}#{instruct}" orig=dob_src.obj orig=orig.gsub(/#{Mx[:tc_c]}/,"\n") trans=(dob_trn=='') ? '' : dob_trn.obj trans=trans.gsub(/#{Mx[:tc_c]}/,"\n") util=pot_structure_wrap(desc,orig,trans) unwrapped=util.no_line_wrap_block @pot[:body] << unwrapped << br end def idx_markup(idx) struct=['={'] idx.sort.each do |x| x.each_with_index do |y,i0| case y when String struct << ';' unless struct[-1] =~/=\{/ struct << y if x[i0+1].class == Hash \ and x[i0+1][:sub].length > 0 struct << ':' end when Hash if y[:plus].to_i > 0 struct << '+' + y[:plus].to_s end if y[:sub].length > 0 y[:sub].each_with_index do |z,i1| z.each_with_index do |a,i2| #p a if z.length > 0 struct << a[0] if a[1][:plus].to_i > 0 struct << '+' + a[1][:plus].to_s end if (i1 + 1) < y[:sub].length struct << '|' end end end end end end end end struct << '}' #puts struct.join struct.join end def idx(dob_src='',dob_trn='') #% used for book index but broken as original markup lost, already abstracted, fix mark="={ ... }" instruct=s_mark='' if @md.opt.act[:maintenance][:set]==:on instruct=%{\n# the book index should be attached unwrapped to the preceding text block } \ + %{(there should be a new line, but no empty line)} s_mark="\n# " + %{"\\n#{mark}\\n\\n"} end d='book-idx' desc="#{d}#{s_mark}#{instruct}" orig=pot_structure.idx_markup(dob_src.idx) #'={' + dob_src.idx + '}' trans=if defined? dob_trn.idx \ and not dob_trn.idx.nil? \ and not dob_trn.idx.empty? pot_structure.idx_markup(dob_trn.idx) #'={' + dob_trn.idx + '}' else '' end util=pot_structure_wrap(desc,orig,trans) unwrapped=util.no_line_wrap_block @pot[:body] << unwrapped << br end self end def pot_markup(data_src,data_trn) #@endnotes,@copen,@pot_contents_close=Array.new(3){[]} a_l=if data_trn a_l=(data_src.length >= data_trn.length) \ ? data_src.length : data_trn.length else data_src.length end s,t=0,0 if @md.fns =~ /\.(?:(?:-|ssm\.)?sst|ssm)$/ (data_trn.nil?) \ ? pot_metadata_src : pot_metadata_src_trn end 0.upto(a_l-1) do |i| if data_trn unless data_src[s] \ and data_trn[t] break end if data_src[s].of == :comment \ and data_trn[t].of == :comment \ and (data_src[s].is == data_trn[t].is) s+=1;t+=1 next end if ((data_src[s].is == :comment) \ || (data_trn[t].is == :comment)) \ and (data_src[s].is != data_trn[t].is) if data_src[s].is == :comment if @md.opt.act[:maintenance][:set]==:on puts "src (comment):\n\t" \ + data_src[s].obj end s+=1 #next if data_src[s].is == :comment elsif data_trn[t].is == :comment if @md.opt.act[:maintenance][:set]==:on puts "trans (comment):\n\t" \ + data_trn[t].obj end t+=1 #next if data_trn[t].is == :comment end end if ((defined? data_src[s].ocn) \ && (data_src[s].ocn.is_a?(Fixnum))) \ and ((defined? data_trn[t].ocn) \ && (data_trn[t].ocn.is_a?(Fixnum))) \ and (data_src[s].ocn == data_trn[t].ocn) @m_s,@m_t=s,t elsif ((defined? data_src[s].ocn) \ && (data_src[s].ocn.is_a?(Fixnum))) \ and ((defined? data_trn[t].ocn) \ && (data_trn[t].ocn.is_a?(Fixnum))) \ and (data_src[s].ocn != data_trn[t].ocn) p '--- OCN ---' p 'mis-match' p data_src[s].ocn p data_src[s].obj p data_trn[t].ocn p data_trn[t].obj p '---' p 'previous match' p data_src[@m_s].ocn p data_src[@m_s].obj p data_trn[@m_t].ocn p data_trn[@m_t].obj exit elsif (((defined? data_src[s].ocn) \ && (defined? data_trn[t].ocn)) \ and data_src[s].ocn.class != data_trn[t].ocn.class) p '--- OCN class ---' p 'mis-match' p data_src[s].ocn if defined? data_src[s].ocn p data_src[s].obj p data_trn[t].ocn if defined? data_trn[t].ocn p data_trn[t].obj #p '---' #p 'previous match' #p data_src[@m_s].ocn #p data_src[@m_s].obj #p data_trn[@m_t].ocn #p data_trn[@m_t].obj #elsif (defined? data_src[s].ocn != defined? data_trn[t].ocn) \ #and (data_src[s].ocn.nil? != data_trn[t].ocn.nil?) # p '--- missing OCN? ---' # p 'mis-match' # p data_src[s].ocn if defined? data_src[s].ocn # p data_src[s].obj # p data_trn[t].ocn if defined? data_trn[t].ocn # p data_trn[t].obj else end end notes_s,notes_t='','' data_src[s],notes_s=markup(data_src[s]) if data_trn data_trn[t],notes_t=markup(data_trn[t]) #data_src[s],data_trn[t]=pot_data(data_src[s],notes_s,data_trn[t],notes_t) pot_data(data_src[s],notes_s,data_trn[t],notes_t) else #data_src[s],nul=pot_data(data_src[s],notes_s) pot_data(data_src[s],notes_s) end s+=1;t+=1 end @pot #watch end def pot_data(dob_src='',notes_s='',dob_trn='',notes_t='') if dob_src.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ if defined? dob_src.ocn \ and dob_src.ocn.to_s =~/\d+/ paranum=dob_src.ocn.to_s @p_num=SiSU_Po4aUtils::ParagraphNumber.new(paranum) end case dob_src.is when :heading pot_structure.heading(dob_src,notes_s,dob_trn,notes_t) when :para pot_structure.para(dob_src,notes_s,dob_trn,notes_t) when :group pot_structure.group(dob_src,notes_s,dob_trn,notes_t) when :block pot_structure.block(dob_src,notes_s,dob_trn,notes_t) when :verse pot_structure.verse(dob_src,notes_s,dob_trn,notes_t) when :code pot_structure.code(dob_src,notes_s,dob_trn,notes_t) when :table pot_structure.table(dob_src,notes_s,dob_trn,notes_t) end if defined? dob_src.idx \ and not dob_src.idx.nil? \ and not dob_src.idx.empty? pot_structure.idx(dob_src,dob_trn) end dob_src='' if (dob_src.obj =~/<a name="n\d+">/ \ and dob_src.obj =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/) # -endnote if dob_src ## Clean Prepared Text dob_src.obj=dob_src.obj.gsub(/<!.+!>/,' '). gsub(/<:\S+>/,' ') if dob_src ## Clean Prepared Text end end #[dob_src,dob_trn] end def markup(dob) dob,notes=objects.textface_marks_po4a(dob,:separate) [dob,notes] end def publish(fn,pot) content=[] content << pot[:open] content << pot[:head] content << pot[:metadata] content << pot[:body] content << @@endnotes[:end] if @@endnotes_ Output.new(fn,content,@md,@process).po4a @@endnotes={ para: [], end: [] } end end class Po4aCfg include SiSU_Composite_Doc_Utils # composite doc, .ssm, extract all related insert files, array of filenames test def initialize(opt,file) @opt,@file=opt,file end def po4a_cfg_filename 'po4a.cfg' end def dir def pwd Dir.pwd end def po4a_ 'po4a/' # '' end def pot po4a_ + 'pot' end def po po4a_ + 'po' end self end def po4a_cfg_file File.open("#{Dir.pwd}/#{po4a_cfg_filename}",'w') end def language def sisu_languages_available Px[:lng_lst] end def translation_languages_selected @opt.act[:po4a_lang_trans][:trn] \ ? @opt.act[:po4a_lang_trans][:trn] : [] end def translation_languages_selected_that_are_available translation_languages_selected & sisu_languages_available end def source_language_selected_str @opt.act[:po4a_lang_trans][:src] \ ? @opt.act[:po4a_lang_trans][:src] : 'en' end def translation_languages_selected_that_are_available_str translation_languages_selected_that_are_available.join(' ') end def translation_languages_selected_str @opt.act[:po4a_lang_trans][:trn].join(' ') end self end def po4a_cfg doc_import_list=composite_and_imported_filenames_array(@opt.fno) po4a_cfg_arr=[] po4a_cfg_arr \ << "[po4a_langs] #{language.translation_languages_selected_that_are_available_str}" po4a_cfg_arr \ << "[po4a_paths] #{dir.pot}/$master.pot $lang:#{dir.po}/$lang/$master.po" doc_import_list.each do |file_src| file_src_fn= file_src.gsub(/#{language.source_language_selected_str}\//,'') po4a_cfg_arr \ << "[type: text] #{file_src} $lang:$lang/#{file_src_fn}" end file=@file.write_file.po4a_cfg po4a_cfg_arr.each do |txt| puts txt file << txt << "\n" end file.close end end class Output <Source include SiSU_Param include SiSU_Env def initialize(fn,content,md,process=:complete) @fn,@content,@md,@process=fn,content,md,process @file=SiSU_Env::FileOp.new(md,fn) end def po4a #%pot output file_pot=(@md.opt.f_pth[:lng] == @md.opt.lng_base) \ ? @file.write_file.pot : @file.write_file.po @sisu=[] emptyline=0 @content.each do |para| # this is a hack if para.is_a?(Array) \ and para.length > 0 para.each do |line| if line line=line.gsub(/\s+$/m,''). gsub(/^\A[ ]*\Z/m,'') if line=~/^\A[ ]*\Z/m emptyline+=1 else emptyline=0 end file_pot.puts line if emptyline < 2 #remove extra line spaces (fix upstream) end end else file_pot.puts para #unix plaintext # /^([*=-]|\.){5}/ end end file_pot.close SiSU_Po4aUtils::PotNumber.new.reset po4a_git end def po4a_git unless @md.opt.act[:maintenance][:set]==:on require_relative 'git' # git.rb git=SiSU_Git::Source.new(@md.opt,@process) unless FileTest.directory?(@file.output_path.pot_git.dir) git.create_file_structure_git end if @md.opt.f_pth[:lng] == @md.opt.lng_base FileUtils::cp( @file.place_file.pot.dir, @file.output_path.pot_git.dir ) else # naive, work on --> FileUtils::cp( @file.place_file.po.dir, @file.output_path.po_git.dir ) #unless FileTest.file?(@file.place_file.po_git.dir) end git.read end end end end end __END__ !\|#\|&*\|-\|/\|_\|{\|}\|~\|&# tables are problematic, difficult to reconstitute instruction, check metadata, move to top? and work on footnotes, different types, asterisk, also do you want to have separate paragraphs, or breaks within one block? where no ocn appropriately use ~# or -# or indeed 1~name- comments in document, what to do about them, not sure they are currently retained in dal, could be quite valuable to keep Translate Shell http://www.soimort.org/translate-shell/ translate.google.com