isodoc 1.5.3 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +1 -1
  3. data/.rubocop.yml +6 -4
  4. data/Gemfile +2 -2
  5. data/bin/rspec +1 -2
  6. data/isodoc.gemspec +11 -11
  7. data/lib/isodoc-yaml/i18n-ar.yaml +152 -0
  8. data/lib/isodoc-yaml/i18n-de.yaml +149 -0
  9. data/lib/isodoc-yaml/i18n-es.yaml +151 -0
  10. data/lib/isodoc-yaml/i18n-ru.yaml +154 -0
  11. data/lib/isodoc/base_style/all.css +7 -0
  12. data/lib/isodoc/base_style/metanorma_word.css +7 -0
  13. data/lib/isodoc/base_style/metanorma_word.scss +8 -0
  14. data/lib/isodoc/base_style/reset.css +7 -0
  15. data/lib/isodoc/base_style/reset.scss +9 -0
  16. data/lib/isodoc/base_style/scripts.html +187 -0
  17. data/lib/isodoc/class_utils.rb +6 -5
  18. data/lib/isodoc/common.rb +2 -0
  19. data/lib/isodoc/convert.rb +30 -17
  20. data/lib/isodoc/css.rb +42 -28
  21. data/lib/isodoc/function/blocks.rb +25 -4
  22. data/lib/isodoc/function/blocks_example_note.rb +2 -2
  23. data/lib/isodoc/function/cleanup.rb +1 -2
  24. data/lib/isodoc/function/form.rb +51 -0
  25. data/lib/isodoc/function/inline.rb +32 -10
  26. data/lib/isodoc/function/references.rb +55 -42
  27. data/lib/isodoc/function/table.rb +1 -0
  28. data/lib/isodoc/function/to_word_html.rb +29 -27
  29. data/lib/isodoc/function/utils.rb +41 -38
  30. data/lib/isodoc/gem_tasks.rb +30 -31
  31. data/lib/isodoc/html_convert.rb +6 -4
  32. data/lib/isodoc/html_function/form.rb +62 -0
  33. data/lib/isodoc/html_function/postprocess.rb +35 -76
  34. data/lib/isodoc/html_function/postprocess_footnotes.rb +59 -0
  35. data/lib/isodoc/i18n.rb +33 -31
  36. data/lib/isodoc/pdf_convert.rb +1 -3
  37. data/lib/isodoc/presentation_function/block.rb +26 -11
  38. data/lib/isodoc/presentation_function/inline.rb +60 -111
  39. data/lib/isodoc/presentation_function/math.rb +84 -0
  40. data/lib/isodoc/presentation_xml_convert.rb +2 -1
  41. data/lib/isodoc/version.rb +1 -1
  42. data/lib/isodoc/word_function/body.rb +28 -24
  43. data/lib/isodoc/word_function/footnotes.rb +22 -15
  44. data/lib/isodoc/word_function/inline.rb +6 -0
  45. data/lib/isodoc/word_function/postprocess.rb +16 -6
  46. data/lib/isodoc/xref.rb +10 -11
  47. data/lib/isodoc/xref/xref_counter.rb +31 -15
  48. data/lib/isodoc/xref/xref_gen.rb +28 -22
  49. data/lib/isodoc/xref/xref_sect_gen.rb +22 -20
  50. data/lib/isodoc/xslfo_convert.rb +36 -25
  51. data/spec/assets/html_override.css +1 -0
  52. data/spec/assets/word_override.css +1 -0
  53. data/spec/isodoc/blocks_spec.rb +2599 -2503
  54. data/spec/isodoc/cleanup_spec.rb +1107 -1109
  55. data/spec/isodoc/footnotes_spec.rb +1 -16
  56. data/spec/isodoc/form_spec.rb +156 -0
  57. data/spec/isodoc/i18n_spec.rb +984 -972
  58. data/spec/isodoc/inline_spec.rb +984 -920
  59. data/spec/isodoc/lists_spec.rb +316 -315
  60. data/spec/isodoc/postproc_spec.rb +1692 -1538
  61. data/spec/isodoc/presentation_xml_spec.rb +345 -338
  62. data/spec/isodoc/ref_spec.rb +718 -723
  63. data/spec/isodoc/section_spec.rb +910 -902
  64. data/spec/isodoc/table_spec.rb +566 -556
  65. data/spec/isodoc/terms_spec.rb +252 -256
  66. data/spec/isodoc/xref_spec.rb +3040 -2985
  67. data/spec/isodoc/xslfo_convert_spec.rb +39 -0
  68. data/spec/spec_helper.rb +30 -29
  69. metadata +80 -69
  70. data/.rubocop.ribose.yml +0 -65
  71. data/.rubocop.tb.yml +0 -650
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "isodoc/common"
3
4
  require "fileutils"
