0.0
The project is in a healthy, maintained state
Library to process and handle default Metanorma Tastes, providing configuration-driven customization of Metanorma flavours.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Project Readme

Metanorma Taste: lightweight customizable Metanorma flavours

Gem Version Build Status Pull Requests Commits since latest

Metanorma Taste

Overview

A Metanorma Taste is a lightweight, configuration-only customization of an existing Metanorma flavor.

Unlike a full Metanorma flavor, a taste does not define its own document structure, validation rules, or processing logic. Instead, it provides organizational branding and content customization on top of a base flavor.

Think of it as "taste" being one aspect of "flavor" in real life — a taste modifies the presentation and branding without changing the fundamental characteristics of the underlying flavor.

Features

Configuration-Only

Tastes are defined purely through YAML configuration files and content assets (copyright notices, i18n dictionaries, stylesheets). No code is required.

Base flavor dependency

Every taste must specify a base-flavor (e.g., iso, ietf, ieee) that provides the document structure and validation logic.

Lightweight customization

Tastes can override document attributes, provide custom copyright notices, modify presentation styling, and add internationalization content.

Limitations

Since tastes are configuration-only overlays on existing flavors, they have important limitations.

Document structure constraints

A taste cannot define document structures not allowed by the underlying base flavor. For example, an ISO-based taste cannot add document types that ISO doesn’t support.

Validation inheritance

All document validation rules from the base flavor apply unchanged. This includes:

  • ISO/IEC warnings on terms and definitions requirements

  • Provision requirements and numbering rules

  • Document structure validation

  • Metadata requirements

Processing logic

Tastes cannot modify the core document processing, rendering, or output generation logic of the base flavor.

Customization scope

Tastes can only customize from document attributes or presentation attributes supported by the base flavor.

Installation

The gem is distributed within Metanorma.

Usage

Compiling documents

If a taste abbreviation is used instead of a flavor in compiling a Metanorma document, e.g. as the document attribute :flavor: icc or :mn-document-class: icc, this gem is used to process that document as an instance of its base flavor, and will substitute the necessary configuration files and document attributes required to get the document to render as expected.

Basic usage

require "metanorma-taste"

# Get a registered taste (returns Metanorma::Taste::Icc instance)
taste = Metanorma::TasteRegister.get(:icc)
# => Metanorma::Taste::Icc

# Process document attributes and options
taste.process_input_adoc_overrides(attributes, options)

Listing tastes

# List all available tastes
Metanorma::TasteRegister.available_tastes
# => [:icc, :elf, :enosema]

# Get information about a specific taste
config = Metanorma::TasteRegister.get_config(:icc)
# => #<Metanorma::Taste::TasteConfig:...>
puts config.owner
# => "International Color Consortium"
puts config.base_flavor
# => "iso"

# Get flavor aliases (mapping to base flavours)
Metanorma::TasteRegister.aliases
# => { icc: :iso, elf: :iso, enosema: :iso }

# Demonstrate dynamic class creation
taste = Metanorma::TasteRegister.get(:icc)
puts taste.class.to_s
# => "Metanorma::Taste::Icc"

Official tastes

General

Official tastes are maintained by the Metanorma team and provide standardized customizations for specific organizations or purposes. They are designed to be used with the Metanorma framework and provide consistent branding and presentation across documents.

Adding official tastes

Official tastes are maintained and version tested by the Metanorma team and are not user-configurable.

Official tastes are only available to organizations that have an existing relationship with Metanorma. To request a new official taste, please open an issue on the Metanorma GitHub repository.

Official tastes are located at the data/ directory of the metanorma-taste gem.

Each official taste has its own directory with the taste package structure.

See Creating a taste for instructions on how to create a taste.

Available taste codes

All taste short codes must be unique among tastes. The following tastes are currently available:

Code Organization Base Flavor Description

icc

International Color Consortium

iso

International Color Consortium specifications and standards with ICC branding and copyright

elf

Express Language Foundation

iso

Express Language Foundation specifications and standards with ELF branding and copyright

