From cb08a13eef8b1c57f6f6fb7e8db10359f937eaff Mon Sep 17 00:00:00 2001 From: Lynn Speng Date: Wed, 11 Aug 2021 09:08:00 +0800 Subject: [PATCH 1/4] add pdf build scripts and template --- .gitignore | 2 + docs/compile.py | 94 +++++++++++++++ docs/tex/cover.tex | 5 + docs/tex/custom_template.tex | 216 +++++++++++++++++++++++++++++++++++ docs/utils.py | 74 ++++++++++++ 5 files changed, 391 insertions(+) create mode 100644 docs/compile.py create mode 100644 docs/tex/cover.tex create mode 100644 docs/tex/custom_template.tex create mode 100644 docs/utils.py diff --git a/.gitignore b/.gitignore index 3a9f19f29..c82b687b5 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ data/pikachu* # Pascal VOC2012数据集, 约2G data/VOCdevkit* + +docs/build \ No newline at end of file diff --git a/docs/compile.py b/docs/compile.py new file mode 100644 index 000000000..bb0ce02c9 --- /dev/null +++ b/docs/compile.py @@ -0,0 +1,94 @@ +import os +import re +import glob +from utils import get_content_files, downgrade_heading, create_empty_page, pure_markdown + + +def init(): + os.system("rm -rf build") + os.system("mkdir -p build/docs") + os.system("mkdir -p build/target") + os.system("cp -r img tex -t build") + os.system("cp _sidebar.md -t build") + for file in get_content_files(): + print("Found", file) + os.system("cp {} build/docs".format(file)) # move all markdown files to build/docs + os.chdir("build") + print("Inited.", end="\n\n") + + +def create_chapter(): + files = [] + with open("_sidebar.md", "r") as f: + for line in f.readlines(): + # 提取页面文件 + res = re.findall(r"\]\((.+)\)$", line) + + if len(res) > 0: # 存在对应 markdown 文件 + filename = "docs/{}".format(re.sub(r"^(.+)\/", "", res[0])) + if line[0] == " ": + # 将子章节内的标题统一降一级 + downgrade_heading(filename) + + else: # 不存在对应 markdown 文件 + # 提取页面标题 + title = re.findall(r"\*\s?\[?(.+?)\]?\(?\)?$", line)[0].replace("\\", "") + filename = "docs/{}.md".format(title.replace(" ", "")) + + # this is a work around for not including this chapter + if title == "简介": + continue + + if line[0] == " ": + # 针对子章节生成提示 + create_empty_page(filename, title, is_chapter=False) + else: + # 针对章节生成标题 + create_empty_page(filename, title, is_chapter=True) + files.append(filename) + return files + + +def format(): + print("Formating docs...") + for filename in glob.glob("docs/*.md"): + pure_markdown(filename) + os.system("prettier --write docs") + + +def build(files): + print("Building...") + title = r"《动手学深度学习》PyTorch 实现" + author = r"原书作者:阿斯顿・张、李沐、扎卡里C.立顿、\\ 亚历山大J.斯莫拉、以及其他社区贡献者 \thanks{GitHub 地址: https://github.com/d2l-ai/d2l-zh}" + date = r"\today" + + os.system("pandoc {} -o target/release.pdf \ + --from=markdown+link_attributes+footnotes+blank_before_header \ + --to=pdf \ + --toc \ + --toc-depth=2 \ + --resource-path=./docs \ + --listings \ + --pdf-engine=xelatex \ + --template=tex/custom_template.tex \ + -V documentclass=book \ + -V mathspec \ + -V graphicx \ + -V colorlinks \ + -V title='{}' \ + -V author='{}' \ + -V date='{}' \ + --include-before-body=tex/cover.tex".format(" ".join(files), title, author, date) + ) + + print("Done.", end="\n\n") + + +def main(): + init() + files = create_chapter() + format() + build(files) + +if __name__ == "__main__": + main() diff --git a/docs/tex/cover.tex b/docs/tex/cover.tex new file mode 100644 index 000000000..b3cd32108 --- /dev/null +++ b/docs/tex/cover.tex @@ -0,0 +1,5 @@ +本项目将《动手学深度学习》 原书中 MXNet 代码实现改为 PyTorch 实现。项目地址:\href{https://github.com/ShusenTang/Dive-into-DL-PyTorch}{https://github.com/ShusenTang/Dive-into-DL-PyTorch} 此书的中英版本存在一些不同,针对此书英文版的 PyTorch 重构可参考这个项目。 + +There are some differences between the Chinese and English versions of this book. For the PyTorch modifying of the English version, you can refer to this repo. + +\thispagestyle{empty} \ No newline at end of file diff --git a/docs/tex/custom_template.tex b/docs/tex/custom_template.tex new file mode 100644 index 000000000..adb762947 --- /dev/null +++ b/docs/tex/custom_template.tex @@ -0,0 +1,216 @@ +$if(colorlinks)$ +\PassOptionsToPackage{dvipsnames,svgnames,x11names}{xcolor} +$endif$ + +\documentclass{book} +\usepackage{iftex} +\usepackage{amsmath,amssymb} +\usepackage{mathspec} +\usepackage{lmodern} + +% +% geometry +% +\usepackage[a4paper]{geometry} +\geometry{ + left=2.54cm, + right=2.54cm, + top=3.18cm, + bottom=3.18cm, + footskip=1.48cm, + headsep=.5cm, + headheight=1.5cm +} +\usepackage{caption} +\captionsetup[figure]{labelformat=empty} +\renewcommand{\baselinestretch}{1.3} % 行间距 + + +% +% listings +% +\usepackage{listings} +\usepackage{xcolor} +\newcommand{\passthrough}[1]{#1} + +\lstdefinestyle{lfonts}{ + basicstyle = \small\ttfamily, + stringstyle = \color{purple}, + keywordstyle = \color{blue!60!black}\bfseries, + commentstyle = \color{gray}, +} +\lstdefinestyle{lnumbers}{ + numbers = left, + numberstyle = \small, + numbersep = 1em, + firstnumber = 1, + stepnumber = 1, +} +\lstdefinestyle{llayout}{ + breaklines = true, + postbreak = \mbox{\textcolor{red}{\(\hookrightarrow\)}\space}, + showspaces = false, + showtabs = false, + tabsize = 4, + columns = flexible, +} +\lstdefinestyle{lgeometry}{ + xleftmargin = 20pt, + xrightmargin = 0pt, + frame = tb, + framesep = \fboxsep, + framexleftmargin = 20pt, + aboveskip=1em, +} +\lstdefinestyle{lgeneral}{ + style = lfonts, + style = lnumbers, + style = llayout, + style = lgeometry, +} +\lstdefinelanguage{Python}{ + morekeywords={ + % normal keywords (without data types) + False, await, else, import, pass, + None, break, except,, in, raise, + True, class, finally, is, return, + and, continue, for, lambda, try, + as, def, from, nonlocal, while, + assert, del, global, not, with, + async, elif, if, or, yield + }, + morekeywords={[2] + % built-ins + abs, delattr, hash, memoryview, set, all, dict, help, min, setattr, any, dir, hex, next, slice, ascii, divmod, id, object, sorted, bin, enumerate, input, oct, staticmethod, bool, eval, int, open, str, breakpoint, exec, isinstance, ord, sum, bytearray, filter, issubclass, pow, super, bytes, float, iter, print, tuple, callable, format, len, property, type, chr, frozenset, list, range, vars, classmethod, getattr, locals, repr, zip, compile, globals, map, reversed, __import__, complex, hasattr, max, round, + }, + sensitive, +} +\lstset{ + style = lgeneral, +} + +% +% fonts +% +\usepackage{fontenc} +\usepackage[utf8]{inputenc} +\usepackage{textcomp} % provide euro and other symbols +\usepackage{fontspec} +\PassOptionsToPackage{space}{xeCJK} +\usepackage{xeCJK} +\setmainfont{Palatino Linotype} +\setCJKmainfont{Source Han Serif CN} +% Use upquote if available, for straight quotes in verbatim environments +\IfFileExists{upquote.sty}{\usepackage{upquote}}{} +\IfFileExists{microtype.sty}{% use microtype if available + \usepackage[$for(microtypeoptions)$$microtypeoptions$$sep$,$endfor$]{microtype} + \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts +}{} + + +% +% link +% +\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available +\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}} +\hypersetup{ + colorlinks=true, + linkcolor={$if(linkcolor)$$linkcolor$$else$Maroon$endif$}, + filecolor={$if(filecolor)$$filecolor$$else$Maroon$endif$}, + citecolor={$if(citecolor)$$citecolor$$else$Blue$endif$}, + urlcolor={$if(urlcolor)$$urlcolor$$else$Blue$endif$}, + pdfcreator={LaTeX via pandoc}} +\urlstyle{same} % disable monospaced font for URLs + +% +% table +% +$if(tables)$ +\usepackage{longtable,booktabs,array} +$if(multirow)$ +\usepackage{multirow} +$endif$ +\usepackage{calc} +\usepackage{etoolbox} +\makeatletter +\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} +\makeatother +\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} +\makesavenoteenv{longtable} +$endif$ + +% +% graphics +% +$if(graphics)$ +\usepackage{graphicx} +\makeatletter +\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} +\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} +\makeatother +\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} +\makeatletter +\def\fps@figure{htbp} +\makeatother +$endif$ + + +\setlength{\emergencystretch}{3em} % prevent overfull lines +\providecommand{\tightlist}{% + \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt} +} + +% +% numbering +% +$if(numbersections)$ +\setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$5$endif$} +$else$ +\setcounter{secnumdepth}{-\maxdimen} % remove section numbering +$endif$ + +% +% metainfo +% +$if(title)$ +\title{$title$$if(thanks)$\thanks{$thanks$}$endif$} +$endif$ + +\author{$for(author)$$author$$sep$ \and $endfor$} +\date{$date$} + +$for(header-includes)$ +$header-includes$ +$endfor$ + + +\begin{document} +$if(title)$ +\maketitle +$endif$ + +$for(include-before)$ +$include-before$ +$endfor$ + +% +% toc +% +$if(toc)$ +$if(toc-title)$ + \renewcommand*\contentsname{$toc-title$} +$endif$ +$if(colorlinks)$ + \hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$$endif$} +$endif$ +\setcounter{tocdepth}{$toc-depth$} +\tableofcontents +$endif$ + +$body$ + +$for(include-after)$ +$include-after$ +$endfor$ + +\end{document} diff --git a/docs/utils.py b/docs/utils.py new file mode 100644 index 000000000..a7bdc14db --- /dev/null +++ b/docs/utils.py @@ -0,0 +1,74 @@ +import re + + +def get_content_files(sidebar_filename="_sidebar.md"): + """ + parse the sidebar file and return a list of all content files + """ + + with open(sidebar_filename, "r") as f: + files = re.findall(r"\]\((.+)\)$", f.read(), re.M) + return files + + +def downgrade_heading(filename): + """ + downgrade all headings by 1 level + """ + + print("Downgrading headings in {}".format(filename)) + with open(filename, "r") as f: + lines = f.readlines() + + with open(filename, "w") as f: + is_codeblock = False + for line in lines: + if line.startswith("```"): + is_codeblock = not is_codeblock + elif line.startswith("#") and not is_codeblock: + line = "#" + line + f.write(line) + + +def create_empty_page(filename, title, is_chapter): + """ + create an empty page with the given title + """ + + print("Create new page for {}".format(filename)) + with open(filename, "w") as f: + if is_chapter: + f.write(f"# {title}\n") + else: + f.write(f"## {title}\n\n此章节仍未编写完成,敬请期待。\n") + + +def pure_markdown(filename): + """ + convert all markdown to pure markdown + """ + + with open(filename, "r") as f: + lines = f.readlines() + + with open(filename, "w") as f: + i = 0 + while i < len(lines): + window = lines[i : i + 4] + if window[0].startswith("(.+?)", window[-1]) + re.findall( + r"(.+?)", window[-1] + ) + cap = "" if cap == [] else cap[0].replace("\n", "").replace("\t", "").replace(" ", "") + f.write("\n![{}]({}){{ width={} }}\n\n".format(cap, src, width)) + if cap == "": + i += 3 + else: + i += 4 + else: + f.write(lines[i]) + i += 1 From 49d526921f021166e53d47177ed6e0df27a982dc Mon Sep 17 00:00:00 2001 From: Lynn Speng Date: Wed, 11 Aug 2021 19:01:26 +0800 Subject: [PATCH 2/4] fix indent in tex template --- docs/compile.py | 1 - docs/tex/custom_template.tex | 14 +++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/compile.py b/docs/compile.py index bb0ce02c9..8c0fa9ac6 100644 --- a/docs/compile.py +++ b/docs/compile.py @@ -71,7 +71,6 @@ def build(files): --listings \ --pdf-engine=xelatex \ --template=tex/custom_template.tex \ - -V documentclass=book \ -V mathspec \ -V graphicx \ -V colorlinks \ diff --git a/docs/tex/custom_template.tex b/docs/tex/custom_template.tex index adb762947..cf0f91f8f 100644 --- a/docs/tex/custom_template.tex +++ b/docs/tex/custom_template.tex @@ -24,7 +24,19 @@ \usepackage{caption} \captionsetup[figure]{labelformat=empty} \renewcommand{\baselinestretch}{1.3} % 行间距 - +$if(indent)$ +$else$ +\makeatletter +\@ifundefined{KOMAClassName}{% if non-KOMA class + \IfFileExists{parskip.sty}{% + \usepackage{parskip} + }{% else + \setlength{\parindent}{0pt} + \setlength{\parskip}{6pt plus 2pt minus 1pt}} +}{% if KOMA class + \KOMAoptions{parskip=half}} +\makeatother +$endif$ % % listings From 8b9db567d4c4b260795f079cb7ae0cd4d5412c65 Mon Sep 17 00:00:00 2001 From: Lynn Speng Date: Wed, 11 Aug 2021 19:20:01 +0800 Subject: [PATCH 3/4] add Github Actions to build and release pdf --- .github/workflows/release-pdf.yml | 76 +++++++++++++++++++++++++++++++ docs/release-notes.md | 3 ++ 2 files changed, 79 insertions(+) create mode 100644 .github/workflows/release-pdf.yml create mode 100644 docs/release-notes.md diff --git a/.github/workflows/release-pdf.yml b/.github/workflows/release-pdf.yml new file mode 100644 index 000000000..9279e20ab --- /dev/null +++ b/.github/workflows/release-pdf.yml @@ -0,0 +1,76 @@ +name: Release PDF +on: + push: + branches: + - master + paths: + - .github/workflows/release-pdf.yml + - docs/release-notes.md +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Install fonts + run: | + mkdir -p ~/.fonts + mkdir -p ~/.fonts/palatino-linotype + mkdir -p ~/.fonts/source-han-serif + wget https://github.com/dolbydu/font/raw/master/Serif/Palatino/Palatino%20Linotype%20Bold%20Italic.ttf -O ~/.fonts/palatino-linotype/Palatino-Linotype-Bold-Italic.ttf + wget https://github.com/dolbydu/font/raw/master/Serif/Palatino/Palatino%20Linotype%20Bold.ttf -O ~/.fonts/palatino-linotype/Palatino-Linotype-Bold.ttf + wget https://github.com/dolbydu/font/raw/master/Serif/Palatino/Palatino%20Linotype%20Italic.ttf -O ~/.fonts/palatino-linotype/Palatino-Linotype-Italic.ttf + wget https://github.com/dolbydu/font/raw/master/Serif/Palatino/Palatino%20Linotype.ttf -O ~/.fonts/palatino-linotype/Palatino-Linotype.ttf + wget https://github.com/adobe-fonts/source-han-serif/raw/release/SubsetOTF/CN/SourceHanSerifCN-Bold.otf -O ~/.fonts/source-han-serif/SourceHanSerifCN-Bold.otf + wget https://github.com/adobe-fonts/source-han-serif/raw/release/SubsetOTF/CN/SourceHanSerifCN-ExtraLight.otf -O ~/.fonts/source-han-serif/SourceHanSerifCN-ExtraLight.otf + wget https://github.com/adobe-fonts/source-han-serif/raw/release/SubsetOTF/CN/SourceHanSerifCN-Heavy.otf -O ~/.fonts/source-han-serif/SourceHanSerifCN-Heavy.otf + wget https://github.com/adobe-fonts/source-han-serif/raw/release/SubsetOTF/CN/SourceHanSerifCN-Light.otf -O ~/.fonts/source-han-serif/SourceHanSerifCN-Light.otf + wget https://github.com/adobe-fonts/source-han-serif/raw/release/SubsetOTF/CN/SourceHanSerifCN-Medium.otf -O ~/.fonts/source-han-serif/SourceHanSerifCN-Medium.otf + wget https://github.com/adobe-fonts/source-han-serif/raw/release/SubsetOTF/CN/SourceHanSerifCN-Regular.otf -O ~/.fonts/source-han-serif/SourceHanSerifCN-Regular.otf + wget https://github.com/adobe-fonts/source-han-serif/raw/release/SubsetOTF/CN/SourceHanSerifCN-SemiBold.otf -O ~/.fonts/source-han-serif/SourceHanSerifCN-SemiBold.otf + fc-cache -f -v ~/.fonts + echo "Fonts installed" + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y texlive-xetex texlive-lang-chinese texlive-latex-recommended librsvg2-bin + wget https://github.com/jgm/pandoc/releases/download/2.14.1/pandoc-2.14.1-1-amd64.deb + sudo dpkg -i pandoc-2.14.1-1-amd64.deb + sudo npm install -g --save-dev --save-exact prettier + xelatex --version + pandoc --version + prettier --version + echo "Dependencies installed" + - name: Clone repository + uses: actions/checkout@master + with: + repository: LynnSpeng/Dive-into-DL-PyTorch + - name: Build pdf + run: | + cd docs + python3 compile.py + - name: Set up release env + id: setup + run: | + echo "::set-output name=version::$(head -n 1 docs/release-notes.md)" + echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" + echo "::set-output name=date::$(date +%Y-%m-%d)" + - name: Create pdf release + id: create_release + uses: actions/create-release@latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ steps.setup.outputs.version }}-${{ steps.setup.outputs.sha_short }} + release_name: Release ${{ steps.setup.outputs.date }} + body_path: docs/release-notes.md + draft: false + prerelease: true + - name: Upload pdf release + id: upload_release + uses: actions/upload-release-asset@latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: docs/build/target/release.pdf + asset_name: dive-into-dl-pytorch.pdf + asset_content_type: application/pdf diff --git a/docs/release-notes.md b/docs/release-notes.md new file mode 100644 index 000000000..b0197cf38 --- /dev/null +++ b/docs/release-notes.md @@ -0,0 +1,3 @@ +v0.0.1 + +This release is auto generated by Github Actions. \ No newline at end of file From fa1127ff205a9954b125b4e7afb6a116ba34df6e Mon Sep 17 00:00:00 2001 From: Lynn Speng Date: Wed, 11 Aug 2021 21:31:41 +0800 Subject: [PATCH 4/4] fix style for indent, blockquote and toc --- .github/workflows/release-pdf.yml | 4 +--- docs/compile.py | 5 ++++- docs/tex/custom_template.tex | 30 +++++++++++++++++------------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/.github/workflows/release-pdf.yml b/.github/workflows/release-pdf.yml index 9279e20ab..2605a9a32 100644 --- a/.github/workflows/release-pdf.yml +++ b/.github/workflows/release-pdf.yml @@ -40,9 +40,7 @@ jobs: prettier --version echo "Dependencies installed" - name: Clone repository - uses: actions/checkout@master - with: - repository: LynnSpeng/Dive-into-DL-PyTorch + uses: actions/checkout@v2 - name: Build pdf run: | cd docs diff --git a/docs/compile.py b/docs/compile.py index 8c0fa9ac6..3e53f9229 100644 --- a/docs/compile.py +++ b/docs/compile.py @@ -59,6 +59,7 @@ def format(): def build(files): print("Building...") title = r"《动手学深度学习》PyTorch 实现" + toc_title = r"目录" author = r"原书作者:阿斯顿・张、李沐、扎卡里C.立顿、\\ 亚历山大J.斯莫拉、以及其他社区贡献者 \thanks{GitHub 地址: https://github.com/d2l-ai/d2l-zh}" date = r"\today" @@ -71,13 +72,15 @@ def build(files): --listings \ --pdf-engine=xelatex \ --template=tex/custom_template.tex \ + -V documentclass=book \ -V mathspec \ -V graphicx \ -V colorlinks \ -V title='{}' \ + -V toc-title='{}' \ -V author='{}' \ -V date='{}' \ - --include-before-body=tex/cover.tex".format(" ".join(files), title, author, date) + --include-before-body=tex/cover.tex".format(" ".join(files), title, toc_title, author, date) ) print("Done.", end="\n\n") diff --git a/docs/tex/custom_template.tex b/docs/tex/custom_template.tex index cf0f91f8f..67663041a 100644 --- a/docs/tex/custom_template.tex +++ b/docs/tex/custom_template.tex @@ -24,19 +24,7 @@ \usepackage{caption} \captionsetup[figure]{labelformat=empty} \renewcommand{\baselinestretch}{1.3} % 行间距 -$if(indent)$ -$else$ -\makeatletter -\@ifundefined{KOMAClassName}{% if non-KOMA class - \IfFileExists{parskip.sty}{% - \usepackage{parskip} - }{% else - \setlength{\parindent}{0pt} - \setlength{\parskip}{6pt plus 2pt minus 1pt}} -}{% if KOMA class - \KOMAoptions{parskip=half}} -\makeatother -$endif$ +\usepackage{indentfirst} % % listings @@ -172,6 +160,22 @@ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt} } +% +% blockquotes +% +\definecolor{blockquote-border}{RGB}{221,221,221} +\definecolor{blockquote-text}{RGB}{119,119,119} +\usepackage{mdframed} +\newmdenv[ + rightline = false, + bottomline = false, + topline = false, + linewidth = 4pt, + linecolor = blockquote-border, + skipabove = \parskip +]{customblockquote} +\renewenvironment{quote}{\vspace{4pt}\begin{customblockquote}\list{}{\rightmargin=1pt\leftmargin=1pt}\item\relax\color{blockquote-text}\ignorespaces}{\unskip\unskip\endlist\end{customblockquote}\vspace{4pt}} + % % numbering %