asciidoctor-iso 0.6.0 → 0.6.1

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +7 -10
  3. data/README.adoc +118 -6
  4. data/asciidoctor-iso.gemspec +1 -4
  5. data/lib/asciidoctor-iso.rb +2 -0
  6. data/lib/asciidoctor/iso/base.rb +20 -95
  7. data/lib/asciidoctor/iso/blocks.rb +47 -39
  8. data/lib/asciidoctor/iso/cleanup.rb +25 -97
  9. data/lib/asciidoctor/iso/cleanup_block.rb +10 -1
  10. data/lib/asciidoctor/iso/cleanup_ref.rb +100 -0
  11. data/lib/asciidoctor/iso/converter.rb +5 -2
  12. data/lib/asciidoctor/iso/front.rb +52 -24
  13. data/lib/asciidoctor/iso/html/header.html +10 -10
  14. data/lib/asciidoctor/iso/html/html_iso_intro.html +1 -1
  15. data/lib/asciidoctor/iso/html/html_iso_titlepage.html +5 -5
  16. data/lib/asciidoctor/iso/html/htmlstyle.css +0 -21
  17. data/lib/asciidoctor/iso/html/isodoc.css +13 -28
  18. data/lib/asciidoctor/iso/html/word_iso_intro.html +2 -2
  19. data/lib/asciidoctor/iso/html/word_iso_titlepage.html +7 -7
  20. data/lib/asciidoctor/iso/html/wordstyle.css +998 -0
  21. data/lib/asciidoctor/iso/inline.rb +128 -0
  22. data/lib/asciidoctor/iso/isodoc.rng +1516 -0
  23. data/lib/asciidoctor/iso/isostandard.rnc +38 -39
  24. data/lib/asciidoctor/iso/isostandard.rng +529 -1276
  25. data/lib/asciidoctor/iso/isostandard_diff.rnc +40 -56
  26. data/lib/asciidoctor/iso/lists.rb +30 -28
  27. data/lib/asciidoctor/iso/macros.rb +37 -0
  28. data/lib/asciidoctor/iso/section.rb +1 -1
  29. data/lib/asciidoctor/iso/utils.rb +9 -0
  30. data/lib/asciidoctor/iso/validate.rb +41 -120
  31. data/lib/asciidoctor/iso/validate_section.rb +117 -0
  32. data/lib/asciidoctor/iso/validate_style.rb +5 -7
  33. data/lib/asciidoctor/iso/version.rb +1 -1
  34. data/spec/examples/rice.adoc +41 -8
  35. data/spec/examples/rice.doc +2885 -2859
  36. data/spec/examples/rice.html +316 -649
  37. data/spec/examples/rice.preview.html +51 -10
  38. data/spec/examples/rice.xml +418 -343
  39. metadata +12 -50
  40. data/lib/asciidoctor/iso/inline_anchor.rb +0 -59
  41. data/lib/asciidoctor/iso/validate.make.sh +0 -8
@@ -6,23 +6,15 @@ start = iso-standard
6
6
 
7
7
  iso-standard =
8
8
  element iso-standard {
9
- title+,
10
- status,
11
- creator,
12
- language,
13
- script,
14
- type,
15
- id,
16
- version?,
17
- copyright,
18
- sections
9
+ #title+, status, creator, language, script, type, id, version?, copyright, sections
10
+ bibdata, version?, sections+
19
11
  }
20
12
 
21
13
  language =
22
14
  element language { ( "en" | "fr" ) }
23
15
 
24
16
  script =
25
- element script { "latn" }
17
+ element script { "Latn" }
26
18
 
27
19
  # draft into isodoc? To replace version/version?
28
20
  version =
@@ -34,44 +26,47 @@ version =
34
26
 
35
27
  draft = element draft {text}
36
28
 