4
5
  require "tempfile"
@@ -7,12 +8,12 @@ require_relative "css"
7
8
 
8
9
  module IsoDoc
9
10
  class Convert < ::IsoDoc::Common
10
- attr_accessor :options
11
- attr_accessor :i18n
12
- attr_accessor :meta
11
+ attr_accessor :options, :i18n, :meta, :xrefs
13
12
 
14
13
  # htmlstylesheet: Generic stylesheet for HTML
14
+ # htmlstylesheet_override: Override stylesheet for HTML
15
15
  # wordstylesheet: Generic stylesheet for Word
16
+ # wordstylesheet_override: Override stylesheet for Word
16
17
  # standardsheet: Stylesheet specific to Standard
17
18
  # header: Header file for Word
18
19
  # htmlcoverpage: Cover page for HTML
@@ -36,11 +37,10 @@ module IsoDoc
36
37
  # break_up_urls_in_tables: whether to insert spaces in URLs in tables
37
38
  # every 40-odd chars
38
39
  def initialize(options)
39
- @libdir ||= File.dirname(__FILE__)
40
+ @libdir ||= File.dirname(__FILE__) # rubocop:disable Lint/DisjunctiveAssignmentInConstructor
40
41
  options.merge!(default_fonts(options)) do |_, old, new|
41
42
  old || new
42
- end
43
- .merge!(default_file_locations(options)) do |_, old, new|
43
+ end.merge!(default_file_locations(options)) do |_, old, new|
44
44
  old || new
45
45
  end
46
46
  @options = options
@@ -48,7 +48,10 @@ module IsoDoc
48
48
  @tempfile_cache = []
49
49
  @htmlstylesheet_name = options[:htmlstylesheet]
50
50
  @wordstylesheet_name = options[:wordstylesheet]
51
+ @htmlstylesheet_override_name = options[:htmlstylesheet_override]
52
+ @wordstylesheet_override_name = options[:wordstylesheet_override]
51
53
  @standardstylesheet_name = options[:standardstylesheet]
54
+ @sourcefilename = options[:sourcefilename]
52
55
  @header = options[:header]
53
56
  @htmlcoverpage = options[:htmlcoverpage]
54
57
  @wordcoverpage = options[:wordcoverpage]
@@ -58,15 +61,16 @@ module IsoDoc
58
61
  @smallerfontsize = options[:smallerfontsize]
59
62
  @monospacefontsize = options[:monospacefontsize]
60
63
  @footnotefontsize = options[:footnotefontsize]
61
- @scripts = options[:scripts]
64
+ @scripts = options[:scripts] ||
65
+ File.join(File.dirname(__FILE__), "base_style", "scripts.html")
62
66
  @scripts_pdf = options[:scripts_pdf]
63
67
  @i18nyaml = options[:i18nyaml]
64
68
  @ulstyle = options[:ulstyle]
65
69
  @olstyle = options[:olstyle]
66
70
  @datauriimage = options[:datauriimage]
67
71
  @suppressheadingnumbers = options[:suppressheadingnumbers]
