asciidoctor-iso 0.0.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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