Metanorma: Aequitate Verum


Metanorma allows for documents to be authored in any language.

Localizing predefined text that appears in document output (labels such as “Table”, “Foreword”, predefined text for Normative References, etc.) for each language apart from English is done using a YAML template file.

Supported languages

Metanorma has predefined language templates for English, Chinese (Simplified) and French. The Chinese (Simplified) template localizes punctuation and spacing, mapping them away from the default Latin punctuation used normally in Metanorma.

Adding a language

You can add a new language by creating a YAML template file with predefined text. Document authors will need to link to that file via :i18nyaml: document attribute (see Langauges in Author’s documentation).

See sample YAML file for English, where "Foreword" is replaced with "Frontispiece", under metanorma-iso repository’s examples directory.


A good way to start is to take that sample template and customize it for your language.

Localizing resulting output

  • Copy the lib/isodoc/i18n-en.yaml file from the isodoc gem to your gem.

  • Edit the right-hand text in the file.

  • Give the file location as the i18nyaml document attribute in any files you wish to use your localization.

Every piece of text generated by the toolset instead of the author is looked up in an internationalization file; that means that if the language setting for the document changes, and there is an internationalization 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.

The localization files are 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 localization text consists of one- or two-word labels, such as "Figure" or "Annex"; some predefined text is also included in the localization text, such as the ISO text describing the use of external sources in Terms and Definitions.

Localization 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-m3aawg gem (/lib/isodoc/m3aawg/base_convert.rb), this label is overruled in code to be "Appendix" instead.

The YAML files are read into the IsoDoc classes through the i18n_init() method of IsoDoc::…​::HtmlConvert and Isodoc::…​::WordConvert. The localization 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.

All current gems inherit their localization files from the base isodoc gem. The local i18n_init() instance can overwrite individual labels in code, or they can read in a local additional YAML file for the same language. 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.

The foregoing describes how to incorporate localization into your gem on a permanent basis; but the toolset also allows you to nominate a YAML localization 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 initialization 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.

In the case of cross-reference labels (clause, table, figure, etc.), the corresponding text is by default entered capitalised, and is assumed to retain capital case throughout. If the text is lowercase, Metanorma will attempt to impose correct capitalisation for instances at the start of blocks and sentences, but it may get it wrong. To override such capitalisation, you can use the the flags capital% or lowercase% as the content of the cross-reference, to force that casing on the cross-reference [added in].

Example internationalization code

  • metanorma-mpfa/lib/isodoc/mpfa/i18n-en.yaml: customization of clause label in YAML

clause: Paragraph
  • metanorma-m3aawg/lib/isodoc/m3aawg/m3dhtmlconvert.rb: customization of annex label as class variable

def i18n_init(lang, script)
  @annex_lbl = "Appendix"
  • metanorma-gb/lib/isodoc/gb/gbhtmlconvert.rb: code to read in internationalization YAML templates (merges superclass @labels map, derived from the parent Isodoc::HtmlConvert class, with the labels read in from the GB-specific YAML templates.)

def i18n_init(lang, script)
  y = if lang == "en"
        YAML.load_file(File.join(File.dirname(__FILE__), "i18n-en.yaml"))
      elsif lang == "zh" && script == "Hans"
        YAML.load_file(File.join(File.dirname(__FILE__), "i18n-zh-Hans.yaml"))
  @labels = @labels.merge(y)