如何更改内联元素的前景色和背景色?

How to change both foreground and background color for an inline element?

我正在尝试更改内联元素的前景色和背景色。 文档片段是这样的:

<command role=" f00 b01 ">Lorem Ipsum</command>

我的自定义层中的 XSL 部分是这样的:

[...]
<xsl:template match='db:command[contains(@role, " f00 ")]'>
<fo:inline color='#000000'><xsl:apply-templates/></fo:inline>
</xsl:template>
<xsl:template match='db:command[contains(@role, " b00 ")]'>
<fo:inline background-color='#000000'><xsl:apply-templates/></fo:inline>
</xsl:template>
[255 x 6 more lines, for each fXX and bXX where X is a hex digit
  and the colors are the 256 xterm RGB color specs.]

这只会更改背景颜色或前景色,具体取决于最后一个模板。

角色值为f00 b01时,如何同时应用前景和背景? 注意:不能像 contains " f00 b01 " 那样进行第三次测试,因为有 256 种颜色可供选择,并且指定所有组合会使模板数量激增。

注意:已编辑以更接近实际文件内容

xterm颜色到rgb颜色的映射如下。从颜色 16 开始,它们可以用一个小的 perl 脚本计算(摘自 xterm distruibution 的片段):

# colors 16-231 are a 6x6x6 color cube
for ($red = 0; $red < 6; $red++) {
    for ($green = 0; $green < 6; $green++) {
        for ($blue = 0; $blue < 6; $blue++) {
            $code = 16 + ($red * 36) + ($green * 6) + $blue;
            printf($line1, $code);
            printf($line2, $code);
            printf($line3,
                   ($red ? ($red * 40 + 55) : 0),
                   ($green ? ($green * 40 + 55) : 0),
                   ($blue ? ($blue * 40 + 55) : 0));
        }
    }
}

# colors 232-255 are a grayscale ramp, intentionally leaving out
# black and white
$code=232;
for ($gray = 0; $gray < 24; $gray++) {
    $level = ($gray * 10) + 8;
    $code = 232 + $gray;
    printf($line1, $code);
    printf($line2, $code);
    printf($line3,
           $level, $level, $level);
}

结果:

