asciidoctor-iso 0.0.1 → 0.6.0

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.gitignore +1 -0
  4. data/.hound.yml +3 -0
  5. data/.rubocop.ribose.yml +65 -0
  6. data/.rubocop.tb.yml +640 -0
  7. data/Gemfile +4 -0
  8. data/Gemfile.lock +162 -0
  9. data/Makefile +39 -0
  10. data/README.adoc +396 -59
  11. data/Rakefile +6 -0
  12. data/asciidoctor-iso.gemspec +11 -3
  13. data/lib/asciidoctor/iso/base.rb +122 -51
  14. data/lib/asciidoctor/iso/blocks.rb +119 -108
  15. data/lib/asciidoctor/iso/cleanup.rb +214 -0
  16. data/lib/asciidoctor/iso/cleanup_block.rb +157 -0
  17. data/lib/asciidoctor/iso/converter.rb +5 -3
  18. data/lib/asciidoctor/iso/front.rb +37 -28
  19. data/lib/asciidoctor/iso/html/header.html +184 -0
  20. data/lib/asciidoctor/iso/html/html_iso_intro.html +73 -0
  21. data/lib/asciidoctor/iso/html/html_iso_titlepage.html +31 -0
  22. data/lib/asciidoctor/iso/html/htmlstyle.css +67 -0
  23. data/lib/asciidoctor/iso/html/isodoc.css +679 -0
  24. data/lib/asciidoctor/iso/html/word_iso_intro.html +72 -0
  25. data/lib/asciidoctor/iso/html/word_iso_titlepage.html +58 -0
  26. data/lib/asciidoctor/iso/inline_anchor.rb +20 -26
  27. data/lib/asciidoctor/iso/isostandard.rnc +177 -0
  28. data/lib/asciidoctor/iso/isostandard.rng +1478 -0
  29. data/lib/asciidoctor/iso/isostandard_diff.rnc +295 -0
  30. data/lib/asciidoctor/iso/lists.rb +152 -109
  31. data/lib/asciidoctor/iso/section.rb +164 -0
  32. data/lib/asciidoctor/iso/table.rb +30 -27
  33. data/lib/asciidoctor/iso/utils.rb +61 -183
  34. data/lib/asciidoctor/iso/validate.make.sh +8 -0
  35. data/lib/asciidoctor/iso/validate.rb +195 -24
  36. data/lib/asciidoctor/iso/validate_style.rb +175 -0
  37. data/lib/asciidoctor/iso/version.rb +1 -1
  38. data/spec/examples/rice.adoc +45 -24
  39. data/spec/examples/rice.doc +17708 -0
  40. data/spec/examples/rice.html +1574 -1662
  41. data/spec/examples/rice.preview.html +1811 -0
  42. data/spec/examples/rice.sh +4 -0
  43. data/spec/examples/rice.xml +888 -62
  44. data/spec/examples/rice_images/rice_image1.png +0 -0
  45. data/spec/examples/rice_images/rice_image2.png +0 -0
  46. data/spec/examples/rice_images/rice_image3_1.png +0 -0
  47. data/spec/examples/rice_images/rice_image3_2.png +0 -0
  48. data/spec/examples/rice_images/rice_image3_3.png +0 -0
  49. metadata +135 -12
  50. data/grammar1.gif +0 -0
  51. data/grammar2.gif +0 -0
  52. data/grammar3.gif +0 -0
  53. data/grammar4.gif +0 -0
  54. data/lib/asciidoctor/iso/validate.rnc +0 -444
  55. data/lib/asciidoctor/iso/validate.rng +0 -1001
