isodoc 2.4.0 → 2.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/isodoc.gemspec +1 -0
  3. data/lib/isodoc/base_style/all.css +29 -0
  4. data/lib/isodoc/base_style/metanorma_word.css +9 -0
  5. data/lib/isodoc/base_style/metanorma_word.scss +11 -0
  6. data/lib/isodoc/base_style/reset.css +29 -0
  7. data/lib/isodoc/base_style/reset.scss +34 -0
  8. data/lib/isodoc/base_style/rouge.css +39 -0
  9. data/lib/isodoc/base_style/typography.scss +6 -3
  10. data/lib/isodoc/convert.rb +7 -4
  11. data/lib/isodoc/function/blocks.rb +26 -16
  12. data/lib/isodoc/function/inline.rb +17 -17
  13. data/lib/isodoc/function/references.rb +38 -52
  14. data/lib/isodoc/function/table.rb +22 -13
  15. data/lib/isodoc/function/to_word_html.rb +1 -4
  16. data/lib/isodoc/function/utils.rb +5 -1
  17. data/lib/isodoc/html_function/html.rb +13 -34
  18. data/lib/isodoc/html_function/postprocess.rb +14 -1
  19. data/lib/isodoc/html_function/postprocess_cover.rb +6 -9
  20. data/lib/isodoc/metadata.rb +5 -0
  21. data/lib/isodoc/presentation_function/block.rb +15 -46
  22. data/lib/isodoc/presentation_function/refs.rb +75 -3
  23. data/lib/isodoc/presentation_function/sourcecode.rb +114 -0
  24. data/lib/isodoc/presentation_function/terms.rb +29 -37
  25. data/lib/isodoc/presentation_function/xrefs.rb +9 -6
  26. data/lib/isodoc/version.rb +1 -1
  27. data/lib/isodoc/word_function/body.rb +16 -16
  28. data/lib/isodoc/word_function/postprocess.rb +47 -43
  29. data/lib/isodoc/word_function/postprocess_cover.rb +29 -157
  30. data/lib/isodoc/word_function/postprocess_toc.rb +165 -0
  31. data/lib/isodoc/word_function/table.rb +25 -13
  32. data/lib/isodoc/xref/xref_gen.rb +2 -4
  33. metadata +19 -2
@@ -13,7 +13,7 @@ module IsoDoc
13
13
  if thead
14
14
  table.thead do |h|
15
15
  thead.element_children.each_with_index do |n, i|
16
- tr_parse(n, h, i, thead.element_children.size, true)
16
+ tr_parse(n, h, i, thead.xpath(ns("./tr")).size, true)
17
17
  end
18
18
  end
19
19
  end
@@ -23,7 +23,7 @@ module IsoDoc
23
23
  tbody = node.at(ns("./tbody")) || return
24
24
  table.tbody do |h|
25
25
  tbody.element_children.each_with_index do |n, i|
26
- tr_parse(n, h, i, tbody.element_children.size, false)
26
+ tr_parse(n, h, i, tbody.xpath(ns("./tr")).size, false)
27
27
  end
28
28
  end
29
29
  end
@@ -33,7 +33,7 @@ module IsoDoc
33
33
  if tfoot
34
34
  table.tfoot do |h|
35
35
  tfoot.element_children.each_with_index do |n, i|
36
- tr_parse(n, h, i, tfoot.element_children.size, false)
36
+ tr_parse(n, h, i, tfoot.xpath(ns("./tr")).size, false)
37
37
  end
38
38
  end
39
39
  end
@@ -41,11 +41,13 @@ module IsoDoc
41
41
 
42
42
  def table_attrs(node)
43
43
  width = node["width"] ? "width:#{node['width']};" : nil
44
+ c = node["class"]
45
+ bordered = "border-width:1px;border-spacing:0;"
46
+ (%w(modspec).include?(c) || !c) or bordered = ""
44
47
  attr_code(
45
48
  id: node["id"],
46
- class: node["class"] || "MsoISOTable",
47
- style: "border-width:1px;border-spacing:0;"\
48
- "#{width}#{keep_style(node)}",
49
+ class: c || "MsoISOTable",
50
+ style: "#{bordered}#{width}#{keep_style(node)}",
49
51
  title: node["alt"],
50
52
  )
