撰写手稿

概述

在本页中,我们将向您展示如何在VS Code中使用Quarto撰写学术手稿。您将学习如何:

  • 使用VS Code预览您的手稿。

  • 添加学术前言以描述您的文章。

  • 使用Quarto特定的Markdown添加图表、表格、交叉引用和引用。

  • 使用内联代码或从外部笔记本嵌入包含计算结果。

您将学习的语法适用于任何编辑笔记本的工具。尽管我们将使用Python代码示例,但您也可以使用R或Julia。

您主要使用.ipynb吗?

作为VS Code用户,我们建议您在.qmd文件中撰写文章。然而,如果您目前主要使用VS Code处理.ipynb文件,您可能会发现Jupyter Lab教程更适用。安装Jupyter Lab的Quarto扩展,然后从克隆模板仓库开始Jupyter Lab教程。您可能还会喜欢阅读关于在VS Code的笔记本编辑器中使用Quarto的内容。

本教程适合我吗?

我们将假设您:

  • 能够使用VS Code打开和编辑文件,
  • 拥有GitHub账户,并且能够将仓库克隆到您的计算机上,
  • 能够浏览文件系统,并在终端中执行命令。

设置

要继续学习,您需要安装 VS Code Quarto 扩展,安装一些 Python 包,并克隆模板仓库。

首先安装 Quarto

如果您还没有安装,请确保您已安装最新版本的 Quarto,如 手稿概述 中所述。

安装 Quarto VS Code 扩展

VS Code 扩展市场Open VSX 注册表 安装 Quarto 扩展。

安装 Python 包

模板手稿包含一些可执行的 Python 代码。要渲染 Python 代码,您需要 jupyter 以及此代码特定的包 pandasmatplotlib

终端
python3 -m pip install jupyter matplotlib pandas 

或者,一旦您有了下面的模板仓库,您可以使用 requirements.txt 文件来获取所需的包。

克隆模板仓库

要跟随本教程,您需要拥有 模板仓库 的副本,包括其所有分支。

  1. 前往 GitHub 从模板创建新仓库

    提供一个 仓库名称 并确保勾选 包含所有分支。然后 从模板创建仓库GitHub 从模板创建新仓库页面的截图。仓库名称已填写为 manuscript-template,并且标记为包含所有分支的框已勾选。

  2. 仓库创建完成后,将其克隆到您的本地计算机。

    您可以以任何您熟悉的方式进行,例如在终端中,可能看起来像这样:

    终端
    git clone git@github.com:<用户名>/<仓库名>.git

    其中您使用自己的用户名和仓库名。

  1. 您将在整个教程中在此目录内工作,因此如果您准备好继续,请在 VS Code 中打开该目录。

VS Code 的截图。文件资源管理器打开,显示文件夹:_extensions, _freeze, .github, images, 和 notebooks;以及文件:_quarto.yml, index.ipynb, README.md 和 references.bib。

在 VS Code 中打开的模板手稿

项目文件

最简单的 Quarto 手稿项目包含两个文件:

  • 一个笔记本文件,你在这里撰写文章:index.qmd。该文件包含:
    • 文档元数据,包括文章的前置信息(作者、所属机构等)和 Quarto 选项,
    • 文章正文,使用特殊的 Quarto Markdown 语法编写,允许你添加交叉引用和引用等内容,
    • 可选地,代码部分,你可以控制代码及其输出是否或如何出现在文章中。
  • 一个配置文件 _quarto.yml,用于标识该项目为 Quarto 手稿,并控制手稿的组合方式。

这个特定的手稿项目还包括一些其他文件和文件夹,你将在本教程中逐步了解这些文件。

工作流程

使用 Quarto 编写手稿的基本工作流程是在 index.qmd 中对文章内容进行修改,使用 Quarto 预览更改,并重复此过程。让我们来试试看。

打开 index.qmd

通过点击编辑器菜单栏中的 预览 按钮(预览图标)来预览手稿:

带有突出显示的预览按钮的源编辑器菜单栏的屏幕截图。

你会在终端中看到一些 Quarto 的输出,然后一个新的 Quarto 预览窗格中会出现实时预览。

VS Code 的屏幕截图。编辑器窗格中打开了一个名为 index.qmd 的文件。标题为 Quarto 预览的窗格中打开了一个以标题 La Palma Earthquakes 开头的网站。

接下来你将深入了解这个 index.qmd 的细节,但现在让我们先进行一些更改,看看会发生什么。

找到这一行:

title: La Palma Earthquakes

将其更改为:

title: La Palma Earthquake Mechanisms