00 #000000  80 #af00d7 
01 #cd0000  81 #af00ff 
02 #00cd00  82 #af5f00 
03 #cdcd00  83 #af5f5f 
04 #0000ee  84 #af5f87 
05 #cd00cd  85 #af5faf 
06 #00cdcd  86 #af5fd7 
07 #e5e5e5  87 #af5fff 
08 #7f7f7f  88 #af8700 
09 #ff0000  89 #af875f 
0a #00ff00  8a #af8787 
0b #ffff00  8b #af87af 
0c #5c5cff  8c #af87d7 
0d #ff00ff  8d #af87ff 
0e #00ffff  8e #afaf00 
0f #ffffff  8f #afaf5f 
10 #000000  90 #afaf87 
11 #00005f  91 #afafaf 
12 #000087  92 #afafd7 
13 #0000af  93 #afafff 
14 #0000d7  94 #afd700 
15 #0000ff  95 #afd75f 
16 #005f00  96 #afd787 
17 #005f5f  97 #afd7af 
18 #005f87  98 #afd7d7 
19 #005faf  99 #afd7ff 
1a #005fd7  9a #afff00 
1b #005fff  9b #afff5f 
1c #008700  9c #afff87 
1d #00875f  9d #afffaf 
1e #008787  9e #afffd7 
1f #0087af  9f #afffff 
20 #0087d7  a0 #d70000 
21 #0087ff  a1 #d7005f 
22 #00af00  a2 #d70087 
23 #00af5f  a3 #d700af 
24 #00af87  a4 #d700d7 
25 #00afaf  a5 #d700ff 
26 #00afd7  a6 #d75f00 
27 #00afff  a7 #d75f5f 
28 #00d700  a8 #d75f87 
29 #00d75f  a9 #d75faf 
2a #00d787  aa #d75fd7 
2b #00d7af  ab #d75fff 
2c #00d7d7  ac #d78700 
2d #00d7ff  ad #d7875f 
2e #00ff00  ae #d78787 
2f #00ff5f  af #d787af 
30 #00ff87  b0 #d787d7 
31 #00ffaf  b1 #d787ff 
32 #00ffd7  b2 #d7af00 
33 #00ffff  b3 #d7af5f 
34 #5f0000  b4 #d7af87 
35 #5f005f  b5 #d7afaf 
36 #5f0087  b6 #d7afd7 
37 #5f00af  b7 #d7afff 
38 #5f00d7  b8 #d7d700 
39 #5f00ff  b9 #d7d75f 
3a #5f5f00  ba #d7d787 
3b #5f5f5f  bb #d7d7af 
3c #5f5f87  bc #d7d7d7 
3d #5f5faf  bd #d7d7ff 
3e #5f5fd7  be #d7ff00 
3f #5f5fff  bf #d7ff5f 
40 #5f8700  c0 #d7ff87 
41 #5f875f  c1 #d7ffaf 
42 #5f8787  c2 #d7ffd7 
43 #5f87af  c3 #d7ffff 
44 #5f87d7  c4 #ff0000 
45 #5f87ff  c5 #ff005f 
46 #5faf00  c6 #ff0087 
47 #5faf5f  c7 #ff00af 
48 #5faf87  c8 #ff00d7 
49 #5fafaf  c9 #ff00ff 
4a #5fafd7  ca #ff5f00 
4b #5fafff  cb #ff5f5f 
4c #5fd700  cc #ff5f87 
4d #5fd75f  cd #ff5faf 
4e #5fd787  ce #ff5fd7 
4f #5fd7af  cf #ff5fff 
50 #5fd7d7  d0 #ff8700 
51 #5fd7ff  d1 #ff875f 
52 #5fff00  d2 #ff8787 
53 #5fff5f  d3 #ff87af 
54 #5fff87  d4 #ff87d7 
55 #5fffaf  d5 #ff87ff 
56 #5fffd7  d6 #ffaf00 
57 #5fffff  d7 #ffaf5f 
58 #870000  d8 #ffaf87 
59 #87005f  d9 #ffafaf 
5a #870087  da #ffafd7 
5b #8700af  db #ffafff 
5c #8700d7  dc #ffd700 
5d #8700ff  dd #ffd75f 
5e #875f00  de #ffd787 
5f #875f5f  df #ffd7af 
60 #875f87  e0 #ffd7d7 
61 #875faf  e1 #ffd7ff 
62 #875fd7  e2 #ffff00 
63 #875fff  e3 #ffff5f 
64 #878700  e4 #ffff87 
65 #87875f  e5 #ffffaf 
66 #878787  e6 #ffffd7 
67 #8787af  e7 #ffffff 
68 #8787d7  e8 #080808 
69 #8787ff  e9 #121212 
6a #87af00  ea #1c1c1c 
6b #87af5f  eb #262626 
6c #87af87  ec #303030 
6d #87afaf  ed #3a3a3a 
6e #87afd7  ee #444444 
6f #87afff  ef #4e4e4e 
70 #87d700  f0 #585858 
71 #87d75f  f1 #626262 
72 #87d787  f2 #6c6c6c 
73 #87d7af  f3 #767676 
74 #87d7d7  f4 #808080 
75 #87d7ff  f5 #8a8a8a 
76 #87ff00  f6 #949494 
77 #87ff5f  f7 #9e9e9e 
78 #87ff87  f8 #a8a8a8 
79 #87ffaf  f9 #b2b2b2 
7a #87ffd7  fa #bcbcbc 
7b #87ffff  fb #c6c6c6 
7c #af0000  fc #d0d0d0 
7d #af005f  fd #dadada 
7e #af0087  fe #e4e4e4 
7f #af00af  ff #eeeeee 