enosema

Enosema Foundation

iso

Enosema specifications and standards with Enosema branding and copyright

csa

Cloud Security Alliance

generic

Cloud Security Alliance specifications and standards with CSA branding and copyright

pdfa

PDF Association

ribose

PDF Association specifications and standards with PDFA branding and copyright

swf

Spatial Web Foundation

ribose

Spatial Web Foundation specifications and standards with SWF branding and copyright

mbxif

MBx Interoperability Forum

ribose

MBx Interoperability Forum specifications and standards with MBx-IF branding and copyright

Community tastes

General

Community tastes are user-defined Metanorma tastes. They are not maintained by the Metanorma team, but are available for use by your own community.

Adding community tastes

Warning
This is to be implemented in a future release.

Community tastes can be hosted on GitHub repositories or distributed as zip files.

See Creating a taste for instructions on how to create a taste.

Taste package

General

A taste package is a directory structure that contains all the necessary files to define a Metanorma taste.

It includes configuration files, copyright notices, internationalization dictionaries, and stylesheets if any.

Directory structure

Tastes are configured using a directory-based structure under data/:

data/
└── {taste-code}/
    ├── config.yaml
    ├── copyright.adoc (optional)
    └── i18n.yaml (optional)

Configuration schema

config.yaml

The main configuration file for each taste:

flavor: string             # The name of the custom flavor (e.g., "icc")
owner: string              # Organization name (e.g., "International Color Consortium")
base-flavor: string        # Base Metanorma flavor to extend (e.g., "iso")
base-override:             # Document attributes to override from base flavor
  filename-attributes:     # Metanorma document attributes that contain filenames
    copyright-notice: string   # Path to boilerplate file (e.g., "copyright.adoc")
    i18n-dictionary: string    # Path to internationalization dictionary (e.g., "i18n.yaml")
    publisher-logo: string     # Path to publisher logo (e.g., "icc.png")
    htmlcoverpage: string      # HTML output cover page
    htmlintropage: string      # HTML output introductory page
    htmlstylesheet: string     # HTML output CSS stylesheet
    htmlstylesheet-override: string     # HTML output CSS stylesheet, overriding base flavor stylesheet
    wordcoverpage: string      # Word output cover page
    wordintropage: string      # Word output introductory page
    wordstylesheet: string     # Word output CSS stylesheet
    wordstylesheet-override: string     # Word output CSS stylesheet, overriding base flavor stylesheet
    standardstylesheet: string # Word output secondary CSS stylesheet
    standardstylesheet-override: string # Word output secondary CSS stylesheet, overriding base flavor stylesheet
    header: string             # Word output header and footer content
    pdf-stylesheet: string     # PDF output XSLT stylesheet
    pdf-stylesheet-override: string     # PDF output XSLT stylesheet, overriding base flavor stylesheet
    customize: string          # Path to custom metanorma configuration file
    coverpage-image: string    # Path to coverpage image file
    backpage-image: string     # Path to backpage image file
  value-attributes:        # Metanorma document attributes that contain values
    publisher: string        # Publisher name override
    publisher_abbr: string   # Publisher abbreviation
    body-font: string        # Default font to use in HTML and Word stylesheets
    header-font: string      # Header font to use in HTML and Word stylesheets
    monospace-font: string   # Monospace font to use in HTML and Word stylesheets
    fonts: string            # Comma-delimited listing of fonts to retrieve for the taste from Fontist
    output-extensions: string         # Comma-delimited listing of output formats to support (subset of base flavor's)
    presentation-metadata-*: # Template style attributes for presentation
doctypes:                  # Array of doctypes built over base flavour doctypes
  - taste:                 # taste-specific machine-readable doctype name
    base:                  # Base Metanorma flavor corresponding machine-readable doctype name
    override-attributes:   # Hash of document attributes to override from base flavor for this doctype
