Skip to content

Commit 05f7ae2

Browse files
chrispy-snpsjelovirt
authored andcommitted
Support HTML5 attribute group passthrough (dita-ot#4488)
Signed-off-by: chrispy <[email protected]> Signed-off-by: Jarno Elovirta <[email protected]>
1 parent 0e4d777 commit 05f7ae2

File tree

8 files changed

+163
-33
lines changed

8 files changed

+163
-33
lines changed

src/main/plugins/org.dita.html5/xsl/topic.xsl

Lines changed: 81 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ See the accompanying LICENSE file for applicable license.
107107
</xsl:choose>
108108
</xsl:variable>
109109

110-
<xsl:variable name="FILTERDOC"
110+
<xsl:variable name="FILTERDOC" as="document-node()?"
111111
select="if (string-length($FILTERFILEURL) > 0)
112112
then document($FILTERFILEURL, /)
113113
else ()"/>
@@ -1846,35 +1846,7 @@ See the accompanying LICENSE file for applicable license.
18461846
<xsl:apply-templates select="." mode="set-output-class">
18471847
<xsl:with-param name="default" select="string-join($default-output-class, ' ')"/>
18481848
</xsl:apply-templates>
1849-
<xsl:choose>
1850-
<xsl:when test="exists($passthrough-attrs[empty(@att) and empty(@value)])">
1851-
<xsl:variable name="specializations" as="xs:string*">
1852-
<xsl:for-each select="ancestor-or-self::*[@domains][1]/@domains">
1853-
<xsl:analyze-string select="normalize-space(.)" regex="a\(props (.+?)\)">
1854-
<xsl:matching-substring>
1855-
<xsl:sequence select="tokenize(regex-group(1), '\s+')"/>
1856-
</xsl:matching-substring>
1857-
</xsl:analyze-string>
1858-
</xsl:for-each>
1859-
</xsl:variable>
1860-
<xsl:for-each select="@props |
1861-
@audience |
1862-
@platform |
1863-
@product |
1864-
@otherprops |
1865-
@deliveryTarget |
1866-
@*[local-name() = $specializations]">
1867-
<xsl:attribute name="data-{name()}" select="."/>
1868-
</xsl:for-each>
1869-
</xsl:when>
1870-
<xsl:when test="exists($passthrough-attrs)">
1871-
<xsl:for-each select="@*">
1872-
<xsl:if test="$passthrough-attrs[@att = name(current()) and (empty(@val) or (some $v in tokenize(current(), '\s+') satisfies $v = @val))]">
1873-
<xsl:attribute name="data-{name()}" select="."/>
1874-
</xsl:if>
1875-
</xsl:for-each>
1876-
</xsl:when>
1877-
</xsl:choose>
1849+
<xsl:apply-templates select="." mode="create-passthrough-attributes"/>
18781850
</xsl:template>
18791851

18801852
<!-- Set the class attribute on the resulting output element. The default for a class of elements
@@ -1988,6 +1960,85 @@ See the accompanying LICENSE file for applicable license.
19881960
<xsl:attribute name="dir" select="."/>
19891961
</xsl:template>
19901962

1963+
<!-- Create HTML5 data-* passthrough attributes if specified by DITAVAL -->
1964+
<xsl:mode name="create-passthrough-attributes" on-no-match="deep-skip"/>
1965+
1966+
<xsl:template match="*[exists($passthrough-attrs)]" mode="create-passthrough-attributes">
1967+
<!-- Get specialized profiling attribute names, if defined -->
1968+
<xsl:variable name="specialized-attr-names" as="xs:string*">
1969+
<xsl:for-each select="ancestor-or-self::*[@domains][1]/@domains">
1970+
<xsl:analyze-string select="normalize-space(.)" regex="a\(props (.+?)\)">
1971+
<xsl:matching-substring>
1972+
<xsl:sequence select="tokenize(regex-group(1), '\s+')"/>
1973+
</xsl:matching-substring>
1974+
</xsl:analyze-string>
1975+
</xsl:for-each>
1976+
</xsl:variable>
1977+
1978+
<!-- Get all profiling attributes for this element -->
1979+
<xsl:variable name="profiling-attrs" as="attribute()*">
1980+
<xsl:sequence select="@props | @audience | @platform | @product | @otherprops | @deliveryTarget"/>
1981+
<xsl:sequence select="@*[local-name(.) = $specialized-attr-names]"/>
1982+
</xsl:variable>
1983+
1984+
<!-- Ungroup and organize all profiling attribute values for this element. For example, the values for:
1985+
1986+
<p product="v1 grpA(Av2) v3 grpB(Bv3 Bv4)"/>
1987+
1988+
would be stored in an <ATTVAL> element sequence as follows:
1989+
1990+
<ATTVAL att="product" group="product" values="v1"/>
1991+
<ATTVAL att="product" group="product" values="v3"/>
1992+
<ATTVAL att="product" group="grpA" values="Av2"/>
1993+
<ATTVAL att="product" group="grpB" values="Bv3"/>
1994+
<ATTVAL att="product" group="grpB" values="Bv4"/> -->
1995+
<xsl:variable name="all-attvals" as="element()*">
1996+
<xsl:for-each select="$profiling-attrs">
1997+
<xsl:variable name="attr-name" select="local-name(.)"/>
1998+
<!-- Regex pattern tries to match "group(val val)" first, "val" second -->
1999+
<xsl:analyze-string select="." regex="([^\s(]+)\(([^)]*)\)|(\S+)">
2000+
<xsl:matching-substring>
2001+
<xsl:choose>
2002+
<xsl:when test="regex-group(1) and regex-group(2)">
2003+
<!-- Explicit group value: @att="group(val val)" -->
2004+
<xsl:for-each select="tokenize(regex-group(2))">
2005+
<ATTVAL att="{$attr-name}" group="{regex-group(1)}" val="{.}"/>
2006+
</xsl:for-each>
2007+
</xsl:when>
2008+
<xsl:when test="regex-group(3)">
2009+
<!-- Implicit group value: @att="val" (group name is attribute name)-->
2010+
<ATTVAL att="{$attr-name}" group="{$attr-name}" val="{regex-group(3)}"/>
2011+
</xsl:when>
2012+
</xsl:choose>
2013+
</xsl:matching-substring>
2014+
</xsl:analyze-string>
2015+
</xsl:for-each>
2016+
</xsl:variable>
2017+
2018+
<!-- Get all <ATTVAL> entries that match passthrough actions. An <ATTVAL> entry matches if:
2019+
2020+
* A passthrough action exists without an @att value (matches all attributes)
2021+
* A passthrough action exists with an @att value matching the <ATTVAL> @att or @group value, and
2022+
* The passthrough action has no @val value (matches all values), or
2023+
* The passthrough action has a @val value that matches the <ATTVAL> @val value -->
2024+
<xsl:variable name="matching-attvals" as="element()*">
2025+
<xsl:for-each select="$all-attvals">
2026+
<xsl:variable name="attval" select="."/>
2027+
<xsl:if test="$passthrough-attrs[empty(@att) or (@att = $attval/(@att, @group) and (empty(@val) or @val = $attval/@val))]">
2028+
<xsl:sequence select="$attval"/>
2029+
</xsl:if>
2030+
</xsl:for-each>
2031+
</xsl:variable>
2032+
2033+
<!-- Create HTML5 data-* passthrough attributes.
2034+
2035+
Passthrough attributes are always named by group name (implicit or explicit) regardless of
2036+
how their values were matched by passthrough actions. -->
2037+
<xsl:for-each-group select="$matching-attvals" group-by="@group">
2038+
<xsl:attribute name="data-{current-grouping-key()}" select="sort(distinct-values(current-group()/@val))"/>
2039+
</xsl:for-each-group>
2040+
</xsl:template>
2041+
19912042
<xsl:template name="setscale">
19922043
<xsl:if test="@scale">
19932044
<!-- <xsl:attribute name="style">font-size: <xsl:value-of select="@scale"/>%;</xsl:attribute> -->

src/test/java/org/dita/dost/IntegrationTestHtml5.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,17 @@ public void html5_ditaval_passthrough_all() throws Throwable {
116116
.warnCount(1)
117117
.test();
118118
}
119+
120+
@Test
121+
public void html5_ditaval_passthrough_groups_all() throws Throwable {
122+
final File srcDir = new File(resourceDir, "html5_ditaval_groups" + File.separator + "src");
123+
builder()
124+
.name("html5_ditaval_groups")
125+
.transtype(HTML5)
126+
.input(Paths.get("all.ditamap"))
127+
.put("validate", "no")
128+
.put("dita.input.valfile", new File(srcDir, "all.ditaval").getAbsolutePath())
129+
.warnCount(1)
130+
.test();
131+
}
119132
}

