asciidoctor-iso 0.6.0 → 0.6.1

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