首先,是的,如果 XSLT 样式表中存在不明确的规则匹配,则选择最新的(即最后一个)模板。


这个答案的大部分内容完全是猜测,因为我们没有看到太多输入或 XSLT 代码。但似乎单独的模板不太适合处理这个问题。

一般匹配db:command然后使用xsl:if如何?

XML 输入

<db:command xmlns:db="http://docbook.org/ns/docbook" role=" fgRed bgGreen ">Lorem Ipsum</db:command>

XSLT 样式表

我做了以下假设:

  • db:command 本身的存在意味着 fo:inline 应该在输出中
  • bgfg 之后的(小写)颜色名称是符合 XSL-FO 规范的颜色

完整示例:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:db="http://docbook.org/ns/docbook"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="xml"  omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:template match="db:command">
        <fo:inline>
                <xsl:if test="contains(@role, 'bg')">
                    <xsl:attribute name="background-color">
                        <xsl:value-of select="translate(substring-before(substring-after(@role,'bg'),' '),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghjiklmnopqrstuvwxyz')"/>
                    </xsl:attribute>
                </xsl:if>
                <xsl:if test="contains(@role, 'fg')">
                    <xsl:attribute name="color">
                        <xsl:value-of select="translate(substring-before(substring-after(@role,'fg'),' '),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghjiklmnopqrstuvwxyz')"/>
                    </xsl:attribute>
                </xsl:if>
                <!--Add more if conditions for any other formatting style-->
        </fo:inline>
    </xsl:template>

</xsl:transform>

XML输出

<fo:inline xmlns:db="http://docbook.org/ns/docbook"
           xmlns:fo="http://www.w3.org/1999/XSL/Format"
           background-color="green"
           color="red"/>

编辑:经过我们的讨论,代码的另一个版本。

XML 输入

输入 XML 现在是:

<db:command xmlns:db="http://docbook.org/ns/docbook" role=" f00 b01 ">Lorem Ipsum</db:command>

XSLT 1.0 样式表(需要 EXSLT)

样式表使用EXSLT的str:tokenize()功能,但我已经用我的xsltproc版本测试过,支持此功能。

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:db="http://docbook.org/ns/docbook"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">

    <xsl:output method="xml"  omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:template match="db:command">
        <fo:inline>
            <xsl:for-each select="str:tokenize(@role,' ')">
                <xsl:if test="contains(.,'f')">
                    <xsl:attribute name="color">
                        <xsl:if test="substring-after(.,'f') = '00'">
                            <xsl:value-of select="'#000000'"/>
                        </xsl:if>
                        <!--Other possible values-->
                    </xsl:attribute>
                </xsl:if>
                <xsl:if test="contains(.,'b')">
                    <xsl:attribute name="background-color">
                        <xsl:if test="substring-after(.,'b') = '01'">
                            <xsl:value-of select="'#000000'"/>
                        </xsl:if>
                        <!--Other possible values-->
                    </xsl:attribute>
                </xsl:if>
            </xsl:for-each>
            <xsl:apply-templates/>
        </fo:inline>
    </xsl:template>

    <xsl:template match="text()">
        <xsl:copy/>
    </xsl:template>
</xsl:transform>

XSL-FO 输出

<fo:inline xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:db="http://docbook.org/ns/docbook" color="#000000" background-color="#000000">Lorem Ipsum</fo:inline>

首先也是最重要的:如果您是源文档的作者,您应该为每个……好吧,属性使用一个单独的属性,这样可以避免使用笨拙的字符串操作来提取各个值的痛苦。这就是 XML 的意义所在。

其次,使用 2 x 256 模板的想法是荒谬的。您只需要提取表示 xterm 颜色的两个十六进制数字代码并将它们转换为#rrggb 格式。

尽管如此,提取过程(如果属性是分开的,则根本不需要)并不那么困难。给定:

<command role=" f00 b01 ">Lorem Ipsum</command>

您可以使用:

