Skip to content

Commit

Permalink
refactor passthrough as XML preprocessing, process formats=all: metan…
Browse files Browse the repository at this point in the history
  • Loading branch information
opoudjis committed Nov 13, 2023
1 parent 2afe2bd commit 54b65b4
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 24 deletions.
2 changes: 1 addition & 1 deletion lib/isodoc/convert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def preprocess_xslt(docxml)
docxml = Nokogiri::XSLT(x).transform(docxml)
end
docxml
rescue
rescue ::Error => e
require "debug"; binding.b
end

Expand Down
43 changes: 37 additions & 6 deletions lib/isodoc/presentation_function/bibdata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,48 @@ def bibdata(docxml)

def extension_insert(docxml, path = [])
ins = docxml.at(ns("//metanorma-extension")) ||
docxml.at(ns("//bibdata")).after("<metanorma-extension/>").next_element
docxml.at(ns("//bibdata"))&.after("<metanorma-extension/>")&.next_element ||
docxml.root.elements.first.before("<metanorma-extension/>").previous_element
path.each do |n|
ins = ins.at(ns("./#{n}")) || ins.add_child("<#{n}/>").first
end
ins
end

def preprocess_xslt_insert(docxml)
content = preprocess_xslt_read or return
content = ""
p = passthrough_xslt and content += p
p = preprocess_xslt_read and content += File.read(p)
content.empty? and return
ins = extension_insert(docxml, %w(render))
ins << File.read(content)
ins << content
end

def passthrough_xslt
@output_formats.nil? and return nil
@output_formats.empty? and return nil
@output_formats.each_key.with_object([]) do |k, m|
m << <<~XSLT
<preprocess-xslt format="#{k}">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name() = 'passthrough']">
<xsl:if test="contains(@formats,',#{k},')"> <!-- delimited -->
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
</preprocess-xslt>
XSLT
end.join("\n")
end

# read in from file, but with `<preprocess-xslt @format="">` wrapper
Expand All @@ -45,7 +76,7 @@ def toc_metadata(docxml)
ins << "<toc type='table'><title>#{@i18n.toc_tables}</title></toc>"
@tocfigures and
ins << "<toc type='recommendation'><title>#{@i18n.toc_recommendations}" \
"</title></toc>"
"</title></toc>"
end

def address_precompose(bib)
Expand Down Expand Up @@ -152,8 +183,8 @@ def i8n_name(hash, pref)
when Array
hash.reject { |a| blank?(a) }.each_with_object([])
.with_index do |(v1, g), i|
i8n_name(v1, "#{i18n_safe(k)}.#{i}").each { |x| g << x }
end
i8n_name(v1, "#{i18n_safe(k)}.#{i}").each { |x| g << x }

Check warning on line 186 in lib/isodoc/presentation_function/bibdata.rb

View check run for this annotation

Codecov / codecov/patch

lib/isodoc/presentation_function/bibdata.rb#L186

Added line #L186 was not covered by tests
end
else [i18n_tag(pref, hash)]
end
end
Expand Down
21 changes: 18 additions & 3 deletions lib/isodoc/presentation_function/inline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,29 @@ def custom_charset(docxml)
end
end

def passthrough(docxml)
formats = @output_formats.keys
docxml.xpath(ns("//passthrough")).each do |p|
passthrough1(p, formats)
end
end

def passthrough1(elem, formats)
(elem["formats"] && !elem["formats"].empty?) or elem["formats"] = "all"
f = elem["formats"].split(",")
(f - formats).size == f.size or elem["formats"] = "all"
elem["formats"] == "all" and elem["formats"] = formats.join(",")
elem["formats"] = ",#{elem['formats']},"
end

private

def extract_custom_charsets(docxml)
docxml.xpath(ns("//presentation-metadata/custom-charset-font")).
each_with_object({}) do |x, m|
kv = x.text.split(":", 2)
m[kv[0]] = kv[1]
end
kv = x.text.split(":", 2)
m[kv[0]] = kv[1]
end
end

def found_matching_variant_sibling(node)
Expand Down
1 change: 1 addition & 0 deletions lib/isodoc/presentation_xml_convert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def inline(docxml)
variant docxml
identifier docxml
date docxml
passthrough docxml
inline_format docxml
end

Expand Down
21 changes: 15 additions & 6 deletions spec/isodoc/blocks_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1812,13 +1812,17 @@

