metanorma-iso 1.0.8 → 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -7
- data/README.adoc +30 -364
- data/docs/adopting-spec.adoc +72 -0
- data/docs/adopting-toolchain.adoc +389 -0
- data/docs/asciiiso-syntax.adoc +305 -0
- data/docs/customisation.adoc +5 -643
- data/docs/guidance.adoc +73 -64
- data/docs/localizing-output.adoc +57 -0
- data/docs/navigation.adoc +23 -0
- data/docs/quickstart.adoc +106 -304
- data/docs/replacing-asciidoc.adoc +15 -0
- data/docs/styling-output-html.adoc +37 -0
- data/docs/styling-output-msword.adoc +38 -0
- data/lib/asciidoctor/iso/biblio.rng +10 -0
- data/lib/asciidoctor/iso/cleanup.rb +24 -0
- data/lib/asciidoctor/iso/front.rb +32 -5
- data/lib/asciidoctor/iso/isodoc.rng +3 -0
- data/lib/asciidoctor/iso/isostandard.rng +6 -0
- data/lib/asciidoctor/iso/validate.rb +2 -1
- data/lib/isodoc/iso/html/html_iso_titlepage.html +2 -2
- data/lib/isodoc/iso/html/style-human.scss +1 -1
- data/lib/isodoc/iso/html/style-iso.scss +1 -1
- data/lib/isodoc/iso/html/word_iso_titlepage.html +2 -2
- data/lib/isodoc/iso/metadata.rb +8 -13
- data/lib/metanorma/iso/version.rb +1 -1
- data/spec/asciidoctor-iso/base_spec.rb +17 -13
- data/spec/asciidoctor-iso/refs_spec.rb +0 -3
- data/spec/asciidoctor-iso/validate_spec.rb +2 -0
- data/spec/assets/iso.doc +12 -12
- data/spec/assets/iso.html +1 -1
- data/spec/examples/rice.preview.html +25 -25
- data/spec/isodoc/metadata_spec.rb +8 -6
- data/spec/isodoc/postproc_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -3
- metadata +10 -2
@@ -0,0 +1,305 @@
|
|
1
|
+
= AsciiISO syntax reference
|
2
|
+
|
3
|
+
AsciiISO is syntax based on AsciiDoc, with some extensions specific to authoring ISO documents.
|
4
|
+
|
5
|
+
== ISO specific syntax
|
6
|
+
|
7
|
+
TIP: Full details of Asciidoctor-ISO–specific markup and conventions is given in the https://github.com/riboseinc/metanorma-iso/blob/master/README.adoc[Asciidoctor-ISO Readme] and the https://github.com/riboseinc/metanorma-iso/wiki/Guidance-for-authoring[Guidance for authoring].
|
8
|
+
|
9
|
+
The sections that have a fixed position according to ISO/IEC DIR 2 (Introduction, Scope, Normative References, Terms and Definitions, Symbols and Abbreviations, Bibliography) need to be titled as such, as first-level headings.
|
10
|
+
|
11
|
+
== AsciiDoc syntax supported
|
12
|
+
|
13
|
+
The Rice document illustrates almost the full range of formatting available via Asciidoctor; Annex E (which is not in the original) illustrates features not demonstrated in the original document.
|
14
|
+
|
15
|
+
Syntax includes the following; the links are to the Asciidoctor User Manual. All examples are taken from the Metanorma Asciidoctor Rice document.
|
16
|
+
|
17
|
+
=== https://asciidoctor.org/docs/user-manual/#doc-header[Document header]
|
18
|
+
|
19
|
+
Attributes of the document, which typically appear in the coverpage (if at all), rather than in the document proper. The permitted attributes for all Metanorma documents, and their expected values, are documented in the https://github.com/riboseinc/metanorma-standoc#document-attributes[metanorma-standoc Readme]; each standards-specific gem adds documentation of its own specific attributes (e.g. https://github.com/riboseinc/metanorma-iso#document-attributes).
|
20
|
+
|
21
|
+
Note that the initial title line and author line expected in Asciidoctor are ignored in favour of specific document attributes, although they still need to be supplied for the document to be valid.
|
22
|
+
|
23
|
+
[source,asciidoctor]
|
24
|
+
--
|
25
|
+
= Rice model
|
26
|
+
Author
|
27
|
+
:docnumber: 17301
|
28
|
+
:revdate: 2010-01-02
|
29
|
+
:title: Cereals and pulses -- Specifications and test methods -- Rice
|
30
|
+
:language: en
|
31
|
+
:status: published
|
32
|
+
|
33
|
+
...
|
34
|
+
--
|
35
|
+
|
36
|
+
=== Inline formatting
|
37
|
+
|
38
|
+
* https://asciidoctor.org/docs/user-manual/#text-formatting[Formatting marks]: bold, italic, monospace, subscript, superscript
|
39
|
+
|
40
|
+
[source,asciidoctor]
|
41
|
+
--
|
42
|
+
This document specifies minimum requirements and test methods for rice (_Oryza sativa L._).
|
43
|
+
--
|
44
|
+
|
45
|
+
* https://asciidoctor.org/docs/user-manual/#anchordef[Anchors] (for internal cross-references): these can be defined for any section or subsection, and any block (e.g. images, lists, examples, formulas, and so forth). The numbering of all blocks and clauses is automated, and does not need to be provided in the text.
|
46
|
+
* https://asciidoctor.org/docs/user-manual/#internal-cross-references[Internal Cross-references] reference anchors within the document. By default, the text for these is also automatically generated, including naming the container of a block where required (e.g. `B.6, Formula (B.1)` for a formula in an annex). However, cross-references can supply their own text as an override, following a comma (e.g. `<``<AnnexB,the following annex>``>`).
|
47
|
+
|
48
|
+
[source,asciidoctor]
|
49
|
+
--
|
50
|
+
The International Organization for Standardization (ISO) draws attention to the fact that it is claimed that compliance with this document may involve the use of a patent concerning sample dividers given in <<AnnexA>> and shown in <<figureA-1>>.
|
51
|
+
|
52
|
+
...
|
53
|
+
[[figureA-1]]
|
54
|
+
.Split-it-right sample divider
|
55
|
+
image::images/rice_image1.png[]
|
56
|
+
--
|
57
|
+
|
58
|
+
* https://asciidoctor.org/docs/user-manual/#url[URLs]
|
59
|
+
|
60
|
+
[source,asciidoctor]
|
61
|
+
--
|
62
|
+
http://www.iso.org/obp[OBP]
|
63
|
+
--
|
64
|
+
|
65
|
+
* https://asciidoctor.org/docs/user-manual/#activating-stem-support[STEM support] (mathematical expressions), as both inline and block formatting. (Numbered formulae are expressed as stem blocks.) Asciidoctor natively uses http://asciimath.org[AsciiMath] for its mathematical expressions; the `:stem:` document attribute must be present for AsciiMath to be recognised. The gem will ensure that any AsciiMath is rendered in the HTML output, and converted to Microsoft Office's OOXML (via MathML) in the Word output. Asciidoctor also supports LaTeX, but the gem does not cater for converting LaTeX to a Word-compatible output.
|
66
|
+
|
67
|
+
[source,asciidoctor]
|
68
|
+
--
|
69
|
+
[[formulaA-1,A.1]]
|
70
|
+
[stem]
|
71
|
+
++++
|
72
|
+
w = (m_D) / (m_s)
|
73
|
+
++++
|
74
|
+
|
75
|
+
where
|
76
|
+
|
77
|
+
stem:[w]:: is the mass fraction of grains with a particular defect in the test sample;
|
78
|
+
--
|
79
|
+
|
80
|
+
* https://asciidoctor.org/docs/user-manual/#user-footnotes[Footnotes]. Note that footnotes are treated as inline formatting, so they cannot straightforwardly span more than a single paragraph in Asciidoctor. Footnotes within figures and tables are rendered within their blocks.
|
81
|
+
|
82
|
+
[source,asciidoctor]
|
83
|
+
--
|
84
|
+
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.]
|
85
|
+
--
|
86
|
+
|
87
|
+
=== Blocks
|
88
|
+
|
89
|
+
Blocks are groupings of paragraphs and text into larger units, commonly https://asciidoctor.org/docs/user-manual/#delimited-blocks[delimited], and optionally including a https://asciidoctor.org/docs/user-manual/#title[title] and https://asciidoctor.org/docs/user-manual/#metadata-2[metadata].
|
90
|
+
|
91
|
+
TIP: For UNECE, paragraph numbering is generated automatically by the gem, which treats each paragraph as a leaf-node section. Paragraph numbers must not be entered in the Asciidoctor source.
|
92
|
+
|
93
|
+
* https://asciidoctor.org/docs/user-manual/#unordered-lists[Unordered lists]
|
94
|
+
|
95
|
+
[source,asciidoctor]
|
96
|
+
--
|
97
|
+
The main changes compared to the previous edition are:
|
98
|
+
|
99
|
+
* updated normative references;
|
100
|
+
* deletion of 4.3.
|
101
|
+
--
|
102
|
+
|
103
|
+
* https://asciidoctor.org/docs/user-manual/#ordered-lists[Ordered lists]. The gem automatically creates labels for the nested levels of ordered lists (in the sequence lowercase letter–Arabic numeral–lowercase Roman numeral–upppercase letter–uppercase Roman numeral), and ignores any https://asciidoctor.org/docs/user-manual/#numbering-styles[numbering styles] indicated by the user.
|
104
|
+
|
105
|
+
[source,asciidoctor]
|
106
|
+
--
|
107
|
+
. the sampling method used;
|
108
|
+
. the test method used;
|
109
|
+
. the test result(s) obtained or, if the repeatability has been checked, the final quoted result obtained;
|
110
|
+
--
|
111
|
+
|
112
|
+
* https://asciidoctor.org/docs/user-manual/#labeled-list[Definition lists]. These are used for all keys of figures and formulae, and as the content of Symbols and Abbreviations clauses and subclauses:
|
113
|
+
|
114
|
+
[source,asciidoctor]
|
115
|
+
--
|
116
|
+
stem:[w]:: is the mass fraction of grains with a particular defect in the test sample;
|
117
|
+
stem:[m_D]:: is the mass, in grams, of grains with that defect;
|
118
|
+
stem:[m_S]:: is the mass, in grams, of the test sample.
|
119
|
+
--
|
120
|
+
|
121
|
+
Note that the key to a figure must be preceded by the paragraph `*Key*`, and the key to a formula must be preceded by the paragraph `where`.
|
122
|
+
|
123
|
+
* https://asciidoctor.org/docs/user-manual/#tables[Tables]. Asciidoctor supports a rich range of table formatting:
|
124
|
+
|
125
|
+
[source,asciidoctor]
|
126
|
+
--
|
127
|
+
[[tableD-1]]
|
128
|
+
[cols="<,^,^,^,^",headerrows=2]
|
129
|
+
.Repeatability and reproducibility of husked rice yield
|
130
|
+
|===
|
131
|
+
.2+| Description 4+| Rice sample
|
132
|
+
| Arborio | Drago footnote:[Parboiled rice.] | Balilla | Thaibonnet
|
133
|
+
|
134
|
+
| Number of laboratories retained after eliminating outliers | 13 | 11 | 13 | 13
|
135
|
+
| Mean value, g/100 g | 81,2 | 82,0 | 81,8 | 77,7
|
136
|
+
|===
|
137
|
+
--
|
138
|
+
|
139
|
+
* https://asciidoctor.org/docs/user-manual/#images[Images], which are mapped to Metanorma figures, with accompanying titles:
|
140
|
+
|
141
|
+
[source,asciidoctor]
|
142
|
+
--
|
143
|
+
[[figureC-1]]
|
144
|
+
.Typical gelatinization curve
|
145
|
+
image::images/rice_image2.png[]
|
146
|
+
footnote:[The time stem:[t_90] was estimated to be 18,2 min for this example.]
|
147
|
+
--
|
148
|
+
|
149
|
+
* https://asciidoctor.org/docs/user-manual/#admonition[Admonitions], which express Notes, Warnings, Cautions, etc.
|
150
|
+
|
151
|
+
[source,asciidoctor]
|
152
|
+
--
|
153
|
+
CAUTION: Only use paddy or parboiled rice for the determination of husked rice yield.
|
154
|
+
--
|
155
|
+
|
156
|
+
TIP: For UNECE, admonitions are used to render boxes. Admonitions can have titles.
|
157
|
+
|
158
|
+
* https://asciidoctor.org/docs/user-manual/#prose-excerpts-quotes-and-verses[Block quotes]
|
159
|
+
|
160
|
+
[source,asciidoctor]
|
161
|
+
--
|
162
|
+
[quote, ISO, "ISO7301,clause 1"]
|
163
|
+
_____
|
164
|
+
This International Standard gives the minimum specifications for rice (_Oryza sativa_ L.) which is subject to international trade. It is applicable to the following types: husked rice and milled rice, parboiled or not, intended for direct human consumption. It is neither applicable to other products derived from rice, nor to waxy rice (glutinous rice).
|
165
|
+
_____
|
166
|
+
--
|
167
|
+
|
168
|
+
* https://asciidoctor.org/docs/user-manual/#example[Examples]
|
169
|
+
|
170
|
+
* https://asciidoctor.org/docs/user-manual/#listing-blocks[Listing blocks] (source code), including https://asciidoctor.org/docs/user-manual/#callouts[source code callouts]
|
171
|
+
|
172
|
+
[source,asciidoctor]
|
173
|
+
----
|
174
|
+
.Sample Code
|
175
|
+
====
|
176
|
+
|
177
|
+
[source,ruby]
|
178
|
+
--
|
179
|
+
puts "Hello, world."
|
180
|
+
%w{a b c}.each do |x| <1>
|
181
|
+
puts x
|
182
|
+
end
|
183
|
+
--
|
184
|
+
<1> This is an annotation
|
185
|
+
====
|
186
|
+
----
|
187
|
+
|
188
|
+
* https://asciidoctor.org/docs/user-manual/#comments[Comments] (which are *not* rendered in the output)
|
189
|
+
|
190
|
+
[source,ruby]
|
191
|
+
--
|
192
|
+
// all terms and defs references are dated
|
193
|
+
--
|
194
|
+
|
195
|
+
=== Sections
|
196
|
+
|
197
|
+
* The Asciidoctor https://asciidoctor.org/docs/user-manual/#doc-preamble[Document preamble] is treated as the document Foreword: it is the text appearing between the document header and the first section header. (Note that the foreword is here given a https://asciidoctor.org/docs/user-manual/#title[block title], but that will be provided automatically anyway.)
|
198
|
+
|
199
|
+
[source,asciidoctor]
|
200
|
+
--
|
201
|
+
[[foreword]]
|
202
|
+
.Foreword
|
203
|
+
ISO (the International Organization for Standardization)
|
204
|
+
--
|
205
|
+
|
206
|
+
* The Asciidoctor https://asciidoctor.org/docs/user-manual/#sections[Sections] correspond to Metanorma clauses, starting with the Introduction (if present). Each section and subsection is delimited with a header; the number of equal signs before the header indicate the level of nesting of the section, starting with two equal signs. No numbering should be given for any header: numbering is done automatically by the gem.
|
207
|
+
|
208
|
+
[source,asciidoctor]
|
209
|
+
--
|
210
|
+
== Sampling
|
211
|
+
Sampling shall be carried out in accordance with <<ISO24333,clause 5>>
|
212
|
+
|
213
|
+
== Test methods
|
214
|
+
--
|
215
|
+
|
216
|
+
https://asciidoctor.org/docs/user-manual/#section-styles[Section styles] are used to indicate specific types of section: `[bibliography]` for Normative References and Bibliography, `[appendix]` for Annexes, and `[%appendix]` for Appendixes (annexes of annexes). These styles must be provided for the sections to be processed correctly: bibliographic references will not be recognised as such, for example, without the `[bibliography]` style applied:
|
217
|
+
|
218
|
+
[source,asciidoctor]
|
219
|
+
--
|
220
|
+
[bibliography]
|
221
|
+
== Bibliography
|
222
|
+
|
223
|
+
* [[[ISO3696,ISO 3696]]], _Water for analytical laboratory use -- Specification and test methods_
|
224
|
+
--
|
225
|
+
|
226
|
+
Sections whose position is set by the standard (e.g., for ISO, Introduction, Scope, Normative References, Terms and Definitions, Symbols and Abbreviations, Bibliography) need to be titled as such, as first-level headings.
|
227
|
+
|
228
|
+
=== Terms and Definitions
|
229
|
+
|
230
|
+
Terms and Definitions sections follow a strict grammar in their Metanorma-ISO markup, as ISO/IEC DIR 2 prescribes their structure so strictly. The following illustrates the complete structure of a term entry; the Rice document splits up these features among several terms.
|
231
|
+
|
232
|
+
[source,asciidoctor]
|
233
|
+
--
|
234
|
+
[[paddy]]
|
235
|
+
=== paddy
|
236
|
+
alt:[paddy rice]
|
237
|
+
alt:[rough rice]
|
238
|
+
deprecated:[cargo rice]
|
239
|
+
domain:[rice]
|
240
|
+
|
241
|
+
rice retaining its husk after threshing
|
242
|
+
|
243
|
+
[example]
|
244
|
+
Foreign seeds, husks, bran, sand, dust.
|
245
|
+
|
246
|
+
NOTE: The starch of waxy rice consists almost entirely of amylopectin. The kernels have a tendency to stick together after cooking.
|
247
|
+
|
248
|
+
[.source]
|
249
|
+
<<ISO7301,section 3.2>>, The term "cargo rice" is shown as deprecated,
|
250
|
+
and Note 1 to entry is not included here
|
251
|
+
--
|
252
|
+
|
253
|
+
Term banks such as the http://www.electropedia.org[IEV] must be treated like any other document, with terms treated as clauses; e.g. `<<IEV,clause "103-01-01">>`. The IEV must be explictly referenced with that label; when the XML is generated, it will be replaced by the official references to `IEC 60050-nnn:2001` standards documents.
|
254
|
+
|
255
|
+
Exceptionally, an introductory section can be treated as a subclause instead of a term, by prefixing it with the style attribute `[.nonterm]`.
|
256
|
+
|
257
|
+
=== References (Normative, Informative)
|
258
|
+
|
259
|
+
All bibliographic entries must be given as unordered lists. Normative references are expected to include only ISO and related standards; informative references may include any source.
|
260
|
+
|
261
|
+
For ISO and related standards, the reference is given as a bibliographic anchor (in triple brackets), consisting of an internal identifier followed by the ISO identifier. The internal identifier can be used in cross-references (citations). The date may be added to the ISO identifier, as required by ISO/IEC DIR 2; standards under preparation have their date given as `--`, and should be accompanied by a footnote detailing the status of the standard.
|
262
|
+
|
263
|
+
[source,asciidoctor]
|
264
|
+
--
|
265
|
+
Grade 3 quality as specified in <<ISO3696>>.
|
266
|
+
|
267
|
+
...
|
268
|
+
|
269
|
+
* [[[ISO3696,ISO 3696]]], _Water for analytical laboratory use -- Specification and test methods_
|
270
|
+
* [[[ISO7301,ISO 7301:2011]]], _Rice -- Specification_
|
271
|
+
* [[[ISO16634,ISO 16634:--]]] footnote:[Under preparation. (Stage at the time of publication ISO/DIS 16634)], _Cereals, pulses, milled cereal products, oilseeds and animal feeding stuffs -- Determination of the total nitrogen content by combustion according to the Dumas principle and calculation of the crude protein content_
|
272
|
+
--
|
273
|
+
|
274
|
+
Non-ISO references under normative references are still cited by document identifier. Under informative references, non-ISO documents are both displayed and cited with reference numbers in brackets. In Metanorma-ISO, the cross-reference is a normal anchor identifier; the bracket numbering for informative references is automatic.
|
275
|
+
|
276
|
+
[source,asciidoctor]
|
277
|
+
--
|
278
|
+
For details concerning the use of the Dumas method, see References <<ref10>> and <<ref16>>.
|
279
|
+
|
280
|
+
...
|
281
|
+
|
282
|
+
* [[[ref10,10]]] [smallcap]#Standard No I.C.C 167#. _Determination of the protein content in cereal and cereal products for food and animal feeding stuffs according to the Dumas combustion method_ (see http://www.icc.or.at)
|
283
|
+
|
284
|
+
* [[[ref16,16]]] [smallcap]#Tkachuk R.# Nitrogen-to-protein conversion factors for cereals and oilseed meals. _Cereal Chem._ 1969, *46* (4) pp 419-423
|
285
|
+
--
|
286
|
+
|
287
|
+
In cross-references, bibliographic localities (e.g. page numbers, clause numbers) can be added directly after the comma, as part of the cross-reference text. Bibliographic localities are expressed as a sequence of lowercase locality type, then an equal sign, then by the locality number or range:
|
288
|
+
|
289
|
+
[source,asciidoctor]
|
290
|
+
--
|
291
|
+
<<ISO7301,clause=3.1>>
|
292
|
+
|
293
|
+
NOTE: This table is based on <<ISO7301,table=1>>.
|
294
|
+
|
295
|
+
Sampling shall be carried out in accordance with <<ISO24333,clause=5>>
|
296
|
+
--
|
297
|
+
|
298
|
+
ISO clause references in particular will suppress the word "Clause" before a subclause reference, following ISO/IEC DIR 2: `<``<ISO24333,clause=5>``>` will be rendered as _ISO 24333, Clause 5_, but `<``<ISO7301,clause=3.1>``>` will be rendered as _ISO 7301, 3.1_.
|
299
|
+
|
300
|
+
|
301
|
+
=== Annexes
|
302
|
+
|
303
|
+
For ISO standards, annexes are treated as normative by default; if they are informative, they must additionally be tagged with an obligation of "informative" (so `[appendix, obligation=informative]`).
|
304
|
+
|
305
|
+
The numbering of annexes and appendices is automatic: do not insert "Annex A" or "Appendix 1" as part of the title.
|
data/docs/customisation.adoc
CHANGED
@@ -1,645 +1,7 @@
|
|
1
|
-
=
|
1
|
+
= Customising Metanorma
|
2
2
|
|
3
|
-
|
3
|
+
Refer to Metanorma adoption FAQ for advice on how to adopt the Metanorma approach
|
4
|
+
to document generation for your documents.
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
TIP: Copy the RSD schema from https://github.com/riboseinc/metanorma-iso/blob/master/grammars/rsd.rng. You may need to adapt some of the enums in the model, or in the ISO Standards model that it inherits; but in the first instance, you can just ignore the differences—and ignore the validation feedback that the toolset gives.
|
8
|
-
|
9
|
-
The Standoc specification is expressed in http://www.relaxng.org[RelaxNG schema for XML], and is intended to be customisable for different types of publication. The customisation of Standoc relies on inheritance, with the following schemas embedded hierarchically:
|
10
|
-
|
11
|
-
* https://github.com/riboseinc/bib-models[Relaton]: bibliography
|
12
|
-
* https://github.com/riboseinc/basicdoc-models[BasicDoc]: block-level and inline formatting
|
13
|
-
* https://github.com/riboseinc/metanorma-standoc[StanDoc]: organisation of sections for a generic standards document
|
14
|
-
* Models specific to standards
|
15
|
-
|
16
|
-
Because of the richness of the ISO standards model, most Standoc standards to date (including the sample gem https://github.com/riboseinc/metanorma-sample) inherit from the ISO Standards model, which itself inherits from Standoc.
|
17
|
-
|
18
|
-
Specialisation of a model consists of:
|
19
|
-
|
20
|
-
* Adding classes to a base model.
|
21
|
-
* Changing attributes of a base model class. This is not restricted to adding attributes, as is the case in typical entity subclassing; it can also include removing attributes from a class, changing their obligation and cardinality, and changing their type, including changing enumerations. Attributes can be overruled at any level; for example, standards-specific models routinely enhance the bibliographic model at the base of the hierarchy.
|
22
|
-
* For reasons of clarity, renaming classes and attributes is avoided in specialisation.
|
23
|
-
|
24
|
-
To adapt the schema for your publication set,
|
25
|
-
|
26
|
-
* Get familiar with the Standoc set of models, and identify any elements that you would want to represent differently for your documents (different types, different enums), or enhance for your documents (additional element attributes, additional elements)
|
27
|
-
* Create a grammar inheriting from StanDoc or from a specific standard, which expresses what is distinctive about your grammar.
|
28
|
-
** We recommend starting your modelling in UML, as an effective communication tool; compare the UML models for Standoc standards at https://github.com/riboseinc/metanorma-iso
|
29
|
-
** The tool suite expects to validate against a set of schemas expressed in RelaxNG. We have been authoring grammars in RelaxNG Compact, as a more human-readable format, then compiling those grammars to RelaxNG using https://github.com/relaxng/jing-trang[jing-trang]. You can choose to use a different schema language, but you will need to customise the tool chain to validate against that form of schema instead.
|
30
|
-
** In order to make schema inheritance easier, we have avoided using namespaces for the individual schemas; a namespace is added to the standards-specific schema at the very end of the inheritance chain.
|
31
|
-
|
32
|
-
=== Schema customisation
|
33
|
-
|
34
|
-
For example, the `rsd.rnc` schema, expressed in RelaxNG Compact, is specific to Ribose Standard documents: it inherits from the ISO Standards model, modifying 10 elements, and adding five. As an example of modifying elements, RSD permits preformatted text (Ascii art) in figures, which ISO does not:
|
35
|
-
|
36
|
-
.ISO
|
37
|
-
[source,asciidoctor]
|
38
|
-
----
|
39
|
-
figure =
|
40
|
-
element figure {
|
41
|
-
attribute id { xsd:ID },
|
42
|
-
tname?,
|
43
|
-
( image | subfigure+ ),
|
44
|
-
fn*, dl?, note*
|
45
|
-
}
|
46
|
-
----
|
47
|
-
|
48
|
-
.RSD
|
49
|
-
[source,asciidoctor]
|
50
|
-
----
|
51
|
-
figure =
|
52
|
-
element figure {
|
53
|
-
attribute id { xsd:ID },
|
54
|
-
tname?,
|
55
|
-
( image | pre | subfigure+ ),
|
56
|
-
fn*, dl?, note*
|
57
|
-
}
|
58
|
-
----
|
59
|
-
|
60
|
-
The preformatted text tag `pre` is an addition to the RSD specification, which is why it lies outside the `include "isostandard.rnc {}"` container:
|
61
|
-
|
62
|
-
.RSD
|
63
|
-
[source,asciidoctor]
|
64
|
-
----
|
65
|
-
pre = element pre { text }
|
66
|
-
----
|
67
|
-
|
68
|
-
As another instance of customisation, the `BibItemType` enumeration of permissible bibliographical item types is extended in RSD to include the document types specific to RSD:
|
69
|
-
|
70
|
-
.RSD
|
71
|
-
[source,asciidoctor]
|
72
|
-
----
|
73
|
-
BibItemType |=
|
74
|
-
"policy-and-procedures" | "best-practices" | "supporting-document" | "report" | "legal" | "directives" | "proposal" |
|
75
|
-
"standard"
|
76
|
-
----
|
77
|
-
|
78
|
-
|
79
|
-
== How can I adapt the StanDoc toolchain for my own publications?
|
80
|
-
|
81
|
-
[TIP]
|
82
|
-
====
|
83
|
-
The easiest way to adopt StanDoc is to use the metanorma-acme gem: https://github.com/riboseinc/metanorma-acme, supplying your own stylesheets and HTML files for styling.
|
84
|
-
|
85
|
-
If you wish to create a custom gem, in order to customise behaviour further:
|
86
|
-
|
87
|
-
* Clone the metanorma-sample gem: https://github.com/riboseinc/metanorma-sample.
|
88
|
-
* Change the namespace for RSD documents (`RSD_NAMESPACE = "https://open.ribose.com/standards/rsd"`) to a namespace specific to your organisation's document standard.
|
89
|
-
* Change any references to `sample` or `Sample` in the gem to your organisation's document standard.
|
90
|
-
* Change the styling of the document outputs (`.../lib/isodoc/XXX/html`).
|
91
|
-
====
|
92
|
-
|
93
|
-
The tool chains currently available proceed in two steps: map an input markup language (currently Asciidoctor only) into Standoc XML, and map Standoc XML into various output formats (currently Word doc, HTML, PDF via HTML). Running the metanorma tool involves a third step, of exposing the capabilities available in the first two in a consistent format. These two steps are represented as three separate modules, which are included in the same gem; for the Sample gem, they are `Asciidoctor::Sample`, `Isodoc::Sample`, and `Metanorma::Sample`. (In the case of Asciidoctor-ISO, almost all the content of `Isodoc::ISO` is in the isodoc gem, so the base classes of the two steps are in separate gems.)
|
94
|
-
|
95
|
-
Your adaptation of the toolchain will need to instantiate these three modules. The connection between the two first steps is taken care of in the toolchain, and metanorma explicitly invokes the two steps, feeding the XML output of the first step as input into the second. The metanorma-sample gem outputs both Word and HTML; you can choose to output only Word (as is done in metanorma-m3d), or only HTML (as is done in metanorma-csand), and you can choose to generate PDF from HTML as well (as is done in metanorma-csd).
|
96
|
-
|
97
|
-
The modules involve classes which rely on inheritance from other classes; the current gems use `Asciidoctor::{Standoc, ISO}::Converter`, `Isodoc::{Metadata, HtmlConvert, WordConvert}`, and `Metanorma::Processor` as their base classes. This allows the standards-specific classes to be quite succinct, as most of their behaviour is inherited from other classes; but it also means that you need to be familiar with the underlying gems, in order to do most customisation.
|
98
|
-
|
99
|
-
In the case of `Asciidoctor::X` classes, the changes you will need to make involve the intermediate XML representation of your document, which is built up through Nokogiri Builder; e.g. adding different enums, or adding new elements. The adaptations in `Asciidoctor::Sample::Converter` are limited, and most projects can take them across as is.
|
100
|
-
|
101
|
-
The customisations needed for Metanorma::Sample::Processor are minor, and involve invoking methods specific to the gem for document generation.
|
102
|
-
|
103
|
-
The customisations needed for Isodoc::Sample are more extensive. Three base classes are involved:
|
104
|
-
|
105
|
-
* `Isodoc::Metadata` processes the metadata about the document stored in `//bibdata`. This information typically ends up in the document title page, as opposed to the document body. For that reason, metadata is extracted into a hash, which is passed to document output (title page, Word header) via the https://shopify.github.io/liquid/[Liquid template language].
|
106
|
-
* `Isodoc::HtmlConvert` converts Standoc XML to HTML.
|
107
|
-
* `Isodoc::WordConvert` converts Standoc XML to Word HTML; the https://github.com/riboseinc/html2doc[html2doc] gem then converts this to a .doc document.
|
108
|
-
|
109
|
-
The `Isodoc::HtmlConvert` and `Isodoc::WordConvert` overlap substantially, as both use variants of HTML. However there is no reason not to make substantially different rendering choices in the HTML and Word branches of the code.
|
110
|
-
|
111
|
-
=== Asciidoctor::Standoc customisation in metanorma-sample
|
112
|
-
|
113
|
-
Examples from Asciidoctor::Sample in metanorma-sample. In the following snippets, the parameter `node` represents the current node of the Asciidoctor document, and `xml` represents the Nokogiri Builder node of the XML output.
|
114
|
-
|
115
|
-
* The boilerplate representation of the document's author, publisher and copyright holder names Acme instead of ISO as the responsible organisation.
|
116
|
-
|
117
|
-
[source,ruby]
|
118
|
-
--
|
119
|
-
def metadata_author(node, xml)
|
120
|
-
xml.contributor do |c|
|
121
|
-
c.role **{ type: "author" }
|
122
|
-
c.organization do |a|
|
123
|
-
a.name "Acme"
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
--
|
128
|
-
|
129
|
-
* The editorial committees are represented as a single element, as opposed to ISO's name plus number. (`node.attr()` recovers Asciidoctor document attribute values.)
|
130
|
-
|
131
|
-
[source,ruby]
|
132
|
-
--
|
133
|
-
def metadata_committee(node, xml)
|
134
|
-
xml.editorialgroup do |a|
|
135
|
-
a.committee node.attr("committee"),
|
136
|
-
**attr_code(type: node.attr("committee-type"))
|
137
|
-
end
|
138
|
-
end
|
139
|
-
--
|
140
|
-
|
141
|
-
* The document title is monolingual, not bilingual. (`asciidoc_sub()` is already defined to apply Asciidoctor text substitutions to its contents, such as smart quotes and em-dashes.)
|
142
|
-
|
143
|
-
[source,ruby]
|
144
|
-
--
|
145
|
-
def title(node, xml)
|
146
|
-
["en"].each do |lang|
|
147
|
-
xml.title **{ language: lang, format: "plain" } do |t|
|
148
|
-
t << asciidoc_sub(node.attr("title"))
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
--
|
153
|
-
|
154
|
-
* The document status is a single element, as opposed to ISO's two-part code.
|
155
|
-
|
156
|
-
[source,ruby]
|
157
|
-
--
|
158
|
-
def metadata_status(node, xml)
|
159
|
-
xml.status(**{ format: "plain" }) { |s| s << node.attr("status") }
|
160
|
-
end
|
161
|
-
--
|
162
|
-
|
163
|
-
* The document identifier is a single element.
|
164
|
-
|
165
|
-
[source,ruby]
|
166
|
-
--
|
167
|
-
def metadata_id(node, xml)
|
168
|
-
xml.docidentifier { |i| i << node.attr("docnumber") }
|
169
|
-
end
|
170
|
-
--
|
171
|
-
|
172
|
-
* A security element is added to the document metadata.
|
173
|
-
|
174
|
-
[source,ruby]
|
175
|
-
--
|
176
|
-
def metadata_security(node, xml)
|
177
|
-
security = node.attr("security") || return
|
178
|
-
xml.security security
|
179
|
-
end
|
180
|
-
|
181
|
-
def metadata(node, xml)
|
182
|
-
super
|
183
|
-
metadata_security(node, xml)
|
184
|
-
end
|
185
|
-
--
|
186
|
-
|
187
|
-
* Title validation and style validation is disabled.
|
188
|
-
|
189
|
-
[source,ruby]
|
190
|
-
--
|
191
|
-
def title_validate(root)
|
192
|
-
nil
|
193
|
-
end
|
194
|
-
--
|
195
|
-
|
196
|
-
* The root element of the document is changed from `iso-standard` to `sample-standard`.
|
197
|
-
|
198
|
-
[source,ruby]
|
199
|
-
--
|
200
|
-
def makexml(node)
|
201
|
-
result = ["<?xml version='1.0' encoding='UTF-8'?>\n<sample-standard>"]
|
202
|
-
@draft = node.attributes.has_key?("draft")
|
203
|
-
result << noko { |ixml| front node, ixml }
|
204
|
-
result << noko { |ixml| middle node, ixml }
|
205
|
-
result << "</sample-standard>"
|
206
|
-
....
|
207
|
-
end
|
208
|
-
--
|
209
|
-
|
210
|
-
* The document type attribute is restricted to a prescribed set of options.
|
211
|
-
|
212
|
-
[source,ruby]
|
213
|
-
--
|
214
|
-
def doctype(node)
|
215
|
-
d = node.attr("doctype")
|
216
|
-
unless %w{policy-and-procedures best-practices
|
217
|
-
supporting-document report legal directives proposal
|
218
|
-
standard}.include? d
|
219
|
-
warn "#{d} is not a legal document type: reverting to 'standard'"
|
220
|
-
d = "standard"
|
221
|
-
end
|
222
|
-
d
|
223
|
-
end
|
224
|
-
--
|
225
|
-
|
226
|
-
* The `literal` asciidoctor block is processed as a preformatted tag (`pre`).
|
227
|
-
(The code uses the built-in Asciidoctor `literal()` method, and embeds `pre` within a `figure` tag.)
|
228
|
-
|
229
|
-
[source,ruby]
|
230
|
-
--
|
231
|
-
def literal(node)
|
232
|
-
noko do |xml|
|
233
|
-
xml.figure **id_attr(node) do |f|
|
234
|
-
figure_title(node, f)
|
235
|
-
f.pre node.lines.join("\n")
|
236
|
-
end
|
237
|
-
end
|
238
|
-
end
|
239
|
-
--
|
240
|
-
|
241
|
-
* A `keyword` element is added. (The keyword is encoded through the role attribute of Asciidoc: `[.keyword]#text#`)
|
242
|
-
|
243
|
-
[source,ruby]
|
244
|
-
--
|
245
|
-
def inline_quoted(node)
|
246
|
-
noko do |xml|
|
247
|
-
case node.type
|
248
|
-
...
|
249
|
-
else
|
250
|
-
case node.role
|
251
|
-
...
|
252
|
-
when "keyword" then xml.keyword node.text
|
253
|
-
else
|
254
|
-
xml << node.text
|
255
|
-
end
|
256
|
-
end
|
257
|
-
end.join
|
258
|
-
end
|
259
|
-
--
|
260
|
-
|
261
|
-
* The inline headers of ISO are ignored.
|
262
|
-
|
263
|
-
[source,ruby]
|
264
|
-
--
|
265
|
-
def sections_cleanup(x)
|
266
|
-
super
|
267
|
-
x.xpath("//*[@inline-header]").each do |h|
|
268
|
-
h.delete("inline-header")
|
269
|
-
end
|
270
|
-
end
|
271
|
-
--
|
272
|
-
|
273
|
-
=== Metanorma::Processor customisation in metanorma-sample
|
274
|
-
|
275
|
-
* `initialize` names the token by which Asciidoctor registers the standard
|
276
|
-
|
277
|
-
[source,ruby]
|
278
|
-
--
|
279
|
-
def initialize
|
280
|
-
@short = :sample
|
281
|
-
@input_format = :asciidoc
|
282
|
-
@asciidoctor_backend = :sample
|
283
|
-
end
|
284
|
-
--
|
285
|
-
|
286
|
-
* `output_formats` names the available output formats (including XML, which is inherited from the parent class)
|
287
|
-
|
288
|
-
[source,ruby]
|
289
|
-
--
|
290
|
-
def output_formats
|
291
|
-
super.merge(
|
292
|
-
html: "html",
|
293
|
-
doc: "doc",
|
294
|
-
pdf: "pdf"
|
295
|
-
)
|
296
|
-
end
|
297
|
-
--
|
298
|
-
|
299
|
-
* `version` gives the current version string for the gem
|
300
|
-
|
301
|
-
[source,ruby]
|
302
|
-
--
|
303
|
-
def version
|
304
|
-
"Asciidoctor::Sample #{Asciidoctor::Sample::VERSION}"
|
305
|
-
end
|
306
|
-
--
|
307
|
-
|
308
|
-
* `input_to_isodoc` is the call which converts Asciidoctor input into IsoDoc XML
|
309
|
-
|
310
|
-
[source,ruby]
|
311
|
-
--
|
312
|
-
def input_to_isodoc(file)
|
313
|
-
Metanorma::Input::Asciidoc.new.process(file, @asciidoctor_backend)
|
314
|
-
end
|
315
|
-
--
|
316
|
-
|
317
|
-
* `output` is the call which converts IsoDoc XML into various nominated output formats
|
318
|
-
|
319
|
-
[source,ruby]
|
320
|
-
--
|
321
|
-
def output(isodoc_node, outname, format, options={})
|
322
|
-
case format
|
323
|
-
when :html
|
324
|
-
IsoDoc::Sample::HtmlConvert.new(options).convert(outname, isodoc_node)
|
325
|
-
when :doc
|
326
|
-
IsoDoc::Sample::WordConvert.new(options).convert(outname, isodoc_node)
|
327
|
-
when :pdf
|
328
|
-
IsoDoc::Sample::PdfConvert.new(options).convert(outname, isodoc_node)
|
329
|
-
else
|
330
|
-
super
|
331
|
-
end
|
332
|
-
end
|
333
|
-
--
|
334
|
-
|
335
|
-
=== Isodoc::Standoc customisation in metanorma-sample
|
336
|
-
|
337
|
-
* Setting the document title (`:doctitle`) in metadata, as a single element in ISO XML; ignore any document subtitle.
|
338
|
-
|
339
|
-
[source,ruby]
|
340
|
-
--
|
341
|
-
def title(isoxml, _out)
|
342
|
-
main = isoxml&.at(ns("//title[@language='en']"))&.text
|
343
|
-
set(:doctitle, main)
|
344
|
-
end
|
345
|
-
|
346
|
-
def subtitle(_isoxml, _out)
|
347
|
-
nil
|
348
|
-
end
|
349
|
-
--
|
350
|
-
|
351
|
-
* Add to version metadata a metadata element for the revision date (already stored as `:revdate`), expressed as month+year (`:revdate_monthyear`)/
|
352
|
-
|
353
|
-
[source,ruby]
|
354
|
-
--
|
355
|
-
def version(isoxml, _out)
|
356
|
-
super
|
357
|
-
revdate = get[:revdate]
|
358
|
-
set(:revdate_monthyear, monthyr(revdate))
|
359
|
-
end
|
360
|
-
|
361
|
-
def monthyr(isodate)
|
362
|
-
m = /(?<yr>\d\d\d\d)-(?<mo>\d\d)/.match isodate
|
363
|
-
return isodate unless m && m[:yr] && m[:mo]
|
364
|
-
return "#{MONTHS[m[:mo].to_sym]} #{m[:yr]}"
|
365
|
-
end
|
366
|
-
--
|
367
|
-
|
368
|
-
* Initialise the HTML Converter:
|
369
|
-
** Set `@libdir`, the current directory of the HTML converter, and the basis of the `html_doc_path()` method for accessing HTML assets (the `html` subdirectory of the current directory).
|
370
|
-
** Copy the logo JPG from the HTML asset directory to the working directory, so that it can be access by the HTML template; flag the copy for deletion at the end of processing.
|
371
|
-
|
372
|
-
[source,ruby]
|
373
|
-
--
|
374
|
-
def initialize(options)
|
375
|
-
@libdir = File.dirname(__FILE__)
|
376
|
-
super
|
377
|
-
FileUtils.cp html_doc_path('logo.jpg'), "logo.jpg"
|
378
|
-
@files_to_delete << "logo.jpg"
|
379
|
-
end
|
380
|
-
--
|
381
|
-
|
382
|
-
* Set the default fonts for the HTML rendering, which will be used to populate the HTML CSS stylesheet.
|
383
|
-
|
384
|
-
[source,ruby]
|
385
|
-
--
|
386
|
-
class HtmlConvert < IsoDoc::HtmlConvert
|
387
|
-
def default_fonts(options)
|
388
|
-
{
|
389
|
-
bodyfont: (options[:script] == "Hans" ? '"SimSun",serif' : '"Overpass",sans-serif'),
|
390
|
-
headerfont: (options[:script] == "Hans" ? '"SimHei",sans-serif' : '"Overpass",sans-serif'),
|
391
|
-
monospacefont: '"Space Mono",monospace'
|
392
|
-
}
|
393
|
-
end
|
394
|
-
--
|
395
|
-
|
396
|
-
* Set the default HTML assets for the HTML rendering.
|
397
|
-
|
398
|
-
[source,ruby]
|
399
|
-
--
|
400
|
-
class HtmlConvert < IsoDoc::HtmlConvert
|
401
|
-
def default_file_locations(_options)
|
402
|
-
{
|
403
|
-
htmlstylesheet: html_doc_path("htmlstyle.scss"),
|
404
|
-
htmlcoverpage: html_doc_path("html_sample_titlepage.html"),
|
405
|
-
htmlintropage: html_doc_path("html_sample_intro.html"),
|
406
|
-
scripts: html_doc_path("scripts.html"),
|
407
|
-
}
|
408
|
-
end
|
409
|
-
--
|
410
|
-
|
411
|
-
* Set distinct default fonts and HTML assets for the Word rendering.
|
412
|
-
|
413
|
-
[source,ruby]
|
414
|
-
--
|
415
|
-
class WordConvert < IsoDoc::WordConvert
|
416
|
-
def default_fonts(options)
|
417
|
-
{
|
418
|
-
bodyfont: (options[:script] == "Hans" ? '"SimSun",serif' : '"Arial",sans-serif'),
|
419
|
-
headerfont: (options[:script] == "Hans" ? '"SimHei",sans-serif' : '"Arial",sans-serif'),
|
420
|
-
monospacefont: '"Courier New",monospace'
|
421
|
-
}
|
422
|
-
end
|
423
|
-
|
424
|
-
def default_file_locations(_options)
|
425
|
-
{
|
426
|
-
wordstylesheet: html_doc_path("wordstyle.scss"),
|
427
|
-
standardstylesheet: html_doc_path("sample.scss"),
|
428
|
-
header: html_doc_path("header.html"),
|
429
|
-
wordcoverpage: html_doc_path("word_sample_titlepage.html"),
|
430
|
-
wordintropage: html_doc_path("word_sample_intro.html"),
|
431
|
-
ulstyle: "l3",
|
432
|
-
olstyle: "l2",
|
433
|
-
}
|
434
|
-
end
|
435
|
-
--
|
436
|
-
|
437
|
-
|
438
|
-
* Set the content of the HTML head, other than the CSS stylesheets. Note that the head title is given as a Liquid Template reference to metadata ()`{{ doctitle }}`, which we have seen populated above.)
|
439
|
-
|
440
|
-
[source,ruby]
|
441
|
-
--
|
442
|
-
def html_head
|
443
|
-
<<~HEAD.freeze
|
444
|
-
<title>{{ doctitle }}</title>
|
445
|
-
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
446
|
-
<!--TOC script import-->
|
447
|
-
<script type="text/javascript" src="https://cdn.rawgit.com/jgallen23/toc/0.3.2/dist/toc.min.js"></script>
|
448
|
-
<!--Google fonts-->
|
449
|
-
....
|
450
|
-
<style class="anchorjs"></style>
|
451
|
-
HEAD
|
452
|
-
end
|
453
|
-
--
|
454
|
-
|
455
|
-
* Change the default label for annexes from "Annex" to "Appendix".
|
456
|
-
|
457
|
-
[source,ruby]
|
458
|
-
--
|
459
|
-
def i18n_init(lang, script)
|
460
|
-
super
|
461
|
-
@annex_lbl = "Appendix"
|
462
|
-
end
|
463
|
-
--
|
464
|
-
|
465
|
-
* Define rendering for the `pre` and `keyword` preformatted text tags.
|
466
|
-
|
467
|
-
[source,ruby]
|
468
|
-
--
|
469
|
-
def pre_parse(node, out)
|
470
|
-
out.pre node.text # content.gsub(/</, "<").gsub(/>/, ">")
|
471
|
-
end
|
472
|
-
|
473
|
-
def error_parse(node, out)
|
474
|
-
# catch elements not defined in ISO
|
475
|
-
case node.name
|
476
|
-
when "pre"
|
477
|
-
pre_parse(node, out)
|
478
|
-
when "keyword"
|
479
|
-
out.span node.text, **{ class: "keyword" }
|
480
|
-
else
|
481
|
-
super
|
482
|
-
end
|
483
|
-
end
|
484
|
-
--
|
485
|
-
|
486
|
-
* Render term headings in the same paragraph as the term heading number
|
487
|
-
|
488
|
-
[source,ruby]
|
489
|
-
--
|
490
|
-
def term_cleanup(docxml)
|
491
|
-
docxml.xpath("//p[@class = 'Terms']").each do |d|
|
492
|
-
h2 = d.at("./preceding-sibling::*[@class = 'TermNum'][1]")
|
493
|
-
h2.add_child(" ")
|
494
|
-
h2.add_child(d.remove)
|
495
|
-
end
|
496
|
-
docxml
|
497
|
-
end
|
498
|
-
--
|
499
|
-
|
500
|
-
|
501
|
-
== How can I style the resulting HTML output?
|
502
|
-
|
503
|
-
[TIP]
|
504
|
-
====
|
505
|
-
* Clone the metanorma-sample gem: https://github.com/riboseinc/metanorma-sample.
|
506
|
-
* Edit the `html_sample_titlepage.html` and `html_sample_intro.html` pages to match your organisation's branding.
|
507
|
-
** Leave the Liquid Template instructions alone (`{{`, `{%`) unless you know what you're doing with them: they are how the pages are populated with metadata.
|
508
|
-
* Edit the `default_fonts()` method in your `IsoDoc::...::HtmlConvert` class, to match your desired fonts.
|
509
|
-
* Edit the `default_file_locations()` method in your `IsoDoc::...::HtmlConvert` class, to match your desired stylesheets and HTML templates.
|
510
|
-
* Edit the `htmlstyle.scss` stylesheet to match your organisation's branding. The classes already in place there are used to style existing blocks of text; refer to the sample documents included in the gem (`spec/examples`) for their use.
|
511
|
-
====
|
512
|
-
|
513
|
-
Styling of output is intended to be configurable. HTML stylesheets are expressed in https://sass-lang.com/guide[SCSS], with their fonts populated through the `default_fonts()` method in the `IsoDoc::...::HtmlConvert` class. Frontispiece content is templated, populated from metadata parsed in the `IsoDoc::...::Metadata` class, via https://shopify.github.io/liquid/[Liquid templates]. The default stylesheets and HTML templates themselves are nominated in the `default_file_locations()` method in the `IsoDoc::...::HtmlConvert` class. That means you can change the styling of output documents readily, so long as you are aware of the functionality of the stylesheet.
|
514
|
-
|
515
|
-
* Styling information is stored in the `.../lib/isodoc/html` folder of the gem, and applies to both Word and HTML content. For HTML content, the relevant files are `html_..._titlepage.html` (title page HTML template), `html_..._intro.html` (introductory HTML template, typically restricted to Table of Contents), `scripts.html` (Javascript scripts), and `htmlstyle.scss` (the HTML stylesheet).
|
516
|
-
* The styling files to be loaded in are set in the `default_file_locations()` method of `IsoDoc::...::HtmlConvert`. The files can be overridden through document variables in the Asciidoc document.
|
517
|
-
* Additional files (e.g. logos) can be loaded in the `initialize()` method of `IsoDoc::...::HtmlConvert`; for them to be access during document generation, they need to be copied to the working directory. (They can be removed subsequently by adding them to the `@files_to_delete` array. All image files are copied into an `_html` subdirectory.)
|
518
|
-
* The HTML templates are populated through Liquid Templates: variables in `{{` correspond to the hash keys for metadata extracted in `IsoDoc::...::Metadata`, and its superclass `IsoDoc::Metadata` in the isodoc gem.
|
519
|
-
* The SCSS stylesheets treat fonts as variables. Those variables are set in `default_fonts()`, which generates variable assignments for SCSS. Stylesheets normally recognise three fonts: `$bodyfont` for body text, `$headerfont` for headers and captions (which may be the same font as `$bodyfont`), and `$monospacefont` for monospace text. Note that `default_fonts()` takes the options passed to initialise `HtmlConvert` as a paremeter; the document language and script can be used to make different font choices for different document scripts. (The existing gems refer to `Latn`, Latin script, and `Hans`, Simplified Chinese script.)
|
520
|
-
* Javascript scripts are populated in `scripts.html`; the scripts already in place in any gem you modify are in live use, and you should work out what they do before removing them. The AnchorJS script, for example, is used to generate navigable anchors in the document.
|
521
|
-
* Additional scripts and fonts may be loaded in the document head through the `html_head()` method of `IsoDoc::...::HtmlConvert`. The existing gems use the document head to load Jquery, the Table of Contents generation script, Google Fonts, and Font Awesome.
|
522
|
-
* The classes in the SCSS stylesheet correspond to static HTML content in the HTML templates, and dynamic HTML content in the `IsoDoc::...::HtmlConvert` class, and its superclasses `IsoDoc::HtmlConvert` and `IsoDoc::Common` in the isodoc gem.
|
523
|
-
|
524
|
-
An HTML document is populated as follows:
|
525
|
-
* HTML Head wrapper (in `IsoDoc::HtmlConvert`)
|
526
|
-
** `html_head()` content
|
527
|
-
** `@htmlstylesheet` CSS stylesheet (expected to be in SCSS, generated from SCSS in the `generate_css()` method of `Isodoc::HtmlConvert`).
|
528
|
-
* HTML Body
|
529
|
-
** `@htmlcoverpage` HTML template (optional, corresponds to `html_..._titlepage.html`)
|
530
|
-
** `@htmlintropage` HTML template (optional, corresponds to `html_..._intro.html`)
|
531
|
-
** Document proper (converted from Standoc XML)
|
532
|
-
** `@scripts` Javascript Scripts (optional, corresponds to `scripts.html`)
|
533
|
-
|
534
|
-
== How can I style the resulting Word output?
|
535
|
-
|
536
|
-
[TIP]
|
537
|
-
====
|
538
|
-
* There is no quick way of doing this.
|
539
|
-
* Everything you can do in Word, you can do in Word HTML. Save Word documents as Word HTML to see how.
|
540
|
-
* Clone the metanorma-sample gem: https://github.com/riboseinc/metanorma-sample.
|
541
|
-
* Edit the `word_sample_titlepage.html` and `word_sample_intro.html` pages to match your organisation's branding. With lots of iterations of saving Word documents as HTML, for trial and error.
|
542
|
-
** Leave the Liquid Template instructions alone (`{{`, `{%`) unless you know what you're doing with them: they are how the pages are populated with metadata.
|
543
|
-
* Edit the `default_fonts()` method in your `IsoDoc::...::WordConvert` class, to match your desired fonts.
|
544
|
-
* Edit the `default_file_locations()` method in your `IsoDoc::...::WordConvert` class, to match your desired stylesheets and file templates.
|
545
|
-
* Edit the `wordstyle.scss` and `sample.scss` stylesheets to match your organisation's branding. With lots of iterations of saving Word documents as HTML, for trial and error.
|
546
|
-
====
|
547
|
-
|
548
|
-
Word output in the document toolset is generated through Word HTML, the variant of HTML that you get when you save a Word document as HTML. (That is why documents are saved in `.doc`, not `.docx`.) This has the advantage over https://en.wikipedia.org/wiki/Office_Open_XML[OOXML], the native markup of DOCX, of using a well-known markup language, with a low barrier to entry: if you want to work out how to do something in Word HTML, do it in Word, save the document as HTML, and open up the HTML in a text editor. (For more on the choice of using Word HTML, see https://github.com/riboseinc/html2doc/wiki/Why-not-docx%3F.)
|
549
|
-
|
550
|
-
However Word HTML is not quite the HTML you are used to: it is a restricted, syntactically idiosyncratic variant of HTML 4, with a non-standard and weakened form of CSS. Doing any styling in Word HTML involves lots of trial and error, and paying close attention to how Word HTML does things in its CSS. We have documented a few of the clearer gotchas in https://github.com/riboseinc/html2doc/blob/master/README.adoc.
|
551
|
-
|
552
|
-
It's still better than learning OOXML.
|
553
|
-
|
554
|
-
The process for generating Word output is fairly similar to that for generating HTML, since both processes are generating a form of HTML; as we already noted, the two processes share a substantial amount of code. The main differences are in the handling of page-media features that CSS has lagged in (footnotes, pagination, headers and footers), and in the styling of lists, for which Word HTML uses custom (and undocumented) CSS classes prefixed with `@`, specifying inter alia the numbering for nine levels of nesting of the same list.
|
555
|
-
|
556
|
-
* Styling information is stored in the `.../lib/isodoc/html` folder of the gem, and applies to both Word and HTML content. For Word content, the relevant files are `word_..._titlepage.html` (title page HTML template), `word_..._intro.html` (introductory HTML template, typically restricted to Table of Contents), `wordstyle.scss` and `{name_of_standard}.scss` (the Word stylesheets), and `header.html` (document headers, footers, and endnote/footnote separators, referenced from the stylesheets).
|
557
|
-
* The styling files to be loaded in are set in the `default_file_locations()` method of `IsoDoc::...::WordConvert`.
|
558
|
-
* As with HTML generation, additional files (e.g. logos) can be loaded in the `initialize()` method of `IsoDoc::...::WordConvert`. The `initialize()` method also sets the `@` styles in the stylesheet to be used for unordered and ordered lists; a single such style is intended to capture the behaviour of all levels of indentation.
|
559
|
-
* As with HTML output, the HTML templates are populated through Liquid Templates: variables in `{{` correspond to the hash keys for metadata extracted in `IsoDoc::...::Metadata`, and its superclass `IsoDoc::Metadata` in the isodoc gem.
|
560
|
-
* As with HTML, the SCSS stylesheets treat fonts as variables, and are set in the `default_fonts()` method of `IsoDoc::...::WordConvert`.
|
561
|
-
* Document headers and footers are set in the `header.html` file. This is also an HTML template, which is populated with metadata attributes through Liquid Template. The structure of `header.html` is determined by Word, and elements of `header.html` need to be crossreferenced from the Word stylesheet. To inspect Word `header.html` files, save a Word document as HTML, and look inside the `{document_name}.fld` folder generated alongside the HTML output.
|
562
|
-
* The classes in the SCSS stylesheet correspond to static HTML content in the HTML templates, and dynamic HTML content in the `IsoDoc::...::WordConvert` class, and its superclasses `IsoDoc::WordConvert` and `IsoDoc::Common` in the isodoc gem.
|
563
|
-
|
564
|
-
A Word HTML document is populated as follows:
|
565
|
-
* HTML Head wrapper (in `IsoDoc::WordConvert`)
|
566
|
-
** `@wordstylesheet` CSS stylesheet (generated from SCSS through the `generate_css()` method of `Isodoc::WordConvert`); corresponds to `wordstyle.scss`.
|
567
|
-
** `@standstylesheet` CSS stylesheet (generated from SCSS through the `generate_css()` method of `Isodoc::WordConvert`); intended to override any generic CSS in `@wordstylesheet`. Optional, corresponds to `{name_of_standard}.scss`.
|
568
|
-
* HTML Body
|
569
|
-
** `@wordcoverpage` HTML template (optional, corresponds to `word_..._titlepage.html`). Included in `<div class=WordSection1>`.
|
570
|
-
** `@htmlintropage` HTML template (optional, corresponds to `word_..._intro.html`). Included in `<div class=WordSection2>`. In the existing gems, WordSection2 is paginated with roman numerals.
|
571
|
-
** Document proper (converted from Standoc XML). Included in `<div class=WordSection2>` (prefatory material) and `<div class=WordSection3>` (main document). In the existing gems, WordSection3 is paginated with roman numerals.
|
572
|
-
|
573
|
-
== How can I localize the resulting output?
|
574
|
-
|
575
|
-
[TIP]
|
576
|
-
====
|
577
|
-
* Copy the `lib/isodoc/i18n-en.yaml` file from the isodoc gem to your gem.
|
578
|
-
* Edit the right-hand text in the file.
|
579
|
-
* Give the file location as the `i18nyaml` document attribute in any files you wish to use your localisation.
|
580
|
-
====
|
581
|
-
|
582
|
-
Every piece of text generated by the toolset instead of the author is looked up in an internationalisation file; that means that if the language setting for the document changes, and there is an internationalisation file for that language, all output is localised to that language. Of the existing gems, metanorma-gb is localised in this way for English and Chinese, and metanorma-iso is localised for English, French and Chinese.
|
583
|
-
|
584
|
-
The localisation files are http://yaml.org[YAML] files stores in `lib/isodoc/`, named `i18n-{languagecode}.yaml`. (In the case of Chinese, the script code is added to the filename: `i18n-zh-Hans.yaml`.) Most localised text are direct mappings from English metalanguage to the target language (including English itself); there are also instances of hashes in the YAML files. Most localisation text consists of one- or two-word labels, such as "Figure" or "Annex"; some boilerplate text is also included in the localisation text, such as the ISO text describing the use of external sources in Terms and Definitions.
|
585
|
-
|
586
|
-
Localisation is mostly used for translation purposes, but they can also be used to customise the rendering of particular labels in English. For example, the default English label for a first-level supplementary section is "Annex", reflecting ISO practice; but in the metanorma-sample gem, as seen above, this label is overruled in code to be "Appendix" instead.
|
587
|
-
|
588
|
-
The YAML files are read into the `IsoDoc` classes through the `i18n_init()` method of `IsoDoc::...::HtmlConvert` and `Isodoc::...::WordConvert`. The localisation equivalents for the nominated language are read from the corresponding YAML file into the `@labels` hash. The base Isodoc instance of `i18n_init()` also assigns an instance variable for each label (e.g. `@annex_lbl` for English "Annex"). These instance variables are used to generate all automated text in the Isodoc classes.
|
589
|
-
|
590
|
-
All current gems inherit their localisation files from the base isodoc gem. The local `i18n_init()` instance can overwrite individual labels in code (metanorma-csd), or they can read in a local additional YAML file for the same language (metanorma-gb). If you are implementing a completely new language, you will need to replace the base `i18n_init()` method rather than inheriting from it, to ensure that the local YAML files are read in.
|
591
|
-
|
592
|
-
The foregoing describes how to incorporate localisation into your gem on a permanent basis; but the toolset also allows you to nominate a YAML localisation file just for the current document. In Asciidoc, the YAML file is nominated as the i18nyaml document attribute; for IsoDoc, it is passed in as the `i18nyaml` hash attribute to the initialisation method. You will still need to access the base IsoDoc YAML instances, to make sure that all necessary labels are given in your YAML document.
|
593
|
-
|
594
|
-
=== Example internationalisation code
|
595
|
-
|
596
|
-
* metanorma-mpfd/lib/isodoc/mpfd/i18n-en.yaml: customisation of clause label in YAML
|
597
|
-
|
598
|
-
[source]
|
599
|
-
--
|
600
|
-
clause: Paragraph
|
601
|
-
--
|
602
|
-
|
603
|
-
* metanorma-m3d/lib/isodoc/m3d/m3dhtmlconvert.rb: customisation of annex label as class variable
|
604
|
-
|
605
|
-
[source,ruby]
|
606
|
-
--
|
607
|
-
def i18n_init(lang, script)
|
608
|
-
super
|
609
|
-
@annex_lbl = "Appendix"
|
610
|
-
end
|
611
|
-
--
|
612
|
-
|
613
|
-
* metanorma-gb/lib/isodoc/gb/gbhtmlconvert.rb: code to read in internationalisation YAML templates (merges superclass `@labels` map, derived from the parent Isodoc::HtmlConvert class, with the labels read in from the GB-specific YAML templates.)
|
614
|
-
|
615
|
-
[source,ruby]
|
616
|
-
--
|
617
|
-
def i18n_init(lang, script)
|
618
|
-
super
|
619
|
-
y = if lang == "en"
|
620
|
-
YAML.load_file(File.join(File.dirname(__FILE__), "i18n-en.yaml"))
|
621
|
-
elsif lang == "zh" && script == "Hans"
|
622
|
-
YAML.load_file(File.join(File.dirname(__FILE__),
|
623
|
-
"i18n-zh-Hans.yaml"))
|
624
|
-
else
|
625
|
-
YAML.load_file(File.join(File.dirname(__FILE__), "i18n-zh-Hans.yaml"))
|
626
|
-
end
|
627
|
-
@labels = @labels.merge(y)
|
628
|
-
end
|
629
|
-
--
|
630
|
-
|
631
|
-
== I can translate my specifications into IsoDoc XML myself (i.e. I don't like AsciiDoc, or I already have my own toolchain). Can I only use IsoDoc XML to produce pretty output?
|
632
|
-
|
633
|
-
[TIP]
|
634
|
-
====
|
635
|
-
* Generate correct IsoDoc XML (make sure it validates!)
|
636
|
-
* Create just the `IsoDoc::...::HtmlConvert` and/or `IsoDoc::...::WordConvert` classes to convert the IsoDoc XML into target formats.
|
637
|
-
* Initialise the IsoDoc class passing the necessary information about fonts and scripts; the existing gems all illustrate this kind of initialisation.
|
638
|
-
* Create the target format using the method `.convert(filename, xml)`.
|
639
|
-
====
|
640
|
-
|
641
|
-
The Asciidoctor-to-XML and XML-to-Output classes are separate, so you can invoke just the latter without the former. Of course, you will need to make sure that the IsoDoc XML you are passing to the generators is valid.
|
642
|
-
|
643
|
-
The `IsoDoc::...::HtmlConvert` and/or `IsoDoc::...::WordConvert` are initialised in the existing gems with a hash giving the fonts to be used in the document (to be injected in the document SCSS stylesheets), the script of the document (to be used to pick the right font, in case of default font settings), and the `i18nyaml` YAML file for localisation. All existing gems have defaults set for these values on the Asciidoctor side invoking the class, so all parameters are optional.
|
644
|
-
|
645
|
-
Once you have the classes set up, all you need to do is invoke the conversion of XML to the target format, with the method `.convert(filename, xml)`, where XML is the IsoDoc XML.
|
6
|
+
You will usually find there a detailed customisation guidance prefixed with a short summary
|
7
|
+
for a quick-and-dirty implementation.
|