保存笔记本,点击预览,你会看到预览更新。

VS Code 的屏幕截图。编辑器窗格中打开了一个名为 index.qmd 的文件,文本为 title: La Palma Earthquake Mechanisms。Quarto 预览窗格中打开了一个标题为 La Palma Earthquake Mechanisms 的文章网页。

可视化编辑器

VS Code 可视化编辑器为 Quarto 笔记本提供了一个 WYSIWYM 编辑界面。一些任务,比如添加引用或创建表格,在可视化编辑器中更容易完成——我们会在介绍这些功能时指出。

文件 `index.qmd` 在源代码编辑器中打开的截图。文件显示行号和插入图片和表格的原始 Markdown 代码。

源代码编辑器

文件 `index.qmd` 在可视化编辑器中打开的截图。文件显示图片和表格。

可视化编辑器

要在源代码编辑器和可视化编辑器模式之间切换,请使用编辑器菜单并选择“在可视化模式下编辑”或“在源代码模式下编辑”模式,或使用键盘快捷键

VS Code 中编辑器菜单的截图。菜单中的“在可视化模式下编辑”项被突出显示。

还有其他切换模式的方法,请阅读 VS Code 中的可视化编辑 以了解更多信息,以及可视化编辑器的其他功能。

您可以随时在源代码编辑器和可视化编辑器之间切换——光标位置和撤销/重做历史记录会被保留。

笔记本结构

文件 index.qmd 是一个 Quarto Markdown 文件。它包含三种类型的内容:

  • 它以一个 YAML 头开始,用于设置文档元数据,包括学术前言。YAML 头以三行破折号(---)开始和结束,在这些行之间,内容被解析为 YAML。

  • 它可能包含可执行的代码块,这些代码块以三个反引号开头,后跟花括号中的代码语言(例如 ```{r}```{python})。这些代码块的顶部可能包含以 #| 开头的 Quarto 注释。这些注释设置了控制代码及其输出在文章中显示方式的 Quarto 选项。

  • 文档的其余部分被解释为特定于 Quarto 的 Markdown,这使你能够包含图表、表格、方程、交叉引用和引用等内容。

本页的其余部分将自上而下地引导你浏览本文,向你介绍编写学术文章时最可能需要的 Quarto 功能。

前言

YAML 头部由使用 key: value 语法设置的键值对组成。由于用于指定大量的学术前言内容,如作者及其所属机构,以及摘要等,文章的头部通常较为广泛。

title: 拉帕尔马地震
author:
  - name: 史蒂夫·珀维斯
    orcid: 0000-0002-0760-5497
    corresponding: true
    email: steve@curvenote.com
    roles:
      - 调查
      - 项目管理
      - 软件
      - 可视化
    affiliations:
      - Curvenote
  - name: 罗恩·科基特
    orcid: 0000-0002-7859-8394
    corresponding: false
    roles: []
    affiliations:
      - Curvenote
keywords:
  - 拉帕尔马
  - 地震
abstract: |
  2021年9月,西班牙加那利群岛的拉帕尔马岛地震活动显著增加,标志着火山危机的开始,这一危机在撰写本文时仍在持续。地震数据由西班牙国家地理研究所(IGN)持续收集并发布。...
plain-language-summary: |
  2021年9月拉帕尔马岛火山喷发期间的地震数据发现...
key-points:
  - 开发了一个网络爬虫脚本,从西班牙国家地理研究所提取数据,以便进行机器可读的分析
  - 拉帕尔马岛的地震事件与地幔和地壳储层的活动一致。
date: last-modified
bibliography: references.bib
citation:
  container-title: 地球与空间科学
number-sections: true

例如,在 index.qmd 的头部顶层设置了以下键:titleauthorkeywordsabstractplain-language-summarykey-pointsdatebibliographycitationnumber-sections

你已经看到,编辑 title 键会更新稿件网页上的文章标题。title 键也被 PDF 和 Word 格式使用,但并非所有键在所有格式中都被使用。

你可以在 Scholarly Front Matter 中阅读更多关于为你的文章设置前言的内容。

Markdown

文档中的Markdown单元格将由Quarto特定的Markdown语法处理。Quarto的Markdown语法基于Pandoc Markdown,而Pandoc Markdown又基于John Gruber的Markdown

例如,创建文章介绍标题的Markdown语法是:

## Introduction

一级标题保留用于文章标题,因此您将使用二级及更深层次的标题来构建文章的各个部分。

如果对Markdown语法不熟悉,您可能需要阅读关于Quarto的Markdown基础

计算

Python 示例

本节使用 Python 代码示例,但 Quarto 也支持 R、Julia 和 Observable。

