Implementing the Ruby Module

Personal Note 14 July 2005

This version:
$Id: NOTE-ruby-implementation.html,v 1.219 2005/07/14 11:31:58 mimasa Exp $
Latest version:
http://www.w3.org/People/mimasa/test/schemas/NOTE-ruby-implementation
Previous version:
http://www.w3.org/TR/2001/NOTE-ruby-implementation-20010531
Author:
Masayasu Ishikawa, W3C

Abstract

Ruby Annotation specification [Ruby] defines an abstract definition of ruby annotation markup. This Note describes sample module implementations of this abstract definition in several schemas — DTD, RELAX [RELAX], TREX [TREX], RELAX NG [RELAXNG], Schematron [Schematron], and the XML Schema [XMLSchema]. Familiarity with those schema languages as well as Ruby Annotation and the XHTML Modularization framework [XHTMLMOD] is assumed.

Status of This Document

This document is a Personal Note for your information only. This Note just describes the author's personal experiments. Implementations found in this document are informative only, and may contain errors. This is a draft document and may or may not be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use this Note as reference material or to cite this as other than "personal experiments".

While the author welcomes comments on this document, author does not guarantee a reply or any further action. Comments on this document should be sent to the author.

Table of Contents


1.  Introduction

Ruby Annotation specification [Ruby] defines an abstract definition of ruby annotation markup, and provides a Ruby DTD Module for XHTML which is used in XHTML 1.1 [XHTML11] as a module implementation. But DTD is just an implementation method, and other implementations are also possible.

In this Note, module implementations of the Ruby abstract definition in several schemas are explored — DTD, RELAX [RELAX], TREX [TREX], RELAX NG [RELAXNG], Schematron [Schematron], and the XML Schema [XMLSchema].

2.  Abstract definition of ruby markup

The following is the abstract definition of ruby markup, found in section 2.1 of Ruby Annotation [Ruby]. This abstract definition is consistent with the XHTML Modularization framework [XHTMLMOD]. Further definitions of XHTML abstract modules can be found in Modularization of XHTML [XHTMLMOD].

Elements Attributes Minimal Content Model
ruby Common (rb, (rt | (rp, rt, rp)))
rbc Common rb+
rtc Common rt+
rb Common (PCDATA | Inline - ruby)*
rt Common, rbspan (CDATA) (PCDATA | Inline - ruby)*
rp Common PCDATA*

The maximal content model for the ruby element is as follows:

((rb, (rt | (rp, rt, rp))) | (rbc, rtc, rtc?))

3.  Implementing the Ruby Module in DTD

3.1  Ruby DTD Module

The following is an implementation of the Ruby Module in DTD, found in Appendix A of Ruby Annotation [Ruby]. This module is designed to be a conforming full ruby module implementation.

<!-- ...................................................................... -->
<!-- XHTML Ruby Module .................................................... -->
<!-- file: xhtml-ruby-1.mod

     This is XHTML, a reformulation of HTML as a modular XML application.
     Copyright 1999-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
     Revision: $Id: xhtml-ruby-1.mod,v 4.0 2001/04/03 23:14:33 altheim Exp $

     This module is based on the W3C Ruby Annotation Specification:

        http://www.w3.org/TR/ruby

     This DTD module is identified by the PUBLIC and SYSTEM identifiers:

       PUBLIC "-//W3C//ELEMENTS XHTML Ruby 1.0//EN"
       SYSTEM "http://www.w3.org/TR/ruby/xhtml-ruby-1.mod"

     ...................................................................... -->

<!-- Ruby Elements

        ruby, rbc, rtc, rb, rt, rp

     This module declares the elements and their attributes used to
     support ruby annotation markup.
-->

<!-- declare qualified element type names:
-->
<!ENTITY % ruby.qname  "ruby" >
<!ENTITY % rbc.qname  "rbc" >
<!ENTITY % rtc.qname  "rtc" >
<!ENTITY % rb.qname  "rb" >
<!ENTITY % rt.qname  "rt" >
<!ENTITY % rp.qname  "rp" >

<!-- rp fallback is included by default.
-->
<!ENTITY % Ruby.fallback "INCLUDE" >
<!ENTITY % Ruby.fallback.mandatory "IGNORE" >

<!-- Complex ruby is included by default; it may be 
     overridden by other modules to ignore it.
-->
<!ENTITY % Ruby.complex "INCLUDE" >

<!-- Fragments for the content model of the ruby element -->
<![%Ruby.fallback;[
<![%Ruby.fallback.mandatory;[
<!ENTITY % Ruby.content.simple 
     "( %rb.qname;, %rp.qname;, %rt.qname;, %rp.qname; )"
>
]]>
<!ENTITY % Ruby.content.simple 
     "( %rb.qname;, ( %rt.qname; | ( %rp.qname;, %rt.qname;, %rp.qname; ) ) )"
>
]]>
<!ENTITY % Ruby.content.simple "( %rb.qname;, %rt.qname; )" >

<![%Ruby.complex;[
<!ENTITY % Ruby.content.complex 
     "| ( %rbc.qname;, %rtc.qname;, %rtc.qname;? )"
>
]]>
<!ENTITY % Ruby.content.complex "" >

<!-- Content models of the rb and the rt elements are intended to
     allow other inline-level elements of its parent markup language,
     but it should not include ruby descendent elements. The following
     parameter entity %NoRuby.content; can be used to redefine
     those content models with minimum effort.  It's defined as
     '( #PCDATA )' by default.
-->
<!ENTITY % NoRuby.content "( #PCDATA )" >

<!-- one or more digits (NUMBER) -->
<!ENTITY % Number.datatype "CDATA" >

<!-- ruby element ...................................... -->

<!ENTITY % ruby.element  "INCLUDE" >
<![%ruby.element;[
<!ENTITY % ruby.content
     "( %Ruby.content.simple; %Ruby.content.complex; )"
>
<!ELEMENT %ruby.qname;  %ruby.content; >
<!-- end of ruby.element -->]]>

<![%Ruby.complex;[
<!-- rbc (ruby base component) element ................. -->

<!ENTITY % rbc.element  "INCLUDE" >
<![%rbc.element;[
<!ENTITY % rbc.content
     "(%rb.qname;)+"
>
<!ELEMENT %rbc.qname;  %rbc.content; >
<!-- end of rbc.element -->]]>

<!-- rtc (ruby text component) element ................. -->

<!ENTITY % rtc.element  "INCLUDE" >
<![%rtc.element;[
<!ENTITY % rtc.content
     "(%rt.qname;)+"
>
<!ELEMENT %rtc.qname;  %rtc.content; >
<!-- end of rtc.element -->]]>
]]>

<!-- rb (ruby base) element ............................ -->

<!ENTITY % rb.element  "INCLUDE" >
<![%rb.element;[
<!-- %rb.content; uses %NoRuby.content; as its content model,
     which is '( #PCDATA )' by default. It may be overridden
     by other modules to allow other inline-level elements
     of its parent markup language, but it should not include
     ruby descendent elements.
-->
<!ENTITY % rb.content "%NoRuby.content;" >
<!ELEMENT %rb.qname;  %rb.content; >
<!-- end of rb.element -->]]>

<!-- rt (ruby text) element ............................ -->

<!ENTITY % rt.element  "INCLUDE" >
<![%rt.element;[
<!-- %rt.content; uses %NoRuby.content; as its content model,
     which is '( #PCDATA )' by default. It may be overridden
     by other modules to allow other inline-level elements
     of its parent markup language, but it should not include
     ruby descendent elements.
-->
<!ENTITY % rt.content "%NoRuby.content;" >

<!ELEMENT %rt.qname;  %rt.content; >
<!-- end of rt.element -->]]>

<!-- rbspan attribute is used for complex ruby only ...... -->
<![%Ruby.complex;[
<!ENTITY % rt.attlist  "INCLUDE" >
<![%rt.attlist;[
<!ATTLIST %rt.qname;
      rbspan         %Number.datatype;      "1"
>
<!-- end of rt.attlist -->]]>
]]>

<!-- rp (ruby parenthesis) element ..................... -->

<![%Ruby.fallback;[
<!ENTITY % rp.element  "INCLUDE" >
<![%rp.element;[
<!ENTITY % rp.content
     "( #PCDATA )"
>
<!ELEMENT %rp.qname;  %rp.content; >
<!-- end of rp.element -->]]>
]]>

<!-- Ruby Common Attributes

     The following optional ATTLIST declarations provide an easy way
     to define common attributes for ruby elements.  These declarations
     are ignored by default.

     Ruby elements are intended to have common attributes of its
     parent markup language.  For example, if a markup language defines
     common attributes as a parameter entity %attrs;, you may add
     those attributes by just declaring the following parameter entities

         <!ENTITY % Ruby.common.attlists  "INCLUDE" >
         <!ENTITY % Ruby.common.attrib  "%attrs;" >

     before including the Ruby module.
-->

<!ENTITY % Ruby.common.attlists  "IGNORE" >
<![%Ruby.common.attlists;[
<!ENTITY % Ruby.common.attrib  "" >

<!-- common attributes for ruby ........................ -->

<!ENTITY % Ruby.common.attlist  "INCLUDE" >
<![%Ruby.common.attlist;[
<!ATTLIST %ruby.qname;
      %Ruby.common.attrib;
>
<!-- end of Ruby.common.attlist -->]]>

<![%Ruby.complex;[
<!-- common attributes for rbc ......................... -->

<!ENTITY % Rbc.common.attlist  "INCLUDE" >
<![%Rbc.common.attlist;[
<!ATTLIST %rbc.qname;
      %Ruby.common.attrib;
>
<!-- end of Rbc.common.attlist -->]]>

<!-- common attributes for rtc ......................... -->

<!ENTITY % Rtc.common.attlist  "INCLUDE" >
<![%Rtc.common.attlist;[
<!ATTLIST %rtc.qname;
      %Ruby.common.attrib;
>
<!-- end of Rtc.common.attlist -->]]>
]]>

<!-- common attributes for rb .......................... -->

<!ENTITY % Rb.common.attlist  "INCLUDE" >
<![%Rb.common.attlist;[
<!ATTLIST %rb.qname;
      %Ruby.common.attrib;
>
<!-- end of Rb.common.attlist -->]]>

<!-- common attributes for rt .......................... -->

<!ENTITY % Rt.common.attlist  "INCLUDE" >
<![%Rt.common.attlist;[
<!ATTLIST %rt.qname;
      %Ruby.common.attrib;
>
<!-- end of Rt.common.attlist -->]]>

<![%Ruby.fallback;[
<!-- common attributes for rp .......................... -->

<!ENTITY % Rp.common.attlist  "INCLUDE" >
<![%Rp.common.attlist;[
<!ATTLIST %rp.qname;
      %Ruby.common.attrib;
>
<!-- end of Rp.common.attlist -->]]>
]]>
]]>

