Creating your own Metanorma flavor
How do I adapt Metanorma for my own publications?
.Summary The easiest way to adopt StanDoc is to use the metanorma-generic gem, supplying your own stylesheets and HTML files for styling, which is described on this page. {blank}[Renamed from metanorma-acme as of https://github.com/metanorma/metanorma-generic/releases/tag/v1.4.5]
This gem can work with YAML file where you can customize the behaviour of the flavour without needing to write any code. It will only deal with fairly simple standards flavours.
General
Metanorma Generic is a base implementation that facilitates easy creation of your own Metanorma flavor without programming.
Specifically, Metanorma Generic allows you to specify configuration options to customize presentation attributes without needing to create a packaged Ruby Gem.
Customizations of the document workflow, however, will require programming. In this case, Metanorma Generic provides a solid base for building your very own Metanorma flavour in a Ruby Gem.
Customization via YAML
A simple Metanorma flavour can be created using Metanorma Generic's ability to use a metanorma-config.yml config file.
Place a metanorma-config.yml file in the same directory as your Metanorma AsciiDoc file, and populate it with any necessary attributes.
The following shows the default values that you can override, when necessary.
---
metanorma_name: generic
organization_name_short: Acme
organization_name_long: Acme Corp.
document_namespace: link:/standards/generic
xml_root_tag: 'generic-standard'
logo_path: lib/isodoc/generic/html/logo.jpg
logo_paths: []
validate_rng_file: lib/metanorma/generic/generic.rng
formats:
- html
- doc
- pdf
htmlcoverpage: lib/isodoc/generic/html/html_generic_titlepage.html
htmlintropage: lib/isodoc/generic/html/html_generic_intro.html
htmlstylesheet: lib/isodoc/generic/html/htmlstyle.css
scripts: lib/isodoc/generic/html/scripts.html
standardstylesheet: lib/isodoc/generic/html/generic.css
header: lib/isodoc/generic/html/header.html
wordcoverpage: lib/isodoc/generic/html/word_generic_titlepage.html
wordintropage: lib/isodoc/generic/html/word_generic_intro.html
wordstylesheet: lib/isodoc/generic/html/wordstyle.css
i18nyaml: lib/isodoc/generic/html/i18n-en.yml
boilerplate: lib/metanorma/generic/boilerplate.xml
docid_template: "{{ organization_name_short }} {{ docnumeric }}"
published_stages: ["published", "withdrawn"]
committees: []
committees: [committee]
relations: []
default_stage: "published"
metadata_extensions: []
stage_abbreviations: (initials of stage)
doctypes: []
default_doctype: "standard"
html_bodyfont: "Overpass",sans-serif
html_headerfont: "Overpass",sans-serif
html_monospacefont: "Space Mono",monospace
html_normalfontsize: "1.0em"
html_monospacefontsize: "0.8em"
html_smallerfontsize: "0.9em"
html_footnotefontsize: "0.8em"
word_bodyfont: "Arial",sans-serif
word_headerfont: "Arial",sans-serif
word_monospacefont: "Courier New",monospace
word_normalfontsize: "12.0pt"
word_monospacefontsize: "11.0pt"
word_smallerfontsize: "10.0pt"
word_footnotefontsize: "9.0pt"
termsdefs_titles:
- Terms and definitions
- Terms, definitions, symbols and abbreviated terms
- Terms, definitions, symbols and abbreviations
- Terms, definitions and symbols
- Terms, definitions and abbreviations
- Terms, definitions and abbreviated terms
symbols_titles:
- Symbols and abbreviated terms
- Symbols
- Abbreviated terms
- Abbreviations
normative_references_titles:
- Normative references
bibliography_titles:
- Bibliography
webfont:
- https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,300i,600,600i&display=swap
- https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,300;0,600;1,300;1,600&display=swap
fonts_manifest:
Source Sans Pro: ["Regular", "Light"]
Source Serif Pro:Key:
metanorma_name- Short name of the Metanorma flavour, for use in invoking the gem as software metanorma-generic ≥ v1.4.8. For example,
metanorma -t {short name} document.adocor:mn-document-class: {short name}. organizationnameshort,organizationnamelong- Name of your organization
document_namespace- attribute for creating Metanorma Standoc XML, will be used for as namespace name for XML tags generated
xmlroottag- attribute for creating Metanorma Standoc XML, will be used as tag name for root tag
logo_path- path to a single logo file, used for metanorma metadata. As with all file locations in the configuration, these are relative paths from the gem root
logo_paths- list of paths of multiple logo files, used for metanorma metadata, and treated as an array (e.g.
{{ logo_paths[0] }}) metanorma-generic ≥ v1.4.8. For example,- lib/isodoc/generic/html/logo1.jpg - lib/isodoc/generic/html/logo2.jpg - lib/isodoc/generic/html/logo3.jpg validaterngfile- validation file with rules used in your flavour, see `generic.rng` for example. This and all other file directory paths are relative to the gem root.
htmlcoverpage,htmlintropage,htmlstylesheet,scripts- paths used for styling HTML output files. Accepts a path to a CSS (
.css) or SASS/SCSS (.sass,.scss) file.Examples available at the `metanorma-generic` gemSee examples at the `metanorma-generic` gem.
NoteIn order to use SASS/SCSS stylesheets (
.sass,.scss), which can include variables likehtml_bodyfontandhtml_headerfont, require thesasscgem to compile such files into normal CSS (.css). You will need to add the line `gem "sassc“ to yourGemfileto achieve this.Alternatively, you can provide a pure CSS (
.css) stylesheet by resolving all variables inside a SASS/SCSS stylesheet. e.g. resolve all the$variables by filling in CSS-compliant values. wordcoverpage,wordintropage,wordstylesheet,header- paths used for styling word output files.Examples available at the `metanorma-generic` gem
See examples at the `metanorma-generic` gem.
docid_template- template to generate a document identifier, using Liquid template language, and metadata values (see Default metadata values); the config file values can also be used in the Liquid template metanorma-generic ≥ v1.4.1. In addition, values from the
bibdatametadata of the document are available directly to Liquid, via thebibdataobject; e.g.{{ bibdata.ext.doctype.type }}is the doctype of the document metanorma-generic ≥ v3.0.5. i18nyaml- YAML file to be used for internationalization and labels metanorma-generic ≥ v1.6.3.
The configuration may instead be a hash of language abbreviations to files metanorma-generic ≥ v1.6.4.
Setting `i18nyaml` to point to language filesen: yaml-en.yml fr: yaml-fr.yml boilerplate- Predefined text file for inclusion in Metanorma XML metanorma-generic ≥ v1.6.4. The configuration may be a single file, or a hash of language abbreviations to files, as with
i18nyaml. For the format of boilerplate files, see Predefined text. published_stages- list of stages considered published
committee_types- list of possible hierarchical level of committees metanorma-generic ≥ v3.1.3. Assumes a single hierarchy. Note that the values here need to match the corresponding document attributes; e.g. a value of
workgroupwill correspond to the document attributes:workgroup:,:workgroup-number:,:workgroup-type:,:workgroup_2:,:workgroup-number_2:,:workgroup-type_2:, etc. committees- list of legal committee values metanorma-generic ≥ v1.6.4. Assumes one level of committee.
relations- list of recognised relations to other documents, expressed through document attributes metanorma-generic ≥ v1.6.4
stage_abbreviations- hash of stages and their corresponding abbreviations. If not supplied, the initials of the stage are used, as is the default for Metanorma. This structure is used to configure stages.
doctypes- array or hash of legal document types metanorma-generic ≥ v1.4.8. If it is an array, only the document types are given; if it is a hash metanorma-generic ≥ v1.7.3, the document types are mapped to abbreviations.Defining doctypes in an array
doctypes: - standard - guideDefining doctypes in a hashdoctypes: standard: guide: G default_doctype- default doctype metanorma-generic ≥ v1.4.8. If not supplied, the first element of
doctypes is used; if that is not supplied either,standardis used. formats- output formats supported metanorma-generic ≥ v2.7.1, specified as an array. If not supplied, the default is
["html", "doc"]. Every format specified needs to be supported with stylesheets and font settings appropriate for the format, as specified below. html_bodyfont- The default font to use in HTML output for body text metanorma-generic ≥ v1.4.4.
html_headerfont- The default font to use in HTML output for headers metanorma-generic ≥ v1.4.4.
html_monospacefont- The default font to use in HTML output for monospace text metanorma-generic ≥ v1.4.4.
html_normalfontsize- The font size to use in HTML output for body text metanorma-generic ≥ v1.8.0.
html_monospacefontsize- The font size to use in HTML output for monospace text metanorma-generic ≥ v1.8.0.
html_smallerfontsize- The font size to use in HTML output for smaller than body text metanorma-generic ≥ v1.8.0.
html_footnotefontsize- The font size to use in HTML output for footnotes metanorma-generic ≥ v1.8.0.
word_bodyfont- The default font to use in DOC output for body text metanorma-generic ≥ v1.4.4.
word_headerfont- The default font to use in DOC output for headers metanorma-generic ≥ v1.4.4.
word_monospacefont- The default font to use in DOC output for monospace text metanorma-generic ≥ v1.4.4.
word_normalfontsize- The font size to use in DOC output for body text metanorma-generic ≥ v1.8.0.
word_monospacefontsize- The font size to use in DOC output for monospace text metanorma-generic ≥ v1.8.0.
word_smallerfontsize- The font size to use in DOC output for smaller than body text metanorma-generic ≥ v1.8.0.
word_footnotefontsize- The font size to use in DOC output for footnotes metanorma-generic ≥ v1.8.0.
metadata_extensions- A set of fields to be added to
bibdata/extfor the document, as metadata. These can be entered in one of two formats:
- A list of single-value fields to add to
bibdata/extfor the document, as metadata; they will be populated through document attributes with the same name metanorma-generic ≥ v1.4.7.Example of metadata extensionsmetadata_extensions: - security - comment-period- A nested list of fields, representing the target XML structure metanorma-generic ≥ v1.7.1. Each field corresponds to the corresponding document attribute. CSV-delimited values can be indicated with the special key
_list: true; fields to be treated as attributes, with_attribute: true. If the field is to have a different name in the XML structure, that name is given with the special key_output. For example:metadata_extensions: comment-period: comment-period-type: _output: type _attribute: true comment-period-from: _output: from _list: true comment-period-to: _output: to reply-to: security:given the Metanorma AsciiDoc document attributes:
:comment-period-from: A,B,C :comment-period-to: D :comment-period-type: E :reply-to: F :security: Xwill generate the metadata extensions:
<ext> <comment-period type="E"> <from>A</from> <from>B</from> <from>C</from> <to>D</to> <reply-to>F</reply-to> </comment-period> <security>X</security> </ext> - The Liquid metadata template exports
/bibdata/extas a Ruby object undermetadata_extensionsmetanorma-generic ≥ v1.7.1, in order to preserve its structure; so the foregoing example maps to::metadata_extensions=>{ "comment-period_type"=>"E", "comment-period"=>{ "from"=>["A", "B", "C"], "to"=>"D", "reply-to"=>"F" }, "security"=>"X"}
- A nested list of fields, representing the target XML structure metanorma-generic ≥ v1.7.1. Each field corresponds to the corresponding document attribute. CSV-delimited values can be indicated with the special key
webfont- A list of URLs of web fonts, to be loaded into HTML output metanorma-generic ≥ v1.4.8.Setting webfonts
- https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,300i,600,600i&display=swap - https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,300;0,600;1,300;1,600&display=swap termsdefs_titles- Titles which will be automatically recognised as introducing Terms sections metanorma-generic ≥ v1.4.8.
symbols_titles- Titles which will be automatically recognised as introducing Symbols/Abbreviations sections metanorma-generic ≥ v1.4.8.
normref_titles- Titles which will be automatically recognised as introducing Normative References sections metanorma-generic ≥ v1.4.8.
bibliography_titles- Titles which will be automatically recognised as introducing Bibliography sections metanorma-generic ≥ v1.4.8.
fonts_manifest- A listing of the fonts to be used. This list of fonts is to be installed via Fontist metanorma-generic ≥ v2.7.0.
The listing takes the form of a Fontist Manifest: a font name that Fontist recognises, mapped to
nilor to an array of required font styles.
A document may specify its own metanorma-config.yml instance, to override that of the gem configuration. This is done using a :customize: document attribute. metanorma-generic ≥ v1.4.2
= Title
:customize: config/my_metanorma.ymlCustomization via Ruby Gem
General
Metanorma Generic also supports configuration via Ruby code. By following the steps below you can create your own Ruby Gem for your Metanorma flavour.
Step 1: Create an empty Gem
Initialize an empty Ruby Gem:
bundle initThen add metanorma-generic as a dependency in your {gem-name}.gemspec file.
{gem-name} is typically metanorma-{your-flavor-name}.
For Metanorma Ribose, the gem name is metanorma-ribose.
Step 2: Create your Metanorma configuration in Ruby
In this step you will create:
lib/metanorma-{your-flavor-name}.rb
lib/metanorma-{your-flavor-name}.rb is the entry point for your gem.
For example, this is lib/metanorma-ribose.rb:
Metanorma::Generic.configure do |config|
config.organization_name_long = 'Ribose Inc.'
config.organization_name_short = 'Ribose'
config.document_namespace = 'https://open.ribose.com/standards/ribose'
isodoc_rsd_html_folder = File.join(
File.expand_path('isodoc', __dir__), 'ribose', 'html'
)
config.wordstylesheet = File.join(
isodoc_rsd_html_folder, 'wordstyle.css'
)
config.standardstylesheet = File.join(isodoc_rsd_html_folder, 'ribose.css')
config.header = File.join(isodoc_rsd_html_folder, 'header.html')
config.wordcoverpage = File.join(
isodoc_rsd_html_folder, 'word_rsd_titlepage.html'
)
config.wordintropage = File.join(isodoc_rsd_html_folder,
'word_rsd_intro.html')
config.htmlstylesheet = File.join(isodoc_rsd_html_folder,
'htmlstyle.css')
config.htmlcoverpage = File.join(isodoc_rsd_html_folder,
'html_rsd_titlepage.html')
config.htmlintropage = File.join(isodoc_rsd_html_folder,
'html_rsd_intro.html')
config.scripts = File.join(isodoc_rsd_html_folder, 'scripts.html')
config.logo_path = File.join(isodoc_rsd_html_folder, 'logo.png')
config.xml_root_tag = 'ribose-standard'
rsd_rng_folder = File.join(File.expand_path('metanorma', __dir__), 'ribose')
config.validate_rng_file = File.join(rsd_rng_folder, 'ribose.rng')
end
require 'metanorma/ribose'
require 'isodoc/generic'In this configuration, you have to provide paths to your style definitions:
- Word Doc: using
config.word* - HTML: using
config.html*
Please refer to yaml-config for a detailed explanation for each configuration option.
Step 3: Define your flavor in the Metanorma framework
In this step you will create these folders:
lib/metanorma/{your-flavor-name}/lib/isodoc/{your-flavor-name}/
And these files:
lib/metanorma/{your-flavor-name}.rblib/metanorma/{your-flavor-name}/processor.rblib/metanorma/{your-flavor-name}/version.rblib/metanorma/{your-flavor-name}/converter.rblib/isodoc/{your-flavor-name}.rblib/isodoc/{your-flavor-name}/metadata.rblib/isodoc/{your-flavor-name}/{converter-type}.rb(one converter per output format)
For example, in metanorma-ribose, you would have these files:
lib/metanorma/ribose.rblib/metanorma/ribose/processor.rblib/metanorma/ribose/version.rblib/metanorma/ribose/converter.rblib/isodoc/ribose.rblib/isodoc/ribose/metadata.rblib/isodoc/ribose/html_converter.rblib/isodoc/ribose/word_converter.rb
The first file lib/metanorma/{your-flavor-name}.rb defines your module, and links your flavor's processor to the Metanorma processor framework, and also your input converters.
require "metanorma"
require "metanorma/ribose/processor"
require "metanorma/ribose/converter"
module Metanorma
module Rsd
end
end
# This line registers your Metanorma Processor to the Metanorma Registry
Metanorma::Registry.instance.register(Metanorma::Rsd::Processor)lib/isodoc/{your-flavor-name}/metadata.rb links your configuration to IsoDoc by inheriting the IsoDoc::Generic::Metadata class:
require "isodoc"
module IsoDoc
module Rsd
class Metadata < IsoDoc::Generic::Metadata
def configuration
Metanorma::Rsd.configuration
end
end
end
endInherit IsoDoc::Generic convertors depending on the types of outputs your flavour wishes to support, using the previously created Metadata file.
The following code from lib/isodoc/ribose/html_convert.rb shows an example where the HTML convertor is inherited to provide HTML output for Ribose, and to read in IsoDoc::Generic::Metadata.
require "isodoc"
require "isodoc/generic/html_convert"
require "isodoc/ribose/metadata"
module IsoDoc
module Rsd
class HtmlConvert < IsoDoc::Generic::HtmlConvert
def configuration
Metanorma::Rsd.configuration
end
def metadata_init(lang, script, labels)
@meta = Metadata.new(lang, script, labels)
end
end
end
endlib/metanorma/{your-flavor-name}/processor.rb defines your flavor's Processor by inheriting from Metanorma::Processor. This is the entry point for content processing.
require "metanorma/processor"
module Metanorma
module Rsd
class Processor < Metanorma::Processor
def initialize
@short = :ribose
@input_format = :asciidoc
@asciidoctor_backend = :ribose
end
def output_formats
super.merge(
html: "html",
doc: "doc",
pdf: "pdf"
)
end
def version
"Metanorma::Rsd #{Metanorma::Rsd::VERSION}"
end
def input_to_isodoc(file, filename)
Metanorma::Input::Asciidoc.new.process(file, filename, @asciidoctor_backend)
end
def output(isodoc_node, outname, format, options={})
case format
when :html
IsoDoc::Rsd::HtmlConvert.new(options).convert(outname, isodoc_node)
when :doc
IsoDoc::Rsd::WordConvert.new(options).convert(outname, isodoc_node)
when :pdf
IsoDoc::Rsd::PdfConvert.new(options).convert(outname, isodoc_node)
else
super
end
end
end
end
endCreate the version file indicating your flavor's gem version at lib/metanorma/{your-flavor-name}/version.rb
require "metanorma/ribose"
module Metanorma
module Rsd
VERSION = "0.0.1".freeze
end
endlib/metanorma/{your-flavor-name}/converter.rb registers your new flavour to be used in Metanorma::Cli.
require "metanorma/standoc/converter"
require 'metanorma/generic/converter'
module Metanorma
module Rsd
# A {Converter} implementation that generates Ribose output, and a document
# schema encapsulation of the document for validation
#
class Converter < Metanorma::Generic::Converter
register_for "ribose"
end
end
end