您的文章可以包含可执行代码。默认情况下,代码本身不会在文章中显示,但任何输出(包括表格和图表)都会显示。当您在文章中包含代码时,您还会在稿件网页的“笔记本”下获得一个额外的“文章笔记本”链接。这是包含代码的文章笔记本的渲染版本。

例如,index.qmd 包含:

```{python}
import matplotlib.pyplot as plt
import numpy as np
eruptions = [1492, 1585, 1646, 1677, 1712, 1949, 1971, 2021]
```

此代码不会出现在渲染的文章中,但会出现在“文章笔记本”中。

渲染文章的截图,其中有一个以 'Let x denote' 开头的部分。没有代码可见。

渲染的文章

文章笔记本的截图,其中有一个以 'Let x denote' 开头的部分。代码在两个单元格中可见。第一个单元格以 'import matplotlib' 开头。

文章笔记本

您可以通过在顶部添加 #| 注释,然后使用 YAML 语法添加 Quarto 选项。例如,添加 echo 选项并将其值设置为 true 将如下所示:

```{python}
#| echo: true
import matplotlib.pyplot as plt
import numpy as np
eruptions = [1492, 1585, 1646, 1677, 1712, 1949, 1971, 2021]
```

echo 选项描述代码是否包含在渲染的文章中。如果您进行此更改并保存 index.qmd,您将看到此代码现在出现在文章中。

您可以在 Jupyter 代码单元格 参考页面上找到所有可用的代码单元格选项的列表。

下一个代码单元格创建一个图表:

```{python}
#| label: fig-timeline
#| fig-cap: 拉帕尔马近期地震的时间线
#| fig-alt: 拉帕尔马最近8次喷发的年份事件图。

plt.figure(figsize=(6, 1))
plt.eventplot(eruptions, lineoffsets=0, linelengths=0.1, color='black')
plt.gca().axes.get_yaxis().set_visible(False)
plt.ylabel('')
plt.show()
```

label 选项用于为代码单元格及其输出添加标识符,例如允许交叉引用。对于图表交叉引用,前缀 fig- 是必需的,但后缀(在本例中为 timeline)则由您决定。您将在下面了解更多关于 交叉引用 的信息。

选项 fig-cap 提供了在手稿中显示在图表下方的标题文本,而 fig-alt 则为图表提供了替代文本,有助于您的手稿网页符合可访问性指南。

计算也是基于数据包含表格的好方法。您可以在 Quarto 文档中阅读更多关于 基于计算的表格 的内容。

如果您有不想包含在文章中的代码输出,可以使用 output: false。例如,您可能有一个对编写内容有帮助的值,但您不希望它在文章中出现。下一个代码单元格是一个示例:

```{python}
#| output: false
avg_years_between_eruptions = np.mean(np.diff(eruptions[:-1]))
avg_years_between_eruptions
```

如果您正在查看渲染后的“文章笔记本”,您会看到 avg_years_between_eruptions 的值显示在此代码下方,但该值不会出现在渲染后的文章中。

如果您希望排除单元格及其输出,使其既不在文章中也不在渲染的笔记本中出现,可以使用 include: false 代替:

```{python}
#| include: false
avg_years_between_eruptions = np.mean(np.diff(eruptions[:-1]))
avg_years_between_eruptions
```

您还可以通过使用内联代码直接在文章文本中使用计算值。在 内联代码 中了解更多信息。

除了直接在文章中包含计算外,您还可以嵌入其他笔记本的输出,请在下面的 嵌入笔记本 中了解更多信息。

代码何时执行?

默认情况下,Quarto 会在渲染过程中执行 .qmd 笔记本中的代码。这意味着,当您编辑 index.qmd 时,您可能会注意到指示代码正在运行的消息。

此手稿模板使用了 Quarto 的冻结功能,这使我们能够在发布过程中避免设置计算环境。冻结保存了笔记本的渲染版本,因此它们不会重新渲染,除非它们的源代码发生变化,代码也不会重新评估。

您可能没有注意到,但第一次渲染手稿时没有评估任何代码。这是因为模板仓库包含了 _freeze/ 文件夹,并且自生成冻结以来 index.qmd 的内容没有改变。当您更改 index.qmd 时,代码将被重新评估,_freeze/ 的内容将被更新。请记住,当您准备发布时,您还需要提交 _freeze/ 中的更改。

引用

文章引用

本节介绍如何在文章正文中添加引用。文章网页底部显示的引用信息通过前言进行控制。

