diff --git a/d2lbook/build.py b/d2lbook/build.py index f37cf11..16a7b36 100644 --- a/d2lbook/build.py +++ b/d2lbook/build.py @@ -8,6 +8,9 @@ import shutil import subprocess import sys +import tarfile +import zipfile +import requests import nbformat import notedown @@ -222,6 +225,35 @@ def _copy_rst(self): for src, tgt in updated_rst: copy(src, tgt) return rst_files + + def _download_extract_latex(self, url, folder='latex_style', sha1_hash=None): + os.makedirs(folder, exist_ok=True) + fname = os.path.join(folder, url.split('/')[-1]) + # Check if hit cache + if os.path.exists(fname) and sha1_hash: + sha1 = hashlib.sha1() + with open(fname, 'rb') as f: + while True: + data = f.read(1048576) + if not data: + break + sha1.update(data) + if sha1.hexdigest() == sha1_hash: + return fname + print(f'Downloading {fname} from {url}...') + r = requests.get(url, stream=True, verify=True) + with open(fname, 'wb') as f: + f.write(r.content) + base_dir = os.path.dirname(folder) + data_dir, ext = os.path.splitext(fname) + if ext == '.zip': + fp = zipfile.ZipFile(fname, 'r') + elif ext in ('.tar', '.gz'): + fp = tarfile.open(fname, 'r') + else: + assert False, 'Only zip/tar files can be extracted.' + fp.extractall(folder) + @_once def merge(self): @@ -356,6 +388,9 @@ def linkcheck(self): @_once def pdf(self): self.rst() + if self.config.pdf['style'] == 'cambridge': + self._download_extract_latex(self.config.pdf['latex_url']) + run_cmd([ 'sphinx-build ', self.config.rst_dir, self.config.pdf_dir, '-b latex -c', self.config.rst_dir, self.sphinx_opts]) diff --git a/d2lbook/config_default.ini b/d2lbook/config_default.ini index dc3d855..8e030f5 100644 --- a/d2lbook/config_default.ini +++ b/d2lbook/config_default.ini @@ -136,6 +136,11 @@ latex_logo = # Bibtext bibfile bibfile = +# Specify the url of external latex resources. +latex_url = + +# Specify the latex style. We now support "cambridge" and the defaut sphinx style. +style = [library] diff --git a/d2lbook/sphinx.py b/d2lbook/sphinx.py index 45e9094..e92824b 100644 --- a/d2lbook/sphinx.py +++ b/d2lbook/sphinx.py @@ -12,7 +12,10 @@ def prepare_sphinx_env(config): class SphinxEnv(object): def __init__(self, config): self.config = config - self.pyconf = template.sphinx_conf + if self.config.pdf['style'] == 'cambridge': + self.pyconf = template.sphinx_conf_cambridge + else: + self.pyconf = template.sphinx_conf def prepare_env(self): self._copy_static_files() diff --git a/d2lbook/sphinx_template.py b/d2lbook/sphinx_template.py index 702b8d1..5643030 100644 --- a/d2lbook/sphinx_template.py +++ b/d2lbook/sphinx_template.py @@ -51,9 +51,7 @@ ] rsvg_converter_args = ['-z', '0.8'] - bibtex_bibfiles = ["BIBFILE"] - latex_engine = 'xelatex' # for utf-8 supports latex_show_pagerefs = True latex_show_urls = 'footnote' @@ -151,6 +149,212 @@ def setup(app): app.add_directive('card', mxtheme.CardDirective) """ +sphinx_conf_cambridge = r""" +import sys +sys.path.insert(0, '..') +sys.path.insert(0, '.') + +project = "TITLE" +copyright = "COPYRIGHT" +author = "AUTHOR" +release = "RELEASE" + +extensions = [EXTENSIONS] + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +master_doc = 'INDEX' +numfig = True +numfig_secnum_depth = 2 +math_numfig = True +math_number_all = True + +suppress_warnings = ['misc.highlighting_failure'] +linkcheck_ignore = [r'.*localhost.*'] +linkcheck_timeout = 5 +linkcheck_workers = 20 + +autodoc_default_options = { + 'undoc-members': True, + 'show-inheritance': True, +} + + +html_theme = 'mxtheme' +html_theme_options = { + 'primary_color': 'blue', + 'accent_color': 'deep_orange', + 'header_links': [ + HEADER_LINKS + ], + 'show_footer': False +} +html_static_path = ['_static'] + +html_favicon = 'FAVICON' + +html_logo = 'HTML_LOGO' + +latex_documents = [ + (master_doc, "NAME.tex", "TITLE", + author, 'PT1'), +] + + + +rsvg_converter_args = ['-z', '0.8'] + +bibtex_bibfiles = ["BIBFILE"] + +latex_engine = 'xelatex' # for utf-8 supports +latex_show_pagerefs = True +latex_show_urls = 'footnote' + +latex_logo = 'LATEX_LOGO' + +latex_elements = { +'papersize':'a4paper,prodtf,twoside', +'figure_align': 'htbp', +'pointsize': '11pt', +'fvset':r'''\fvset{fontsize=\small}''', +'preamble': r''' +\usepackage{graphicx} +\usepackage{booktabs} +\usepackage{amsthm} +\usepackage{color} +\usepackage[figuresright]{rotating} +\usepackage{floatpag} +\rotfloatpagestyle{empty} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage[parfill]{parskip} +\usepackage{titlesec} +\usepackage{multicol} +\protected\def\sphinxcite{\citep} + +% Add bib to TOC +\usepackage[nottoc,numbib]{tocbibind} + +% QR code sidenotes for all footnotes +% Make sure to replace special charactors URL Encoding: https://www.urlencoder.io/learn/ +\usepackage{sidenotes} +\usepackage{marginfix} +\setlength\marginparpush{20pt} +\usepackage{qrcode} +\newcommand{\qrsidenote}[1]{ +\sidenote{ +\qrcode[height=8mm]{#1}} +} +\newcommand{\relaxfootnote}[1][]{} + +\makeatletter +\let\ps@normal\ps@headings +\let\sphinxthebibliography\thebibliography +\let\sphinxtheindex\theindex +\let\sphinxAtStartFootnote\! +\let\footnote\relaxfootnote +\let\sphinxnolinkurl\qrsidenote + +\sphinxDeclareColorOption{TitleColor}{{rgb}{0,0,0}} +\sphinxDeclareColorOption{InnerLinkColor}{{rgb}{0,0,0}} +\sphinxDeclareColorOption{OuterLinkColor}{{rgb}{0,0,0}} + +% So some large pictures won't get the full page +\renewcommand{\floatpagefraction}{.8} + +% Set the page margin size +\geometry{left=1.9in, right=1.4in, includefoot, bottom=0.5in} + +% Section and subsection style +\titleformat{\section}{\LARGE\centering}{\thesection}% + {0.5em}{}[{\hspace{-1.65in}\raggedleft\includegraphics[width=35pc]{PT1secrule.eps}}] +\titleformat{\subsection}{\Large\centering}% + {\thesubsection}{0.5em}{}[{\color{gray}\titlerule[0.8pt]}] + +% Code font style, for more font style, visit: https://tug.org/FontCatalogue/ +\setmonofont{Inconsolata} +%\renewcommand\ttfamily{\sffamily} + +% Resize all figures +\let\ORIincludegraphics\includegraphics +\renewcommand{\includegraphics}[2][]{\ORIincludegraphics[scale=0.75,#1]{#2}} +% main text font style +\usepackage{times} + +% Rewrite table of contents +\renewcommand\tableofcontents{\@restonecolfalse + \if@twocolumn\@restonecoltrue\onecolumn\fi + %\AJW@addtocfalse + \chapter*{\contentsname} + %\@starttoc{toc} + %\AJW@addtoctrue + \if@restonecol\twocolumn\fi + \@starttoc{toc} +} + +\newcommand\cambridge{PT1} +\theoremstyle{plain}% default +\newtheorem{theorem}{Theorem}[chapter] +\newtheorem{lemma}[theorem]{Lemma} +\newtheorem*{corollary}{Corollary} +\theoremstyle{definition} +\newtheorem{definition}[theorem]{Definition} +\newtheorem{condition}[theorem]{Condition} +\newtheorem{example-norules}[theorem]{Example} +\theoremstyle{remark} +\newtheorem*{remark}{Remark} +\newtheorem*{case}{Case} + + +\hyphenation{line-break line-breaks docu-ment triangle cambridge + amsthdoc cambridgemods baseline-skip author authors + cambridgestyle en-vir-on-ment polar astron-omers solu-tion} + +\setcounter{tocdepth}{1} + +\hbadness=99999 % or any number >=10000 +\vfuzz=30pt +\hfuzz=30pt + +% Defines macros for code-blocks styling +\definecolor{d2lbookOutputCellBackgroundColor}{RGB}{255,255,255} +\definecolor{d2lbookOutputCellBorderColor}{RGB}{0,0,0} +\def\diilbookstyleoutputcell + {\sphinxcolorlet{VerbatimColor}{d2lbookOutputCellBackgroundColor}% + \sphinxcolorlet{VerbatimBorderColor}{d2lbookOutputCellBorderColor}% + \sphinxsetup{verbatimwithframe,verbatimborder=0.5pt}% + }% +% +\definecolor{d2lbookInputCellBackgroundColor}{rgb}{.95,.95,.95} +\def\diilbookstyleinputcell + {\sphinxcolorlet{VerbatimColor}{d2lbookInputCellBackgroundColor}% + \sphinxsetup{verbatimwithframe=false,verbatimborder=0pt}% + }% + +''', +'sphinxsetup': '''verbatimsep=2mm, + VerbatimColor={rgb}{.95,.95,.95}, + VerbatimBorderColor={rgb}{.95,.95,.95}, + pre_border-radius=3pt, + ''', +'maketitle':'\\maketitle', +'tableofcontents': '\\tableofcontents', +'fncychap':'', +'makeindex':'\\makeindex' +} + +latex_additional_files = ["latex_style/PT1/PT1.cls", "latex_style/PT1header.eps", "latex_style/PT1secrule.eps", "latex_style/PT1/PT1box.eps", "latex_style/PT1/PT1chrule.eps", "latex_style/PT1/multind.sty", "latex_style/PT1/amsthm.sty", "latex_style/PT1/floatpag.sty","latex_style/PT1/rotating.sty", "latex_style/PT1/myriad-pt1.sty", "latex_style/PT1/natbib.sty", "latex_style/sphinxlatexstyleheadings.sty", "latex_style/sphinxlatexstylepage.sty", "latex_style/sphinxlatexindbibtoc.sty", "latex_style/sphinxmessages.sty", "latex_style/sphinxlatexobjects.sty", "latex_style/PT1/natbib.dtx", "latex_style/sphinxpackagefootnote.sty", "latex_style/sphinxlatexlists.sty"] + +SPHINX_CONFIGS + +def setup(app): + # app.add_js_file('https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js') + app.add_js_file('d2l.js') + app.add_css_file('d2l.css') + import mxtheme + app.add_directive('card', mxtheme.CardDirective) +""" + google_tracker = """ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ @@ -444,7 +648,7 @@ def setup(app): } .mdl-tabs__tab.is-active { - background: rgb(0,0,0,.09); + background: rgb(0,0,0,.09); } """