0.0
The project is in a healthy, maintained state
metanorma-jis lets you write JIS standards in AsciiDoc syntax. This gem is in active development.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

Runtime

 Project Readme

metanorma-JIS: Metanorma processor for Japanese Industrial Standards

Gem Version Build Status Pull Requests Commits since latest

Functionality

This gem processes Metanorma documents following the Metanorma model for generating JIS standards.

The gem is a thin flavor on top of the https://github.com/metanorma/metanorma-iso gem. It adds JIS-specific presentation semantics: the JIS XML namespace, the JIS document model, and DOCX output that faithfully reproduces the JDT2023 template distribution.

The following outputs are supported:

  • .xml — canonical Metanorma-JIS XML representation (root tag jis-standard)

  • .html — HTML rendering

  • .docx — native Word DOCX produced via Uniword from data/jis/template.docx

  • .pdf — PDF rendering

The legacy .doc (MHTML) output has been removed. Use .docx instead.

Required fonts

JIS documents use Japanese-specific fonts. The DOCX output declares:

  • MS Mincho, MS Gothic (Windows; the template’s native fonts)

  • IPAexMincho, IPAexGothic (cross-platform open-source equivalents)

Authors on macOS/Linux should install the IPAex family for accurate rendering.

Architecture

The gem has three layers, each with a single responsibility. The layers communicate via typed interfaces — no layer reaches into another’s internals.

Layer 1 — AsciiDoc → JIS presentation XML

Metanorma::Jis::Converter (a subclass of Metanorma::Iso::Converter) parses the AsciiDoc input and produces a JIS presentation XML tree. The XML uses the JIS namespace (https://www.metanorma.org/ns/jis) and the JIS root tag (jis-standard).

Layer 2 — JIS presentation XML → typed model

Metanorma::Jis::Document::Root.from_xml parses the presentation XML into a typed lutaml-model model. The model is the single source of truth for the DOCX Adapter.

presentation XML
    ↓ Root.from_xml (lutaml-model)
typed model
    (Bibdata → Cover, Preface → JisClauseSection,
     Sections → JisSections → JisClauseSection[] → ...)

Layer 3 — Typed model → DOCX (via Uniword)

IsoDoc::Jis::Docx::Adapter is the only entry point for DOCX output. It composes Uniword’s typed OOXML model:

typed model
    ↓ Adapter#convert(xml, path)
Uniword.load(template.docx) → clear body
    ↓ CoverRenderer.render (cover from Bibdata model)
    ↓ BodyRenderer.render (walk JisSections → clauses → paragraphs)
        InlineRenderer.render (walk each_mixed_content → RunBuilder)
    ↓ Uniword::DocumentWriter.save(path)
template.docx + body content → valid .docx

The DOCX Adapter is intentionally narrow: it does not parse the presentation XML, does not access Nokogiri, and does not hand-roll OOXML strings. It consumes the typed model and emits Uniword builders (ParagraphBuilder, RunBuilder, TableBuilder, TableRowBuilder, TableCellBuilder). Uniword::DocumentWriter does the final packaging (ZIP, content types, relationships).

File structure

lib/metanorma-jis.rb                            # gem entry: requires namespaces only
lib/metanorma/jis.rb                           # Metanorma::Jis autoloads
lib/isodoc/jis.rb                              # IsoDoc::Jis autoloads
lib/relaton/render-jis.rb                      # Relaton::Render::Jis autoloads

lib/metanorma/jis/converter.rb                 # Converter (Layer 1)
lib/metanorma/jis/cleanup.rb                   # cleanup hooks
lib/metanorma/jis/validate.rb                  # validation
lib/metanorma/jis/processor.rb                 # Processor: route :docx to Adapter
lib/metanorma/jis/front.rb                     # Front module (mixed into Converter)
lib/metanorma/jis/log.rb                       # Log module (mixed into Converter)

lib/metanorma/jis/document/                    # typed model (Layer 2)
  root.rb                                      # Document::Root
  cover.rb                                     # Document::Cover
  namespace.rb                                 # JIS XML namespace
  sections.rb                                  # Document::Sections namespace
  sections/jis_sections.rb                     # <sections> container
  sections/jis_clause_section.rb
  sections/jis_annex_section.rb
  sections/jis_commentary_section.rb
  sections/jis_index_section.rb
  terms.rb                                     # Document::Terms namespace
  terms/jis_term.rb

lib/isodoc/jis/docx/                           # DOCX Adapter (Layer 3)
  adapter.rb                                   # Adapter: the only entry point
  body_renderer.rb                             # walk clauses → Uniword builders
  cover_renderer.rb                            # cover from Bibdata model
  inline_renderer.rb                           # bold/italic/sub/sup/links
  style_mapping.rb                             # template path + style mapping
  style_resolver.rb                            # strict styleId lookup
  errors.rb                                    # typed errors

data/jis/                                      # runtime assets
  template.docx                                # 41 KB, 635 styles, 6 headers, 6 footers
  style_mapping.yml                            # semantic key → styleId
  doctype_overrides.yml                        # doctype → section routing
  document_properties.yml                      # docProps metadata

Design properties

  • Open/Closed: adding a new block type = adding a case to BodyRenderer.render_block_children and (optionally) a new inline element type to InlineRenderer.render_mixed. No edit to dispatch logic.

  • MECE: each renderer handles one concern (cover, body, inline). No renderer reaches into another renderer’s state.

  • Model-driven, semantically-driven: every render decision comes from the typed model. The DOCX is a projection of the model, not a transformation of XML strings.

  • No Nokogiri in lib/isodoc/jis/docx/: the Adapter takes the typed model in, emits Uniword builders out. XML parsing is upstream (Root.from_xml) and never leaks into the write path.

  • No hand-rolled OOXML: every <w:p>, <w:r>, <w:t> is constructed via Uniword’s typed builder classes. The Adapter never concatenates OOXML strings.

  • No "Writer" class: metanorma-iso’s pattern has one entry point (the Adapter) with Renderers::Registry fan-out. JIS is small enough that a registry is overkill — the Adapter delegates directly to renderers via class-keyed dispatch.

  • Strict style resolution: StyleResolver#paragraph_style raises UnknownStyleError on miss. Mapping lapses surface immediately.

  • No require_relative: every internal load is via autoload declared in the immediate parent namespace’s file.

  • No send on private methods, no instance_variable_set/get, no respond_to?: type-safe access via the lutaml-model typed attributes and each_mixed_content.

Template source

data/jis/template.docx is built from the JDT2023 distribution (reference-docs/JDT2023/レイアウト/JDT_本文.dotx). Uniword parses the source DOCX, the build script clears the body, and Uniword writes the result. The template carries 635 paragraph
character styles, 3 headers, and 3 footers — everything needed for JIS layout except the body content, which is produced per-document from the typed model.

Quickstart

$ gem install metanorma-jis
$ metanorma --type jis a.adoc             # HTML by default
$ metanorma --type jis --extensions docx a.adoc   # DOCX (JDT2023 template)
$ metanorma --type jis --extensions xml a.adoc    # Metanorma-JIS XML

Authoring

Refer to the Metanorma-ISO documentation for general authoring guidance. JIS-specific authoring rules (the JIS document model, equivalence markers IDT/MOD/NEQ, committee metadata) are documented inline in the model classes (lib/metanorma/jis/document/).