37
- copyright =
38
- element copyright {
39
- from, owner
29
+ # TODO to docidentifier
30
+ #id =
31
+ #element id {
32
+ #documentnumber,
33
+ #tc-documentnumber?
34
+ #}
35
+
36
+ # add type to docidentifier in isodoc?
37
+ docidentifier =
38
+ element docidentifier {
39
+ ( text | documentnumber | tc-documentnumber )
40
40
  }
41
41
 
42
- owner =
43
- element owner {
44
- owner-affiliation
42
+ # TODO to orgname
43
+ #creator =
44
+ #element creator {
45
+ #attribute role { text },
46
+ #technical-committee,
47
+ #subcommittee?,
48
+ #workgroup?,
49
+ #secretariat?
50
+ #}
51
+
52
+ organization =
53
+ element organization {
54
+ orgname, uri?, org-identifier*, contact*,
55
+ technical-committee?, subcommittee?, workgroup?, secretariat?
45
56
  }
46
57
 
47
- owner-affiliation = element affiliation { "ISO" }
48
-
49
- id =
50
- element id {
51
- documentnumber,
52
- tc-documentnumber?
53
- }
54
-
55
- creator =
56
- element creator {
57
- attribute role { text },
58
- technical-committee,
59
- subcommittee?,
60
- workgroup?,
61
- secretariat?
62
- }
63
-
64
- type =
65
- element type {
66
- ( "international-standard" | "technical-specification" |
67
- "technical-report" | "publicly-available-specification" |
68
- "international-workshop-agreement" | "guide" )
69
- }
58
+ # Do not constrain in XML: add to validation
59
+ # type =
60
+ # element type {
61
+ # ( "international-standard" | "technical-specification" |
62
+ # "technical-report" | "publicly-available-specification" |
63
+ # "international-workshop-agreement" | "guide" )
64
+ # }
70
65
 
71
66
  status =
72
67
  element status {
73
- stage,
74
- substage?
68
+ FormattedString |
69
+ ( stage, substage? )
75
70
  }
76
71
 
77
72
  stage =
@@ -116,10 +111,10 @@ workgroup =
116
111
  secretariat =
117
112
  element secretariat { text }
118
113
 
119
- title =
114
+ btitle =
120
115
  element title {
121
- attribute language { text },
122
- title-intro?, title-main, title-part?
116
+ text |
117
+ ( title-intro?, title-main, title-part? )
123
118
  }
124
119
 
125
120
  title-intro =
@@ -279,17 +274,6 @@ Clause-Section =
279
274
  clause-subsection+
280
275
  )
281
276
 
282
-
283
- BibliographicItem =
284
- attribute id { xsd:ID },
285
- attribute type { "article" | "book" | "booklet" | "conference" | "manual" |
286
- "proceedings" | "presentation" | "thesis" | "techreport" |
287
- "standard" | "unpublished" }?,
288
- (bname | formatted), source?, publishdate?, docidentifier*, accesseddate?, creator*,
289
- publisher*, edition?,
290
- biblionote*, partof*, creationdate?, language*, script*, abstract?
291
-
292
-
293
277
  # }
294
278
 
295
279
 
@@ -7,12 +7,12 @@ module Asciidoctor
7
7
  style(item, item.text)
8
8
  if item.blocks?
9
9
  xml_li.p **id_attr(item) do |t|
10
- t << item.text
10
+ t << item.text
11
11
  end
12
12
  xml_li << item.content
13
13
  else
14
14
  xml_li.p **id_attr(item) do |p|
15
- p << item.text
15
+ p << item.text
16
16
  end
17
17
  end
18
18
  end
@@ -31,40 +31,41 @@ module Asciidoctor
31
31
  end
32
32
 
33
33
  def iso_publisher(t)
34
- t.publisher **{ role: "publisher" } do |p|
35
- p.affiliation do |aff|
34
+ t.contributor do |c|
35
+ c.role **{ type: "publisher" }
36
+ c.organization do |aff|
36
37
  aff.name "ISO"
37
38
  end
38
39
  end
39
40
  end
40
41
 
41
- def isorefmatches(xml, matched)
42
- ref_attributes = { id: matched[:anchor], type: "standard" }
42
+ def isorefmatches(xml, m)
43
+ ref_attributes = { id: m[:anchor], type: "standard" }
43
44
  xml.bibitem **attr_code(ref_attributes) do |t|
44
- t.name { |i| i << ref_normalise(matched[:text]) }
45
- t.publishDate matched[:year] if matched[:year]
46
- t.docidentifier matched[:code]
45
+ t.title **{ format: "text/plain" } { |i| i << ref_normalise(m[:text]) }
46
+ t.docidentifier m[:code]
47
+ t.date m[:year], { type: "published" } if m[:year]
47
48
  iso_publisher(t)
48
49
  end
49
50
  end
50
51
 
51
- def isorefmatches2(xml, matched)
52
- ref_attributes = { id: matched[:anchor], type: "standard" }
52
+ def isorefmatches2(xml, m)
53
+ ref_attributes = { id: m[:anchor], type: "standard" }
53
54
  xml.bibitem **attr_code(ref_attributes) do |t|
54
- t.name { |i| i << ref_normalise(matched[:text]) }
55
- t.publishDate "--"
56
- t.docidentifier matched[:code]
55
+ t.title **{ format: "text/plain" } { |i| i << ref_normalise(m[:text]) }
56
+ t.docidentifier m[:code]
57
+ t.date "--", { type: "published" }
57
58
  iso_publisher(t)
58
- t.note { |p| p << "ISO DATE: #{matched[:fn]}" }
59
+ t.note **{ format: "text/plain" } { |p| p << "ISO DATE: #{m[:fn]}" }
59
60
  end
60
61
  end
61
62
 
62
- def isorefmatches3(xml, matched)
63
- ref_attributes = { id: matched[:anchor], type: "standard" }
63
+ def isorefmatches3(xml, m)
64
+ ref_attributes = { id: m[:anchor], type: "standard" }
64
65
  xml.bibitem **attr_code(ref_attributes) do |t|
65
- t.name { |i| i << ref_normalise(matched[:text]) }
66
- t.publishDate matched[:year] if matched[:year]
67
- t.docidentifier "#{matched[:code]}:All Parts"
66
+ t.title **{ format: "text/plain" } { |i| i << ref_normalise(m[:text]) }
67
+ t.docidentifier "#{m[:code]}:All Parts"
68
+ t.date m[:year], { type: "published" } if m[:year]
68
69
  iso_publisher(t)
69
70
  end
70
71
  end
@@ -74,7 +75,9 @@ module Asciidoctor
74
75
  if m.nil? then Utils::warning(node, "no anchor on reference", item)
75
76
  else
76
77
  xml.bibitem **attr_code(id: m[:anchor]) do |t|
77
- t.formatted { |i| i << ref_normalise_no_format(m[:text]) }
78
+ t.formattedref **{ format: "application/x-isodoc+xml" } do |i|
79
+ i << ref_normalise_no_format(m[:text])
80
+ end
78
81
  code = m[:code]
79
82
  code = "[#{code}]" if /^\d+$?/.match? code
80
83
  t.docidentifier code
@@ -96,15 +99,15 @@ module Asciidoctor
96
99
  end
97
100
 
98
101
  ISO_REF = %r{^<ref\sid="(?<anchor>[^"]+)">
