metanorma-iso 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +4 -0
  3. data/.gitignore +11 -0
  4. data/.hound.yml +3 -0
  5. data/.oss-guides.rubocop.yml +1077 -0
  6. data/.rubocop.ribose.yml +66 -0
  7. data/.rubocop.tb.yml +650 -0
  8. data/.rubocop.yml +15 -0
  9. data/.travis.yml +21 -0
  10. data/CODE_OF_CONDUCT.md +46 -0
  11. data/Gemfile +7 -0
  12. data/LICENSE +25 -0
  13. data/Makefile +39 -0
  14. data/README.adoc +882 -0
  15. data/Rakefile +6 -0
  16. data/asciidoctor-iso.gemspec.old +50 -0
  17. data/bin/rspec +18 -0
  18. data/docs/customisation.adoc +186 -0
  19. data/docs/guidance.adoc +436 -0
  20. data/docs/htmloutput.adoc +115 -0
  21. data/docs/quickstart.adoc +375 -0
  22. data/lib/asciidoctor-iso.rb +11 -0
  23. data/lib/asciidoctor/iso/base.rb +48 -0
  24. data/lib/asciidoctor/iso/biblio.rng +836 -0
  25. data/lib/asciidoctor/iso/cleanup.rb +39 -0
  26. data/lib/asciidoctor/iso/converter.rb +19 -0
  27. data/lib/asciidoctor/iso/front.rb +131 -0
  28. data/lib/asciidoctor/iso/isodoc.rng +1059 -0
  29. data/lib/asciidoctor/iso/isostandard.rnc +176 -0
  30. data/lib/asciidoctor/iso/isostandard.rng +1001 -0
  31. data/lib/asciidoctor/iso/section.rb +72 -0
  32. data/lib/asciidoctor/iso/validate.rb +190 -0
  33. data/lib/asciidoctor/iso/validate_requirements.rb +105 -0
  34. data/lib/asciidoctor/iso/validate_section.rb +214 -0
  35. data/lib/asciidoctor/iso/validate_style.rb +134 -0
  36. data/lib/asciidoctor/iso/version.rb +5 -0
  37. data/lib/isodoc/iso/html/header.html +206 -0
  38. data/lib/isodoc/iso/html/html_iso_intro.html +34 -0
  39. data/lib/isodoc/iso/html/html_iso_titlepage.html +34 -0
  40. data/lib/isodoc/iso/html/htmlstyle.scss +46 -0
  41. data/lib/isodoc/iso/html/isodoc.scss +696 -0
  42. data/lib/isodoc/iso/html/scripts.html +174 -0
  43. data/lib/isodoc/iso/html/style-human.scss +1277 -0
  44. data/lib/isodoc/iso/html/style-iso.scss +1257 -0
  45. data/lib/isodoc/iso/html/word_iso_intro.html +72 -0
  46. data/lib/isodoc/iso/html/word_iso_titlepage.html +62 -0
  47. data/lib/isodoc/iso/html/wordstyle.scss +1175 -0
  48. data/lib/isodoc/iso/html_convert.rb +118 -0
  49. data/lib/isodoc/iso/metadata.rb +107 -0
  50. data/lib/isodoc/iso/word_convert.rb +141 -0
  51. data/lib/metanorma/iso.rb +7 -0
  52. data/lib/metanorma/iso/processor.rb +44 -0
  53. data/spec/asciidoctor-iso/base_spec.rb +350 -0
  54. data/spec/asciidoctor-iso/blocks_spec.rb +469 -0
  55. data/spec/asciidoctor-iso/cleanup_spec.rb +765 -0
  56. data/spec/asciidoctor-iso/inline_spec.rb +162 -0
  57. data/spec/asciidoctor-iso/isobib_cache_spec.rb +332 -0
  58. data/spec/asciidoctor-iso/lists_spec.rb +190 -0
  59. data/spec/asciidoctor-iso/macros_spec.rb +111 -0
  60. data/spec/asciidoctor-iso/refs_spec.rb +643 -0
  61. data/spec/asciidoctor-iso/section_spec.rb +334 -0
  62. data/spec/asciidoctor-iso/table_spec.rb +307 -0
  63. data/spec/asciidoctor-iso/validate_spec.rb +907 -0
  64. data/spec/assets/header.html +7 -0
  65. data/spec/assets/html.css +2 -0
  66. data/spec/assets/htmlcover.html +4 -0
  67. data/spec/assets/htmlintro.html +5 -0
  68. data/spec/assets/i18n.yaml +2 -0
  69. data/spec/assets/iso.doc +1093 -0
  70. data/spec/assets/iso.headless.html +33 -0
  71. data/spec/assets/iso.html +278 -0
  72. data/spec/assets/iso.xml +8 -0
  73. data/spec/assets/rice_image1.png +0 -0
  74. data/spec/assets/scripts.html +3 -0
  75. data/spec/assets/std.css +2 -0
  76. data/spec/assets/word.css +2 -0
  77. data/spec/assets/wordcover.html +3 -0
  78. data/spec/assets/wordintro.html +4 -0
  79. data/spec/examples/103_01_02.html +247 -0
  80. data/spec/examples/english.yaml +69 -0
  81. data/spec/examples/iso_123_.xml +45 -0
  82. data/spec/examples/iso_123_all_parts.xml +45 -0
  83. data/spec/examples/iso_123_no_year_note.xml +46 -0
  84. data/spec/examples/iso_124_.xml +41 -0
  85. data/spec/examples/iso_216_.xml +47 -0
  86. data/spec/examples/iso_iec_12382_.xml +48 -0
  87. data/spec/examples/rice.adoc +715 -0
  88. data/spec/examples/rice.preview.html +1877 -0
  89. data/spec/examples/rice.sh +4 -0
  90. data/spec/examples/rice_images/rice_image1.png +0 -0
  91. data/spec/examples/rice_images/rice_image2.png +0 -0
  92. data/spec/examples/rice_images/rice_image3_1.png +0 -0
  93. data/spec/examples/rice_images/rice_image3_2.png +0 -0
  94. data/spec/examples/rice_images/rice_image3_3.png +0 -0
  95. data/spec/isodoc/i18n_spec.rb +642 -0
  96. data/spec/isodoc/iso_spec.rb +168 -0
  97. data/spec/isodoc/metadata_spec.rb +152 -0
  98. data/spec/isodoc/postproc_spec.rb +405 -0
  99. data/spec/isodoc/section_spec.rb +522 -0
  100. data/spec/isodoc/xref_spec.rb +1337 -0
  101. data/spec/metanorma/processor_spec.rb +70 -0
  102. data/spec/spec_helper.rb +227 -0
  103. metadata +402 -0
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,50 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path("../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "asciidoctor/iso/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "asciidoctor-iso"
9
+ spec.version = Asciidoctor::ISO::VERSION
10
+ spec.authors = ["Ribose Inc."]
11
+ spec.email = ["open.source@ribose.com"]
12
+
13
+ spec.summary = "asciidoctor-iso lets you write ISO standards "\
14
+ "in AsciiDoc."
15
+ spec.description = <<~DESCRIPTION
16
+ asciidoctor-iso lets you write ISO standards in AsciiDoc syntax.
17
+
18
+ This gem is in active development.
19
+ DESCRIPTION
20
+
21
+ spec.homepage = "https://github.com/riboseinc/asciidoctor-iso"
22
+ spec.license = "BSD-2-Clause"
23
+ spec.post_install_message = "The asciidoctor-iso gem has been deprecated and has been replaced by metanorma-iso"
24
+
25
+ spec.bindir = "bin"
26
+ spec.require_paths = ["lib"]
27
+ spec.files = `git ls-files`.split("\n")
28
+ spec.test_files = `git ls-files -- {spec}/*`.split("\n")
29
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
30
+
31
+ spec.add_dependency "asciidoctor", "~> 1.5.7"
32
+ spec.add_dependency "ruby-jing"
33
+ spec.add_dependency "isodoc", "~> 0.8.8"
34
+ spec.add_dependency "iev", "~> 0.2.0"
35
+ spec.add_dependency "relaton", "~> 0.1.3"
36
+ spec.add_dependency "metanorma-standoc", "~> 0.0.1"
37
+
38
+ spec.add_development_dependency "bundler", "~> 1.15"
39
+ spec.add_development_dependency "byebug"
40
+ spec.add_development_dependency "equivalent-xml", "~> 0.6"
41
+ spec.add_development_dependency "guard", "~> 2.14"
42
+ spec.add_development_dependency "guard-rspec", "~> 4.7"
43
+ spec.add_development_dependency "rake", "~> 12.0"
44
+ spec.add_development_dependency "rspec", "~> 3.6"
45
+ spec.add_development_dependency "rubocop", "~> 0.50"
46
+ spec.add_development_dependency "simplecov", "~> 0.15"
47
+ spec.add_development_dependency "timecop", "~> 0.9"
48
+ spec.add_development_dependency "metanorma", "~> 0.2.6"
49
+ spec.add_development_dependency "isobib", "~> 0.2.0"
50
+ end
data/bin/rspec ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require "pathname"
10
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path(
11
+ "../../Gemfile", Pathname.new(__FILE__).realpath
12
+ )
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("rspec-core", "rspec")
18
+
@@ -0,0 +1,186 @@
1
+ = Gem Customisation Guide
2
+
3
+ In this guide, we give advice on how to adopt the Metanorma approach to document generation for your documents. We provide enough guidance for you to do full customisation, but we prefix each section with a Tip for quick-and-dirty implementation.
4
+
5
+ == How can I adopt the StanDoc specification for my own publications?
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
+ == How can I adapt the StanDoc toolchain for my own publications?
33
+
34
+ [TIP]
35
+ ====
36
+ 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.
37
+
38
+ If you wish to create a custom gem, in order to customise behaviour further:
39
+
40
+ * Clone the metanorma-sample gem: https://github.com/riboseinc/metanorma-sample.
41
+ * Change the namespace for RSD documents (`RSD_NAMESPACE = "https://open.ribose.com/standards/rsd"`) to a namespace specific to your organisation's document standard.
42
+ * Change any references to `sample` or `Sample` in the gem to your organisation's document standard.
43
+ * Change the styling of the document outputs (`.../lib/isodoc/XXX/html`).
44
+ ====
45
+
46
+ 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.)
47
+
48
+ 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).
49
+
50
+ The modules involve classes which rely on inheritance from other classes; the current gems all use `Asciidoctor::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.
51
+
52
+ In the case of `Asciidoctor::X` classes, the changes you will need to make involve the intermediate XML representation of your document; 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:
53
+
54
+ * The boilerplate representation of the document's author, publisher and copyright holder names Ribose instead of ISO as the responsible organisation.
55
+ * The editorial committees are represented as a single element, as opposed to ISO's name plus number.
56
+ * The document title is monolingual, not bilingual.
57
+ * The document status is a single element, as opposed to ISO's two-part code.
58
+ * The document identifier is a single element.
59
+ * Title validation and style validation is disabled.
60
+ * The root element of the document is changed from `iso-standard` to `rsd-standard`.
61
+ * The document type attribute is restricted to a prescribed set of options.
62
+ * A `literal` element and a `keyword` element is added to the ISO instance of Standoc.
63
+ * The inline headers of ISO are ignored.
64
+
65
+ The customisations needed for Metanorma::Sample::Processor are minor:
66
+
67
+ * `initialize` names the token by which Asciidoctor registers the standard
68
+ * `output_formats` names the available output formats (including XML, which is inherited from the parent class)
69
+ * `version` gives the current version string for the gem
70
+ * `input_to_isodoc` is the call which converts Asciidoctor input into IsoDoc XML
71
+ * `output` is the call which converts IsoDoc XML into various nominated output formats
72
+
73
+ The customisations needed for Isodoc::Sample are more extensive. Three base classes are involved:
74
+
75
+ * `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].
76
+ * `Isodoc::HtmlConvert` converts Standoc XML to HTML.
77
+ * `Isodoc::WordConvert` converts Standoc XML to Word HTML; the https://github.com/riboseinc/html2doc[html2doc] gem then converts this to a .doc document.
78
+
79
+ The `Isodoc::HtmlConvert` and `Isodoc::WordConvert` overlap substantially, as both use variants of HTML; in fact the files `samplehtmlrender.rb` and `samplewordrender.rb` are deliberately identical, apart from the class their code belongs to. However there is no reason not to make substantially different rendering choices in the HTML and Word branches of the code.
80
+
81
+ = How can I style the resulting HTML output?
82
+
83
+ [TIP]
84
+ ====
85
+ * Clone the metanorma-sample gem: https://github.com/riboseinc/metanorma-sample.
86
+ * Edit the `html_sample_titlepage.html` and `html_sample_intro.html` pages to match your organisation's branding.
87
+ ** Leave the Liquid Template instructions alone (`{{`, `{%`) unless you know what you're doing with them: they are how the pages are populated with metadata.
88
+ * Edit the `default_fonts()` method in your `IsoDoc::...::HtmlConvert` class, to match your desired fonts.
89
+ * Edit the `default_file_locations()` method in your `IsoDoc::...::HtmlConvert` class, to match your desired stylesheets and HTML templates.
90
+ * 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.
91
+ ====
92
+
93
+ 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.
94
+
95
+ * 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).
96
+ * 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.
97
+ * 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.)
98
+ * 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.
99
+ * 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.)
100
+ * 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.
101
+ * 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.
102
+ * An HTML document is populated as follows:
103
+ ** HTML Head wrapper (in `IsoDoc::HtmlConvert`)
104
+ *** `html_head()` content
105
+ *** `@htmlstylesheet` CSS stylesheet (expected to be in SCSS, generated from SCSS in the `generate_css()` method of `Isodoc::HtmlConvert`).
106
+ ** HTML Body
107
+ *** `@htmlcoverpage` HTML template (optional, corresponds to `html_..._titlepage.html`)
108
+ *** `@htmlintropage` HTML template (optional, corresponds to `html_..._intro.html`)
109
+ *** Document proper (converted from Standoc XML)
110
+ *** `@scripts` Javascript Scripts (optional, corresponds to `scripts.html`)
111
+ * 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.
112
+
113
+ = How can I style the resulting Word output?
114
+
115
+ [TIP]
116
+ ====
117
+ * There is no quick way of doing this.
118
+ * Everything you can do in Word, you can do in Word HTML. Save Word documents as Word HTML to see how.
119
+ * Clone the metanorma-sample gem: https://github.com/riboseinc/metanorma-sample.
120
+ * 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.
121
+ ** Leave the Liquid Template instructions alone (`{{`, `{%`) unless you know what you're doing with them: they are how the pages are populated with metadata.
122
+ * Edit the `default_fonts()` method in your `IsoDoc::...::WordConvert` class, to match your desired fonts.
123
+ * Edit the `default_file_locations()` method in your `IsoDoc::...::WordConvert` class, to match your desired stylesheets and file templates.
124
+ * 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.
125
+ ====
126
+
127
+ 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.)
128
+
129
+ 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.
130
+
131
+ It's still better than learning OOXML.
132
+
133
+ 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.
134
+
135
+ * 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).
136
+ * The styling files to be loaded in are set in the `default_file_locations()` method of `IsoDoc::...::WordConvert`.
137
+ * 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.
138
+ * 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.
139
+ * As with HTML, the SCSS stylesheets treat fonts as variables, and are set in the `default_fonts()` method of `IsoDoc::...::WordConvert`.
140
+ * 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.
141
+ * A Word HTML document is populated as follows:
142
+ ** HTML Head wrapper (in `IsoDoc::WordConvert`)
143
+ *** `@wordstylesheet` CSS stylesheet (generated from SCSS through the `generate_css()` method of `Isodoc::WordConvert`); corresponds to `wordstyle.scss`.
144
+ *** `@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`.
145
+ ** HTML Body
146
+ *** `@wordcoverpage` HTML template (optional, corresponds to `word_..._titlepage.html`). Included in `<div class=WordSection1>`.
147
+ *** `@htmlintropage` HTML template (optional, corresponds to `word_..._intro.html`). Included in `<div class=WordSection2>`. In the existing gems, WordSection2 is paginated with roman numerals.
148
+ *** 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.
149
+ * 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.
150
+
151
+ = How can I localize the resulting output?
152
+
153
+ [TIP]
154
+ ====
155
+ * Copy the `lib/isodoc/i18n-en.yaml` file from the isodoc gem to your gem.
156
+ * Edit the right-hand text in the file.
157
+ * Give the file location as the `i18nyaml` document attribute in any files you wish to use your localisation.
158
+ ====
159
+
160
+ 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.
161
+
162
+ 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.
163
+
164
+ 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-csd gem, this label is overruled in code to be "Appendix" instead.
165
+
166
+ 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.
167
+
168
+ 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.
169
+
170
+ 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.
171
+
172
+ = 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?
173
+
174
+ [TIP]
175
+ ====
176
+ * Generate correct IsoDoc XML (make sure it validates!)
177
+ * Create just the `IsoDoc::...::HtmlConvert` and/or `IsoDoc::...::WordConvert` classes to convert the IsoDoc XML into target formats.
178
+ * Initialise the IsoDoc class passing the necessary information about fonts and scripts; the existing gems all illustrate this kind of initialisation.
179
+ * Create the target format using the method `.convert(filename, xml)`.
180
+ ====
181
+
182
+ 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.
183
+
184
+ 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.
185
+
186
+ 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.
@@ -0,0 +1,436 @@
1
+ = Guidance for Authoring
2
+ The Asciidoc approach to authoring ISO standards (and other related standards under Metanorma) is not https://en.wikipedia.org/wiki/WYSIWYG[WYSIWYG]: you are dealing with a text editor and a console rather than a Word document, and you are authoring something that looks more like HTML than the final product. On the other hand, editing documents with a markup system like Asciidoc makes it much easier to automate key validation and formatting processes, such as checking for missing document components, autonumbering, and generating output in multiple formats.
3
+
4
+ The documents you will be authoring will be in the http://asciidoctor.org[Asciidoc] formatting language, so you need to be familiar with that language's markup conventions: the http://asciidoctor.org/docs/user-manual/[Asciidoctor User Manual] will be your companion (supplemented by the https://github.com/riboseinc/metanorma-iso#asciidoctor-model-additions[additions to markup made for ISO standards]. However we have tried to make things easier for you by preparing an https://github.com/riboseinc/metanorma-iso/blob/master/spec/examples/rice.adoc[AsciiDoc version] of the ISO Standard exemplar, the https://www.iso.org/publication/PUB100407.html["Rice document"]. If you use this document as a template for your own ISO standard document, you will find most of the formatting you need illustrated there.
5
+
6
+ == Usage
7
+
8
+ See the README on https://github.com/riboseinc/metanorma-iso#usage[how to deploy and use the gem].
9
+
10
+ == Output in different languages
11
+
12
+ The gem allows generation of standards in different languages; the language of the document is specified in the `:language:` document attribute (and `:script:`, for languages with more than one script).
13
+
14
+ For each language, language-specific templated text is specified for the boilerplate, labels and cross-references that are included in document output. The gem has predefined templates for English, Chinese (Simplified) and French. You can specify your own language by providing your own http://www.yaml.org/spec/1.2/spec.html[YAML] template file, and linking to it with the `:i18nyaml` document attribute. The YAML template you provide needs to match https://github.com/riboseinc/isodoc/blob/master/lib/isodoc/i18n-en.yaml, substituting translations for each of the fields given.
15
+
16
+ The Chinese (Simplified) template also localises punctuation and spacing, mapping them away from the default Latin punctuation used elsewhere in the gem.
17
+
18
+ == Validation
19
+
20
+ All AsciiISO documents that are processed by the Asciidoctor-ISO gem are validated against a formal schema for the document structure, as well as style rules around content. The gem will generate a sequence of warnings; you should pay attention to them.
21
+
22
+ The content warnings come first, and are prefixed with `ISO Style`. They try to impose rules on content taken from http://www.iec.ch/members_experts/refdocs/iec/isoiecdir-2%7Bed7.0%7Den.pdf[ISO/IEC DIR 2], including restrictions on where requirements may be stated, usage of decimal points, hanging clauses, and subclauses that are the only child of their parent clause. While the error detection is not infallible, they should be reviewed at least once. Where possible, the gem will give the ID or section heading associated with the error. For example:
23
+
24
+ [source,console]
25
+ --
26
+ ISO style: WARNING (Section: ): Footnote may contain requirement: The maximum permissible mass fraction of defects shall be determined with respect to the mass fraction obtained after milling.
27
+ ISO style: WARNING (Section: Wire sieve,): possible decimal point: 0.02
28
+ ISO style: invalid technical committee type XYZ
29
+ ISO style: AnnexA-4-1:Preparation of test sample: subsection is only child
30
+ --
31
+
32
+ The syntax errors come afterwards, and they report the line number and line position of the syntax error in the intermediate XML format generated by the gem. (For example, the AsciiDoc document `rice.adoc` generates the intermediate XML file `rice.xml`.) These errors deal with restrictions on what kinds of text can appear where, pointers within the document that are orphaned, and elements that appear in the wrong sequence. Deciphering what has gone wrong with them may take more effort, but the errors they point to are more serious than the style errors, and need to be resolved for the document to be well-formed. The gem will usually (but not always!) generate HTML and Word output despite the presence of those errors.
33
+
34
+ For example:
35
+
36
+ [source,console]
37
+ --
38
+ value of attribute "date" is invalid; must be an ISO date @ 454:183
39
+ element "review" missing required attribute "from" @ 454:183
40
+ element "subsection" not allowed here; expected the element end-tag or element "admonition", "dl", "example", "figure", "formula", "note", "ol", "p", "quote", "review", "sourcecode", "table" or "ul" @ 467:52
41
+ value of attribute "date" is invalid; must be an ISO date @ 476:233
42
+ IDREF "Annex-A-2" without matching ID @ 315:50
43
+ IDREF "last_conformance_class" without matching ID @ 649:236
44
+ IDREF "Annex-A" without matching ID @ 308:141
45
+ --
46
+
47
+ Currently validation only processes English-language text for language-specific rules (e.g. requirements); French validation is planned.
48
+
49
+ The gem also validates terms cited from the IEV against the online IEV Electropedia entries: if the preferred term does not match the form given in the IEV for that entry, it will issue a warning.
50
+
51
+ == Document header
52
+
53
+ The core metadata about the standard comes from the Asciidoc document header (the list of colon-delimited attributes at the start of the document), and the https://github.com/riboseinc/metanorma-iso#document-attributes[README documents what those fields should be]. Use the Rice document as a template, and be careful about sticking to the guidelines on populating them.
54
+
55
+ The Rice document contains some additional fields that are not essential to ISO rendering, and help Asciidoctor preview the document with its native renderer, should you so choose. (For example, `:appendix-caption: Annex` ensures that the native Asciidoctor renderer calls appendices Annexes; but the Word and HTML output of the gem will do so regardless of how this value is populated.) You will need to leave the `:stem:` field in if you have any AsciiMath or MathML to include in the document; otherwise they will not be detected.
56
+
57
+ The document header, unlike the document proper, cannot deal with HTML entities. If you need to enter accented characters for the French title, or dashes for compound titles, you will need to enter them directly as Unicode (even if your console text editor doesn't like it): `:title-main-fr: Spécification et méthodes d'essai`, not `:title-main-fr: Sp\&eacute;cification et m\&eacute;thodes d'essai`; `:title-part-en:Information Technology—Security`, not `:title-part-en:Information Technology\&mdash;Security`.
58
+
59
+ == Document sections
60
+
61
+ Sections are marked off in Asciidoc with titles prefixed by double equal signs, `==`. The gem depends on the titles given to identify the different kinds of sections in the document. As a result, you cannot choose to modify the titles of sections; the `Introduction`, `Scope`, `Normative References`, `Terms and Definitions`, `Symbols and Abbreviations`, and `Bibliography` need to be titled as such.
62
+
63
+ The Foreword of an ISO standard is detected as any text between the document header and the first section header (the document preamble). The Rice document gives the `.Foreword` title to the preamble, but the gem will supply the "Foreword" title regardless of what title is present.
64
+
65
+ In the Rice document, Asciidoctor section numbering is disabled for the Foreword and Introduction, and reenabled for the Scope. Again, the gem will number those sections correctly whatever the markup.
66
+
67
+
68
+ === Bibliographies
69
+
70
+ The Normative References and the Bibliography must be preceded by the style attribute `[bibliography]`, so that the references they contain may be recognised as such.
71
+
72
+ All bibliographic entries must be given as unordered lists.
73
+
74
+ Currently the gem only supports formatted citations, which are given as such in the Asciidoc source. In the future, we expect to integrate the documents with http://www.bibtex.org[BibTex] databases, through the https://github.com/riboseinc/asciidoctor-bibliography[asciidoctor-bibliography] gem.
75
+
76
+ ==== ISO References
77
+
78
+ For ISO and related standards, the entry must be preceded by a bibliographic anchor, in triple brackets: this consists of an internal identifier (used in citations), followed by the ISO identifier for the reference as its label. For example:
79
+
80
+ [source,asciidoc]
81
+ --
82
+ * [[[ricepotentialmilling,ISO 6646]]], _Rice -- Determination of the potential milling yield from paddy and from husked rice_
83
+ * [[[ISOGuide73, ISO Guide 73:2009]]], _Risk management -- Vocabulary_
84
+ --
85
+
86
+ [subs="quotes"]
87
+ ISO 6646 is cited from elsewhere in the document through crossreferences to the `ricepotentialmilling` identifier; e.g. `<< ricepotentialmilling>>` (which will be rendered as `ISO 6646`), `<<``ricepotentialmilling, section 5``>>` (which will be rendered as `ISO 6646, Section 5`), `<<``ricepotentialmilling,section 5: the foregoing discussion``>>` (which will be tagged in the XML representation as Section 5 of ISO 6646, but will be displayed as `the foregoing discussion`.)
88
+
89
+ If an ISO reference is in preparation, ISO/IEC DIR 2 dictates that details of the reference status be given as a footnote. In Asciidoc, this is done by giving the date as a double dash, and following the bibliographic anchor with a footnote macro:
90
+
91
+ [source,asciidoc]
92
+ --
93
+ * [[[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_
94
+ --
95
+
96
+ If an ISO reference includes all parts of the standard, that is indicated by appending `(all parts)` after the reference anchor:
97
+
98
+ [source,asciidoc]
99
+ --
100
+ * [[[ISO16634,ISO 16634 (all parts)]]] _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_
101
+ --
102
+
103
+
104
+ In informative references, ISO references are still given with the same format of bibliographic anchor, and they are cited by ISO document code -- although they are displayed with an incrementing reference number in brackets instead. So
105
+
106
+ [source,asciidoc]
107
+ --
108
+ [bibliography]
109
+ == Bibliography
110
+
111
+ * [[[ISO3696,ISO 3696]]], _Water for analytical laboratory use -- Specification and test methods_
112
+ --
113
+
114
+ is displayed as:
115
+
116
+ [quote]
117
+ ____
118
+ *Bibliography*
119
+
120
+ [1] ISO 3696, _Water for analytical laboratory use -- Specification and test methods_
121
+ ____
122
+
123
+ ==== ISO Reference Fetching
124
+
125
+ If any bibliographic entry has a label prefixed with `ISO`, e.g. `[[` `[ricepotentialmilling,ISO 6646]` `]]`, the gem accesses the ISO website (via the `isobib` stem), and screenscrapes the details of that item. The screenscraped data overrides any content about the item provided in the document, since the ISO website is treated as the bibliographic source of truth on ISO documents.
126
+
127
+ ==== Non-ISO References
128
+
129
+ In normative references, non-ISO documents must still be given a document code (or title) in their bibliographic anchor:
130
+
131
+ [source,asciidoc]
132
+ --
133
+ * [[[RFC4291,IETC RFC 4193]]] _Unique Local IPc6 Unicast Addresses_, October 2005. http://www.ietf.org/rfc/rfc4291.txt
134
+ * [[IANAMediaTypes,IANA Media Types Assignment]]], March 2017. http://www.iana.org/assignments/media-types/media-types.xthml
135
+ --
136
+
137
+ In informative references, non-ISO documents are both displayed and cited with reference numbers in brackets. Those numbers are given in the reference anchor instead of the ISO document code. ISO references appear before non-ISO references; the reference number is expected to be correct in context:
138
+
139
+ [source,asciidoc]
140
+ --
141
+ * [[[IEC61010-2,IEC 61010-2:1998]]], _Safety requirements for electric equipment for measurement, control, and laboratory use -- Part 2: Particular requirements for laboratory equipment for the heating of material_
142
+
143
+ * [[[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)
144
+ --
145
+
146
+ ==== Cross-References
147
+
148
+ Normally in Asciidoctor, any text in a cross-reference that follows a comma constitutes custom text for the cross-reference. So a cross-reference `<<ISO7301,the foregoing reference>>` will be rendered as "the foregoing reference", and hyperlinked to the ISO7301 reference.
149
+
150
+ In AsciiISO cross-references, bibliographic localities (e.g. page numbers, clause numbers) can be added directly after the comma, as part of the cross-reference text: this overrides the normal Asciidoctor treatment of custom text. Bibliographic localities are expressed as a sequence of lowercase locality type, then an equal sign, then the locality value or range of values. The locality can appear in quotations, if it contains special characters (like dashes or commas).
151
+
152
+ [source,asciidoctor]
153
+ --
154
+ <<ISO7301,clause=3.1-3.4>>
155
+
156
+ NOTE: This table is based on <<ISO7301,table=1>>.
157
+
158
+ Sampling shall be carried out in accordance with <<xxx,section="5-3-1,bis">>
159
+ --
160
+
161
+ Any text after the bibliographic localities is still treated as custom cross-reference text; e.g. `<<ISO7301,clause=5,table=1,the foregoing reference>>`.
162
+
163
+ Custom cross-references should not be used in ISO standards, either for an external reference, or for a section of the current document: ISO/IEC DIR 2 requires any cross-references to be transparent in text. For example, a cross-reference to the anchor `[[tabular]]` on clause 5 should be given as just `<<tabular>>`, without any custom text: it will be automatically rendered as `Clause 5` by the gem.
164
+
165
+ 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_.
166
+
167
+
168
+ === Terms and Definitions
169
+
170
+ The title of a top-level Terms and Definitions clause is populated automatically, overriding the title provided by the user: if it contains a Symbols and Abbreviated Terms subclause, it is titled _Terms, definitions, symbols and abbreviated terms_, otherwise it is titled _Terms and definitions_. A Terms and Definitions clause will be recognised if either title is given, regardless of case. Symbols and Abbreviated Terms subclauses are also automatically titled; other subclauses of Terms and Definitions clauses are not.
171
+
172
+ If the Terms and Definitions are partly or fully sourced from another standard, that document is named as a `[source=REFERENCE]` attribute to the section. (The attribute needs to be applied to the top-level clause, if there are subclauses.) If there are no terms and definitions defined in this standard, no terms should be included in the section body (it should be blank). The boilerplate at the start of the section is adjusted to reflect both possibilities; any paragraphs or lists in the Asciidoctor input (which can replicate the expected boilerplate) is stripped in the intermediate XML format.
173
+
174
+ Terms and Definitions sections follow a strict grammar, which is reflected in their Asciidoc markup:
175
+
176
+ * The term is given as a subheading at the appropriate level (three equal signs, unless there are subsections in the Terms and Definition section). The term may be crossreferenced from other terms, in which case it should have an anchor.
177
+ * The term is optionally followed by alternative/admitted terms, which must be marked up in an `+alt:[...]+` macro; deprecated terms, which must be marked up in a `+deprecated:[...]+` macro; and a term domain, which must be marked up in a `+domain:[...]+` macro.
178
+ * The definition of the term is given in a separate paragraph.
179
+ * The definition is optionally followed by examples (paragraphs with an `[example]` style attribute).
180
+ * The definition is then optionally followed by notes (denoted with a `NOTE:` prefix).
181
+ * The definition is then followed by a citation for the term, marked with a `[.source]` role attribute).
182
+ * The citation is a cross-reference to a normative reference, optionally followed by a comma and a modification if applicable.
183
+
184
+ For example,
185
+
186
+ [source,asciidoc]
187
+ --
188
+ [[paddy]]
189
+ === paddy
190
+ alt:[paddy rice]
191
+ alt:[rough rice]
192
+ deprecated:[cargo rice]
193
+ domain:[rice]
194
+
195
+ rice retaining its husk after threshing
196
+
197
+ [example]
198
+ Foreign seeds, husks, bran, sand, dust.
199
+
200
+ NOTE: The starch of waxy rice consists almost entirely of amylopectin. The kernels have a tendency to stick together after cooking.
201
+
202
+ [.source]
203
+ <<ISO7301,section 3.2>>, The term "cargo rice" is shown as deprecated,
204
+ and Note 1 to entry is not included here
205
+ --
206
+
207
+ The requirement that the source of a term be given in a citation also applies when the source is a term bank, such as http://www.electropedia.org[IEV]. By ISO convention, IEV references are not included in the bibliography, but for consistency and validation purposes, the IEV should be cited as a normal reference, with the term given as a clause, and the source should be named as IEV in the bibliography. The XML encoding of the document will include the IEV reference, substituting a canonical form of the reference in the bibliography; the output rendering of the document will drop the reference from the bibliography. For example:
208
+
209
+ [source,asciidoc]
210
+ --
211
+ [.source]
212
+ <<ievtermbank,clause="103-01-02">>
213
+ ....
214
+
215
+ [bibliography]
216
+ * [[[ievtermbank,IEV]]], _IEV: Electropedia_
217
+ // will be excluded from HTML and Word output. Will be replaced by a canonical reference in XML output.
218
+ --
219
+
220
+ Note that, for IEV entries to be validated, the IEV reference must be given as a Clause, and in quotes (otherwise the locality syntax would be interpreted as a range); so `<<ievtermbank,clause="103-01-02">>` for IEV 103-01-02.
221
+
222
+ Asciidoc does not permit macros to be nested inside other macros; so the following markup, introducing a stem expression as an admitted term, is illegal. (The use of stem expressions as preferred terms is not a problem, because the macro appears as a header.)
223
+
224
+ [source,asciidoc]
225
+ --
226
+ === stem:[t_90]
227
+ alt:[stem:[t_A]]
228
+
229
+ Time to launch.
230
+ --
231
+
232
+ However, the gem will treat any standalone paragraph in a term section, consisting of just a stem macro, as an admitted term:
233
+
234
+ [source,asciidoc]
235
+ --
236
+ === stem:[t_90]
237
+
238
+ stem:[t_A]
239
+
240
+ Time to launch.
241
+ --
242
+
243
+
244
+ === Symbols and Abbreviations
245
+
246
+ Symbols and Abbreviations sections are expected to be simple definition lists (http://asciidoctor.org/docs/user-manual/#labeled-list["labelled lists"] in Asciidoc nomenclature). The gem takes care of sorting the symbols in the order prescribed by ISO/IEC DIR 2, provided the symbols are in AsciiMath; sorting MathML entries is not currently supported.
247
+
248
+ === Clauses
249
+
250
+ Blank subclause headings can be given as `=== {blank}`. These are used when you want to give a subclause number for a new subclause, but without an associated header text. So e.g. in the Rice Model document,
251
+
252
+ [source,asciidoc]
253
+ --
254
+ === Physical and chemical characteristics
255
+
256
+ ==== {blank}
257
+
258
+ The mass fraction of moisture, determined in accordance with...
259
+ --
260
+
261
+ renders as
262
+
263
+ ____
264
+ *4.2. Physical and chemical characteristics*
265
+
266
+ *4.2.1.* The mass fraction of moisture, determined in accordance with...
267
+ ____
268
+
269
+
270
+ Inline subclause headings (e.g. for test methods) are indicated by preceding the heading with the `[%inline-header]` option attribute. So in the Rice Model document,
271
+
272
+ [source,asciidoc]
273
+ --
274
+ [%inline-header]
275
+ ==== Sieve,
276
+
277
+ with round perforations of diameter 1,4 mm.
278
+ --
279
+
280
+ renders as
281
+
282
+ ____
283
+ *A.2.1.1. Sieve,* with round perforations of diameter 1,4 mm.
284
+ ____
285
+
286
+
287
+ Normative clauses are indicated with the attribute `[obligation=informative]`; they are normative by default.
288
+
289
+ === Annexes
290
+
291
+ All annexes must be preceded by the style attribute `[appendix]`, in order to be recognised correctly. 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]`).
292
+
293
+ Appendixes to annexes can occur, although they are not mentioned in ISO/IEC DIR 2; ISO/IEC DIR 1 features them. They are marked up as immediate subsections of annexes, and must be tagged with an option attribute of "appendix":
294
+
295
+ [source,asciidoc]
296
+ --
297
+ [appendix]
298
+ == Annex A
299
+ Text
300
+
301
+ [%appendix]
302
+ === Appendix 1
303
+ Text
304
+ --
305
+
306
+ The numbering of annexes and appendices is automatic: do not insert "Annex A" or "Appendix 1" as part of the title. Annex and Appendix titles can be left blank, as with Clauses.
307
+
308
+ == Text markup
309
+
310
+ === Mathematical formatting
311
+
312
+ Mathematical formatting is done using the `[stem]` macro. Asciidoc supports http://asciimath.org[AsciiMath] and LaTeX natively (AsciiMath by default); as of this writing the gem only supports AsciiMath. AsciiMath is converted to Microsoft Word's OOML via MathML, using the https://github.com/asciidoctor/asciimath[AsciiMath] Ruby gem; the syntax of the Ruby gem may be at odds with the usual MathJax processor of AsciiMath. (We have found that the Ruby gem insists on numerators being bracketed.)
313
+
314
+ === Formulae
315
+
316
+ Formulae are marked up as `[stem]` blocks. Any explanation of symbols in the formula is given as a "where" paragraph, followed by a definition list. For example:
317
+
318
+ [source,asciidoc]
319
+ --
320
+ [[formulaA-1]]
321
+ [stem]
322
+ ++++
323
+ w = (m_D) / (m_s)
324
+ ++++
325
+
326
+ where
327
+
328
+ stem:[w]:: is the mass fraction of grains with a particular defect in the test sample;
329
+ stem:[m_D]:: is the mass, in grams, of grains with that defect;
330
+ stem:[m_S]:: is the mass, in grams, of the test sample.
331
+ --
332
+
333
+ === Figures
334
+
335
+ Like formulae, figures can be followed by a definition list for the variables used in the figure; the definition list is preceded by `+*Key*+`. For example:
336
+
337
+ [source,asciidoc]
338
+ --
339
+ [[figureC-1]]
340
+ .Typical gelatinization curve
341
+ image::rice_images/rice_image2.png[]
342
+ footnote:[The time stem:[t_90] was estimated to be 18,2 min for this example.]
343
+
344
+ *Key*
345
+
346
+ stem:[w]:: mass fraction of gelatinized kernels, expressed in per cent
347
+ stem:[t]:: cooking time, expressed in minutes
348
+ stem:[t_90]:: time required to gelatinize 90 % of the kernels
349
+ P:: point of the curve corresponding to a cooking time of stem:[t_90]
350
+
351
+ NOTE: These results are based on a study carried out on three different types of kernel.
352
+ --
353
+
354
+ Subfigures are entered by including images in an Asciidoc example:
355
+
356
+ [source,asciidoc]
357
+ --
358
+ [[figureC-2]]
359
+ .Stages of gelatinization
360
+ ====
361
+ .Initial stages: No grains are fully gelatinized (ungelatinized starch granules are visible inside the kernels)
362
+ image::rice_images/rice_image3_1.png[]
363
+
364
+ .Intermediate stages: Some fully gelatinized kernels are visible
365
+ image::rice_images/rice_image3_2.png[]
366
+
367
+ .Final stages: All kernels are fully gelatinized
368
+ image::rice_images/rice_image3_3.png[]
369
+
370
+ ====
371
+ --
372
+
373
+ === Tables
374
+
375
+ Asciidoc tables are quite powerful for a non-XML markup language, but we have had to add the option of multiple header rows (attribute `headerrows=n`), to deal with the complexity of ISO tables with labels, variables, and units lining up in the header.
376
+
377
+ Asciidoc allows table cells to have footnotes (which the gem renders inside the table), and notes following the table (which the gem moves inside the table footer.) Table 1 in the Rice document illustrates a large range of table formatting options.
378
+
379
+ === Lists
380
+
381
+ Unordered lists in Word are rendered with em-dashes instead of bullets, as preferred by ISO. Ordered lists in Word are rendered with their labels bracketed. (_a)_, _1)_, etc.) Ordered lists in both HTML and Word have their labels pre-configured, to align with ISO/IEC DIR 2: _a), b), c)_ for the first level, then _1), 2), 3)_ for the second level, then _i), ii), iii)_, then _A), B), C)_, then _I), II), III)_. The `type` attribute for ordered lists in Asciidoc, which allows the user to specify the label of an ordered list, is ignored.
382
+
383
+ === Footnotes
384
+
385
+ Asciidoc supports only single-paragraph footnotes through its footnote macro (which can only contain a single line of text); this reflects a stylistic bias against digressive text by the Asciidoc creator, and will not change. At best, it can be worked around by introducing line breaks into the macro (see https://github.com/asciidoctor/asciidoctor.org/issues/599, http://discuss.asciidoctor.org/footnotes-with-paragraph-breaks-td4130.html).
386
+
387
+ === Notes
388
+
389
+ Notes that are not at the end of a clause are folded into the preceding block, if that block is not delimited (so that the user could not choose to include or exclude a note): that is, notes are folded into a preceding paragraph, list, formula, or figure.
390
+
391
+ === Reviewer Notes
392
+
393
+ We have introduced a mechanism in the gem to annotate arbitrary blocks of text, using Asciidoc sidebars and anchors for the beginning and end of the annotation; see https://github.com/riboseinc/metanorma-iso#reviewer-notes[discussion in the README].
394
+
395
+ == Cross-references
396
+
397
+ The gem follows the guidance given in ISO/IEC DIR 2 rigorously. In particular, if a formula, example, figure, list, list item or table is cross-referenced outside its (sub)clause, the clause containing the item is always given in the cross-reference, unless the item is being referenced in the same clause. In the case of notes, the containing clause is extended to containing example, figure or table.
398
+
399
+ So for example, in the Rice model document, formula B-.1 is defined in Annex B.6, and is referenced in B.6 and B.7. In the PDF Rice model document, both instances are cited as "Formula (B.1)"; but the gem follows ISO/IEC DIR 2 in citing the former as "Formula (B.1)", but the latter as "B.6, Formula (B.1)".
400
+
401
+ The label of the item cross-referenced, the use of brackets, and the containing reference are all taken care of by the gem; the document author needs only give the item identifier in the Asciidoc (e.g. `<<``formulaB-1``>>` generates either "Formula (B.1)" or "B.6, Formula (B.1)", depending on where in the document it occurs.)
402
+
403
+ List items can be cross-referenced by inserting a bookmark at the very start of the list item:
404
+
405
+ [source,asciidoc]
406
+ --
407
+ . Ordered list
408
+ .. [[id]] This is the first list item
409
+ ... [[id]] This is a list sub-item
410
+ --
411
+
412
+ == Asciidoctor Tips
413
+
414
+ As we have noted, the http://asciidoctor.org/docs/user-manual/[Asciidoctor User Manual] should be your companion when authoring any Asciidoc documents, including Asciidoc documents under Metanorma. There are some more specialised aspects of Asciidoctor markup, which you might need to dig deeper to find in the manual; we list some of them here.
415
+
416
+ * A note or admonition can be made to span multiple paragraphs (including lists and tables), by making it a https://asciidoctor.org/docs/user-manual/#delimited-blocks[delimited block]:
417
+
418
+ [source,asciidoc]
419
+ --
420
+ [NOTE]
421
+ ====
422
+ This is a multi-paragraph note.
423
+
424
+ It includes:
425
+
426
+ * A list
427
+
428
+ |===
429
+ | And
430
+
431
+ | a table
432
+ |===
433
+ ====
434
+ --
435
+
436
+ * https://asciidoctor.org/docs/user-manual/#using-attributes-set-assign-and-reference[Attribute references] can be used as template variables in a document: if your document contains the text `{foo}`, you can assign the value to be populated in `{foo}` by setting it as a document attribute in the Asciidoctor header: `:foo: this is the text to replace "foo"`. In the Rice Model document example, document attributes are used to provide the Subcommittee and Technical Committee names, which are populated as template entries in the document foreword.