@@ -0,0 +1,164 @@
1
+ require "htmlentities"
2
+ require "uri"
3
+
4
+ module Asciidoctor
5
+ module ISO
6
+ module Section
7
+ @scope = false
8
+ @biblio = false
9
+ @term_def = false
10
+ @norm_ref = false
11
+
12
+ def in_scope
13
+ @scope
14
+ end
15
+
16
+ def in_biblio
17
+ @biblio
18
+ end
19
+
20
+ def in_terms
21
+ @term_def
22
+ end
23
+
24
+ def in_norm_ref
25
+ @norm_ref
26
+ end
27
+
28
+ def section(node)
29
+ a = { id: Utils::anchor_or_uuid(node) }
30
+ noko do |xml|
31
+ case node.title.downcase
32
+ when "introduction" then
33
+ if node.level == 1
34
+ introduction_parse(a, xml, node)
35
+ else
36
+ clause_parse(a, xml, node)
37
+ end
38
+ when "patent notice" then patent_notice_parse(xml, node)
39
+ when "scope" then scope_parse(a, xml, node)
40
+ when "normative references" then norm_ref_parse(a, xml, node)
41
+ when "terms and definitions"
42
+ term_def_parse(a, xml, node, node.title.downcase)
43
+ when "terms, definitions, symbols and abbreviations"
44
+ term_def_parse(a, xml, node, node.title.downcase)
45
+ when "symbols and abbreviated terms"
46
+ symbols_parse(a, xml, node)
47
+ when "bibliography" then bibliography_parse(a, xml, node)
48
+ else
49
+ if @term_def
50
+ term_def_subclause_parse(a, xml, node)
51
+ elsif @biblio
52
+ bibliography_parse(a, xml, node)
53
+ elsif node.attr("style") == "appendix" && node.level == 1
54
+ annex_parse(a, xml, node)
55
+ else
56
+ clause_parse(a, xml, node)
57
+ end
58
+ end
59
+ end.join("\n")
60
+ end
61
+
62
+ def clause_parse(attrs, xml, node)
63
+ attrs["inline-header".to_sym] = true if node.option? "inline-header"
64
+ w = "Scope contains subsections: should be succint"
65
+ style_warning(node, w, nil) if @scope
66
+ # Not testing max depth of sections: Asciidoctor already limits
67
+ # it to 5 levels of nesting
68
+ sect = node.level == 1 ? "clause" : "subsection"
69
+ xml.send sect, **attr_code(attrs) do |xml_section|
70
+ xml_section.title { |n| n << node.title } unless node.title.nil?
71
+ xml_section << node.content
72
+ end
73
+ end
74
+
75
+ def annex_parse(attrs, xml, node)
76
+ attrs["inline-header".to_sym] = true if node.option? "inline-header"
77
+ attrs[:subtype] = "informative"
78
+ if node.attributes.has_key?("subtype")
79
+ attrs[:subtype] = node.attr("subtype")
80
+ end
81
+ xml.annex **attr_code(attrs) do |xml_section|
82
+ xml_section.title { |name| name << node.title }
83
+ xml_section << node.content
84
+ end
85
+ end
86
+
87
+ def bibliography_parse(attrs, xml, node)
88
+ @biblio = true
89
+ xml.references **attr_code(attrs) do |xml_section|
90
+ title = node.level == 1 ? "Bibliography" : node.title
91
+ xml_section.title { |t| t << title }
92
+ xml_section << node.content
93
+ end
94
+ @biblio = true
95
+ end
96
+
97
+ def symbols_parse(attrs, xml, node)
98
+ xml.symbols_abbrevs **attr_code(attrs) do |xml_section|
99
+ xml_section << node.content
100
+ end
101
+ end
102
+
103
+ def term_def_subclause_parse(attrs, xml, node)
104
+ xml.term **attr_code(attrs) do |xml_section|
105
+ xml_section.preferred { |name| name << node.title }
106
+ xml_section << node.content
107
+ end
108
+ end
109
+
110
+ def term_def_parse(attrs, xml, node, title)
111
+ @term_def = true
112
+ xml.terms **attr_code(attrs) do |xml_section|
113
+ if title == "terms, definitions, symbols and abbreviations"
114
+ title = "Terms, Definitions, Symbols and Abbreviations"
115
+ else
116
+ title = "Terms and Definitions"
117
+ end
118
+ xml_section.title { |t| t << title }
119
+ xml_section << node.content
120
+ end
121
+ @term_def = false
122
+ end
123
+
124
+ def norm_ref_parse(attrs, xml, node)
125
+ @norm_ref = true
126
+ xml.references **attr_code(attrs) do |xml_section|
127
+ xml_section.title { |t| t << "Normative References" }
128
+ xml_section << node.content
129
+ end
130
+ @norm_ref = false
131
+ end
132
+
133
+ def introduction_parse(attrs, xml, node)
134
+ xml.content **attr_code(attrs) do |xml_section|
135
+ xml_section.title = "Introduction"
136
+ content = node.content
137
+ xml_section << content
138
+ introduction_style(node,
139
+ Utils::flatten_rawtext(content).
140
+ join("\n"))
141
+ end
142
+ end
143
+
144
+ def patent_notice_parse(xml, node)
145
+ # xml.patent_notice do |xml_section|
146
+ # xml_section << node.content
147
+ # end
148
+ xml << node.content
149
+ end
150
+
151
+ def scope_parse(attrs, xml, node)
152
+ @scope = true
153
+ xml.clause **attr_code(attrs) do |xml_section|
154
+ xml_section.title { |t| t << "Scope" }
155
+ content = node.content
156
+ xml_section << content
157
+ c = Utils::flatten_rawtext(content).join("\n")
158
+ scope_style(node, c)
159
+ end
160
+ @scope = false
161
+ end
162
+ end
163
+ end
164
+ end
@@ -1,14 +1,17 @@
1
1
  module Asciidoctor