it "processes passthrough with compatible format" do
FileUtils.rm_f "test.html"
IsoDoc::HtmlConvert.new({}).convert("test", <<~INPUT, false)
input = <<~INPUT
<iso-standard xmlns="http://riboseinc.com/isoxml">
<preface><foreword displayorder="1">
<preface><foreword>
<passthrough format="html,rfc">&lt;A&gt;</passthrough><em>Hello</em><passthrough format="html,rfc">&lt;/A&gt;</passthrough>
</foreword></preface>
</iso-standard>
INPUT
presxml = IsoDoc::PresentationXMLConvert
.new(presxml_options.merge(output_formats: { html: "html", rfc: "rfc" }))
.convert("test", input, true)
IsoDoc::HtmlConvert.new({}).convert("test", presxml, false)
expect(xmlpp(File.read("test.html")
.gsub(%r{^.*<h1 class="ForewordTitle">Foreword</h1>}m, "")
.gsub(%r{</div>.*}m, ""))).to be_equivalent_to xmlpp(<<~OUTPUT)
Expand All @@ -1832,14 +1836,17 @@
begin
input = <<~INPUT
<iso-standard xmlns="http://riboseinc.com/isoxml">
<preface><foreword displayorder="1">
<preface><foreword>
<passthrough format="html,rfc">&lt;A&gt;</passthrough><em>Hello</em>
</foreword></preface>
</iso-standard>
INPUT
presxml = IsoDoc::PresentationXMLConvert
.new(presxml_options.merge(output_formats: { html: "html", rfc: "rfc" }))
.convert("test", input, true)
expect do
IsoDoc::HtmlConvert.new({})
.convert("test", input, false)
.convert("test", presxml, false)
end.to raise_error(SystemExit)
rescue SystemExit
end
Expand Down Expand Up @@ -1868,8 +1875,11 @@
</body>
</html>
OUTPUT
presxml = IsoDoc::PresentationXMLConvert
.new(presxml_options.merge(output_formats: { html: "html", rfc: "rfc" }))
.convert("test", input, true)
expect(xmlpp(strip_guid(IsoDoc::HtmlConvert.new({})
.convert("test", input, true)))).to be_equivalent_to xmlpp(output)
.convert("test", presxml, true)))).to be_equivalent_to xmlpp(output)
end

it "ignores columnbreak" do
Expand All @@ -1881,7 +1891,6 @@
<columnbreak/>
</clause>
<foreword displayorder="2">
<passthrough format="doc,rfc">&lt;A&gt;</passthrough>
</foreword></preface>
</iso-standard>
INPUT
Expand Down
20 changes: 12 additions & 8 deletions spec/isodoc/figures_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -561,20 +561,22 @@
</html>
DOC