51
53
  end
@@ -91,26 +93,33 @@ module IsoDoc
91
93
  # border-left:#{col.zero? ? "#{SW} 1.5pt;" : "none;"}
92
94
  # border-right:#{SW} #{col == totalcols && !header ? "1.5" : "1.0"}pt;
93
95
 
94
- def make_tr_attr(cell, row, totalrows, header)
96
+ def make_tr_attr(cell, row, totalrows, header, bordered)
95
97
  style = cell.name == "th" ? "font-weight:bold;" : ""
96
98
  cell["align"] and style += "text-align:#{cell['align']};"
97
99
  cell["valign"] and style += "vertical-align:#{cell['valign']};"
98
100
  rowmax = cell["rowspan"] ? row + cell["rowspan"].to_i - 1 : row
99
- style += <<~STYLE
100
- border-top:#{row.zero? ? "#{SW} 1.5pt;" : 'none;'}
101
- border-bottom:#{SW} #{rowmax == totalrows ? '1.5' : '1.0'}pt;
102
- STYLE
101
+ style += make_tr_attr_style(row, rowmax, totalrows, header, bordered)
103
102
  header and scope = (cell["colspan"] ? "colgroup" : "col")
104
103
  !header && cell.name == "th" and
105
104
  scope = (cell["rowspan"] ? "rowgroup" : "row")
106
105
  { rowspan: cell["rowspan"], colspan: cell["colspan"],
107
- style: style.gsub(/\n/, ""), scope: scope }
106
+ style: style.gsub(/\n/, ""), scope: scope, class: cell["class"] }
107
+ end
108
+
109
+ def make_tr_attr_style(row, rowmax, totalrows, _header, bordered)
110
+ bordered or return ""
111
+ <<~STYLE.gsub(/\n/, "")
112
+ border-top:#{row.zero? ? "#{SW} 1.5pt;" : 'none;'}
113
+ border-bottom:#{SW} #{rowmax >= totalrows ? '1.5' : '1.0'}pt;
114
+ STYLE
108
115
  end
109
116
 
110
117
  def tr_parse(node, out, ord, totalrows, header)
118
+ c = node.parent.parent["class"]
119
+ bordered = %w(modspec).include?(c) || !c
111
120
  out.tr do |r|
112
121
  node.elements.each do |td|
113
- attrs = make_tr_attr(td, ord, totalrows - 1, header)
122
+ attrs = make_tr_attr(td, ord, totalrows - 1, header, bordered)
114
123
  r.send td.name, **attr_code(attrs) do |entry|
115
124
  td.children.each { |n| parse(n, entry) }
116
125
  end
@@ -8,10 +8,6 @@ module IsoDoc
8
8
  @termdomain = termdomain
9
9
  end
10
10
 
11
- def in_sourcecode
12
- @sourcecode
13
- end
14
-
15
11
  def note?
16
12
  @note
17
13
  end
@@ -101,6 +97,7 @@ module IsoDoc
101
97
  end
102
98
 
103
99
  def info(isoxml, out)
100
+ @meta.code_css isoxml, out
104
101
  @meta.title isoxml, out
105
102
  @meta.subtitle isoxml, out
106
103
  @meta.docstatus isoxml, out
@@ -37,10 +37,14 @@ module IsoDoc
37
37
  DOCTYPE_HDR = "<!DOCTYPE html SYSTEM " \
38
38
  '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'.freeze
39
39
 
40
+ HUGESTRICT =
41
+ Nokogiri::XML::ParseOptions::HUGE |
42
+ Nokogiri::XML::ParseOptions::STRICT
43
+
40
44
  def to_xhtml(xml)
41
45
  xml = to_xhtml_prep(xml)
42
46
  begin
43
- Nokogiri::XML.parse(xml, &:strict)
47
+ Nokogiri::XML.parse(xml, nil, nil, HUGESTRICT)
44
48
  rescue Nokogiri::XML::SyntaxError => e