要添加引用,您需要一个包含引用数据的参考文献文件(.bib)。您可以在文档 YAML 中使用 bibliography 选项指定此文件。例如,index.qmd 的引用数据存储在 references.bib 中:

bibliography: references.bib

references.bib 文件仅包含一个引用:

references.bib
@article{marrero2019,
  author = {Marrero, Jos{\' e} and Garc{\' i}a, Alicia and Berrocoso, Manuel and Llinares, {\' A}ngeles and Rodr{\' i}guez-Losada, Antonio and Ortiz, R.},
  journal = {Journal of Applied Volcanology},
  year = {2019},
  month = {7},
  pages = {},
  title = {Strategies for the development of volcanic hazard maps in monogenetic volcanic fields: the example of {La} {Palma} ({Canary} {Islands})},
  volume = {8},
  doi = {10.1186/s13617-019-0085-5},
}

要在正文中引用参考文献中的文章,您可以使用 @ 后跟引用标识符,例如 marrero2019。例如,文章中包含引用此参考文献的这一行:

Studies of the magma systems feeding the volcano, such as @marrero2019, have proposed ...

这会呈现为:

Studies of the magma systems feeding the volcano, such as Marrero et al. (2019), have proposed …

将鼠标悬停在引用文本上会显示完整的参考文献详细信息。点击引用会将读者带到文章末尾的参考文献部分:

渲染后的文章截图,显示标题为 References 的部分。标题下方是一个完整的参考文献,开头为 'Marrero, José, '。

交叉引用

Quarto 可以生成交叉引用,自动为你管理编号和链接。交叉引用的通用语法是 @ 后面跟一个标签。例如,要引用时间线图,你可以写:

@fig-timeline

渲染时,交叉引用会包含一个词来指示被引用对象的类型,如“图”或“表”。因此,例如在 index.qmd 中的这一行:

自15世纪末以来,已记录了八次喷发 (@fig-timeline)。

结果是:

自15世纪末以来,已记录了八次喷发(图1)。

其中“图1”也是一个指向相应图表的链接。

你添加到元素的标签必须有适当的标签前缀,以允许交叉引用:

元素 标签前缀 渲染的交叉引用
fig- 图1
tbl- 表1
方程 eq- 方程1
章节 sec- 章节1

你已经看到可以通过 label 代码块选项为代码生成的输出添加标签。在下面的学习中,你将看到如何为非代码生成的元素(如方程表格静态图表)添加标签。

要交叉引用章节,你的文档 YAML 头部还必须包含:

number-sections: true

你可以在章节标题后的花括号中添加标签,例如:

## 数据与方法 {#sec-data-methods}

然后你可以在文本中引用这个章节,例如:

数据和方法在 @sec-data-methods 中讨论。

这将渲染为:

数据和方法在第2节中讨论。

你可以在 Quarto 交叉引用 文档中阅读更多关于可以引用的对象类型,包括代码列表和数学定理,以及一些控制引用显示方式的选项。

在可视化编辑器中,你可以使用 插入 -> 交叉引用 来获取一个包含文档中可用标签的对话框,并快速生成交叉引用所需的语法。

方程

Quarto markdown 可以包含使用 LaTeX 符号指定的方程。使用单个美元符号($)来添加行内方程,或使用双美元符号($$)来添加显示方程。以下段落展示了这两种用法,位于 index.qmd 中:

设 $x$ 表示一年内的喷发次数。那么,$x$ 可以用泊松分布来建模

$$
p(x) = \frac{e^{-\lambda} \lambda^{x}}{x !}
$$ {#eq-poisson}

其中 $\lambda$ 是每年的喷发率。利用 @eq-poisson,可以计算未来 $t$ 年内发生喷发的概率。

请注意,显示方程在关闭的 $$ 后添加了花括号中的标签。这使得可以在文本中使用 @eq-poisson 来引用它。

渲染后,显示为:

\(x\) 表示一年内的喷发次数。那么,\(x\) 可以用泊松分布来建模 \[ p(x) = \frac{e^{-\lambda} \lambda^{x}}{x !} \tag{1}\] 其中 \(\lambda\) 是每年的喷发率。利用 Equation 1,可以计算未来 \(t\) 年内发生喷发的概率。

表格

表格可以通过所谓的管道语法内联添加。例如,在 index.qmd 中,地震表被指定为:

| 名称                 | 年份   |
| -------------------- | ------ |
| 当前                 | 2021   |
| 特内吉亚             | 1971   |
| 南布罗克             | 1949   |
| 埃尔查科             | 1712   |
| 圣安东尼奥火山       | 1677   |
| 圣马丁火山           | 1646   |
| 埃尔帕索附近的塔朱亚 | 1585   |
| 蒙塔尼亚克马达       | 1492   |

: 拉帕尔马近期历史喷发 {#tbl-history}

列由管道符号 (|) 分隔,第二行的破折号 (-) 将标题行与表格的其余部分分隔开。可以通过以 : 开头的行提供标题。在标题末尾的花括号内添加一个可用于交叉引用的标签。与图表一样,交叉引用的标签前缀 tbl- 是必需的,但后缀由您决定。

使用 Markdown 语法插入和编辑表格可能会很繁琐。 可视化编辑器提供了编辑现有表格和插入新表格的工具。使用可视化编辑器工具栏中的表格菜单或在表格内右键单击以调出选项。

您可以在 Quarto 文档的 表格 页面了解更多关于 Quarto 中的表格信息,包括称为网格表格的替代语法。

静态图表

要包含来自文件的图片,Markdown 语法如下所示:

![标题](图片文件路径)

例如,要包含项目中 images/ 文件夹下的 la-palma-map.png 图片,并附上标题 “La Palma 地图”,你可以这样写:

![La Palma 地图](images/la-palma-map.png)
图片文件位置

虽然 images/ 是一个常见的惯例,但你不必将图片存储在名为 images/ 的文件夹中。你的图片可以放在手稿项目目录内的任何位置,只需确保你包含了相对于 index.qmd 位置的完整路径。

index.qmd 中的实际 Markdown 还包括一个额外的属性 #fig-map,它在图片路径后的花括号内,用于提供交叉引用的标签:

![La Palma 地图](images/la-palma-map.png){#fig-map}

你可能希望添加的另一个属性是 fig-alt,即为图片提供的替代文本。例如:

![La Palma 地图](images/la-palma-map.png){#fig-map fig-alt="加那利群岛的地图。第二西部的岛屿,La Palma,被突出显示。"}

你可以在 Quarto 文档的 Figures 页面上阅读更多关于在 Quarto 文档中包含图片的内容,包括如何调整图片大小和排列多个图片。

外部嵌入

嵌入Quarto笔记本

本节介绍如何嵌入Quarto文档(.qmd)的输出。您还可以嵌入Jupyter笔记本(.ipynb)的输出

在文章笔记本中直接包含计算的另一种方法是嵌入其他笔记本的输出。此手稿项目在notebooks/文件夹中包含了笔记本data-screening.qmd

要嵌入笔记本的输出,可以使用embed短代码。Quarto短代码是生成内容的特殊Markdown指令。embed短代码用于主文章文件中的这一行:

index.qmd
{{< embed notebooks/data-screening.qmd#fig-spatial-plot >}}

双大括号({{)和尖括号(<)表示这是一个短代码。embed短代码需要一个指向笔记本块的路径。在本例中,它是源笔记本的文件路径data-screening.qmd,后跟#和一个块标签。块标签是通过在data-screening.qmd笔记本中使用Quarto块选项label设置的:

data-screening.qmd
```{python}
#| label: fig-spatial-plot
#| fig-cap: 2017年以来拉帕尔马地震的位置。
#| fig-alt: 地震位置的散点图,绘制纬度与经度。
from matplotlib import colormaps
cmap = colormaps['viridis_r']
ax = df.plot.scatter(x="Longitude", y="Latitude", 
                     s=47-df["Depth(km)"], c=df["Magnitude"], 
                     figsize=(12,10), grid="on", cmap=cmap)
colorbar = ax.collections[0].colorbar
colorbar.set_label("Magnitude")

plt.show()
```

就像任何图形一样,使用以fig-开头的标签可以在文本中进行交叉引用。其他选项,如图形标题(fig-cap)和替代文本(fig-alt),也可以在源笔记本中设置。

每当你更改data-screening.qmd的内容,包括更新块选项如标题时,它将被重新渲染。因此,data-screening.qmd中的代码也将重新运行。

例如,如果您将标题编辑为:

#| fig-cap: "2017年以来拉帕尔马的地震。"

您会注意到在后台quarto preview重新渲染了文件:

Terminal
处理文件:data-screening.qmd
                                                                                    输出文件:data-screening.qmd

渲染输出笔记本 [notebooks/data-screening.qmd]
渲染HTML预览 [notebooks/data-screening.qmd]

然后主文章预览中的标题会更新。

下一步

你现在已经了解了使用Quarto撰写手稿的主要功能。你编辑了index.qmd,添加了图表、笔记本或参考文献等资源,并预览了结果。

一旦你对所做的更改感到满意,你需要更新你的公开手稿网页。

前往发布,学习如何发布并与全世界分享你的手稿。