应用自定义样式表

到目前为止,我们讨论了使用默认样式表的各种方法。您可以指示 Asciidoctor 使用您选择的自定义样式表来代替默认样式表。在本页上,您将了解如何应用自定义样式表,以及在必要时如何让 Asciidoctor 将该样式表复制并链接到正确的位置。您还将了解在处理多个文档时此功能的某些限制。

指定自定义样式表

Asciidoctor 会查找 `stylesheet` 文档属性指定样式表文件。如果此属性的值为空(默认),Asciidoctor 则使用默认样式表。否则,Asciidoctor 假定该值为相对于源文档的自定义样式表文件的路径。在《样式表模式》中描述的所有行为均仍然适用,只是 Asciidoctor 使用指定的样式表代替了默认样式表。

首先,您必须创建一个样式表文件。现在,请将此文件创建在您的 AsciiDoc 文档旁边。为了简单起见,我们将定义一个将所有文本更改为红色的基本样式表。在与您的 AsciiDoc 源文件相同的目录中创建文件 my-stylesheet.css,并填充以下内容:

示例 1. my-stylesheet.css
body {
  color: #ff0000;
}

现在,让我们使用 `stylesheet` 属性来应用它。

`stylesheet` 文档属性必须在页眉结束前设置才能生效。一种方法是在文档页眉中设置该属性:

示例 2. 在文档页眉中设置 stylesheet 属性
= The Dangers of Wolpertingers
:url-wolpertinger: https://en.wikipedia.org/wiki/Wolpertinger
:stylesheet: my-stylesheet.css

Don't worry about gumberoos or splintercats.
Something far more fearsome plagues the days, nights, and inbetweens.
Wolpertingers.

== Origins

Wolpertingers are {url-wolpertinger}[ravenous beasts].

您还可以使用 API 或 CLI(此处显示)设置 `stylesheet`:

$ asciidoctor -a stylesheet=my-stylesheet.css my-document.adoc

当您在浏览器中查看生成的 HTML 文件 my-document.html 时,您会看到所有文本都是红色的。

如果您想通过扩展默认样式表来创建自定义样式表,请参阅 扩展默认样式表

与默认样式表一样,您可以设置 `linkcss` 文档属性,Asciidoctor 会改为链接到您的样式表。(请注意,在这种情况下,由于它已与输出文件在同一文件夹中,因此不会复制它)。

$ asciidoctor -a stylesheet=my-stylesheet.css -a linkcss my-document.adoc

您可能不想将样式表保留在与 AsciiDoc 文档相同的目录中。让我们看看如何告诉 Asciidoctor 在其他地方查找它。

配置样式目录

当您的样式表位于 AsciiDoc 文档下方的目录中时,您需要告诉 Asciidoctor 在哪里查找样式表。有两种等效的方法可以做到这一点:

  • 使用 `stylesheet` 属性指定样式表文件的名称,并使用 `stylesdir` 属性指定其位置所在的目录。

  • 在 `stylesheet` 属性的值中包含样式表所在的目录(而不是使用 `stylesdir` 属性)。

`stylesdir` 属性的值可以以斜杠(`/`)结尾,但这不是必需的。

如果未设置 `linkcss` 属性,则样式目录可以是相对路径或绝对路径。当 `linkcss` 设置时,情况会变得更复杂,我们将在 稍后进行介绍。

假设您想将样式表放在相对于您的 AsciiDoc 文档的 my-styles 文件夹中。请创建该文件夹,并将您的自定义样式表移动到其中以供本示例使用。现在,我们需要使用 `stylesdir` 告诉 Asciidoctor 它的位置。

`stylesdir` 文档属性必须在页眉结束前设置才能生效。一种方法是在文档页眉中设置该属性:

示例 3. 在文档页眉中设置 stylesdir 属性
= The Dangers of Wolpertingers
:url-wolpertinger: https://en.wikipedia.org/wiki/Wolpertinger
:stylesheet: my-stylesheet.css
:stylesdir: my-styles

Don't worry about gumberoos or splintercats.
Something far more fearsome plagues the days, nights, and inbetweens.
Wolpertingers.

== Origins

Wolpertingers are {url-wolpertinger}[ravenous beasts].

您还可以使用 API 或 CLI(此处显示)设置 `stylesdir`:

$ asciidoctor -a stylesdir=my-styles -a stylesheet=my-stylesheet.css my-document.adoc

Asciidoctor 现在会在相对于 AsciiDoc 文档的位置查找样式表文件 my-styles/my-stylesheet.css,并将其嵌入到 HTML 中。

您可以通过在 `stylesheet` 属性的值中包含目录来达到相同的效果:

$ asciidoctor -a stylesheet=my-styles/my-stylesheet.css my-document.adoc