Example 1. Taste configuration example from ICC
flavor: icc
owner: International Color Consortium
base-flavor: iso
base-override:
  filename-attributes:
    copyright-notice: copyright.adoc
    i18n-dictionary: i18n.yaml
    publisher-logo: icc-full.svg
    htmlcoverpage: htmlcoverpage.html
    htmlstylesheet-override: htmlstylesheet-override.scss
  value-attributes:
    publisher: International Color Consortium
    publisher_abbr: ICC
    presentation-metadata-color-secondary: '#376795'
    presentation-metadata-backcover-text: color.org
    body-font: Arial, 'Helvetica Neue', Helvetica, sans-serif
    header-font: Arial, 'Helvetica Neue', Helvetica, sans-serif
    output-extensions: xml,html,pdf,doc
doctypes:
- taste: specification # Specification # The name goes into i18n.yaml
  base: international-standard
  override-attributes:
  - presentation-metadata-color-secondary: '#376795'

i18n.yaml

Internationalization dictionary for custom text translations:

doctype_dict:             # Document type translations
  international-standard: string  # Custom name for document types
  # Add more document type mappings as needed

Every taste-specific doctype is required to have a renderable corresponding entry under doctype_dict.

The same is the case for the native doctypes in the base flavor’s i18n.yaml files.

Example 2. i18n.yaml example from ICC
doctype_dict:
  specification: Specification

This file supplies taste-specific copyright, legal, license and feedback text.

This file can contain:

  • Copyright statements with template variables (e.g., {{ docyear }})

  • License information

  • Legal disclaimers

  • Organization contact information

The file is in the Metanorma AsciiDoc format, with the following syntax:

== copyright-statement
...
Example 3. Copyright notice from ICC
== copyright-statement
=== Copyright notice

Copyright (c) {{ docyear }} Your Organization Name

[legal text here...]

== feedback-statement
=== Contact information

[organization contact details...]

The same file format is used internally for Metanorma flavors, and is documented in Metadata and predefined text.

Base-override configuration

General

The base-override section allows customization of document attributes supported by the base flavor through two categories.

The reason for this division is that some attributes contain file paths relative to the taste definition, while others contain simple values that are not relevant to path resolution.

  • Filename attributes are used to point to custom files provided by the taste, under the data/{taste}/ directory.

    When :publisher-logo: {logo-file-path} is defined in the taste’s config.yaml, the actual logo file is expected to be located at data/{taste}/{logo-file-path}.

    When :publisher-logo: {logo-file-path} is defined as a document attribute in the input document, the logo file is expected to be located relative to the input document’s location at {input-document-directory}/{logo-file-path}.

  • Value attributes are simple values (strings, numbers, lists) that do not involve file paths. These attributes are identical whether defined in the taste’s config.yaml or as document attributes in the input document.

    :publisher_abbr: {abbreviation} is a simple string value and does not involve any file path resolution.

Filename attributes (filename-attributes)

These are Metanorma document attributes that take file paths as values.

copyright-notice

Path to boilerplate file containing copyright, license, and legal notices

i18n-dictionary

Path to internationalization dictionary

publisher-logo

Path to organization logo file

htmlcoverpage, htmlintropage

HTML output page templates

htmlstylesheet, htmlstylesheet-override

HTML CSS stylesheets

wordcoverpage, wordintropage

Word output page templates

wordstylesheet, wordstylesheet-override

Word CSS stylesheets

standardstylesheet, standardstylesheet-override

Secondary Word CSS stylesheets

header

Word output header and footer content

pdf-stylesheet, pdf-stylesheet-override

PDF XSLT stylesheets

customize

Path to custom metanorma configuration file

coverpage-image, backpage-image

Cover and back page image files

Value attributes (value-attributes)

These are Metanorma document attributes that contain path-independent values.

publisher

Organization name

publisher_abbr

Organization abbreviation

body-font, header-font, monospace-font

Typography settings

fonts

Comma-delimited list of fonts to retrieve from Fontist

output-extensions

Comma-delimited list of supported output formats

presentation-metadata-*

Visual styling attributes for presentation, including:

