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.
- checksums.yaml +4 -4
- data/.gitattributes +2 -0
- data/.gitignore +1 -0
- data/.hound.yml +3 -0
- data/.rubocop.ribose.yml +65 -0
- data/.rubocop.tb.yml +640 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +162 -0
- data/Makefile +39 -0
- data/README.adoc +396 -59
- data/Rakefile +6 -0
- data/asciidoctor-iso.gemspec +11 -3
- data/lib/asciidoctor/iso/base.rb +122 -51
- data/lib/asciidoctor/iso/blocks.rb +119 -108
- data/lib/asciidoctor/iso/cleanup.rb +214 -0
- data/lib/asciidoctor/iso/cleanup_block.rb +157 -0
- data/lib/asciidoctor/iso/converter.rb +5 -3
- data/lib/asciidoctor/iso/front.rb +37 -28
- data/lib/asciidoctor/iso/html/header.html +184 -0
- data/lib/asciidoctor/iso/html/html_iso_intro.html +73 -0
- data/lib/asciidoctor/iso/html/html_iso_titlepage.html +31 -0
- data/lib/asciidoctor/iso/html/htmlstyle.css +67 -0
- data/lib/asciidoctor/iso/html/isodoc.css +679 -0
- data/lib/asciidoctor/iso/html/word_iso_intro.html +72 -0
- data/lib/asciidoctor/iso/html/word_iso_titlepage.html +58 -0
- data/lib/asciidoctor/iso/inline_anchor.rb +20 -26
- data/lib/asciidoctor/iso/isostandard.rnc +177 -0
- data/lib/asciidoctor/iso/isostandard.rng +1478 -0
- data/lib/asciidoctor/iso/isostandard_diff.rnc +295 -0
- data/lib/asciidoctor/iso/lists.rb +152 -109
- data/lib/asciidoctor/iso/section.rb +164 -0
- data/lib/asciidoctor/iso/table.rb +30 -27
- data/lib/asciidoctor/iso/utils.rb +61 -183
- data/lib/asciidoctor/iso/validate.make.sh +8 -0
- data/lib/asciidoctor/iso/validate.rb +195 -24
- data/lib/asciidoctor/iso/validate_style.rb +175 -0
- data/lib/asciidoctor/iso/version.rb +1 -1
- data/spec/examples/rice.adoc +45 -24
- data/spec/examples/rice.doc +17708 -0
- data/spec/examples/rice.html +1574 -1662
- data/spec/examples/rice.preview.html +1811 -0
- data/spec/examples/rice.sh +4 -0
- data/spec/examples/rice.xml +888 -62
- data/spec/examples/rice_images/rice_image1.png +0 -0
- data/spec/examples/rice_images/rice_image2.png +0 -0
- data/spec/examples/rice_images/rice_image3_1.png +0 -0
- data/spec/examples/rice_images/rice_image3_2.png +0 -0
- data/spec/examples/rice_images/rice_image3_3.png +0 -0
- metadata +135 -12
- data/grammar1.gif +0 -0
- data/grammar2.gif +0 -0
- data/grammar3.gif +0 -0
- data/grammar4.gif +0 -0
- data/lib/asciidoctor/iso/validate.rnc +0 -444
- data/lib/asciidoctor/iso/validate.rng +0 -1001
@@ -1,37 +1,208 @@
|
|
1
|
+
require "asciidoctor/iso/utils"
|
2
|
+
require_relative './validate_style.rb'
|
1
3
|
require "nokogiri"
|
4
|
+
require "jing"
|
5
|
+
require "pp"
|
2
6
|
|
3
7
|
module Asciidoctor
|
4
8
|
module ISO
|
5
9
|
module Validate
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
if root.at("//title_en/title_part").nil? &&
|
17
|
-
!root.at("//title_fr/title_part").nil?
|
18
|
-
warn "No English Title Part!"
|
19
|
-
end
|
20
|
-
if !root.at("//title_en/title_part").nil? &&
|
21
|
-
root.at("//title_fr/title_part").nil?
|
22
|
-
warn "No French Title Part!"
|
23
|
-
end
|
10
|
+
|
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")
|
14
|
+
if title_intro_en.nil? && !title_intro_fr.nil?
|
15
|
+
warn "No English Title Intro!"
|
16
|
+
end
|
17
|
+
if !title_intro_en.nil? && title_intro_fr.nil?
|
18
|
+
warn "No French Title Intro!"
|
24
19
|
end
|
20
|
+
end
|
21
|
+
|
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")
|
25
|
+
if title_part_en.nil? && !title_part_fr.nil?
|
26
|
+
warn "No English Title Part!"
|
27
|
+
end
|
28
|
+
if !title_part_en.nil? && title_part_fr.nil?
|
29
|
+
warn "No French Title Part!"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def title_names_type_validate(root)
|
34
|
+
doctypes = /International\sStandard | Technical\sSpecification |
|
35
|
+
Publicly\sAvailable\sSpecification | Technical\sReport | Guide /xi
|
36
|
+
title_main_en = root.at("//title[@language='en']/title-main")
|
37
|
+
if doctypes.match? title_main_en.text
|
38
|
+
warn "Main Title may name document type"
|
39
|
+
end
|
40
|
+
title_intro_en = root.at("//title[@language='en']/title-intro")
|
41
|
+
if !title_intro_en.nil? && doctypes.match?(title_intro_en.text)
|
42
|
+
warn "Part Title may name document type"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def title_validate(root)
|
47
|
+
title_intro_validate(root)
|
48
|
+
title_part_validate(root)
|
49
|
+
title_names_type_validate(root)
|
50
|
+
end
|
51
|
+
|
52
|
+
def onlychild_clause_validate(root)
|
53
|
+
q = "//subsection"
|
54
|
+
root.xpath(q).each do |c|
|
55
|
+
next unless c.xpath("../subsection").size == 1
|
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?
|
63
|
+
warn "ISO style: #{location}: subsection is only child"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
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
|
25
78
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
warn "
|
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
|
32
87
|
end
|
33
88
|
end
|
34
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
|
+
def iso8601_validate(root)
|
173
|
+
root.xpath("//review/@date | //revision-date").each do |d|
|
174
|
+
/^\d{8}(T\d{4,6})?$/.match? d.text or
|
175
|
+
warn "ISO style: #{d.text} is not an ISO 8601 date"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def content_validate(doc)
|
180
|
+
title_validate(doc.root)
|
181
|
+
foreword_validate(doc.root)
|
182
|
+
normref_validate(doc.root)
|
183
|
+
symbols_validate(doc.root)
|
184
|
+
iso8601_validate(doc.root)
|
185
|
+
onlychild_clause_validate(doc.root)
|
186
|
+
sections_sequence_validate(doc.root)
|
187
|
+
end
|
188
|
+
|
189
|
+
def schema_validate(doc, filename)
|
190
|
+
File.open(".tmp.xml", "w") { |f| f.write(doc.to_xml) }
|
191
|
+
begin
|
192
|
+
errors = Jing.new(filename).validate(".tmp.xml")
|
193
|
+
rescue Jing::Error => e
|
194
|
+
abort "what what what #{e}"
|
195
|
+
end
|
196
|
+
warn "Valid!" if errors.none?
|
197
|
+
errors.each do |error|
|
198
|
+
warn "#{error[:message]} @ #{error[:line]}:#{error[:column]}"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def validate(doc)
|
203
|
+
content_validate(doc)
|
204
|
+
schema_validate(doc, File.join(File.dirname(__FILE__), "isostandard.rng"))
|
205
|
+
end
|
35
206
|
end
|
36
207
|
end
|
37
208
|
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require "asciidoctor/iso/utils"
|
2
|
+
require "nokogiri"
|
3
|
+
require "jing"
|
4
|
+
require "pp"
|
5
|
+
|
6
|
+
module Asciidoctor
|
7
|
+
module ISO
|
8
|
+
module Validate
|
9
|
+
|
10
|
+
REQUIREMENT_RE_STR = <<~REGEXP
|
11
|
+
\\b
|
12
|
+
( shall | (is|are)_to |
|
13
|
+
(is|are)_required_(not_)?to |
|
14
|
+
has_to |
|
15
|
+
only\\b[^.,]+\\b(is|are)_permitted |
|
16
|
+
it_is_necessary |
|
17
|
+
(needs|need)_to |
|
18
|
+
(is|are)_not_(allowed | permitted |
|
19
|
+
acceptable | permissible) |
|
20
|
+
(is|are)_not_to_be |
|
21
|
+
(need|needs)_not |
|
22
|
+
do_not )
|
23
|
+
\\b
|
24
|
+
REGEXP
|
25
|
+
REQUIREMENT_RE =
|
26
|
+
Regexp.new(REQUIREMENT_RE_STR.gsub(/\s/, "").gsub(/_/, "\\s"),
|
27
|
+
Regexp::IGNORECASE)
|
28
|
+
|
29
|
+
def requirement(text)
|
30
|
+
text.split(/\.\s+/).each do |t|
|
31
|
+
return t if REQUIREMENT_RE.match? t
|
32
|
+
end
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
RECOMMENDATION_RE_STR = <<~REGEXP
|
37
|
+
\\b
|
38
|
+
should |
|
39
|
+
ought_(not_)?to |
|
40
|
+
it_is_(not_)?recommended_that
|
41
|
+
\\b
|
42
|
+
REGEXP
|
43
|
+
RECOMMENDATION_RE =
|
44
|
+
Regexp.new(RECOMMENDATION_RE_STR.gsub(/\s/, "").gsub(/_/, "\\s"),
|
45
|
+
Regexp::IGNORECASE)
|
46
|
+
|
47
|
+
def recommendation(text)
|
48
|
+
text.split(/\.\s+/).each do |t|
|
49
|
+
return t if RECOMMENDATION_RE.match? t
|
50
|
+
end
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
54
|
+
PERMISSION_RE_STR = <<~REGEXP
|
55
|
+
\\b
|
56
|
+
may |
|
57
|
+
(is|are)_(permitted | allowed | permissible ) |
|
58
|
+
it_is_not_required_that |
|
59
|
+
no\\b[^.,]+\\b(is|are)_required
|
60
|
+
\\b
|
61
|
+
REGEXP
|
62
|
+
PERMISSION_RE =
|
63
|
+
Regexp.new(PERMISSION_RE_STR.gsub(/\s/, "").gsub(/_/, "\\s"),
|
64
|
+
Regexp::IGNORECASE)
|
65
|
+
|
66
|
+
def permission(text)
|
67
|
+
text.split(/\.\s+/).each do |t|
|
68
|
+
return t if PERMISSION_RE.match? t
|
69
|
+
end
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
|
73
|
+
POSSIBILITY_RE_STR = <<~REGEXP
|
74
|
+
\\b
|
75
|
+
can | cannot | be_able_to |
|
76
|
+
there_is_a_possibility_of |
|
77
|
+
it_is_possible_to | be_unable_to |
|
78
|
+
there_is_no_possibility_of |
|
79
|
+
it_is_not_possible_to
|
80
|
+
\\b
|
81
|
+
REGEXP
|
82
|
+
POSSIBILITY_RE =
|
83
|
+
Regexp.new(POSSIBILITY_RE_STR.gsub(/\s/, "").gsub(/_/, "\\s"),
|
84
|
+
Regexp::IGNORECASE)
|
85
|
+
|
86
|
+
def posssibility(text)
|
87
|
+
text.split(/\.\s+/).each do |t|
|
88
|
+
return t if POSSIBILITY_RE.match? t
|
89
|
+
end
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
|
93
|
+
def external_constraint(text)
|
94
|
+
text.split(/\.\s+/).each do |t|
|
95
|
+
return t if /\b(must)\b/xi.match? t
|
96
|
+
end
|
97
|
+
nil
|
98
|
+
end
|
99
|
+
|
100
|
+
def style_no_guidance(node, text, docpart)
|
101
|
+
r = requirement(text)
|
102
|
+
style_warning(node, "#{docpart} may contain requirement", r) if r
|
103
|
+
r = permission(text)
|
104
|
+
style_warning(node, "#{docpart} may contain permission", r) if r
|
105
|
+
r = recommendation(text)
|
106
|
+
style_warning(node, "#{docpart} may contain recommendation", r) if r
|
107
|
+
end
|
108
|
+
|
109
|
+
def foreword_style(node, text)
|
110
|
+
style_no_guidance(node, text, "Foreword")
|
111
|
+
end
|
112
|
+
|
113
|
+
def scope_style(node, text)
|
114
|
+
style_no_guidance(node, text, "Scope")
|
115
|
+
end
|
116
|
+
|
117
|
+
def introduction_style(node, text)
|
118
|
+
r = requirement(text)
|
119
|
+
style_warning(node, "Introduction may contain requirement", r) if r
|
120
|
+
end
|
121
|
+
|
122
|
+
def termexample_style(node, text)
|
123
|
+
style_no_guidance(node, text, "Term Example")
|
124
|
+
style(node, text)
|
125
|
+
end
|
126
|
+
|
127
|
+
def note_style(node, text)
|
128
|
+
style_no_guidance(node, text, "Note")
|
129
|
+
style(node, text)
|
130
|
+
end
|
131
|
+
|
132
|
+
def footnote_style(node, text)
|
133
|
+
style_no_guidance(node, text, "Footnote")
|
134
|
+
style(node, text)
|
135
|
+
end
|
136
|
+
|
137
|
+
def style_warning(node, msg, text)
|
138
|
+
w = "ISO style: WARNING (#{Utils::current_location(node)}): #{msg}"
|
139
|
+
w += ": #{text}" if text
|
140
|
+
warn w
|
141
|
+
end
|
142
|
+
|
143
|
+
# style check with a single regex
|
144
|
+
def style_single_regex(n, text, re, warning)
|
145
|
+
m = re.match(text) and style_warning(n, warning, m[:num])
|
146
|
+
end
|
147
|
+
|
148
|
+
# style check with a regex on a token
|
149
|
+
# and a negative match on its preceding token
|
150
|
+
def style_two_regex_not_prev(n, text, re, re_prev, warning)
|
151
|
+
return if text.nil?
|
152
|
+
words = text.split(/\W+/).each_index do |i|
|
153
|
+
next if i == 0
|
154
|
+
m = re.match text[i]
|
155
|
+
m_prev = re_prev.match text[i - 1]
|
156
|
+
if !m.nil? && m_prev.nil?
|
157
|
+
style_warning(n, warning, m[:num])
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def style(n, text)
|
163
|
+
style_single_regex(n, text, /\b(?<num>[0-9]+\.[0-9]+)\b/,
|
164
|
+
"possible decimal point")
|
165
|
+
style_two_regex_not_prev(n, text, /^(?<num>[0-9]{4,})$/,
|
166
|
+
%r{(\bISO|\bIEC|\bIEEE|/)$},
|
167
|
+
"number not broken up in threes")
|
168
|
+
style_single_regex(n, text, /\b(?<num>[0-9.,]+%)/,
|
169
|
+
"no space before percent sign")
|
170
|
+
style_single_regex(n, text, /\b(?<num>[0-9.,]+ \u00b1 [0-9,.]+ %)/,
|
171
|
+
"unbracketed tolerance before percent sign")
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
data/spec/examples/rice.adoc
CHANGED
@@ -11,11 +11,11 @@
|
|
11
11
|
:title-main-en: Specifications and test methods
|
12
12
|
:title-part-en: Rice
|
13
13
|
:title-intro-fr: Céréales et légumineuses
|
14
|
-
:title-main-fr: Spécification et
|
14
|
+
:title-main-fr: Spécification et méthodes d'essai
|
15
15
|
:title-part-fr: Riz
|
16
16
|
:doctype: international-standard
|
17
|
-
:docstage:
|
18
|
-
:docsubstage:
|
17
|
+
:docstage: 30
|
18
|
+
:docsubstage: 92
|
19
19
|
:technical-committee-number: 34
|
20
20
|
:technical-committee: Food products
|
21
21
|
:subcommittee-number: 4
|
@@ -23,7 +23,7 @@
|
|
23
23
|
:workgroup-number: 3
|
24
24
|
:workgroup: Rice Group
|
25
25
|
:toc:
|
26
|
-
:sectnumlevels:
|
26
|
+
:sectnumlevels: 7
|
27
27
|
:stem:
|
28
28
|
:xrefstyle: short
|
29
29
|
:appendix-caption: Annex
|
@@ -33,7 +33,8 @@
|
|
33
33
|
:example-caption: Figure
|
34
34
|
|
35
35
|
.Foreword
|
36
|
-
ISO (the International Organization for Standardization)
|
36
|
+
ISO (the International Organization for Standardization)
|
37
|
+
is a worldwide federation of national standards bodies (ISO member bodies). The work of preparing International Standards is normally carried out through ISO technical committees. Each member body interested in a subject for which a technical committee has been established has the right to be represented on that committee. International organizations, governmental and non-governmental, in liaison with ISO, also take part in the work. ISO collaborates closely with the International Electrotechnical Commission (IEC) on all matters of electrotechnical standardization.
|
37
38
|
|
38
39
|
The procedures used to develop this document and those intended for its further maintenance are described in the ISO/IEC Directives, Part 1. In particular the different approval criteria needed for the different types of ISO documents should be noted. This document was drafted in accordance with the editorial rules of the ISO/IEC Directives, Part 2 (see www.iso.org/directives).
|
39
40
|
|
@@ -72,6 +73,7 @@ ISO takes no position concerning the evidence, validity and scope of this patent
|
|
72
73
|
|
73
74
|
The holder of this patent right has assured ISO that he/she is willing to negotiate licences under reasonable and non-discriminatory terms and conditions with applicants throughout the world. In this respect, the statement of the holder of this patent right is registered with ISO. Information may be obtained from:
|
74
75
|
|
76
|
+
[align=left]
|
75
77
|
Vache Equipment +
|
76
78
|
Fictitious +
|
77
79
|
World +
|
@@ -134,7 +136,7 @@ rice retaining its husk after threshing
|
|
134
136
|
_paddy_ (<<paddy>>) from which the husk only has been removed
|
135
137
|
|
136
138
|
[.source]
|
137
|
-
<<ISO7301>>, 3.2,
|
139
|
+
<<ISO7301>>, 3.2, The term "cargo rice" is shown as deprecated, and Note 1 to entry is not included here
|
138
140
|
|
139
141
|
=== milled rice
|
140
142
|
[alt]#white rice#
|
@@ -246,10 +248,12 @@ The mass fraction of extraneous matter and defective kernels in husked and mille
|
|
246
248
|
|
247
249
|
NOTE: Lower mass fractions of moisture are sometimes needed for certain destinations depending on the climate, duration of transport and storage. For further details, see <<ISO6322-1>>, <<ISO6322-2>> and <<ISO6322-3>>.
|
248
250
|
|
251
|
+
==== {blank}
|
252
|
+
|
249
253
|
The defect tolerance for the categories considered, and determined in accordance with the method given in <<AnnexA>>, shall not exceed the limits given in <<table1>>.
|
250
254
|
|
251
255
|
[#table1]
|
252
|
-
[cols="<,^,^,^,^",options="footer"]
|
256
|
+
[cols="<,^,^,^,^",options="header,footer",headerrows=2]
|
253
257
|
.Maximum permissible mass fraction of defects
|
254
258
|
|===
|
255
259
|
.2+|Defect 4+^| Maximum permissible mass fraction of defects in husked rice +
|
@@ -275,13 +279,14 @@ stem:[w_max]
|
|
275
279
|
| Waxy rice | 1,0 footnoteref:[defectsmass] | 1,0 | 1,0 footnoteref:[defectsmass] | 1,0
|
276
280
|
|
277
281
|
5+a| Live insects shall not be present. Dead insects shall be included in extraneous matter.
|
282
|
+
|===
|
278
283
|
|
279
284
|
NOTE: This table is based on <<ISO7301>>, Table 1.
|
280
285
|
|
281
286
|
NOTE: Some commercial contracts require information in addition to that provided in this table.
|
282
287
|
|
283
288
|
NOTE: Only full red husked (cargo) rice is considered in this table.
|
284
|
-
|
289
|
+
|
285
290
|
|
286
291
|
[[clause5]]
|
287
292
|
== Sampling
|
@@ -368,15 +373,15 @@ For each test method, the test report shall specify the following:
|
|
368
373
|
|
369
374
|
The packaging shall not transmit any odour or flavour to the product and shall not contain substances which may damage the product or constitute a health risk.
|
370
375
|
|
371
|
-
If bags are used, they shall comply with the requirements of <<ISO8531-1>>, Clause 9, or <<ISO8351-2
|
376
|
+
If bags are used, they shall comply with the requirements of <<ISO8531-1>>, Clause 9, or <<ISO8351-2>>, as appropriate.
|
372
377
|
|
373
378
|
== Marking
|
374
379
|
|
375
380
|
The packages shall be marked or labelled as required by the country of destination.
|
376
381
|
|
377
382
|
[[AnnexA]]
|
378
|
-
[appendix]
|
379
|
-
== Determination of defects
|
383
|
+
[appendix,subtype=normative]
|
384
|
+
== Determination of defects
|
380
385
|
|
381
386
|
// "normative" follows title
|
382
387
|
=== Principle
|
@@ -387,27 +392,33 @@ Extraneous matter, broken kernels, damaged kernels and other kinds of rice are s
|
|
387
392
|
|
388
393
|
The usual laboratory apparatus and, in particular, the following.
|
389
394
|
|
390
|
-
|
395
|
+
[%inline-header]
|
391
396
|
[[AnnexA-2-1]]
|
392
397
|
==== Sample divider,
|
393
398
|
|
394
399
|
consisting of a conical sample divider or multiple-slot sample divider with a distribution system, e.g. "Split-it-right" sample divider, such as that shown in <<figureA-1>>.
|
395
400
|
|
401
|
+
[%inline-header]
|
396
402
|
==== Sieve,
|
397
403
|
|
398
404
|
with round perforations of diameter 1,4 mm.
|
399
405
|
|
406
|
+
[%inline-header]
|
400
407
|
==== Tweezers.
|
401
408
|
|
409
|
+
[%inline-header]
|
402
410
|
==== Scalpel.
|
403
411
|
|
412
|
+
[%inline-header]
|
404
413
|
==== Paintbrush.
|
405
414
|
|
415
|
+
[%inline-header]
|
406
416
|
[[AnnexA-2-6]]
|
407
417
|
==== Steel bowls,
|
408
418
|
|
409
419
|
of diameter 100 mm ± 5 mm; seven per test sample.
|
410
420
|
|
421
|
+
[%inline-header]
|
411
422
|
==== Balance,
|
412
423
|
|
413
424
|
which can be read to the nearest 0,01 g.
|
@@ -427,11 +438,11 @@ All parts of kernels which get stuck in the perforations of a sieve should be co
|
|
427
438
|
|
428
439
|
[[figureA-1]]
|
429
440
|
.Split-it-right sample divider
|
430
|
-
image::
|
441
|
+
image::rice_images/rice_image1.png[]
|
431
442
|
|
432
443
|
=== Determination
|
433
444
|
|
434
|
-
Weigh, to the nearest 0,1 g, one of the test samples obtained in accordance with <<AnnexA-4-1>> and separate the different defects into the bowls (<<AnnexA-2-6>>). When a kernel has several defects, classify it in the defect category for which the maximum permissible value is the lowest (see <<table1
|
445
|
+
Weigh, to the nearest 0,1 g, one of the test samples obtained in accordance with <<AnnexA-4-1>> and separate the different defects into the bowls (<<AnnexA-2-6>>). When a kernel has several defects, classify it in the defect category for which the maximum permissible value is the lowest (see <<table1>>).
|
435
446
|
|
436
447
|
Weigh, to the nearest 0,01 g, the fractions so obtained.
|
437
448
|
|
@@ -442,7 +453,7 @@ Express the mass fraction of each defect using Formula (<<formulaA-1>>):
|
|
442
453
|
[[formulaA-1,A.1]]
|
443
454
|
[stem]
|
444
455
|
++++
|
445
|
-
w = m_D/m_s
|
456
|
+
w = (m_D) / (m_s)
|
446
457
|
++++
|
447
458
|
|
448
459
|
where
|
@@ -457,7 +468,7 @@ Report the results as specified in <<clause7>>.
|
|
457
468
|
|
458
469
|
[[AnnexB]]
|
459
470
|
[appendix]
|
460
|
-
== Determination of the waxy rice content of parboiled rice
|
471
|
+
== Determination of the waxy rice content of parboiled rice
|
461
472
|
|
462
473
|
=== Principle
|
463
474
|
|
@@ -467,32 +478,39 @@ Waxy rice kernels have a reddish brown colour when stained in an iodine solution
|
|
467
478
|
|
468
479
|
The usual laboratory apparatus and, in particular, the following.
|
469
480
|
|
481
|
+
[%inline-header]
|
470
482
|
[[AnnexB-2-1]]
|
471
483
|
==== Balance,
|
472
484
|
|
473
485
|
capable of weighing to the nearest 0,01 g.
|
474
486
|
|
487
|
+
[%inline-header]
|
475
488
|
[[AnnexB-2-2]]
|
476
489
|
==== Glass beaker,
|
477
490
|
|
478
491
|
of capacity 250 ml.
|
479
492
|
|
493
|
+
[%inline-header]
|
480
494
|
[[AnnexB-2-3]]
|
481
495
|
==== Small white colour bowls,
|
482
496
|
|
483
497
|
or any white colour container of a suitable size.
|
484
498
|
|
499
|
+
[%inline-header]
|
485
500
|
[[AnnexB-2-4]]
|
486
501
|
==== Wire sieve,
|
487
502
|
|
488
503
|
with long rounded apertures of (1 mm stem:[{:(+0.02),(0):}] mm) × (20 mm stem:[{:(+2),(-1):}] mm).
|
489
504
|
|
505
|
+
[%inline-header]
|
490
506
|
[[AnnexB-2-5]]
|
491
507
|
==== Stirrer rod.
|
492
508
|
|
509
|
+
[%inline-header]
|
493
510
|
[[AnnexB-2-6]]
|
494
511
|
==== Tweezers or forceps.
|
495
512
|
|
513
|
+
[%inline-header]
|
496
514
|
[[AnnexB-2-7]]
|
497
515
|
==== Tissue paper.
|
498
516
|
|
@@ -500,16 +518,19 @@ with long rounded apertures of (1 mm stem:[{:(+0.02),(0):}] mm) × (20 mm s
|
|
500
518
|
|
501
519
|
WARNING: Direct contact of iodine with skin can cause lesions so care should be taken in handling iodine. Iodine vapour is very irritating to eyes and mucous membranes.
|
502
520
|
|
521
|
+
[%inline-header]
|
503
522
|
[[AnnexB-3-1]]
|
504
523
|
==== Deionized water,
|
505
524
|
|
506
525
|
Grade 3 quality as specified in <<ISO3696>>.
|
507
526
|
|
527
|
+
[%inline-header]
|
508
528
|
[[AnnexB-3-2]]
|
509
529
|
==== Iodine stock solution,
|
510
530
|
|
511
531
|
containing a mass fraction of 4,1 % iodine and 6,3 % potassium iodide in deionized water such as Lugols.footnote:[Lugols is an example of a suitable product available commercially. This information is given for the convenience of users of this document and does not constitute an endorsement by ISO of this product.]
|
512
532
|
|
533
|
+
[%inline-header]
|
513
534
|
[[AnnexB-3-3]]
|
514
535
|
==== Iodine working solution,
|
515
536
|
|
@@ -546,7 +567,7 @@ Calculate the mass fraction, expressed as a percentage, of the waxy rice, stem:[
|
|
546
567
|
[[formulaB-1,B.1]]
|
547
568
|
[stem]
|
548
569
|
++++
|
549
|
-
w_(wax) = m_1/(m_1 + m_2) xx 100
|
570
|
+
w_(wax) = (m_1) / (m_1 + m_2) xx 100
|
550
571
|
++++
|
551
572
|
|
552
573
|
where
|
@@ -559,15 +580,15 @@ stem:[m_2]:: is the mass, expressed in grams, of the non-waxy rice portion.
|
|
559
580
|
Report the results as specified in <<clause7>>, giving the results calculated using Formula (<<formulaB-1>>).
|
560
581
|
|
561
582
|
[[AnnexC]]
|
562
|
-
[appendix]
|
563
|
-
== Gelatinization
|
583
|
+
[appendix,subtype=informative]
|
584
|
+
== Gelatinization
|
564
585
|
|
565
586
|
<<figureC-1>> gives an example of a typical gelatinization curve. <<figureC-2>> shows the three stages of gelatinization.
|
566
587
|
|
567
588
|
[[figureC-1]]
|
568
589
|
.Typical gelatinization curve
|
569
590
|
// Footnote macro cannot contain stem macro!
|
570
|
-
image::
|
591
|
+
image::rice_images/rice_image2.png[]
|
571
592
|
footnote:[The time stem:[t_90] was estimated to be 18,2 min for this example.]
|
572
593
|
|
573
594
|
*Key*
|
@@ -583,19 +604,19 @@ NOTE: These results are based on a study carried out on three different types of
|
|
583
604
|
.Stages of gelatinization
|
584
605
|
====
|
585
606
|
.Initial stages: No grains are fully gelatinized (ungelatinized starch granules are visible inside the kernels)
|
586
|
-
image::
|
607
|
+
image::rice_images/rice_image3_1.png[]
|
587
608
|
|
588
609
|
.Intermediate stages: Some fully gelatinized kernels are visible
|
589
|
-
image::
|
610
|
+
image::rice_images/rice_image3_2.png[]
|
590
611
|
|
591
612
|
.Final stages: All kernels are fully gelatinized
|
592
|
-
image::
|
613
|
+
image::rice_images/rice_image3_3.png[]
|
593
614
|
|
594
615
|
====
|
595
616
|
|
596
617
|
[[AnnexD]]
|
597
618
|
[appendix]
|
598
|
-
== Results of interlaboratory test for husked rice yields
|
619
|
+
== Results of interlaboratory test for husked rice yields
|
599
620
|
|
600
621
|
An interlaboratory test <<ref15>> was carried out by the ENR [Rice Research Centre (Italy)] in accordance with <<ISO5725-1>> and <<ISO5725-2>>, with the participation of 15 laboratories. Each laboratory carried out three determinations on four different types of kernel. The statistical results are shown in <<tableD-1>>.
|
601
622
|
|