Quarto Book

以《R学习笔记》为例

章节安排及其他设置

_quarto.yml决定章节的安排

project:
  type: book
  output-dir: /www/wwwroot/www.mmphcrc.com/books/rln  # 设置渲染后文件放置的位置

book:
  title: "R学习笔记 - R learning notes"
  author: "胡林辉"
  date: "11/25/2023"
  chapters:
    - part: index.qmd
      chapters:
        - study_resources.qmd
    - part: basic.qmd
      chapters:
        - packages.qmd
        - pipe.qmd
        - check_info.qmd
        - character.qmd
        - datetime.qmd
        - files.qmd
        - math_calculation.qmd
    - part: data.qmd
      chapters:
        - built-in-data.qmd
        - worksheet.qmd
        - textdata.qmd
        - relational-database.qmd
        - missing_data.qmd
        - duplicate.qmd
        - select.qmd
        - sort.qmd
        - datetime.qmd
        - replace.qmd
        - mutate.qmd
        - aggregate.qmd
        - merge.qmd
        - export.qmd
    - part: visualization.qmd
      chapters:
        - ggplot2.qmd

bibliography: references.bib
comments:
  hypothesis: true
crossref:
  fig-title:
  tbl-title:
  title-delim:
  tbl-prefix:
  fig-prefix:

format:
  html:
    theme:
      - cosmo
      - styles.scss
    link-external-newwindow: true
    link-external-icon: true
    df-print: kable
  pdf:
    documentclass: scrreprt

渲染命令

quarto render  # 包括pdf, docx和html
quarto render --to html  # 只渲染成html

qurto convert xxx.ipynb --output xxx.qmd

部署至www服务器

最佳实践

在工程项目的_quarto.yml文件设置项目导出的路径就行了。

output-dir: /www/wwwroot/www.mmphcrc.com/books/rln

历史探索实践

  • 生成文件夹,并赋非root用户可写权限757。该命令需要root权限,在jupyter或者宝塔打开都有root权限。
mkdir -m 757 /www/wwwroot/www.mmphcrc.com/books/ggplot2
  • 链接实现软同步