<xsl:template match="command">
    <xsl:variable name="fg" select="substring-before(substring-after(@role, ' f'), ' ')" />
    <xsl:variable name="bg" select="substring-before(substring-after(@role, ' b'), ' ')" />
    <!--  -->
</xsl:template>

现在您只需要将提取的xterm 代码转换为rgb。您没有说这些代码最初是如何导出的。我怀疑这可以反向计算,但如果这不可能或不方便,请使用外部 XML 文档(或内部变量)进行查找。


这是一个从内部变量查找的示例:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="command">
    <xsl:variable name="fg" select="substring-before(substring-after(@role, ' f'), ' ')" />
    <xsl:variable name="bg" select="substring-before(substring-after(@role, ' b'), ' ')" />

    <xsl:variable name="color-set" select="exsl:node-set($colors)/color" />

    <xsl:variable name="color" select="$color-set[@code=$fg]" />
    <xsl:variable name="background-color" select="$color-set[@code=$bg]" />
    <!--  -->   
</xsl:template>

<xsl:variable name="colors">
    <color code="00">#000000</color>
    <color code="01">#cd0000</color>
    <color code="02">#00cd00</color>
    <color code="03">#cdcd00</color>
    <color code="04">#0000ee</color>
    <color code="05">#cd00cd</color>
    <color code="06">#00cdcd</color>
    <color code="07">#e5e5e5</color>
    <color code="08">#7f7f7f</color>
    <color code="09">#ff0000</color>
    <color code="0a">#00ff00</color>
    <color code="0b">#ffff00</color>
    <color code="0c">#5c5cff</color>
    <color code="0d">#ff00ff</color>
    <color code="0e">#00ffff</color>
    <color code="0f">#ffffff</color>
    <color code="10">#000000</color>
    <color code="11">#00005f</color>
    <color code="12">#000087</color>
    <color code="13">#0000af</color>
    <color code="14">#0000d7</color>
    <color code="15">#0000ff</color>
    <color code="16">#005f00</color>
    <color code="17">#005f5f</color>
    <color code="18">#005f87</color>
    <color code="19">#005faf</color>
    <color code="1a">#005fd7</color>
    <color code="1b">#005fff</color>
    <color code="1c">#008700</color>
    <color code="1d">#00875f</color>
    <color code="1e">#008787</color>
    <color code="1f">#0087af</color>
    <color code="20">#0087d7</color>
    <color code="21">#0087ff</color>
    <color code="22">#00af00</color>
    <color code="23">#00af5f</color>
    <color code="24">#00af87</color>
    <color code="25">#00afaf</color>
    <color code="26">#00afd7</color>
    <color code="27">#00afff</color>
    <color code="28">#00d700</color>
    <color code="29">#00d75f</color>
    <color code="2a">#00d787</color>
    <color code="2b">#00d7af</color>
    <color code="2c">#00d7d7</color>
    <color code="2d">#00d7ff</color>
    <color code="2e">#00ff00</color>
    <color code="2f">#00ff5f</color>
    <color code="30">#00ff87</color>
    <color code="31">#00ffaf</color>
    <color code="32">#00ffd7</color>
    <color code="33">#00ffff</color>
    <color code="34">#5f0000</color>
    <color code="35">#5f005f</color>
    <color code="36">#5f0087</color>
    <color code="37">#5f00af</color>
    <color code="38">#5f00d7</color>
    <color code="39">#5f00ff</color>
    <color code="3a">#5f5f00</color>
    <color code="3b">#5f5f5f</color>
    <color code="3c">#5f5f87</color>
    <color code="3d">#5f5faf</color>
    <color code="3e">#5f5fd7</color>
    <color code="3f">#5f5fff</color>
    <color code="40">#5f8700</color>
    <color code="41">#5f875f</color>
    <color code="42">#5f8787</color>
    <color code="43">#5f87af</color>
    <color code="44">#5f87d7</color>
    <color code="45">#5f87ff</color>
    <color code="46">#5faf00</color>
    <color code="47">#5faf5f</color>
    <color code="48">#5faf87</color>
    <color code="49">#5fafaf</color>
    <color code="4a">#5fafd7</color>
    <color code="4b">#5fafff</color>
    <color code="4c">#5fd700</color>
    <color code="4d">#5fd75f</color>
    <color code="4e">#5fd787</color>
    <color code="4f">#5fd7af</color>
    <color code="50">#5fd7d7</color>
    <color code="51">#5fd7ff</color>
    <color code="52">#5fff00</color>
    <color code="53">#5fff5f</color>
    <color code="54">#5fff87</color>
    <color code="55">#5fffaf</color>
    <color code="56">#5fffd7</color>
    <color code="57">#5fffff</color>
    <color code="58">#870000</color>
    <color code="59">#87005f</color>
    <color code="5a">#870087</color>
    <color code="5b">#8700af</color>
    <color code="5c">#8700d7</color>
    <color code="5d">#8700ff</color>
    <color code="5e">#875f00</color>
    <color code="5f">#875f5f</color>
    <color code="60">#875f87</color>
    <color code="61">#875faf</color>
    <color code="62">#875fd7</color>
    <color code="63">#875fff</color>
    <color code="64">#878700</color>
    <color code="65">#87875f</color>
    <color code="66">#878787</color>
    <color code="67">#8787af</color>
    <color code="68">#8787d7</color>
    <color code="69">#8787ff</color>
    <color code="6a">#87af00</color>
    <color code="6b">#87af5f</color>
    <color code="6c">#87af87</color>
    <color code="6d">#87afaf</color>
    <color code="6e">#87afd7</color>
    <color code="6f">#87afff</color>
    <color code="70">#87d700</color>
    <color code="71">#87d75f</color>
    <color code="72">#87d787</color>
    <color code="73">#87d7af</color>
    <color code="74">#87d7d7</color>
    <color code="75">#87d7ff</color>
    <color code="76">#87ff00</color>
    <color code="77">#87ff5f</color>
    <color code="78">#87ff87</color>
    <color code="79">#87ffaf</color>
    <color code="7a">#87ffd7</color>
    <color code="7b">#87ffff</color>
    <color code="7c">#af0000</color>
    <color code="7d">#af005f</color>
    <color code="7e">#af0087</color>
    <color code="7f">#af00af</color>
    <color code="80">#af00d7</color>
    <color code="81">#af00ff</color>
    <color code="82">#af5f00</color>
    <color code="83">#af5f5f</color>
    <color code="84">#af5f87</color>
    <color code="85">#af5faf</color>
    <color code="86">#af5fd7</color>
    <color code="87">#af5fff</color>
    <color code="88">#af8700</color>
    <color code="89">#af875f</color>
    <color code="8a">#af8787</color>
    <color code="8b">#af87af</color>
    <color code="8c">#af87d7</color>
    <color code="8d">#af87ff</color>
    <color code="8e">#afaf00</color>
    <color code="8f">#afaf5f</color>
    <color code="90">#afaf87</color>
    <color code="91">#afafaf</color>
    <color code="92">#afafd7</color>
    <color code="93">#afafff</color>
    <color code="94">#afd700</color>
    <color code="95">#afd75f</color>
    <color code="96">#afd787</color>
    <color code="97">#afd7af</color>
    <color code="98">#afd7d7</color>
    <color code="99">#afd7ff</color>
    <color code="9a">#afff00</color>
    <color code="9b">#afff5f</color>
    <color code="9c">#afff87</color>
    <color code="9d">#afffaf</color>
    <color code="9e">#afffd7</color>
    <color code="9f">#afffff</color>
    <color code="a0">#d70000</color>
    <color code="a1">#d7005f</color>
    <color code="a2">#d70087</color>
    <color code="a3">#d700af</color>
    <color code="a4">#d700d7</color>
    <color code="a5">#d700ff</color>
    <color code="a6">#d75f00</color>
    <color code="a7">#d75f5f</color>
    <color code="a8">#d75f87</color>
    <color code="a9">#d75faf</color>
    <color code="aa">#d75fd7</color>
    <color code="ab">#d75fff</color>
    <color code="ac">#d78700</color>
    <color code="ad">#d7875f</color>
    <color code="ae">#d78787</color>
    <color code="af">#d787af</color>
    <color code="b0">#d787d7</color>
    <color code="b1">#d787ff</color>
    <color code="b2">#d7af00</color>
    <color code="b3">#d7af5f</color>
    <color code="b4">#d7af87</color>
    <color code="b5">#d7afaf</color>
    <color code="b6">#d7afd7</color>
    <color code="b7">#d7afff</color>
    <color code="b8">#d7d700</color>
    <color code="b9">#d7d75f</color>
    <color code="ba">#d7d787</color>
    <color code="bb">#d7d7af</color>
    <color code="bc">#d7d7d7</color>
    <color code="bd">#d7d7ff</color>
    <color code="be">#d7ff00</color>
    <color code="bf">#d7ff5f</color>
    <color code="c0">#d7ff87</color>
    <color code="c1">#d7ffaf</color>
    <color code="c2">#d7ffd7</color>
    <color code="c3">#d7ffff</color>
    <color code="c4">#ff0000</color>
    <color code="c5">#ff005f</color>
    <color code="c6">#ff0087</color>
    <color code="c7">#ff00af</color>
    <color code="c8">#ff00d7</color>
    <color code="c9">#ff00ff</color>
    <color code="ca">#ff5f00</color>
    <color code="cb">#ff5f5f</color>
    <color code="cc">#ff5f87</color>
    <color code="cd">#ff5faf</color>
    <color code="ce">#ff5fd7</color>
    <color code="cf">#ff5fff</color>
    <color code="d0">#ff8700</color>
    <color code="d1">#ff875f</color>
    <color code="d2">#ff8787</color>
    <color code="d3">#ff87af</color>
    <color code="d4">#ff87d7</color>
    <color code="d5">#ff87ff</color>
    <color code="d6">#ffaf00</color>
    <color code="d7">#ffaf5f</color>
    <color code="d8">#ffaf87</color>
    <color code="d9">#ffafaf</color>
    <color code="da">#ffafd7</color>
    <color code="db">#ffafff</color>
    <color code="dc">#ffd700</color>
    <color code="dd">#ffd75f</color>
    <color code="de">#ffd787</color>
    <color code="df">#ffd7af</color>
    <color code="e0">#ffd7d7</color>
    <color code="e1">#ffd7ff</color>
    <color code="e2">#ffff00</color>
    <color code="e3">#ffff5f</color>
    <color code="e4">#ffff87</color>
    <color code="e5">#ffffaf</color>
    <color code="e6">#ffffd7</color>
    <color code="e7">#ffffff</color>
    <color code="e8">#080808</color>
    <color code="e9">#121212</color>
    <color code="ea">#1c1c1c</color>
    <color code="eb">#262626</color>
    <color code="ec">#303030</color>
    <color code="ed">#3a3a3a</color>
    <color code="ee">#444444</color>
    <color code="ef">#4e4e4e</color>
    <color code="f0">#585858</color>
    <color code="f1">#626262</color>
    <color code="f2">#6c6c6c</color>
    <color code="f3">#767676</color>
    <color code="f4">#808080</color>
    <color code="f5">#8a8a8a</color>
    <color code="f6">#949494</color>
    <color code="f7">#9e9e9e</color>
    <color code="f8">#a8a8a8</color>
    <color code="f9">#b2b2b2</color>
    <color code="fa">#bcbcbc</color>
    <color code="fb">#c6c6c6</color>
    <color code="fc">#d0d0d0</color>
    <color code="fd">#dadada</color>
    <color code="fe">#e4e4e4</color>
    <color code="ff">#eeeeee</color>
</xsl:variable>

</xsl:stylesheet>