c&d: small fixes
[software/sisu] / lib / sisu / develop / shared_markup_alt.rb
1 # encoding: utf-8
2 =begin
3
4 * Name: SiSU
5
6 ** Description: documents, structuring, processing, publishing, search
7 *** system environment, resource control and configuration details
8
9 ** Author: Ralph Amissah
10 <ralph@amissah.com>
11 <ralph.amissah@gmail.com>
12
13 ** Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
14 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Ralph Amissah,
15 All Rights Reserved.
16
17 ** License: GPL 3 or later:
18
19 SiSU, a framework for document structuring, publishing and search
20
21 Copyright (C) Ralph Amissah
22
23 This program is free software: you can redistribute it and/or modify it
24 under the terms of the GNU General Public License as published by the Free
25 Software Foundation, either version 3 of the License, or (at your option)
26 any later version.
27
28 This program is distributed in the hope that it will be useful, but WITHOUT
29 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
30 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
31 more details.
32
33 You should have received a copy of the GNU General Public License along with
34 this program. If not, see <http://www.gnu.org/licenses/>.
35
36 If you have Internet connection, the latest version of the GPL should be
37 available at these locations:
38 <http://www.fsf.org/licensing/licenses/gpl.html>
39 <http://www.gnu.org/licenses/gpl.html>
40
41 <http://www.sisudoc.org/sisu/en/manifest/gpl.fsf.html>
42
43 ** SiSU uses:
44 * Standard SiSU markup syntax,
45 * Standard SiSU meta-markup syntax, and the
46 * Standard SiSU object citation numbering and system
47
48 ** Hompages:
49 <http://www.jus.uio.no/sisu>
50 <http://www.sisudoc.org>
51
52 ** Git
53 <http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=summary>
54 <http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=blob;f=lib/sisu/develop/shared_markup_alt.rb;hb=HEAD>
55
56 =end
57 module SiSU_TextRepresentation
58 class Alter
59 def initialize(x)
60 if x.is_a?(String)
61 @t_o,@s=nil,x
62 else
63 @t_o,@s=x,x.obj.dup
64 end
65 end
66 def strip_clean_of_extra_spaces # dal output tuned
67 @s=@s.dup
68 @s=@s.gsub(/[ ]+([,.;:?](?:$|\s))/,'\1') unless @s =~/#{Mx[:en_a_o]}|#{Mx[:en_b_o]}/
69 @s=@s.gsub(/ [ ]+/,' ').
70 gsub(/^ [ ]+/,'').
71 gsub(/ [ ]+$/,'').
72 gsub(/((?:#{Mx[:fa_bold_c]}|#{Mx[:fa_italics_c]})')[ ]+(s )/,'\1\2').
73 gsub(/((?:#{Mx[:fa_bold_c]}|#{Mx[:fa_italics_c]})')[ ]+(s )/,'\1\2')
74 end
75 def strip_clean_of_markup # text form used in sql db search, used for digest, define rules, make same as in db clean
76 @s=@s.dup #% same as db clean -->
77 @s=@s.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'\1').
78 gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'\1').
79 gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'\1').
80 gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'\1').
81 gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'\1').
82 gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'\1').
83 gsub(/#{Mx[:fa_superscript_o]}(\d+)#{Mx[:fa_superscript_c]}/,'[\1]').
84 gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'\1').
85 gsub(/#{Mx[:fa_hilite_o]}(.+?)#{Mx[:fa_hilite_c]}/,'\1').
86 gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/i,'~').
87 gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,''). # endnote removed
88 gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,''). # endnote removed
89 gsub(/(?:#{Mx[:nbsp]})+/,' ').
90 gsub(/(?:#{Mx[:br_nl]})+/,"\n").
91 gsub(/(?:#{Mx[:br_paragraph]})+/,"\n").
92 gsub(/(?:#{Mx[:br_line]})+/,"\n").
93 gsub(/#{Mx[:gl_o]}(?:#lt|#060)#{Mx[:gl_c]}/,'<').
94 gsub(/#{Mx[:gl_o]}(?:#gt|#062)#{Mx[:gl_c]}/,'>').
95 gsub(/#{Mx[:gl_o]}#(?:038|amp)#{Mx[:gl_c]}/,'&').
96 gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!').
97 gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#').
98 gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*').
99 gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-').
100 gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/').
101 gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_').
102 gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{').
103 gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}').
104 gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~').
105 gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©').
106 gsub(/\s\s+/,' ').
107 gsub(/\s\s+/,' ').
108 strip
109 end
110 def semi_revert_markup # used for digest, define rules, make same as in db clean
111 if @t_o
112 @s=@s.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'*{\1}*').
113 gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'/{\1}/').
114 gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'_{\1}_').
115 gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'"{\1}"').
116 gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'+{\1}+').
117 gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strke_c]}/,'-{\1}-').
118 gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'^{\1}^').
119 gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,',{\1},').
120 gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/i,'~').
121 gsub(/#{Mx[:en_a_o]}([\d*+]+\s+.+?)#{Mx[:en_a_c]}/,'~{\1}~'). # endnote marker marked up
122 gsub(/#{Mx[:en_b_o]}([\d*+]+\s+.+?)#{Mx[:en_b_c]}/,'~[\1]~') # endnote marker marked up
123 if @t_o.is==:heading \
124 || @t_o.is==:para
125 @s=@s.gsub(/ [ ]+/,' ')
126 @s=@s.gsub(/(?:#{Mx[:nbsp]})+/,' ')
127 if @t_o.is==:heading
128 @s=@t_o.lv + '~ ' + @s
129 end
130 if @t_o.is==:para
131 if @t_o.bullet_
132 @s='_* ' + @s
133 end
134 if @t_o.indent.to_i > 0
135 @s="_#{@t_o.indent} " + @s
136 @s=@s.gsub(/^(_[1-9])\s_\*\s/,'\1* ')
137 end
138 end
139 end
140 if @t_o.is==:block \
141 || @t_o.is==:group \
142 || @t_o.is==:code
143 @s=@s.gsub(/#{Mx[:nbsp]}/,' ')
144 @s="#{@t_o.is.to_s}{\n\n#{@s}\n\n}#{@t_o.is.to_s}"
145 @s=@s.gsub(/(?:#{Mx[:br_nl]}|\n)+/m,"\n\n")
146 end
147 #dealing with poem and verse calls for change in dal, where start and end verse of poem are marked as such
148 @s=@s.strip
149 end
150 @s
151 end
152 def html_lite #test whether eventually can be used in db_import replacing shared_html_lite (search for SiSU_FormatShared)
153 if @t_o
154 @s=@s.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>').
155 gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>').
156 gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>').
157 gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'"\1"').
158 gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'+{\1}+').
159 gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strke_c]}/,'-{\1}-').
160 gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>').
161 gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>').
162 gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/i,'~')
163 if @t_o.is !=:code
164 if @s =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/
165 wm=@s.scan(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)|\S+/)
166 words=urls(wm)
167 @s=@s.gsub(/.+/m,words)
168 end
169 @s=@s.gsub(/#{Mx[:gl_o]}(#[0-9]{3})#{Mx[:gl_c]}/u,'&\1;').
170 gsub(/#{Mx[:gl_o]}#([a-z]{2,4})#{Mx[:gl_c]}/u,'&\1;').
171 gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'<a href="\1" target="_top">\1</a>'). #http ftp matches escaped, no decoration
172 gsub(/(#{Mx[:lnk_c]})#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1<a href="\2" target="_top">\2</a>\3'). #special case \{ e.g. \}http://url
173 gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,%{#{@url_brace.xml_open}<a href="\\1" target="_top">\\1</a>#{@url_brace.xml_close}}) #http ftp matches with decoration
174 else
175 @s=@s.gsub(/</m,'&lt;').gsub(/>/m,'&gt;')
176 end
177 if @t_o.is==:paragraph
178 if @t_o.bullet_
179 @s=@s
180 end
181 if @t_o.indent > 0
182 @s=@s
183 end
184 end
185 if @t_o.is==:heading
186 @s=@s
187 end
188 else
189 p __FILE__ << ':' << __LINE__.to_s
190 end
191 @s
192 end
193 end
194 class ModifiedTextPlusHashDigest
195 def initialize(md,x)
196 @md=md
197 if x.is_a?(String)
198 @t_o,@s=nil,x
199 else
200 @t_o,@s=x,x.obj.dup
201 end
202 @env ||=SiSU_Env::InfoEnv.new(@md.fns)
203 @sha_ = @env.digest(@md.opt).type
204 begin
205 case @sha_
206 when :sha512
207 require 'digest/sha2'
208 when :sha256
209 require 'digest/sha2'
210 when :md5
211 require 'digest/md5'
212 end
213 rescue LoadError
214 SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).error((@sha_ ? 'digest/sha2' : 'digest/md5') + ' NOT FOUND')
215 end
216 end
217 def digest(txt)
218 d=nil
219 case @sha_
220 when :sha512
221 for hash_class in [ Digest::SHA512 ]
222 d=hash_class.hexdigest(txt)
223 end
224 when :sha256
225 for hash_class in [ Digest::SHA256 ]
226 d=hash_class.hexdigest(txt)
227 end
228 when :md5
229 for hash_class in [ Digest::MD5 ]
230 d=hash_class.hexdigest(txt)
231 end
232 end
233 d
234 end
235 def strip_clean_of_markup
236 def txt
237 SiSU_TextRepresentation::Alter.new(@s).strip_clean_of_markup
238 end
239 def dgst
240 txt_dgst=digest(txt)
241 { txt: txt, dgst_txt: txt_dgst }
242 end
243 self
244 end
245 def semi_revert_markup
246 def txt
247 SiSU_TextRepresentation::Alter.new(@s).semi_revert_markup
248 end
249 def dgst
250 txt_dgst=digest(txt)
251 { txt: txt, dgst_txt: txt_dgst }
252 end
253 self
254 end
255 def composite
256 def stripped_clean(txt)
257 SiSU_TextRepresentation::Alter.new(txt).strip_clean_of_markup
258 end
259 def markup_reverted(txt)
260 SiSU_TextRepresentation::Alter.new(txt).semi_revert_markup
261 end
262 def images(imgs)
263 sys=SiSU_Env::SystemCall.new
264 line_image=[]
265 if imgs and imgs.length > 0
266 @image_name,@image_dgst,@img=[],[],[]
267 imgs.each do |i|
268 image_source=if FileTest.file?("#{@env.path.image_source_include_local}/#{i}")
269 @env.path.image_source_include_local
270 elsif FileTest.file?("#{@env.path.image_source_include_remote}/#{i}")
271 @env.path.image_source_include_remote
272 elsif FileTest.file?("#{@env.path.image_source_include}/#{i}")
273 @env.path.image_source_include
274 else
275 SiSU_Screen::Ansi.new(
276 @md.opt.act[:color_state][:set],
277 "ERROR - image:",
278 %{"#{i}" missing},
279 "search locations: #{@env.path.image_source_include_local}, #{@env.path.image_source_include_remote} and #{@env.path.image_source_include}"
280 ).error2 unless @md.opt.act[:quiet][:set]==:on
281 nil
282 end
283 img_type = /\S+\.(png|jpg|gif)/.match(i)[1]
284 if image_source
285 para_image = image_source + '/' + i
286 image_name = i
287 image_dgst =(@sha_ ? sys.sha256(para_image) : sys.md5(para_image))
288 else
289 image_name = i + ' [image missing]'
290 image_dgst = ''
291 end
292 line_image << { img_dgst: image_dgst[1], img_name: image_name, img_type: img_type }
293 end
294 end
295 line_image
296 end
297 def endnotes(en)
298 en_dgst=[]
299 if en and en.length > 0
300 en.flatten.each do |e|
301 note_no=e.gsub(/^([\d*+]+)\s+.+/,'\1')
302 e=digest(stripped_clean(e))
303 note_dgst=digest(e)
304 en_dgst << { note_number: note_no, note_dgst: note_dgst }
305 end
306 end
307 en_dgst
308 end
309 def dgst
310 if @t_o.of !=:comment \
311 && @t_o.of !=:structure \
312 && @t_o.of !=:layout
313 txt_stripped_dgst=digest(stripped_clean(@t_o))
314 txt_markup_reverted_dgst=digest(markup_reverted(@t_o))
315 endnotes_dgst=[]
316 rgx_notes=/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+\s+.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/
317 notes=@t_o.obj.scan(rgx_notes)
318 endnotes_dgst=endnotes(notes)
319 rgx_image=/#{Mx[:lnk_o]}(\S+\.(?:png|jpg|gif))\s.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/
320 imgs=if (@t_o.is==:para \
321 || @t_o.is==:image) \
322 and @t_o.obj =~rgx_image
323 imgs=@t_o.obj.scan(rgx_image).flatten
324 line_image=images(imgs)
325 end
326 dgst={ is: @t_o.is, ocn: @t_o.ocn, dgst_stripped_txt: txt_stripped_dgst, dgst_markedup_txt: txt_markup_reverted_dgst }
327 dgst[:endnotes]=endnotes_dgst if endnotes_dgst and endnotes_dgst.length > 0
328 dgst[:images]=line_image if line_image and line_image.length > 0
329 end
330 dgst
331 end
332 self
333 end
334 end
335 end
336 __END__