From ee1ba8addad2c2d5cc4a5d5940eb7c310ef4d10b Mon Sep 17 00:00:00 2001 From: Alexey Morozov Date: Tue, 12 Dec 2023 13:57:58 +0100 Subject: [PATCH] Integrate vectory --- .gitignore | 1 + isodoc.gemspec | 2 +- lib/isodoc.rb | 1 + lib/isodoc/presentation_function/image.rb | 114 +++++-------- spec/assets/img.eps | 199 ++++++++++++++++++++++ spec/isodoc/figures_spec.rb | 30 ---- spec/isodoc/presentation_xml_spec.rb | 45 ++++- 7 files changed, 281 insertions(+), 111 deletions(-) create mode 100644 .gitignore create mode 100644 spec/assets/img.eps diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..75537078 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +spec/assets/img.svg diff --git a/isodoc.gemspec b/isodoc.gemspec index 628069c1..8555252d 100644 --- a/isodoc.gemspec +++ b/isodoc.gemspec @@ -31,7 +31,6 @@ Gem::Specification.new do |spec| spec.add_dependency "html2doc", "~> 1.7.1" spec.add_dependency "htmlentities", "~> 4.3.4" # spec.add_dependency "isodoc-i18n", "~> 1.1.0" # already in relaton-render and mn-requirements - spec.add_dependency "emf2svg" spec.add_dependency "liquid", "~> 5" #spec.add_dependency "relaton-cli" # spec.add_dependency "metanorma-utils", "~> 1.5.0" # already in isodoc-i18n @@ -44,6 +43,7 @@ Gem::Specification.new do |spec| spec.add_dependency "thread_safe" spec.add_dependency "twitter_cldr", ">= 6.6.0" spec.add_dependency "uuidtools" + spec.add_dependency "vectory", "~> 0.5" spec.add_development_dependency "debug" spec.add_development_dependency "equivalent-xml", "~> 0.6" diff --git a/lib/isodoc.rb b/lib/isodoc.rb index cb32be2e..131bc964 100644 --- a/lib/isodoc.rb +++ b/lib/isodoc.rb @@ -10,6 +10,7 @@ require "liquid" require "htmlentities" require "relaton-render" +require "vectory" require "isodoc/common" require "isodoc/convert" diff --git a/lib/isodoc/presentation_function/image.rb b/lib/isodoc/presentation_function/image.rb index 1c8e6313..37259b66 100644 --- a/lib/isodoc/presentation_function/image.rb +++ b/lib/isodoc/presentation_function/image.rb @@ -1,5 +1,4 @@ require "base64" -require "emf2svg" module IsoDoc class PresentationXMLConvert < ::IsoDoc::Convert @@ -92,33 +91,56 @@ def emf_encode(img) def svg_prep(img) img["mimetype"] = "image/svg+xml" - %r{^data:image}.match?(img["src"]) or - img["src"] = Metanorma::Utils::datauri(img["src"]) + %r{^data:}.match?(img["src"]) or + img["src"] = Vectory::Emf.from_path(img["src"]).to_uri.content end def emf_to_svg(img) - emf = Metanorma::Utils::save_dataimage(img.at(ns("./emf/@src")).text) - Emf2svg.from_file(emf).sub(/<\?[^>]+>/, "") + datauri_src = img.at(ns("./emf/@src")).text + Vectory::Emf.from_datauri(datauri_src) + .to_svg + .content + .sub(/<\?[^>]+>/, "") end def eps_to_svg(node) - uri = eps_to_svg_uri(node) - ret = imgfile_suffix(uri, "svg") - File.exist?(ret) and return ret - inkscape_convert(uri, ret, "--export-plain-svg") + if !node.text.strip.empty? || %r{^data:}.match?(node["src"]) + return eps_to_svg_from_node(node) + end + + target_path = imgfile_suffix(node["src"], "svg") + return target_path if File.exist?(target_path) + + eps_to_svg_from_node(node, target_path) + end + + def eps_to_svg_from_node(node, target_path = nil) + svg = Vectory::Eps.from_node(node).to_svg + return svg.write(target_path).path if target_path + + svg.write.path end def svg_to_emf(node) @output_formats[:doc] or return - uri = svg_to_emf_uri(node) + svg_impose_height_attr(node) - ret = imgfile_suffix(uri, "emf") - if File.exist?(ret) && File.exist?(node["src"]) - warn "Exists: #{ret}, Exists: #{node['src']}" - return ret + + if node.elements&.first&.name == "svg" || %r{^data:}.match?(node["src"]) + return svg_to_emf_from_node(node) end - warn "Converting..." - inkscape_convert(uri, ret, '--export-type="emf"') + + target_path = imgfile_suffix(node["src"], "emf") + return target_path if File.exist?(target_path) + + svg_to_emf_from_node(node, target_path) + end + + def svg_to_emf_from_node(node, target_path = nil) + emf = Vectory::Svg.from_node(node).to_emf + return emf.write(target_path).to_uri.content if target_path + + emf.to_uri.content end def svg_impose_height_attr(node) @@ -129,68 +151,8 @@ def svg_impose_height_attr(node) node["width"] = e["width"] end - def inkscape_convert(uri, file, option) - exe = inkscape_installed? or raise "Inkscape missing in PATH, unable" \ - "to convert image #{uri}. Aborting." - uri = Metanorma::Utils::external_path uri - exe = Metanorma::Utils::external_path exe - warn %(#{exe} #{option} #{uri}) - err = system %(#{exe} #{option} #{uri}) - File.exist?(file) and return Metanorma::Utils::datauri(file) - file2 = uri + File.extname(file) - warn "Checking #{file2}" - File.exist?(file2) and return Metanorma::Utils::datauri(file2) - raise %(Fail on #{exe} #{option} #{uri} outputting #{file}: status #{err}) - end - - def svg_to_emf_uri(node) - uri = svg_to_emf_uri_convert(node) - cache_dataimage(uri) - end - - def eps_to_svg_uri(node) - uri = eps_to_svg_uri_convert(node) - cache_dataimage(uri) - end - - def cache_dataimage(uri) - if %r{^data:}.match?(uri) - uri = save_dataimage(uri) - end - uri - end - - def svg_to_emf_uri_convert(node) - if node.elements&.first&.name == "svg" - a = Base64.strict_encode64(node.children.to_xml) - "data:image/svg+xml;base64,#{a}" - else node["src"] - end - end - - def eps_to_svg_uri_convert(node) - if node.text.strip.empty? - node["src"] - else - a = Base64.strict_encode64(node.children.to_xml) - "data:application/postscript;base64,#{a}" - end - end - def imgfile_suffix(uri, suffix) "#{File.join(File.dirname(uri), File.basename(uri, '.*'))}.#{suffix}" end - - def inkscape_installed? - cmd = "inkscape" - exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""] - ENV["PATH"].split(File::PATH_SEPARATOR).each do |path| - exts.each do |ext| - exe = File.join(path, "#{cmd}#{ext}") - return exe if File.executable?(exe) && !File.directory?(exe) - end - end - nil - end end end diff --git a/spec/assets/img.eps b/spec/assets/img.eps new file mode 100644 index 00000000..7d13e00e --- /dev/null +++ b/spec/assets/img.eps @@ -0,0 +1,199 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Document-Fonts: Times-Roman +%%Title: circle.eps +%%Creator: PS_Write.F +%%CreationDate: 02-Aug-99 +%%Pages: 1 +%%BoundingBox: 36 36 576 756 +%%LanguageLevel: 1 +%%EndComments +%%BeginProlog +%%EndProlog +/inch {72 mul} def +/Palatino-Roman findfont +1.00 inch scalefont +setfont + 0.0000 0.0000 0.0000 setrgbcolor +%% Page: 1 1 +save + 63 153 moveto + newpath + 63 153 moveto + 549 153 lineto + stroke + newpath + 549 153 moveto + 549 639 lineto + stroke + newpath + 549 639 moveto + 63 639 lineto + stroke + newpath + 63 639 moveto + 63 153 lineto + stroke + newpath + 360 261 108 0 360 arc + closepath stroke + newpath + 361 357 moveto + 358 358 lineto + 353 356 lineto + 348 353 lineto + 342 347 lineto + 336 340 lineto + 329 331 lineto + 322 321 lineto + 315 309 lineto + 307 296 lineto + 300 283 lineto + 292 268 lineto + 285 253 lineto + 278 237 lineto + 271 222 lineto + 266 206 lineto + 260 191 lineto + 256 177 lineto + 252 164 lineto + 249 152 lineto + 247 141 lineto + 246 131 lineto + 246 123 lineto + 247 117 lineto + 248 113 lineto + 251 111 lineto + 254 110 lineto + 259 112 lineto + 264 115 lineto + 270 121 lineto + 276 128 lineto + 283 137 lineto + 290 147 lineto + 297 159 lineto + 305 172 lineto + 312 185 lineto + 320 200 lineto + 327 215 lineto + 334 231 lineto + 341 246 lineto + 346 262 lineto + 352 277 lineto + 356 291 lineto + 360 304 lineto + 363 316 lineto + 365 327 lineto + 366 337 lineto + 366 345 lineto + 365 351 lineto + 364 355 lineto + 361 357 lineto + stroke + newpath + 171 261 moveto + 171 531 lineto + stroke + newpath + 198 261 moveto + 198 531 lineto + stroke + newpath + 225 261 moveto + 225 531 lineto + stroke + newpath + 252 261 moveto + 252 531 lineto + stroke + newpath + 279 261 moveto + 279 531 lineto + stroke + newpath + 306 261 moveto + 306 531 lineto + stroke + newpath + 333 261 moveto + 333 531 lineto + stroke + newpath + 360 261 moveto + 360 531 lineto + stroke + newpath + 387 261 moveto + 387 531 lineto + stroke + newpath + 414 261 moveto + 414 531 lineto + stroke + newpath + 441 261 moveto + 441 531 lineto + stroke + newpath + 171 261 moveto + 441 261 lineto + stroke + newpath + 171 288 moveto + 441 288 lineto + stroke + newpath + 171 315 moveto + 441 315 lineto + stroke + newpath + 171 342 moveto + 441 342 lineto + stroke + newpath + 171 369 moveto + 441 369 lineto + stroke + newpath + 171 396 moveto + 441 396 lineto + stroke + newpath + 171 423 moveto + 441 423 lineto + stroke + newpath + 171 450 moveto + 441 450 lineto + stroke + newpath + 171 477 moveto + 441 477 lineto + stroke + newpath + 171 504 moveto + 441 504 lineto + stroke + newpath + 171 531 moveto + 441 531 lineto + stroke + newpath + 306 396 5 0 360 arc + closepath stroke + 0.0000 1.0000 0.0000 setrgbcolor + newpath + 387 477 54 0 90 arc + stroke + 171 261 moveto + 0.0000 0.0000 0.0000 setrgbcolor +/Palatino-Roman findfont + 0.250 inch scalefont +setfont +(This is "circle.plot".) show + 171 342 moveto +/Palatino-Roman findfont + 0.125 inch scalefont +setfont +(This is small print.) show +restore showpage +%%Trailer diff --git a/spec/isodoc/figures_spec.rb b/spec/isodoc/figures_spec.rb index 1702021e..3023b236 100644 --- a/spec/isodoc/figures_spec.rb +++ b/spec/isodoc/figures_spec.rb @@ -681,36 +681,6 @@ .to be_equivalent_to strip_guid(xmlpp(word)) end - context "disable inkscape" do - it "converts SVG (Word) with inkscape disabled" do - FileUtils.rm_rf "spec/assets/odf1.emf" - allow(IsoDoc::PresentationXMLConvert) - .to receive(:inkscape_installed?).and_return(nil) - allow_any_instance_of(IsoDoc::PresentationXMLConvert) - .to receive(:inkscape_installed?) - - input = <<~INPUT - - - -
- - - -
-
-
-
- INPUT - expect do - IsoDoc::PresentationXMLConvert - .new(presxml_options.merge(output_formats: { html: "html", doc: "doc" })) - .convert("test", input, true) - end.to raise_error("Inkscape missing in PATH, unable" \ - "to convert image spec/assets/odf1.svg. Aborting.") - end - end - it "does not label embedded figures, sourcecode" do input = <<~INPUT diff --git a/spec/isodoc/presentation_xml_spec.rb b/spec/isodoc/presentation_xml_spec.rb index 731eb317..14b44f4d 100644 --- a/spec/isodoc/presentation_xml_spec.rb +++ b/spec/isodoc/presentation_xml_spec.rb @@ -403,7 +403,7 @@ '"data:image/emf;base64"') .gsub(%r{"data:application/x-msmetafile;base64,[^"]+"}, '"data:application/x-msmetafile;base64"')))) - .to be_equivalent_to (output) + .to be_equivalent_to (xmlpp(output)) output = <<~OUTPUT @@ -464,7 +464,7 @@ .to be_equivalent_to (output) end - xit "converts EPS to SVG files" do + it "converts EPS to SVG files" do input = <<~INPUT @@ -678,14 +678,15 @@ INPUT output = <<~OUTPUT - + + Table of contents 1.<tab/>Clause
Figure 1 - 3 + 3
@@ -699,6 +700,42 @@ .to be_equivalent_to (output) end + it "converts file EPS to SVG" do + input = <<~INPUT + + + + + Clause +
+ 3 +
+
+
+
+ INPUT + output = <<~OUTPUT + + + + Table of contents + + + 1.<tab/>Clause +
Figure 1 + 3 +
+
+
+
+ OUTPUT + expect(xmlpp(strip_guid(IsoDoc::PresentationXMLConvert.new(presxml_options) + .convert("test", input, true) + .sub(%r{.*}m, "") + .gsub(%r{src="[^"]+?\.svg"}, 'src="_.svg"')))) + .to be_equivalent_to(output) + end + it "adds types to ordered lists" do input = <<~INPUT