45
49
  File.open("#{@filename}.#{@format}.err", "w:UTF-8") do |f|
46
50
  f.write xml
@@ -7,7 +7,7 @@ module IsoDoc
7
7
  def convert1(docxml, filename, dir)
8
8
  bibitem_lookup(docxml)
9
9
  noko do |xml|
10
- xml.html **{ lang: @lang.to_s } do |html|
10
+ xml.html lang: @lang.to_s do |html|
11
11
  info docxml, nil
12
12
  populate_css
13
13
  html.head { |head| define_head head, filename, dir }
@@ -19,7 +19,7 @@ module IsoDoc
19
19
  def make_body1(body, _docxml)
20
20
  return if @bare
21
21
 
22
- body.div **{ class: "title-section" } do |div1|
22
+ body.div class: "title-section" do |div1|
23
23
  div1.p { |p| p << "&#xa0;" } # placeholder
24
24
  end
25
25
  section_break(body)
@@ -28,14 +28,14 @@ module IsoDoc
28
28
  def make_body2(body, _docxml)
29
29
  return if @bare
30
30
 
31
- body.div **{ class: "prefatory-section" } do |div2|
31
+ body.div class: "prefatory-section" do |div2|
32
32
  div2.p { |p| p << "&#xa0;" } # placeholder
33
33
  end
34
34
  section_break(body)
35
35
  end
36
36
 
37
37
  def make_body3(body, docxml)
38
- body.div **{ class: "main-section" } do |div3|
38
+ body.div class: "main-section" do |div3|
39
39
  boilerplate docxml, div3
40
40
  preface_block docxml, div3
41
41
  abstract docxml, div3
@@ -51,8 +51,8 @@ module IsoDoc
51
51
 
52
52
  def googlefonts
53
53
  <<~HEAD.freeze
54
- <link href="https://fonts.googleapis.com/css?family=Overpass:300,300i,600,900" rel="stylesheet">
55
- <link href="https://fonts.googleapis.com/css?family=Lato:400,400i,700,900" rel="stylesheet">
54
+ <link href="https://fonts.googleapis.com/css?family=Overpass:300,300i,600,900" rel="stylesheet"/>
55
+ <link href="https://fonts.googleapis.com/css?family=Lato:400,400i,700,900" rel="stylesheet"/>
56
56
  HEAD
57
57
  end
58
58
 
@@ -66,11 +66,11 @@ module IsoDoc
66
66
  <script type="text/javascript">#{toclevel}</script>
67
67
 
68
68
  <!--Google fonts-->
69
- <link rel="preconnect" href="https://fonts.gstatic.com">#{' '}
69
+ <link rel="preconnect" href="https://fonts.gstatic.com"/>
70
70
  #{googlefonts}
71
71
  <!--Font awesome import for the link icon-->
72
- <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous">
73
- <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/fontawesome.css" integrity="sha384-q3jl8XQu1OpdLgGFvNRnPdj5VIlCvgsDQTQB6owSOHWlAurxul7f+JpUOVdAiJ5P" crossorigin="anonymous">
72
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous"/>
73
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/fontawesome.css" integrity="sha384-q3jl8XQu1OpdLgGFvNRnPdj5VIlCvgsDQTQB6owSOHWlAurxul7f+JpUOVdAiJ5P" crossorigin="anonymous"/>
74
74
  <style class="anchorjs"></style>
75
75
  HEAD
76
76
  end
@@ -89,33 +89,12 @@ module IsoDoc
89
89
  d.children.empty? or d.children.first.previous = html_button
90
90
  end
91
91
 
92
- def sourcecodelang(lang)
93
- return unless lang
94
-
95
- case lang.downcase
96
- when "javascript" then "lang-js"
97
- when "c" then "lang-c"
98
- when "c+" then "lang-cpp"
99
- when "console" then "lang-bsh"
100
- when "ruby" then "lang-rb"
101
- when "html" then "lang-html"
102
- when "java" then "lang-java"
103
- when "xml" then "lang-xml"
104
- when "perl" then "lang-perl"
105
- when "python" then "lang-py"
106
- when "xsl" then "lang-xsl"
107
- else
108
- ""
109
- end
110
- end
111
-
112
92
  def sourcecode_parse(node, out)