如果您将 `stylesdir` 的值设置为绝对目录,则 Asciidoctor 仍然可以找到样式表并将其嵌入到 HTML 中。但这可能会在您将转换器配置为链接到样式表时引起问题。让我们看看这些问题以及解决方法。

样式目录和 linkcss

当您链接到样式表而不是嵌入它时,使用 `stylesdir` 会变得复杂。这是因为我们现在处理的是两个不同的路径。一个是样式表在磁盘上的位置(绝对路径或相对于文档的路径)。另一个是浏览器用来访问样式表的路径。

首先,重要的是要理解 Asciidoctor 会镜像 `stylesdir` 路径在链接引用中的位置。让我们使用前面的示例来说明。如果您像这样调用 Asciidoctor:

$ asciidoctor -a stylesdir=my-styles -a stylesheet=my-stylesheet.css -a linkcss my-document.adoc

然后,当您检查 HTML 时,您会看到:

<link rel="stylesheet" href="my-styles/asciidoctor.css">

请注意 `stylesdir` 的值(my-styles)是如何包含在引用的路径中的。Asciidoctor 在需要复制样式表文件时也会保留此目录。

在某些情况下,这可能不起作用(至少在将文件发布到公共互联网时)。让我们考虑一种这种情况。我们将 `stylesdir` 的位置指定为绝对路径,并将输出文件生成到单独的输出目录中。

$ asciidoctor -a stylesdir=`pwd`/my-styles -a stylesheet=my-stylesheet.css -a linkcss -D public my-document.adoc

Asciidoctor 将 HTML 文件生成到 public 文件夹中,但不会复制样式表。此外,它在链接到样式表时使用了绝对路径:

<link rel="stylesheet" href="/path/to/documents/my-styles/asciidoctor.css">

我们希望 Asciidoctor 将样式表复制到输出目录,并使用相对路径链接到它。

如果您想独立于源位置控制 HTML 引用的样式目录和样式表文件,也会出现类似的问题。

简而言之,我们需要能够将读取样式表的位置与发布和引用样式表的位置解耦。这就是 `copycss` 属性重新发挥作用的地方。

对于涉及 `stylesdir`、`linkcss` 和显式输出目录的复杂组合,`stylesdir` 的含义会过于复杂,需要进行调和。我们可以转向 `copycss` 属性来解决这种情况。

这种情况仅发生在设置了 `linkcss` 的情况下。当转换器嵌入样式表时,这不是问题,因为没有二次引用涉及。

`copycss` 属性可以接受一个非空值。Asciidoctor 将此值用作读取样式表的覆盖位置。转换器则不使用此值。这意味着我们可以使用 `stylesdir` 和 `stylesheet` 来组装相对于输出目录的路径,Asciidoctor 应在该目录中写入并链接到样式表,而与读取文件的位置无关。

让我们回顾上一节中损坏的场景,并使用 `copycss` 来解决问题:

$ asciidoctor -a stylesdir=css -a stylesheet=default.css \
-a copycss=$PWD/my-styles/my-stylesheet.css -a linkcss -D public my-document.adoc

Asciidoctor 将样式表从 `copycss` 属性指定的绝对路径复制到路径 public/css/default.css,并使用路径 css/default.css 链接到它。请注意,我们在输出中更改了文件夹和样式表文件的名称。这表明我们已经将读取样式表的位置与发布和引用样式表的位置解耦。

在 JRuby 上运行时,您可以将 `copycss` 指向类加载器 URI,以从 JAR 文件中加载样式表(例如,`uri:classloader:/css/styles.css`)。但是,HTML 无法链接到该位置。因此,您必须使用 `stylesheet` 属性(以及可选的 `stylesdir`)来指定一个文件名或相对路径,Asciidoctor 将在此处写入样式表。然后,HTML 将能够链接到该目标。

链接时样式目录和嵌套文档

针对一组嵌套的文档调用 Asciidoctor 时,目前无法为 `stylesdir` 属性指定一个适用于所有文档的相对路径。这是因为样式表位置的相对深度对于子目录中的文档是不同的。解决此问题的一种方法是在每个文档中维护 `stylesdir` 的路径。

假设您在以下目录结构中保存了三个 AsciiDoc 文档:

/my-documents
  a.adoc
  b.adoc
  /my-nested-documents
    c.adoc
  /my-styles

对于 a.adocb.adoc,将 `stylesdir` 设置为:

:stylesdir: my-styles

对于 c.adoc,将 `stylesdir` 设置为:

:stylesdir: ../my-styles

如果您通过 Web 服务器提供文档,可以通过提供样式表的绝对路径来解决此问题。您还可以尝试为每个文档使用 `copycss` 来控制 Asciidoctor 的查找样式表的位置,而与 Asciidoctor 复制它的位置以及转换器配置的 HTML 引用它的位置无关。