presentation-metadata-color-secondary

Secondary color for styling

presentation-metadata-backcover-text

Text for document back cover

presentation-metadata-ul-label-list

Unordered list label formatting

presentation-metadata-annex-delim

Annex delimiter formatting

presentation-metadata-middle-title

Middle title formatting

presentation-metadata-ol-label-template-alphabet

Ordered list alphabet template

presentation-metadata-ol-label-template-alphabet_upper

Ordered list uppercase alphabet template

presentation-metadata-ol-label-template-roman

Ordered list roman numeral template

presentation-metadata-ol-label-template-roman_upper

Ordered list uppercase roman numeral template

presentation-metadata-ol-label-template-arabic

Ordered list arabic numeral template

Custom organization-specific attributes

These are any additional attributes supported by the base flavor or taste.

The availability of these attributes depends on the base flavor’s supported document attributes and template system.

For example, the ISO flavor supports specific presentation metadata attributes.

Other flavors may have different customization options. Please check the base flavor documentation for available attributes.

Mappings of structures from taste to base flavours

The taste configuration includes various document classifications which need to be mapped between values specific to the taste, and corresponding values in the base flavor.

The document will actually be compiled with the base flavor settings, but it will be rendered using the taste’s corresponding values.

These include:

  • doctype: mapping of taste doctypes to native base flavor doctypes

  • stage: mapping of taste stages to native base flavor stages

Data model

The metanorma-taste system follows this architecture:

+------------------+       +-------------------+
|   TasteRegister  |       |   Taste::Base     |
|   (Singleton)    |       |                   |
| +available_tastes|<>---->| +flavor           |
| +get(flavor)     |       | +config           |
| +get_config()    |       | +directory        |
+--------+---------+       | +process_input_*  |
         |                 +-------------------+
         |
         | scans
+--------v---------+       +-------------------+
|   data/ directory|       |   Dynamic Classes |
|                  |       |                   |
| +{taste}/        |------>| Taste::Icc        |
|   config.yaml    |       | Taste::Elf        |
|   copyright.adoc |       | Taste::Enosema    |
|   i18n.yaml      |       | (auto-generated)  |
+------------------+       +-------------------+

Components

TasteRegister

(Singleton) Manages taste discovery and registration. Scans the data/ directory on initialization and creates a registry of available tastes.

Taste::Base

Base class containing the core logic for processing document attributes and applying taste-specific overrides.

Taste::* dynamic taste classes

Automatically generated classes (e.g., Taste::Icc) that inherit from Taste::Base and are configured with taste-specific data.

Configuration files

YAML and AsciiDoc files that define the behavior and content for each taste.

Workflow

  1. Discovery: On gem load, TasteRegister scans data/ directory for taste configurations

  2. Registration: Each valid taste directory is registered with its configuration

  3. Access: Users call TasteRegister.get(:flavor) to obtain a configured taste instance

  4. Processing: The taste instance applies overrides and customizations to document attributes

  5. Integration: The customized attributes are used by Metanorma for document processing

Creating a taste

Overview

Creating a new Metanorma taste is straightforward and involves defining a configuration directory with the necessary files.

Directory structure

To create a new taste:

  1. Create directory: Add a new directory under data/ with your unique taste code

  2. Add configuration: Create config.yaml with your taste settings

  3. Add content: Optionally add copyright.adoc and i18n.yaml files

  4. Test: The taste will be automatically discovered and available via the TasteRegister

Example for a new acme taste:

data/acme/
├── config.yaml
├── copyright.adoc
└── i18n.yaml

The taste will be accessible as:

taste = Metanorma::TasteRegister.get(:acme)
# Returns an instance of Metanorma::Taste::Acme

Taste code

  • Must be unique among all tastes

  • Should be short and descriptive (typically 2-5 characters)

  • Must be valid Ruby constant names when capitalized

  • Should reflect the owner organization’s name

This gem is developed, maintained and funded by Ribose Inc.

License

The gem is available as open source under the terms of the 2-Clause BSD License.