<!-- end of xhtml-ruby-1.mod -->

3.2  Integrating the Ruby DTD Module into markup languages

3.2.1  How to integrate the Ruby DTD Module into markup languages

Unlike its structural complexity, integrating this Ruby DTD Module into markup languages is fairly easy. There are four important parameter entities in this Ruby Module that markup language designers should care, which are defined in the Ruby Module as follows:

<!ENTITY % Ruby.complex "INCLUDE" >
<!ENTITY % NoRuby.content "( #PCDATA )" >
<!ENTITY % Ruby.common.attlists  "IGNORE" >
<!ENTITY % Ruby.common.attrib  "" >

And there are also two optional non-standard parameter entities:

<!ENTITY % Ruby.fallback "INCLUDE" >
<!ENTITY % Ruby.fallback.mandatory "IGNORE" >

The function of the above parameter entities is as follows:

%Ruby.complex;

This parameter entity provides an option whether to include complex ruby markup or not. This is set to 'INCLUDE' by default. By setting it to 'IGNORE', markup language designers can exclude the complex ruby markup. In this case, the rbspan attribute of the rt element is not included, as it's useless for simple ruby.

%NoRuby.content;

This paremeter entity provides an easy way to redefine the content models of the rb and the rt elements. It's defined as '( #PCDATA )' by default. Basically, these elements will have the same content model, which is intended to allow other inline-level elements of its host markup language, but it should not include ruby descendent elements. By using this paremeter entity, markup language designers can redefine those content models at once, without redefining them separately.

%Ruby.common.attlists;

This paremeter entity provides an easy way to define common attributes for ruby elements. This is set to 'IGNORE' by default. Basically, ruby elements are intended to have common attributes of its host markup language. By setting this paremeter entity to 'INCLUDE', markup language designers can define common attributes for ruby elements at once using the parameter entity %Ruby.common.attrib;, without defining them separately.

%Ruby.common.attrib;

This paremeter entity defines common attributes for ruby elements, which is empty by default. In the case of XHTML 1.1 [XHTML11], it is defined as follows:

<!ENTITY % Ruby.common.attrib "%Common.attrib;" >
%Ruby.fallback;

This optional paremeter entity provides an option whether to include rp fallback mechanism or not. This is set to 'INCLUDE' by default. By setting it to 'IGNORE' (e.g. in internal subset), authors can exclude this fallback mechanism.

Note that setting it to 'IGNORE' further restricts the minimal content model of the ruby element, thus makes that usage nonconformant to [Ruby], though, the resultant document still conforms to [Ruby]. This option is provided only for authors' convenience should they really wish to exclude rp fallback from their contents. Markup language designers should not alter this paremeter entity to define their markup languages.

%Ruby.fallback.mandatory;

This optional paremeter entity provides an option whether to enforce rp fallback mechanism or not. This is set to 'IGNORE' by default. By setting it to 'INCLUDE' (e.g. in internal subset), authors can enforce this fallback mechanism.

This option is provided only for authors' convenience should they really wish to enforce rp fallback in their contents. Markup language designers should not alter this paremeter entity to define their markup languages.

In addition to redefining the above parameter entities (if necessary), markup language designers have to add the ruby element to some elements' content models where inline-level elements may appear.

In any case, markup language designers would have to redefine %NoRuby.content;, %Ruby.common.attlists; and %Ruby.common.attrib; as appropriate, when integrating the Ruby Module into their markup languages. There's no magic here. But %Ruby.complex; (and %Ruby.fallback;) can be used to choose the preferred structure of ruby markup. The following examples illustrate how markup language designers and authors can choose the preferred structure by just modifying %Ruby.complex; (and %Ruby.fallback;).

Case 1: using the full ruby markup

When markup language designers want to use the full ruby markup, namely, with support for both simple ruby and complex ruby, they don't have to redefine %Ruby.complex;.

In this case, the structure of ruby markup is the same as the one used in XHTML 1.1 [XHTML11].

Case 2: using the simple ruby markup

When markup language designers want to use the the simple ruby markup, namely, without support for complex ruby, they can redefine %Ruby.complex; as follows:

<!ENTITY % Ruby.complex "IGNORE" >

In this case, the structure of ruby markup is the same as the one currently supported in Microsoft Internet Explorer 5.0 and later.

Case 3: using the full ruby markup, without fallback

Note. Though the resultant document still conforms to [Ruby], using this structure for defining a markup language is nonconforming to [Ruby].

When authors want to use the full ruby markup, namely with support for both simple ruby and complex ruby but don't want to use rp fallback mechanism, they can redefine %Ruby.fallback; (e.g. in internal subset) as follows:

<!ENTITY % Ruby.fallback "IGNORE" >

In this case, the structure of ruby markup is the same as the one developed for JIS X 4052:2000 "Exchange format for Japanese documents with composition markup" [JISX4052].

Case 4: using the simple ruby markup, without fallback

Note. Though the resultant document still conforms to [Ruby], using this structure for defining a markup language is nonconforming to [Ruby].

When authors want to use the the simple ruby markup, namely without support for complex ruby and rp fallback mechanism, they can redefine %Ruby.complex; and %Ruby.fallback; (e.g. in internal subset) as follows:

<!ENTITY % Ruby.complex "IGNORE" >
<!ENTITY % Ruby.fallback "IGNORE" >

In this case, the structure of ruby markup is the same as the one used in the JepaX format [JepaX].

After redefining these parameter entities, the Ruby Module may be integrated into markup languages. The following is an excerpt from the XHTML 1.1 [XHTML11] DTD driver.

<!ENTITY % xhtml-ruby.module "INCLUDE" >
<![%xhtml-ruby.module;[
<!ENTITY % xhtml-ruby.mod
     PUBLIC "-//W3C//ELEMENTS XHTML Ruby 1.0//EN"
            "xhtml-ruby-1.mod" >
%xhtml-ruby.mod;]]>

3.2.2  Example of integrating the Ruby DTD Module (1): XML Specification DTD

As shown above, the Ruby DTD Module can be readily integrated into [XHTML11]. It's natural that it works, as the Ruby Module is primarily designed for that purpose.

But it also works with other DTDs as well, so long as those are properly parameterized. The following is an example DTD driver to integrate the Ruby Module into the XML Specification DTD [XMLspec]. Thanks to its fine parameterization, the XML Specification DTD can easily integrate the Ruby Module with minimum effort. Of course, by controlling %Ruby.complex;, markup language designers can choose preferred structure.

Note. At the time of writing, the latest version of [XMLspec] is Version 2.4, but here Version 2.0 is used because a rewrite in RELAX is based on Version 2.0, so it is more consistent to use Version 2.0 for comparison purpose.

<!-- XML Specification + Ruby DTD .................................. -->

<!-- Include XML Specification DTD ................................. -->

<!ENTITY % local.annot.class   "|ruby" >

<!ENTITY % xmlspec
    PUBLIC "-//W3C//DTD Specification V2.0//EN" "xmlspec-v20.dtd" >
%xmlspec;

<!-- Include Ruby Module ........................................... -->

<!ENTITY % Ruby.common.attlists "INCLUDE" >
<!ENTITY % Ruby.common.attrib   "%common.att;" >

<!ENTITY % xhtml-ruby.mod
     PUBLIC "-//W3C//ELEMENTS XHTML Ruby 1.0//EN" "xhtml-ruby-1.mod" >
%xhtml-ruby.mod;

Note. In the above example, %NoRuby.content; is NOT redefined so the content model of the rb and the rt elements is '( #PCDATA )'.

Note that since the [XMLspec] is not designed to be namespace-aware, the above example doesn't deal with namespace issues. An example of namespace-aware integration is shown in section 3.2.3.

3.2.3  Example of integrating the Ruby DTD Module(2): SVG DTD

SVG (Scalable Vector Graphics) [SVG] is a language for describing two-dimensional vector and mixed vector/raster graphics in XML, with a defined namespace. The Ruby Module can be part of the XHTML namespace (or other namespaces), so adding ruby annotation markup to SVG concerns mixing multiple markup vocabularies from different namespaces.

Modularization of XHTML [XHTMLMOD] provides a way to deal with namespaces, using the XHTML Qname (Qualified Name) Module. The following DTD driver defines a hybrid document type which allows ruby annotation markup inside the desc, title, text, tspan, textPath and a elements in SVG, in a namespace-aware way. See [XHTMLMOD] for more details.

<!-- SVG + Ruby DTD ................................................ -->

<!-- Include XHTML Qname (Qualified Name) Module ................... -->

<!ENTITY % URI.datatype "CDATA" >

<!ENTITY % xhtml-qname.mod
     PUBLIC "-//W3C//ENTITIES XHTML Qualified Names 1.0//EN"
            "xhtml-qname-1.mod" >
%xhtml-qname.mod;

<!-- Include SVG 1.0 DTD ........................................... -->

<!ENTITY % descExt "|%ruby.qname;" >
<!ENTITY % titleExt "|%ruby.qname;" >
<!ENTITY % textExt "|%ruby.qname;" >
<!ENTITY % tspanExt "|%ruby.qname;" >
<!ENTITY % textPathExt "|%ruby.qname;" >
<!ENTITY % aExt "|%ruby.qname;" >

<!ENTITY % SVG
     PUBLIC "-//W3C//DTD SVG 1.0//EN"
            "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" >
%SVG;

<!-- Include Ruby Module ........................................... -->

<!ENTITY % Ruby.common.attlists "INCLUDE" >
<!ENTITY % Ruby.common.attrib
     "id           ID       #IMPLIED
      xml:lang     NMTOKEN  #IMPLIED" >

<!ENTITY % xhtml-ruby.mod
     PUBLIC "-//W3C//ELEMENTS XHTML Ruby 1.0//EN" "xhtml-ruby-1.mod" >
%xhtml-ruby.mod;

<!ATTLIST %ruby.qname; %XHTML.xmlns.attrib; >

Note. In the above example, the id and xml:lang attributes are defined for ruby elements. %NoRuby.content; is NOT redefined so the content model of the rb and the rt elements is '( #PCDATA )'.

By using this DTD driver, by default, ruby elements can be used like this:

<ruby xmlns="http://www.w3.org/1999/xhtml">...</ruby>

If prefixing ruby elements is preferred, one can set %NS.prefixed; parameter entity to "INCLUDE", and can define arbitrary namespace prefix with %XHTML.prefix; parameter entity inside the internal subset of an instance. An example instance would be something like this:

<?xml version="1.0" standalone="no"?>
<?xml-stylesheet type="text/css" href="ruby-prefixed.css"?>
<!DOCTYPE svg SYSTEM "svg+ruby.dtd"[
<!ENTITY % NS.prefixed "INCLUDE" >
<!ENTITY % XHTML.prefix "xhtml" >
]>
<svg width="10cm" height="3cm">
  <desc>Example SVG with ruby annotation</desc>

  <text x="2.5cm" y="1.5cm"
        style="font-family:Verdana; font-size:16pt; fill:blue">
    Example of ruby:
    <xhtml:ruby xmlns:xhtml="http://www.w3.org/1999/xhtml">
      <xhtml:rb>AA</xhtml:rb><xhtml:rt>aaa</xhtml:rt>
    </xhtml:ruby>
  </text>
</svg>

4.  Implementing the Ruby Module in RELAX

RELAX Core [RELAX] allows defining RELAX grammars as XML instances, and provides the same datatypes as the XML Schema Part 2 [XMLSchema] (with a few extensions — none and emptyString). In addition, it allows to describe constraints not expressible by other schemas like DTD and XML Schema, e.g. the rbspan attribute of the rt element should not be allowed in simple ruby markup. Each RELAX Core module defines a single namespace grammar.

RELAX Namespace [RELAX-NS] allows mixing grammars from different namespaces. RELAX Namespace divides mixed-namespace instance into "islands", where each island consists of a single namespace, and each island can be validated by the RELAX Core processor. A module defining a single namespace may use schema languages other than RELAX Core, such as TREX [TREX].

4.1  Ruby RELAX Modules

In section 4.1.1, an implementation of the Ruby Module in RELAX is defined. This module defines all the necessary grammars for the Ruby Module, and allows simple ruby markup by default. In section 4.1.2, another RELAX module that allows full ruby markup is defined, by including and extending the Ruby RELAX Module defined in section 4.1.1.

4.1.1  Ruby RELAX Module

Note. In the following grammar, "Ruby.common.attrib" is assumed to be defined in other module.

Download this RELAX grammar

<module relaxCoreVersion="1.0"
  xmlns="http://www.xml.gr.jp/xmlns/relaxCore"
  moduleVersion="$Id: xhtml-ruby-1.rxm,v 1.1 2001/05/30 00:29:58 mimasa Exp $"
  targetNamespace="http://www.w3.org/1999/xhtml">

  <annotation>
    <documentation>
      XHTML Ruby Module in RELAX

        Ruby Elements

          ruby, rbc, rtc, rb, rt, rp

      This module defines grammars to support ruby annotation markup.
      This module is based on the W3C Ruby Annotation Specification:

        http://www.w3.org/TR/ruby
    </documentation>
  </annotation>

  <div>
    <annotation>
      <documentation>
        hedgeRules for the content model of the ruby element
      </documentation>
    </annotation>

    <hedgeRule label="Ruby.content.simple">
      <annotation>
        <documentation>Content model of simple ruby</documentation>
      </annotation>

      <sequence>
        <ref label="rb"/>
        <choice>
          <ref label="rt-simple"/>
          <sequence>
            <ref label="rp"/>
            <ref label="rt-simple"/>
            <ref label="rp"/>
          </sequence>
        </choice>
      </sequence>
    </hedgeRule>

    <hedgeRule label="Ruby.content.complex">
      <annotation>
        <documentation>Content model of complex ruby</documentation>
      </annotation>

      <sequence>
        <ref label="rbc"/>
        <ref label="rtc"/>
        <ref label="rtc" occurs="?"/>
      </sequence>
    </hedgeRule>

    <hedgeRule label="Ruby.content">
      <annotation>
        <documentation>Simple ruby is used by default</documentation>
      </annotation>

      <hedgeRef label="Ruby.content.simple"/>
    </hedgeRule>
  </div>

  <div>
    <annotation>
      <documentation>ruby element</documentation>
    </annotation>

    <elementRule role="ruby">
      <hedgeRef label="Ruby.content"/>
    </elementRule>

    <tag name="ruby">
      <ref role="Ruby.common.attrib"/>
    </tag>
  </div>

  <div>
    <annotation>
      <documentation>rbc (ruby base component) element</documentation>
    </annotation>

    <elementRule role="rbc">
      <ref label="rb" occurs="+"/>
    </elementRule>

    <tag name="rbc">
      <ref role="Ruby.common.attrib"/>
    </tag>
  </div>

  <div>
    <annotation>
      <documentation>rtc (ruby text component) element</documentation>
    </annotation>

    <elementRule role="rtc">
      <ref label="rt-complex" occurs="+"/>
    </elementRule>

    <tag name="rtc">
      <ref role="Ruby.common.attrib"/>
    </tag>
  </div>

  <div>
    <annotation>
      <documentation>rb (ruby base) element</documentation>
    </annotation>

    <elementRule role="rb">
      <mixed>
        <hedgeRef label="NoRuby.content" occurs="*"/>
      </mixed>
    </elementRule>

    <tag name="rb">
      <ref role="Ruby.common.attrib"/>
    </tag>
  </div>

  <div>
    <annotation>
      <documentation>rt (ruby text) element</documentation>
    </annotation>

    <elementRule label="rt-simple">
      <annotation>
        <documentation>
          elementRule for simple ruby

          rbspan attribute is not allowed in simple ruby
        </documentation>
      </annotation>

      <tag name="rt">
        <ref role="Ruby.common.attrib"/>
        <attribute name="rbspan" type="none"/>
      </tag>

      <mixed>
        <hedgeRef label="NoRuby.content" occurs="*"/>
      </mixed>
    </elementRule>

    <elementRule label="rt-complex">
      <annotation>
        <documentation>
          elementRule for complex ruby
        </documentation>
      </annotation>

      <tag name="rt">
        <ref role="Ruby.common.attrib"/>
        <attribute name="rbspan" type="positiveInteger"/>
      </tag>

      <mixed>
        <hedgeRef label="NoRuby.content" occurs="*"/>
      </mixed>
    </elementRule>
  </div>

  <div>
    <annotation>
      <documentation>rp (ruby parenthesis) element</documentation>
    </annotation>

    <elementRule role="rp" type="string"/>

    <tag name="rp">
      <ref role="Ruby.common.attrib"/>
    </tag>
  </div>

  <div>
   <annotation>
      <documentation>
        Ruby Common Attributes

        Ruby elements are intended to have common attributes of its
        parent markup language. An attPool "Ruby.common.attrib" MUST
        be defined to integrate this module.
      </documentation>
    </annotation>
  </div>

  <hedgeRule label="NoRuby.content">
    <annotation>
      <documentation>
        Content models of the rb and the rt elements are intended to
        allow other inline-level elements of its parent markup language,
        but it should not include ruby descendent elements. The hedgeRule
        'NoRuby.content' can be used to redefine those content models.
        It's defined as 'empty' by default.
      </documentation>
    </annotation>

    <empty/>
  </hedgeRule>

</module>

4.1.2  Ruby RELAX Module for full ruby markup

Download this RELAX grammar

<module relaxCoreVersion="1.0" xmlns="http://www.xml.gr.jp/xmlns/relaxCore"
  moduleVersion="$Id: xhtml-full-ruby-1.rxm,v 1.2 2001/05/30 00:38:43 mimasa Exp $"
  targetNamespace="http://www.w3.org/1999/xhtml">

  <annotation>
    <documentation>
      XHTML Ruby Module in RELAX for full ruby markup
    </documentation>
  </annotation>

  <include moduleLocation="xhtml-ruby-1.rxm"/>

  <hedgeRule label="Ruby.content">
    <annotation>
      <documentation>
        Allow complex ruby markup in addition to simple ruby markup
      </documentation>
    </annotation>

    <hedgeRef label="Ruby.content.complex"/>
  </hedgeRule>

</module>

4.2  Integrating the Ruby RELAX Module into markup languages

4.2.1  How to integrate the Ruby RELAX Module into markup languages

In RELAX, multiple hedgeRules may share the same label. A hedgeRef element referencing to some labels will be expanded by the following procedure:

  1. Locate all hedgeRules for this label.
  2. Group hedge models of these hedgeRules with a choice element.
  3. Copy the occurs attribute of the hedgeRef to this choice element.
  4. Replace the hedgeRef with this choice element.

This feature may be used to extend the content model. An example of using this feature is the Ruby RELAX Module shown in section 4.1.2, which extends the hedgeRule "Ruby.content" to allow complex ruby markup. Namely, the following hedgeRule:

  <hedgeRule label="Ruby.content">
    <hedgeRef label="Ruby.content.simple"/>
  </hedgeRule>

and the following hedgeRule:

  <hedgeRule label="Ruby.content">
    <hedgeRef label="Ruby.content.complex"/>
  </hedgeRule>

share the same label, so these hedgeRules will be merged as:

  <hedgeRule label="Ruby.content">
    <choice>
      <hedgeRef label="Ruby.content.simple"/>
      <hedgeRef label="Ruby.content.complex"/>
    </choice>
  </hedgeRule>

and will be expanded to:

  <hedgeRule label="Ruby.content">
    <choice>
      <sequence>
        <ref label="rb"/>
        <choice>
          <ref label="rt-simple"/>
          <sequence>
            <ref label="rp"/>
            <ref label="rt-simple"/>
            <ref label="rp"/>
          </sequence>
        </choice>
      </sequence>
      <sequence>
        <ref label="rbc"/>
        <ref label="rtc"/>
        <ref label="rtc" occurs="?"/>
      </sequence>
    </choice>
  </hedgeRule>

which allows both the simple and the full ruby markup.

Similarly, the following hedgeRule is used to define the content models of the rb and the rt elements.

  <hedgeRule label="NoRuby.content">
    <empty/>
  </hedgeRule>

This hedgeRule is referred inside elementRules for rb and rt as:

  <mixed>
    <hedgeRef label="NoRuby.content" occurs="*"/>
  </mixed>

so by default the content models of the rb and the rt elements are effectively the same as:

  <mixed>
    <empty/>
  </mixed>

which approximates '( #PCDATA )' in DTD. When integrating the Ruby RELAX Module, another hedgeRule(s) which share the same label may be defined to allow inline-level elements inside the rb and the rt elements. For example, if em and strong are allowed as inline-level elements, the following hedgeRule could be defined:

  <hedgeRule label="NoRuby.content">
    <choice>
      <ref label="em"/>
      <ref label="strong"/>
    </choice>
  </hedgeRule>

This hedgeRule will be merged with the above hedgeRule and will be expanded to:

  <hedgeRule label="NoRuby.content">
    <choice>
      <empty/>
      <choice>
        <ref label="em"/>
        <ref label="strong"/>
      </choice>
    </choice>
  </hedgeRule>

so the content models of the rb and the rt elements will effectively become:

  <mixed>
    <choice occurs="*">
      <ref label="em"/>
      <ref label="strong"/>
    </choice>
  </mixed>

The hedgeRule "NoRuby.content" MUST not include the ruby element.

Note. RELAX has ability to disallow the ruby element to appear as a direct or indirect subordinate of the rb or the rt elements. However, while it's possible, writing a RELAX grammar to prohibit indirect nesting of ruby is not quite easy.

In order to integrate the Ruby RELAX Module, an attPool "Ruby.common.attrib" MUST also be defined. This attPool will define common attributes for ruby-related elements. For example, if common attributes are defined in an attPool "Common.attrib", "Ruby.common.attrib" could be defined like this:

  <attPool role="Ruby.common.attrib">
    <ref role="Common.attrib"/>
  </attPool>

If there's no common attribute, "Ruby.common.attrib" may be empty:

  <attPool role="Ruby.common.attrib"/>

4.2.2  Example of integrating the Ruby RELAX Module: XML Specification DTD rewritten in RELAX

Like section 3.2.2, the [XMLspec] rewritten in RELAX by Murata Makoto, is used as an example. In the rewritten [XMLspec] RELAX grammar, the following hedgeRule is defined:

  <hedgeRule label="local.annot.class">
    <none/>
  </hedgeRule>

In order to add ruby, new hedgeRule with the same label can be defined like this:

  <hedgeRule label="local.annot.class">
    <ref label="ruby"/>
  </hedgeRule>

Thus, the following hedgeRule:

  <hedgeRule label="annot.class">
    <choice>
      <ref label="footnote"/>
      <hedgeRef label="local.annot.class"/>
    </choice>
  </hedgeRule>

will be expanded to:

  <hedgeRule label="annot.class">
    <choice>
      <ref label="footnote"/>
      <choice>
        <none/>
        <ref label="ruby"/>
      </choice>
    </choice>
  </hedgeRule>

which is effectively the same as:

  <hedgeRule label="annot.class">
    <choice>
      <ref label="footnote"/>
      <ref label="ruby"/>
    </choice>
  </hedgeRule>

So integrating the Ruby RELAX Module into the [XMLspec] rewritten in RELAX will be done like this:

<?xml version="1.0"?>
<module relaxCoreVersion="1.0"
  xmlns="http://www.xml.gr.jp/xmlns/relaxCore">

  <interface/>

  <hedgeRule label="local.annot.class">
    <ref label="ruby"/>
i  </hedgeRule>

  <include moduleLocation="xmlspec-v20.rxm"/>

  <attPool role="Ruby.common.attrib">
    <ref role="common.att"/>
  </attPool>

  <include moduleLocation="xhtml-ruby-1.rxm"/>

</module>

Note that strictly speaking, [XMLspec] and [Ruby] are in different namespace ([XMLspec] doesn't belong to any namespace, while [Ruby] is supposed to belong to other namespace, such as the XHTML namespace), so the above example will not work. The above example is only to illustrate the basic idea, in comparison with the DTD-based integration.

To mix vocabularies from different namespaces, RELAX Namespace [RELAX-NS] can be used. In order to allow the ruby element in [XMLspec] using RELAX Namespace, the namespace attribute can be added to the ref element:

  <hedgeRule label="local.annot.class">
    <ref label="ruby" namespace="http://www.w3.org/1999/xhtml"/>
  </hedgeRule>

So by using RELAX Namespace, the above example could be rewritten like this:

<grammar relaxNamespaceVersion="1.0"
  xmlns="http://www.xml.gr.jp/xmlns/relaxNamespace"
  grammarVersion="$Id: xmlspec+ruby.rxg,v 1.5 2001/05/30 00:43:42 mimasa Exp $">

  <topLevel>
    <ref label="spec" namespace=""
      xmlns="http://www.xml.gr.jp/xmlns/relaxCore"/>
  </topLevel>

  <namespace name="">
    <module relaxCoreVersion="1.0"
      xmlns="http://www.xml.gr.jp/xmlns/relaxCore">

      <include moduleLocation="xmlspec-v20.rxm"/>

      <hedgeRule label="local.annot.class">
        <ref label="ruby" namespace="http://www.w3.org/1999/xhtml"/>
      </hedgeRule>

    </module>
  </namespace>

  <namespace name="http://www.w3.org/1999/xhtml">
    <module relaxCoreVersion="1.0"
      xmlns="http://www.xml.gr.jp/xmlns/relaxCore">

      <interface>
        <export label="ruby"/>
      </interface>

      <include moduleLocation="xhtml-ruby-1.rxm"/>

      <attPool role="Ruby.common.attrib"/>

    </module>
  </namespace>

</grammar>

Note. Common attributes for ruby-related elements are not defined in the above example.

Ruby RELAX Module for full ruby markup can also be integrated just like the same way.

5.  Implementing the Ruby Module in TREX

Like RELAX, TREX [TREX] allows defining TREX patterns as XML instances, and a TREX pattern specifies a pattern for the structure and content of an XML document. Among other things, TREX makes it easiter to describe exclusion-like constraint, such as disallowing the nesting of the ruby element.

TREX does not have built-in datatypes, and may be used with the datatyping vocabularies such as XML Schema Part 2 [XMLSchema]. Note that the following example uses [XMLSchema] for datatyping, but TREX implementations may differ in the datatyping vocabularies they support, e.g. an implementation might support older version of [XMLSchema] identified by the namespace URI http://www.w3.org/2000/10/XMLSchema, or might support another datatyping vocabulary, or might not support datatyping at all.

5.1  Ruby TREX Modules

In section 5.1.1, an implementation of the Ruby TREX Module is defined. This module defines all the necessary patterns for the Ruby Module, and allows simple ruby markup by default. In section 5.1.2, another Ruby TREX Module that allows full ruby markup is defined, by including and extending the Ruby TREX Module defined in section 5.1.1.

Note that the following modules include annotations using facilities from XML Schema, but elements and attributes from other than the TREX namespace will be ignored, so you can use arbitrary elements and attributes from a separate namespace for annotations.

5.1.1  Ruby TREX Module

Download this TREX pattern

<grammar xmlns="http://www.thaiopensource.com/trex"
         ns="http://www.w3.org/1999/xhtml"
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <xsd:annotation>
    <xsd:documentation>
      Ruby TREX Module
      Revision: $Id: xhtml-ruby-1.trex,v 1.1 2001/05/29 22:13:14 mimasa Exp $

      Ruby Elements

        ruby, rbc, rtc, rb, rt, rp

      This module defines patterns to support ruby annotation markup.
      This module is based on the W3C Ruby Annotation Specification:

        http://www.w3.org/TR/ruby
    </xsd:documentation>
  </xsd:annotation>

  <xsd:annotation>
    <xsd:documentation>ruby element</xsd:documentation>
  </xsd:annotation>

  <define name="ruby">
    <element name="ruby">
      <ref name="ruby.attlist"/>
      <ref name="ruby.content"/>
    </element>
  </define>

  <define name="ruby.attlist">
    <ref name="Ruby.common.attrib"/>
  </define>

  <xsd:annotation>
    <xsd:documentation>rbc (ruby base component) element</xsd:documentation>
  </xsd:annotation>

  <define name="rbc">
    <element name="rbc">
      <ref name="rbc.attlist"/>
      <oneOrMore>
        <ref name="rb"/>
      </oneOrMore>
    </element>
  </define>

  <define name="rbc.attlist">
    <ref name="Ruby.common.attrib"/>
  </define>

  <xsd:annotation>
    <xsd:documentation>rtc (ruby text component) element</xsd:documentation>
  </xsd:annotation>

  <define name="rtc">
    <element name="rtc">
      <ref name="rtc.attlist"/>
      <oneOrMore>
        <ref name="rt"/>
      </oneOrMore>
    </element>
  </define>

  <define name="rtc.attlist">
    <ref name="Ruby.common.attrib"/>
  </define>

  <xsd:annotation>
    <xsd:documentation>rb (ruby base) element</xsd:documentation>
  </xsd:annotation>

  <define name="rb">
    <element name="rb">
      <ref name="rb.attlist"/>
      <ref name="NoRuby.content"/>
    </element>
  </define>

  <define name="rb.attlist">
    <ref name="Ruby.common.attrib"/>
  </define>

  <xsd:annotation>
    <xsd:documentation>rt (ruby text) element</xsd:documentation>
  </xsd:annotation>

  <define name="rt">
    <element name="rt">
      <ref name="rt.attlist"/>
      <ref name="NoRuby.content"/>
    </element>
  </define>

  <define name="rbspan.attrib">
    <optional>
      <attribute name="rbspan">
        <data type="xsd:positiveInteger"/>
      </attribute>
    </optional>
  </define>

  <define name="rt.attlist">
    <ref name="Ruby.common.attrib"/>
  </define>

  <xsd:annotation>
    <xsd:documentation>rp (ruby parenthesis) element</xsd:documentation>
  </xsd:annotation>

  <define name="rp">
    <element name="rp">
      <ref name="rp.attlist"/>
      <anyString/>
    </element>
  </define>

  <define name="rp.attlist">
    <ref name="Ruby.common.attrib"/>
  </define>

  <xsd:annotation>
    <xsd:documentation>
      Fragments for the content model of the ruby element
    </xsd:documentation>
  </xsd:annotation>

  <define name="Ruby.content.simple">
    <group>
      <ref name="rb"/>
      <ref name="rt"/>
    </group>
  </define>

  <define name="Ruby.content.simple.fallback">
    <group>
      <ref name="rb"/>
      <ref name="rp"/>
      <ref name="rt"/>
      <ref name="rp"/>
    </group>
  </define>

  <define name="Ruby.content.complex">
    <group>
      <ref name="rbc"/>
      <ref name="rtc"/>
      <optional>
        <ref name="rtc"/>
      </optional>
    </group>
  </define>

  <define name="ruby.content">
    <xsd:annotation>
      <xsd:documentation>
        Support simple ruby by default
      </xsd:documentation>
    </xsd:annotation>

    <choice>
      <ref name="Ruby.content.simple"/>
      <ref name="Ruby.content.simple.fallback"/>
    </choice>
  </define>

  <define name="Ruby.common.attrib">
    <xsd:annotation>
      <xsd:documentation>
        Ruby Common Attributes

        Content models of the rb and the rt elements are intended to
        allow other inline-level elements of its parent markup language,
        but it should not include ruby descendent elements. The following
        pattern NoRuby.content can be used to redefine those content models
        with minimum effort.
      </xsd:documentation>
    </xsd:annotation>

    <ref name="Common.attrib"/>
  </define>

  <define name="NoRuby.content">
    <xsd:annotation>
      <xsd:documentation>
        Content models of the rb and the rt elements are intended to
        allow other inline-level elements of its parent markup language,
        but it should not include ruby descendent elements. This pattern
        implements these constraints.  "Inline.model" has to be defined
        in other module.
      </xsd:documentation>
    </xsd:annotation>

    <concur>
      <ref name="Inline.model"/>
      <ref name="Ruby.concur"/>
    </concur>
  </define>

  <define name="Ruby.concur">
    <xsd:annotation>
      <xsd:documentation>Prohibit nesting of ruby</xsd:documentation>
    </xsd:annotation>

    <grammar>
      <start name="not.excluded">
        <zeroOrMore>
          <choice>
            <element>
              <not>
                <name>ruby</name>
              </not>
              <zeroOrMore>
                <attribute>
                  <anyName/>
                </attribute>
              </zeroOrMore>
              <ref name="not.excluded"/>
            </element>
            <anyString/>
          </choice>
        </zeroOrMore>
      </start>
    </grammar>
  </define>

  <xsd:annotation>
    <xsd:documentation>
      Add ruby into inline elements class; "Inline.class" has to be defined
      in other module.
    </xsd:documentation>
  </xsd:annotation>

  <define name="Ruby.class">
    <choice>
      <ref name="ruby"/>
    </choice>
  </define>

  <define name="Inline.class" combine="choice">
    <ref name="Ruby.class"/>
  </define>

</grammar>

5.1.2  Ruby TREX Module for full ruby markup

Download this TREX pattern

<grammar xmlns="http://www.thaiopensource.com/trex"
         ns="http://www.w3.org/1999/xhtml"
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <xsd:annotation>
    <xsd:documentation>
      Ruby TREX Module for full ruby markup
      Revision: $Id: xhtml-full-ruby-1.trex,v 1.1 2001/05/29 22:13:45 mimasa Exp $
    </xsd:documentation>
  </xsd:annotation>

  <include href="xhtml-ruby-1.trex"/>

  <define name="ruby.content" combine="choice">
    <xsd:annotation>
      <xsd:documentation>Add complex ruby support</xsd:documentation>
    </xsd:annotation>

     <ref name="Ruby.content.complex"/>
  </define>

  <define name="rt.attlist" combine="interleave">
    <xsd:annotation>
      <xsd:documentation>
        Add the rbspan attribute as one of attributes of the rt element
      </xsd:documentation>
    </xsd:annotation>

    <ref name="rbspan.attrib"/>
  </define>

</grammar>

5.2  Integrating the Ruby TREX Module into markup languages

5.2.1  How to integrate the Ruby TREX Module into markup languages

The modules defined in section 5.1.1 and section 5.1.2 are primarily designed to be used with other XHTML modules, to build XHTML Family document types. Unlike DTD-based modularization, the modules take care of redefining the content models appropriately, so you don't have to define the content model for a collection of modules. Such an example is shown in section 5.2.2.

When you integrate the Ruby Module into other markup languages, the patterns "Common.attrib", "Inline.model" and "Inline.class" have to be defined in other module(s). "Common.attrib" would include patterns of common attributes that may be used on ruby-related elements. Such attributes may be taken from a module implementing the XHTML Attribute Collections.

"Inline.model" would be defined like the following, where "Inline.class" defines a list of inline-level elements.

  <define name="Inline.model">
    <zeroOrMore>
      <choice>
        <anyString/>
        <ref name="Inline.class"/>
      </choice>
    </zeroOrMore>
  </define>

This corresponds to '( PCDATA | Inline )*' in the abstract definition. The "Ruby.concur" pattern defines a pattern to exclude a ruby at any depth, so the following pattern "NoRuby.content" corresponds to '( PCDATA | Inline -ruby )*' in the abstract definition.

  <define name="NoRuby.content">
    <concur>
      <ref name="Inline.model"/>
      <ref name="Ruby.concur"/>
    </concur>
  </define>

Note that in TREX, order of including modules is not irrelevant. For example, if two duplicated definitions come from different modules, the latter definition can be combined with the former, and if the latter specifies the combine attribute with the value replace, then the former definition will be replaced by the latter. This is different from DTD, where the former wins, or RELAX, where order of inclusion is irrelevant.

5.2.2  Example of integrating the Ruby TREX Module: TREX pattern for XHTML Basic

The following is an example of adding simple ruby markup into TREX pattern for XHTML Basic [XHTMLBasic], written by James Clark. If you would like to use full ruby markup, just replace xhtml-ruby-1.trex with xhtml-full-ruby-1.trex.

<!-- XHTML Basic plus simple ruby -->

<grammar ns="http://www.w3.org/1999/xhtml"
         xmlns="http://www.thaiopensource.com/trex">

<include href="datatypes.trex"/>
<include href="attribs.trex"/>
<include href="struct.trex"/>
<include href="text.trex"/>
<include href="hypertext.trex"/>
<include href="list.trex"/>
<include href="basic-form.trex"/>
<include href="basic-table.trex"/>
<include href="image.trex"/>
<include href="param.trex"/>
<include href="object.trex"/>
<include href="meta.trex"/>
<include href="link.trex"/>
<include href="base.trex"/>
<include href="xhtml-ruby-1.trex"/>

</grammar>

6.  Implementing the Ruby Module in RELAX NG

RELAX NG [RELAXNG] is a simple schema language for XML based on RELAX [RELAX] and TREX [TREX], developed by the OASIS RELAX NG Technical Committee.

As such, RELAX NG provides the power of both RELAX and TREX, e.g. it can describe the context-sensitive attribute like RELAX, and while RELAX NG itself doesn't provide an equivalent for TREX's concur, it is possible to check exclusions with a separate schema, as described in section 6.1.3.

Like TREX, RELAX NG allows patterns to reference externally-defined datatypes, such as those defined by XML Schema Part 2 [XMLSchema]. The following patterns use the datatype library defined by [XMLSchema], identified by the URI http://www.w3.org/2001/XMLSchema-datatypes.

4.1  Ruby RELAX NG Modules

In section 6.1.1, an implementation of the Ruby Module in RELAX NG is defined. This module defines all the necessary patterns for the Ruby Module, and allows simple ruby markup by default. In section 6.1.2, another RELAX NG module that allows full ruby markup is defined, by including and extending the Ruby RELAX NG Module defined in section 6.1.1. In section 6.1.3, yet another RELAX NG schema to check nesting of the ruby element is defined. This schema is intended to be used in addition to the main schema that incorporates the Ruby Module.

Note. Following advice from the Internationalization Working Group (members only), these modules does not define namespace for ruby (such as http://www.w3.org/1999/xhtml) by themselves. It is assumed to be provided by a schema that integrates the Ruby Module.

6.1.1  Ruby RELAX NG Module

Note. In the following schema, "Common.attrib", "Inline.class" and "Inline.model" are assumed to be defined in other module.

Download this RELAX NG schema

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
         xmlns:x="http://www.w3.org/1999/xhtml"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">

  <x:h1>Ruby Module in RELAX NG</x:h1>

  <x:pre>
    Ruby Elements

      ruby, rbc, rtc, rb, rt, rp

    This module defines grammars to support ruby annotation markup.
    This module is based on the W3C Ruby Annotation Specification:

      http://www.w3.org/TR/ruby

    Copyright &#xA9;2003 W3C&#xAE; (MIT, ERCIM, Keio), All Rights Reserved.

      Editor:   Masayasu Ishikawa &lt;mimasa@w3.org&gt;
      Revision: $Id: ruby-1.rng,v 1.7 2003/05/01 04:58:15 mimasa Exp $

    Permission to use, copy, modify and distribute this RELAX NG schema
    for Ruby Annotation and its accompanying documentation for any purpose
    and without fee is hereby granted in perpetuity, provided that the above
    copyright notice and this paragraph appear in all copies. The copyright
    holders make no representation about the suitability of this RELAX NG
    schema for any purpose.

    It is provided "as is" without expressed or implied warranty.
    For details, please refer to the W3C software license at:

      <x:a href="http://www.w3.org/Consortium/Legal/copyright-software"
      >http://www.w3.org/Consortium/Legal/copyright-software</x:a>
  </x:pre>

  <div>
    <x:h2>patterns for the content model of the ruby element</x:h2>

    <define name="Ruby.content.simple">
      <x:p>Content model of simple ruby</x:p>
      <group>
        <ref name="rb"/>
        <choice>
          <ref name="rt-simple"/>
          <group>
            <ref name="rp"/>
            <ref name="rt-simple"/>
            <ref name="rp"/>
          </group>
        </choice>
      </group>
    </define>

    <define name="Ruby.content.complex">
      <x:p>Content model of complex ruby</x:p>
      <group>
        <ref name="rbc"/>
        <ref name="rtc"/>
        <optional>
          <ref name="rtc"/>
        </optional>
      </group>
    </define>

    <define name="Ruby.content">
      <x:p>Simple ruby is used by default</x:p>
      <ref name="Ruby.content.simple"/>
    </define>
  </div>

  <div>
    <x:h2>Ruby Elements</x:h2>

    <x:h3>ruby element</x:h3>

    <define name="ruby">
      <element name="ruby">
        <ref name="Ruby.content"/>
        <ref name="Ruby.common.attrib"/>
      </element>
    </define>

    <x:h3>rbc (ruby base component) element</x:h3>

    <define name="rbc">
      <element name="rbc">
        <oneOrMore>
          <ref name="rb"/>
        </oneOrMore>
        <ref name="Ruby.common.attrib"/>
      </element>
    </define>

    <x:h3>rtc (ruby text component) element</x:h3>

    <define name="rtc">
      <element name="rtc">
        <oneOrMore>
          <ref name="rt-complex"/>
        </oneOrMore>
        <ref name="Ruby.common.attrib"/>
      </element>
    </define>

    <x:h3>rb (ruby base) element</x:h3>

    <define name="rb">
      <element name="rb">
        <ref name="NoRuby.content"/>
        <ref name="Ruby.common.attrib"/>
      </element>
    </define>

    <x:h3>rt (ruby text) element</x:h3>

    <define name="rt-simple">
      <x:p>grammar for simple ruby</x:p>
      <x:p>rbspan attribute is not allowed in simple ruby</x:p>
      <element name="rt">
        <ref name="NoRuby.content"/>
        <ref name="Ruby.common.attrib"/>
      </element>
    </define>

    <define name="rt-complex">
      <x:p>grammar for complex ruby</x:p>
      <element name="rt">
        <ref name="NoRuby.content"/>
        <ref name="Ruby.common.attrib"/>
        <optional>
          <attribute name="rbspan" a:defaultValue="1">
            <data type="positiveInteger">
              <param name="pattern">[1-9][0-9]*</param>
            </data>
          </attribute>
        </optional>
      </element>
    </define>

    <x:h3>rp (ruby parenthesis) element</x:h3>

    <define name="rp">
      <element name="rp">
        <text/>
        <ref name="Ruby.common.attrib"/>
      </element>
    </define>
  </div>

  <div>
    <x:h2>Ruby Common Attributes</x:h2>

    <x:p>Ruby elements are intended to have common attributes of its
      parent markup language. The pattern "Common.attrib" MUST be
      defined to integrate this module.</x:p>

    <define name="Ruby.common.attrib">
      <ref name="Common.attrib"/>
    </define>
  </div>

  <div>
    <x:p>Content models of the rb and the rt elements are intended to
      allow other inline-level elements of its parent markup language,
      but it should not include ruby descendent elements. This RELAX NG
      module itself doesn't check nesting of ruby elements.
      The patterns "Inline.class" and "Inline.model" MUST be defined
      to integrate this module.</x:p>

    <define name="Inline.class" combine="choice">
      <ref name="ruby"/>
    </define>

    <define name="NoRuby.content">
      <ref name="Inline.model"/>
    </define>
  </div>

</grammar>

6.1.2  Ruby RELAX NG Module for full ruby markup

Download this RELAX NG schema

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:x="http://www.w3.org/1999/xhtml">

  <x:h1>Ruby Module in RELAX NG for full ruby markup</x:h1>

  <x:pre>
    Copyright &#xA9;2003 W3C&#xAE; (MIT, ERCIM, Keio), All Rights Reserved.

      Editor:   Masayasu Ishikawa &lt;mimasa@w3.org&gt;
      Revision: $Id: full-ruby-1.rng,v 1.4 2003/04/30 06:50:03 mimasa Exp $
  </x:pre>

  <include href="ruby-1.rng"/>

  <define name="Ruby.content" combine="choice">
    <x:p>Allow complex ruby markup in addition to simple ruby markup</x:p>
    <ref name="Ruby.content.complex"/>
  </define>

</grammar>

6.1.3  Ruby RELAX NG Module to check exclusions

Download this RELAX NG schema

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:x="http://www.w3.org/1999/xhtml">

  <x:p>Checks exclusions applying to the ruby element.
    This schema is intended to be used in addition to a schema that
    includes ruby.  An appropriate namespace for ruby should be supplied
    to check validity.</x:p>

  <start>
    <ref name="normalElement"/>
  </start>

  <define name="normalElement">
    <element>
      <anyName>
        <except>
          <name>ruby</name>
        </except>
      </anyName>
      <ref name="normalContent"/>
    </element>
  </define>

  <define name="normalContent">
    <zeroOrMore>
      <choice>
        <ref name="normalElement"/>
        <ref name="rubyElement"/>
        <ref name="anyAttribute"/>
        <text/>
      </choice>
    </zeroOrMore>
  </define>

  <define name="rubyElement">
    <element name="ruby">
      <ref name="rubyContent"/>
    </element>
  </define>

  <define name="rubyContent">
    <zeroOrMore>
      <choice>
        <element>
          <anyName>
            <except>
              <name>ruby</name>
            </except>
          </anyName>
          <ref name="rubyContent"/>
        </element>
        <ref name="anyAttribute"/>
        <text/>
      </choice>
    </zeroOrMore>
  </define>

  <define name="anyAttribute">
    <attribute>
      <anyName/>
    </attribute>
  </define>

</grammar>

6.2  Integrating the Ruby RELAX NG Module into markup languages

6.2.1  How to integrate the Ruby RELAX NG Module into markup languages

The modules defined in section 6.1.1 and section 6.1.2 are primarily designed to be used with other XHTML modules, to build XHTML Family document types. Like TREX, the modules take care of redefining the content models appropriately, so you don't have to define the content model for a collection of modules. Such an example is shown in section 6.2.2.

When you integrate the Ruby Module into other markup languages, the patterns "Common.attrib", "Inline.model" and "Inline.class" have to be defined in other module(s). "Common.attrib" would include patterns of common attributes that may be used on ruby-related elements. Such attributes may be taken from a module implementing the XHTML Attribute Collections.

"Inline.model" would be defined like the following, where "Inline.class" defines a list of inline-level elements.

  <define name="Inline.model">
    <zeroOrMore>
      <choice>
        <text/>
        <ref name="Inline.class"/>
      </choice>
    </zeroOrMore>
  </define>

This corresponds to '( PCDATA | Inline )*' in the abstract definition.

Note that in RELAX NG, unlike TREX (or like RELAX), order of including modules is irrelevant, so basically the Ruby Module may be included at any place in the driver schema.

To integrate full ruby markup, simply include the following line:

  <include href="full-ruby-1.rng"/>

To integrate simple ruby markup, use the following line instead:

  <include href="ruby-1.rng"/>

Unless otherwise specified, these inclusions integrate ruby markup into the namespace of the host language. If you want to integrate ruby markup as another namespace (e.g. XHTML namespace) than the host language, use the ns attribute to indicate the namespace of the Ruby Module:

  <grammar ns="http://example.com/some/host/language"
           xmlns="http://relaxng.org/ns/structure/1.0">
    ... other patterns ...
    <include href="full-ruby-1.rng" ns="http://www.w3.org/1999/xhtml"/>
    ... other patterns ...
  </grammar>

6.2.2  Example of integrating the Ruby RELAX NG Module: XHTML 2.0

The following is the RELAX NG schema for XHTML 2.0 [XHTML2], which integrates full ruby markup. In this case, the Ruby Module is integrated into the XHTML 2.0 namespace.

Download this RELAX NG schema

<?xml version="1.0" encoding="UTF-8"?>
<grammar ns="http://www.w3.org/2002/06/xhtml2/"
         xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:x="http://www.w3.org/1999/xhtml">

  <x:h1>RELAX NG schema for XHTML 2.0</x:h1>

  <x:pre>
    Copyright ©2003-2005 W3C® (MIT, ERCIM, Keio), All Rights Reserved.

      Editor:   Masayasu Ishikawa &lt;mimasa@w3.org&gt;
      Revision: $Id: xhtml2.rng,v 1.39 2005/06/13 13:20:27 mimasa Exp $

    Permission to use, copy, modify and distribute this RELAX NG schema
    for XHTML 2.0 and its accompanying documentation for any purpose and
    without fee is hereby granted in perpetuity, provided that the above
    copyright notice and this paragraph appear in all copies. The copyright
    holders make no representation about the suitability of this RELAX NG
    schema for any purpose.

    It is provided "as is" without expressed or implied warranty.
    For details, please refer to the W3C software license at:

      <x:a href="http://www.w3.org/Consortium/Legal/copyright-software"
      >http://www.w3.org/Consortium/Legal/copyright-software</x:a>
  </x:pre>

  <div>
    <x:h2>XHTML 2.0 modules</x:h2>

    <x:h3>Attribute Collections Module</x:h3>
    <include href="xhtml-attribs-2.rng"/>

    <x:h3>Document Module</x:h3>
    <include href="xhtml-document-2.rng"/>

    <x:h3>Structural Module</x:h3>
    <include href="xhtml-structural-2.rng"/>

    <x:h3>Text Module</x:h3>
    <include href="xhtml-text-2.rng"/>

    <x:h3>Hypertext Module</x:h3>
    <include href="xhtml-hypertext-2.rng"/>

    <x:h3>List Module</x:h3>
    <include href="xhtml-list-2.rng"/>

    <x:h3>Metainformation Module</x:h3>
    <include href="xhtml-meta-2.rng"/>

    <x:h3>Object Module</x:h3>
    <include href="xhtml-object-2.rng"/>

    <x:h3>Handler Module</x:h3>
    <include href="xhtml-handler-2.rng"/>

    <x:h3>Image Module</x:h3>
    <include href="xhtml-image-2.rng"/>

    <x:h3>Style Sheet Module</x:h3>
    <include href="xhtml-style-2.rng"/>

    <x:h3>Tables Module</x:h3>
    <include href="xhtml-table-2.rng"/>

    <x:h3>Support Modules</x:h3>

    <x:h4>Datatypes Module</x:h4>
    <include href="xhtml-datatypes-2.rng"/>

    <x:h4>Param Module</x:h4>
    <include href="xhtml-param-2.rng"/>

    <x:h4>Caption Module</x:h4>
    <include href="xhtml-caption-2.rng"/>
  </div>


  <div>
    <x:h2>XML Events module</x:h2>
    <include href="xml-events-1.rng"/>
  </div>

  <div>
    <x:h2>Ruby module</x:h2>

    <include href="full-ruby-1.rng">

      <define name="Inline.class">
        <notAllowed/>
      </define>

      <define name="NoRuby.content">
        <ref name="Text.model"/>
      </define>

    </include>

    <define name="Inline.model">
      <notAllowed/>
    </define>

    <define name="Text.class" combine="choice">
      <ref name="ruby"/>
    </define>
  </div>

  <div>
    <x:h2>XForms module</x:h2>
    <x:p>To-Do: work out integration of XForms</x:p>
    <!--include href="xforms-11.rng"/-->
  </div>

  <div>
    <x:h2>XML Schema instance module</x:h2>
    <include href="XMLSchema-instance.rng"/>
  </div>

</grammar>

7.  Implementing the Ruby Module in Schematron

The Schematron [Schematron] is a simple and powerful structural schema language being standardized as Part 3 of ISO/IEC 19757 - Document Schema Definition Languages (DSDL). The Schematron Overview says:

The Schematron differs in basic concept from other schema languages in that it not based on grammars but on finding tree patterns in the parsed document. This approach allows many kinds of structures to be represented which are inconvenient and difficult in grammar-based schema languages.

The Schematron schemas are open (they allow anything by default and the schema restricts what is allowed). As such, it is not quite appropriate to describe specific structures, but it is particularly useful to describe constraints not easily expressible with closed schema languages (they allow nothing by default, and the schema allows specific structures).

7.1  Ruby Schematron Module

The following is an implementation of Ruby Module in Schematron for XHTML 1.x and XHTML 2.0 namespaces. Note that this schema doesn't attempt to describe all the constraints of ruby, rather, it only checks exclusion which is difficult or impossible to validate with other (grammar-based) schema languages. This schema is intended to be used together with other schema languages.

Note. This schema is based on Schematron 1.5, not ISO DSDL Part 3.

Download this Schematron schema

<schema xmlns="http://www.ascc.net/xml/schematron"
        xmlns:x1="http://www.w3.org/1999/xhtml"
        xmlns:x2="http://www.w3.org/2002/06/xhtml2/">
  <title>Schematron schema for Ruby Annotation</title>

  <ns prefix="x1" uri="http://www.w3.org/1999/xhtml"/>
  <ns prefix="x2" uri="http://www.w3.org/2002/06/xhtml2/"/>

  <p>Author: Masayasu Ishikawa</p>

  <p>CAUTION: This is purely experimental.</p>

  <pattern name="Exclusion" id="exclusion"
    see="http://www.w3.org/TR/ruby/#rb">

    <rule role="ruby_nest1" context="x1:ruby">
      <report test="ancestor::x1:ruby"
      >The ruby element MUST NOT contain other ruby elements.</report>
    </rule>

    <rule role="ruby_nest2" context="x2:ruby">
      <report test="ancestor::x2:ruby"
      >The ruby element MUST NOT contain other ruby elements.</report>
    </rule>

  </pattern>

</schema>

8.  Implementing the Ruby Module in XML Schema

Note. The following schemas are defined in C.3.22. Ruby of "Modularization of XHTML 1.0 - Second Edition" [XHTMLMOD].

8.1  Ruby XML Schema Modules

In section 8.1.1, an XML Schema module implementation that supports full ruby markup is defined. In section 8.1.2, another XML Schema module that supports simple ruby markup is defined.

8.1.1  Ruby XML Schema Module

Download this XML Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.w3.org/1999/xhtml"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="http://www.w3.org/1999/xhtml">

  <xs:annotation>
    <xs:documentation>
      This is the Ruby module for XHTML
      $Id: xhtml-ruby-1.xsd,v 1.1 2004/02/18 03:43:24 vivien Exp $
    </xs:documentation>
    <xs:documentation source="xhtml-copyright-1.xsd"/>
  </xs:annotation>

  <xs:annotation>
    <xs:documentation>
      "Ruby" are short runs of text alongside the base text, typically
      used in East Asian documents to indicate pronunciation or to
      provide a short annotation. The full specification for Ruby is here:
      
        http://www.w3.org/TR/2001/REC-ruby-20010531/
      
      This module defines "Ruby " or "complex Ruby" as described
      in the specification:
      
        http://www.w3.org/TR/2001/REC-ruby-20010531/#complex
    
      Simple or Basic Ruby are defined in a separate module.
      
      This module declares the elements and their attributes used to
      support complex ruby annotation markup. Elements defined here
            * ruby, rbc, rtc, rb, rt, rp
      
      This module expects the document model to define the
      following content models
        + InlNoRuby.mix                 
    </xs:documentation>
    <xs:documentation
         source="http://www.w3.org/TR/2001/REC-ruby-20010531/"/>    
  </xs:annotation>

  
  <xs:group name="ruby.content.simple">
    <xs:sequence>
      <xs:element ref="rb"/>
      <xs:choice>
        <xs:element ref="rt"/>
        <xs:sequence>
          <xs:element ref="rp"/>
          <xs:element ref="rt"/>
          <xs:element ref="rp"/>
        </xs:sequence>
      </xs:choice>
    </xs:sequence>
  </xs:group>

  <xs:group name="ruby.content.complex">
    <xs:sequence>
      <xs:element ref="rbc"/>
      <xs:element ref="rtc" maxOccurs="2"/>
    </xs:sequence>
  </xs:group>

  <!--
   add to this group any common attributes for all Ruby elements
  -->
  <xs:attributeGroup name="ruby.common.attrib"/>
  
  <xs:group name="ruby.content">
    <xs:choice>
      <xs:group ref="ruby.content.simple"/>
      <xs:group ref="ruby.content.complex"/>
    </xs:choice>
  </xs:group>

  <xs:complexType name="ruby.type">
    <xs:group ref="ruby.content"/>
    <xs:attributeGroup ref="ruby.common.attrib"/>
  </xs:complexType>

  <xs:element name="ruby" type="ruby.type"/>

  <!--
   rbc (ruby base component) element 
  -->
  <xs:attributeGroup name="rbc.attlist">
    <xs:attributeGroup ref="ruby.common.attrib"/>
  </xs:attributeGroup>
  
  <xs:group name="rbc.content">
    <xs:sequence>
      <xs:element ref="rb"/>
    </xs:sequence>
  </xs:group>  

  <xs:complexType name="rbc.type">
    <xs:group ref="rbc.content"/>
    <xs:attributeGroup ref="rbc.attlist"/>
  </xs:complexType>

  <xs:element name="rbc" type="rbc.type"/>

  <!--
   rtc (ruby text component) element
  -->
  <xs:attributeGroup name="rtc.attlist">
    <xs:attributeGroup ref="ruby.common.attrib"/>
  </xs:attributeGroup>
  
  <xs:group name="rtc.content">
    <xs:sequence>
      <xs:element ref="rt" maxOccurs="unbounded"/>
    </xs:sequence>  
  </xs:group>    

  <xs:complexType name="rtc.type">
    <xs:group ref="rt.content"/>  
    <xs:attributeGroup ref="rtc.attlist"/>
  </xs:complexType>

  <xs:element name="rtc" type="rtc.type"/>

  <!--
   rb (ruby base) element 
  -->
  <xs:attributeGroup name="rb.attlist">
    <xs:attributeGroup ref="ruby.common.attrib"/>
  </xs:attributeGroup>

  <xs:group name="rb.content">
    <xs:sequence>
       <xs:group ref="InlNoRuby.mix" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:group>      

  <xs:complexType name="rb.type" mixed="true">
    <xs:group ref="rb.content"/>
    <xs:attributeGroup ref="rb.attlist"/>
  </xs:complexType>
    
  <xs:element name="rb" type="rb.type"/>

  <!--
   rt (ruby text) element 
  -->
  <xs:attributeGroup name="rt.attlist">
    <xs:attributeGroup ref="ruby.common.attrib"/>
    <xs:attribute name="rbspan" type="Number" default="1"/>
  </xs:attributeGroup>

  <xs:group name="rt.content">
    <xs:sequence>
       <xs:group ref="InlNoRuby.mix" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:group>      
  
  <xs:complexType name="rt.type" mixed="true">
    <xs:group ref="rt.content"/>  
    <xs:attributeGroup ref="rt.attlist"/>
  </xs:complexType>

  <xs:element name="rt" type="rt.type"/>

  <!-- rp (ruby parenthesis) element  -->
  <xs:attributeGroup name="rp.attlist">
    <xs:attributeGroup ref="ruby.common.attrib"/>
  </xs:attributeGroup>
  
  <xs:group name="rp.content">
    <xs:sequence/>
  </xs:group>      
  

  <xs:complexType name="rp.type" mixed="true">
    <xs:group ref="rp.content"/>
    <xs:attributeGroup ref="rp.attlist"/>
  </xs:complexType>

  <xs:element name="rp" type="rp.type"/>

</xs:schema>

8.1.2  Simple Ruby XML Schema Module

Download this XML Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.w3.org/1999/xhtml"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="http://www.w3.org/1999/xhtml">

  <xs:annotation>
    <xs:documentation>
      This is the XML Schema module for Ruby Basic.
      $Id: xhtml-ruby-basic-1.xsd,v 1.1 2004/02/18 03:43:24 vivien Exp $
    </xs:documentation>
    <xs:documentation source="xhtml-copyright-1.xsd"/>
  </xs:annotation>

  <xs:annotation>
    <xs:documentation>
      "Ruby" are short runs of text alongside the base text, typically
      used in East Asian documents to indicate pronunciation or to
      provide a short annotation. The full specification for Ruby is here:
      
        http://www.w3.org/TR/2001/REC-ruby-20010531/

      This module defines "Ruby Basic" or "simple Ruby" as described
      in the specification:
      
        http://www.w3.org/TR/ruby/#simple-ruby1
        
      This module declares the elements and their attributes used to
      support simple ruby annotation markup. Elements defined here are
          * ruby, rb, rt, rp
      Ruby Basic does not use the rbc or rtc elements.
      The content of the ruby element for Ruby Basic
      uses the rp element for fallback purposes.        
    </xs:documentation>
    <xs:documentation
         source="http://www.w3.org/TR/2001/REC-ruby-20010531/#simple-ruby1"/>  
  </xs:annotation>

  <xs:group name="ruby.content.simple">
    <xs:sequence>
      <xs:element ref="rb"/>
      <xs:choice>
        <xs:element ref="rt"/>
        <xs:sequence>
          <xs:element ref="rp"/>
          <xs:element ref="rt"/>
          <xs:element ref="rp"/>
        </xs:sequence>
      </xs:choice>
    </xs:sequence>
  </xs:group>

  <!-- 
   add to this group any common attributes for all Ruby elements 
  -->
  <xs:attributeGroup name="ruby.common.attrib"/>

  <xs:complexType name="ruby.basic.type">
    <xs:group ref="ruby.content.simple"/>
    <xs:attributeGroup ref="ruby.common.attrib"/>
  </xs:complexType>

  <xs:element name="ruby" type="ruby.basic.type"/>

  <!-- 
   rb (ruby base) element 
  -->
  <xs:attributeGroup name="rb.attrib">
    <xs:attributeGroup ref="ruby.common.attrib"/>
  </xs:attributeGroup>

  <xs:complexType name="rb.type" mixed="true">
    <xs:attributeGroup ref="rb.attrib"/>
  </xs:complexType>

  <xs:element name="rb" type="rb.type"/>

  <!--
   rt (ruby text) element 
  -->
  <xs:attributeGroup name="rt.attrib">
    <xs:attributeGroup ref="ruby.common.attrib"/>
  </xs:attributeGroup>

  <!--
   Note that the rbspan element is not used in Ruby Basic
  -->
  <xs:complexType name="rt.type" mixed="true">
    <xs:attributeGroup ref="rt.attrib"/>
  </xs:complexType>

  <xs:element name="rt" type="rt.type"/>

  <!-- 
   rp (ruby parenthesis) element 
  -->
  <xs:attributeGroup name="rp.attrib">
    <xs:attributeGroup ref="ruby.common.attrib"/>
  </xs:attributeGroup>

  <xs:complexType name="rp.type" mixed="true">
    <xs:attributeGroup ref="rp.attrib"/>
  </xs:complexType>

  <xs:element name="rp" type="rp.type"/>

</xs:schema>

8.2  Integrating the Ruby XML Schema Module into markup languages

The way to integrate XML Schema Modules into markup languages will be explained in "Modularization of XHTML 1.0 - Second Edition" [XHTMLMOD].

9.  Sample CSS / XSL style sheets for Ruby

Although the primary purpose of this Note is to explore module implementations of ruby, it is of course preferable that instances which use ruby could be rendered in some way. This section briefly explores how ruby could be rendered using style sheets.

9.1  Sample CSS2 style sheets for Ruby

The following is a sample CSS2 style sheet fragment for ruby.

ruby, rbc, rtc, rb, rt { display: inline }
rp               { display: none }
ruby > rt:before { content: "(" }
ruby rtc:before  { content: "(" }
ruby rtc + rtc:before  { content: "; " }
ruby:after       { content: ")" }

An example rendering of an XHTML 1.1 document by Mozilla 1.1, with style sheets that include the above fragments, is shown in Figure 1.

example ruby rendering in Mozilla

Figure 1: Example ruby rendering in Mozilla

Note. The above example XHTML 1.1 document is served as "application/xhtml+xml", and rendering is controlled by CSS. Some XHTML user agents might not be able to render this document.

Note that as shown in Figure 1, the above style sheets render ruby text as inline annotation, rather than interlinear annotation (i.e. ruby annotation). Formatting properties for styling ruby are under development, see section 9.2 for sample CSS3 style sheets using properties defined in "CSS3 Ruby Module" [CSS3-Ruby]. Ruby may also be used in vertical layout, see "CSS3 Text Module" [CSS3-Text] (work in progress) for relevant properties.

It is also possible to imitate "ruby as interlinear annotation" using CSS2's 'inline-table' property. The following is a sample CSS2 style sheet fragment to render ruby as interlinear annotation.

ruby { display: inline-table }
ruby * {
	display: inline;
	line-height: 1.2;
	text-indent: 0;
	text-align: center;
	white-space: nowrap;
}
ruby > * {
	display: table-row-group;
}
ruby > rt, ruby rtc {
	display: table-header-group;
	font-size: 60%;
}
ruby rtc + rtc { display: table-footer-group }
ruby rbc > *, ruby rtc > * { display: table-cell }
/* this only works when an rt spans across all rb */
ruby rtc > *[rbspan] { display: table-caption }
ruby rp { display: none }

An example rendering of another XHTML 1.1 document by Mozilla 1.1, with style sheets that include the above fragments, is shown in Figure 2 (enlarged for readability).

another example ruby rendering in Mozilla

Figure 2: Another example ruby rendering in Mozilla, using inline-table

Note that the rbspan attribute cannot be handled correctly with the above style sheets - it only "works" when an rt element spans across all rb elements. Correct handling of the rbspan attribute should be provided through the ruby-span property of [CSS3-Ruby]. See section 9.2 for an example.

Although the rendering of ruby should be controlled by style sheets, when appropriate style information is not provided, user agents could still try to render ruby in some meaningful way. The following examples illustrate how a user agent could support ruby.

W3C's Amaya browser/editor implements ruby as part of XHTML 1.1 support since version 5.0. Figure 3 is an example rendering of sample XHTML 1.1 document in its main view, and Figure 4 is another example rendering of the same document in alternate view. It is of course possible to apply style properties like "color" to ruby-related elements.

example ruby rendering in Amaya, main view

Figure 3: Example ruby rendering in Amaya (main view)

example ruby rendering in Amaya, alternate view

Figure 4: Example ruby rendering in Amaya (alternate view)

9.2  Sample CSS3 style sheets for Ruby

The following is a sample CSS3 style sheet fragment using formatting properties defined in [CSS3-Ruby].

ruby             { display: ruby }
rbc              { display: ruby-base-container }
ruby > rtc       { display: ruby-text-container; ruby-position: before }
ruby > rtc + rtc { display: ruby-text-container; ruby-position: after }
rb               { display: ruby-base }
rt               { display: ruby-text; ruby-span: attr(rbspan) }
rp               { display: none }

9.3  Sample XSL style sheets for Ruby

XSL 1.0 [XSL] doesn't provide formatting objects for ruby yet. However, some work-around is possible with inline-container. The following is a sample XSL style sheet fragment for ruby.

<xsl:template match="ruby">
  <fo:inline-container text-indent="0mm" last-line-end-indent="0mm"
       start-indent="0mm" end-indent="0mm">
    <fo:block font-size="0.5em" text-align="center" line-height="1.3"
        space-before.conditionality="retain" wrap-option="no-wrap">
      <xsl:apply-templates select="rt|rtc[1]"/>
    </fo:block>
    <fo:block text-align="center" line-height="1" wrap-option="no-wrap">
      <xsl:apply-templates select="rb|rbc"/>
    </fo:block>
    <fo:block font-size="0.5em" text-align="center" line-height="1.3"
        space-before.conditionality="retain" wrap-option="no-wrap">
      <xsl:apply-templates select="rtc[2]"/>
    </fo:block>
  </fo:inline-container>
</xsl:template>

An example rendering by Antenna House's XSL Formatter is shown in Figure 5.

example ruby rendering in XSL Formatter

Figure 5: Example ruby rendering in XSL Formatter

Note that the above style sheets don't handle baseline adjustment.

References

[CSS3-Ruby]
"CSS3 Ruby Module", W3C Candidate Recommendation
M. Suignard, ed., 14 May 2003, work in progress.
Available at: http://www.w3.org/TR/2003/CR-css3-ruby-20030514
The latest version is available at: http://www.w3.org/TR/css3-ruby
[CSS3-Text]
"CSS3 Text Module", W3C Candidate Recommendation
M. Suignard, C. Lilley, eds., 14 May 2003, work in progress.
Available at: http://www.w3.org/TR/2003/CR-css3-text-20030514
The latest version is available at: http://www.w3.org/TR/css3-text
Note that this document is expected to be replaced by the CSS3 Text Effects Module and the CSS3 Text Layout Module, and vertical layout will be part of the Text Layout Module.
[JepaX]
"JepaX — JEPA electronic publishing exchange format" (in Japanese)
Japanese Electronic Publishing Association (JEPA), work in progress.
Available at: http://x.jepa.or.jp/jepax/
[JISX4052]
"Exchange format for Japanese documents with composition markup" (in Japanese)
JIS X 4052:2000, Japanese Standards Association
[RELAX]
"Regular Language Description for XML: RELAX Core" (in Japanese; English translation is also available)
JIS TR X 0029:2000, Japanese Standards Association
"RELAX Core" was submitted to ISO and was published as "ISO/IEC TR 22250-1:2002, Document Description and Processing Languages — Regular Language Description for XML (RELAX) — Part 1: RELAX Core" in 2002, but was later withdrawn.
Information about RELAX can be available at: http://www.xml.gr.jp/relax/
Also note that RELAX and TREX has been unified as RELAX NG [RELAXNG].
[RELAX-NS]
"Regular Language Description for XML (RELAX) Namespace" (in Japanese)
JIS TR X 0044:2001, Japanese Standards Association
"RELAX Namespace" was also submitted to ISO as "ISO/IEC DTR 22250-2, Document Description and Processing Languages — Regular Language Description for XML (RELAX) — Part 2: RELAX Namespace", but was later withdrawn.
[RELAXNG]
"RELAX NG Specification", OASIS Committee Specification
J. Clark, Murata M., eds., The Organization for the Advancement of Structured Information Standards (OASIS), 3 December 2001.
Available at: http://relaxng.org/spec-20011203.html
RELAX NG has been standardized as part of ISO/IEC 19757 - Document Schema Definition Languages (DSDL), as ISO/IEC 19757-2:2003 "Information technology -- Document Schema Definition Language (DSDL) -- Part 2: Regular-grammar-based validation -- RELAX NG". See home page for Document Schema Definition Languages at http://dsdl.org/ for details.
[Ruby]
"Ruby Annotation", W3C Recommendation
M. Sawicki, M. Suignard, M. Ishikawa, M. Dürst, T. Texin, eds., 31 May 2001.
Available at: http://www.w3.org/TR/2001/REC-ruby-20010531
The latest version is available at: http://www.w3.org/TR/ruby
[Schematron]
"Document Schema Definition Languages (DSDL) — Part 3: Rule-based validation — Schematron"
Rick Jelliffe, ed., ISO/IEC JTC 1 SC 34. It is currently a Final Committee Draft, see home page for Document Schema Definition Languages at http://dsdl.org/ for details.
[SVG]
"Scalable Vector Graphics (SVG) 1.0 Specification", W3C Recommendation
J. Ferraiolo, ed., 4 September 2001.
Available at: http://www.w3.org/TR/2001/REC-SVG-20010904/
The latest version is available at: http://www.w3.org/TR/SVG
[TREX]
"TREX - Tree Regular Expressions for XML"
J. Clark (Thai Open Source Software Center), 2001.
Information about TREX can be available at: http://www.thaiopensource.com/trex/
Note that TREX and RELAX has been unified as RELAX NG [RELAXNG].
[XHTML11]
"XHTML™ 1.1 — Module-based XHTML", W3C Recommendation
M. Altheim, S. McCarron, eds., 31 May 2001.
Available at: http://www.w3.org/TR/2001/REC-xhtml11-20010531
The latest version is available at: http://www.w3.org/TR/xhtml11
[XHTML2]
"XHTML™ 2.0", W3C Working Draft
J. Axelsson et al., eds., 27 May 2005, work in progress.
Available at: http://www.w3.org/TR/2005/WD-xhtml2-20050527
The latest version is available at: http://www.w3.org/TR/xhtml2
[XHTMLBasic]
"XHTML™ Basic", W3C Recommendation
M. Baker, M. Ishikawa, S. Matsui, P. Stark, T. Wugofski, T. Yamakami, eds., 19 December 2000.
Available at: http://www.w3.org/TR/2000/REC-xhtml-basic-20001219
The latest version is available at: http://www.w3.org/TR/xhtml-basic
[XHTMLMOD]
"Modularization of XHTML™ 1.0 - Second Edition", W3C Working Draft
S. P. McCarron et al., 18 February 2004.
Available at: http://www.w3.org/TR/2004/WD-xhtml-modularization-20040218
The first edition of this Recommendation is available at: http://www.w3.org/TR/2001/REC-xhtml-modularization-20010410
The latest version is available at: http://www.w3.org/TR/xhtml-modularization
[XMLSchema]
"XML Schema Part 1: Structures Second Edition", W3C Recommendation
H. S. Thompson, D. Beech, M. Maloney, N. Mendelsohn, eds., 28 October 2004.
Available at: http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/
The latest version is available at: http://www.w3.org/TR/xmlschema-1
See also "XML Schema Part 2: Datatypes Second Edition", available at: http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/
The latest version is available at: http://www.w3.org/TR/xmlschema-2
[XMLspec]
"Guide to the W3C XML Specification ("XMLspec") DTD"
E. Maler, ed., available at: http://www.w3.org/XML/1998/06/xmlspec-report.htm
At the time of writing, this page describes version 2.1. Later versions of the XML Spec schema and style sheets are maintained by Norman Walsh, available at: http://www.w3.org/2002/xmlspec/
[XSL]
"Extensible Stylesheet Language (XSL) Version 1.0", W3C Recommendation
S. Adler et al., 15 October 2001.
Available at: http://www.w3.org/TR/2001/REC-xsl-20011015/
The latest version is available at: http://www.w3.org/TR/xsl

Acknowledgments

Special thanks to Murata Makoto and James Clark for providing useful sample grammars/patterns, and of course to their excellent work on RELAX, TREX and RELAX NG. Thanks to Ruud Steltenpool for reporting errors in this document.

Changes

Changes from the 31 May 2001 version

Fixed a couple of typos.

Downloadable version of the Ruby RELAX Module was incorrectly replaced by the Ruby RELAX Module for full ruby markup.

Added RELAX NG section.

Added Schematron section.

Added another sample CSS2 style sheets and sample CSS3 style sheets.

Added Acknowledgments section.

Updated References section.