99
- \[ISO\s(?<code>[0-9-]+)(:(?<year>[0-9]+))?\]</ref>,?\s
102
+ \[(?<code>(ISO|IEC)[^0-9]*\s[0-9-]+)(:(?<year>[0-9]+))?\]</ref>,?\s
100
103
  (?<text>.*)$}xm
101
104
 
102
105
  ISO_REF_NO_YEAR = %r{^<ref\sid="(?<anchor>[^"]+)">
103
- \[ISO\s(?<code>[0-9-]+):--\]</ref>,?\s?
106
+ \[(?<code>(ISO|IEC)[^0-9]*\s[0-9-]+):--\]</ref>,?\s?
104
107
  <fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>,?\s?(?<text>.*)$}xm
105
108
 
106
109
  ISO_REF_ALL_PARTS = %r{^<ref\sid="(?<anchor>[^"]+)">
107
- \[ISO\s(?<code>[0-9]+)\s\(all\sparts\)\]</ref>(<p>)?,?\s?
110
+ \[(?<code>(ISO|IEC)[^0-9]*\s[0-9]+)\s\(all\sparts\)\]</ref>(<p>)?,?\s?
108
111
  (?<text>.*)(</p>)?$}xm
109
112
 
110
113
  NON_ISO_REF = %r{^<ref\sid="(?<anchor>[^"]+)">