68
- @break_up_urls_in_tables = options[:break_up_urls_in_tables] == 'true'
69
- @termdomain = ''
72
+ @break_up_urls_in_tables = options[:break_up_urls_in_tables] == "true"
73
+ @termdomain = ""
70
74
  @termexample = false
71
75
  @note = false
72
76
  @sourcecode = false
@@ -88,17 +92,17 @@ module IsoDoc
88
92
  @wordToClevels = 2 if @wordToClevels.zero?
89
93
  @htmlToClevels = options[:htmltoclevels].to_i
90
94
  @htmlToClevels = 2 if @htmlToClevels.zero?
91
- @bookmarks_allocated = { 'X' => true }
95
+ @bookmarks_allocated = { "X" => true }
92
96
  @fn_bookmarks = {}
93
97
  end
94
98
 
95
99
  def tmpimagedir_suffix
96
- '_images'
100
+ "_images"
97
101
  end
98
102
 
99
103
  def html_doc_path(*file)
100
104
  file.each do |f|
101
- ret = File.join(@libdir, File.join('html', f))
105
+ ret = File.join(@libdir, File.join("html", f))
102
106
  File.exist?(ret) and return ret
103
107
  end
104
108
  nil
@@ -108,7 +112,7 @@ module IsoDoc
108
112
  @xrefs.parse docxml
109
113
  noko do |xml|
110
114
  xml.html **{ lang: @lang.to_s } do |html|
111
- html.parent.add_namespace('epub', 'http://www.idpf.org/2007/ops')
115
+ html.parent.add_namespace("epub", "http://www.idpf.org/2007/ops")
112
116
  info docxml, nil
113
117
  populate_css
114
118
  html.head { |head| define_head head, filename, dir }
@@ -130,8 +134,8 @@ module IsoDoc
130
134
  @i18n = I18n.new(lang, script, i18nyaml || @i18nyaml)
131
135
  end
132
136
 
133
- def l10n(x, lang = @lang, script = @script)
134
- @i18n.l10n(x, lang, script)
137
+ def l10n(expr, lang = @lang, script = @script)
138
+ @i18n.l10n(expr, lang, script)
135
139
  end
136
140
 
137
141
  def convert_init(file, input_filename, debug)
@@ -153,14 +157,23 @@ module IsoDoc
153
157
  docxml, filename, dir = convert_init(file, input_filename, debug)
154
158
  result = convert1(docxml, filename, dir)
155
159
  return result if debug
160
+
156
161
  output_filename ||= "#{filename}.#{@suffix}"
157
162
  postprocess(result, output_filename, dir)
158
163
  FileUtils.rm_rf dir
159
164
  end
160
165
 
161
- def middle_clause(docxml = nil)
166
+ def middle_clause(_docxml = nil)
162
167
  "//clause[parent::sections][not(@type = 'scope')]"\
