TEIC / Stylesheets

TEI XSL Stylesheets
231 stars 124 forks source link

val and tag elements are ignored #567

Closed sydb closed 9 months ago

sydb commented 2 years ago

The <val> element is ignored by teitohtml.

That is, the input

The <att>n</att> attribute may be specified as <val>0</val>, but only on a full moon.

is converted to

The <span class="att">n</span> attribute may be specified as 0, but only on a full moon.

rather than

The <span class="att">n</span> attribute may be specified as <span class="val">"0"</span>, but only on a full moon.

which (I claim) is what should be generated.

sydb commented 2 years ago

BTW, some may argue the output should not have LIT (or LITA) delimiters[1] in the content, but rather CSS should do that. I don’t really care much, and can see arguments both ways.

Here is a tiny test file which has “.txt.” tacked on the end of the filename to make GitHub happy.

Notes [1] LIT is straight double quote (U+0022), LITA is straight single quote (U+0027), sometimes called “pop”, short for “apostrophe” I presume, from the days before ’ (U+2019) was apostrophe.

sydb commented 2 years ago

Addendum: same is true of the <tag> element. Except that its output should have pointy brackets, etc., based on the value of @type; and probably the value of @scheme should be reflected in the output @class somehow. So in retrospect, maybe this should have been a different ticket. Sigh.

sydb commented 1 year ago

BTW, in today’s Stylesheets group discussion I alluded to doing this as a “combined” template. What I meant was something like

  <xsl:template match="tei:gi | tei:att | tei:val | tei:tag">
    <span class="{local-name(.)}">
      <xsl:variable name="start_delimiter">
        <xsl:choose>
          <xsl:when test="self::tei:gi">&lt;</xsl:when>
          <xsl:when test="self::tei:att">@</xsl:when>
          <xsl:when test="self::tei:val">"</xsl:when>
          <xsl:when test="self::tei:tag[@type eq 'start']">&lt;</xsl:when>
          <xsl:when test="self::tei:tag[@type eq 'end']">&lt;/</xsl:when>
          <xsl:when test="self::tei:tag[@type eq 'empty']">&lt;</xsl:when>
          <xsl:when test="self::tei:tag[@type eq 'pi']">&lt;?</xsl:when>
          <xsl:when test="self::tei:tag[@type eq 'comment']">&lt;!--</xsl:when>
          <xsl:when test="self::tei:tag[@type eq 'ms']">&lt;[CDATA[</xsl:when>
          <xsl:when test="self::tei:tag[ not( @type ) ]">&lt;</xsl:when>
        </xsl:choose>
      </xsl:variable>
      <xsl:variable name="end_delimiter">
        <xsl:choose>
          <xsl:when test="self::tei:gi">&gt;</xsl:when>
          <xsl:when test="self::tei:att"></xsl:when>
          <xsl:when test="self::tei:val">"</xsl:when>
          <xsl:when test="self::tei:tag[@type eq 'start']">&gt;</xsl:when>
          <xsl:when test="self::tei:tag[@type eq 'end']">&gt;</xsl:when>
          <xsl:when test="self::tei:tag[@type eq 'empty']">/&gt;</xsl:when>
          <xsl:when test="self::tei:tag[@type eq 'pi']">?&gt;</xsl:when>
          <xsl:when test="self::tei:tag[@type eq 'comment']">--&gt;</xsl:when>
          <xsl:when test="self::tei:tag[@type eq 'ms']">]]&gt;</xsl:when>
          <xsl:when test="self::tei:tag[ not( @type ) ]">&gt;</xsl:when>
        </xsl:choose>
      </xsl:variable>
      <xsl:sequence select="$start_delimiter"/>
      <xsl:apply-templates/>
      <xsl:sequence select="$end_delimiter"/>
    </span>
  </xsl:template>

If we were using XSLT 3, could make this somewhat more compact using a map:

  <xsl:template match="tei:gi | tei:att | tei:val | tei:tag">
    <xsl:variable name="delimiters" as="map( xs:string, xs:string )">
      <xsl:map>
        <xsl:map-entry key="'startgi'"         select="'&lt;'"       />
        <xsl:map-entry key="'startatt'"        select="'@'"          />
        <xsl:map-entry key="'startval'"        select="'&quot;'"     />
        <xsl:map-entry key="'starttagstart'"   select="'&lt;'"       />
        <xsl:map-entry key="'starttagend'"     select="'&lt;/'"      />
        <xsl:map-entry key="'starttagempty'"   select="'&lt;'"       />
        <xsl:map-entry key="'starttagpi'"      select="'&lt;?'"      />
        <xsl:map-entry key="'starttagcomment'" select="'&lt;!--'"    />
        <xsl:map-entry key="'starttagms'"      select="'&lt;[CDATA['"/>
        <xsl:map-entry key="'starttag'"        select="'&lt;'"       />
        <xsl:map-entry key="'endgi'"           select="'&gt;'"       />
        <xsl:map-entry key="'endatt'"          select="''"           />
        <xsl:map-entry key="'endval'"          select="'&quot;'"     />
        <xsl:map-entry key="'endtagstart'"     select="'&gt;'"       />
        <xsl:map-entry key="'endtagend'"       select="'&gt;'"       />
        <xsl:map-entry key="'endtagempty'"     select="'/&gt;'"      />
        <xsl:map-entry key="'endtagpi'"        select="'?&gt;'"      />
        <xsl:map-entry key="'endtagcomment'"   select="'-->'"        />
        <xsl:map-entry key="'endtagms'"        select="']]>'"        />
        <xsl:map-entry key="'endtag'"          select="'&gt;'"       />
      </xsl:map>
    </xsl:variable>
    <span class="{local-name(.)}">
      <xsl:sequence select="map:get( $delimiters, 'start'||local-name(.)||@type )"/>
      <xsl:apply-templates/>
      <xsl:sequence select="map:get( $delimiters, 'end'  ||local-name(.)||@type )"/>
    </span>
  </xsl:template>

But this stylesheet is in XSLT 2. (Beware — neither of these is remotely well tested.)

joeytakeda commented 1 year ago

I needed some handling for tag for a project, so I am proposing a fix in branch issue_567_val (see commit https://github.com/TEIC/Stylesheets/commit/536039ffb162370046836aa1e57bbc355f0d8cee)

Interestingly, the handling for gi is in html/html_tagdocs.xsl (which is where you'd expect), but att is html_core.xsl (which I think this has something to do with where the makeRendition template is defined). In any case, I've added new templates for tag and val (one for each rather than combined, just to keep things clean) as well as a new named template called makeDelimiter, which wraps the delimiter in a <span> rather than just plain-text so that those delimiters could be targeted if so desired—e.g. if the Guidelines thinks everything ought to be pseudo-elements, then the CSS could be:

:is(.tag, .val) > .delim {
 display:none;
}

.tag.start::before {
  content: "<";
}

.tag.start::after {
 content: ">";
}
joeytakeda commented 11 months ago

Per Stylesheets meeting: with commit fd1172633515771b2e82a930e29b33f37b1074cc , this issue's linked PR (#618) supersedes PR #508 (and should fix #503, too)