src/test/resources/html5_ditaval/exp/html5/all.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ <h1 class="title topictitle1" id="ariaid-title1">Topic title</h1>
1515
<div class="body">
1616
<p class="p" data-audience="expert" data-deliveryTarget="print" data-platform="intel"
1717
data-product="notepad" data-os="win"></p>
18-
<p class="p"
19-
data-props="audience(expert) deliveryTarget(print) platform(intel) product(notepad) os(win)"
20-
></p>
18+
<p class="p" data-audience="expert" data-deliveryTarget="print" data-platform="intel"
19+
data-product="notepad" data-os="win"></p>
2120
</div>
2221
</article>
2322
</main>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html
2+
SYSTEM "about:legacy-compat">
3+
<html lang="en">
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="copyright" content="(C) Copyright 2021">
7+
<meta name="generator" content="DITA-OT">
8+
<title>Topic title</title>
9+
<link rel="stylesheet" type="text/css" href="commonltr.css">
10+
</head>
11+
<body id="topic-1">
12+
<main role="main">
13+
<article role="article" aria-labelledby="ariaid-title1">
14+
<h1 class="title topictitle1" id="ariaid-title1">Topic title</h1>
15+
<div class="body">
16+
<p class="p" data-group1="val1-1 val1-2 val1-3"></p>
17+
<p class="p" data-group2="val2-1 val2-3"></p>
18+
<p class="p" data-group3="val3-1 val3-3"></p>
19+
</div>
20+
</article>
21+
</main>
22+
</body>
23+
</html>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html
2+
SYSTEM "about:legacy-compat">
3+
<html lang="en">
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="copyright" content="(C) Copyright 2021">
7+
<meta name="generator" content="DITA-OT">
8+
<title></title>
9+
<link rel="stylesheet" type="text/css" href="commonltr.css">
10+
</head>
11+
<body>
12+
<nav>
13+
<ul class="map">
14+
<li class="topicref">
15+
<a href="all.html">Topic title</a>
16+
</li>
17+
</ul>
18+
</nav>
19+
</body>
20+
</html>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version='1.0' encoding='UTF-8'?>
2+
<!DOCTYPE topic PUBLIC "-//OASIS//DTD DITA Topic//EN" "topic.dtd">
3+
<topic id="topic-1"
4+
domains="(topic abbrev-d) a(props deliveryTarget) (topic equation-d) (topic hazard-d) (topic hi-d) (topic indexing-d) (topic markup-d) (topic mathml-d) (topic pr-d) (topic relmgmt-d) (topic sw-d) (topic svg-d) (topic ui-d) (topic ut-d) a(props os) (topic markup-d xml-d)">
5+
<title>Topic title</title>
6+
<body>
7+
<p product="group1(val1-3 val1-2) foo(bar) group1(val1-1) baz"/>
8+
<p product="group2(val2-3 val2-2) foo(bar) group2(val2-1) baz"/>
9+
<p product="group3(val3-3 val3-2) foo(bar) group3(val3-1) baz"/>
10+
</body>
11+
</topic>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd">
3+
<map>
4+
<topicref href="all.dita"/>
5+
</map>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<val>
3+
<prop att="group1" action="passthrough"/>
4+
<prop att="group2" val="val2-3" action="passthrough"/>
5+
<prop att="group2" val="val2-1" action="passthrough"/>
6+
<prop att="product" val="val3-3" action="passthrough"/>
7+
<prop att="product" val="val3-1" action="passthrough"/>
8+
</val>

0 commit comments

Comments
 (0)