163
- '[not(descendant::terms)]'
168
+ "[not(descendant::terms)]"
169
+ end
170
+
171
+ def target_pdf(node)
172
+ if /#/.match?(node["target"])
173
+ node["target"].sub(/#/, ".pdf#")
174
+ else
175
+ "##{node['target']}"
176
+ end
164
177
  end
165
178
  end
166
179
  end
data/lib/isodoc/css.rb CHANGED
@@ -6,26 +6,40 @@ module IsoDoc
6
6
  def precompiled_style_or_original(stylesheet_path)
7
7
  # Already have compiled stylesheet, use it
8
8
  return stylesheet_path if stylesheet_path.nil? ||
9
- File.extname(stylesheet_path) == '.css'
10
- basename = File.basename(stylesheet_path, '.*')
9
+ File.extname(stylesheet_path) == ".css"
10
+
11
+ basename = File.basename(stylesheet_path, ".*")
11
12
  compiled_path = File.join(File.dirname(stylesheet_path),
12
13
  "#{basename}.css")
13
14
  return stylesheet_path unless File.file?(compiled_path)
15
+
14
16
  compiled_path
15
17
  end
16
18
 
19
+ def localpath(path)
20
+ return path if %r{^[A-Z]:|^/|^file:/}.match?(path)
21
+ return path unless (@sourcedir || @localdir) && path
22
+
23
+ File.expand_path(File.join((@sourcedir || @localdir), path))
24
+ end
25
+
17
26
  # run this after @meta is populated
18
27
  def populate_css
19
- @htmlstylesheet = generate_css(@htmlstylesheet_name, true)
20
- @wordstylesheet = generate_css(@wordstylesheet_name, false)
21
- @standardstylesheet = generate_css(@standardstylesheet_name, false)
28
+ @htmlstylesheet = generate_css(localpath(@htmlstylesheet_name), true)
29
+ @wordstylesheet = generate_css(localpath(@wordstylesheet_name), false)
30
+ @standardstylesheet =
31
+ generate_css(localpath(@standardstylesheet_name), false)
32
+ @htmlstylesheet_override_name and @htmlstylesheet_override =
33
+ File.open(localpath(@htmlstylesheet_override_name))
34
+ @wordstylesheet_override_name and @wordstylesheet_override =
35
+ File.open(localpath(@wordstylesheet_override_name))
22
36
  end
23
37
 
24
38
  def default_fonts(_options)
25
39
  {
26
- bodyfont: 'Arial',
27
- headerfont: 'Arial',
28
- monospacefont: 'Courier',
40
+ bodyfont: "Arial",
41
+ headerfont: "Arial",
42
+ monospacefont: "Courier",
29
43
  }
30
44
  end
31
45
 
@@ -37,35 +51,35 @@ module IsoDoc
37
51
 
38
52
  def fonts_options
39
53
  {
40
- 'bodyfont' => options[:bodyfont] || 'Arial',
41
- 'headerfont' => options[:headerfont] || 'Arial',
42
- 'monospacefont' => options[:monospacefont] || 'Courier',
54
+ "bodyfont" => options[:bodyfont] || "Arial",
55
+ "headerfont" => options[:headerfont] || "Arial",
56
+ "monospacefont" => options[:monospacefont] || "Courier",
43
57
  "normalfontsize" => options[:normalfontsize],
44
58
  "monospacefontsize" => options[:monospacefontsize],
45
59
  "smallerfontsize" => options[:smallerfontsize],
46
- "footnotefontsize" => options[:footnotefontsize]
60
+ "footnotefontsize" => options[:footnotefontsize],
47
61
  }
48
62
  end
49
63
 
50
64
  def scss_fontheader(is_html_css)
51
- b = options[:bodyfont] || 'Arial'
52
- h = options[:headerfont] || 'Arial'
53
- m = options[:monospacefont] || 'Courier'
54
- ns = options[:normalfontsize] || (is_html_css ? "1.0em" : '12.0pt')
55
- ms = options[:monospacefontsize] || (is_html_css ? "0.8em" : '11.0pt')
56
- ss = options[:smallerfontsize] || (is_html_css ? "0.9em" : '10.0pt')
57
- fs = options[:footnotefontsize] || (is_html_css ? "0.9em" : '9.0pt')
65
+ b = options[:bodyfont] || "Arial"
66
+ h = options[:headerfont] || "Arial"
67
+ m = options[:monospacefont] || "Courier"
68
+ ns = options[:normalfontsize] || (is_html_css ? "1.0em" : "12.0pt")
69
+ ms = options[:monospacefontsize] || (is_html_css ? "0.8em" : "11.0pt")
70
+ ss = options[:smallerfontsize] || (is_html_css ? "0.9em" : "10.0pt")
71
+ fs = options[:footnotefontsize] || (is_html_css ? "0.9em" : "9.0pt")
58
72
  "$bodyfont: #{b};\n$headerfont: #{h};\n$monospacefont: #{m};\n"\
59
73
  "$normalfontsize: #{ns};\n$monospacefontsize: #{ms};\n"\
60
74
  "$smallerfontsize: #{ss};\n$footnotefontsize: #{fs};\n"
61
75
  end
62
76
 
63
77
  def convert_scss(filename, stylesheet, stripwordcss)
64
- require 'sassc'
65
- require 'isodoc/sassc_importer'
78
+ require "sassc"
79
+ require "isodoc/sassc_importer"
66
80
 
67
- [File.join(Gem.loaded_specs['isodoc'].full_gem_path,
68
- 'lib', 'isodoc'),
81
+ [File.join(Gem.loaded_specs["isodoc"].full_gem_path,
82
+ "lib", "isodoc"),
69
83
  File.dirname(filename)].each do |name|
70
84
  SassC.load_paths << name
71
85
  end
@@ -79,14 +93,14 @@ module IsoDoc
79
93
  return nil if filename.nil?
80
94
 
81
95
  filename = precompiled_style_or_original(filename)
82
- stylesheet = File.read(filename, encoding: 'UTF-8')
96
+ stylesheet = File.read(filename, encoding: "UTF-8")
83
97
  stylesheet = populate_template(stylesheet, :word)
84
- stylesheet.gsub!(/(\s|\{)mso-[^:]+:[^;]+;/m, '\\1') if stripwordcss
85
- if File.extname(filename) == '.scss'
98
+ stylesheet.gsub!(/(\s|\{)mso-[^:]+:[^;]+;/m, "\\1") if stripwordcss
99
+ if File.extname(filename) == ".scss"
86
100
  stylesheet = convert_scss(filename, stylesheet, stripwordcss)
87
101
  end
88
- Tempfile.open([File.basename(filename, '.*'), 'css'],
89
- encoding: 'utf-8') do |f|
102
+ Tempfile.open([File.basename(filename, ".*"), "css"],
103
+ encoding: "utf-8") do |f|
90
104
  f.write(stylesheet)
91
105
  f
92
106
  end
@@ -4,6 +4,16 @@ module IsoDoc::Function
4
4
  module Blocks
5
5
  @annotation = false
6
6
 
7
+ def middle_title(_isoxml, out)
8
+ out.p(**{ class: "zzSTDTitle1" }) { |p| p << @meta.get[:doctitle] }
9
+ end
10
+
11
+ def middle_admonitions(isoxml, out)
12
+ isoxml.xpath(ns("//sections/note | //sections/admonition")).each do |x|
13
+ parse(x, out)
14
+ end
15
+ end
16
+
7
17
  def figure_name_parse(node, div, name)
8
18
  return if name.nil?
9
19
  div.p **{ class: "FigureTitle", style: "text-align:center;" } do |p|
@@ -24,6 +34,7 @@ module IsoDoc::Function
24
34
  def figure_parse(node, out)
25
35
  return pseudocode_parse(node, out) if node["class"] == "pseudocode" ||
26
36
  node["type"] == "pseudocode"
37
+
27
38
  @in_figure = true
28
39
  out.div **figure_attrs(node) do |div|
29
40
  node.children.each do |n|
@@ -51,6 +62,7 @@ module IsoDoc::Function
51
62
 
52
63
  def sourcecode_name_parse(node, div, name)
53
64
  return if name.nil?
65
+
54
66
  div.p **{ class: "SourceTitle", style: "text-align:center;" } do |p|
55
67
  name.children.each { |n| parse(n, p) }
56
68
  end
@@ -91,14 +103,15 @@ module IsoDoc::Function
91
103
  @annotation = false
92
104
  end
93
105
 
94
- def admonition_class(node)
106
+ def admonition_class(_node)
95
107
  "Admonition"
96
108
  end
97
109
 
98
110
  def admonition_name(node, type)
99
111
  name = node&.at(ns("./name")) and return name
100
- name = Nokogiri::XML::Node.new('name', node.document)
112
+ name = Nokogiri::XML::Node.new("name", node.document)
101
113
  return unless type && @i18n.admonition[type]
114
+
102
115
  name << @i18n.admonition[type]&.upcase
103
116
  name
104
117
  end
@@ -119,7 +132,8 @@ module IsoDoc::Function
119
132
 
120
133
  def formula_where(dl, out)
121
134
  return unless dl
122
- out.p **{ style: "page-break-after:avoid;"} do |p|
135
+
136
+ out.p **{ style: "page-break-after:avoid;" } do |p|
123
137
  p << @i18n.where
124
138
  end
125
139
  parse(dl, out)
@@ -148,6 +162,7 @@ module IsoDoc::Function
148
162
  formula_where(node.at(ns("./dl")), div)
149
163
  node.children.each do |n|
150
164
  next if %w(stem dl name).include? n.name
165
+
151
166
  parse(n, div)
152
167
  end
153
168
  end
@@ -182,6 +197,7 @@ module IsoDoc::Function
182
197
  author = node.at(ns("./author"))
183
198
  source = node.at(ns("./source"))
184
199
  return if author.nil? && source.nil?
200
+
185
201
  out.p **{ class: "QuoteAttribution" } do |p|
186
202
  p << "&mdash; #{author.text}" if author
187
203
  p << ", " if author && source
@@ -201,9 +217,14 @@ module IsoDoc::Function
201
217
  end
202
218
 
203
219
  def passthrough_parse(node, out)
204
- return if node["format"] and
220
+ return if node["format"] &&
205
221
  !(node["format"].split(/,/).include? @format.to_s)
222
+
206
223
  out.passthrough node.text
207
224
  end
225
+
226
+ def svg_parse(node, out)
227
+ out << node.to_xml
228
+ end
208
229
  end
209
230
  end
@@ -59,7 +59,7 @@ module IsoDoc::Function
59
59
  name = node&.at(ns("./name"))&.remove
60
60
  div.p do |p|
61
61
  name and p.span **{ class: "note_label" } do |s|
62
- name and name.children.each { |n| parse(n, s) }
62
+ name.children.each { |n| parse(n, s) }
63
63
  s << note_delim
64
64
  end
65
65
  insert_tab(p, 1)
@@ -98,7 +98,7 @@ module IsoDoc::Function
98
98
  @note = true
99
99
  out.div **note_attrs(node) do |div|
100
100
  node&.at(ns("./*[local-name() != 'name'][1]"))&.name == "p" ?
101
- #node.first_element_child.name == "p" ?
101
+ # node.first_element_child.name == "p" ?
102
102
  note_p_parse(node, div) : note_parse1(node, div)
103
103
  end
104
104
  @note = false
@@ -204,8 +204,7 @@ module IsoDoc::Function
204
204
  docxml
205
205
  end
206
206
 
207
- def symbols_cleanup(docxml)
208
- end
207
+ def symbols_cleanup(docxml); end
209
208
 
210
209
  def table_footnote_reference_format(a)
211
210
  a
@@ -0,0 +1,51 @@
1
+ module IsoDoc::Function
2
+ module Form
3
+ def form_parse(node, out)
4
+ node.children.each do |n|
5
+ parse(n, out)
6
+ end
7
+ end
8
+
9
+ def input_parse(node, out)
10
+ case node["type"]
11
+ when "button" then out << "[#{node['value'] || 'BUTTON'}]"
12
+ when "checkbox" then out << "&#x2610; "
13
+ when "date" then text_input(out)
14
+ when "file" then text_input(out)
15
+ when "password" then text_input(out)
16
+ when "radio" then out << "&#x25CE; "
17
+ when "submit" # nop
18
+ when "text" then text_input(out, node["maxlength"])
19
+ end
20
+ end
21
+
22
+ def text_input(out, length = 10)
23
+ length ||= 10
24
+ length = length.to_i
25
+ length.zero? and length = 10
26
+ out << "_" * length
27
+ out << " "
28
+ end
29
+
30
+ def select_parse(node, out)
31
+ text_input(out, node["size"] || 10)
32
+ end
33
+
34
+ def label_parse(node, out)
35
+ node.children.each do |n|
36
+ parse(n, out)
37
+ end
38
+ end
39
+
40
+ def option_parse(node, out); end
41
+
42
+ def textarea_parse(_node, out)
43
+ out.table **{ border: 1, width: "50%" } do |t|
44
+ t.tr do |tr|
45
+ tr.td do |td|
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -23,21 +23,27 @@ module IsoDoc::Function
23
23
  end
24
24
 
25
25
  def xref_parse(node, out)
26
- target = /#/.match(node["target"]) ? node["target"].sub(/#/, ".html#") :
27
- "##{node["target"]}"
28
- out.a(**{ "href": target }) { |l| no_locality_parse(node, l) }
26
+ target = if /#/.match?(node["target"])
27
+ node["target"].sub(/#/, ".html#")
28
+ else
29
+ "##{node['target']}"
30
+ end
31
+ out.a(**{ "href": target }) { |l| no_locality_parse(node, l) }
29
32
  end
30
33
 
31
34
  def suffix_url(url)
32
- return url if %r{^http[s]?://}.match(url)
35
+ return url if %r{^https?://}.match?(url)
36
+ return url unless File.extname(url).empty?
37
+
33
38
  url.sub(/#{File.extname(url)}$/, ".html")
34
39
  end
35
40
 
36
41
  def eref_target(node)
37
- href = "#" + node["bibitemid"]
42
+ href = "##{node['bibitemid']}"
38
43
  url = node.at(ns("//bibitem[@id = '#{node['bibitemid']}']/"\
39
44
  "uri[@type = 'citation']"))
40
45
  return href unless url
46
+
41
47
  href = suffix_url(url.text)
42
48
  anchor = node&.at(ns(".//locality[@type = 'anchor']"))&.text&.strip
43
49
  anchor and href += "##{anchor}"
@@ -68,10 +74,11 @@ module IsoDoc::Function
68
74
  end
69
75
 
70
76
  def stem_parse(node, out)
71
- ooml = if node["type"] == "AsciiMath"
77
+ ooml = case node["type"]
78
+ when "AsciiMath"
72
79
  "#{@openmathdelim}#{HTMLEntities.new.encode(node.text)}"\
73
80
  "#{@closemathdelim}"
74
- elsif node["type"] == "MathML" then node.first_element_child.to_s
81
+ when "MathML" then node.first_element_child.to_s
75
82
  else
76
83
  HTMLEntities.new.encode(node.text)
77
84
  end
@@ -93,7 +100,7 @@ module IsoDoc::Function
93
100
  height: node["height"] || "auto",
94
101
  width: node["width"] || "auto",
95
102
  title: node["title"],
96
- alt: node["alt"] }
103
+ alt: node["alt"] }
97
104
  out.img **attr_code(attrs)
98
105
  image_title_parse(out, caption)
99
106
  end
@@ -106,12 +113,27 @@ module IsoDoc::Function
106
113
 
107
114
  def text_parse(node, out)
108
115
  return if node.nil? || node.text.nil?
116
+
109
117
  text = node.to_s
110
- text = text.gsub("\n", "<br/>").gsub("<br/> ", "<br/>&nbsp;").
111
- gsub(/[ ](?=[ ])/, "&nbsp;") if in_sourcecode
118
+ if in_sourcecode
119
+ text = text.gsub("\n", "<br/>").gsub("<br/> ", "<br/>&nbsp;")
120
+ .gsub(/ (?= )/, "&nbsp;")
121
+ end
112
122
  out << text
113
123
  end
114
124
 
125
+ def add_parse(node, out)
126
+ out.span **{class: "addition"} do |e|
127
+ node.children.each { |n| parse(n, e) }
128
+ end
129
+ end
130
+
131
+ def del_parse(node, out)
132
+ out.span **{class: "deletion"} do |e|
133
+ node.children.each { |n| parse(n, e) }
134
+ end
135
+ end
136
+
115
137
  def error_parse(node, out)
116
138
  text = node.to_xml.gsub(/</, "&lt;").gsub(/>/, "&gt;")
117
139
  out.para do |p|