@@ -122,9 +125,8 @@ module Asciidoctor
122
125
  elsif !matched3.nil? then isorefmatches3(xml, matched3)
123
126
  end
124
127
  if matched3.nil? && matched2.nil? && matched.nil? && normative
125
- Utils::warning(node,
126
- "non-ISO/IEC reference not expected as normative",
127
- item)
128
+ w = "non-ISO/IEC reference not expected as normative"
129
+ Utils::warning(node, w, item)
128
130
  end
129
131
  end
130
132
 
@@ -169,7 +171,7 @@ module Asciidoctor
169
171
  return
170
172
  end
171
173
  xml_dl.dd do |xml_dd|
172
- style(dd, dd.text)
174
+ style(dd, dd.text) if dd.text?
173
175
  xml_dd.p { |t| t << dd.text } if dd.text?
174
176
  xml_dd << dd.content if dd.blocks?
175
177
  end
@@ -0,0 +1,37 @@
1
+ require 'asciidoctor/extensions'
2
+ module Asciidoctor
3
+ module ISO
4
+ class AltTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
5
+ use_dsl
6
+ named :alt
7
+ parse_content_as :text
8
+ using_format :short
9
+
10
+ def process parent, target, attrs
11
+ %{<admitted>#{Asciidoctor::Inline.new(parent, :quoted, attrs['text']).convert}</admitted>}
12
+ end
13
+ end
14
+
15
+ class DeprecatedTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
16
+ use_dsl
17
+ named :deprecated
18
+ parse_content_as :text
19
+ using_format :short
20
+
21
+ def process parent, target, attrs
22
+ %{<deprecates>#{attrs["text"]}</deprecates>}
23
+ end
24
+ end
25
+
26
+ class DomainTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
27
+ use_dsl
28
+ named :domain
29
+ parse_content_as :text
30
+ using_format :short
31
+
32
+ def process parent, target, attrs
33
+ %{<domain>#{attrs["text"]}</domain>}
34
+ end
35
+ end
36
+ end
37
+ end
@@ -131,7 +131,7 @@ module Asciidoctor
131
131
  end
132
132
 
133
133
  def introduction_parse(attrs, xml, node)
134
- xml.content **attr_code(attrs) do |xml_section|
134
+ xml.introduction **attr_code(attrs) do |xml_section|
135
135
  xml_section.title = "Introduction"
136
136
  content = node.content
137
137
  xml_section << content
@@ -97,6 +97,15 @@ module Asciidoctor
97
97
  end.to_h
98
98
  end
99
99
 
100
+ # if the contents of node are blocks, output them to out;
101
+ # else, wrap them in <p>
102
+ def wrap_in_para(node, out)
103
+ if node.blocks? then out << node.content
104
+ else
105
+ out.p { |p| p << node.content }
106
+ end
107
+ end
108
+
100
109
  end
101
110
  end
102
111
  end
@@ -1,5 +1,6 @@
1
1
  require "asciidoctor/iso/utils"
2
- require_relative './validate_style.rb'
2
+ require_relative "./validate_style.rb"
3
+ require_relative "./validate_section.rb"
3
4
  require "nokogiri"
4
5
  require "jing"
5
6
  require "pp"
@@ -7,10 +8,9 @@ require "pp"
7
8
  module Asciidoctor
8
9
  module ISO
9
10
  module Validate
10
-
11
11
  def title_intro_validate(root)
12
- title_intro_en = root.at("//title[@language='en']/title-intro")
13
- title_intro_fr = root.at("//title[@language='fr']/title-intro")
12
+ title_intro_en = root.at("//title-intro[@language='en']")
13
+ title_intro_fr = root.at("//title-intro[@language='fr']")
14
14
  if title_intro_en.nil? && !title_intro_fr.nil?
15
15
  warn "No English Title Intro!"
16
16
  end
@@ -20,8 +20,8 @@ module Asciidoctor
20
20
  end
21
21
 
22
22
  def title_part_validate(root)
23
- title_part_en = root.at("//title[@language='en']/title-part")
24
- title_part_fr = root.at("//title[@language='fr']/title-part")
23
+ title_part_en = root.at("//title-part[@language='en']")
24
+ title_part_fr = root.at("//title-part[@language='fr']")
25
25
  if title_part_en.nil? && !title_part_fr.nil?
26
26
  warn "No English Title Part!"
27
27
  end
@@ -33,11 +33,11 @@ module Asciidoctor
33
33
  def title_names_type_validate(root)
34
34
  doctypes = /International\sStandard | Technical\sSpecification |
35
35
  Publicly\sAvailable\sSpecification | Technical\sReport | Guide /xi
36
- title_main_en = root.at("//title[@language='en']/title-main")
36
+ title_main_en = root.at("//title-main[@language='en']")
37
37
  if doctypes.match? title_main_en.text
38
38
  warn "Main Title may name document type"
39
39
  end
40
- title_intro_en = root.at("//title[@language='en']/title-intro")
40
+ title_intro_en = root.at("//title-intro[@language='en']")
41
41
  if !title_intro_en.nil? && doctypes.match?(title_intro_en.text)
42
42
  warn "Part Title may name document type"
43
43
  end
@@ -54,121 +54,12 @@ module Asciidoctor
54
54
  root.xpath(q).each do |c|
55
55
  next unless c.xpath("../subsection").size == 1
56
56
  title = c.at("./title")
57
- location = if c["id"].nil? && title.nil?
58
- c.text[0..60] + "..."
59
- else
60
- c["id"]
61
- end
62
- location += ":#{title.text}" unless title.nil?
57
+ location = c["id"] || c.text[0..60] + "..."
58
+ location += ":#{title.text}" if c["id"] && !title.nil?
63
59
  warn "ISO style: #{location}: subsection is only child"
64
60
  end
65
61
  end
66
62
 
67
- def foreword_validate(root)
68
- f = root.at("//content[title = 'Foreword']")
69
- s = f.at("./subsection")
70
- warn "ISO style: foreword contains subsections" unless s.nil?
71
- end
72
-
73
- def normref_validate(root)
74
- f = root.at("//references[title = 'Normative References']")
75
- f.at("./references") and
76
- warn "ISO style: normative references contains subsections"
77
- end
78
-
79
- def symbols_validate(root)
80
- f = root.at("//clause[title = 'Symbols and Abbreviations']")
81
- return if f.nil?
82
- f.elements do |e|
83
- unless e.name == "dl"
84
- warn "ISO style: Symbols and Abbreviations can only contain "\
85
- "a definition list"
86
- return
87
- end
88
- end
89
- end
90
-
91
- def seqcheck(names, msg, accepted)
92
- n = names.shift
93
- unless accepted.include? n
94
- warn "ISO style: #{msg}"
95
- names = []
96
- end
97
- names
98
- end
99
-
100
- # spec of permissible section sequence
101
- SEQ = [
102
- {
103
- msg: "Initial section must be (content) Foreword",
104
- val: [{ tag: "content", title: "Foreword" }],
105
- },
106
- {
107
- msg: "Prefatory material must be followed by (clause) Scope",
108
- val: [{ tag: "content", title: "Introduction" },
109
- { tag: "clause", title: "Scope" }],
110
- },
111
- {
112
- msg: "Prefatory material must be followed by (clause) Scope",
113
- val: [{ tag: "clause", title: "Scope" }],
114
- },
115
- {
116
- msg: "Scope must be followed by Normative References",
117
- val: [{ tag: "references", title: "Normative References" }]
118
- },
119
- {
120
- msg: "Normative References must be followed by "\
121
- "Terms and Definitions",
122
- val: [
123
- { tag: "terms", title: "Terms and Definitions" },
124
- { tag: "terms",
125
- title: "Terms, Definitions, Symbols and Abbreviations" }
126
- ]
127
- },
128
- ]
129
-
130
- def sections_sequence_validate(root)
131
- f = root.xpath(" //sections/content | //sections/terms | "\
132
- "//sections/clause | //sections/references | "\
133
- "//sections/annex")
134
- names = f.map { |s| { tag: s.name, title: s.at("./title").text } }
135
- names = seqcheck(names, SEQ[0][:msg], SEQ[0][:val]) or return
136
- n = names[0]
137
- names = seqcheck(names, SEQ[1][:msg], SEQ[1][:val]) or return
138
- if n == { tag: "content", title: "Introduction" }
139
- names = seqcheck(names, SEQ[2][:msg], SEQ[2][:val]) or return
140
- end
141
- names = seqcheck(names, SEQ[3][:msg], SEQ[3][:val]) or return
142
- names = seqcheck(names, SEQ[4][:msg], SEQ[4][:val]) or return
143
- n = names.shift
144
- if n == { tag: "clause", title: "Symbols and Abbreviations" }
145
- n = names.shift or return
146
- end
147
- n[:tag] == "clause" or
148
- warn "ISO style: Document must contain at least one clause"
149
- n == { tag: "clause", title: "Scope" } and
150
- warn "ISO style: Scope must occur before Terms and Definitions"
151
- n = names.shift or return
152
- while n[:tag] == "clause"
153
- n[:title] == "Scope" and
154
- warn "ISO style: Scope must occur before Terms and Definitions"
155
- n[:title] == "Symbols and Abbreviations" and
156
- warn "ISO style: Symbols and Abbreviations must occur "\
157
- "right after Terms and Definitions"
158
- n = names.shift or return
159
- end
160
- unless n[:tag] == "annex" or n[:tag] == "references"
161
- warn "ISO style: Only annexes and references can follow clauses"
162
- end
163
- while n[:tag] == "annex"
164
- n = names.shift or return
165
- end
166
- n == { tag: "references", title: "Bibliography" } or
167
- warn "ISO style: Final section must be (references) Bibliography"
168
- names.empty? or
169
- warn "ISO style: There are sections after the final Bibliography"
170
- end
171
-
172
63
  def iso8601_validate(root)
173
64
  root.xpath("//review/@date | //revision-date").each do |d|
174
65
  /^\d{8}(T\d{4,6})?$/.match? d.text or
@@ -176,8 +67,22 @@ module Asciidoctor
176
67
  end
177
68
  end
178
69
 
70
+ def isosubgroup_validate(root)
71
+ root.xpath("//technical-committee/@type").each do |t|
72
+ unless %w{TC PC JTC JPC}.include? t.text
73
+ warn "ISO: invalid technical committee type #{t}"
74
+ end
75
+ end
76
+ root.xpath("//subcommittee/@type").each do |t|
77
+ unless %w{SC JSC}.include? t.text
78
+ warn "ISO: invalid subcommittee type #{t}"
79
+ end
80
+ end
81
+ end
82
+
179
83
  def content_validate(doc)
180
84
  title_validate(doc.root)
85
+ isosubgroup_validate(doc.root)
181
86
  foreword_validate(doc.root)
182
87
  normref_validate(doc.root)
183
88
  symbols_validate(doc.root)
@@ -199,9 +104,25 @@ module Asciidoctor
199
104
  end
200
105
  end
201
106
 
107
+ # RelaxNG cannot cope well with wildcard attributes. So we strip
108
+ # any attributes from FormattedString instances (which can contain
109
+ # xs:any markup, and are signalled with @format) before validation.
110
+ def formattedstr_strip(doc)
111
+ doc.xpath("//*[@format]").each do |n|
112
+ n.elements.each do |e|
113
+ e.traverse do |e1|
114
+ next unless e1.element?
115
+ e1.each { |k, v| e.delete(k) }
116
+ end
117
+ end
118
+ end
119
+ doc
120
+ end
121
+
202
122
  def validate(doc)
203
123
  content_validate(doc)
204
- schema_validate(doc, File.join(File.dirname(__FILE__), "isostandard.rng"))
124
+ schema_validate(formattedstr_strip(doc.dup),
125
+ File.join(File.dirname(__FILE__), "isostandard.rng"))
205
126
  end
206
127
  end
207
128
  end