ln -sf /home/hulihuihong/Books/rln/_book/* /www/wwwroot/www.mmphcrc.com/books/rln

渲染和同步一步执行

注意:每次有新的章节时均需要重新渲染和软连接。因此,可以将以上代码保存在render.sh文件里,内容如下:

quarto render --to html
ln -sf /home/hulihuihong/Books/rln/_book/* /www/wwwroot/www.mmphcrc.com/books/rln

可以将代码放置在根目录下,保存为render.sh文件,并通过chmod +x ./render.sh添加可执行权限。

./render.sh

如果是已有qmd文件的更新,则只要render该qmd文件即可。

jupyterlab生成Book

优点是可以使用多个kernel,使用多个语言进行编程和生成书籍。

最佳实践

  • 升级jupyterlab,其支持qmd文件,其他操作同Rstudio。

初始实践

  • jupyterlab升级至4.0以上,先新建.md文件,编辑内容后,重命名为.qmd文件,可打开.qmd文件,类似之前的.ipynb文件一样编辑、执行。
  • 直接在jupyterlab里执行quarto render,将output-dir设置为www服务器文件夹。
project:
  type: book
  output-dir: /www/wwwroot/www.mmphcrc.com/books/pyln

缺点: - 经常出错和不能正常显示单元格。 - {.unnumbered}设置失效。 - 外链在_quarto.yml设置失效。

优点: - 可灵活使用各个kernel

改进实战

qmd文件出错的问题

  • ipynb文件和qmd文件结合使用:在ipynb文件里编辑,再将ipynb文件转换成qmd文件,再渲染qmd文件。 注意:ipynb文件跟qmd文件名不能相同,否则ipynb会在渲染时被删除。比如ipynb文件可以加上_notebook的后缀。
  • 编写转换和渲染脚本文件:render.py
import os
import subprocess
import sys

# 获取第一个参数
notebook = sys.argv[1]

if notebook == "all":
    # 获取当前目录下的所有.ipynb文件
    notebooks = [file for file in os.listdir() if file.endswith('.ipynb')]
    
    # 遍历每个.ipynb文件,并进行转换
    for notebook in notebooks:
        if not notebook.replace(".ipynb", "").endswith('_notebook'):
            raise ValueError("Input file must contain suffix of '_notebook'.")
        # 因quarto在render时会删除同名的ipynb文件,故qmd文件和ipynb文件不能同名
        qmd_file = notebook.replace("_notebook", "").replace('.ipynb', '.qmd')
        # 构建转换命令
        command = f'quarto convert {notebook} --output {qmd_file}'
        # 执行转换命令
        subprocess.run(command, shell=True)
    # 执行渲染命令
    command = f'quarto render'
    # 执行转换命令
    subprocess.run(command, shell=True)

else:
    # 确保指定的文件为ipynb,并且存在
    if not notebook.endswith('.ipynb'):
        raise ValueError("Input file must be a .ipynb file.")
    elif not os.path.exists(notebook):
        raise ValueError("Input file must exist.")
    elif not notebook.replace(".ipynb", "").endswith('_notebook'):
        raise ValueError("Input file must contain suffix of '_notebook'.")
    else:
        # 因quarto在render时会删除同名的ipynb文件,故qmd文件和ipynb文件不能同名
        qmd_file = notebook.replace("_notebook", "").replace('.ipynb', '.qmd')
        # 构建转换命令
        command = f'quarto convert {notebook} --output {qmd_file}'
        
        # 执行转换命令
        subprocess.run(command, shell=True)

        # 执行渲染命令
        command = f'quarto render {qmd_file}'
        # 执行转换命令
        subprocess.run(command, shell=True)
  • 在终端执行:
python render.py all   # 转换所有ipynb并render
python render.py meeting_program_notebook.ipynb  # 转换特定ipynb并render

{.unnumbered}设置失效的问题

  • rstudio新建qmd文件,复制至jupyterlab
sudo cp ../index.qmd /www/wwwroot/www.mmphcrc.com/pdf/jupyter/HuLinhuiPy/思平教育/index.qmd
sudo cp ../math.qmd /www/wwwroot/www.mmphcrc.com/pdf/jupyter/HuLinhuiPy/思平教育/math.qmd
  • jupyterlab命令行新建qmd文件

在demo.txt文件编辑,写入至qmd文件

cat demo.txt > demo.qmd

外链在_quarto.yml设置失效的问题

  • 单独在每个ipynb文件的开始设置yml
---
title: 暨南大学博士
format: 
  html: 
    link-external-icon: true
    link-external-newwindow: true
    link-external-filter:  ^https://www.mmphcrc.com/books/wsl/
---

问题解决

DT包不能正常显示。

通过nano打开qmd,将kernel等jupyter自动添加上的参数删除,保存,再次quarto render,即跟rstudio里的流程一样正常生成在线交互表格。

SASPy在渲染时报错

sas-ttest.qmd文件为例

  1. 编辑sas-ttest.qmd文件,并在文件自身的yml部分设置eval: false,目的是不报错通过。在_quarto.yml里安排章节,通过quarto render整个工程,生成相应的目录和搜索。
  2. 通过quarto convert sas-ttest.qmd命令将sas-ttest.qmd转换为sas-ttest.ipynb文件。
  3. 打开sas-ttest.ipynb执行所有code单元格里的代码,保存ipynb文件。
  4. 通过quarto render sas-ttest.ipynb命令,将sas-ttest.ipynb转换为sas-ttest.html及其对应的静态支持文件夹sas-ttest_files
  5. sas-ttest.ipynb生成的sas-ttest.html文件(以下称notebook_html)里code单元格的输出部分添加至sas-ttest.qmd生成的sas-ttest.html文件(以下简称quarto_html)。相关流程与代码见:https://www.mmphcrc.com/books/pyln/sas-output-adjust.html