113
93
  name = node.at(ns("./name"))
114
- class1 = "prettyprint #{sourcecodelang(node&.at(ns('./@lang'))&.value)}"
115
- out.pre **sourcecode_attrs(node).merge(class: class1) do |div|
116
- @sourcecode = true
117
- node.children.each { |n| parse(n, div) unless n.name == "name" }
118
- @sourcecode = false
94
+ tag = node.at(ns(".//sourcecode | .//table")) ? "div" : "pre"
95
+ attr = sourcecode_attrs(node).merge(class: "sourcecode")
96
+ out.send tag, **attr do |div|
97
+ sourcecode_parse1(node, div)
119
98
  end
120
99
  sourcecode_name_parse(node, out, name)
121
100
  end
@@ -27,7 +27,20 @@ module IsoDoc
27
27
  def html_cleanup(html)
28
28
  html = term_header(html_footnote_filter(html_preface(htmlstyle(html))))
29
29
  html = footnote_format(footnote_backlinks(html_toc(html)))
30
- mathml(html_list_clean(remove_placeholder_paras(html)))
30
+ html = mathml(html_list_clean(remove_placeholder_paras(html)))
31
+ sourcecode_cleanup(html)
32
+ end
33
+
34
+ def sourcecode_cleanup(html)
35
+ ann = ".//div[@class = 'annotation']"
36
+ html.xpath("//pre[#{ann}] | //div[@class = 'sourcecode'][#{ann}]")
37
+ .each do |p|
38
+ ins = p.after("<pre class='sourcecode'/>").next_element
39
+ p.xpath(ann).each do |d|
40
+ ins << d.remove.children
41
+ end
42
+ end
43
+ html
31
44
  end
32
45
 
33
46
  def remove_placeholder_paras(html)
@@ -31,6 +31,9 @@ module IsoDoc
31
31
  head = docxml.at("//*[local-name() = 'head']")
32
32
  head << htmlstylesheet(@htmlstylesheet)
33
33
  s = htmlstylesheet(@htmlstylesheet_override) and head << s
34
+ s = @meta.get[:code_css] and
35
+ head << "<style><!--#{s.gsub(/sourcecode/,
36
+ 'pre.sourcecode')}--></style>"
34
37
  @bare and
35
38
  head << "<style>body {margin-left: 2em; margin-right: 2em;}</style>"
36
39
  docxml
@@ -40,7 +43,6 @@ module IsoDoc
40
43
  html_cover(docxml) if @htmlcoverpage && !@bare
41
44
  html_intro(docxml) if @htmlintropage && !@bare
42
45
  docxml.at("//body") << mathjax(@openmathdelim, @closemathdelim)
43
- docxml.at("//body") << sourcecode_highlighter
44
46
  html_main(docxml)
45
47
  authority_cleanup(docxml)
46
48
  docxml
@@ -48,7 +50,7 @@ module IsoDoc
48
50
 
49
51
  def authority_cleanup1(docxml, klass)
50
52
  dest = docxml.at("//div[@id = 'boilerplate-#{klass}-destination']")