expect(strip_guid(xmlpp(IsoDoc::PresentationXMLConvert
output = IsoDoc::PresentationXMLConvert
.new(presxml_options.merge(output_formats: { html: "html", doc: "doc" }))
.convert("test", input, true)
expect(strip_guid(xmlpp(output
.gsub(/&lt;/, "&#x3c;")
.sub(%r{<metanorma-extension>.*</metanorma-extension}m, "")
.gsub(%r{data:image/emf;base64,[^"']+}, "data:image/emf;base64"))))
.to be_equivalent_to xmlpp(presxml
.gsub(%r{data:image/emf;base64,[^"']+}, "data:image/emf;base64"))
expect(xmlpp(strip_guid(IsoDoc::HtmlConvert.new({})
.convert("test", presxml, true)))).to be_equivalent_to xmlpp(html)
.convert("test", output, true)))).to be_equivalent_to strip_guid(xmlpp(html))
expect(xmlpp(strip_guid(IsoDoc::WordConvert.new({})
.convert("test", presxml, true)
.convert("test", output, true)
.gsub(/['"][^'".]+(?<!odf1)(?<!odf)\.emf['"]/, "'_.emf'")
.gsub(/['"][^'".]+\.(gif|xml)['"]/, "'_.\\1'"))))
.to be_equivalent_to xmlpp(doc)
.to be_equivalent_to strip_guid(xmlpp(doc))
end

it "converts SVG (Word)" do
Expand Down Expand Up @@ -619,7 +621,7 @@
</preface>
</iso-standard>
OUTPUT
output = <<~OUTPUT
word = <<~OUTPUT
<html xmlns:epub='http://www.idpf.org/2007/ops' lang='en'>
<head>
<style>
Expand Down Expand Up @@ -662,19 +664,21 @@
</body>
</html>
OUTPUT
expect(strip_guid(xmlpp(IsoDoc::PresentationXMLConvert
output = IsoDoc::PresentationXMLConvert
.new(presxml_options.merge(output_formats: { html: "html", doc: "doc" }))
.convert("test", input, true)
expect(strip_guid(xmlpp(output
.sub(%r{<metanorma-extension>.*</metanorma-extension}m, "")
.gsub(/&lt;/, "&#x3c;"))
.gsub(%r{data:image/emf;base64,[^"']+}, "data:image/emf;base64")))
.to be_equivalent_to xmlpp(presxml
.gsub(%r{data:image/emf;base64,[^"']+}, "data:image/emf;base64"))
expect(xmlpp(strip_guid(IsoDoc::WordConvert.new({})
.convert("test", presxml, true)
.convert("test", output, true)
.gsub(/['"][^'".]+(?<!odf1)(?<!odf)\.emf['"]/, "'_.emf'")
.gsub(/['"][^'".]+\.(gif|xml)['"]/, "'_.\\1'")
.gsub(/mso-bookmark:_Ref\d+/, "mso-bookmark:_Ref"))))
.to be_equivalent_to xmlpp(output)
.to be_equivalent_to strip_guid(xmlpp(word))
end

context "disable inkscape" do
Expand Down
79 changes: 79 additions & 0 deletions spec/isodoc/presentation_xml_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,7 @@
.new(presxml_options.merge(output_formats: { html: "html", doc: "doc" }))
.convert("test", input, true)
.sub(%r{<localized-strings>.*</localized-strings>}m, "")
.sub(%r{<metanorma-extension>.*</metanorma-extension>}m, "")
.gsub(%r{"data:image/emf;base64,[^"]+"},
'"data:image/emf;base64"')
.gsub(%r{"data:application/x-msmetafile;base64,[^"]+"},
Expand Down Expand Up @@ -789,6 +790,7 @@
.new(presxml_options.merge(output_formats: { html: "html" }))
.convert("test", input, true)
.sub(%r{<localized-strings>.*</localized-strings>}m, "")
.sub(%r{<metanorma-extension>.*</metanorma-extension>}m, "")
.gsub(%r{"data:image/emf;base64,[^"]+"},
'"data:image/emf;base64"')
.gsub(%r{"data:application/x-msmetafile;base64,[^"]+"},
Expand Down Expand Up @@ -1866,6 +1868,83 @@
.to be_equivalent_to (presxml)
end

it "supplies formats in passthrough" do
input = <<~INPUT
<standard-document xmlns="https://www.metanorma.org/ns/standoc" type="semantic">
<preface>
<foreword id="A">
<p>
<passthrough formats="html">A</passthrough>
<passthrough formats="word,html">A</passthrough>
<passthrough formats="word,html,pdf">A</passthrough>
<passthrough>A</passthrough>
<passthrough formats="all">A</passthrough>
</p>
</foreword></preface></standard-document>
INPUT
presxml = <<~OUTPUT
<standard-document xmlns="https://www.metanorma.org/ns/standoc" type="presentation">
<metanorma-extension>
<render>
<preprocess-xslt format="html">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name() = 'passthrough']">
<xsl:if test="contains(@formats,',html,')">
<!-- delimited -->
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
</preprocess-xslt>
<preprocess-xslt format="doc">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name() = 'passthrough']">
<xsl:if test="contains(@formats,',doc,')">
<!-- delimited -->
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
</preprocess-xslt>
</render>
</metanorma-extension>
<preface><clause type="toc" id="_" displayorder="1"><title depth="1">Table of contents</title></clause>
<foreword id="A" displayorder="2">
<p>
<passthrough formats=",html,">A</passthrough>
<passthrough formats=",word,html,">A</passthrough>
<passthrough formats=",word,html,pdf,">A</passthrough>
<passthrough formats=",html,doc,">A</passthrough>
<passthrough formats=",html,doc,">A</passthrough>
</p>
</foreword>
</preface>
</standard-document>
OUTPUT
expect(xmlpp(strip_guid(IsoDoc::PresentationXMLConvert
.new(presxml_options.merge(output_formats: { html: "html", doc: "doc" }))
.convert("test", input, true))
.sub(%r{<localized-strings>.*</localized-strings>}m, "")))
.to be_equivalent_to xmlpp(presxml)
end

private

Expand Down

0 comments on commit 54b65b4

Please sign in to comment.