2
2
  module ISO
3
3
  module Table
4
+ def table_attrs(node)
5
+ { id: Utils::anchor_or_uuid(node),
6
+ headerrows: node.attr("headerrows") }
7
+ end
8
+
4
9
  def table(node)
10
+ @table_fn_number = "a"
5
11
  noko do |xml|
6
- has_body = false
7
- xml.table **attr_code(anchor: node.id) do |xml_table|
12
+ xml.table **attr_code(table_attrs(node)) do |xml_table|
8
13
  %i(head body foot).reject do |tblsec|
9
14
  node.rows[tblsec].empty?
10
- end.each do |tblsec|
11
- has_body = true if tblsec == :body
12
15
  end
13
16
  xml_table.name node.title if node.title?
14
17
  table_head_body_and_foot node, xml_table
@@ -18,31 +21,31 @@ module Asciidoctor
18
21
 
19
22
  private
20
23
 
24
+ def table_cell1(cell, thd)
25
+ if cell.style == :asciidoc
26
+ thd << cell.content
27
+ else
28
+ thd << cell.text
29
+ style(cell, cell.text)
30
+ end
31
+ end
32
+
33
+ def table_cell(c, xml_tr, tblsec)
34
+ cell_attributes = { id: c.id, colspan: c.colspan,
35
+ rowspan: c.rowspan, align: c.attr("halign") }
36
+ cell_tag = "td"
37
+ cell_tag = "th" if tblsec == :head || c.style == :header
38
+ xml_tr.send cell_tag, **attr_code(cell_attributes) do |thd|
39
+ table_cell1(c, thd)
40
+ end
41
+ end
42
+
21
43
  def table_head_body_and_foot(node, xml)
22
- %i(head body foot).reject do |tblsec|
23
- node.rows[tblsec].empty?
24
- end.each do |tblsec|
25
- tblsec_tag = "t#{tblsec}"
26
- # "anchor" attribute from tblsec.id not supported
27
- xml.send tblsec_tag do |xml_tblsec|
28
- node.rows[tblsec].each_with_index do |row, i|
44
+ %i(head body foot).reject { |s| node.rows[s].empty? }.each do |s|
45
+ xml.send "t#{s}" do |xml_tblsec|
46
+ node.rows[s].each do |row|
29
47
  xml_tblsec.tr do |xml_tr|