51
- auth = docxml.at("//div[@id = 'boilerplate-#{klass}' or "\
53
+ auth = docxml.at("//div[@id = 'boilerplate-#{klass}' or " \
52
54
  "@class = 'boilerplate-#{klass}']")
53
55
  auth&.xpath(".//h1[not(text())] | .//h2[not(text())]")&.each(&:remove)
54
56
  auth&.xpath(".//h1 | .//h2")&.each { |h| h["class"] = "IntroTitle" }
@@ -92,7 +94,7 @@ module IsoDoc
92
94
  end
93
95
 
94
96
  def html_toc_entry(level, header)
95
- content = header.at("./following-sibling::p"\
97
+ content = header.at("./following-sibling::p" \
96
98
  "[@class = 'variant-title-toc']") || header
97
99
  %(<li class="#{level}"><a href="##{header['id']}">\
98
100
  #{header_strip(content)}</a></li>)
@@ -127,7 +129,7 @@ module IsoDoc
127
129
  end
128
130
 
129
131
  def toc_exclude_class
130
- "[not(@class = 'TermNum')][not(@class = 'noTOC')]"\
132
+ "[not(@class = 'TermNum')][not(@class = 'noTOC')]" \
131
133
  "[string-length(normalize-space(.))>0]"
132
134
  end
133
135
 
@@ -142,11 +144,6 @@ module IsoDoc
142
144
  "#{a[0]}#{scripts}#{scripts_override}</body>#{a[1]}"
143
145
  end
144
146
 
145
- def sourcecode_highlighter
146
- '<script src="https://cdn.rawgit.com/google/code-prettify/master/'\
147
- 'loader/run_prettify.js"></script>'
148
- end
149
-
150
147
  MATHJAX_ADDR =
151
148
  "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js".freeze
152
149
  MATHJAX = <<~"MATHJAX".freeze
@@ -168,5 +168,10 @@ module IsoDoc
168
168
  end
169
169
  set(:title_footnote, ret)
170
170
  end
171
+
172
+ def code_css(isoxml, _out)
173
+ c = isoxml.at(ns("//misc-container/source-highlighter-css")) or return
174
+ set(:code_css, c.text)
175
+ end
171
176
  end
172
177
  end
@@ -1,4 +1,6 @@
1
1
  require_relative "./image"
2
+ require_relative "./sourcecode"
3
+ require "rouge"
2
4
 
3
5
  module IsoDoc
4
6
  class PresentationXMLConvert < ::IsoDoc::Convert
@@ -25,24 +27,8 @@ module IsoDoc
25
27
  end
26
28
  end
27
29
 
28
- def sourcecode(docxml)
29
- docxml.xpath(ns("//sourcecode")).each do |f|
30
- sourcecode1(f)
31
- end
32
- end
33
-
34
- def sourcecode1(elem)
35
- return if labelled_ancestor(elem)
36
-
37
- lbl = @xrefs.anchor(elem["id"], :label, false) or return
38
- prefix_name(elem, block_delim,
39
- l10n("#{lower2cap @i18n.figure} #{lbl}"), "name")
40
- end
41
-
42
30
  def formula(docxml)
43
- docxml.xpath(ns("//formula")).each do |f|
44
- formula1(f)
45
- end
31
+ docxml.xpath(ns("//formula")).each { |f| formula1(f) }
46
32
  end
47
33
 
48
34
  def formula1(elem)
@@ -51,48 +37,38 @@ module IsoDoc
51
37
  end
52
38
 
53
39
  def example(docxml)
54
- docxml.xpath(ns("//example")).each do |f|
55
- example1(f)
56
- end
40
+ docxml.xpath(ns("//example")).each { |f| example1(f) }
57
41
  end
58
42
 
59
43
  def example1(elem)
60
44
  n = @xrefs.get[elem["id"]]
61
45
  lbl = if n.nil? || n[:label].nil? || n[:label].empty?
62
46
  @i18n.example
63
- else
64
- l10n("#{@i18n.example} #{n[:label]}")
47
+ else l10n("#{@i18n.example} #{n[:label]}")
65
48
  end
66
49
  prefix_name(elem, block_delim, lbl, "name")
67
50
  end
68
51
 
69
52
  def note(docxml)
70
- docxml.xpath(ns("//note")).each do |f|
71
- note1(f)
72
- end
53
+ docxml.xpath(ns("//note")).each { |f| note1(f) }
73
54
  end
74
55
 
75
56
  def note1(elem)
76
- return if elem.parent.name == "bibitem" || elem["notag"] == "true"
77
-
57
+ elem.parent.name == "bibitem" || elem["notag"] == "true" and return
78
58
  n = @xrefs.get[elem["id"]]
79
59
  lbl = if n.nil? || n[:label].nil? || n[:label].empty?
80
60
  @i18n.note
81
- else
82
- l10n("#{@i18n.note} #{n[:label]}")
61
+ else l10n("#{@i18n.note} #{n[:label]}")
83
62
  end
84
63
  prefix_name(elem, "", lbl, "name")
85
64
  end
86
65
 
87
66
  def admonition(docxml)
88
- docxml.xpath(ns("//admonition")).each do |f|
89
- admonition1(f)
90
- end
67
+ docxml.xpath(ns("//admonition")).each { |f| admonition1(f) }
91
68
  end
92
69
 
93
70
  def admonition1(elem)
94
- return if elem.at(ns("./name")) || elem["notag"] == "true"
95
-
71
+ elem.at(ns("./name")) || elem["notag"] == "true" and return
96
72
  prefix_name(elem, "", @i18n.admonition[elem["type"]]&.upcase, "name")
97
73
  end
98
74
 
@@ -121,15 +97,12 @@ module IsoDoc
121
97
  end
122
98
 
123
99
  def table(docxml)
124
- docxml.xpath(ns("//table")).each do |f|
125
- table1(f)
126
- end
100
+ docxml.xpath(ns("//table")).each { |f| table1(f) }
127
101
  end
128
102
 
129
103
  def table1(elem)
130
- return if labelled_ancestor(elem)
131
- return if elem["unnumbered"] && !elem.at(ns("./name"))
132
-
104
+ labelled_ancestor(elem) and return
105
+ elem["unnumbered"] && !elem.at(ns("./name")) and return
133
106
  n = @xrefs.anchor(elem["id"], :label, false)
134
107
  prefix_name(elem, block_delim, l10n("#{lower2cap @i18n.table} #{n}"),
135
108
  "name")
@@ -137,9 +110,7 @@ module IsoDoc
137
110
 
138
111
  # we use this to eliminate the semantic amend blocks from rendering
139
112
  def amend(docxml)
140
- docxml.xpath(ns("//amend")).each do |f|
141
- amend1(f)
142
- end
113
+ docxml.xpath(ns("//amend")).each { |f| amend1(f) }
143
114
  end
144
115
 
145
116
  def amend1(elem)
@@ -150,9 +121,7 @@ module IsoDoc
150
121
  end
151
122
 
152
123
  def ol(docxml)
153
- docxml.xpath(ns("//ol")).each do |f|
154
- ol1(f)
155
- end
124
+ docxml.xpath(ns("//ol")).each { |f| ol1(f) }
156
125
  @xrefs.list_anchor_names(docxml.xpath(ns(@xrefs.sections_xpath)))
157
126
  end
158
127
 
@@ -49,8 +49,8 @@ module IsoDoc
49
49
  def bibrender_relaton(xml, renderings)
50
50
  f = renderings[xml["id"]][:formattedref]
51
51
  f &&= "<formattedref>#{f}</formattedref>"
52
- xml.children =
53
- "#{f}#{xml.xpath(ns('./docidentifier | ./uri | ./note')).to_xml}"
52
+ x = xml.xpath(ns("./docidentifier | ./uri | ./note | ./biblio-tag"))
53
+ xml.children = "#{f}#{x.to_xml}"
54
54
  end
55
55
 
56
56
  def bibrenderer
@@ -74,6 +74,7 @@ module IsoDoc
74
74
  i = bibliography_bibitem_number1(b, i)
75
75
  end
76
76
  @xrefs.references docxml
77
+ bibliography_bibitem_tag(docxml)
77
78
  end
78
79
 
79
80
  def bibliography_bibitem_number1(bibitem, idx)
@@ -99,8 +100,79 @@ module IsoDoc
99
100
 
100
101
  def docid_prefixes(docxml)
101
102
  docxml.xpath(ns("//references/bibitem/docidentifier")).each do |i|
102
- i.children = @xrefs.klass.docid_prefix(i["type"], i.text)
103
+ i.children = @xrefs.klass.docid_prefix(i["type"], to_xml(i.children))
103
104
  end
104
105
  end
106
+
107
+ def bibliography_bibitem_tag(docxml)
108
+ [true, false].each do |norm|
109
+ i = 0
110
+ docxml.xpath(ns("//references[@normative = '#{norm}']")).each do |r|
111
+ i = bibliography_bibitem_tag1(r, i, norm)
112
+ end
113
+ end
114
+ end
115
+
116
+ def bibliography_bibitem_tag1(ref, idx, norm)
117
+ ref.xpath(ns("./bibitem")).each do |b|
118
+ @xrefs.klass.implicit_reference(b) and next
119
+ idx += 1 unless b["hidden"]
120
+ insert_biblio_tag(b, idx, !norm, @xrefs.klass.standard?(b))
121
+ end
122
+ idx
123
+ end
124
+
125
+ def insert_biblio_tag(bib, ordinal, biblio, standard)
126
+ datefn = date_note_process(bib)
127
+ ids = @xrefs.klass.bibitem_ref_code(bib)
128
+ idents = @xrefs.klass.render_identifier(ids)
129
+ ret = if biblio then biblio_ref_entry_code(ordinal, idents, ids,
130
+ standard, datefn)
131
+ else norm_ref_entry_code(ordinal, idents, ids, standard, datefn)
132
+ end
133
+ bib << "<biblio-tag>#{ret}</biblio-tag>"
134
+ end
135
+
136
+ def norm_ref_entry_code(_ordinal, idents, _ids, _standard, datefn)
137
+ ret = (idents[:ordinal] || idents[:metanorma] || idents[:sdo]).to_s
138
+ (idents[:ordinal] || idents[:metanorma]) && idents[:sdo] and
139
+ ret += ", #{idents[:sdo]}"
140
+ ret += datefn
141
+ ret.empty? and return ret
142
+ idents[:sdo] and ret += ","
143
+ "#{ret} "
144
+ end
145
+
146
+ # if ids is just a number, only use that ([1] Non-Standard)
147
+ # else, use both ordinal, as prefix, and ids
148
+ def biblio_ref_entry_code(ordinal, ids, _id, standard, datefn)
149
+ standard and id = nil
150
+ ret = (ids[:ordinal] || ids[:metanorma] || "[#{ordinal}]")
151
+ if ids[:sdo]
152
+ ret = prefix_bracketed_ref(ret)
153
+ ret += "#{ids[:sdo]}#{datefn}, "
154
+ else
155
+ ret = prefix_bracketed_ref("#{ret}#{datefn}")
156
+ end
157
+ ret
158
+ end
159
+
160
+ def prefix_bracketed_ref(text)
161
+ "#{text}<tab/>"
162
+ end
163
+
164
+ # strip any fns in docidentifier before they are extracted for rendering
165
+ def date_note_process(bib)
166
+ ret = ident_fn(bib)
167
+ date_note = bib.at(ns("./note[@type = 'Unpublished-Status']"))
168
+ date_note.nil? and return ret
169
+ id = UUIDTools::UUID.random_create.to_s
170
+ "#{ret}<fn reference='#{id}'><p>#{date_note.content}</p></fn>"
171
+ end
172
+
173
+ def ident_fn(bib)
174
+ ret = bib.at(ns("./docidentifier//fn")) or return ""
175
+ to_xml(ret.remove)
176
+ end
105
177
  end
106
178
  end
@@ -0,0 +1,114 @@
1
+ module IsoDoc
2
+ class PresentationXMLConvert < ::IsoDoc::Convert
3
+ def sourcehighlighter_css(docxml)
4
+ @sourcehighlighter or return
5
+ ins = docxml.at(ns("//misc-container")) ||
6
+ docxml.at(ns("//bibdata")).after("<misc-container/>").next_element
7
+ ins << "<source-highlighter-css>#{sourcehighlighter_css_file}" \
8
+ "</source-highlighter-css>"
9
+ end
10
+
11
+ def sourcehighlighter_css_file
12
+ File.read(File.join(File.dirname(__FILE__), "..", "base_style",
13
+ "rouge.css"))
14
+ end
15
+
16
+ def sourcehighlighter
17
+ @sourcehighlighter or return
18
+ f = Rouge::Formatters::HTML.new
19
+ opts = { gutter_class: "rouge-gutter", code_class: "rouge-code" }
20
+ { formatter: f,
21
+ formatter_line: Rouge::Formatters::HTMLLineTable.new(f, opts) }
22
+ end
23
+
24
+ def sourcecode(docxml)
25
+ sourcehighlighter_css(docxml)
26
+ @highlighter = sourcehighlighter
27
+ docxml.xpath(ns("//sourcecode")).each do |f|
28
+ sourcecode1(f)
29
+ end
30
+ end
31
+
32
+ def sourcecode1(elem)
33
+ source_highlight(elem)
34
+ source_label(elem)
35
+ end
36
+
37
+ def source_highlight(elem)
38
+ @highlighter or return
39
+ markup = source_remove_markup(elem)
40
+ p = source_lex(elem)
41
+ elem.children = if elem["linenums"] == "true"
42
+ r = sourcecode_table_to_elem(elem, p)
43
+ source_restore_markup_table(r, markup)
44
+ else
45
+ r = @highlighter[:formatter].format(p)
46
+ source_restore_markup(Nokogiri::XML.fragment(r), markup)
47
+ end
48
+ end
49
+
50
+ def source_remove_markup(elem)
51
+ ret = {}
52
+ name = elem.at(ns("./name")) and ret[:name] = name.remove.to_xml
53
+ ret[:ann] = elem.xpath(ns("./annotation")).each(&:remove)
54
+ ret[:call] = elem.xpath(ns("./callout")).each_with_object([]) do |c, m|
55
+ m << { xml: c.remove.to_xml, line: c.line - elem.line }
56
+ end
57
+ ret
58
+ end
59
+
60
+ def source_restore_markup(wrapper, markup)
61
+ ret = source_restore_callouts(wrapper, markup[:call])
62
+ "#{markup[:name]}#{ret}#{markup[:ann]}"
63
+ end
64
+
65
+ def source_restore_markup_table(wrapper, markup)
66
+ source_restore_callouts_table(wrapper, markup[:call])
67
+ ret = to_xml(wrapper)
68
+ "#{markup[:name]}#{ret}#{markup[:ann]}"
69
+ end
70
+
71
+ def source_restore_callouts(code, callouts)
72
+ text = to_xml(code)
73
+ text.split(/[\n\r]/).each_with_index do |c, i|
74
+ while !callouts.empty? && callouts[0][:line] == i
75
+ c.sub!(/\s+$/, " <span class='c'>#{callouts[0][:xml]}</span> ")
76
+ callouts.shift
77
+ end
78
+ end.join("\n")
79
+ end
80
+
81
+ def source_restore_callouts_table(table, callouts)
82
+ table.xpath(".//td[@class = 'rouge-code']/sourcecode")
83
+ .each_with_index do |c, i|
84
+ while !callouts.empty? && callouts[0][:line] == i
85
+ c << " <span class='c'>#{callouts[0][:xml]}</span> "
86
+ callouts.shift
87
+ end
88
+ end
89
+ end
90
+
91
+ def sourcecode_table_to_elem(elem, tokens)
92
+ r = Nokogiri::XML(@highlighter[:formatter_line].format(tokens)).root
93
+ r.xpath(".//td[@class = 'rouge-code']/pre").each do |pre|
94
+ %w(style).each { |n| elem[n] and pre[n] = elem[n] }
95
+ pre.name = "sourcecode"
96
+ pre.children = to_xml(pre.children).sub(/\s+$/, "")
97
+ end
98
+ r
99
+ end
100
+
101
+ def source_lex(elem)
102
+ l = (Rouge::Lexer.find(elem["lang"] || "plaintext") ||
103
+ Rouge::Lexer.find("plaintext"))
104
+ l.lex(@c.decode(elem.children.to_xml))
105
+ end
106
+
107
+ def source_label(elem)
108
+ labelled_ancestor(elem) and return
109
+ lbl = @xrefs.anchor(elem["id"], :label, false) or return
110
+ prefix_name(elem, block_delim,
111
+ l10n("#{lower2cap @i18n.figure} #{lbl}"), "name")
112
+ end
113
+ end
114
+ end