[jsword-devel] jsword-devel Digest, Vol 47, Issue 17

DM Smith dmsmith555 at yahoo.com
Thu Apr 24 05:13:00 MST 2008


Yiguang Hu wrote:
> DM,
>
> Do you have samples about how to do parallel and
> interlinear display?
>   
See below. Feel free to send me patches for DwrBridge or anything else 
that needs to change in projects where you cannot submit commits.
> This is what I got now. Once I have parallel and
> interlinear display working, I can start to organize
> the layout and make it more real.
>   
That's the same way I'd approach it!
> http://rock.ccim.org/jswordweb/
>
> Yiguang

The basic process of getting OSIS is to get a Book and a Key then create 
a BookData. From the BookData one can get a SAX stream which can be styled.

The process for parallel books is similar, with first argument to 
BookData being Book[], rather than Book. One further thing, this 
constructor also takes a third argument indicating whether adjacent 
Bibles of the same language should be compared.

As to interlinear this would be a change to the xslt. This won't work 
for BibleDesktop, but will for real browsers. The CSS was in an earlier 
email.

I haven't thought it through, but basically when producing the data, 
every <w> element needs to be in something like:
The difference to this template is: <span class="verse">...</span>
  <xsl:template match="verse[not(@eID)]">
    ....
    <!-- Always output the verse -->
    <xsl:choose>
       <xsl:when test="$VLine = 'true'">
        <div class="l"><a name="{@osisID}"><xsl:call-template 
name="versenum"/></a><span class="verse"><xsl:apply-templates/></span></div>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="versenum"/><span 
class="verse"><xsl:apply-templates/></span>
        <!-- Follow the verse with an extra space -->
        <!-- when they don't start on lines to themselves -->
        <xsl:text> </xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

And also (note the <span>...</span>), to surround the word:
  <xsl:template match="w">
    <!-- Output the content followed by all the lemmas and then all the 
morphs. -->
    <span><xsl:apply-templates/></span>
    <xsl:if test="$Strongs = 'true' and (starts-with(@lemma, 
'x-Strongs:') or starts-with(@lemma, 'strong:'))">
      <xsl:call-template name="lemma">
        <xsl:with-param name="lemma" select="@lemma"/>
      </xsl:call-template>
    </xsl:if>
    <xsl:if test="$Morph = 'true' and (starts-with(@morph, 
'x-Robinson:') or starts-with(@morph, 'robinson:'))">
      <xsl:call-template name="morph">
        <xsl:with-param name="morph" select="@morph"/>
      </xsl:call-template>
    </xsl:if>
    <!--
        except when followed by a text node or non-printing node.
        This is true whether the href is output or not.
    -->
    <xsl:variable name="siblings" select="../child::node()"/>
    <xsl:variable name="next-position" select="position() + 1"/>
    <xsl:if test="$siblings[$next-position] and 
name($siblings[$next-position]) != ''">
      <xsl:text> </xsl:text>
    </xsl:if>
  </xsl:template>

The named templates "lemma" and "morph" need to change the <sub> around 
the entries. Below is lemma, morph would be similar.
Note the styling change.
  <xsl:template name="lemma">
    <xsl:param name="lemma"/>
    <xsl:param name="part" select="0"/>
    <xsl:variable name="orig-lemma" select="substring-after($lemma, ':')"/>
    <xsl:variable name="protocol">
      <xsl:choose>
        <xsl:when test="substring($orig-lemma, 1, 1) = 'H'">
          <xsl:value-of select="$hebrew.def.protocol"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$greek.def.protocol"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:variable name="separator">
      <xsl:choose>
        <xsl:when test="contains($orig-lemma, '|')">
          <xsl:value-of select="'|'"/>
        </xsl:when>
        <xsl:when test="contains($orig-lemma, ' ')">
          <xsl:value-of select="' '"/>
        </xsl:when>
      </xsl:choose>
    </xsl:variable>
    <xsl:variable name="sub">
      <xsl:choose>
        <xsl:when test="$separator != '' and $part = '0'">
          <xsl:value-of select="$part + 1"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$part"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="$separator = ''">
        <a href="{$protocol}{$orig-lemma}"><xsl:value-of 
select="format-number(substring($orig-lemma,2),'#')"/></a>
      </xsl:when>
      <xsl:otherwise>
        <!-- <sub class="strongs"><a 
href="{$protocol}{substring-before($orig-lemma, 
$separator)}">S<xsl:number level="single" from="/osis//verse" 
format="1"/><xsl:number value="$sub" format="a"/></a>, </sub> -->
        <a href="{$protocol}{substring-before($orig-lemma, 
$separator)}"><xsl:value-of 
select="format-number(substring(substring-before($orig-lemma, 
$separator),2),'#')"/></a><xsl:text>, </xsl:text>
        <xsl:call-template name="lemma">
          <xsl:with-param name="lemma" select="substring-after($lemma, 
$separator)"/>
          <xsl:with-param name="part">
            <xsl:choose>
              <xsl:when test="$sub">
                <xsl:value-of select="$sub + 1"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="1"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:with-param>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

There's a few last things:
There are other elements, such as <transChange> that need to have their 
output put in <span><span>...</span></span>
  <xsl:template match="transChange">
    <span><span class="added"><xsl:apply-templates/></span></span>
  </xsl:template>

Text that is not in a <w> element, but stands between them needs to be 
put into <span><span>...</span></span>
I'm not sure that this can be done easily in xslt. The difficulty is 
that you'd need something like:
  <xsl:template match="text()">
  .... if the parent is <verse> then <span><span><xslt:value-of 
select="."/></span></span>...
  </xsl:template>
But the "containing" verse might be of the form <verse sID="xxx"/> and 
thus not a parent, but a remote sibling. Finding a remote sibling is a 
big performance hit. This is why in all the OSIS modules I have created 
(KJV, ESV,...) verses are containers.
So, I'd be inclined to do it in JavaScript. Something like: get all the 
children of <span class="verse"> and any that are not all whitespace, 
put in <span><span>...</span><span>

The other ugliness is the placement of punctuation. If that text begins 
with punctuation, it should be put in the preceding span holding the 
actual text.

Finally, one also needs to make the same changes to the corresponding 
mode="jesus" templates.

I think this needs to be a separate style sheet, with just these 
elements. By careful arrangement of import statements (with a real xslt 
parser) one can have these override the others. With the javeline or 
google xslt parsers one would need to have everything else duplicated.

Hope this helps. For the next month or so, my work demands will keep me 
from much coding. But I'd be glad to apply patches.

Working together with Christ,
    DM




More information about the jsword-devel mailing list