30
- rowlength = 0
31
- row.each do |cell|
32
- cell_attributes = {
33
- anchor: cell.id,
34
- colspan: cell.colspan,
35
- rowspan: cell.rowspan,
36
- align: cell.attr("halign"),
37
- }
38
-
39
- cell_tag = "td"
40
- cell_tag = "th" if tblsec == :head || cell.style == :header
41
- rowlength += cell.text.size
42
- xml_tr.send cell_tag, **attr_code(cell_attributes) do |thd|
43
- thd << (cell.style == :asciidoc ? cell.content : cell.text)
44
- end
45
- end
48
+ row.each { |cell| table_cell(cell, xml_tr, s) }
46
49
  end
47
50
  end
48
51
  end
@@ -4,165 +4,85 @@ require "htmlentities"
4
4
  require "json"
5
5
  require "pathname"
6
6
  require "open-uri"
7
+ require "uuidtools"
7
8
  require "pp"
8
9
 
9
10
  module Asciidoctor
10
11
  module ISO
11
12
  module Utils
12
- def convert(node, transform = nil, opts = {})
13
- transform ||= node.node_name
14
- opts.empty? ? (send transform, node) : (send transform, node, opts)
15
- end
16
-
17
- def document_ns_attributes(_doc)
18
- # ' xmlns="http://riboseinc.com/isoxml"'
19
- nil
20
- end
21
-
22
- def cleanup(xmldoc)
23
- intro_cleanup(xmldoc)
24
- termdef_cleanup(xmldoc)
25
- isotitle_cleanup(xmldoc)
26
- tablenote_cleanup(xmldoc)
27
- formula_cleanup(xmldoc)
28
- figure_cleanup(xmldoc)
29
- back_cleanup(xmldoc)
30
- ref_cleanup(xmldoc)
31
- end
32
-
33
- def intro_cleanup(xmldoc)
34
- intro = xmldoc.at("//introduction")
35
- foreword = xmldoc.at("//foreword")
36
- front = xmldoc.at("//front")
37
- unless foreword.nil? || front.nil?
38
- foreword.remove
39
- front << foreword
40
- end
41
- unless intro.nil? || front.nil?
42
- intro.remove
43
- front << intro
44
- end
45
- end
46
-
47
- def termdef_cleanup(xmldoc)
48
- # release termdef tags from surrounding paras
49
- nodes = xmldoc.xpath("//p/admitted_term | //p/termsymbol |
50
- //p/deprecated_term")
51
- while !nodes.empty?
52
- nodes[0].parent.replace(nodes[0].parent.children)
53
- nodes = xmldoc.xpath("//p/admitted_term | //p/termsymbol |
54
- //p/deprecated_term")
55
- end
56
- xmldoc.xpath("//termdef/p/stem").each do |a|
57
- if a.parent.elements.size == 1
58
- # para containing just a stem expression
59
- t = Nokogiri::XML::Element.new("termsymbol", xmldoc)
60
- parent = a.parent
61
- a.remove
62
- t.children = a
63
- parent.replace(t)
64
- end
65
- end
66
- xmldoc.xpath("//p/termdomain").each do |a|
67
- prev = a.parent.previous
68
- a.remove
69
- prev.next = a
70
- end
71
- end
72
-
73
- def isotitle_cleanup(xmldoc)
74
- # Remove italicised ISO titles
75
- xmldoc.xpath("//isotitle").each do |a|
76
- if a.elements.size == 1 && a.elements[0].name == "em"
77
- a.children = a.elements[0].children
13
+ class << self
14
+ def anchor_or_uuid(node = nil)
15
+ uuid = UUIDTools::UUID.random_create
16
+ node.nil? || node.id.nil? || node.id.empty? ? "_" + uuid : node.id
17
+ end
18
+
19
+ def current_location(n)
20
+ return "Line #{n.lineno}" if n.respond_to?(:lineno) &&
21
+ !n.lineno.nil? && !n.lineno.empty?
22
+ return "ID #{n.id}" if n.respond_to?(:id) && !n.id.nil?
23
+ while !n.nil? &&
24
+ (!n.respond_to?(:level) || n.level.positive?) &&
25
+ (!n.respond_to?(:context) || n.context != :section)
26
+ n = n.parent
27
+ return "Section: #{n.title}" if !n.nil? && n.context == :section
78
28
  end
79
- end
80
- end
81
-
82
- def tablenote_cleanup(xmldoc)
83
- # move notes after table footer
84
- xmldoc.xpath("//tfoot/tr/td/note | //tfoot/tr/th/note").each do |n|
85
- target = n.parent.parent.parent.parent
86
- n.remove
87
- target << n
88
- end
89
- end
90
-
91
- def formula_cleanup(xmldoc)
92
- # include where definition list inside stem block
93
- xmldoc.xpath("//formula").each do |s|
94
- if !s.next_element.nil? && s.next_element.name == "p" &&
95
- s.next_element.content == "where" &&
96
- !s.next_element.next_element.nil? &&
97
- s.next_element.next_element.name == "dl"
98
- dl = s.next_element.next_element.remove
99
- s.next_element.remove
100
- s << dl
29
+ "??"
30
+ end
31
+
32
+ def warning(node, msg, text)
33
+ warntext = "asciidoctor: WARNING"\
34
+ "(#{current_location(node)}): #{msg}"
35
+ warntext += ": #{text}" if text
36
+ warn warntext
37
+ end
38
+
39
+ # if node contains blocks, flatten them into a single line;
40
+ # and extract only raw text
41
+ def flatten_rawtext(node)
42
+ result = []
43
+ if node.respond_to?(:blocks) && node.blocks?
44
+ node.blocks.each { |b| result << flatten_rawtext(b) }
45
+ elsif node.respond_to?(:lines)
46
+ node.lines.each do |x|
47
+ if node.respond_to?(:context) && (node.context == :literal ||
48
+ node.context == :listing)
49
+ result << x.gsub(/</, "&lt;").gsub(/>/, "&gt;")
50
+ else
51
+ # strip not only HTML tags <tag>,
52
+ # but also Asciidoc crossreferences <<xref>>
53
+ result << x.gsub(/<[^>]*>+/, "")
54
+ end
55
+ end
56
+ elsif node.respond_to?(:text)
57
+ result << node.text.gsub(/<[^>]*>+/, "")
58
+ else
59
+ result << node.content.gsub(/<[^>]*>+/, "")
101
60
  end
61
+ result.reject(&:empty?)
102
62
  end
103
63
  end
104
64
 
105
- def figure_cleanup(xmldoc)
106
- # include key definition list inside figure
107
- xmldoc.xpath("//figure").each do |s|
108
- if !s.next_element.nil? && s.next_element.name == "p" &&
109
- s.next_element.content =~ /^\s*Key\s*$/m &&
110
- !s.next_element.next_element.nil? &&
111
- s.next_element.next_element.name == "dl"
112
- dl = s.next_element.next_element.remove
113
- s.next_element.remove
114
- s << dl
115
- end
116
- end
117
-
118
- # examples containing only figures become subfigures of figures
119
- nodes = xmldoc.xpath("//example/figure")
120
- while !nodes.empty?
121
- nodes[0].parent.name = "figure"
122
- nodes = xmldoc.xpath("//example/figure")
123
- end
65
+ def convert(node, transform = nil, opts = {})
66
+ transform ||= node.node_name
67
+ opts.empty? ? (send transform, node) : (send transform, node, opts)
124
68
  end
125
69
 
126
- def back_cleanup(xmldoc)
127
- # move annex/bibliography to back
128
- if !xmldoc.xpath("//annex | //bibliography").empty?
129
- b = Nokogiri::XML::Element.new("back", xmldoc)
130
- xmldoc.root << b
131
- xmldoc.xpath("//annex").each do |e|
132
- e.remove
133
- b << e
134
- end
135
- xmldoc.xpath("//bibliography").each do |e|
136
- e.remove
137
- b << e
138
- end
139
- end
70
+ def document_ns_attributes(_doc)
71
+ nil
140
72
  end
141
73
 
142
- def ref_cleanup(xmldoc)
143
- # move ref before p
144
- xmldoc.xpath("//p/ref").each do |r|
145
- parent = r.parent
146
- r.remove
147
- parent.previous = r
148
- end
149
-
150
- xmldoc
151
- end
74
+ NOKOHEAD = <<~HERE
75
+ <!DOCTYPE html SYSTEM
76
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
77
+ <html xmlns="http://www.w3.org/1999/xhtml">
78
+ <head> <title></title> <meta charset="UTF-8" /> </head>
79
+ <body> </body> </html>
80
+ HERE
152
81
 
153
82
  # block for processing XML document fragments as XHTML,
154
83
  # to allow for HTMLentities
155
84
  def noko(&block)
156
- # fragment = ::Nokogiri::XML::DocumentFragment.parse("")
157
- # fragment.doc.create_internal_subset("xml", nil, "xhtml.dtd")
158
- head = <<HERE
159
- <!DOCTYPE html SYSTEM
160
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
161
- <html xmlns="http://www.w3.org/1999/xhtml">
162
- <head> <title></title> <meta charset="UTF-8" /> </head>
163
- <body> </body> </html>
164
- HERE
165
- doc = ::Nokogiri::XML.parse(head)
85
+ doc = ::Nokogiri::XML.parse(NOKOHEAD)
166
86
  fragment = doc.fragment("")
167
87
  ::Nokogiri::XML::Builder.with fragment, &block
168
88
  fragment.to_xml(encoding: "US-ASCII").lines.map do |l|
@@ -177,48 +97,6 @@ HERE
177
97
  end.to_h
178
98
  end
179
99
 
180
- def current_location(node)
181
- if node.respond_to?(:lineno) && !node.lineno.nil? &&
182
- !node.lineno.empty?
183
- return "Line #{node.lineno}"
184
- end
185
- if node.respond_to?(:id) && !node.id.nil?
186
- return "ID #{node.id}"
187
- end
188
- while !node.nil? && (!node.respond_to?(:level) ||
189
- node.level.positive?) && node.context != :section
190
- node = node.parent
191
- if !node.nil? && node.context == :section
192
- return "Section: #{node.title}"
193
- end
194
- end
195
- "??"
196
- end
197
-
198
- # if node contains blocks, flatten them into a single line;
199
- # and extract only raw text
200
- def flatten_rawtext(node)
201
- result = []
202
- if node.respond_to?(:blocks) && node.blocks?
203
- node.blocks.each { |b| result << flatten_rawtext(b) }
204
- elsif node.respond_to?(:lines)
205
- node.lines.each do |x|
206
- if node.respond_to?(:context) && (node.context == :literal ||
207
- node.context == :listing)
208
- result << x.gsub(/</, "&lt;").gsub(/>/, "&gt;")
209
- else
210
- # strip not only HTML tags <tag>,
211
- # but also Asciidoc crossreferences <<xref>>
212
- result << x.gsub(/<[^>]*>+/, "")
213
- end
214
- end
215
- elsif node.respond_to?(:text)
216
- result << node.text.gsub(/<[^>]*>+/, "")
217
- else
218
- result << node.content.gsub(/<[^>]*>+/, "")
219
- end
220
- result.reject(&:empty?)
221
- end
222
100
  end
223
101
  end
224
102
  end