diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..8394dba --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,8 @@ +# jira ticket + +https://singular-ai.atlassian.net/browse/ + +# todo list + +- [ ] Version bump +- [ ] Clean up code diff --git a/.github/workflows/release_dev.yml b/.github/workflows/release_dev.yml new file mode 100644 index 0000000..ef9a980 --- /dev/null +++ b/.github/workflows/release_dev.yml @@ -0,0 +1,77 @@ +name: Release Dev Docker image to Linode + +on: + push: + branches-ignore: + - 'master' +env: + IMAGE_NAME_CLIENT: ${{ secrets.DOCKER_USERNAME }}/derecksprojects-client + CONTAINER_NAME_CLIENT: dev_linode_derecksprojects-client + +jobs: + push_to_registry_client: + name: Push Docker client image to Docker Hub + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Login to Docker Hub + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push client image + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 + with: + context: ./ + file: ./Dockerfile + push: true + tags: ${{ env.IMAGE_NAME_CLIENT }}:latest_dev + + deploy_to_linode: + name: Deploy docker-compose.yml to Linode + needs: push_to_registry_client + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Create .env file for docker-compose deployment + run: | + echo IMAGE_NAME_CLIENT=${{ env.IMAGE_NAME_CLIENT }}:latest_dev > .env + echo CONTAINER_NAME_CLIENT=${{ env.CONTAINER_NAME_CLIENT }} >> .env + echo PORT_MAP_CLIENT=3005 >> .env + + - name: Copy docker-compose.yml to remote server + uses: appleboy/scp-action@master + with: + host: ${{ secrets.REMOTE_HOST }} + username: ${{ secrets.REMOTE_USERNAME }} + password: ${{ secrets.REMOTE_PASSWORD }} + port: ${{ secrets.REMOTE_PORT }} + source: './docker-compose.yml, .env' + target: '/root/dev_docker-compose-derecksprojects/' + + - name: Deploy to remote server + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.REMOTE_HOST }} + username: ${{ secrets.REMOTE_USERNAME }} + password: ${{ secrets.REMOTE_PASSWORD }} + port: ${{ secrets.REMOTE_PORT }} + command_timeout: 20m + script: | + cd /root/dev_docker-compose-derecksprojects/ + docker pull ${{ env.IMAGE_NAME_SERVER }}:latest_dev + docker pull ${{ env.IMAGE_NAME_CLIENT }}:latest_dev + docker container prune -f + docker system prune -af + docker rm -f ${{ env.CONTAINER_NAME_SERVER }} || true + docker rm -f ${{ env.CONTAINER_NAME_CLIENT }} || true + docker compose --env-file .env --project-name derecksprojects-dev down + docker compose --env-file .env --project-name derecksprojects-dev up -d diff --git a/.github/workflows/release_prod.yml b/.github/workflows/release_prod.yml new file mode 100644 index 0000000..438d68d --- /dev/null +++ b/.github/workflows/release_prod.yml @@ -0,0 +1,76 @@ +name: Release Prod Docker image to Linode + +on: + release: + types: [published] +env: + IMAGE_NAME_CLIENT: ${{ secrets.DOCKER_USERNAME }}/derecksprojects-client + CONTAINER_NAME_CLIENT: prod_linode_derecksprojects-client + +jobs: + push_to_registry_client: + name: Push Docker client image to Docker Hub + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Login to Docker Hub + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push client image + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 + with: + context: ./ + file: ./Dockerfile + push: true + tags: ${{ env.IMAGE_NAME_CLIENT }}:latest_prod + + deploy_to_linode: + name: Deploy docker-compose.yml to Linode + needs: push_to_registry_client + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Create .env file for docker-compose deployment + run: | + echo IMAGE_NAME_CLIENT=${{ env.IMAGE_NAME_CLIENT }}:latest_prod > .env + echo CONTAINER_NAME_CLIENT=${{ env.CONTAINER_NAME_CLIENT }} >> .env + echo PORT_MAP_CLIENT=3004 >> .env + + - name: Copy docker-compose.yml to remote server + uses: appleboy/scp-action@master + with: + host: ${{ secrets.REMOTE_HOST }} + username: ${{ secrets.REMOTE_USERNAME }} + password: ${{ secrets.REMOTE_PASSWORD }} + port: ${{ secrets.REMOTE_PORT }} + source: './docker-compose.yml, .env' + target: '/root/prod_docker-compose-derecksprojects/' + + - name: Deploy to remote server + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.REMOTE_HOST }} + username: ${{ secrets.REMOTE_USERNAME }} + password: ${{ secrets.REMOTE_PASSWORD }} + port: ${{ secrets.REMOTE_PORT }} + command_timeout: 20m + script: | + cd /root/prod_docker-compose-derecksprojects/ + docker pull ${{ env.IMAGE_NAME_SERVER }}:latest_prod + docker pull ${{ env.IMAGE_NAME_CLIENT }}:latest_prod + docker container prune -f + docker system prune -af + docker rm -f ${{ env.CONTAINER_NAME_SERVER }} || true + docker rm -f ${{ env.CONTAINER_NAME_CLIENT }} || true + docker compose --env-file .env --project-name derecksprojects-prod down + docker compose --env-file .env --project-name derecksprojects-prod up -d diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3b4ec2e --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +# dev +dev/ +deprecated/ + +# machine +.DS_Store + +# tufte quarto template +/env/ +.env +/.quarto/ +TufteStyledBook.tex +TufteStyledBook.cls +TufteStyledBook.toc +TufteStyledBook.bst +TufteStyledBook.pdf +TufteStyledBook.log +TufteStyledBook.aux +TufteStyledBook.def +tufte-book.tex +tufte-book.toc +tufte-book.bst +tufte-book.pdf +tufte-book.log +tufte-book.aux +tufte-book.def +_tufte/ +docs/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6925da7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM dereckmezquita/r-quarto-base:latest AS builder + +WORKDIR /app + +COPY . /app + +# Render Quarto document +RUN quarto render /app --output-dir /app/output + +# Serve static files +FROM nginx:stable-alpine AS runner + +COPY --from=builder /app/output /usr/share/nginx/html + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/README.md b/README.md index 995fde3..939fde3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1 @@ -# derecksprojects.com -Dereck's Projects | Consulting and contracting +# [derecksprojects.com](https://www.derecksprojects.com) diff --git a/_extensions/fredguth/tufte/_extension.yml b/_extensions/fredguth/tufte/_extension.yml new file mode 100644 index 0000000..c38d4f6 --- /dev/null +++ b/_extensions/fredguth/tufte/_extension.yml @@ -0,0 +1,53 @@ +title: Tufte Quarto +author: Fred Guth +version: 1.1.0 +quarto-version: ">=1.2.215" +contributes: + project: + project: + type: book + output-dir: docs + format: + html: + page-layout: full + reference-location: margin + citation-location: block + title-block-style: none + css: styles.css + number-sections: false + linkcolor: Maroon + backgroundcolor: FloralWhite + sidebarbackgroundcolor: FloralWhite + mainfont: "heuristica" + toc-location: left + toc-title: "Contents" + default-image-extension: svg + pdf: + reference-location: margin + citation-location: margin + fig-cap-location: bottom + documentclass: tufte-book + classoption: [sfsidenotes] + number-sections: false + format-resources: + - tufte-book.cls + - tufte-common.def + - tufte.bst + template-partials: # replaces + - "partials/title.tex" + - "partials/before-body.tex" + include-in-header: #adds + - "partials/in-header.tex" + - "partials/definitions.tex" + include-after-body: #adds + - "partials/after-body.tex" + toc-depth: 2 + toc-title: "Contents" + indent: 0px + biblio-style: dinat + # mainfont: "Minion Pro" + mainfont: "ETbb" + sansfont: "TeX Gyre Heros" + sansfontoptions: "Scale=MatchUppercase" + default-image-extension: pdf + diff --git a/_extensions/fredguth/tufte/partials/after-body.tex b/_extensions/fredguth/tufte/partials/after-body.tex new file mode 100644 index 0000000..e69de29 diff --git a/_extensions/fredguth/tufte/partials/before-body.tex b/_extensions/fredguth/tufte/partials/before-body.tex new file mode 100644 index 0000000..a9884a5 --- /dev/null +++ b/_extensions/fredguth/tufte/partials/before-body.tex @@ -0,0 +1,22 @@ +\IfFileExists{Images/bookcover.pdf}{\includepdf{Images/bookcover.pdf}\clearpage}{} + +$if(has-frontmatter)$ +\frontmatter +$endif$ +$if(title)$ +$if(beamer)$ +\frame{\titlepage} +$else$ +\maketitle +\pagenumbering{gobble} +\IfFileExists{01-Front/copyright.tex}{\input{01-Front/copyright.tex}\clearpage}{} +\IfFileExists{01-Front/dedication.tex}{\input{01-Front/dedication.tex}\clearpage}{} +\IfFileExists{01-Front/epigraph.tex}{\input{01-Front/epigraph.tex}\clearpage}{} +$endif$ +$if(abstract)$ +\begin{abstract} +$abstract$ +\end{abstract} +$endif$ +$endif$ +\pagenumbering{arabic} \ No newline at end of file diff --git a/_extensions/fredguth/tufte/partials/definitions.tex b/_extensions/fredguth/tufte/partials/definitions.tex new file mode 100644 index 0000000..875eba3 --- /dev/null +++ b/_extensions/fredguth/tufte/partials/definitions.tex @@ -0,0 +1,108 @@ + +% DEFINITIONS + + +% The fancyvrb package lets us customize the formatting of verbatim +% environments. We use a slightly smaller font. +\usepackage{fancyvrb} +\fvset{fontsize=\normalsize} + +%% +% Prints argument within hanging parentheses (i.e., parentheses that take +% up no horizontal space). Useful in tabular environments. +\newcommand{\hangp}[1]{\makebox[0pt][r]{(}#1\makebox[0pt][l]{)}} + +%% +% Prints an asterisk that takes up no horizontal space. +% Useful in tabular environments. +\newcommand{\hangstar}{\makebox[0pt][l]{*}} + +%% +% Prints a trailing space in a smart way. +\usepackage{xspace} + + +% Prints the month name (e.g., January) and the year (e.g., 2008) +\newcommand{\monthyear}{% + \ifcase\month\or January\or February\or March\or April\or May\or June\or + July\or August\or September\or October\or November\or + December\fi\space\number\year +} + + +% Prints an epigraph and speaker in sans serif, all-caps type. +\newcommand{\epigraph}[2]{% + \begin{fullwidth} + \begin{flushright} + \sffamily\fontsize{8}{10}\selectfont + \sffamily\footnotesize + \begin{doublespace} + \vspace{-8cm}\noindent\allcaps{#1}\\% epigraph + \noindent\allcaps{#2}\\% author + \end{doublespace} + \vspace{5.1cm} + \end{flushright} + \end{fullwidth} + \normalfont +} + + +\newcommand{\blankpage}{\newpage\hbox{}\thispagestyle{empty}\newpage} + + +% insert 4cm before quote +\renewenvironment{quote}{ + \list{}{\leftmargin=3.5cm\topsep=0pt} + \item\relax\small\itshape +} +{\endlist} + + +% change chapter formatting +\titlespacing*{\chapter}{0pt}{5cm}{1cm} +% \titlespacing*{\section}{0pt}{.6em}{.3em} +% \titlespacing*{\subsection}{0pt}{.4em}{.2em} + +\titlespacing*{\section}{0pt}{0pt}{0pt} +\titlespacing*{\subsection}{0pt}{0pt}{0pt} + + +% Change Figure Caption in the Margin size +% \renewenvironment{@tufte@margin@float}[2][-1.2ex]% +% {\FloatBarrier% process all floats before this point so the figure/table numbers stay in order. +% \begin{lrbox}{\@tufte@margin@floatbox}% +% \begin{minipage}{\marginparwidth}% +% \@tufte@caption@font\footnotesize% <-- Add fontnotesize +% \def\@captype{#2}% +% \hbox{}\vspace*{#1}% +% \@tufte@caption@justification% +% \@tufte@margin@par% +% \noindent\normalsize%<-- restored size +% } +% {\end{minipage}% +% \end{lrbox}% +% \marginpar{\usebox{\@tufte@margin@floatbox}}% + % } + + +% \renewcommand\footnotesize{% +% \@setfontsize\footnotesize\@viiipt{9}% +% \abovedisplayskip 5\p@ \@plus2\p@ \@minus4\p@ +% \abovedisplayshortskip \z@ \@plus\p@ +% \belowdisplayshortskip 2.8\p@ \@plus\p@ \@minus2\p@ +% \def\@listi{\leftmargin\leftmargini +% \topsep 2.5\p@ \@plus\p@ \@minus\p@ +% \parsep 2\p@ \@plus\p@ \@minus\p@ +% \itemsep \parsep}% +% \belowdisplayskip \abovedisplayskip +% } + +% % Define Tuftian float styles (with the caption in the margin) +% \newcommand{\floatc@tufteplain}[2]{% +% \begin{lrbox}{\@tufte@caption@box}% +% \begin{minipage}[\floatalignment]{\marginparwidth}\hbox{}% +% \footnotesize\@tufte@caption@font{\@fs@cfont #1:} #2\par\normalsize% +% \end{minipage}% +% \end{lrbox}% +% \smash{\hspace{\@tufte@caption@fill}\usebox{\@tufte@caption@box}}% +% } \ No newline at end of file diff --git a/_extensions/fredguth/tufte/partials/in-header.tex b/_extensions/fredguth/tufte/partials/in-header.tex new file mode 100644 index 0000000..6380868 --- /dev/null +++ b/_extensions/fredguth/tufte/partials/in-header.tex @@ -0,0 +1,77 @@ +% FIX Marginnote duplication +\usepackage{savesym} +\savesymbol{marginfigure} +\savesymbol{marginnote} +\savesymbol{sidenote} + +%%%%%%% +% FIX Makeuppercase error +% FIX Font clash Math error +% See https://tex.stackexchange.com/q/202142/157312 +% + +\renewcommand{\textls}[2][5]{% + \begingroup\addfontfeatures{LetterSpace=#1}#2\endgroup +} +\renewcommand{\allcapsspacing}[1]{\textls[15]{#1}} +\renewcommand{\smallcapsspacing}[1]{\textls[10]{#1}} +\renewcommand{\allcaps}[1]{\textls[15]{\MakeTextUppercase{#1}}} +\renewcommand{\smallcaps}[1]{\smallcapsspacing{\scshape\MakeTextLowercase{#1}}} +\renewcommand{\textsc}[1]{\smallcapsspacing{\textsmallcaps{#1}}} + +\PassOptionsToPackage{no-math}{fontspec} +% \usepackage[mathlf, minionint,footnotefigures, frenchmath]{MinionPro} +% \setmainfont{$$} +% \setsansfont{TeX Gyre Heros}[Scale=MatchUppercase] + +\ExplSyntaxOn +\int_new:N \l_mathcode_minus_int +\int_new:N \l_mathcode_equal_int +\exp_args:Nx \AtBeginDocument { + \exp_not:n { + \int_set:Nn \l_mathcode_minus_int { \XeTeXmathcodenum `\- } + \int_set:Nn \l_mathcode_equal_int { \XeTeXmathcodenum `\= } + } + \mathcode \int_eval:n { `\- } = \number \mathcode `\- \scan_stop: + \mathcode \int_eval:n { `\= } = \number \mathcode `\= \scan_stop: +} +\AtBeginDocument { + \XeTeXmathcodenum `\- = \l_mathcode_minus_int + \XeTeXmathcodenum `\= = \l_mathcode_equal_int +} +\ExplSyntaxOff + +\usepackage[italic]{mathastext} +% \setromanfont{TeX Gyre Termes} + + +%%%%%%% + + +\usepackage{pdfpages} % for cover page +\graphicspath{{Images/}} % Make Images/ default figure path + + +\setlength{\parindent}{0pt}% +\setlength{\RaggedRightParindent}{0pt} +\setlength{\JustifyingParindent}{0pt}% +\setlength{\parskip}{\baselineskip} + +%% +% Produces a full title page + +\renewcommand{\maketitlepage}[0]{% + \cleardoublepage% + {% + \sffamily% + \begin{fullwidth}% + \fontsize{12}{14}\selectfont\par\noindent\textcolor{darkgray}{\allcaps{\thanklessauthor}}% + \vspace{12.5pc}% + \fontsize{20}{28}\selectfont\par\noindent\textcolor{darkgray}{\allcaps{\thanklesstitle}}% + \vfill% + \fontsize{10}{12}\selectfont\par\noindent\allcaps{\thanklesspublisher}% + \end{fullwidth}% + } + \thispagestyle{empty}% + \clearpage% +} diff --git a/_extensions/fredguth/tufte/partials/title.tex b/_extensions/fredguth/tufte/partials/title.tex new file mode 100644 index 0000000..bbf5e44 --- /dev/null +++ b/_extensions/fredguth/tufte/partials/title.tex @@ -0,0 +1,17 @@ + +% TITLE PAGE + +$if(book.title)$ +\title[$book.title-short$]{$title$} +$endif$ +$if(book.author)$ +\author{$author$} +$endif$ +$if(book.publisher)$ +\publisher{$book.publisher$} +$endif$ + + + + + diff --git a/_extensions/fredguth/tufte/styles.css b/_extensions/fredguth/tufte/styles.css new file mode 100644 index 0000000..6811d68 --- /dev/null +++ b/_extensions/fredguth/tufte/styles.css @@ -0,0 +1,171 @@ +.column-margin figcaption, .margin-caption, div.aside, aside, .column-margin { + color: #5a6570; + font-size: .625rem; +} +.sidebar-title { + margin-top: .25rem; + padding-bottom: .5rem; + font-size: .76rem; + line-height: 1rem; + visibility: visible; +} + +.sidebar-item-container .chapter-number { + color: #212529; + font-size: .7rem; +} + +.title .chapter-number { + color: #212529; + font-size: 1.5rem; + margin-right: 2rem; +} + +.header-section-number { + color: #5a6570; + font-size: 1.3rem; + margin-right: 2rem; +} + +html { + scroll-behavior: smooth; +} + +body { + font-size: 18px; + line-height: 24px; + quotes: "‘" "’"; +} + +/* h1 { + font-family: 'Minion Pro', 'Crimson', serif; + font-style: italic; + padding-bottom: 1rem; + letter-spacing: 0rem; +} */ + +header .chapter-title { + font-family: 'Minion Pro', 'Crimson', serif; + font-style: italic; + text-transform: none; + font-size: 2.2rem; + letter-spacing: normal; +} + +.sidebar { + font-family: sans-serif; + +} + +/* Hide scrollbar for Chrome, Safari and Opera */ +.sidebar::-webkit-scrollbar { + display: none; +} + +/* Hide scrollbar for IE, Edge and Firefox */ +.sidebar { + -ms-overflow-style: none; /* IE and Edge */ + scrollbar-width: none; /* Firefox */ +} + +.navbar-brand { + font-family: helvetica, monospace; + font-style: normal; + text-transform: uppercase; + letter-spacing: .11em; + line-height: 1.5rem; + font-size: 1em; +} +.sidebar-header > div > div > a > i { +display: none +} + +.navbar-brand > a{ + color: maroon; +} +.sidebar nav[role=doc-toc] ul { + font-size: 14px; +} +.sidebar nav[role=doc-toc] ul>li>a.active { + border-left: 1px solid maroon; + color: maroon !important; +} +.sidebar nav[role=doc-toc] ul>li>ul>li>a.active { + border-left: 1px solid maroon; + color: maroon !important; +} +.sidebar-title { + font-family: helvetica, monospace; + font-style: normal; + text-transform: uppercase; + letter-spacing: .11em; + line-height: 1.12rem; + font-size: .48rem; +} +.quarto-secondary-nav-title, .title { + /* font-family: 'Minion Pro', 'Crimson', serif; */ + font-family: helvetica, monospace; + font-style: normal; + text-transform: uppercase; + letter-spacing: .125em; + line-height: 1.25em; + font-size: 1.5rem; + padding-top: .825rem + +} +.quarto-secondary-nav-title { + font-size: 1.1rem; +} +.blockquote { + border-left: none; +} +.blockquote p { + font-size: smaller; + color: #5a6570; + font-style: italic; +} + + +@media (min-width:1280px) { + .blockquote p { + padding-left: 4cm; + } +} + +.panel-caption, .figure-caption, figcaption { + color: #5a6570; + font-size: .825rem; + margin-bottom: .825rem; +} + +.theorem-title { + margin-right: 1.5rem; +} + + +#fig-cover img { + background-color: white; + border: 1px solid #555; +} + +.figure-img { + margin: auto; +} + +#quarto-sidebar { + background: transparent; +} + +div.sidebar-item-container .active, div.sidebar-item-container :hover, div.sidebar-item-container .show>.nav-link, div.sidebar-item-container .sidebar-link>code { + color: maroon; +} + +nav[role=doc-toc] { + padding-bottom: 100px; +} + +.sans-serif { + font-family: helvetica, monospace; + font-style: normal; + text-transform: uppercase; +} \ No newline at end of file diff --git a/_extensions/fredguth/tufte/tufte-book.cls b/_extensions/fredguth/tufte/tufte-book.cls new file mode 100644 index 0000000..f733ce2 --- /dev/null +++ b/_extensions/fredguth/tufte/tufte-book.cls @@ -0,0 +1,88 @@ +\NeedsTeXFormat{LaTeX2e}[1994/06/01] + +\ProvidesClass{tufte-book}[2015/06/30 v3.5.3 Tufte-book class] + +%% +% Declare we're tufte-book +\newcommand{\@tufte@class}{book}% the base LaTeX class (defaults to the book style) +\newcommand{\@tufte@pkgname}{tufte-book}% the name of the package (defaults to tufte-handout) + +%% +% Load the common style elements +\input{tufte-common.def} + + +%% +% Set up any book-specific stuff now + +%% +% The front matter in Tufte's /Beautiful Evidence/ contains everything up +% to the opening page of Chapter 1. The running heads, when they appear, +% contain only the (arabic) page number in the outside corner. +%\newif\if@mainmatter \@mainmattertrue +\renewcommand\frontmatter{% + \if@openright% + \cleardoublepage% + \else% + \clearpage% + \fi% + \@mainmatterfalse% + \pagenumbering{arabic}% + %\pagestyle{plain}% + \fancyhf{}% + \ifthenelse{\boolean{@tufte@twoside}}% + {\fancyhead[LE,RO]{\thepage}}% + {\fancyhead[RE,RO]{\thepage}}% +} + + +%% +% The main matter in Tufte's /Beautiful Evidence/ doesn't restart the page +% numbering---it continues where it left off in the front matter. +\renewcommand\mainmatter{% + \if@openright% + \cleardoublepage% + \else% + \clearpage% + \fi% + \@mainmattertrue% + \fancyhf{}% + \ifthenelse{\boolean{@tufte@twoside}}% + {% two-side + \renewcommand{\chaptermark}[1]{\markboth{##1}{}}% + \fancyhead[LE]{\thepage\quad\smallcaps{\newlinetospace{\plaintitle}}}% book title + \fancyhead[RO]{\smallcaps{\newlinetospace{\leftmark}}\quad\thepage}% chapter title + }% + {% one-side + \fancyhead[RE,RO]{\smallcaps{\newlinetospace{\plaintitle}}\quad\thepage}% book title + }% +} + + +%% +% The back matter contains appendices, indices, glossaries, endnotes, +% bibliographies, list of contributors, illustration credits, etc. +\renewcommand\backmatter{% + \if@openright% + \cleardoublepage% + \else% + \clearpage% + \fi% + \@mainmatterfalse% +} + +%% +% Only show the chapter titles in the table of contents +\setcounter{tocdepth}{0} + +%% +% If there is a `tufte-book-local.sty' file, load it. + +\IfFileExists{tufte-book-local.tex}{% + \@tufte@info@noline{Loading tufte-book-local.tex}% + \input{tufte-book-local}% +}{} + +%% +% End of file +\endinput diff --git a/_extensions/fredguth/tufte/tufte-common.def b/_extensions/fredguth/tufte/tufte-common.def new file mode 100644 index 0000000..2aea90a --- /dev/null +++ b/_extensions/fredguth/tufte/tufte-common.def @@ -0,0 +1,2026 @@ +%% +%% This file contains the code that is common to the Tufte-LaTeX document classes. +%% + +\ProvidesFile{tufte-common.def}[2015/06/21 v3.5.2 Common code for the Tufte-LaTeX styles] + +%% +% The `xkeyval' package simplifies the user interface for the document class options +\RequirePackage{xkeyval} + +%% +% We use the `xifthen' package to handle our package option switches +\RequirePackage{xifthen} + +%% +% Define some shortcut macros for error/warning/info logging. +\RequirePackage{hardwrap} +\GenerateClassLogMacros[@tufte]{\@tufte@pkgname} +\newcommand{\@tufte@debug@info}[1]{\ifthenelse{\boolean{@tufte@debug}}{\@tufte@info{#1}}{}} +\newcommand{\@tufte@debug@info@noline}[1]{\ifthenelse{\boolean{@tufte@debug}}{\@tufte@info@noline{#1}}{}} + +%% +% `debug' option -- provides more information in the .log file for use in +% troubleshooting problems +\newboolean{@tufte@debug} +\DeclareOptionX[tufte]{debug}{\setboolean{@tufte@debug}{true}} + +%% +% `nofonts' option -- doesn't load any fonts +% `fonts' option -- tries to load fonts +\newboolean{@tufte@loadfonts}\setboolean{@tufte@loadfonts}{true} +\DeclareOptionX[tufte]{fonts}{\setboolean{@tufte@loadfonts}{true}} +\DeclareOptionX[tufte]{nofonts}{\setboolean{@tufte@loadfonts}{false}} + +%% +% `nols' option -- doesn't configure letterspacing +% `ls' option -- configures letterspacing +\newboolean{@tufte@letterspace}\setboolean{@tufte@letterspace}{true} +\DeclareOptionX[tufte]{ls}{\setboolean{@tufte@letterspace}{true}} +\DeclareOptionX[tufte]{nols}{\setboolean{@tufte@letterspace}{false}} + +%% +% `nobib' option -- doesn't load natbib or adjust the \cite command +\newboolean{@tufte@loadnatbib}\setboolean{@tufte@loadnatbib}{true} +\DeclareOptionX[tufte]{nobib}{\setboolean{@tufte@loadnatbib}{false}} + +%% +% `titlepage' option -- creates a full title page with \maketitle + +\newboolean{@tufte@titlepage} +\DeclareOptionX[tufte]{titlepage}{\setboolean{@tufte@titlepage}{true}} +\DeclareOptionX[tufte]{notitlepage}{\setboolean{@tufte@titlepage}{false}} + +%% +% `a4paper' option + +\newboolean{@tufte@afourpaper} +\DeclareOptionX[tufte]{a4paper}{\setboolean{@tufte@afourpaper}{true}} + +%% +% `b5paper' option + +\newboolean{@tufte@bfivepaper} +\DeclareOptionX[tufte]{b5paper}{\setboolean{@tufte@bfivepaper}{true}} + +%% +% `sfsidenotes' option -- typesets sidenotes in sans serif typeface + +\newboolean{@tufte@sfsidenotes} +\DeclareOptionX[tufte]{sfsidenotes}{\setboolean{@tufte@sfsidenotes}{true}} + +%% +% `symmetric' option -- puts marginpar space to the outside edge of the page +% Note: this option forces the twoside option (see the .cls files) + +\newboolean{@tufte@symmetric} +\DeclareOptionX[tufte]{symmetric}{ + \setboolean{@tufte@symmetric}{true} + \@tufte@info@noline{The `symmetric' option implies `twoside'} + \ExecuteOptionsX[tufte]{twoside} +} + +%% +% `twoside' option -- alternates running heads + +\newboolean{@tufte@twoside} +\DeclareOptionX[tufte]{twoside}{% + \setboolean{@tufte@twoside}{true} + \@tufte@info@noline{Passing the `twoside' option to the `\@tufte@class' class} + \PassOptionsToClass{twoside}{\@tufte@class} +} + +%% +% `notoc' option -- suppresses the Tufte-style table of contents + +\newboolean{@tufte@toc} +\setboolean{@tufte@toc}{true} +\DeclareOptionX[tufte]{notoc}{\setboolean{@tufte@toc}{false}} +\DeclareOptionX[tufte]{toc}{\setboolean{@tufte@toc}{true}} + +%% +% `justified' option -- uses fully justified text (flush left and flush +% right) instead of ragged right. + +\newboolean{@tufte@justified} +\DeclareOptionX[tufte]{justified}{\setboolean{@tufte@justified}{true}} + +%% +% `bidi' option -- loads the bidi package for bi-directional text + +\newboolean{@tufte@loadbidi} +\DeclareOptionX[tufte]{bidi}{\setboolean{@tufte@loadbidi}{true}} +\DeclareOptionX[tufte]{nobidi}{\setboolean{@tufte@loadbidi}{false}} + +%% +% `nohyper' option -- suppresses loading of the hyperref package + +\newboolean{@tufte@loadhyper} +\setboolean{@tufte@loadhyper}{true} +\DeclareOptionX[tufte]{hyper}{\setboolean{@tufte@loadhyper}{true}} +\DeclareOptionX[tufte]{nohyper}{\setboolean{@tufte@loadhyper}{false}} + +%% +% `sidenote', `marginnote', `caption', `citation', `marginals' options +% Each allows one of {justified,raggedleft,raggedright,raggedouter,auto}. + +\newcommand*{\@tufte@sidenote@justification}{\@tufte@justification@autodetect} +\define@choicekey*+[tufte]{common}{sidenoteTFT}[\@tufte@kvtext\@tufte@kvnum]{justified,raggedleft,raggedright,raggedouter,auto}[auto]{% + \ifcase\@tufte@kvnum\relax + \renewcommand*{\@tufte@sidenote@justification}{\justifying}% justified + \or + \renewcommand*{\@tufte@sidenote@justification}{\RaggedLeft}% ragged left + \or + \renewcommand*{\@tufte@sidenote@justification}{\RaggedRight}% ragged right + \or + \renewcommand*{\@tufte@sidenote@justification}{\@tufte@justification@outer}% ragged outer (flush right on verso pages, flush left on recto pages) + \or + \renewcommand*{\@tufte@sidenote@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options + \fi +}{% + \@tufte@warning@noline{Invalid option `#1' for sidenote key. Must be one of: justified, raggedleft, raggedright, raggedouter, auto} + \renewcommand*{\@tufte@sidenote@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options +} + +\newcommand*{\@tufte@marginnote@justification}{\@tufte@justification@autodetect} +\define@choicekey*+[tufte]{common}{marginnote}[\@tufte@kvtext\@tufte@kvnum]{justified,raggedleft,raggedright,raggedouter,auto}[auto]{% + \ifcase\@tufte@kvnum\relax + \renewcommand*{\@tufte@marginnote@justification}{\justifying}% justified + \or + \renewcommand*{\@tufte@marginnote@justification}{\RaggedLeft}% ragged left + \or + \renewcommand*{\@tufte@marginnote@justification}{\RaggedRight}% ragged right + \or + \renewcommand*{\@tufte@marginnote@justification}{\@tufte@justification@outer}% ragged outer (flush right on verso pages, flush left on recto pages) + \or + \renewcommand*{\@tufte@marginnote@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options + \fi +}{% + \@tufte@warning@noline{Invalid option `#1' for marginnote key. Must be one of: justified, raggedleft, raggedright, raggedouter, auto} + \renewcommand*{\@tufte@marginnote@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options +} + +\newcommand*{\@tufte@caption@justification}{\@tufte@justification@autodetect} +\define@choicekey*+[tufte]{common}{caption}[\@tufte@kvtext\@tufte@kvnum]{justified,raggedleft,raggedright,raggedouter,auto}[auto]{% + \ifcase\@tufte@kvnum\relax + \renewcommand*{\@tufte@caption@justification}{\justifying}% justified + \or + \renewcommand*{\@tufte@caption@justification}{\RaggedLeft}% ragged left + \or + \renewcommand*{\@tufte@caption@justification}{\RaggedRight}% ragged right + \or + \renewcommand*{\@tufte@caption@justification}{\@tufte@justification@caption@outer}% ragged outer (flush right on verso pages, flush left on recto pages) + \or + \renewcommand*{\@tufte@caption@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options + \fi +}{% + \@tufte@warning@noline{Invalid option `#1' for caption key. Must be one of: justified, raggedleft, raggedright, raggedouter, auto} + \renewcommand*{\@tufte@caption@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options +} + +\newcommand*{\@tufte@citation@justification}{\@tufte@justification@autodetect} +\define@choicekey*+[tufte]{common}{citation}[\@tufte@kvtext\@tufte@kvnum]{justified,raggedleft,raggedright,raggedouter,auto}[auto]{% + \ifcase\@tufte@kvnum\relax + \renewcommand*{\@tufte@citation@justification}{\justifying}% justified + \or + \renewcommand*{\@tufte@citation@justification}{\RaggedLeft}% ragged left + \or + \renewcommand*{\@tufte@citation@justification}{\RaggedRight}% ragged right + \or + \renewcommand*{\@tufte@citation@justification}{\@tufte@justification@outer}% ragged outer (flush right on verso pages, flush left on recto pages) + \or + \renewcommand*{\@tufte@citation@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options + \fi +}{% + \@tufte@warning@noline{Invalid option `#1' for citation key. Must be one of: justified, raggedleft, raggedright, raggedouter, auto} + \renewcommand*{\@tufte@citation@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options +} + +% The ``marginals'' key simultaneously sets the same justification for all marginal material +\define@choicekey*+[tufte]{common}{marginals}[\@tufte@kvtext\@tufte@kvnum]{justified,raggedleft,raggedright,raggedouter,auto}[auto]{% + \ifcase\@tufte@kvnum\relax + \ExecuteOptionsX[tufte]{citation=justified,sidenote=justified,caption=justified,marginnote=justified}% justified + \or + \ExecuteOptionsX[tufte]{citation=raggedleft,sidenote=raggedleft,caption=raggedleft,marginnote=raggedleft}% ragged left + \or + \ExecuteOptionsX[tufte]{citation=raggedright,sidenote=raggedright,caption=raggedright,marginnote=raggedright}% ragged right + \or + \ExecuteOptionsX[tufte]{citation=raggedouter,sidenote=raggedouter,caption=raggedouter,marginnote=raggedouter}% ragged outer (flush right on verso pages, flush left on recto pages) + \or + \ExecuteOptionsX[tufte]{citation=auto,sidenote=auto,caption=auto,marginnote=auto}% autodetects best justification mode based on all class options + \fi +}{% + \@tufte@warning@noline{Invalid option `#1' for marginals key. Must be one of: justified, raggedleft, raggedright, raggedouter, auto} + \ExecuteOptionsX[tufte]{citation=auto,sidenote=auto,caption=auto,marginnote=auto}% autodetects best justification mode based on all class options +} + + +%% +% Unsupported options + +\newcommand{\@tufte@unsupported@option}[1]{\@tufte@warning@noline{Option `#1' is not supported -- ignoring option}\OptionNotUsed} + +\DeclareOptionX[tufte]{10pt}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{11pt}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{12pt}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{a5paper}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{executivepaper}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{legalpaper}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{landscape}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{onecolumn}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{twocolumn}{\@tufte@unsupported@option{\CurrentOption}} + +%% +% Default `book' and `handout' options + +\ifthenelse{\equal{\@tufte@pkgname}{tufte-book}} + {\ExecuteOptionsX[tufte]{titlepage}} + {\ExecuteOptionsX[tufte]{notitlepage}} + + +\DeclareOptionX*{% + \@tufte@info@noline{Passing \CurrentOption\space to the `\@tufte@class' class.}% + \PassOptionsToClass{\CurrentOption}{\@tufte@class}% +} +\ProcessOptionsX*[tufte]\relax + +%% +% Load the appropriate base class +\@tufte@info@noline{Loading the base class `\@tufte@class'} +\LoadClass{\@tufte@class} + +%% +% Detect whether we're in two-side mode or not. (Used to set up running +% heads later.) + +\ifthenelse{\boolean{@twoside}} + {\setboolean{@tufte@twoside}{true}} + {} + + + +%% +% Detect if we're using pdfLaTeX + +\newboolean{@tufte@pdf} +\IfFileExists{ifpdf.sty}{% + \RequirePackage{ifpdf} + \ifthenelse{\boolean{pdf}} + {\setboolean{@tufte@pdf}{true}} + {\setboolean{@tufte@pdf}{false}} +}{% assume we're not using pdfTex? + \setboolean{@tufte@pdf}{false} +} + +%% +% Detect if we're using XeLaTeX + +\newboolean{@tufte@xetex} +\IfFileExists{ifxetex.sty}{% + \RequirePackage{ifxetex} + \ifthenelse{\boolean{xetex}} + {\setboolean{@tufte@xetex}{true}} + {\setboolean{@tufte@xetex}{false}} +}{% not using xelatex + \setboolean{@tufte@xetex}{false} +} + +\ifthenelse{\boolean{@tufte@xetex}}{% + \RequirePackage{xltxtra}% xltxtra loads xunicode and fontspec; must be loaded before bidi +}{} + +%% +% Detect if we're using LuaTeX + +\newboolean{@tufte@luatex} +\IfFileExists{ifluatex.sty}{% + \RequirePackage{ifluatex} + \ifthenelse{\boolean{luatex}} + {\setboolean{@tufte@luatex}{true}} + {\setboolean{@tufte@luatex}{false}} +}{% not using luatex + \setboolean{@tufte@luatex}{false} +} + +\ifthenelse{\boolean{@tufte@luatex}}{% + \RequirePackage{fontspec} + \RequirePackage[osf,sc]{mathpazo} + \setmainfont[Renderer=Basic, Numbers=OldStyle, Scale = 1.0]{TeX Gyre Pagella} + \setsansfont[Renderer=Basic, Scale=0.90]{TeX Gyre Heros} + \setmonofont[Renderer=Basic]{TeX Gyre Cursor} +}{} + +%% +% Globally sets the length + +\newcommand*{\gsetlength}[2]{% + \setlength{#1}{#2}% + \global#1=#1\relax% +} + +%% +% Globally sets a boolean + +\newcommand*{\gsetboolean}[2]{% based on code from ifthen pkg + \lowercase{\def\@tempa{#2}}% + \@ifundefined{@tempswa\@tempa}% + {\PackageError{ifthen}{You can only set a boolean to `true' or `false'}\@ehc}% + {\@ifundefined{#1\@tempa}% + {\PackageError{ifthen}{Boolean #1 undefined}\@ehc}% + {\global\csname#1\@tempa\endcsname}% + }% +} + +%% +% The titlesec and titletoc packages are used to change the style of the +% section headings. These packages should be loaded before the hyperref +% package. + +\RequirePackage{titlesec,titletoc} + +%%% +%% Loads the hyperref package and sets some default options. + +\newcommand{\TufteLoadHyperref}{% + \ifthenelse{\boolean{@tufte@xetex}} + {\RequirePackage[unicode,hyperfootnotes=false,xetex]{hyperref}} + {\RequirePackage[unicode,hyperfootnotes=false]{hyperref}} + \hypersetup{% + pdfborder = {0 0 0}, + bookmarksdepth = section, + citecolor = DarkGreen, + linkcolor = DarkBlue, + urlcolor = DarkGreen, + }% +} + +%%% +%% Load the `hyperref' package. + +\ifthenelse{\boolean{@tufte@loadhyper}}{% + \TufteLoadHyperref% +}{% hyperfootnotes override our modifications to the \footnote* and \@footnote* commands. + \PassOptionsToPackage{hyperfootnotes=false}{hyperref} +} + +%% +% Set the font sizes and baselines to match Tufte's books +\renewcommand\normalsize{% + \@setfontsize\normalsize\@xpt{14}% + \abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@ + \abovedisplayshortskip \z@ \@plus3\p@ + \belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@ + \belowdisplayskip \abovedisplayskip + \let\@listi\@listI} +\normalbaselineskip=14pt +\normalsize +\renewcommand\small{% + \@setfontsize\small\@ixpt{12}% + \abovedisplayskip 8.5\p@ \@plus3\p@ \@minus4\p@ + \abovedisplayshortskip \z@ \@plus2\p@ + \belowdisplayshortskip 4\p@ \@plus2\p@ \@minus2\p@ + \def\@listi{\leftmargin\leftmargini + \topsep 4\p@ \@plus2\p@ \@minus2\p@ + \parsep 2\p@ \@plus\p@ \@minus\p@ + \itemsep \parsep}% + \belowdisplayskip \abovedisplayskip +} +\renewcommand\footnotesize{% + \@setfontsize\footnotesize\@viiipt{10}% + \abovedisplayskip 6\p@ \@plus2\p@ \@minus4\p@ + \abovedisplayshortskip \z@ \@plus\p@ + \belowdisplayshortskip 3\p@ \@plus\p@ \@minus2\p@ + \def\@listi{\leftmargin\leftmargini + \topsep 3\p@ \@plus\p@ \@minus\p@ + \parsep 2\p@ \@plus\p@ \@minus\p@ + \itemsep \parsep}% + \belowdisplayskip \abovedisplayskip +} +\renewcommand\scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt} +\renewcommand\tiny{\@setfontsize\tiny\@vpt\@vipt} +\renewcommand\large{\@setfontsize\large\@xipt{15}} +\renewcommand\Large{\@setfontsize\Large\@xiipt{16}} +\renewcommand\LARGE{\@setfontsize\LARGE\@xivpt{18}} +\renewcommand\huge{\@setfontsize\huge\@xxpt{30}} +\renewcommand\Huge{\@setfontsize\Huge{24}{36}} + +\setlength\leftmargini {1pc} +\setlength\leftmarginii {1pc} +\setlength\leftmarginiii {1pc} +\setlength\leftmarginiv {1pc} +\setlength\leftmarginv {1pc} +\setlength\leftmarginvi {1pc} +\setlength\labelsep {.5pc} +\setlength\labelwidth {\leftmargini} +\addtolength\labelwidth{-\labelsep} + +%% +% \RaggedRight allows hyphenation + +\setlength{\parindent}{1.0pc}% +\setlength{\parskip}{0pt}% +\RequirePackage{ragged2e} +\setlength{\RaggedRightRightskip}{\z@ plus 0.08\hsize} + +% Paragraph indentation and separation for normal text +\newcommand{\@tufte@reset@par}{% + \setlength{\RaggedRightParindent}{1.0pc}% + \setlength{\JustifyingParindent}{1.0pc}% + \setlength{\parindent}{1pc}% + \setlength{\parskip}{0pt}% +} +\@tufte@reset@par + +% Paragraph indentation and separation for marginal text +\newcommand{\@tufte@margin@par}{% + \setlength{\RaggedRightParindent}{0.5pc}% + \setlength{\JustifyingParindent}{0.5pc}% + \setlength{\parindent}{0.5pc}% + \setlength{\parskip}{0pt}% +} + + +%% +% Set page layout geometry + +\RequirePackage[letterpaper,left=1in,top=1in,headsep=2\baselineskip,textwidth=26pc,marginparsep=2pc,marginparwidth=12pc,textheight=44\baselineskip,headheight=\baselineskip]{geometry} + +\ifthenelse{\boolean{@tufte@afourpaper}} + {\geometry{a4paper,left=24.8mm,top=27.4mm,headsep=2\baselineskip,textwidth=107mm,marginparsep=8.2mm,marginparwidth=49.4mm,textheight=49\baselineskip,headheight=\baselineskip}} + {} + +\ifthenelse{\boolean{@tufte@bfivepaper}} + {\geometry{paperwidth=176mm,paperheight=250mm,left=14.66mm,top=13.88mm,textwidth=102.66mm,marginparsep=7.33mm,marginparwidth=36.66mm,textheight=38\baselineskip,includehead}} + {} + +\ifthenelse{\boolean{@tufte@symmetric}} + {} + {\geometry{asymmetric}}% forces internal LaTeX `twoside' + + +%% +% Separation marginpars by a line's worth of space. + +\setlength\marginparpush{10pt} + +%% +% Font for margin items + +\ifthenelse{\boolean{@tufte@sfsidenotes}} + {\newcommand{\@tufte@marginfont}{\normalfont\footnotesize\sffamily}} + {\newcommand{\@tufte@marginfont}{\normalfont\footnotesize}} + +\newcommand*{\@tufte@sidenote@font}{\@tufte@marginfont} +\newcommand*{\@tufte@caption@font}{\@tufte@marginfont} +\newcommand*{\@tufte@marginnote@font}{\@tufte@marginfont} +\newcommand*{\@tufte@citation@font}{\@tufte@marginfont} + +\newcommand*{\setsidenotefont}[1]{\renewcommand*{\@tufte@sidenote@font}{#1}} +\newcommand*{\setcaptionfont}[1]{\renewcommand*{\@tufte@caption@font}{#1}} +\newcommand*{\setmarginnotefont}[1]{\renewcommand*{\@tufte@marginnote@font}{#1}} +\newcommand*{\setcitationfont}[1]{\renewcommand*{\@tufte@citation@font}{#1}} + +%% +% Set the justification based on the `justified' class option + +\newcommand{\@tufte@justification}{% + \ifthenelse{\boolean{@tufte@justified}}% + {\justifying}% + {\RaggedRight}% +} + +%% +% Turn off section numbering + +\setcounter{secnumdepth}{-1} + +%% +% Tighten up space between displays (e.g., a figure or table) and make symmetric + +\setlength\abovedisplayskip{6pt plus 2pt minus 4pt} +\setlength\belowdisplayskip{6pt plus 2pt minus 4pt} + +%% +% To implement full-width display environments + +\newboolean{@tufte@changepage} +\IfFileExists{changepage.sty}{% + \@tufte@debug@info@noline{Found changepage.sty} + \RequirePackage[strict]{changepage} + \setboolean{@tufte@changepage}{true} +}{% + \@tufte@debug@info@noline{Found chngpage.sty} + \RequirePackage[strict]{chngpage} + \setboolean{@tufte@changepage}{false} +} + +% Write our own aliases for the \checkoddpage and \ifoddpage or \ifcpoddpage commands +\newboolean{@tufte@odd@page} +\setboolean{@tufte@odd@page}{true} +\newcommand*{\@tufte@checkoddpage}{% + \checkoddpage% + \ifthenelse{\boolean{@tufte@changepage}}{% + \ifoddpage% + \setboolean{@tufte@odd@page}{true}% + \else% + \setboolean{@tufte@odd@page}{false}% + \fi% + }{% + \ifcpoddpage% + \setboolean{@tufte@odd@page}{true}% + \else% + \setboolean{@tufte@odd@page}{false}% + \fi% + }% +} + +%% +% Compute lengths used for full-width displays + +\newlength{\@tufte@overhang}% used by the fullwidth environment and the running heads +\newlength{\@tufte@fullwidth} +\newlength{\@tufte@caption@fill} + +\newcommand{\TufteRecalculate}{% + \setlength{\@tufte@overhang}{\marginparwidth} + \addtolength{\@tufte@overhang}{\marginparsep} + + \setlength{\@tufte@fullwidth}{\textwidth} + \addtolength{\@tufte@fullwidth}{\marginparsep} + \addtolength{\@tufte@fullwidth}{\marginparwidth} + + \setlength{\@tufte@caption@fill}{\textwidth} + \addtolength{\@tufte@caption@fill}{\marginparsep} +} + +\AtBeginDocument{\TufteRecalculate} + +%% +% Modified \title, \author, and \date commands. These store the +% (footnote-less) values in \plaintitle, \plainauthor, and \thedate, respectively. + +\newcommand{\plaintitle}{}% plain-text-only title +\newcommand{\plainauthor}{}% plain-text-only author +\newcommand{\plainpublisher}{}% plain-text-only publisher + +\newcommand{\thanklesstitle}{}% full title text minus \thanks{} +\newcommand{\thanklessauthor}{}% full author text minus \thanks{} +\newcommand{\thanklesspublisher}{}% full publisher minus \thanks{} + +\newcommand{\@publisher}{}% full publisher with \thanks{} +\newcommand{\thedate}{\today} + +% TODO Fix it so that \thanks is not spaced out (with `soul') and can be +% used in \maketitle when the `sfsidenotes' option is provided. +\renewcommand{\thanks}[1]{\NoCaseChange{\footnote{#1}}} + +\renewcommand{\title}[2][]{% + \gdef\@title{#2}% + \begingroup% + % TODO store contents of \thanks command + \renewcommand{\thanks}[1]{}% swallow \thanks contents + \protected@xdef\thanklesstitle{#2}% + \endgroup% + \ifthenelse{\isempty{#1}}% + {\renewcommand{\plaintitle}{\thanklesstitle}}% use thankless title + {\renewcommand{\plaintitle}{#1}}% use provided plain-text title + \ifthenelse{\isundefined{\hypersetup}}% + {}% hyperref is not loaded; do nothing + {\hypersetup{pdftitle={\plaintitle}}}% set the PDF metadata title +} + +\let\@author\@empty% suppress default latex.ltx ``no author'' warning +\renewcommand{\author}[2][]{% + \ifthenelse{\isempty{#2}}{}{\gdef\@author{#2}}% + \begingroup% + % TODO store contents of \thanks command + \renewcommand{\thanks}[1]{}% swallow \thanks contents + \protected@xdef\thanklessauthor{#2}% + \endgroup% + \ifthenelse{\isempty{#1}}% + {\renewcommand{\plainauthor}{\thanklessauthor}}% use thankless author + {\renewcommand{\plainauthor}{#1}}% use provided plain-text author + \ifthenelse{\isundefined{\hypersetup}}% + {}% hyperref is not loaded; do nothing + {\hypersetup{pdfauthor={\plainauthor}}}% set the PDF metadata author +} + +\renewcommand{\date}[1]{% + \gdef\@date{#1}% + \begingroup% + % TODO store contents of \thanks command + \renewcommand{\thanks}[1]{}% swallow \thanks contents + \protected@xdef\thedate{#1}% + \endgroup% +} + +%% +% Provides a \publisher command to set the publisher + +\newcommand{\publisher}[2][]{% + \gdef\@publisher{#2}% + \begingroup% + \renewcommand{\thanks}[1]{}% swallow \thanks contents + \protected@xdef\thanklesspublisher{#2}% + \endgroup% + \ifthenelse{\isempty{#1}} + {\renewcommand{\plainpublisher}{\thanklesspublisher}}% use thankless publisher + {\renewcommand{\plainpublisher}{#1}}% use provided plain-text publisher +} + +% TODO: Test \hypersetup{pdfauthor,pdftitle} with DVI and XeTeX + +%% +% Require paralist package for tighter lists + +\RequirePackage{paralist} + +% Add rightmargin to compactenum + +\def\@compactenum@{% + \expandafter\list\csname label\@enumctr\endcsname{% + \usecounter{\@enumctr}% + \rightmargin=2em% added this + \parsep\plparsep + \itemsep\plitemsep + \topsep\pltopsep + \partopsep\plpartopsep + \def\makelabel##1{\hss\llap{##1}}}} + +%% +% Improved letterspacing of small caps and all-caps text. +% +% First, try to use the `microtype' package, if it's available. +% Failing that, try to use the `soul' package, if it's available. +% Failing that, well, I give up. + +\DeclareTextFontCommand{\textsmallcaps}{\scshape} + +\RequirePackage{textcase} % provides \MakeTextUppercase and \MakeTextLowercase +\def\allcapsspacing{\@tufte@warning{Proper spacing of ALL-CAPS letters has not been set up.}} +\def\smallcapsspacing{\@tufte@warning{Proper spacing of small-caps letters has not been set up.}} +\newcommand{\allcaps}[1]{\allcapsspacing{\MakeTextUppercase{#1}}} +\newcommand{\smallcaps}[1]{\smallcapsspacing{\MakeTextLowercase{#1}}} + +% If we're using pdfLaTeX v1.40+, use the letterspace package. +% If we're using pdfLaTex < v1.40, use the soul package. +% If we're using XeLaTeX, use XeLaTeX letterspacing options. +% Otherwise fall back on the soul package. + +\ifthenelse{\boolean{@tufte@pdf}} + {\@tufte@debug@info@noline{ifpdf = true}} + {\@tufte@debug@info@noline{ifpdf = false}} + +\ifthenelse{\boolean{@tufte@xetex}} + {\@tufte@debug@info@noline{ifxetex = true}} + {\@tufte@debug@info@noline{ifxetex = false}} + +% Check pdfLaTeX version +\def\@tufte@pdftexversion{0} +\ifx\normalpdftexversion\@undefined \else + \let\pdftexversion \normalpdftexversion + \let\pdftexrevision\normalpdftexrevision + \let\pdfoutput \normalpdfoutput +\fi +\ifx\pdftexversion\@undefined \else + \ifx\pdftexversion\relax \else + \def\@tufte@pdftexversion{6} + \ifnum\pdftexversion < 140 + \def\@tufte@pdftexversion{5} + \fi + \fi +\fi + +\newboolean{@tufte@letterspace@pkg@prereqs} +\setboolean{@tufte@letterspace@pkg@prereqs}{true} +\ifnum\@tufte@pdftexversion<6 + \setboolean{@tufte@letterspace@pkg@prereqs}{false} +\fi + + +\newcommand{\@tufte@letterspacing@soul}{% + \RequirePackage{soul}% + \sodef\allcapsspacing{}{0.15em}{0.65em}{0.6em}% + \sodef\smallcapsspacing{}{0.075em}{0.5em}{0.6em}% + \sodef\sotextsc{\scshape}{0.075em}{0.5em}{0.6em}% + \renewcommand{\allcaps}[1]{\allcapsspacing{\MakeTextUppercase{##1}}}% + \renewcommand{\smallcaps}[1]{\smallcapsspacing{\scshape\MakeTextLowercase{##1}}}% + \renewcommand{\textsc}[1]{\sotextsc{##1}}% +} + +\newcommand{\@tufte@letterspacing@letterspace}{% + \@tufte@debug@info@noline{Modern version of pdfTeX detected. Using `letterspace' package}% + \RequirePackage{letterspace}% + % Set up letterspacing (using microtype package) -- requires pdfTeX v1.40+ + \renewcommand{\allcapsspacing}[1]{\textls[200]{##1}}% + \renewcommand{\smallcapsspacing}[1]{\textls[50]{##1}}% + \renewcommand{\allcaps}[1]{\allcapsspacing{\MakeTextUppercase{##1}}}% + \renewcommand{\smallcaps}[1]{\smallcapsspacing{\scshape\MakeTextLowercase{##1}}}% + \renewcommand{\textsc}[1]{\smallcapsspacing{\textsmallcaps{##1}}}% +} + +\ifthenelse{\boolean{@tufte@letterspace}}{% + \ifthenelse{\boolean{@tufte@pdf}\AND\boolean{@tufte@letterspace@pkg@prereqs}\AND\NOT\boolean{@tufte@xetex}}{% + % load letterspace pkg + \IfFileExists{letterspace.sty}{% + \@tufte@letterspacing@letterspace + }{}% + }{}% + % load soul pkg + \@ifpackageloaded{letterspace}{}{% + \IfFileExists{soul.sty}{% + \@tufte@letterspacing@soul + }{% + \@tufte@warning@noline{Couldn't locate `soul' package}% + }% soul not installed... giving up. + }% +}{} + +%\ifthenelse{\boolean{@tufte@letterspace}}{% + %\ifthenelse{\boolean{pdf}}{% + %\ifthenelse{\NOT\boolean{@tufte@letterspace@pkg@prereqs}}{% + %% pdfLaTeX version is too old or not using pdfLaTeX + %\ifthenelse{\boolean{@tufte@xetex}}{% + %% TODO use xetex letterspacing + %\@tufte@debug@info@noline{XeTeX detected. Reverting to `soul' package for letterspacing}% + %\@tufte@loadsoul% + %}{% + %% use `soul' package for letterspacing + %\@tufte@debug@info@noline{Old version of pdfTeX detected. Reverting to `soul' package for letterspacing}% + %\@tufte@loadsoul% + %} + %}{% + %\IfFileExists{letterspace.sty}{% + %\@tufte@debug@info@noline{Modern version of pdfTeX detected. Using `letterspace' package} + %\RequirePackage{letterspace} + %% Set up letterspacing (using microtype package) -- requires pdfTeX v1.40+ + %\renewcommand{\allcapsspacing}[1]{\textls[200]{##1}} + %\renewcommand{\smallcapsspacing}[1]{\textls[50]{##1}} + %\renewcommand{\allcaps}[1]{\textls[200]{\MakeTextUppercase{##1}}} + %\renewcommand{\smallcaps}[1]{\smallcapsspacing{\MakeTextLowercase{##1}}} + %\renewcommand{\textsc}[1]{\smallcapsspacing{\textsmallcaps{##1}}} + %}{% microtype failed, check for soul + %\@tufte@debug@info@noline{Modern version of pdfTeX detected, but `letterspace' package not installed. Reverting to `soul' package for letterspacing} + %\@tufte@loadsoul + %}% + %}% + %}{% + %\@tufte@debug@info@noline{Plain LaTeX detected. Using `soul' package for letterspacing} + %\@tufte@loadsoul + %} +%}{% +%% we're not to load letterspacing, so do nothing +%} + + +%% +% An environment for paragraph-style section + +\providecommand\newthought[1]{% + \tuftebreak + \noindent\textsc{#1}% +} + +%% +% Redefine the display environments (quote, quotation, etc.) + +\renewenvironment{verse} + {\let\\\@centercr + \list{}{\itemsep \z@ + \itemindent -1pc% + \listparindent\itemindent + \rightmargin \leftmargin + \advance\leftmargin 1pc}% + \small% + \item\relax} + {\endlist} +\renewenvironment{quotation} + {\list{}{\listparindent 1pc% + \itemindent \listparindent + \rightmargin \leftmargin + \parsep \z@ \@plus\p@}% + \small% + \item\relax\noindent\ignorespaces} + {\endlist} +\renewenvironment{quote} + {\list{}{\rightmargin\leftmargin}% + \small% + \item\relax} + {\endlist} + +%% +% Italicize description run-in headings (instead of the default bold) + +\renewcommand*\descriptionlabel[1]{\hspace\labelsep\normalfont\em #1} + + +%% +% Used for doublespacing, and other linespacing + +\RequirePackage{setspace} + +%% +% Color +\RequirePackage[dvipsnames,svgnames]{xcolor}% load before bidi + +%% +% Load the bidi package if instructed to do so. This package must be loaded +% prior to our redefining the \footnote and \cite commands. + +\ifthenelse{\boolean{@tufte@loadbidi}}{% + \AtBeginDocument{% + \RequirePackage{bidi} + \@tufte@pkghook@post@bidi% + }% +}{} + + +%% +% A function that removes leading and trailing spaces from the supplied macro. +% Based on code written by Michael Downes (See ``Around the Bend'', #15.) +% Executing \@tufte@trim@spaces\xyzzy will result in the contents of \xyzzy +% being trimmed of leading and trailing white space. + +\catcode`\Q=3 +\def\@tufte@trim@spaces#1{% + % Use grouping to emulate a multi-token afterassignment queue + \begingroup% + % Put `\toks 0 {' into the afterassignment queue + \aftergroup\toks\aftergroup0\aftergroup{% + % Apply \trimb to the replacement text of #1, adding a leading + % \noexpand to prevent brace stripping and to serve another purpose + % later. + \expandafter\@tufte@trim@b\expandafter\noexpand#1Q Q}% + % Transfer the trimmed text back into #1. + \edef#1{\the\toks0}% +} + +% \trimb removes a trailing space if present, then calls \@tufte@trim@c to +% clean up any leftover bizarre Qs, and trim a leading space. In +% order for \trimc to work properly we need to put back a Q first. +\def\@tufte@trim@b#1 Q{\@tufte@trim@c#1Q} + +% Execute \vfuzz assignment to remove leading space; the \noexpand +% will now prevent unwanted expansion of a macro or other expandable +% token at the beginning of the trimmed text. The \endgroup will feed +% in the \aftergroup tokens after the \vfuzz assignment is completed. +\def\@tufte@trim@c#1Q#2{\afterassignment\endgroup \vfuzz\the\vfuzz#1} +\catcode`\Q=11 + +%% +% Citations should go in the margin as sidenotes + +\ifthenelse{\boolean{@tufte@loadnatbib}}{% + \RequirePackage{natbib}% + \RequirePackage{bibentry}% allows bibitems to be typeset outside thebibliography environment + % Redefine the \BR@b@bibitem command to fix a bug with bibentry+chicago style + \renewcommand\BR@b@bibitem[2][]{% + \ifthenelse{\isempty{#1}}% + {\BR@bibitem{#2}}% + {\BR@bibitem[#1]{#2}}% + \BR@c@bibitem{#2}% + }% + \nobibliography*% pre-loads the bibliography keys + \providecommand{\doi}[1]{\textsc{doi:} #1}% pre-defining this so it may be used before the \bibliography command it issued +}{} + +%% +% Normal \cite behavior +\newcounter{@tufte@num@bibkeys}% +\newcommand{\@tufte@normal@cite}[2][0pt]{% + % Snag the last bibentry in the list for later comparison + \let\@temp@last@bibkey\@empty% + \@for\@temp@bibkey:=#2\do{\let\@temp@last@bibkey\@temp@bibkey}% + \sidenote[][#1]{% + % Loop through all the bibentries, separating them with semicolons and spaces + \normalsize\normalfont\@tufte@citation@font% + \setcounter{@tufte@num@bibkeys}{0}% + \@for\@temp@bibkeyx:=#2\do{% + \ifthenelse{\equal{\@temp@last@bibkey}{\@temp@bibkeyx}}% + {\ifthenelse{\equal{\value{@tufte@num@bibkeys}}{0}}{}{and\ }% + \@tufte@trim@spaces\@temp@bibkeyx% trim spaces around bibkey + \bibentry{\@temp@bibkeyx}}% + {\@tufte@trim@spaces\@temp@bibkeyx% trim spaces around bibkey + \bibentry{\@temp@bibkeyx};\ }% + \stepcounter{@tufte@num@bibkeys}% + }% + }% +} + + +%% +% Macros for holding the list of cite keys until after the \sidenote + +\gdef\@tufte@citations{}% list of cite keys +\newcommand\@tufte@add@citation[1]{\relax% adds a new bibkey to the list of cite keys + \ifx\@tufte@citations\@empty\else + \g@addto@macro\@tufte@citations{,}% separate by commas + \fi + \g@addto@macro\@tufte@citations{#1} +} + +\newcommand{\@tufte@print@citations}[1][0pt]{% puts the citations in a margin note + % Snag the last bibentry in the list for later comparison + \let\@temp@last@bibkey\@empty% + \@for\@temp@bibkey:=\@tufte@citations\do{\let\@temp@last@bibkey\@temp@bibkey}% + \marginpar{% + \hbox{}\vspace*{#1}% + \@tufte@citation@font% + \@tufte@citation@justification% + \@tufte@margin@par% use parindent and parskip settings for marginal text + \vspace*{-1\baselineskip}% + % Loop through all the bibentries, separating them with semicolons and spaces + \setcounter{@tufte@num@bibkeys}{0}% + \@for\@temp@bibkeyx:=\@tufte@citations\do{% + \ifthenelse{\equal{\@temp@last@bibkey}{\@temp@bibkeyx}}% + {\ifthenelse{\equal{\value{@tufte@num@bibkeys}}{0}}{}{and\ }% + \@tufte@trim@spaces\@temp@bibkeyx% trim spaces around bibkey + \bibentry{\@temp@bibkeyx}}% + {\@tufte@trim@spaces\@temp@bibkeyx% trim spaces around bibkey + \bibentry{\@temp@bibkeyx};\ }% + \stepcounter{@tufte@num@bibkeys}% + }% + }% +} + +%% +% \cite behavior when executed within a sidenote + +\newcommand{\@tufte@sidenote@citations}{}% contains list of \cites in sidenote +\newcommand{\@tufte@infootnote@cite}[1]{% + \@tufte@add@citation{#1} +} + +%% +% Set the default \cite style. This is set and reset by the \sidenote command. + +\ifthenelse{\boolean{@tufte@loadnatbib}}{% + \let\cite\@tufte@normal@cite +}{} + +%% +% Transform existing \footnotes into \sidenotes +% Sidenote: ``Where God meant footnotes to go.'' ---Tufte + +\RequirePackage{optparams}% for our new sidenote commands -- provides multiple optional arguments for commands + +\providecommand{\footnotelayout}{\@tufte@sidenote@font\@tufte@sidenote@justification} +\renewcommand{\footnotelayout}{\@tufte@sidenote@font\@tufte@sidenote@justification} + +% Override footmisc's definition to set the sidenote marks (numbers) inside the +% sidenote's text block. +\long\def\@makefntext#1{\@textsuperscript{\@tufte@sidenote@font\tiny\@thefnmark}\,\footnotelayout#1} + +% Set the in-text footnote mark in the same typeface as the body text itself. +\def\@makefnmark{\hbox{\@textsuperscript{\normalfont\footnotesize\@thefnmark}}} + +\providecommand*{\multiplefootnotemarker}{3sp} +\providecommand*{\multfootsep}{,} + +\renewcommand{\@footnotemark}{% + \leavevmode% + \ifhmode% + \edef\@x@sf{\the\spacefactor}% + \@tufte@check@multiple@sidenotes% + \nobreak% + \fi% + \@makefnmark% + \ifhmode\spacefactor\@x@sf\fi% + \relax% +} + +\newcommand{\@tufte@check@multiple@sidenotes}{% + \ifdim\lastkern=\multiplefootnotemarker\relax% + \edef\@x@sf{\the\spacefactor}% + \unkern% + \textsuperscript{\multfootsep}% + \spacefactor\@x@sf\relax% + \fi +} + +\renewcommand\@footnotetext[2][0pt]{% + \marginpar{% + \hbox{}\vspace*{#1}% + \def\baselinestretch {\setspace@singlespace}% + \reset@font\footnotesize% + \@tufte@margin@par% use parindent and parskip settings for marginal text + \vspace*{-1\baselineskip}\noindent% + \protected@edef\@currentlabel{% + \csname p@footnote\endcsname\@thefnmark% + }% + \color@begingroup% + \@makefntext{% + \ignorespaces#2% + }% + \color@endgroup% + }% +}% + +% Ensure this is run after the bidi package has been loaded +\def\@tufte@pkghook@post@bidi{}% +\g@addto@macro{\@tufte@pkghook@post@bidi}{% + \renewcommand\@footnotetext[2][0pt]{% + \marginpar{% + \hbox{}\vspace*{#1}% + \def\baselinestretch {\setspace@singlespace}% + \if@rl@footnote\@rltrue\else\@rlfalse\fi% + \reset@font\footnotesize% + \@tufte@margin@par% use parindent and parskip settings for marginal text + \vspace*{-1\baselineskip}\noindent% + \protected@edef\@currentlabel{% + \csname p@footnote\endcsname\@thefnmark% + }% + \color@begingroup% + \@makefntext{% + \ignorespaces#2% + }% + \color@endgroup% + }% + }% +}% + +% +% Define \sidenote command. Can handle \cite. + +\newlength{\@tufte@sidenote@vertical@offset} +\setlength{\@tufte@sidenote@vertical@offset}{0pt} + +% #1 = footnote num, #2 = vertical offset, #3 = footnote text +\long\def\@tufte@sidenote[#1][#2]#3{% + \ifthenelse{\boolean{@tufte@loadnatbib}}{% + \let\cite\@tufte@infootnote@cite% use the in-sidenote \cite command + }{}% + \gdef\@tufte@citations{}% clear out any old citations + \ifthenelse{\NOT\isempty{#2}}{% + \gsetlength{\@tufte@sidenote@vertical@offset}{#2}% + }{% + \gsetlength{\@tufte@sidenote@vertical@offset}{0pt}% + }% + \ifthenelse{\isempty{#1}}{% + % no specific footnote number provided + \stepcounter\@mpfn% + \protected@xdef\@thefnmark{\thempfn}% + \@footnotemark\@footnotetext[\@tufte@sidenote@vertical@offset]{#3}% + }{% + % specific footnote number provided + \begingroup% + \csname c@\@mpfn\endcsname #1\relax% + \unrestored@protected@xdef\@thefnmark{\thempfn}% + \endgroup% + \@footnotemark\@footnotetext[\@tufte@sidenote@vertical@offset]{#3}% + }% + \@tufte@print@citations% print any citations + \ifthenelse{\boolean{@tufte@loadnatbib}}{% + \let\cite\@tufte@normal@cite% go back to using normal in-text \cite command + }{}% + \unskip\ignorespaces% remove extra white space + \kern-\multiplefootnotemarker% remove \kern left behind by sidenote + \kern\multiplefootnotemarker\relax% add new \kern here to replace the one we yanked +} + +\newcommand{\sidenote}{\optparams{\@tufte@sidenote}{[][0pt]}} +\renewcommand{\footnote}{\optparams{\@tufte@sidenote}{[][0pt]}} + +%% +% Sidenote without the footnote mark + +\newcommand\marginnote[2][0pt]{% + \ifthenelse{\boolean{@tufte@loadnatbib}}{% + \let\cite\@tufte@infootnote@cite% use the in-sidenote \cite command + }{}% + \gdef\@tufte@citations{}% clear out any old citations + \marginpar{\hbox{}\vspace*{#1}\@tufte@marginnote@font\@tufte@marginnote@justification\@tufte@margin@par\vspace*{-1\baselineskip}\noindent #2}% + \@tufte@print@citations% print any citations + \ifthenelse{\boolean{@tufte@loadnatbib}}{% + \let\cite\@tufte@normal@cite% go back to using normal in-text \cite command + }{}% +} + + +%% +% The placeins package provides the \FloatBarrier command. This forces +% LaTeX to place all of the floats before proceeding. We'll use this to +% keep the float (figure and table) numbers in sequence. +\RequirePackage{placeins} + +%% +% Margin float environment + +\newsavebox{\@tufte@margin@floatbox} +\newenvironment{@tufte@margin@float}[2][-1.2ex]% + {\FloatBarrier% process all floats before this point so the figure/table numbers stay in order. + \begin{lrbox}{\@tufte@margin@floatbox}% + \begin{minipage}{\marginparwidth}% + \@tufte@caption@font% + \def\@captype{#2}% + \hbox{}\vspace*{#1}% + \@tufte@caption@justification% + \@tufte@margin@par% + \noindent% + } + {\end{minipage}% + \end{lrbox}% + \marginpar{\usebox{\@tufte@margin@floatbox}}% + } + + +%% +% Margin figure environment + +% \newenvironment{marginfigure}[1][-1.2ex]% +% {\begin{@tufte@margin@float}[#1]{figure}} +% {\end{@tufte@margin@float}} + + +% %% +% % Margin table environment + +% \newenvironment{margintable}[1][-1.2ex]% +% {\begin{@tufte@margin@float}[#1]{table}} +% {\end{@tufte@margin@float}} + + +%% +% Auto-detects the proper text alignment based on the various class options + +\newcommand*{\@tufte@justification@autodetect}{% + \ifthenelse{\boolean{@tufte@justified}}% + {\justifying}% + {\RaggedRight}% +} + +%% +% Forces the outer edge of the caption to be set ragged. +% Therefore, on verso pages it's ragged left, and on recto pages it's ragged right. + +\newcommand*{\@tufte@justification@caption@outer}{% + \ifthenelse{\boolean{@tufte@float@recto}}% + {\RaggedRight}% + {\RaggedLeft}% +} + +\newcommand*{\@tufte@justification@outer}{% + \@tufte@checkoddpage% + \ifthenelse{\boolean{@tufte@odd@page}}% + {\RaggedRight}% + {\RaggedLeft}% +} + + + +%% +% A collection of macros to be used with the new Tufte-style float environments. +% \setfloatalignment forces the caption placement to be treated as top, bottom, etc. +% \forcerectofloat forces the float to be treated as if it were appearing on a recto page. +% \forceversofloat does the same, but for verso pages. + +\newcommand{\@tufte@float@debug@info}{}% contains debug info generated as the float is processed +\newcommand{\@tufte@float@debug}[1]{% adds debug info to the queue for output + \ifthenelse{\equal{\@tufte@float@debug@info}{}}% + {\def\@tufte@float@debug@info{#1}}% + {\g@addto@macro\@tufte@float@debug@info{\MessageBreak#1}}% +} + +\newcommand{\floatalignment}{x}% holds the current float alignment (t, b, h, p) +\newcommand{\setfloatalignment}[1]{\global\def\floatalignment{#1}\@tufte@float@debug{Forcing position: [#1]}}% manually sets the float alignment +\newboolean{@tufte@float@recto} +\newcommand{\forcerectofloat}{\gsetboolean{@tufte@float@recto}{true}\@tufte@float@debug{Forcing page: [recto]}} +\newcommand{\forceversofloat}{\gsetboolean{@tufte@float@recto}{false}\@tufte@float@debug{Forcing page: [verso]}} + +% Boxes to temporarily store our float and caption +\newsavebox{\@tufte@figure@box} +\newsavebox{\@tufte@caption@box} + +% Save original LaTeX float environment +\let\@tufte@orig@float\@float +\let\@tufte@orig@endfloat\end@float + +% New length for tweaking float captions +\newlength{\@tufte@caption@vertical@offset} +\setlength{\@tufte@caption@vertical@offset}{0pt} + +% Store the caption and label contents +\newcommand{\@tufte@stored@shortcaption}{} +\newcommand{\@tufte@stored@caption}{} +\newcommand{\@tufte@stored@label}{} + +\long\def\@tufte@caption[#1][#2]#3{% + \ifthenelse{\isempty{#1}}% + {\gdef\@tufte@stored@shortcaption{#3}}% + {\gdef\@tufte@stored@shortcaption{#1}}% + \gsetlength{\@tufte@caption@vertical@offset}{-#2}% we want a positive offset to lower captions + \gdef\@tufte@stored@caption{#3}% +} + +\newcommand{\@tufte@label}[1]{% + \gdef\@tufte@stored@label{#1}% +} + +\newcommand{\@tufte@fps}{} + +\newboolean{@tufte@float@star} +\newlength{\@tufte@float@contents@width} + +%% +% Define a float environment to place the captions in the margin space + +\newenvironment{@tufte@float}[3][htbp]% + {% begin @tufte@float + % Should this float be full-width or just text-width? + \ifthenelse{\equal{#3}{star}}% + {\gsetboolean{@tufte@float@star}{true}}% + {\gsetboolean{@tufte@float@star}{false}}% + % Check page side (recto/verso) and store detected value -- can be overriden in environment contents + \@tufte@checkoddpage% + \ifthenelse{\boolean{@tufte@odd@page}}% + {\gsetboolean{@tufte@float@recto}{true}\@tufte@float@debug{Detected page: [recto/odd]}}% + {\gsetboolean{@tufte@float@recto}{false}\@tufte@float@debug{Detected page: [verso/even]}}% + % If the float placement specifier is 'b' and only 'b', then bottom-align the mini-pages, otherwise top-align them. + \renewcommand{\@tufte@fps}{#1}% + \@tufte@float@debug{Allowed positions: [#1]}% + \ifthenelse{\equal{#1}{b}\OR\equal{#1}{B}}% + {\renewcommand{\floatalignment}{b}\@tufte@float@debug{Presumed position: [bottom]}}% + {\renewcommand{\floatalignment}{t}\@tufte@float@debug{Presumed position: [top]}}% + % Capture the contents of the \caption and \label commands to use later + \global\let\@tufte@orig@caption\caption% + \global\let\@tufte@orig@label\label% + \renewcommand{\caption}{\optparams{\@tufte@caption}{[][0pt]}}% + \renewcommand{\label}[1]{\@tufte@label{##1}}% + % Handle subfigure package compatibility + \ifthenelse{\boolean{@tufte@packages@subfigure}}{% + % don't move the label while inside a \subfigure or \subtable command + \global\let\label\@tufte@orig@label% + }{}% subfigure package is not loaded + \@tufte@orig@float{#2}[#1]% + \ifthenelse{\boolean{@tufte@float@star}}% + {\setlength{\@tufte@float@contents@width}{\@tufte@fullwidth}}% + {\setlength{\@tufte@float@contents@width}{\textwidth}}% + \begin{lrbox}{\@tufte@figure@box}% + \begin{minipage}[\floatalignment]{\@tufte@float@contents@width}\hbox{}% + }{% end @tufte@float + \par\hbox{}\vspace{-\baselineskip}\ifthenelse{\prevdepth>0}{\vspace{-\prevdepth}}{}% align baselines of boxes + \end{minipage}% + \end{lrbox}% + % build the caption box + \begin{lrbox}{\@tufte@caption@box}% + \begin{minipage}[\floatalignment]{\marginparwidth}\hbox{}% + \ifthenelse{\NOT\equal{\@tufte@stored@caption}{}}{\@tufte@orig@caption[\@tufte@stored@shortcaption]{\@tufte@stored@caption}}{}% + \ifthenelse{\NOT\equal{\@tufte@stored@label}{}}{\@tufte@orig@label{\@tufte@stored@label}}{}% + \par\vspace{-\prevdepth}%% TODO: DOUBLE-CHECK FOR SAFETY + \end{minipage}% + \end{lrbox}% + % now typeset the stored boxes + \begin{fullwidth}% + \begin{minipage}[\floatalignment]{\linewidth}% + \ifthenelse{\boolean{@tufte@float@star}}% + {\@tufte@float@fullwidth[\@tufte@caption@vertical@offset]{\@tufte@figure@box}{\@tufte@caption@box}}% + {\@tufte@float@textwidth[\@tufte@caption@vertical@offset]{\@tufte@figure@box}{\@tufte@caption@box}}% + \end{minipage}% + \end{fullwidth}% + \@tufte@orig@endfloat% end original LaTeX float environment + % output debug info + \ifthenelse{\boolean{@tufte@debug}}{% + \typeout{^^J^^J----------- Tufte-LaTeX float information ----------}% + \ifthenelse{\equal{\@tufte@stored@label}{}}% + {\typeout{Warning: Float unlabeled!}}% + {\typeout{Float label: [\@tufte@stored@label]}}% + \typeout{Page number: [\thepage]}% + \def\MessageBreak{^^J}% + \typeout{\@tufte@float@debug@info}% + \ifthenelse{\boolean{@tufte@symmetric}}% + {\typeout{Symmetric: [true]}}% + {\typeout{Symmetric: [false]}}% + \typeout{----------------------------------------------------^^J^^J}% + }{}% + % reset commands and temp boxes and captions + \gdef\@tufte@float@debug@info{}% + \let\caption\@tufte@orig@caption% + \let\label\@tufte@orig@label% + \begin{lrbox}{\@tufte@figure@box}\hbox{}\end{lrbox}% + \begin{lrbox}{\@tufte@caption@box}\hbox{}\end{lrbox}% + \gdef\@tufte@stored@shortcaption{}% + \gdef\@tufte@stored@caption{}% + \gdef\@tufte@stored@label{}% + \gsetlength{\@tufte@caption@vertical@offset}{0pt}% reset caption offset + } + +\newcommand{\@tufte@float@textwidth}[3][0pt]{% + \ifthenelse{\NOT\boolean{@tufte@symmetric}\OR\boolean{@tufte@float@recto}}{% + % asymmetric or page is odd, so caption is on the right + \hbox{% + \usebox{#2}% + \hspace{\marginparsep}% + \smash{\raisebox{#1}{\usebox{#3}}}% + }% + \@tufte@float@debug{Caption position: [right]}% + }{% symmetric pages and page is even, so caption is on the left + \hbox{% + \smash{\raisebox{#1}{\usebox{#3}}}% + \hspace{\marginparsep}% + \usebox{#2}% + }% + \@tufte@float@debug{Caption position: [left]}% + }% +} + +\newcommand{\@tufte@float@fullwidth}[3][0pt]{% + \ifthenelse{\equal{\floatalignment}{b}}% + {% place caption above figure + \ifthenelse{\NOT\boolean{@tufte@symmetric}\OR\boolean{@tufte@float@recto}}% + {\hfill\smash{\raisebox{#1}{\usebox{#3}}}\par\usebox{#2}\@tufte@float@debug{Caption position: [above right]}}% caption on the right + {\smash{\raisebox{#1}{\usebox{#3}}}\hfill\par\usebox{#2}\@tufte@float@debug{Caption position: [above left]}}% caption on the left + }{% place caption below figure + \ifthenelse{\NOT\boolean{@tufte@symmetric}\OR\boolean{@tufte@float@recto}}% + {\usebox{#2}\par\hfill\smash{\raisebox{#1}{\usebox{#3}}}\@tufte@float@debug{Caption position: [below right]}}% caption on the right + {\usebox{#2}\par\smash{\raisebox{#1}{\usebox{#3}}}\hfill\@tufte@float@debug{Caption position: [below left]}}% caption on the left + }% +} + + +%% +% Redefine the figure environment to place the captions in the margin space + +\renewenvironment{figure}[1][htbp]% + {\ifvmode\else\unskip\fi\begin{@tufte@float}[#1]{figure}{}} + {\end{@tufte@float}} + + +%% +% Redefine the table environment to place the captions in the margin space + +\renewenvironment{table}[1][htbp] + {\ifvmode\else\unskip\fi\begin{@tufte@float}[#1]{table}{}} + {\end{@tufte@float}} + + +%% +% Full-width figure + +\renewenvironment{figure*}[1][htbp]% + {\ifvmode\else\unskip\fi\begin{@tufte@float}[#1]{figure}{star}} + {\end{@tufte@float}} + + +%% +% Full-width table + +\renewenvironment{table*}[1][htbp]% + {\ifvmode\else\unskip\fi\begin{@tufte@float}[#1]{table}{star}} + {\end{@tufte@float}} + + +%% +% Full-page-width area + +\newenvironment{fullwidth} + {\ifthenelse{\boolean{@tufte@symmetric}}% + {\ifthenelse{\boolean{@tufte@changepage}}{\begin{adjustwidth*}{}{-\@tufte@overhang}}{\begin{adjustwidth}[]{}{-\@tufte@overhang}}}% + {\begin{adjustwidth}{}{-\@tufte@overhang}}% + }% + {\ifthenelse{\boolean{@tufte@symmetric}}% + {\ifthenelse{\boolean{@tufte@changepage}}{\end{adjustwidth*}}{\end{adjustwidth}}}% + {\end{adjustwidth}}% + } + +%% +% Format the captions in a style similar to the sidenotes + +\long\def\@caption#1[#2]#3{% + \par% + \addcontentsline{\csname ext@#1\endcsname}{#1}% + {\protect\numberline{\csname the#1\endcsname}{\ignorespaces #2}}% + \begingroup% + \@parboxrestore% + \if@minipage% + \@setminipage% + \fi% + \@tufte@caption@font\@tufte@caption@justification% + \noindent\csname fnum@#1\endcsname: \ignorespaces#3\par% + %\@makecaption{\csname fnum@#1\endcsname}{\ignorespaces #3}\par + \endgroup} + +%% +% If we're NOT using XeLaTeX and the `nofonts' class option was NOT provided, +% we should load the Palatino, Helvetica, and Bera Mono fonts (if they are +% installed.) + +\ifthenelse{\boolean{@tufte@loadfonts}\AND\NOT\boolean{@tufte@xetex}\AND\NOT\boolean{@tufte@luatex}}{% + \IfFileExists{mathpazo.sty}{\RequirePackage[osf,sc]{mathpazo}}{} + \IfFileExists{helvet.sty}{\RequirePackage[scaled=0.90]{helvet}}{} + \IfFileExists{beramono.sty}{\RequirePackage[scaled=0.85]{beramono}}{} + \RequirePackage[T1]{fontenc} + \RequirePackage{textcomp} +}{} + + +%% +% Turns newlines into spaces. Based on code from the `titlesec' package. + +\DeclareRobustCommand{\@tufte@newlinetospace}{% + \@ifstar{\@tufte@newlinetospace@i}{\@tufte@newlinetospace@i}% +} + +\def\@tufte@newlinetospace@i{% + \ifdim\lastskip>\z@\else\space\fi + \ignorespaces% +} + +\DeclareRobustCommand{\newlinetospace}[1]{% + \let\@tufte@orig@cr\\% save the original meaning of \\ + \def\\{\@tufte@newlinetospace}% turn \\ and \\* into \space + \let\newline\\% turn \newline into \space + #1% + \let\\\@tufte@orig@cr% revert to original meaning of \\ +} + + +%% +% Sets up the running heads and folios. + +\RequirePackage{fancyhdr} + +% Set the default page style to 'fancy' +\pagestyle{fancy} + +% Set the header/footer width to be the body text block plus the margin +% note area. +\AtBeginDocument{% + \ifthenelse{\boolean{@tufte@symmetric}} + {\fancyhfoffset[LE,RO]{\@tufte@overhang}} + {\fancyhfoffset[RE,RO]{\@tufte@overhang}} +} + +% The running heads/feet don't have rules +\renewcommand{\headrulewidth}{0pt} +\renewcommand{\footrulewidth}{0pt} + +% The 'fancy' page style is the default style for all pages. +\fancyhf{} % clear header and footer fields +\ifthenelse{\boolean{@tufte@twoside}} + {\fancyhead[LE]{\thepage\quad\smallcaps{\newlinetospace{\plainauthor}}}% + \fancyhead[RO]{\smallcaps{\newlinetospace{\plaintitle}}\quad\thepage}} + {\fancyhead[RE,RO]{\smallcaps{\newlinetospace{\plaintitle}}\quad\thepage}} + + +% The `plain' page style is used on chapter opening pages. +% In Tufte's /Beautiful Evidence/ he never puts page numbers at the +% bottom of pages -- the folios are unexpressed. +\fancypagestyle{plain}{ + \fancyhf{} % clear header and footer fields + % Uncomment the following five lines of code if you want the opening page + % of the chapter to express the folio in the lower outside corner. + %\ifthenelse{\boolean{@tufte@twoside}} + % {\fancyfoot[LE,RO]{\thepage}} + % {\fancyfoot[RE,RO]{\thepage}} +} + +% The `empty' page style suppresses all headers and footers. +% It's used on title pages and `intentionally blank' pages. +\fancypagestyle{empty}{ + \fancyhf{} % clear header and footer fields +} + + +%% +% Set raggedright and paragraph indentation for document + +\AtBeginDocument{\@tufte@justification} + + +%% +% Prints the list of class options and their states. + +\newcommand{\typeoutbool}[2]{% + \ifthenelse{\boolean{#2}} + {\typeout{\space\space#1: true}} + {\typeout{\space\space#1: false}} +} + +\newcommand{\typeoutstr}[2]{% + \typeout{\space\space#1: #2} +} + +\newcommand{\PrintTufteSettings}{% + \typeout{-------------------- Tufte-LaTeX settings ----------} + \typeout{Class: \@tufte@pkgname} + \typeout{} + \typeout{Class options:} + \typeoutbool{a4paper}{@tufte@afourpaper} + \typeoutbool{b5paper}{@tufte@bfivepaper} + \typeoutbool{load fonts}{@tufte@loadfonts} + \typeoutbool{fully-justified}{@tufte@justified} + \typeoutbool{letterspacing}{@tufte@letterspace} + \typeoutbool{sans-serif sidenotes}{@tufte@sfsidenotes} + \typeoutbool{symmetric margins}{@tufte@symmetric} + \typeoutbool{titlepage}{@tufte@titlepage} + \typeoutbool{twoside}{@tufte@twoside} + \typeoutbool{debug}{@tufte@debug} + \typeout{} + \typeout{Internal variables:} + \typeoutbool{[twoside]}{@twoside} + \typeoutbool{pdflatex}{@tufte@pdf} + \typeoutbool{xelatex}{@tufte@xetex} + \typeout{----------------------------------------------------} +} + +%% +% Amount of space to skip before \newthought or after title block + +\newskip\tufteskipamount +\tufteskipamount=1.0\baselineskip plus 0.5ex minus 0.2ex + +\newcommand{\tuftebreak}{\par\ifdim\lastskip<\tufteskipamount + \removelastskip\penalty-100\tufteskip\fi} + +\newcommand{\tufteskip}{\vspace\tufteskipamount} + + +%% +% Produces a full title page + +\newcommand{\maketitlepage}[0]{% + \cleardoublepage% + {% + \sffamily% + \begin{fullwidth}% + \fontsize{18}{20}\selectfont\par\noindent\textcolor{darkgray}{\allcaps{\thanklessauthor}}% + \vspace{11.5pc}% + \fontsize{36}{40}\selectfont\par\noindent\textcolor{darkgray}{\allcaps{\thanklesstitle}}% + \vfill% + \fontsize{14}{16}\selectfont\par\noindent\allcaps{\thanklesspublisher}% + \end{fullwidth}% + } + \thispagestyle{empty}% + \clearpage% +} + +%% +% Title block + +\renewcommand{\maketitle}{% + \newpage + \global\@topnum\z@% prevent floats from being placed at the top of the page + \begingroup + \setlength{\parindent}{0pt}% + \setlength{\parskip}{4pt}% + \let\@@title\@empty + \let\@@author\@empty + \let\@@date\@empty + \ifthenelse{\boolean{@tufte@sfsidenotes}}{% + \gdef\@@title{\sffamily\LARGE\allcaps{\@title}\par}% + \gdef\@@author{\sffamily\Large\allcaps{\@author}\par}% + \gdef\@@date{\sffamily\Large\allcaps{\@date}\par}% + }{% + \gdef\@@title{\LARGE\itshape\@title\par}% + \gdef\@@author{\Large\itshape\@author\par}% + \gdef\@@date{\Large\itshape\@date\par}% + }% + \@@title + \@@author + \@@date + \endgroup + \thispagestyle{plain}% suppress the running head + \tuftebreak% add some space before the text begins + \@afterindentfalse\@afterheading% suppress indentation of the next paragraph +} + + +%% +% Title page (if the `titlepage' option was passed to the tufte-handout +% class.) + +\ifthenelse{\boolean{@tufte@titlepage}} + {\renewcommand{\maketitle}{\maketitlepage}} + {} + +%% +% When \cleardoublepage is called, produce a blank (empty) page -- i.e., +% without headers and footers +\def\cleardoublepage{\clearpage\if@twoside\ifodd\c@page\else + \hbox{} + %\vspace*{\fill} + %\begin{center} + % This page intentionally contains only this sentence. + %\end{center} + %\vspace{\fill} + \thispagestyle{empty} + \newpage + \if@twocolumn\hbox{}\newpage\fi\fi\fi} + +%% +% Make Tuftian-style section headings and TOC formatting + +\titleformat{\chapter}% + [display]% shape + {\relax\ifthenelse{\NOT\boolean{@tufte@symmetric}}{\begin{fullwidth}}{}}% format applied to label+text + {\itshape\huge\thechapter}% label + {0pt}% horizontal separation between label and title body + {\huge\rmfamily\itshape}% before the title body + [\ifthenelse{\NOT\boolean{@tufte@symmetric}}{\end{fullwidth}}{}]% after the title body + +\titleformat{\section}% + [hang]% shape + {\normalfont\Large\itshape}% format applied to label+text + {\thesection}% label + {1em}% horizontal separation between label and title body + {}% before the title body + []% after the title body + +\titleformat{\subsection}% + [hang]% shape + {\normalfont\large\itshape}% format applied to label+text + {\thesubsection}% label + {1em}% horizontal separation between label and title body + {}% before the title body + []% after the title body + +\titleformat{\paragraph}% + [runin]% shape + {\normalfont\itshape}% format applied to label+text + {\theparagraph}% label + {1em}% horizontal separation between label and title body + {}% before the title body + []% after the title body + +\titlespacing*{\chapter}{0pt}{50pt}{40pt} +\titlespacing*{\section}{0pt}{3.5ex plus 1ex minus .2ex}{2.3ex plus .2ex} +\titlespacing*{\subsection}{0pt}{3.25ex plus 1ex minus .2ex}{1.5ex plus.2ex} + +% Subsubsection and following section headings shouldn't be used. +% See Bringhurst's _The Elements of Typography_, section 4.2.2. +\renewcommand\subsubsection{% + \@tufte@error{\string\subsubsection is undefined by this class. + See Robert Bringhurst's _The Elements of + Typographic Style_, section 4.2.2. + \string\subsubsection was used} + {From Bringhurst's _The Elements of Typographic Style_, section 4.2.2: Use as + many levels of headings as you need, no more and no fewer. Also see the many + related threads on Ask E.T. at http://www.edwardtufte.com/.} +} + +\renewcommand\subparagraph{% + \@tufte@error{\string\subparagraph is undefined by this class.% + See Robert Bringhurst's _The Elements of + Typographic Style_, section 4.2.2. + \string\subparagraph was used} + {From Bringhurst's _The Elements of Typographic Style_, section 4.2.2: Use as + many levels of headings as you need, no more and no fewer. Also see the many + related threads on Ask E.T. at http://www.edwardtufte.com/.} +} + + +% Formatting for main TOC (printed in front matter) +% {section} [left] {above} {before w/label} {before w/o label} {filler + page} [after] +\ifthenelse{\boolean{@tufte@toc}}{% + \titlecontents{part}% FIXME + [0em] % distance from left margin + {\vspace{1.5\baselineskip}\begin{fullwidth}\LARGE\rmfamily\itshape} % above (global formatting of entry) + {\contentslabel{2em}} % before w/label (label = ``II'') + {} % before w/o label + {\rmfamily\upshape\qquad\thecontentspage} % filler + page (leaders and page num) + [\end{fullwidth}] % after + \titlecontents{chapter}% + [0em] % distance from left margin + {\vspace{1.5\baselineskip}\begin{fullwidth}\LARGE\rmfamily\itshape} % above (global formatting of entry) + {\hspace*{0em}\contentslabel{2em}} % before w/label (label = ``2'') + {\hspace*{0em}} % before w/o label + {\rmfamily\upshape\qquad\thecontentspage} % filler + page (leaders and page num) + [\end{fullwidth}] % after + \titlecontents{section}% FIXME + [0em] % distance from left margin + {\vspace{0\baselineskip}\begin{fullwidth}\Large\rmfamily\itshape} % above (global formatting of entry) + {\hspace*{2em}\contentslabel{2em}} % before w/label (label = ``2.6'') + {\hspace*{2em}} % before w/o label + {\rmfamily\upshape\qquad\thecontentspage} % filler + page (leaders and page num) + [\end{fullwidth}] % after + \titlecontents{subsection}% FIXME + [0em] % distance from left margin + {\vspace{0\baselineskip}\begin{fullwidth}\large\rmfamily\itshape} % above (global formatting of entry) + {\hspace*{4em}\contentslabel{4em}} % before w/label (label = ``2.6.1'') + {\hspace*{4em}} % before w/o label + {\rmfamily\upshape\qquad\thecontentspage} % filler + page (leaders and page num) + [\end{fullwidth}] % after + \titlecontents{paragraph}% FIXME + [0em] % distance from left margin + {\vspace{0\baselineskip}\begin{fullwidth}\normalsize\rmfamily\itshape} % above (global formatting of entry) + {\hspace*{6em}\contentslabel{2em}} % before w/label (label = ``2.6.0.0.1'') + {\hspace*{6em}} % before w/o label + {\rmfamily\upshape\qquad\thecontentspage} % filler + page (leaders and page num) + [\end{fullwidth}] % after +}{} + +%% +% Format lists of figures/tables + +\renewcommand\listoffigures{% + \ifthenelse{\equal{\@tufte@class}{book}}% + {\chapter*{\listfigurename}}% + {\section*{\listfigurename}}% +% \begin{fullwidth}% + \@starttoc{lof}% +% \end{fullwidth}% +} + +\renewcommand\listoftables{% + \ifthenelse{\equal{\@tufte@class}{book}}% + {\chapter*{\listtablename}}% + {\section*{\listtablename}}% +% \begin{fullwidth}% + \@starttoc{lot}% +% \end{fullwidth}% +} + +\newcommand{\@tufte@lof@line}[2]{% + % #1 is the figure/table number and its caption text + % #2 is the page number on which the figure/table appears + \leftskip 0.0em + \rightskip 0em + \parfillskip 0em plus 1fil + \parindent 0.0em + \@afterindenttrue + \interlinepenalty\@M + \leavevmode + \@tempdima 2.0em + \advance\leftskip\@tempdima + \null\nobreak\hskip -\leftskip + {#1}\nobreak\qquad\nobreak#2% + \par% +} + +\renewcommand*\l@figure{\@tufte@lof@line} +\let\l@table\l@figure + + +%% +% A handy command to disable hyphenation for short bits of text. +% Borrowed from Peter Wilson's `hyphenat' package. + +\AtBeginDocument{% + \@ifpackageloaded{hyphenat}{}{% + \newlanguage\langwohyphens% define a language without hyphenation rules + \providecommand{\nohyphens}[1]{{\language\langwohyphens #1}}% used for short bits of text + \providecommand{\nohyphenation}{\language\langwohyphens}% can be used inside environments for longer text + }% +} + +%% +% Redefine \bibsection to not mark the running heads. +% (Code modified from natbib.sty.) + +\ifthenelse{\boolean{@tufte@loadnatbib}}{% + \@ifundefined{chapter}{% + \renewcommand\bibsection{\section*{\refname}}% + }{% + \@ifundefined{NAT@sectionbib}{% + \renewcommand\bibsection{\chapter{\bibname}}% + }{% + \renewcommand\bibsection{\section*{\bibname}}% + }% + }% +} + +%% +% An index environment to mimic Tufte's indexes + +\RequirePackage{multicol} +\renewenvironment{theindex}{% + \ifthenelse{\equal{\@tufte@class}{book}}% + {\chapter{\indexname}}% + {\section*{\indexname}}% + \begin{fullwidth}% + \small% + \parskip0pt% + \parindent0pt% + \let\item\@idxitem% + \begin{multicols}{3}% +}{% + \end{multicols}% + \end{fullwidth}% +} +\renewcommand\@idxitem{\par\hangindent 2em} +\renewcommand\subitem{\par\hangindent 3em\hspace*{1em}} +\renewcommand\subsubitem{\par\hangindent 4em\hspace*{2em}} +\renewcommand\indexspace{\par\addvspace{1.0\baselineskip plus 0.5ex minus 0.2ex}\relax}% +\newcommand{\lettergroup}[1]{}% swallow the letter heading in the index + + +%% +% A couple commands to increase the number of floats you can use at a time. + +\def\morefloats{% provides a total of 52 floats + \ifthenelse{\isundefined{\bx@S}}{% + \@tufte@debug@info@noline{Adding 34 more float slots.} + \newinsert\bx@S + \newinsert\bx@T + \newinsert\bx@U + \newinsert\bx@V + \newinsert\bx@W + \newinsert\bx@X + \newinsert\bx@Y + \newinsert\bx@Z + \newinsert\bx@a + \newinsert\bx@b + \newinsert\bx@c + \newinsert\bx@d + \newinsert\bx@e + \newinsert\bx@f + \newinsert\bx@g + \newinsert\bx@h + \newinsert\bx@i + \newinsert\bx@j + \newinsert\bx@k + \newinsert\bx@l + \newinsert\bx@m + \newinsert\bx@n + \newinsert\bx@o + \newinsert\bx@p + \newinsert\bx@q + \newinsert\bx@r + \newinsert\bx@s + \newinsert\bx@t + \newinsert\bx@u + \newinsert\bx@v + \newinsert\bx@w + \newinsert\bx@x + \newinsert\bx@y + \newinsert\bx@z + \gdef\@freelist{\@elt\bx@A\@elt\bx@B\@elt\bx@C\@elt\bx@D\@elt\bx@E + \@elt\bx@F\@elt\bx@G\@elt\bx@H\@elt\bx@I\@elt\bx@J + \@elt\bx@K\@elt\bx@L\@elt\bx@M\@elt\bx@N + \@elt\bx@O\@elt\bx@P\@elt\bx@Q\@elt\bx@R + \@elt\bx@S\@elt\bx@T\@elt\bx@U\@elt\bx@V + \@elt\bx@W\@elt\bx@X\@elt\bx@Y\@elt\bx@Z + \@elt\bx@a\@elt\bx@b\@elt\bx@c\@elt\bx@d\@elt\bx@e + \@elt\bx@f\@elt\bx@g\@elt\bx@h\@elt\bx@i\@elt\bx@j + \@elt\bx@k\@elt\bx@l\@elt\bx@m\@elt\bx@n + \@elt\bx@o\@elt\bx@p\@elt\bx@q\@elt\bx@r + \@elt\bx@s\@elt\bx@t\@elt\bx@u\@elt\bx@v + \@elt\bx@w\@elt\bx@x\@elt\bx@y\@elt\bx@z}% + }{% we've already added another 34 floats, so we'll add 26 more, but that's it! + \ifthenelse{\isundefined{\bx@AA}}{% + \@tufte@debug@info@noline{Adding 26 more float slots.} + \newinsert\bx@AA + \newinsert\bx@BB + \newinsert\bx@CC + \newinsert\bx@DD + \newinsert\bx@EE + \newinsert\bx@FF + \newinsert\bx@GG + \newinsert\bx@HH + \newinsert\bx@II + \newinsert\bx@JJ + \newinsert\bx@KK + \newinsert\bx@LL + \newinsert\bx@MM + \newinsert\bx@NN + \newinsert\bx@OO + \newinsert\bx@PP + \newinsert\bx@QQ + \newinsert\bx@RR + \newinsert\bx@SS + \newinsert\bx@TT + \newinsert\bx@UU + \newinsert\bx@VV + \newinsert\bx@WW + \newinsert\bx@XX + \newinsert\bx@YY + \newinsert\bx@ZZ + \gdef\@freelist{\@elt\bx@A\@elt\bx@B\@elt\bx@C\@elt\bx@D\@elt\bx@E + \@elt\bx@F\@elt\bx@G\@elt\bx@H\@elt\bx@I\@elt\bx@J + \@elt\bx@K\@elt\bx@L\@elt\bx@M\@elt\bx@N + \@elt\bx@O\@elt\bx@P\@elt\bx@Q\@elt\bx@R + \@elt\bx@S\@elt\bx@T\@elt\bx@U\@elt\bx@V + \@elt\bx@W\@elt\bx@X\@elt\bx@Y\@elt\bx@Z + \@elt\bx@a\@elt\bx@b\@elt\bx@c\@elt\bx@d\@elt\bx@e + \@elt\bx@f\@elt\bx@g\@elt\bx@h\@elt\bx@i\@elt\bx@j + \@elt\bx@k\@elt\bx@l\@elt\bx@m\@elt\bx@n + \@elt\bx@o\@elt\bx@p\@elt\bx@q\@elt\bx@r + \@elt\bx@s\@elt\bx@t\@elt\bx@u\@elt\bx@v + \@elt\bx@w\@elt\bx@x\@elt\bx@y\@elt\bx@z + \@elt\bx@AA\@elt\bx@BB\@elt\bx@CC\@elt\bx@DD\@elt\bx@EE + \@elt\bx@FF\@elt\bx@GG\@elt\bx@HH\@elt\bx@II\@elt\bx@JJ + \@elt\bx@KK\@elt\bx@LL\@elt\bx@MM\@elt\bx@NN + \@elt\bx@OO\@elt\bx@PP\@elt\bx@QQ\@elt\bx@RR + \@elt\bx@SS\@elt\bx@TT\@elt\bx@UU\@elt\bx@VV + \@elt\bx@WW\@elt\bx@XX\@elt\bx@YY\@elt\bx@ZZ}% + }{% + \@tufte@error{You may only call \string\morefloats\space twice. See the Tufte-LaTeX documentation for other workarounds} + {There are already 78 float slots allocated. Try using \string\FloatBarrier\space or \string\clearpage\space to place some floats before creating more.} + }% + }% +} + + +%% +% Detect if the subfigure package has been loaded + +\newboolean{@tufte@packages@subfigure} +\setboolean{@tufte@packages@subfigure}{false} +\AtBeginDocument{% + \@ifpackageloaded{subfigure} + {\gsetboolean{@tufte@packages@subfigure}{true}} + {\gsetboolean{@tufte@packages@subfigure}{false}}% +} + + +%% +% Detect of the float package has been loaded + +\AtBeginDocument{% + \@ifpackageloaded{float}{% + % Save the redefined float environment (instead of the LaTeX float environment) + \let\@tufte@orig@float\@float + \let\@tufte@orig@endfloat\end@float + + % Define Tuftian float styles (with the caption in the margin) + \newcommand{\floatc@tufteplain}[2]{% + \begin{lrbox}{\@tufte@caption@box}% + \begin{minipage}[\floatalignment]{\marginparwidth}\hbox{}% + \@tufte@caption@font{\@fs@cfont #1:} #2\par% + \end{minipage}% + \end{lrbox}% + \smash{\hspace{\@tufte@caption@fill}\usebox{\@tufte@caption@box}}% + } + \newcommand{\fs@tufteplain}{% + \def\@fs@cfont{\@tufte@caption@font}% + \let\@fs@capt\floatc@tufteplain% + \def\@fs@pre{}% + \def\@fs@post{}% + \def\@fs@mid{}% + \let\@fs@iftopcapt\iftrue% + } + \let\fs@tufteplaintop=\fs@tufteplain + \let\floatc@tufteplaintop=\floatc@tufteplain + \newcommand\floatc@tufteruled[2]{% + {\@fs@cfont #1} #2\par% + } + \newcommand\fs@tufteruled{% + \def\@fs@cfont{\@tufte@caption@font}% + \let\@fs@capt\floatc@tufteplain% + \def\@fs@pre{\hrule height.8pt depth0pt width\textwidth \kern2pt}% + \def\@fs@post{\kern2pt\hrule width\textwidth\relax}% + \def\@fs@mid{}% + \let\@fs@iftopcapt\iftrue% + } + \newcommand\fs@tufteboxed{% + \def\@fs@cfont{}% + \let\@fs@capt\floatc@tufteplain% + \def\@fs@pre{% + \setbox\@currbox\vbox{\hbadness10000 + \moveleft3.4pt\vbox{\advance\hsize by6.8pt + \hrule \hbox to\hsize{\vrule\kern3pt + \vbox{\kern3pt\box\@currbox\kern3pt}\kern3pt\vrule}\hrule}} + }% + \def\@fs@mid{\kern2pt}% + \def\@fs@post{}% + \let\@fs@iftopcapt\iftrue% + } + }{% + % Nothing to do + } +} + +\AtBeginDocument{% + \@ifpackageloaded{algorithm}{% + % Set the float style to the Tuftian version + \ifthenelse{\equal{\ALG@floatstyle}{plain}\OR\equal{\ALG@floatstyle}{ruled}\OR\equal{\ALG@floatstyle}{boxed}}{% + \@tufte@info@noline{Switching algorithm float style from \ALG@floatstyle\space to tufte\ALG@floatstyle}% + \floatstyle{tufte\ALG@floatstyle}% + \restylefloat{algorithm}% + }{}% + }{% + % Nothing to do + } +} + + +%% +% For compatibility with the subfig package, we'll set captions=false so that +% it doesn't load the caption package (which modifies our own caption +% formatting). + +\PassOptionsToPackage{caption=false}{subfig} + + +%% +% If debugging is enabled, print the Tufte-LaTeX options and the list of +% files. + +\ifthenelse{\boolean{@tufte@debug}} + {\PrintTufteSettings\listfiles} + {} + + +%% +% If there is a `tufte-common-local.tex' file, load it up. + +\IfFileExists{tufte-common-local.tex} + {\input{tufte-common-local.tex}% + \@tufte@info@noline{Loading tufte-common-local.tex}} + {} + + +%% +% End of file +\endinput + diff --git a/_extensions/fredguth/tufte/tufte-handout.cls b/_extensions/fredguth/tufte/tufte-handout.cls new file mode 100644 index 0000000..2ad43c5 --- /dev/null +++ b/_extensions/fredguth/tufte/tufte-handout.cls @@ -0,0 +1,39 @@ +\NeedsTeXFormat{LaTeX2e}[1994/06/01] + +\ProvidesClass{tufte-handout}[2015/06/21 v3.5.2 Tufte-handout class] + +%% +% Declare we're tufte-handout +\newcommand{\@tufte@class}{article}% the base LaTeX class (defaults to the article/handout style) +\newcommand{\@tufte@pkgname}{tufte-handout}% the name of the package (defaults to tufte-handout) + +%% +% Load the common style elements +\input{tufte-common.def} + + +%% +% Set up any handout-specific stuff now + +%% +% Abstract + +% TODO The abstract should be printed on its own page of the `titlepage' +% option was specified. +\renewenvironment{abstract} + {\begin{quotation}\if@tufte@sfsidenotes\begin{sffamily}\fi} + {\if@tufte@sfsidenotes\end{sffamily}\fi\end{quotation}} + + +%% +% If there is a `tufte-handout-local.tex' file, load it. + +\IfFileExists{tufte-handout-local.tex}{% + \input{tufte-handout-local}% + \@tufte@info@noline{Loading tufte-handout-local.tex}% +}{} + + +%% +% End of file +\endinput diff --git a/_extensions/fredguth/tufte/tufte-quarto.def b/_extensions/fredguth/tufte/tufte-quarto.def new file mode 100644 index 0000000..fff406d --- /dev/null +++ b/_extensions/fredguth/tufte/tufte-quarto.def @@ -0,0 +1,2026 @@ +%% +%% This file contains the code that is common to the Tufte-LaTeX document classes. +%% + +\ProvidesFile{tufte-quarto.def}[2022/10/20 Common code for the Tufte-LaTeX styles] + +%% +% The `xkeyval' package simplifies the user interface for the document class options +\RequirePackage{xkeyval} + +%% +% We use the `xifthen' package to handle our package option switches +\RequirePackage{xifthen} + +%% +% Define some shortcut macros for error/warning/info logging. +\RequirePackage{hardwrap} +\GenerateClassLogMacros[@tufte]{\@tufte@pkgname} +\newcommand{\@tufte@debug@info}[1]{\ifthenelse{\boolean{@tufte@debug}}{\@tufte@info{#1}}{}} +\newcommand{\@tufte@debug@info@noline}[1]{\ifthenelse{\boolean{@tufte@debug}}{\@tufte@info@noline{#1}}{}} + +%% +% `debug' option -- provides more information in the .log file for use in +% troubleshooting problems +\newboolean{@tufte@debug} +\DeclareOptionX[tufte]{debug}{\setboolean{@tufte@debug}{true}} + +%% +% `nofonts' option -- doesn't load any fonts +% `fonts' option -- tries to load fonts +\newboolean{@tufte@loadfonts}\setboolean{@tufte@loadfonts}{true} +\DeclareOptionX[tufte]{fonts}{\setboolean{@tufte@loadfonts}{true}} +\DeclareOptionX[tufte]{nofonts}{\setboolean{@tufte@loadfonts}{false}} + +%% +% `nols' option -- doesn't configure letterspacing +% `ls' option -- configures letterspacing +\newboolean{@tufte@letterspace}\setboolean{@tufte@letterspace}{true} +\DeclareOptionX[tufte]{ls}{\setboolean{@tufte@letterspace}{true}} +\DeclareOptionX[tufte]{nols}{\setboolean{@tufte@letterspace}{false}} + +%% +% `nobib' option -- doesn't load natbib or adjust the \cite command +\newboolean{@tufte@loadnatbib}\setboolean{@tufte@loadnatbib}{true} +\DeclareOptionX[tufte]{nobib}{\setboolean{@tufte@loadnatbib}{false}} + +%% +% `titlepage' option -- creates a full title page with \maketitle + +\newboolean{@tufte@titlepage} +\DeclareOptionX[tufte]{titlepage}{\setboolean{@tufte@titlepage}{true}} +\DeclareOptionX[tufte]{notitlepage}{\setboolean{@tufte@titlepage}{false}} + +%% +% `a4paper' option + +\newboolean{@tufte@afourpaper} +\DeclareOptionX[tufte]{a4paper}{\setboolean{@tufte@afourpaper}{true}} + +%% +% `b5paper' option + +\newboolean{@tufte@bfivepaper} +\DeclareOptionX[tufte]{b5paper}{\setboolean{@tufte@bfivepaper}{true}} + +%% +% `sfsidenotes' option -- typesets sidenotes in sans serif typeface + +\newboolean{@tufte@sfsidenotes} +\DeclareOptionX[tufte]{sfsidenotes}{\setboolean{@tufte@sfsidenotes}{true}} + +%% +% `symmetric' option -- puts marginpar space to the outside edge of the page +% Note: this option forces the twoside option (see the .cls files) + +\newboolean{@tufte@symmetric} +\DeclareOptionX[tufte]{symmetric}{ + \setboolean{@tufte@symmetric}{true} + \@tufte@info@noline{The `symmetric' option implies `twoside'} + \ExecuteOptionsX[tufte]{twoside} +} + +%% +% `twoside' option -- alternates running heads + +\newboolean{@tufte@twoside} +\DeclareOptionX[tufte]{twoside}{% + \setboolean{@tufte@twoside}{true} + \@tufte@info@noline{Passing the `twoside' option to the `\@tufte@class' class} + \PassOptionsToClass{twoside}{\@tufte@class} +} + +%% +% `notoc' option -- suppresses the Tufte-style table of contents + +\newboolean{@tufte@toc} +\setboolean{@tufte@toc}{true} +\DeclareOptionX[tufte]{notoc}{\setboolean{@tufte@toc}{false}} +\DeclareOptionX[tufte]{toc}{\setboolean{@tufte@toc}{true}} + +%% +% `justified' option -- uses fully justified text (flush left and flush +% right) instead of ragged right. + +\newboolean{@tufte@justified} +\DeclareOptionX[tufte]{justified}{\setboolean{@tufte@justified}{true}} + +%% +% `bidi' option -- loads the bidi package for bi-directional text + +\newboolean{@tufte@loadbidi} +\DeclareOptionX[tufte]{bidi}{\setboolean{@tufte@loadbidi}{true}} +\DeclareOptionX[tufte]{nobidi}{\setboolean{@tufte@loadbidi}{false}} + +%% +% `nohyper' option -- suppresses loading of the hyperref package + +\newboolean{@tufte@loadhyper} +\setboolean{@tufte@loadhyper}{true} +\DeclareOptionX[tufte]{hyper}{\setboolean{@tufte@loadhyper}{true}} +\DeclareOptionX[tufte]{nohyper}{\setboolean{@tufte@loadhyper}{false}} + +%% +% `sidenote', `marginnote', `caption', `citation', `marginals' options +% Each allows one of {justified,raggedleft,raggedright,raggedouter,auto}. + +\newcommand*{\@tufte@sidenote@justification}{\@tufte@justification@autodetect} +\define@choicekey*+[tufte]{common}{sidenoteTFT}[\@tufte@kvtext\@tufte@kvnum]{justified,raggedleft,raggedright,raggedouter,auto}[auto]{% + \ifcase\@tufte@kvnum\relax + \renewcommand*{\@tufte@sidenote@justification}{\justifying}% justified + \or + \renewcommand*{\@tufte@sidenote@justification}{\RaggedLeft}% ragged left + \or + \renewcommand*{\@tufte@sidenote@justification}{\RaggedRight}% ragged right + \or + \renewcommand*{\@tufte@sidenote@justification}{\@tufte@justification@outer}% ragged outer (flush right on verso pages, flush left on recto pages) + \or + \renewcommand*{\@tufte@sidenote@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options + \fi +}{% + \@tufte@warning@noline{Invalid option `#1' for sidenote key. Must be one of: justified, raggedleft, raggedright, raggedouter, auto} + \renewcommand*{\@tufte@sidenote@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options +} + +\newcommand*{\@tufte@marginnote@justification}{\@tufte@justification@autodetect} +\define@choicekey*+[tufte]{common}{marginnote}[\@tufte@kvtext\@tufte@kvnum]{justified,raggedleft,raggedright,raggedouter,auto}[auto]{% + \ifcase\@tufte@kvnum\relax + \renewcommand*{\@tufte@marginnote@justification}{\justifying}% justified + \or + \renewcommand*{\@tufte@marginnote@justification}{\RaggedLeft}% ragged left + \or + \renewcommand*{\@tufte@marginnote@justification}{\RaggedRight}% ragged right + \or + \renewcommand*{\@tufte@marginnote@justification}{\@tufte@justification@outer}% ragged outer (flush right on verso pages, flush left on recto pages) + \or + \renewcommand*{\@tufte@marginnote@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options + \fi +}{% + \@tufte@warning@noline{Invalid option `#1' for marginnote key. Must be one of: justified, raggedleft, raggedright, raggedouter, auto} + \renewcommand*{\@tufte@marginnote@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options +} + +\newcommand*{\@tufte@caption@justification}{\@tufte@justification@autodetect} +\define@choicekey*+[tufte]{common}{caption}[\@tufte@kvtext\@tufte@kvnum]{justified,raggedleft,raggedright,raggedouter,auto}[auto]{% + \ifcase\@tufte@kvnum\relax + \renewcommand*{\@tufte@caption@justification}{\justifying}% justified + \or + \renewcommand*{\@tufte@caption@justification}{\RaggedLeft}% ragged left + \or + \renewcommand*{\@tufte@caption@justification}{\RaggedRight}% ragged right + \or + \renewcommand*{\@tufte@caption@justification}{\@tufte@justification@caption@outer}% ragged outer (flush right on verso pages, flush left on recto pages) + \or + \renewcommand*{\@tufte@caption@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options + \fi +}{% + \@tufte@warning@noline{Invalid option `#1' for caption key. Must be one of: justified, raggedleft, raggedright, raggedouter, auto} + \renewcommand*{\@tufte@caption@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options +} + +\newcommand*{\@tufte@citation@justification}{\@tufte@justification@autodetect} +\define@choicekey*+[tufte]{common}{citation}[\@tufte@kvtext\@tufte@kvnum]{justified,raggedleft,raggedright,raggedouter,auto}[auto]{% + \ifcase\@tufte@kvnum\relax + \renewcommand*{\@tufte@citation@justification}{\justifying}% justified + \or + \renewcommand*{\@tufte@citation@justification}{\RaggedLeft}% ragged left + \or + \renewcommand*{\@tufte@citation@justification}{\RaggedRight}% ragged right + \or + \renewcommand*{\@tufte@citation@justification}{\@tufte@justification@outer}% ragged outer (flush right on verso pages, flush left on recto pages) + \or + \renewcommand*{\@tufte@citation@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options + \fi +}{% + \@tufte@warning@noline{Invalid option `#1' for citation key. Must be one of: justified, raggedleft, raggedright, raggedouter, auto} + \renewcommand*{\@tufte@citation@justification}{\@tufte@justification@autodetect}% autodetects best justification mode based on all class options +} + +% The ``marginals'' key simultaneously sets the same justification for all marginal material +\define@choicekey*+[tufte]{common}{marginals}[\@tufte@kvtext\@tufte@kvnum]{justified,raggedleft,raggedright,raggedouter,auto}[auto]{% + \ifcase\@tufte@kvnum\relax + \ExecuteOptionsX[tufte]{citation=justified,sidenote=justified,caption=justified,marginnote=justified}% justified + \or + \ExecuteOptionsX[tufte]{citation=raggedleft,sidenote=raggedleft,caption=raggedleft,marginnote=raggedleft}% ragged left + \or + \ExecuteOptionsX[tufte]{citation=raggedright,sidenote=raggedright,caption=raggedright,marginnote=raggedright}% ragged right + \or + \ExecuteOptionsX[tufte]{citation=raggedouter,sidenote=raggedouter,caption=raggedouter,marginnote=raggedouter}% ragged outer (flush right on verso pages, flush left on recto pages) + \or + \ExecuteOptionsX[tufte]{citation=auto,sidenote=auto,caption=auto,marginnote=auto}% autodetects best justification mode based on all class options + \fi +}{% + \@tufte@warning@noline{Invalid option `#1' for marginals key. Must be one of: justified, raggedleft, raggedright, raggedouter, auto} + \ExecuteOptionsX[tufte]{citation=auto,sidenote=auto,caption=auto,marginnote=auto}% autodetects best justification mode based on all class options +} + + +%% +% Unsupported options + +\newcommand{\@tufte@unsupported@option}[1]{\@tufte@warning@noline{Option `#1' is not supported -- ignoring option}\OptionNotUsed} + +\DeclareOptionX[tufte]{10pt}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{11pt}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{12pt}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{a5paper}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{executivepaper}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{legalpaper}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{landscape}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{onecolumn}{\@tufte@unsupported@option{\CurrentOption}} +\DeclareOptionX[tufte]{twocolumn}{\@tufte@unsupported@option{\CurrentOption}} + +%% +% Default `book' and `handout' options + +\ifthenelse{\equal{\@tufte@pkgname}{tufte-book}} + {\ExecuteOptionsX[tufte]{titlepage}} + {\ExecuteOptionsX[tufte]{notitlepage}} + + +\DeclareOptionX*{% + \@tufte@info@noline{Passing \CurrentOption\space to the `\@tufte@class' class.}% + \PassOptionsToClass{\CurrentOption}{\@tufte@class}% +} +\ProcessOptionsX*[tufte]\relax + +%% +% Load the appropriate base class +\@tufte@info@noline{Loading the base class `\@tufte@class'} +\LoadClass{\@tufte@class} + +%% +% Detect whether we're in two-side mode or not. (Used to set up running +% heads later.) + +\ifthenelse{\boolean{@twoside}} + {\setboolean{@tufte@twoside}{true}} + {} + + + +%% +% Detect if we're using pdfLaTeX + +\newboolean{@tufte@pdf} +\IfFileExists{ifpdf.sty}{% + \RequirePackage{ifpdf} + \ifthenelse{\boolean{pdf}} + {\setboolean{@tufte@pdf}{true}} + {\setboolean{@tufte@pdf}{false}} +}{% assume we're not using pdfTex? + \setboolean{@tufte@pdf}{false} +} + +%% +% Detect if we're using XeLaTeX + +\newboolean{@tufte@xetex} +\IfFileExists{ifxetex.sty}{% + \RequirePackage{ifxetex} + \ifthenelse{\boolean{xetex}} + {\setboolean{@tufte@xetex}{true}} + {\setboolean{@tufte@xetex}{false}} +}{% not using xelatex + \setboolean{@tufte@xetex}{false} +} + +\ifthenelse{\boolean{@tufte@xetex}}{% + \RequirePackage{xltxtra}% xltxtra loads xunicode and fontspec; must be loaded before bidi +}{} + +%% +% Detect if we're using LuaTeX + +\newboolean{@tufte@luatex} +\IfFileExists{ifluatex.sty}{% + \RequirePackage{ifluatex} + \ifthenelse{\boolean{luatex}} + {\setboolean{@tufte@luatex}{true}} + {\setboolean{@tufte@luatex}{false}} +}{% not using luatex + \setboolean{@tufte@luatex}{false} +} + +\ifthenelse{\boolean{@tufte@luatex}}{% + \RequirePackage{fontspec} + \RequirePackage[osf,sc]{mathpazo} + \setmainfont[Renderer=Basic, Numbers=OldStyle, Scale = 1.0]{TeX Gyre Pagella} + \setsansfont[Renderer=Basic, Scale=0.90]{TeX Gyre Heros} + \setmonofont[Renderer=Basic]{TeX Gyre Cursor} +}{} + +%% +% Globally sets the length + +\newcommand*{\gsetlength}[2]{% + \setlength{#1}{#2}% + \global#1=#1\relax% +} + +%% +% Globally sets a boolean + +\newcommand*{\gsetboolean}[2]{% based on code from ifthen pkg + \lowercase{\def\@tempa{#2}}% + \@ifundefined{@tempswa\@tempa}% + {\PackageError{ifthen}{You can only set a boolean to `true' or `false'}\@ehc}% + {\@ifundefined{#1\@tempa}% + {\PackageError{ifthen}{Boolean #1 undefined}\@ehc}% + {\global\csname#1\@tempa\endcsname}% + }% +} + +%% +% The titlesec and titletoc packages are used to change the style of the +% section headings. These packages should be loaded before the hyperref +% package. + +\RequirePackage{titlesec,titletoc} + +%%% +%% Loads the hyperref package and sets some default options. + +\newcommand{\TufteLoadHyperref}{% + \ifthenelse{\boolean{@tufte@xetex}} + {\RequirePackage[unicode,hyperfootnotes=false,xetex]{hyperref}} + {\RequirePackage[unicode,hyperfootnotes=false]{hyperref}} + \hypersetup{% + pdfborder = {0 0 0}, + bookmarksdepth = section, + citecolor = DarkGreen, + linkcolor = DarkBlue, + urlcolor = DarkGreen, + }% +} + +%%% +%% Load the `hyperref' package. + +\ifthenelse{\boolean{@tufte@loadhyper}}{% + \TufteLoadHyperref% +}{% hyperfootnotes override our modifications to the \footnote* and \@footnote* commands. + \PassOptionsToPackage{hyperfootnotes=false}{hyperref} +} + +%% +% Set the font sizes and baselines to match Tufte's books +\renewcommand\normalsize{% + \@setfontsize\normalsize\@xpt{14}% + \abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@ + \abovedisplayshortskip \z@ \@plus3\p@ + \belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@ + \belowdisplayskip \abovedisplayskip + \let\@listi\@listI} +\normalbaselineskip=14pt +\normalsize +\renewcommand\small{% + \@setfontsize\small\@ixpt{12}% + \abovedisplayskip 8.5\p@ \@plus3\p@ \@minus4\p@ + \abovedisplayshortskip \z@ \@plus2\p@ + \belowdisplayshortskip 4\p@ \@plus2\p@ \@minus2\p@ + \def\@listi{\leftmargin\leftmargini + \topsep 4\p@ \@plus2\p@ \@minus2\p@ + \parsep 2\p@ \@plus\p@ \@minus\p@ + \itemsep \parsep}% + \belowdisplayskip \abovedisplayskip +} +\renewcommand\footnotesize{% + \@setfontsize\footnotesize\@viiipt{10}% + \abovedisplayskip 6\p@ \@plus2\p@ \@minus4\p@ + \abovedisplayshortskip \z@ \@plus\p@ + \belowdisplayshortskip 3\p@ \@plus\p@ \@minus2\p@ + \def\@listi{\leftmargin\leftmargini + \topsep 3\p@ \@plus\p@ \@minus\p@ + \parsep 2\p@ \@plus\p@ \@minus\p@ + \itemsep \parsep}% + \belowdisplayskip \abovedisplayskip +} +\renewcommand\scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt} +\renewcommand\tiny{\@setfontsize\tiny\@vpt\@vipt} +\renewcommand\large{\@setfontsize\large\@xipt{15}} +\renewcommand\Large{\@setfontsize\Large\@xiipt{16}} +\renewcommand\LARGE{\@setfontsize\LARGE\@xivpt{18}} +\renewcommand\huge{\@setfontsize\huge\@xxpt{30}} +\renewcommand\Huge{\@setfontsize\Huge{24}{36}} + +\setlength\leftmargini {1pc} +\setlength\leftmarginii {1pc} +\setlength\leftmarginiii {1pc} +\setlength\leftmarginiv {1pc} +\setlength\leftmarginv {1pc} +\setlength\leftmarginvi {1pc} +\setlength\labelsep {.5pc} +\setlength\labelwidth {\leftmargini} +\addtolength\labelwidth{-\labelsep} + +%% +% \RaggedRight allows hyphenation + +\setlength{\parindent}{1.0pc}% +\setlength{\parskip}{0pt}% +\RequirePackage{ragged2e} +\setlength{\RaggedRightRightskip}{\z@ plus 0.08\hsize} + +% Paragraph indentation and separation for normal text +\newcommand{\@tufte@reset@par}{% + \setlength{\RaggedRightParindent}{1.0pc}% + \setlength{\JustifyingParindent}{1.0pc}% + \setlength{\parindent}{1pc}% + \setlength{\parskip}{0pt}% +} +\@tufte@reset@par + +% Paragraph indentation and separation for marginal text +\newcommand{\@tufte@margin@par}{% + \setlength{\RaggedRightParindent}{0.5pc}% + \setlength{\JustifyingParindent}{0.5pc}% + \setlength{\parindent}{0.5pc}% + \setlength{\parskip}{0pt}% +} + + +%% +% Set page layout geometry + +\RequirePackage[letterpaper,left=1in,top=1in,headsep=2\baselineskip,textwidth=26pc,marginparsep=2pc,marginparwidth=12pc,textheight=44\baselineskip,headheight=\baselineskip]{geometry} + +\ifthenelse{\boolean{@tufte@afourpaper}} + {\geometry{a4paper,left=24.8mm,top=27.4mm,headsep=2\baselineskip,textwidth=107mm,marginparsep=8.2mm,marginparwidth=49.4mm,textheight=49\baselineskip,headheight=\baselineskip}} + {} + +\ifthenelse{\boolean{@tufte@bfivepaper}} + {\geometry{paperwidth=176mm,paperheight=250mm,left=14.66mm,top=13.88mm,textwidth=102.66mm,marginparsep=7.33mm,marginparwidth=36.66mm,textheight=38\baselineskip,includehead}} + {} + +\ifthenelse{\boolean{@tufte@symmetric}} + {} + {\geometry{asymmetric}}% forces internal LaTeX `twoside' + + +%% +% Separation marginpars by a line's worth of space. + +\setlength\marginparpush{10pt} + +%% +% Font for margin items + +\ifthenelse{\boolean{@tufte@sfsidenotes}} + {\newcommand{\@tufte@marginfont}{\normalfont\footnotesize\sffamily}} + {\newcommand{\@tufte@marginfont}{\normalfont\footnotesize}} + +\newcommand*{\@tufte@sidenote@font}{\@tufte@marginfont} +\newcommand*{\@tufte@caption@font}{\@tufte@marginfont} +\newcommand*{\@tufte@marginnote@font}{\@tufte@marginfont} +\newcommand*{\@tufte@citation@font}{\@tufte@marginfont} + +\newcommand*{\setsidenotefont}[1]{\renewcommand*{\@tufte@sidenote@font}{#1}} +\newcommand*{\setcaptionfont}[1]{\renewcommand*{\@tufte@caption@font}{#1}} +\newcommand*{\setmarginnotefont}[1]{\renewcommand*{\@tufte@marginnote@font}{#1}} +\newcommand*{\setcitationfont}[1]{\renewcommand*{\@tufte@citation@font}{#1}} + +%% +% Set the justification based on the `justified' class option + +\newcommand{\@tufte@justification}{% + \ifthenelse{\boolean{@tufte@justified}}% + {\justifying}% + {\RaggedRight}% +} + +%% +% Turn off section numbering + +\setcounter{secnumdepth}{-1} + +%% +% Tighten up space between displays (e.g., a figure or table) and make symmetric + +\setlength\abovedisplayskip{6pt plus 2pt minus 4pt} +\setlength\belowdisplayskip{6pt plus 2pt minus 4pt} + +%% +% To implement full-width display environments + +\newboolean{@tufte@changepage} +\IfFileExists{changepage.sty}{% + \@tufte@debug@info@noline{Found changepage.sty} + \RequirePackage[strict]{changepage} + \setboolean{@tufte@changepage}{true} +}{% + \@tufte@debug@info@noline{Found chngpage.sty} + \RequirePackage[strict]{chngpage} + \setboolean{@tufte@changepage}{false} +} + +% Write our own aliases for the \checkoddpage and \ifoddpage or \ifcpoddpage commands +\newboolean{@tufte@odd@page} +\setboolean{@tufte@odd@page}{true} +\newcommand*{\@tufte@checkoddpage}{% + \checkoddpage% + \ifthenelse{\boolean{@tufte@changepage}}{% + \ifoddpage% + \setboolean{@tufte@odd@page}{true}% + \else% + \setboolean{@tufte@odd@page}{false}% + \fi% + }{% + \ifcpoddpage% + \setboolean{@tufte@odd@page}{true}% + \else% + \setboolean{@tufte@odd@page}{false}% + \fi% + }% +} + +%% +% Compute lengths used for full-width displays + +\newlength{\@tufte@overhang}% used by the fullwidth environment and the running heads +\newlength{\@tufte@fullwidth} +\newlength{\@tufte@caption@fill} + +\newcommand{\TufteRecalculate}{% + \setlength{\@tufte@overhang}{\marginparwidth} + \addtolength{\@tufte@overhang}{\marginparsep} + + \setlength{\@tufte@fullwidth}{\textwidth} + \addtolength{\@tufte@fullwidth}{\marginparsep} + \addtolength{\@tufte@fullwidth}{\marginparwidth} + + \setlength{\@tufte@caption@fill}{\textwidth} + \addtolength{\@tufte@caption@fill}{\marginparsep} +} + +\AtBeginDocument{\TufteRecalculate} + +%% +% Modified \title, \author, and \date commands. These store the +% (footnote-less) values in \plaintitle, \plainauthor, and \thedate, respectively. + +\newcommand{\plaintitle}{}% plain-text-only title +\newcommand{\plainauthor}{}% plain-text-only author +\newcommand{\plainpublisher}{}% plain-text-only publisher + +\newcommand{\thanklesstitle}{}% full title text minus \thanks{} +\newcommand{\thanklessauthor}{}% full author text minus \thanks{} +\newcommand{\thanklesspublisher}{}% full publisher minus \thanks{} + +\newcommand{\@publisher}{}% full publisher with \thanks{} +\newcommand{\thedate}{\today} + +% TODO Fix it so that \thanks is not spaced out (with `soul') and can be +% used in \maketitle when the `sfsidenotes' option is provided. +\renewcommand{\thanks}[1]{\NoCaseChange{\footnote{#1}}} + +\renewcommand{\title}[2][]{% + \gdef\@title{#2}% + \begingroup% + % TODO store contents of \thanks command + \renewcommand{\thanks}[1]{}% swallow \thanks contents + \protected@xdef\thanklesstitle{#2}% + \endgroup% + \ifthenelse{\isempty{#1}}% + {\renewcommand{\plaintitle}{\thanklesstitle}}% use thankless title + {\renewcommand{\plaintitle}{#1}}% use provided plain-text title + \ifthenelse{\isundefined{\hypersetup}}% + {}% hyperref is not loaded; do nothing + {\hypersetup{pdftitle={\plaintitle}}}% set the PDF metadata title +} + +\let\@author\@empty% suppress default latex.ltx ``no author'' warning +\renewcommand{\author}[2][]{% + \ifthenelse{\isempty{#2}}{}{\gdef\@author{#2}}% + \begingroup% + % TODO store contents of \thanks command + \renewcommand{\thanks}[1]{}% swallow \thanks contents + \protected@xdef\thanklessauthor{#2}% + \endgroup% + \ifthenelse{\isempty{#1}}% + {\renewcommand{\plainauthor}{\thanklessauthor}}% use thankless author + {\renewcommand{\plainauthor}{#1}}% use provided plain-text author + \ifthenelse{\isundefined{\hypersetup}}% + {}% hyperref is not loaded; do nothing + {\hypersetup{pdfauthor={\plainauthor}}}% set the PDF metadata author +} + +\renewcommand{\date}[1]{% + \gdef\@date{#1}% + \begingroup% + % TODO store contents of \thanks command + \renewcommand{\thanks}[1]{}% swallow \thanks contents + \protected@xdef\thedate{#1}% + \endgroup% +} + +%% +% Provides a \publisher command to set the publisher + +\newcommand{\publisher}[2][]{% + \gdef\@publisher{#2}% + \begingroup% + \renewcommand{\thanks}[1]{}% swallow \thanks contents + \protected@xdef\thanklesspublisher{#2}% + \endgroup% + \ifthenelse{\isempty{#1}} + {\renewcommand{\plainpublisher}{\thanklesspublisher}}% use thankless publisher + {\renewcommand{\plainpublisher}{#1}}% use provided plain-text publisher +} + +% TODO: Test \hypersetup{pdfauthor,pdftitle} with DVI and XeTeX + +%% +% Require paralist package for tighter lists + +\RequirePackage{paralist} + +% Add rightmargin to compactenum + +\def\@compactenum@{% + \expandafter\list\csname label\@enumctr\endcsname{% + \usecounter{\@enumctr}% + \rightmargin=2em% added this + \parsep\plparsep + \itemsep\plitemsep + \topsep\pltopsep + \partopsep\plpartopsep + \def\makelabel##1{\hss\llap{##1}}}} + +%% +% Improved letterspacing of small caps and all-caps text. +% +% First, try to use the `microtype' package, if it's available. +% Failing that, try to use the `soul' package, if it's available. +% Failing that, well, I give up. + +\DeclareTextFontCommand{\textsmallcaps}{\scshape} + +\RequirePackage{textcase} % provides \MakeTextUppercase and \MakeTextLowercase +\def\allcapsspacing{\@tufte@warning{Proper spacing of ALL-CAPS letters has not been set up.}} +\def\smallcapsspacing{\@tufte@warning{Proper spacing of small-caps letters has not been set up.}} +\newcommand{\allcaps}[1]{\allcapsspacing{\MakeTextUppercase{#1}}} +\newcommand{\smallcaps}[1]{\smallcapsspacing{\MakeTextLowercase{#1}}} + +% If we're using pdfLaTeX v1.40+, use the letterspace package. +% If we're using pdfLaTex < v1.40, use the soul package. +% If we're using XeLaTeX, use XeLaTeX letterspacing options. +% Otherwise fall back on the soul package. + +\ifthenelse{\boolean{@tufte@pdf}} + {\@tufte@debug@info@noline{ifpdf = true}} + {\@tufte@debug@info@noline{ifpdf = false}} + +\ifthenelse{\boolean{@tufte@xetex}} + {\@tufte@debug@info@noline{ifxetex = true}} + {\@tufte@debug@info@noline{ifxetex = false}} + +% Check pdfLaTeX version +\def\@tufte@pdftexversion{0} +\ifx\normalpdftexversion\@undefined \else + \let\pdftexversion \normalpdftexversion + \let\pdftexrevision\normalpdftexrevision + \let\pdfoutput \normalpdfoutput +\fi +\ifx\pdftexversion\@undefined \else + \ifx\pdftexversion\relax \else + \def\@tufte@pdftexversion{6} + \ifnum\pdftexversion < 140 + \def\@tufte@pdftexversion{5} + \fi + \fi +\fi + +\newboolean{@tufte@letterspace@pkg@prereqs} +\setboolean{@tufte@letterspace@pkg@prereqs}{true} +\ifnum\@tufte@pdftexversion<6 + \setboolean{@tufte@letterspace@pkg@prereqs}{false} +\fi + + +\newcommand{\@tufte@letterspacing@soul}{% + \RequirePackage{soul}% + \sodef\allcapsspacing{}{0.15em}{0.65em}{0.6em}% + \sodef\smallcapsspacing{}{0.075em}{0.5em}{0.6em}% + \sodef\sotextsc{\scshape}{0.075em}{0.5em}{0.6em}% + \renewcommand{\allcaps}[1]{\allcapsspacing{\MakeTextUppercase{##1}}}% + \renewcommand{\smallcaps}[1]{\smallcapsspacing{\scshape\MakeTextLowercase{##1}}}% + \renewcommand{\textsc}[1]{\sotextsc{##1}}% +} + +\newcommand{\@tufte@letterspacing@letterspace}{% + \@tufte@debug@info@noline{Modern version of pdfTeX detected. Using `letterspace' package}% + \RequirePackage{letterspace}% + % Set up letterspacing (using microtype package) -- requires pdfTeX v1.40+ + \renewcommand{\allcapsspacing}[1]{\textls[200]{##1}}% + \renewcommand{\smallcapsspacing}[1]{\textls[50]{##1}}% + \renewcommand{\allcaps}[1]{\allcapsspacing{\MakeTextUppercase{##1}}}% + \renewcommand{\smallcaps}[1]{\smallcapsspacing{\scshape\MakeTextLowercase{##1}}}% + \renewcommand{\textsc}[1]{\smallcapsspacing{\textsmallcaps{##1}}}% +} + +\ifthenelse{\boolean{@tufte@letterspace}}{% + \ifthenelse{\boolean{@tufte@pdf}\AND\boolean{@tufte@letterspace@pkg@prereqs}\AND\NOT\boolean{@tufte@xetex}}{% + % load letterspace pkg + \IfFileExists{letterspace.sty}{% + \@tufte@letterspacing@letterspace + }{}% + }{}% + % load soul pkg + \@ifpackageloaded{letterspace}{}{% + \IfFileExists{soul.sty}{% + \@tufte@letterspacing@soul + }{% + \@tufte@warning@noline{Couldn't locate `soul' package}% + }% soul not installed... giving up. + }% +}{} + +%\ifthenelse{\boolean{@tufte@letterspace}}{% + %\ifthenelse{\boolean{pdf}}{% + %\ifthenelse{\NOT\boolean{@tufte@letterspace@pkg@prereqs}}{% + %% pdfLaTeX version is too old or not using pdfLaTeX + %\ifthenelse{\boolean{@tufte@xetex}}{% + %% TODO use xetex letterspacing + %\@tufte@debug@info@noline{XeTeX detected. Reverting to `soul' package for letterspacing}% + %\@tufte@loadsoul% + %}{% + %% use `soul' package for letterspacing + %\@tufte@debug@info@noline{Old version of pdfTeX detected. Reverting to `soul' package for letterspacing}% + %\@tufte@loadsoul% + %} + %}{% + %\IfFileExists{letterspace.sty}{% + %\@tufte@debug@info@noline{Modern version of pdfTeX detected. Using `letterspace' package} + %\RequirePackage{letterspace} + %% Set up letterspacing (using microtype package) -- requires pdfTeX v1.40+ + %\renewcommand{\allcapsspacing}[1]{\textls[200]{##1}} + %\renewcommand{\smallcapsspacing}[1]{\textls[50]{##1}} + %\renewcommand{\allcaps}[1]{\textls[200]{\MakeTextUppercase{##1}}} + %\renewcommand{\smallcaps}[1]{\smallcapsspacing{\MakeTextLowercase{##1}}} + %\renewcommand{\textsc}[1]{\smallcapsspacing{\textsmallcaps{##1}}} + %}{% microtype failed, check for soul + %\@tufte@debug@info@noline{Modern version of pdfTeX detected, but `letterspace' package not installed. Reverting to `soul' package for letterspacing} + %\@tufte@loadsoul + %}% + %}% + %}{% + %\@tufte@debug@info@noline{Plain LaTeX detected. Using `soul' package for letterspacing} + %\@tufte@loadsoul + %} +%}{% +%% we're not to load letterspacing, so do nothing +%} + + +%% +% An environment for paragraph-style section + +\providecommand\newthought[1]{% + \tuftebreak + \noindent\textsc{#1}% +} + +%% +% Redefine the display environments (quote, quotation, etc.) + +\renewenvironment{verse} + {\let\\\@centercr + \list{}{\itemsep \z@ + \itemindent -1pc% + \listparindent\itemindent + \rightmargin \leftmargin + \advance\leftmargin 1pc}% + \small% + \item\relax} + {\endlist} +\renewenvironment{quotation} + {\list{}{\listparindent 1pc% + \itemindent \listparindent + \rightmargin \leftmargin + \parsep \z@ \@plus\p@}% + \small% + \item\relax\noindent\ignorespaces} + {\endlist} +\renewenvironment{quote} + {\list{}{\rightmargin\leftmargin}% + \small% + \item\relax} + {\endlist} + +%% +% Italicize description run-in headings (instead of the default bold) + +\renewcommand*\descriptionlabel[1]{\hspace\labelsep\normalfont\em #1} + + +%% +% Used for doublespacing, and other linespacing + +\RequirePackage{setspace} + +%% +% Color +\RequirePackage[dvipsnames,svgnames]{xcolor}% load before bidi + +%% +% Load the bidi package if instructed to do so. This package must be loaded +% prior to our redefining the \footnote and \cite commands. + +\ifthenelse{\boolean{@tufte@loadbidi}}{% + \AtBeginDocument{% + \RequirePackage{bidi} + \@tufte@pkghook@post@bidi% + }% +}{} + + +%% +% A function that removes leading and trailing spaces from the supplied macro. +% Based on code written by Michael Downes (See ``Around the Bend'', #15.) +% Executing \@tufte@trim@spaces\xyzzy will result in the contents of \xyzzy +% being trimmed of leading and trailing white space. + +\catcode`\Q=3 +\def\@tufte@trim@spaces#1{% + % Use grouping to emulate a multi-token afterassignment queue + \begingroup% + % Put `\toks 0 {' into the afterassignment queue + \aftergroup\toks\aftergroup0\aftergroup{% + % Apply \trimb to the replacement text of #1, adding a leading + % \noexpand to prevent brace stripping and to serve another purpose + % later. + \expandafter\@tufte@trim@b\expandafter\noexpand#1Q Q}% + % Transfer the trimmed text back into #1. + \edef#1{\the\toks0}% +} + +% \trimb removes a trailing space if present, then calls \@tufte@trim@c to +% clean up any leftover bizarre Qs, and trim a leading space. In +% order for \trimc to work properly we need to put back a Q first. +\def\@tufte@trim@b#1 Q{\@tufte@trim@c#1Q} + +% Execute \vfuzz assignment to remove leading space; the \noexpand +% will now prevent unwanted expansion of a macro or other expandable +% token at the beginning of the trimmed text. The \endgroup will feed +% in the \aftergroup tokens after the \vfuzz assignment is completed. +\def\@tufte@trim@c#1Q#2{\afterassignment\endgroup \vfuzz\the\vfuzz#1} +\catcode`\Q=11 + +%% +% Citations should go in the margin as sidenotes + +\ifthenelse{\boolean{@tufte@loadnatbib}}{% + \RequirePackage{natbib}% + \RequirePackage{bibentry}% allows bibitems to be typeset outside thebibliography environment + % Redefine the \BR@b@bibitem command to fix a bug with bibentry+chicago style + \renewcommand\BR@b@bibitem[2][]{% + \ifthenelse{\isempty{#1}}% + {\BR@bibitem{#2}}% + {\BR@bibitem[#1]{#2}}% + \BR@c@bibitem{#2}% + }% + \nobibliography*% pre-loads the bibliography keys + \providecommand{\doi}[1]{\textsc{doi:} #1}% pre-defining this so it may be used before the \bibliography command it issued +}{} + +%% +% Normal \cite behavior +\newcounter{@tufte@num@bibkeys}% +\newcommand{\@tufte@normal@cite}[2][0pt]{% + % Snag the last bibentry in the list for later comparison + \let\@temp@last@bibkey\@empty% + \@for\@temp@bibkey:=#2\do{\let\@temp@last@bibkey\@temp@bibkey}% + \sidenote[][#1]{% + % Loop through all the bibentries, separating them with semicolons and spaces + \normalsize\normalfont\@tufte@citation@font% + \setcounter{@tufte@num@bibkeys}{0}% + \@for\@temp@bibkeyx:=#2\do{% + \ifthenelse{\equal{\@temp@last@bibkey}{\@temp@bibkeyx}}% + {\ifthenelse{\equal{\value{@tufte@num@bibkeys}}{0}}{}{and\ }% + \@tufte@trim@spaces\@temp@bibkeyx% trim spaces around bibkey + \bibentry{\@temp@bibkeyx}}% + {\@tufte@trim@spaces\@temp@bibkeyx% trim spaces around bibkey + \bibentry{\@temp@bibkeyx};\ }% + \stepcounter{@tufte@num@bibkeys}% + }% + }% +} + + +%% +% Macros for holding the list of cite keys until after the \sidenote + +\gdef\@tufte@citations{}% list of cite keys +\newcommand\@tufte@add@citation[1]{\relax% adds a new bibkey to the list of cite keys + \ifx\@tufte@citations\@empty\else + \g@addto@macro\@tufte@citations{,}% separate by commas + \fi + \g@addto@macro\@tufte@citations{#1} +} + +\newcommand{\@tufte@print@citations}[1][0pt]{% puts the citations in a margin note + % Snag the last bibentry in the list for later comparison + \let\@temp@last@bibkey\@empty% + \@for\@temp@bibkey:=\@tufte@citations\do{\let\@temp@last@bibkey\@temp@bibkey}% + \marginpar{% + \hbox{}\vspace*{#1}% + \@tufte@citation@font% + \@tufte@citation@justification% + \@tufte@margin@par% use parindent and parskip settings for marginal text + \vspace*{-1\baselineskip}% + % Loop through all the bibentries, separating them with semicolons and spaces + \setcounter{@tufte@num@bibkeys}{0}% + \@for\@temp@bibkeyx:=\@tufte@citations\do{% + \ifthenelse{\equal{\@temp@last@bibkey}{\@temp@bibkeyx}}% + {\ifthenelse{\equal{\value{@tufte@num@bibkeys}}{0}}{}{and\ }% + \@tufte@trim@spaces\@temp@bibkeyx% trim spaces around bibkey + \bibentry{\@temp@bibkeyx}}% + {\@tufte@trim@spaces\@temp@bibkeyx% trim spaces around bibkey + \bibentry{\@temp@bibkeyx};\ }% + \stepcounter{@tufte@num@bibkeys}% + }% + }% +} + +%% +% \cite behavior when executed within a sidenote + +\newcommand{\@tufte@sidenote@citations}{}% contains list of \cites in sidenote +\newcommand{\@tufte@infootnote@cite}[1]{% + \@tufte@add@citation{#1} +} + +%% +% Set the default \cite style. This is set and reset by the \sidenote command. + +\ifthenelse{\boolean{@tufte@loadnatbib}}{% + \let\cite\@tufte@normal@cite +}{} + +%% +% Transform existing \footnotes into \sidenotes +% Sidenote: ``Where God meant footnotes to go.'' ---Tufte + +\RequirePackage{optparams}% for our new sidenote commands -- provides multiple optional arguments for commands + +\providecommand{\footnotelayout}{\@tufte@sidenote@font\@tufte@sidenote@justification} +\renewcommand{\footnotelayout}{\@tufte@sidenote@font\@tufte@sidenote@justification} + +% Override footmisc's definition to set the sidenote marks (numbers) inside the +% sidenote's text block. +\long\def\@makefntext#1{\@textsuperscript{\@tufte@sidenote@font\tiny\@thefnmark}\,\footnotelayout#1} + +% Set the in-text footnote mark in the same typeface as the body text itself. +\def\@makefnmark{\hbox{\@textsuperscript{\normalfont\footnotesize\@thefnmark}}} + +\providecommand*{\multiplefootnotemarker}{3sp} +\providecommand*{\multfootsep}{,} + +\renewcommand{\@footnotemark}{% + \leavevmode% + \ifhmode% + \edef\@x@sf{\the\spacefactor}% + \@tufte@check@multiple@sidenotes% + \nobreak% + \fi% + \@makefnmark% + \ifhmode\spacefactor\@x@sf\fi% + \relax% +} + +\newcommand{\@tufte@check@multiple@sidenotes}{% + \ifdim\lastkern=\multiplefootnotemarker\relax% + \edef\@x@sf{\the\spacefactor}% + \unkern% + \textsuperscript{\multfootsep}% + \spacefactor\@x@sf\relax% + \fi +} + +\renewcommand\@footnotetext[2][0pt]{% + \marginpar{% + \hbox{}\vspace*{#1}% + \def\baselinestretch {\setspace@singlespace}% + \reset@font\footnotesize% + \@tufte@margin@par% use parindent and parskip settings for marginal text + \vspace*{-1\baselineskip}\noindent% + \protected@edef\@currentlabel{% + \csname p@footnote\endcsname\@thefnmark% + }% + \color@begingroup% + \@makefntext{% + \ignorespaces#2% + }% + \color@endgroup% + }% +}% + +% Ensure this is run after the bidi package has been loaded +\def\@tufte@pkghook@post@bidi{}% +\g@addto@macro{\@tufte@pkghook@post@bidi}{% + \renewcommand\@footnotetext[2][0pt]{% + \marginpar{% + \hbox{}\vspace*{#1}% + \def\baselinestretch {\setspace@singlespace}% + \if@rl@footnote\@rltrue\else\@rlfalse\fi% + \reset@font\footnotesize% + \@tufte@margin@par% use parindent and parskip settings for marginal text + \vspace*{-1\baselineskip}\noindent% + \protected@edef\@currentlabel{% + \csname p@footnote\endcsname\@thefnmark% + }% + \color@begingroup% + \@makefntext{% + \ignorespaces#2% + }% + \color@endgroup% + }% + }% +}% + +% +% Define \sidenote command. Can handle \cite. + +\newlength{\@tufte@sidenote@vertical@offset} +\setlength{\@tufte@sidenote@vertical@offset}{0pt} + +% #1 = footnote num, #2 = vertical offset, #3 = footnote text +\long\def\@tufte@sidenote[#1][#2]#3{% + \ifthenelse{\boolean{@tufte@loadnatbib}}{% + \let\cite\@tufte@infootnote@cite% use the in-sidenote \cite command + }{}% + \gdef\@tufte@citations{}% clear out any old citations + \ifthenelse{\NOT\isempty{#2}}{% + \gsetlength{\@tufte@sidenote@vertical@offset}{#2}% + }{% + \gsetlength{\@tufte@sidenote@vertical@offset}{0pt}% + }% + \ifthenelse{\isempty{#1}}{% + % no specific footnote number provided + \stepcounter\@mpfn% + \protected@xdef\@thefnmark{\thempfn}% + \@footnotemark\@footnotetext[\@tufte@sidenote@vertical@offset]{#3}% + }{% + % specific footnote number provided + \begingroup% + \csname c@\@mpfn\endcsname #1\relax% + \unrestored@protected@xdef\@thefnmark{\thempfn}% + \endgroup% + \@footnotemark\@footnotetext[\@tufte@sidenote@vertical@offset]{#3}% + }% + \@tufte@print@citations% print any citations + \ifthenelse{\boolean{@tufte@loadnatbib}}{% + \let\cite\@tufte@normal@cite% go back to using normal in-text \cite command + }{}% + \unskip\ignorespaces% remove extra white space + \kern-\multiplefootnotemarker% remove \kern left behind by sidenote + \kern\multiplefootnotemarker\relax% add new \kern here to replace the one we yanked +} + +\newcommand{\sidenote}{\optparams{\@tufte@sidenote}{[][0pt]}} +\renewcommand{\footnote}{\optparams{\@tufte@sidenote}{[][0pt]}} + +%% +% Sidenote without the footnote mark + +\newcommand\marginnote[2][0pt]{% + \ifthenelse{\boolean{@tufte@loadnatbib}}{% + \let\cite\@tufte@infootnote@cite% use the in-sidenote \cite command + }{}% + \gdef\@tufte@citations{}% clear out any old citations + \marginpar{\hbox{}\vspace*{#1}\@tufte@marginnote@font\@tufte@marginnote@justification\@tufte@margin@par\vspace*{-1\baselineskip}\noindent #2}% + \@tufte@print@citations% print any citations + \ifthenelse{\boolean{@tufte@loadnatbib}}{% + \let\cite\@tufte@normal@cite% go back to using normal in-text \cite command + }{}% +} + + +%% +% The placeins package provides the \FloatBarrier command. This forces +% LaTeX to place all of the floats before proceeding. We'll use this to +% keep the float (figure and table) numbers in sequence. +\RequirePackage{placeins} + +%% +% Margin float environment + +\newsavebox{\@tufte@margin@floatbox} +\newenvironment{@tufte@margin@float}[2][-1.2ex]% + {\FloatBarrier% process all floats before this point so the figure/table numbers stay in order. + \begin{lrbox}{\@tufte@margin@floatbox}% + \begin{minipage}{\marginparwidth}% + \@tufte@caption@font% + \def\@captype{#2}% + \hbox{}\vspace*{#1}% + \@tufte@caption@justification% + \@tufte@margin@par% + \noindent% + } + {\end{minipage}% + \end{lrbox}% + \marginpar{\usebox{\@tufte@margin@floatbox}}% + } + + +%% +% Margin figure environment + +% \newenvironment{marginfigure}[1][-1.2ex]% +% {\begin{@tufte@margin@float}[#1]{figure}} +% {\end{@tufte@margin@float}} + + +%% +% Margin table environment + +% \newenvironment{margintable}[1][-1.2ex]% +% {\begin{@tufte@margin@float}[#1]{table}} +% {\end{@tufte@margin@float}} + + +%% +% Auto-detects the proper text alignment based on the various class options + +\newcommand*{\@tufte@justification@autodetect}{% + \ifthenelse{\boolean{@tufte@justified}}% + {\justifying}% + {\RaggedRight}% +} + +%% +% Forces the outer edge of the caption to be set ragged. +% Therefore, on verso pages it's ragged left, and on recto pages it's ragged right. + +\newcommand*{\@tufte@justification@caption@outer}{% + \ifthenelse{\boolean{@tufte@float@recto}}% + {\RaggedRight}% + {\RaggedLeft}% +} + +\newcommand*{\@tufte@justification@outer}{% + \@tufte@checkoddpage% + \ifthenelse{\boolean{@tufte@odd@page}}% + {\RaggedRight}% + {\RaggedLeft}% +} + + + +%% +% A collection of macros to be used with the new Tufte-style float environments. +% \setfloatalignment forces the caption placement to be treated as top, bottom, etc. +% \forcerectofloat forces the float to be treated as if it were appearing on a recto page. +% \forceversofloat does the same, but for verso pages. + +\newcommand{\@tufte@float@debug@info}{}% contains debug info generated as the float is processed +\newcommand{\@tufte@float@debug}[1]{% adds debug info to the queue for output + \ifthenelse{\equal{\@tufte@float@debug@info}{}}% + {\def\@tufte@float@debug@info{#1}}% + {\g@addto@macro\@tufte@float@debug@info{\MessageBreak#1}}% +} + +\newcommand{\floatalignment}{x}% holds the current float alignment (t, b, h, p) +\newcommand{\setfloatalignment}[1]{\global\def\floatalignment{#1}\@tufte@float@debug{Forcing position: [#1]}}% manually sets the float alignment +\newboolean{@tufte@float@recto} +\newcommand{\forcerectofloat}{\gsetboolean{@tufte@float@recto}{true}\@tufte@float@debug{Forcing page: [recto]}} +\newcommand{\forceversofloat}{\gsetboolean{@tufte@float@recto}{false}\@tufte@float@debug{Forcing page: [verso]}} + +% Boxes to temporarily store our float and caption +\newsavebox{\@tufte@figure@box} +\newsavebox{\@tufte@caption@box} + +% Save original LaTeX float environment +\let\@tufte@orig@float\@float +\let\@tufte@orig@endfloat\end@float + +% New length for tweaking float captions +\newlength{\@tufte@caption@vertical@offset} +\setlength{\@tufte@caption@vertical@offset}{0pt} + +% Store the caption and label contents +\newcommand{\@tufte@stored@shortcaption}{} +\newcommand{\@tufte@stored@caption}{} +\newcommand{\@tufte@stored@label}{} + +\long\def\@tufte@caption[#1][#2]#3{% + \ifthenelse{\isempty{#1}}% + {\gdef\@tufte@stored@shortcaption{#3}}% + {\gdef\@tufte@stored@shortcaption{#1}}% + \gsetlength{\@tufte@caption@vertical@offset}{-#2}% we want a positive offset to lower captions + \gdef\@tufte@stored@caption{#3}% +} + +\newcommand{\@tufte@label}[1]{% + \gdef\@tufte@stored@label{#1}% +} + +\newcommand{\@tufte@fps}{} + +\newboolean{@tufte@float@star} +\newlength{\@tufte@float@contents@width} + +%% +% Define a float environment to place the captions in the margin space + +\newenvironment{@tufte@float}[3][htbp]% + {% begin @tufte@float + % Should this float be full-width or just text-width? + \ifthenelse{\equal{#3}{star}}% + {\gsetboolean{@tufte@float@star}{true}}% + {\gsetboolean{@tufte@float@star}{false}}% + % Check page side (recto/verso) and store detected value -- can be overriden in environment contents + \@tufte@checkoddpage% + \ifthenelse{\boolean{@tufte@odd@page}}% + {\gsetboolean{@tufte@float@recto}{true}\@tufte@float@debug{Detected page: [recto/odd]}}% + {\gsetboolean{@tufte@float@recto}{false}\@tufte@float@debug{Detected page: [verso/even]}}% + % If the float placement specifier is 'b' and only 'b', then bottom-align the mini-pages, otherwise top-align them. + \renewcommand{\@tufte@fps}{#1}% + \@tufte@float@debug{Allowed positions: [#1]}% + \ifthenelse{\equal{#1}{b}\OR\equal{#1}{B}}% + {\renewcommand{\floatalignment}{b}\@tufte@float@debug{Presumed position: [bottom]}}% + {\renewcommand{\floatalignment}{t}\@tufte@float@debug{Presumed position: [top]}}% + % Capture the contents of the \caption and \label commands to use later + \global\let\@tufte@orig@caption\caption% + \global\let\@tufte@orig@label\label% + \renewcommand{\caption}{\optparams{\@tufte@caption}{[][0pt]}}% + \renewcommand{\label}[1]{\@tufte@label{##1}}% + % Handle subfigure package compatibility + \ifthenelse{\boolean{@tufte@packages@subfigure}}{% + % don't move the label while inside a \subfigure or \subtable command + \global\let\label\@tufte@orig@label% + }{}% subfigure package is not loaded + \@tufte@orig@float{#2}[#1]% + \ifthenelse{\boolean{@tufte@float@star}}% + {\setlength{\@tufte@float@contents@width}{\@tufte@fullwidth}}% + {\setlength{\@tufte@float@contents@width}{\textwidth}}% + \begin{lrbox}{\@tufte@figure@box}% + \begin{minipage}[\floatalignment]{\@tufte@float@contents@width}\hbox{}% + }{% end @tufte@float + \par\hbox{}\vspace{-\baselineskip}\ifthenelse{\prevdepth>0}{\vspace{-\prevdepth}}{}% align baselines of boxes + \end{minipage}% + \end{lrbox}% + % build the caption box + \begin{lrbox}{\@tufte@caption@box}% + \begin{minipage}[\floatalignment]{\marginparwidth}\hbox{}% + \ifthenelse{\NOT\equal{\@tufte@stored@caption}{}}{\@tufte@orig@caption[\@tufte@stored@shortcaption]{\@tufte@stored@caption}}{}% + \ifthenelse{\NOT\equal{\@tufte@stored@label}{}}{\@tufte@orig@label{\@tufte@stored@label}}{}% + \par\vspace{-\prevdepth}%% TODO: DOUBLE-CHECK FOR SAFETY + \end{minipage}% + \end{lrbox}% + % now typeset the stored boxes + \begin{fullwidth}% + \begin{minipage}[\floatalignment]{\linewidth}% + \ifthenelse{\boolean{@tufte@float@star}}% + {\@tufte@float@fullwidth[\@tufte@caption@vertical@offset]{\@tufte@figure@box}{\@tufte@caption@box}}% + {\@tufte@float@textwidth[\@tufte@caption@vertical@offset]{\@tufte@figure@box}{\@tufte@caption@box}}% + \end{minipage}% + \end{fullwidth}% + \@tufte@orig@endfloat% end original LaTeX float environment + % output debug info + \ifthenelse{\boolean{@tufte@debug}}{% + \typeout{^^J^^J----------- Tufte-LaTeX float information ----------}% + \ifthenelse{\equal{\@tufte@stored@label}{}}% + {\typeout{Warning: Float unlabeled!}}% + {\typeout{Float label: [\@tufte@stored@label]}}% + \typeout{Page number: [\thepage]}% + \def\MessageBreak{^^J}% + \typeout{\@tufte@float@debug@info}% + \ifthenelse{\boolean{@tufte@symmetric}}% + {\typeout{Symmetric: [true]}}% + {\typeout{Symmetric: [false]}}% + \typeout{----------------------------------------------------^^J^^J}% + }{}% + % reset commands and temp boxes and captions + \gdef\@tufte@float@debug@info{}% + \let\caption\@tufte@orig@caption% + \let\label\@tufte@orig@label% + \begin{lrbox}{\@tufte@figure@box}\hbox{}\end{lrbox}% + \begin{lrbox}{\@tufte@caption@box}\hbox{}\end{lrbox}% + \gdef\@tufte@stored@shortcaption{}% + \gdef\@tufte@stored@caption{}% + \gdef\@tufte@stored@label{}% + \gsetlength{\@tufte@caption@vertical@offset}{0pt}% reset caption offset + } + +\newcommand{\@tufte@float@textwidth}[3][0pt]{% + \ifthenelse{\NOT\boolean{@tufte@symmetric}\OR\boolean{@tufte@float@recto}}{% + % asymmetric or page is odd, so caption is on the right + \hbox{% + \usebox{#2}% + \hspace{\marginparsep}% + \smash{\raisebox{#1}{\usebox{#3}}}% + }% + \@tufte@float@debug{Caption position: [right]}% + }{% symmetric pages and page is even, so caption is on the left + \hbox{% + \smash{\raisebox{#1}{\usebox{#3}}}% + \hspace{\marginparsep}% + \usebox{#2}% + }% + \@tufte@float@debug{Caption position: [left]}% + }% +} + +\newcommand{\@tufte@float@fullwidth}[3][0pt]{% + \ifthenelse{\equal{\floatalignment}{b}}% + {% place caption above figure + \ifthenelse{\NOT\boolean{@tufte@symmetric}\OR\boolean{@tufte@float@recto}}% + {\hfill\smash{\raisebox{#1}{\usebox{#3}}}\par\usebox{#2}\@tufte@float@debug{Caption position: [above right]}}% caption on the right + {\smash{\raisebox{#1}{\usebox{#3}}}\hfill\par\usebox{#2}\@tufte@float@debug{Caption position: [above left]}}% caption on the left + }{% place caption below figure + \ifthenelse{\NOT\boolean{@tufte@symmetric}\OR\boolean{@tufte@float@recto}}% + {\usebox{#2}\par\hfill\smash{\raisebox{#1}{\usebox{#3}}}\@tufte@float@debug{Caption position: [below right]}}% caption on the right + {\usebox{#2}\par\smash{\raisebox{#1}{\usebox{#3}}}\hfill\@tufte@float@debug{Caption position: [below left]}}% caption on the left + }% +} + + +%% +% Redefine the figure environment to place the captions in the margin space + +\renewenvironment{figure}[1][htbp]% + {\ifvmode\else\unskip\fi\begin{@tufte@float}[#1]{figure}{}} + {\end{@tufte@float}} + + +%% +% Redefine the table environment to place the captions in the margin space + +\renewenvironment{table}[1][htbp] + {\ifvmode\else\unskip\fi\begin{@tufte@float}[#1]{table}{}} + {\end{@tufte@float}} + + +%% +% Full-width figure + +\renewenvironment{figure*}[1][htbp]% + {\ifvmode\else\unskip\fi\begin{@tufte@float}[#1]{figure}{star}} + {\end{@tufte@float}} + + +%% +% Full-width table + +\renewenvironment{table*}[1][htbp]% + {\ifvmode\else\unskip\fi\begin{@tufte@float}[#1]{table}{star}} + {\end{@tufte@float}} + + +%% +% Full-page-width area + +\newenvironment{fullwidth} + {\ifthenelse{\boolean{@tufte@symmetric}}% + {\ifthenelse{\boolean{@tufte@changepage}}{\begin{adjustwidth*}{}{-\@tufte@overhang}}{\begin{adjustwidth}[]{}{-\@tufte@overhang}}}% + {\begin{adjustwidth}{}{-\@tufte@overhang}}% + }% + {\ifthenelse{\boolean{@tufte@symmetric}}% + {\ifthenelse{\boolean{@tufte@changepage}}{\end{adjustwidth*}}{\end{adjustwidth}}}% + {\end{adjustwidth}}% + } + +%% +% Format the captions in a style similar to the sidenotes + +\long\def\@caption#1[#2]#3{% + \par% + \addcontentsline{\csname ext@#1\endcsname}{#1}% + {\protect\numberline{\csname the#1\endcsname}{\ignorespaces #2}}% + \begingroup% + \@parboxrestore% + \if@minipage% + \@setminipage% + \fi% + \@tufte@caption@font\@tufte@caption@justification% + \noindent\csname fnum@#1\endcsname: \ignorespaces#3\par% + %\@makecaption{\csname fnum@#1\endcsname}{\ignorespaces #3}\par + \endgroup} + +%% +% If we're NOT using XeLaTeX and the `nofonts' class option was NOT provided, +% we should load the Palatino, Helvetica, and Bera Mono fonts (if they are +% installed.) + +\ifthenelse{\boolean{@tufte@loadfonts}\AND\NOT\boolean{@tufte@xetex}\AND\NOT\boolean{@tufte@luatex}}{% + \IfFileExists{mathpazo.sty}{\RequirePackage[osf,sc]{mathpazo}}{} + \IfFileExists{helvet.sty}{\RequirePackage[scaled=0.90]{helvet}}{} + \IfFileExists{beramono.sty}{\RequirePackage[scaled=0.85]{beramono}}{} + \RequirePackage[T1]{fontenc} + \RequirePackage{textcomp} +}{} + + +%% +% Turns newlines into spaces. Based on code from the `titlesec' package. + +\DeclareRobustCommand{\@tufte@newlinetospace}{% + \@ifstar{\@tufte@newlinetospace@i}{\@tufte@newlinetospace@i}% +} + +\def\@tufte@newlinetospace@i{% + \ifdim\lastskip>\z@\else\space\fi + \ignorespaces% +} + +\DeclareRobustCommand{\newlinetospace}[1]{% + \let\@tufte@orig@cr\\% save the original meaning of \\ + \def\\{\@tufte@newlinetospace}% turn \\ and \\* into \space + \let\newline\\% turn \newline into \space + #1% + \let\\\@tufte@orig@cr% revert to original meaning of \\ +} + + +%% +% Sets up the running heads and folios. + +\RequirePackage{fancyhdr} + +% Set the default page style to 'fancy' +\pagestyle{fancy} + +% Set the header/footer width to be the body text block plus the margin +% note area. +\AtBeginDocument{% + \ifthenelse{\boolean{@tufte@symmetric}} + {\fancyhfoffset[LE,RO]{\@tufte@overhang}} + {\fancyhfoffset[RE,RO]{\@tufte@overhang}} +} + +% The running heads/feet don't have rules +\renewcommand{\headrulewidth}{0pt} +\renewcommand{\footrulewidth}{0pt} + +% The 'fancy' page style is the default style for all pages. +\fancyhf{} % clear header and footer fields +\ifthenelse{\boolean{@tufte@twoside}} + {\fancyhead[LE]{\thepage\quad\smallcaps{\newlinetospace{\plainauthor}}}% + \fancyhead[RO]{\smallcaps{\newlinetospace{\plaintitle}}\quad\thepage}} + {\fancyhead[RE,RO]{\smallcaps{\newlinetospace{\plaintitle}}\quad\thepage}} + + +% The `plain' page style is used on chapter opening pages. +% In Tufte's /Beautiful Evidence/ he never puts page numbers at the +% bottom of pages -- the folios are unexpressed. +\fancypagestyle{plain}{ + \fancyhf{} % clear header and footer fields + % Uncomment the following five lines of code if you want the opening page + % of the chapter to express the folio in the lower outside corner. + %\ifthenelse{\boolean{@tufte@twoside}} + % {\fancyfoot[LE,RO]{\thepage}} + % {\fancyfoot[RE,RO]{\thepage}} +} + +% The `empty' page style suppresses all headers and footers. +% It's used on title pages and `intentionally blank' pages. +\fancypagestyle{empty}{ + \fancyhf{} % clear header and footer fields +} + + +%% +% Set raggedright and paragraph indentation for document + +\AtBeginDocument{\@tufte@justification} + + +%% +% Prints the list of class options and their states. + +\newcommand{\typeoutbool}[2]{% + \ifthenelse{\boolean{#2}} + {\typeout{\space\space#1: true}} + {\typeout{\space\space#1: false}} +} + +\newcommand{\typeoutstr}[2]{% + \typeout{\space\space#1: #2} +} + +\newcommand{\PrintTufteSettings}{% + \typeout{-------------------- Tufte-LaTeX settings ----------} + \typeout{Class: \@tufte@pkgname} + \typeout{} + \typeout{Class options:} + \typeoutbool{a4paper}{@tufte@afourpaper} + \typeoutbool{b5paper}{@tufte@bfivepaper} + \typeoutbool{load fonts}{@tufte@loadfonts} + \typeoutbool{fully-justified}{@tufte@justified} + \typeoutbool{letterspacing}{@tufte@letterspace} + \typeoutbool{sans-serif sidenotes}{@tufte@sfsidenotes} + \typeoutbool{symmetric margins}{@tufte@symmetric} + \typeoutbool{titlepage}{@tufte@titlepage} + \typeoutbool{twoside}{@tufte@twoside} + \typeoutbool{debug}{@tufte@debug} + \typeout{} + \typeout{Internal variables:} + \typeoutbool{[twoside]}{@twoside} + \typeoutbool{pdflatex}{@tufte@pdf} + \typeoutbool{xelatex}{@tufte@xetex} + \typeout{----------------------------------------------------} +} + +%% +% Amount of space to skip before \newthought or after title block + +\newskip\tufteskipamount +\tufteskipamount=1.0\baselineskip plus 0.5ex minus 0.2ex + +\newcommand{\tuftebreak}{\par\ifdim\lastskip<\tufteskipamount + \removelastskip\penalty-100\tufteskip\fi} + +\newcommand{\tufteskip}{\vspace\tufteskipamount} + + +%% +% Produces a full title page + +\newcommand{\maketitlepage}[0]{% + \cleardoublepage% + {% + \sffamily% + \begin{fullwidth}% + \fontsize{18}{20}\selectfont\par\noindent\textcolor{darkgray}{\allcaps{\thanklessauthor}}% + \vspace{11.5pc}% + \fontsize{36}{40}\selectfont\par\noindent\textcolor{darkgray}{\allcaps{\thanklesstitle}}% + \vfill% + \fontsize{14}{16}\selectfont\par\noindent\allcaps{\thanklesspublisher}% + \end{fullwidth}% + } + \thispagestyle{empty}% + \clearpage% +} + +%% +% Title block + +\renewcommand{\maketitle}{% + \newpage + \global\@topnum\z@% prevent floats from being placed at the top of the page + \begingroup + \setlength{\parindent}{0pt}% + \setlength{\parskip}{4pt}% + \let\@@title\@empty + \let\@@author\@empty + \let\@@date\@empty + \ifthenelse{\boolean{@tufte@sfsidenotes}}{% + \gdef\@@title{\sffamily\LARGE\allcaps{\@title}\par}% + \gdef\@@author{\sffamily\Large\allcaps{\@author}\par}% + \gdef\@@date{\sffamily\Large\allcaps{\@date}\par}% + }{% + \gdef\@@title{\LARGE\itshape\@title\par}% + \gdef\@@author{\Large\itshape\@author\par}% + \gdef\@@date{\Large\itshape\@date\par}% + }% + \@@title + \@@author + \@@date + \endgroup + \thispagestyle{plain}% suppress the running head + \tuftebreak% add some space before the text begins + \@afterindentfalse\@afterheading% suppress indentation of the next paragraph +} + + +%% +% Title page (if the `titlepage' option was passed to the tufte-handout +% class.) + +\ifthenelse{\boolean{@tufte@titlepage}} + {\renewcommand{\maketitle}{\maketitlepage}} + {} + +%% +% When \cleardoublepage is called, produce a blank (empty) page -- i.e., +% without headers and footers +\def\cleardoublepage{\clearpage\if@twoside\ifodd\c@page\else + \hbox{} + %\vspace*{\fill} + %\begin{center} + % This page intentionally contains only this sentence. + %\end{center} + %\vspace{\fill} + \thispagestyle{empty} + \newpage + \if@twocolumn\hbox{}\newpage\fi\fi\fi} + +%% +% Make Tuftian-style section headings and TOC formatting + +\titleformat{\chapter}% + [display]% shape + {\relax\ifthenelse{\NOT\boolean{@tufte@symmetric}}{\begin{fullwidth}}{}}% format applied to label+text + {\itshape\huge\thechapter}% label + {0pt}% horizontal separation between label and title body + {\huge\rmfamily\itshape}% before the title body + [\ifthenelse{\NOT\boolean{@tufte@symmetric}}{\end{fullwidth}}{}]% after the title body + +\titleformat{\section}% + [hang]% shape + {\normalfont\Large\itshape}% format applied to label+text + {\thesection}% label + {1em}% horizontal separation between label and title body + {}% before the title body + []% after the title body + +\titleformat{\subsection}% + [hang]% shape + {\normalfont\large\itshape}% format applied to label+text + {\thesubsection}% label + {1em}% horizontal separation between label and title body + {}% before the title body + []% after the title body + +\titleformat{\paragraph}% + [runin]% shape + {\normalfont\itshape}% format applied to label+text + {\theparagraph}% label + {1em}% horizontal separation between label and title body + {}% before the title body + []% after the title body + +\titlespacing*{\chapter}{0pt}{50pt}{40pt} +\titlespacing*{\section}{0pt}{3.5ex plus 1ex minus .2ex}{2.3ex plus .2ex} +\titlespacing*{\subsection}{0pt}{3.25ex plus 1ex minus .2ex}{1.5ex plus.2ex} + +% Subsubsection and following section headings shouldn't be used. +% See Bringhurst's _The Elements of Typography_, section 4.2.2. +\renewcommand\subsubsection{% + \@tufte@error{\string\subsubsection is undefined by this class. + See Robert Bringhurst's _The Elements of + Typographic Style_, section 4.2.2. + \string\subsubsection was used} + {From Bringhurst's _The Elements of Typographic Style_, section 4.2.2: Use as + many levels of headings as you need, no more and no fewer. Also see the many + related threads on Ask E.T. at http://www.edwardtufte.com/.} +} + +\renewcommand\subparagraph{% + \@tufte@error{\string\subparagraph is undefined by this class.% + See Robert Bringhurst's _The Elements of + Typographic Style_, section 4.2.2. + \string\subparagraph was used} + {From Bringhurst's _The Elements of Typographic Style_, section 4.2.2: Use as + many levels of headings as you need, no more and no fewer. Also see the many + related threads on Ask E.T. at http://www.edwardtufte.com/.} +} + + +% Formatting for main TOC (printed in front matter) +% {section} [left] {above} {before w/label} {before w/o label} {filler + page} [after] +\ifthenelse{\boolean{@tufte@toc}}{% + \titlecontents{part}% FIXME + [0em] % distance from left margin + {\vspace{1.5\baselineskip}\begin{fullwidth}\LARGE\rmfamily\itshape} % above (global formatting of entry) + {\contentslabel{2em}} % before w/label (label = ``II'') + {} % before w/o label + {\rmfamily\upshape\qquad\thecontentspage} % filler + page (leaders and page num) + [\end{fullwidth}] % after + \titlecontents{chapter}% + [0em] % distance from left margin + {\vspace{1.5\baselineskip}\begin{fullwidth}\LARGE\rmfamily\itshape} % above (global formatting of entry) + {\hspace*{0em}\contentslabel{2em}} % before w/label (label = ``2'') + {\hspace*{0em}} % before w/o label + {\rmfamily\upshape\qquad\thecontentspage} % filler + page (leaders and page num) + [\end{fullwidth}] % after + \titlecontents{section}% FIXME + [0em] % distance from left margin + {\vspace{0\baselineskip}\begin{fullwidth}\Large\rmfamily\itshape} % above (global formatting of entry) + {\hspace*{2em}\contentslabel{2em}} % before w/label (label = ``2.6'') + {\hspace*{2em}} % before w/o label + {\rmfamily\upshape\qquad\thecontentspage} % filler + page (leaders and page num) + [\end{fullwidth}] % after + \titlecontents{subsection}% FIXME + [0em] % distance from left margin + {\vspace{0\baselineskip}\begin{fullwidth}\large\rmfamily\itshape} % above (global formatting of entry) + {\hspace*{4em}\contentslabel{4em}} % before w/label (label = ``2.6.1'') + {\hspace*{4em}} % before w/o label + {\rmfamily\upshape\qquad\thecontentspage} % filler + page (leaders and page num) + [\end{fullwidth}] % after + \titlecontents{paragraph}% FIXME + [0em] % distance from left margin + {\vspace{0\baselineskip}\begin{fullwidth}\normalsize\rmfamily\itshape} % above (global formatting of entry) + {\hspace*{6em}\contentslabel{2em}} % before w/label (label = ``2.6.0.0.1'') + {\hspace*{6em}} % before w/o label + {\rmfamily\upshape\qquad\thecontentspage} % filler + page (leaders and page num) + [\end{fullwidth}] % after +}{} + +%% +% Format lists of figures/tables + +\renewcommand\listoffigures{% + \ifthenelse{\equal{\@tufte@class}{book}}% + {\chapter*{\listfigurename}}% + {\section*{\listfigurename}}% +% \begin{fullwidth}% + \@starttoc{lof}% +% \end{fullwidth}% +} + +\renewcommand\listoftables{% + \ifthenelse{\equal{\@tufte@class}{book}}% + {\chapter*{\listtablename}}% + {\section*{\listtablename}}% +% \begin{fullwidth}% + \@starttoc{lot}% +% \end{fullwidth}% +} + +\newcommand{\@tufte@lof@line}[2]{% + % #1 is the figure/table number and its caption text + % #2 is the page number on which the figure/table appears + \leftskip 0.0em + \rightskip 0em + \parfillskip 0em plus 1fil + \parindent 0.0em + \@afterindenttrue + \interlinepenalty\@M + \leavevmode + \@tempdima 2.0em + \advance\leftskip\@tempdima + \null\nobreak\hskip -\leftskip + {#1}\nobreak\qquad\nobreak#2% + \par% +} + +\renewcommand*\l@figure{\@tufte@lof@line} +\let\l@table\l@figure + + +%% +% A handy command to disable hyphenation for short bits of text. +% Borrowed from Peter Wilson's `hyphenat' package. + +\AtBeginDocument{% + \@ifpackageloaded{hyphenat}{}{% + \newlanguage\langwohyphens% define a language without hyphenation rules + \providecommand{\nohyphens}[1]{{\language\langwohyphens #1}}% used for short bits of text + \providecommand{\nohyphenation}{\language\langwohyphens}% can be used inside environments for longer text + }% +} + +%% +% Redefine \bibsection to not mark the running heads. +% (Code modified from natbib.sty.) + +\ifthenelse{\boolean{@tufte@loadnatbib}}{% + \@ifundefined{chapter}{% + \renewcommand\bibsection{\section*{\refname}}% + }{% + \@ifundefined{NAT@sectionbib}{% + \renewcommand\bibsection{\chapter{\bibname}}% + }{% + \renewcommand\bibsection{\section*{\bibname}}% + }% + }% +} + +%% +% An index environment to mimic Tufte's indexes + +\RequirePackage{multicol} +\renewenvironment{theindex}{% + \ifthenelse{\equal{\@tufte@class}{book}}% + {\chapter{\indexname}}% + {\section*{\indexname}}% + \begin{fullwidth}% + \small% + \parskip0pt% + \parindent0pt% + \let\item\@idxitem% + \begin{multicols}{3}% +}{% + \end{multicols}% + \end{fullwidth}% +} +\renewcommand\@idxitem{\par\hangindent 2em} +\renewcommand\subitem{\par\hangindent 3em\hspace*{1em}} +\renewcommand\subsubitem{\par\hangindent 4em\hspace*{2em}} +\renewcommand\indexspace{\par\addvspace{1.0\baselineskip plus 0.5ex minus 0.2ex}\relax}% +\newcommand{\lettergroup}[1]{}% swallow the letter heading in the index + + +%% +% A couple commands to increase the number of floats you can use at a time. + +\def\morefloats{% provides a total of 52 floats + \ifthenelse{\isundefined{\bx@S}}{% + \@tufte@debug@info@noline{Adding 34 more float slots.} + \newinsert\bx@S + \newinsert\bx@T + \newinsert\bx@U + \newinsert\bx@V + \newinsert\bx@W + \newinsert\bx@X + \newinsert\bx@Y + \newinsert\bx@Z + \newinsert\bx@a + \newinsert\bx@b + \newinsert\bx@c + \newinsert\bx@d + \newinsert\bx@e + \newinsert\bx@f + \newinsert\bx@g + \newinsert\bx@h + \newinsert\bx@i + \newinsert\bx@j + \newinsert\bx@k + \newinsert\bx@l + \newinsert\bx@m + \newinsert\bx@n + \newinsert\bx@o + \newinsert\bx@p + \newinsert\bx@q + \newinsert\bx@r + \newinsert\bx@s + \newinsert\bx@t + \newinsert\bx@u + \newinsert\bx@v + \newinsert\bx@w + \newinsert\bx@x + \newinsert\bx@y + \newinsert\bx@z + \gdef\@freelist{\@elt\bx@A\@elt\bx@B\@elt\bx@C\@elt\bx@D\@elt\bx@E + \@elt\bx@F\@elt\bx@G\@elt\bx@H\@elt\bx@I\@elt\bx@J + \@elt\bx@K\@elt\bx@L\@elt\bx@M\@elt\bx@N + \@elt\bx@O\@elt\bx@P\@elt\bx@Q\@elt\bx@R + \@elt\bx@S\@elt\bx@T\@elt\bx@U\@elt\bx@V + \@elt\bx@W\@elt\bx@X\@elt\bx@Y\@elt\bx@Z + \@elt\bx@a\@elt\bx@b\@elt\bx@c\@elt\bx@d\@elt\bx@e + \@elt\bx@f\@elt\bx@g\@elt\bx@h\@elt\bx@i\@elt\bx@j + \@elt\bx@k\@elt\bx@l\@elt\bx@m\@elt\bx@n + \@elt\bx@o\@elt\bx@p\@elt\bx@q\@elt\bx@r + \@elt\bx@s\@elt\bx@t\@elt\bx@u\@elt\bx@v + \@elt\bx@w\@elt\bx@x\@elt\bx@y\@elt\bx@z}% + }{% we've already added another 34 floats, so we'll add 26 more, but that's it! + \ifthenelse{\isundefined{\bx@AA}}{% + \@tufte@debug@info@noline{Adding 26 more float slots.} + \newinsert\bx@AA + \newinsert\bx@BB + \newinsert\bx@CC + \newinsert\bx@DD + \newinsert\bx@EE + \newinsert\bx@FF + \newinsert\bx@GG + \newinsert\bx@HH + \newinsert\bx@II + \newinsert\bx@JJ + \newinsert\bx@KK + \newinsert\bx@LL + \newinsert\bx@MM + \newinsert\bx@NN + \newinsert\bx@OO + \newinsert\bx@PP + \newinsert\bx@QQ + \newinsert\bx@RR + \newinsert\bx@SS + \newinsert\bx@TT + \newinsert\bx@UU + \newinsert\bx@VV + \newinsert\bx@WW + \newinsert\bx@XX + \newinsert\bx@YY + \newinsert\bx@ZZ + \gdef\@freelist{\@elt\bx@A\@elt\bx@B\@elt\bx@C\@elt\bx@D\@elt\bx@E + \@elt\bx@F\@elt\bx@G\@elt\bx@H\@elt\bx@I\@elt\bx@J + \@elt\bx@K\@elt\bx@L\@elt\bx@M\@elt\bx@N + \@elt\bx@O\@elt\bx@P\@elt\bx@Q\@elt\bx@R + \@elt\bx@S\@elt\bx@T\@elt\bx@U\@elt\bx@V + \@elt\bx@W\@elt\bx@X\@elt\bx@Y\@elt\bx@Z + \@elt\bx@a\@elt\bx@b\@elt\bx@c\@elt\bx@d\@elt\bx@e + \@elt\bx@f\@elt\bx@g\@elt\bx@h\@elt\bx@i\@elt\bx@j + \@elt\bx@k\@elt\bx@l\@elt\bx@m\@elt\bx@n + \@elt\bx@o\@elt\bx@p\@elt\bx@q\@elt\bx@r + \@elt\bx@s\@elt\bx@t\@elt\bx@u\@elt\bx@v + \@elt\bx@w\@elt\bx@x\@elt\bx@y\@elt\bx@z + \@elt\bx@AA\@elt\bx@BB\@elt\bx@CC\@elt\bx@DD\@elt\bx@EE + \@elt\bx@FF\@elt\bx@GG\@elt\bx@HH\@elt\bx@II\@elt\bx@JJ + \@elt\bx@KK\@elt\bx@LL\@elt\bx@MM\@elt\bx@NN + \@elt\bx@OO\@elt\bx@PP\@elt\bx@QQ\@elt\bx@RR + \@elt\bx@SS\@elt\bx@TT\@elt\bx@UU\@elt\bx@VV + \@elt\bx@WW\@elt\bx@XX\@elt\bx@YY\@elt\bx@ZZ}% + }{% + \@tufte@error{You may only call \string\morefloats\space twice. See the Tufte-LaTeX documentation for other workarounds} + {There are already 78 float slots allocated. Try using \string\FloatBarrier\space or \string\clearpage\space to place some floats before creating more.} + }% + }% +} + + +%% +% Detect if the subfigure package has been loaded + +\newboolean{@tufte@packages@subfigure} +\setboolean{@tufte@packages@subfigure}{false} +\AtBeginDocument{% + \@ifpackageloaded{subfigure} + {\gsetboolean{@tufte@packages@subfigure}{true}} + {\gsetboolean{@tufte@packages@subfigure}{false}}% +} + + +%% +% Detect of the float package has been loaded + +\AtBeginDocument{% + \@ifpackageloaded{float}{% + % Save the redefined float environment (instead of the LaTeX float environment) + \let\@tufte@orig@float\@float + \let\@tufte@orig@endfloat\end@float + + % Define Tuftian float styles (with the caption in the margin) + \newcommand{\floatc@tufteplain}[2]{% + \begin{lrbox}{\@tufte@caption@box}% + \begin{minipage}[\floatalignment]{\marginparwidth}\hbox{}% + \@tufte@caption@font{\@fs@cfont #1:} #2\par% + \end{minipage}% + \end{lrbox}% + \smash{\hspace{\@tufte@caption@fill}\usebox{\@tufte@caption@box}}% + } + \newcommand{\fs@tufteplain}{% + \def\@fs@cfont{\@tufte@caption@font}% + \let\@fs@capt\floatc@tufteplain% + \def\@fs@pre{}% + \def\@fs@post{}% + \def\@fs@mid{}% + \let\@fs@iftopcapt\iftrue% + } + \let\fs@tufteplaintop=\fs@tufteplain + \let\floatc@tufteplaintop=\floatc@tufteplain + \newcommand\floatc@tufteruled[2]{% + {\@fs@cfont #1} #2\par% + } + \newcommand\fs@tufteruled{% + \def\@fs@cfont{\@tufte@caption@font}% + \let\@fs@capt\floatc@tufteplain% + \def\@fs@pre{\hrule height.8pt depth0pt width\textwidth \kern2pt}% + \def\@fs@post{\kern2pt\hrule width\textwidth\relax}% + \def\@fs@mid{}% + \let\@fs@iftopcapt\iftrue% + } + \newcommand\fs@tufteboxed{% + \def\@fs@cfont{}% + \let\@fs@capt\floatc@tufteplain% + \def\@fs@pre{% + \setbox\@currbox\vbox{\hbadness10000 + \moveleft3.4pt\vbox{\advance\hsize by6.8pt + \hrule \hbox to\hsize{\vrule\kern3pt + \vbox{\kern3pt\box\@currbox\kern3pt}\kern3pt\vrule}\hrule}} + }% + \def\@fs@mid{\kern2pt}% + \def\@fs@post{}% + \let\@fs@iftopcapt\iftrue% + } + }{% + % Nothing to do + } +} + +\AtBeginDocument{% + \@ifpackageloaded{algorithm}{% + % Set the float style to the Tuftian version + \ifthenelse{\equal{\ALG@floatstyle}{plain}\OR\equal{\ALG@floatstyle}{ruled}\OR\equal{\ALG@floatstyle}{boxed}}{% + \@tufte@info@noline{Switching algorithm float style from \ALG@floatstyle\space to tufte\ALG@floatstyle}% + \floatstyle{tufte\ALG@floatstyle}% + \restylefloat{algorithm}% + }{}% + }{% + % Nothing to do + } +} + + +%% +% For compatibility with the subfig package, we'll set captions=false so that +% it doesn't load the caption package (which modifies our own caption +% formatting). + +\PassOptionsToPackage{caption=false}{subfig} + + +%% +% If debugging is enabled, print the Tufte-LaTeX options and the list of +% files. + +\ifthenelse{\boolean{@tufte@debug}} + {\PrintTufteSettings\listfiles} + {} + + +%% +% If there is a `tufte-common-local.tex' file, load it up. + +\IfFileExists{tufte-common-local.tex} + {\input{tufte-common-local.tex}% + \@tufte@info@noline{Loading tufte-common-local.tex}} + {} + + +%% +% End of file +\endinput + diff --git a/_extensions/fredguth/tufte/tufte.bst b/_extensions/fredguth/tufte/tufte.bst new file mode 100644 index 0000000..ee0c26b --- /dev/null +++ b/_extensions/fredguth/tufte/tufte.bst @@ -0,0 +1,1314 @@ +%% +%% This is file `tufte.bst', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% merlin.mbs (with options: `seq-no,vonx,ed-au,nmlm,x2,m1,yr-com,xmth,tit-qq,qx,atit-u,jxper,trtit-b,volp-com,jwdpg,pp-last,num-xser,pre-pub,edpar,edby,blk-com,pp,ed,abr,ord,url,url-blk,nfss') +%% ---------------------------------------- +%% *** tufte handout bibliography style *** +%% +%% Copyright 1994-2002 Patrick W Daly + % =============================================================== + % IMPORTANT NOTICE: + % This bibliographic style (bst) file has been generated from one or + % more master bibliographic style (mbs) files, listed above. + % + % This generated file can be redistributed and/or modified under the terms + % of the LaTeX Project Public License Distributed from CTAN + % archives in directory macros/latex/base/lppl.txt; either + % version 1 of the License, or any later version. + % =============================================================== + % Name and version information of the main mbs file: + % \ProvidesFile{merlin.mbs}[2002/10/21 4.05 (PWD, AO, DPC)] + % For use with BibTeX version 0.99a or later + %------------------------------------------------------------------- + % This bibliography style file is intended for texts in ENGLISH + % This is a numerical citation style, and as such is standard LaTeX. + % It requires no extra package to interface to the main text. + % The form of the \bibitem entries is + % \bibitem{key}... + % Usage of \cite is as follows: + % \cite{key} ==>> [#] + % \cite[chap. 2]{key} ==>> [#, chap. 2] + % where # is a number determined by the ordering in the reference list. + % The order in the reference list is that by which the works were originally + % cited in the text, or that in the database. + %--------------------------------------------------------------------- + +ENTRY + { address + author + booktitle + chapter + edition + editor + howpublished + institution + journal + key + month + note + number + organization + pages + publisher + school + series + title + type + url + volume + year + } + {} + { label } +INTEGERS { output.state before.all mid.sentence after.sentence after.block } +FUNCTION {init.state.consts} +{ #0 'before.all := + #1 'mid.sentence := + #2 'after.sentence := + #3 'after.block := +} +STRINGS { s t} +FUNCTION {output.nonnull} +{ 's := + output.state mid.sentence = + { ", " * write$ } + { output.state after.block = + { add.period$ write$ + newline$ + "\newblock " write$ + } + { output.state before.all = + 'write$ + { add.period$ " " * write$ } + if$ + } + if$ + mid.sentence 'output.state := + } + if$ + s +} +FUNCTION {output} +{ duplicate$ empty$ + 'pop$ + 'output.nonnull + if$ +} +FUNCTION {output.check} +{ 't := + duplicate$ empty$ + { pop$ "empty " t * " in " * cite$ * warning$ } + 'output.nonnull + if$ +} +FUNCTION {fin.entry} +{ add.period$ + write$ + newline$ +} + +FUNCTION {new.block} +{ output.state before.all = + 'skip$ + { after.block 'output.state := } + if$ +} +FUNCTION {new.sentence} +{ output.state after.block = + 'skip$ + { output.state before.all = + 'skip$ + { after.sentence 'output.state := } + if$ + } + if$ +} +FUNCTION {add.blank} +{ " " * before.all 'output.state := +} + +FUNCTION {date.block} +{ + skip$ +} + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} +FUNCTION {and} +{ 'skip$ + { pop$ #0 } + if$ +} +FUNCTION {or} +{ { pop$ #1 } + 'skip$ + if$ +} +FUNCTION {non.stop} +{ duplicate$ + "}" * add.period$ + #-1 #1 substring$ "." = +} + +STRINGS {z} +FUNCTION {remove.dots} +{ 'z := + "" + { z empty$ not } + { z #1 #1 substring$ + z #2 global.max$ substring$ 'z := + duplicate$ "." = 'pop$ + { * } + if$ + } + while$ +} +FUNCTION {new.block.checka} +{ empty$ + 'skip$ + 'new.block + if$ +} +FUNCTION {new.block.checkb} +{ empty$ + swap$ empty$ + and + 'skip$ + 'new.block + if$ +} +FUNCTION {new.sentence.checka} +{ empty$ + 'skip$ + 'new.sentence + if$ +} +FUNCTION {new.sentence.checkb} +{ empty$ + swap$ empty$ + and + 'skip$ + 'new.sentence + if$ +} +FUNCTION {field.or.null} +{ duplicate$ empty$ + { pop$ "" } + 'skip$ + if$ +} +FUNCTION {emphasize} +{ duplicate$ empty$ + { pop$ "" } + { "\emph{" swap$ * "}" * } + if$ +} +FUNCTION {tie.or.space.prefix} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ +} + +FUNCTION {capitalize} +{ "u" change.case$ "t" change.case$ } + +FUNCTION {space.word} +{ " " swap$ * " " * } + % Here are the language-specific definitions for explicit words. + % Each function has a name bbl.xxx where xxx is the English word. + % The language selected here is ENGLISH +FUNCTION {bbl.and} +{ "and"} + +FUNCTION {bbl.etal} +{ "et~al." } + +FUNCTION {bbl.editors} +{ "eds." } + +FUNCTION {bbl.editor} +{ "ed." } + +FUNCTION {bbl.edby} +{ "edited by" } + +FUNCTION {bbl.edition} +{ "edn." } + +FUNCTION {bbl.volume} +{ "vol." } + +FUNCTION {bbl.of} +{ "of" } + +FUNCTION {bbl.number} +{ "no." } + +FUNCTION {bbl.nr} +{ "no." } + +FUNCTION {bbl.in} +{ "in" } + +FUNCTION {bbl.pages} +{ "pp." } + +FUNCTION {bbl.page} +{ "p." } + +FUNCTION {bbl.chapter} +{ "chap." } + +FUNCTION {bbl.techrep} +{ "Tech. Rep." } + +FUNCTION {bbl.mthesis} +{ "Master's thesis" } + +FUNCTION {bbl.phdthesis} +{ "Ph.D. thesis" } + +FUNCTION {bbl.first} +{ "1st" } + +FUNCTION {bbl.second} +{ "2nd" } + +FUNCTION {bbl.third} +{ "3rd" } + +FUNCTION {bbl.fourth} +{ "4th" } + +FUNCTION {bbl.fifth} +{ "5th" } + +FUNCTION {bbl.st} +{ "st" } + +FUNCTION {bbl.nd} +{ "nd" } + +FUNCTION {bbl.rd} +{ "rd" } + +FUNCTION {bbl.th} +{ "th" } + +MACRO {jan} {"Jan."} + +MACRO {feb} {"Feb."} + +MACRO {mar} {"Mar."} + +MACRO {apr} {"Apr."} + +MACRO {may} {"May"} + +MACRO {jun} {"Jun."} + +MACRO {jul} {"Jul."} + +MACRO {aug} {"Aug."} + +MACRO {sep} {"Sep."} + +MACRO {oct} {"Oct."} + +MACRO {nov} {"Nov."} + +MACRO {dec} {"Dec."} + +FUNCTION {eng.ord} +{ duplicate$ "1" swap$ * + #-2 #1 substring$ "1" = + { bbl.th * } + { duplicate$ #-1 #1 substring$ + duplicate$ "1" = + { pop$ bbl.st * } + { duplicate$ "2" = + { pop$ bbl.nd * } + { "3" = + { bbl.rd * } + { bbl.th * } + if$ + } + if$ + } + if$ + } + if$ +} + +MACRO {acmcs} {"ACM Computing Surveys"} + +MACRO {acta} {"Acta Informatica"} + +MACRO {cacm} {"Communications of the ACM"} + +MACRO {ibmjrd} {"IBM Journal of Research and Development"} + +MACRO {ibmsj} {"IBM Systems Journal"} + +MACRO {ieeese} {"IEEE Transactions on Software Engineering"} + +MACRO {ieeetc} {"IEEE Transactions on Computers"} + +MACRO {ieeetcad} + {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} + +MACRO {ipl} {"Information Processing Letters"} + +MACRO {jacm} {"Journal of the ACM"} + +MACRO {jcss} {"Journal of Computer and System Sciences"} + +MACRO {scp} {"Science of Computer Programming"} + +MACRO {sicomp} {"SIAM Journal on Computing"} + +MACRO {tocs} {"ACM Transactions on Computer Systems"} + +MACRO {tods} {"ACM Transactions on Database Systems"} + +MACRO {tog} {"ACM Transactions on Graphics"} + +MACRO {toms} {"ACM Transactions on Mathematical Software"} + +MACRO {toois} {"ACM Transactions on Office Information Systems"} + +MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"} + +MACRO {tcs} {"Theoretical Computer Science"} +FUNCTION {bibinfo.check} +{ swap$ + duplicate$ missing$ + { + pop$ pop$ + "" + } + { duplicate$ empty$ + { + swap$ pop$ + } + { swap$ + pop$ + } + if$ + } + if$ +} +FUNCTION {bibinfo.warn} +{ swap$ + duplicate$ missing$ + { + swap$ "missing " swap$ * " in " * cite$ * warning$ pop$ + "" + } + { duplicate$ empty$ + { + swap$ "empty " swap$ * " in " * cite$ * warning$ + } + { swap$ + pop$ + } + if$ + } + if$ +} +FUNCTION {format.url} +{ url empty$ + { "" } + { "\urlprefix\url{" url * "}" * } + if$ +} + +STRINGS { bibinfo} +INTEGERS { nameptr namesleft numnames } + +FUNCTION {format.names} +{ 'bibinfo := + duplicate$ empty$ 'skip$ { + 's := + "" 't := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + "{ff~}{vv~}{ll}{, jj}" + format.name$ + bibinfo bibinfo.check + 't := + nameptr #1 > + { + nameptr #1 + #1 + = + numnames #2 + > and + { "others" 't := + #1 'namesleft := } + 'skip$ + if$ + namesleft #1 > + { ", " * t * } + { + numnames #2 > + { "," * } + 'skip$ + if$ + s nameptr "{ll}" format.name$ duplicate$ "others" = + { 't := } + { pop$ } + if$ + t "others" = + { + " " * bbl.etal * + } + { + bbl.and + space.word * t * + } + if$ + } + if$ + } + 't + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + } if$ +} +FUNCTION {format.names.ed} +{ + format.names +} +FUNCTION {format.authors} +{ author "author" format.names +} +FUNCTION {get.bbl.editor} +{ editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ } + +FUNCTION {format.editors} +{ editor "editor" format.names duplicate$ empty$ 'skip$ + { + " " * + get.bbl.editor + "(" swap$ * ")" * + * + } + if$ +} +FUNCTION {format.note} +{ + note empty$ + { "" } + { note #1 #1 substring$ + duplicate$ "{" = + 'skip$ + { output.state mid.sentence = + { "l" } + { "u" } + if$ + change.case$ + } + if$ + note #2 global.max$ substring$ * "note" bibinfo.check + } + if$ +} + +FUNCTION {format.title} +{ title + "title" bibinfo.check + duplicate$ empty$ 'skip$ + { + "\enquote{" swap$ * + "}, " * + } + if$ +} +FUNCTION {end.quote.title} +{ title empty$ + 'skip$ + { before.all 'output.state := } + if$ +} +FUNCTION {output.bibitem} +{ newline$ + "\bibitem{" write$ + cite$ write$ + "}" write$ + newline$ + "" + before.all 'output.state := +} + +FUNCTION {n.dashify} +{ + 't := + "" + { t empty$ not } + { t #1 #1 substring$ "-" = + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } + if$ + } + while$ +} + +FUNCTION {word.in} +{ bbl.in + " " * } + +FUNCTION {format.date} +{ + "" + duplicate$ empty$ + year "year" bibinfo.check duplicate$ empty$ + { swap$ 'skip$ + { "there's a month but no year in " cite$ * warning$ } + if$ + * + } + { swap$ 'skip$ + { + swap$ + " " * swap$ + } + if$ + * + } + if$ + duplicate$ empty$ + 'skip$ + { + before.all 'output.state := + ", " swap$ * + } + if$ +} +FUNCTION {format.btitle} +{ title "title" bibinfo.check + duplicate$ empty$ 'skip$ + { + emphasize + } + if$ +} +FUNCTION {either.or.check} +{ empty$ + 'pop$ + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} +FUNCTION {format.bvolume} +{ volume empty$ + { "" } + { bbl.volume volume tie.or.space.prefix + "volume" bibinfo.check * * + series "series" bibinfo.check + duplicate$ empty$ 'pop$ + { swap$ bbl.of space.word * swap$ + emphasize * } + if$ + "volume and number" number either.or.check + } + if$ +} +FUNCTION {format.number.series} +{ volume empty$ + { number empty$ + { series field.or.null } + { series empty$ + { number "number" bibinfo.check } + { output.state mid.sentence = + { bbl.number } + { bbl.number capitalize } + if$ + number tie.or.space.prefix "number" bibinfo.check * * + bbl.in space.word * + series "series" bibinfo.check * + } + if$ + } + if$ + } + { "" } + if$ +} +FUNCTION {is.num} +{ chr.to.int$ + duplicate$ "0" chr.to.int$ < not + swap$ "9" chr.to.int$ > not and +} + +FUNCTION {extract.num} +{ duplicate$ 't := + "" 's := + { t empty$ not } + { t #1 #1 substring$ + t #2 global.max$ substring$ 't := + duplicate$ is.num + { s swap$ * 's := } + { pop$ "" 't := } + if$ + } + while$ + s empty$ + 'skip$ + { pop$ s } + if$ +} + +FUNCTION {convert.edition} +{ extract.num "l" change.case$ 's := + s "first" = s "1" = or + { bbl.first 't := } + { s "second" = s "2" = or + { bbl.second 't := } + { s "third" = s "3" = or + { bbl.third 't := } + { s "fourth" = s "4" = or + { bbl.fourth 't := } + { s "fifth" = s "5" = or + { bbl.fifth 't := } + { s #1 #1 substring$ is.num + { s eng.ord 't := } + { edition 't := } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + } + if$ + t +} + +FUNCTION {format.edition} +{ edition duplicate$ empty$ 'skip$ + { + convert.edition + output.state mid.sentence = + { "l" } + { "t" } + if$ change.case$ + "edition" bibinfo.check + " " * bbl.edition * + } + if$ +} +INTEGERS { multiresult } +FUNCTION {multi.page.check} +{ 't := + #0 'multiresult := + { multiresult not + t empty$ not + and + } + { t #1 #1 substring$ + duplicate$ "-" = + swap$ duplicate$ "," = + swap$ "+" = + or or + { #1 'multiresult := } + { t #2 global.max$ substring$ 't := } + if$ + } + while$ + multiresult +} +FUNCTION {format.pages} +{ pages duplicate$ empty$ 'skip$ + { duplicate$ multi.page.check + { + bbl.pages swap$ + n.dashify + } + { + bbl.page swap$ + } + if$ + tie.or.space.prefix + "pages" bibinfo.check + * * + } + if$ +} +FUNCTION {format.journal.pages} +{ pages duplicate$ empty$ 'pop$ + { swap$ duplicate$ empty$ + { pop$ pop$ format.pages } + { + ", " * + swap$ + n.dashify + pages multi.page.check + 'bbl.pages + 'bbl.page + if$ + swap$ tie.or.space.prefix + "pages" bibinfo.check + * * + * + } + if$ + } + if$ +} +FUNCTION {format.vol.num.pages} +{ volume field.or.null + duplicate$ empty$ 'skip$ + { + "volume" bibinfo.check + } + if$ + number "number" bibinfo.check duplicate$ empty$ 'skip$ + { + swap$ duplicate$ empty$ + { "there's a number but no volume in " cite$ * warning$ } + 'skip$ + if$ + swap$ + "(" swap$ * ")" * + } + if$ * +} + +FUNCTION {format.chapter.pages} +{ chapter empty$ + { "" } + { type empty$ + { bbl.chapter } + { type "l" change.case$ + "type" bibinfo.check + } + if$ + chapter tie.or.space.prefix + "chapter" bibinfo.check + * * + } + if$ +} + +FUNCTION {format.booktitle} +{ + booktitle "booktitle" bibinfo.check + emphasize +} +FUNCTION {format.in.ed.booktitle} +{ format.booktitle duplicate$ empty$ 'skip$ + { + editor "editor" format.names.ed duplicate$ empty$ 'pop$ + { + bbl.edby + " " * swap$ * + swap$ + "," * + " " * swap$ + * } + if$ + word.in swap$ * + } + if$ +} +FUNCTION {empty.misc.check} +{ author empty$ title empty$ howpublished empty$ + month empty$ year empty$ note empty$ + and and and and and + { "all relevant fields are empty in " cite$ * warning$ } + 'skip$ + if$ +} +FUNCTION {format.thesis.type} +{ type duplicate$ empty$ + 'pop$ + { swap$ pop$ + "t" change.case$ "type" bibinfo.check + } + if$ +} +FUNCTION {format.tr.number} +{ number "number" bibinfo.check + type duplicate$ empty$ + { pop$ bbl.techrep } + 'skip$ + if$ + "type" bibinfo.check + swap$ duplicate$ empty$ + { pop$ "t" change.case$ } + { tie.or.space.prefix * * } + if$ +} +FUNCTION {format.article.crossref} +{ + key duplicate$ empty$ + { pop$ + journal duplicate$ empty$ + { "need key or journal for " cite$ * " to crossref " * crossref * warning$ } + { "journal" bibinfo.check emphasize word.in swap$ * } + if$ + } + { word.in swap$ * " " *} + if$ + " \cite{" * crossref * "}" * +} +FUNCTION {format.crossref.editor} +{ editor #1 "{vv~}{ll}" format.name$ + "editor" bibinfo.check + editor num.names$ duplicate$ + #2 > + { pop$ + "editor" bibinfo.check + " " * bbl.etal + * + } + { #2 < + 'skip$ + { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { + "editor" bibinfo.check + " " * bbl.etal + * + } + { + bbl.and space.word + * editor #2 "{vv~}{ll}" format.name$ + "editor" bibinfo.check + * + } + if$ + } + if$ + } + if$ +} +FUNCTION {format.book.crossref} +{ volume duplicate$ empty$ + { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ + pop$ word.in + } + { bbl.volume + swap$ tie.or.space.prefix "volume" bibinfo.check * * bbl.of space.word * + } + if$ + editor empty$ + editor field.or.null author field.or.null = + or + { key empty$ + { series empty$ + { "need editor, key, or series for " cite$ * " to crossref " * + crossref * warning$ + "" * + } + { series emphasize * } + if$ + } + { key * } + if$ + } + { format.crossref.editor * } + if$ + " \cite{" * crossref * "}" * +} +FUNCTION {format.incoll.inproc.crossref} +{ + editor empty$ + editor field.or.null author field.or.null = + or + { key empty$ + { format.booktitle duplicate$ empty$ + { "need editor, key, or booktitle for " cite$ * " to crossref " * + crossref * warning$ + } + { word.in swap$ * } + if$ + } + { word.in key * " " *} + if$ + } + { word.in format.crossref.editor * " " *} + if$ + " \cite{" * crossref * "}" * +} +FUNCTION {format.org.or.pub} +{ 't := + "" + address empty$ t empty$ and + 'skip$ + { + t empty$ + { address "address" bibinfo.check * + } + { t * + address empty$ + 'skip$ + { ", " * address "address" bibinfo.check * } + if$ + } + if$ + } + if$ +} +FUNCTION {format.publisher.address} +{ publisher "publisher" bibinfo.warn format.org.or.pub +} + +FUNCTION {format.organization.address} +{ organization "organization" bibinfo.check format.org.or.pub +} + +FUNCTION {article} +{ output.bibitem + format.authors "author" output.check + format.title "title" output.check + end.quote.title + crossref missing$ + { + journal + remove.dots + "journal" bibinfo.check + emphasize + "journal" output.check + format.vol.num.pages output + format.date "year" output.check + } + { format.article.crossref output.nonnull + } + if$ + format.journal.pages + format.url output + format.note output + fin.entry +} +FUNCTION {book} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check + } + { format.authors output.nonnull + crossref missing$ + { "author and editor" editor either.or.check } + 'skip$ + if$ + } + if$ + format.btitle "title" output.check + crossref missing$ + { format.bvolume output + format.number.series output + format.publisher.address output + } + { + format.book.crossref output.nonnull + } + if$ + format.edition output + format.date "year" output.check + format.url output + format.note output + fin.entry +} +FUNCTION {booklet} +{ output.bibitem + format.authors output + format.title "title" output.check + end.quote.title + howpublished "howpublished" bibinfo.check output + address "address" bibinfo.check output + format.date output + format.url output + format.note output + fin.entry +} + +FUNCTION {inbook} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check + } + { format.authors output.nonnull + crossref missing$ + { "author and editor" editor either.or.check } + 'skip$ + if$ + } + if$ + format.btitle "title" output.check + crossref missing$ + { + format.publisher.address output + format.bvolume output + format.chapter.pages "chapter and pages" output.check + format.number.series output + } + { + format.chapter.pages "chapter and pages" output.check + format.book.crossref output.nonnull + } + if$ + format.edition output + format.date "year" output.check + format.pages "pages" output.check + format.url output + format.note output + fin.entry +} + +FUNCTION {incollection} +{ output.bibitem + format.authors "author" output.check + format.title "title" output.check + end.quote.title + crossref missing$ + { format.in.ed.booktitle "booktitle" output.check + format.publisher.address output + format.bvolume output + format.number.series output + format.chapter.pages output + format.edition output + format.date "year" output.check + } + { format.incoll.inproc.crossref output.nonnull + format.chapter.pages output + } + if$ + format.pages "pages" output.check + format.url output + format.note output + fin.entry +} +FUNCTION {inproceedings} +{ output.bibitem + format.authors "author" output.check + format.title "title" output.check + end.quote.title + crossref missing$ + { format.in.ed.booktitle "booktitle" output.check + publisher empty$ + { format.organization.address output } + { organization "organization" bibinfo.check output + format.publisher.address output + } + if$ + format.date "year" output.check + format.bvolume output + format.number.series output + } + { format.incoll.inproc.crossref output.nonnull + } + if$ + format.pages "pages" output.check + format.url output + format.note output + fin.entry +} +FUNCTION {conference} { inproceedings } +FUNCTION {manual} +{ output.bibitem + author empty$ + { organization "organization" bibinfo.check + duplicate$ empty$ 'pop$ + { output + address "address" bibinfo.check output + } + if$ + } + { format.authors output.nonnull } + if$ + format.btitle "title" output.check + author empty$ + { organization empty$ + { + address "address" bibinfo.check output + } + 'skip$ + if$ + } + { + organization "organization" bibinfo.check output + address "address" bibinfo.check output + } + if$ + format.edition output + format.date output + format.url output + format.note output + fin.entry +} + +FUNCTION {mastersthesis} +{ output.bibitem + format.authors "author" output.check + format.btitle + "title" output.check + bbl.mthesis format.thesis.type output.nonnull + school "school" bibinfo.warn output + address "address" bibinfo.check output + format.date "year" output.check + format.url output + format.note output + fin.entry +} + +FUNCTION {misc} +{ output.bibitem + format.authors output + format.title output + end.quote.title + howpublished "howpublished" bibinfo.check output + format.date output + format.url output + format.note output + fin.entry + empty.misc.check +} +FUNCTION {phdthesis} +{ output.bibitem + format.authors "author" output.check + format.btitle + "title" output.check + bbl.phdthesis format.thesis.type output.nonnull + school "school" bibinfo.warn output + address "address" bibinfo.check output + format.date "year" output.check + format.url output + format.note output + fin.entry +} + +FUNCTION {proceedings} +{ output.bibitem + editor empty$ + { organization "organization" bibinfo.check output + } + { format.editors output.nonnull } + if$ + format.btitle "title" output.check + format.bvolume output + format.number.series output + editor empty$ + { publisher empty$ + 'skip$ + { + format.publisher.address output + } + if$ + } + { publisher empty$ + { + format.organization.address output } + { + organization "organization" bibinfo.check output + format.publisher.address output + } + if$ + } + if$ + format.date "year" output.check + format.url output + format.note output + fin.entry +} + +FUNCTION {techreport} +{ output.bibitem + format.authors "author" output.check + format.btitle + "title" output.check + format.tr.number output.nonnull + institution "institution" bibinfo.warn output + address "address" bibinfo.check output + format.date "year" output.check + format.url output + format.note output + fin.entry +} + +FUNCTION {unpublished} +{ output.bibitem + format.authors "author" output.check + format.title "title" output.check + end.quote.title + format.date output + format.url output + format.note "note" output.check + fin.entry +} + +FUNCTION {default.type} { misc } +READ +STRINGS { longest.label } +INTEGERS { number.label longest.label.width } +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #1 'number.label := + #0 'longest.label.width := +} +FUNCTION {longest.label.pass} +{ number.label int.to.str$ 'label := + number.label #1 + 'number.label := + label width$ longest.label.width > + { label 'longest.label := + label width$ 'longest.label.width := + } + 'skip$ + if$ +} +EXECUTE {initialize.longest.label} +ITERATE {longest.label.pass} +FUNCTION {begin.bib} +{ preamble$ empty$ + 'skip$ + { preamble$ write$ newline$ } + if$ + "\begin{thebibliography}{" longest.label * "}" * + write$ newline$ + "\newcommand{\enquote}[1]{``#1''}" + write$ newline$ + "\expandafter\ifx\csname url\endcsname\relax" + write$ newline$ + " \def\url#1{\texttt{#1}}\fi" + write$ newline$ + "\expandafter\ifx\csname urlprefix\endcsname\relax\def\urlprefix{URL }\fi" + write$ newline$ +} +EXECUTE {begin.bib} +EXECUTE {init.state.consts} +ITERATE {call.type$} +FUNCTION {end.bib} +{ newline$ + "\end{thebibliography}" write$ newline$ +} +EXECUTE {end.bib} +%% End of customized bst file +%% +%% End of file `tufte.bst'. diff --git a/_quarto.yml b/_quarto.yml new file mode 100644 index 0000000..f7e88b7 --- /dev/null +++ b/_quarto.yml @@ -0,0 +1,29 @@ +project: + type: tufte + preview: + port: 7777 +book: + open-graph: true + favicon: favicon.ico + twitter-card: true + site-url: https://derecksprojects.com/ + repo-url: https://github.com/derecksprojects/derecksprojects.com/ + repo-actions: [issue] + title: | + Dereck's Projects\ + Consulting + subtitle: Software | Bioinformatics | Data Science + title-short: Software and data consulting # used in the pdf head + output-file: derecksprojects.com + author: Dereck Mezquita MSc + publisher: Dereck Mezquita + date-format: YYYY-MM-DD + license: "CC BY" + chapters: + - index.qmd + - pages/consulting.qmd + - part: about.qmd + chapters: + - pages/references.qmd + - pages/acknowledgements.qmd +bibliography: references.bib diff --git a/about.qmd b/about.qmd new file mode 100644 index 0000000..1774ad3 --- /dev/null +++ b/about.qmd @@ -0,0 +1,30 @@ +# About {.unnumbered .unlisted} + +I am a bioinformatician and software engineer with expertise in creating data infrastructures, developing scientific software, and applying advanced computational methods to complex biological problems. I began programming at 15 and have since developed a strong foundation in life sciences and computational methods, this has culminated in a rewarding academic and professional career. + +I love to learn and work on personal projects. I am a polyglot; native in English 🇬🇧, French 🇫🇷, and Spanish 🇪🇸 I am also fluent in Italian 🇮🇹 and I speak Russian 🇷🇺. My personal interests range from combat sports to high-performance robotics and hardware. + +## Education + +My academic background provides a strong foundation in both life sciences and computational methods: + +1. MSc Systems & Synthetic Biology; Bioinformatics + - Université de Paris-Saclay, France (2019 - 2020) + - Degree obtained + - University ranking: 1st in France, 14th world-wide + +2. MSc Molecular Microbiology & Biotech + - Université de Toulouse III, France (2018 - 2019) + - Continuing education + - University ranking: 10-13th in France, 201-300th world-wide + +3. Medicinal & Pharmaceutical Chemistry + - Université d'Angers, France (2014 - 2018) + - Continuing education + +4. BSc Cellular/Molecular Biology & Physiology + - Université d'Angers, France (2014 - 2017) + - Degree obtained + - University ranking: 33-35th in France, 901-1000th world-wide + +This diverse educational background, combined with years of practical programming experience, enables me to work effectively at the intersection of life sciences and advanced computing. diff --git a/derecksprojects.com.Rproj b/derecksprojects.com.Rproj new file mode 100644 index 0000000..35ccc75 --- /dev/null +++ b/derecksprojects.com.Rproj @@ -0,0 +1,16 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 4 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX + +AutoAppendNewline: Yes + StripTrailingWhitespace: Yes \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..270b5be --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +services: + linode_derecksprojects_client: + image: ${IMAGE_NAME_CLIENT} + container_name: ${CONTAINER_NAME_CLIENT} + build: + context: ./ + dockerfile: Dockerfile + ports: + - '${PORT_MAP_CLIENT}:80' + networks: + - dereck-network + restart: unless-stopped + volumes: + - /var/www/derecksprojects.com/images:/app/output/images + +networks: + dereck-network: + external: true \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..942794c Binary files /dev/null and b/favicon.ico differ diff --git a/images/logo/256-20240628_beige-tufte_derecksprojects-logo.png b/images/logo/256-20240628_beige-tufte_derecksprojects-logo.png new file mode 100644 index 0000000..e63810f Binary files /dev/null and b/images/logo/256-20240628_beige-tufte_derecksprojects-logo.png differ diff --git a/images/logo/32-20240628_beige-tufte_derecksprojects-logo.png b/images/logo/32-20240628_beige-tufte_derecksprojects-logo.png new file mode 100644 index 0000000..942794c Binary files /dev/null and b/images/logo/32-20240628_beige-tufte_derecksprojects-logo.png differ diff --git a/images/logo/512-20240628_beige-tufte_derecksprojects-logo.png b/images/logo/512-20240628_beige-tufte_derecksprojects-logo.png new file mode 100644 index 0000000..dca1e9c Binary files /dev/null and b/images/logo/512-20240628_beige-tufte_derecksprojects-logo.png differ diff --git a/images/logo/svg-20240628_beige-tufte_derecksprojects-logo.svg b/images/logo/svg-20240628_beige-tufte_derecksprojects-logo.svg new file mode 100644 index 0000000..8be5bb4 --- /dev/null +++ b/images/logo/svg-20240628_beige-tufte_derecksprojects-logo.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/images/portfolio/derecksnotes.png b/images/portfolio/derecksnotes.png new file mode 100644 index 0000000..9d51318 Binary files /dev/null and b/images/portfolio/derecksnotes.png differ diff --git a/images/portfolio/jpm-11-00785-with-cover.png b/images/portfolio/jpm-11-00785-with-cover.png new file mode 100644 index 0000000..4ce56d4 Binary files /dev/null and b/images/portfolio/jpm-11-00785-with-cover.png differ diff --git a/images/portfolio/jpm-11-00785.png b/images/portfolio/jpm-11-00785.png new file mode 100644 index 0000000..871e5f6 Binary files /dev/null and b/images/portfolio/jpm-11-00785.png differ diff --git a/index.qmd b/index.qmd new file mode 100644 index 0000000..7b6bd66 --- /dev/null +++ b/index.qmd @@ -0,0 +1,82 @@ +```{=html} +
+ Dereck's Projects Consulting +
+``` + +# Preface + +I began programming at age 15 and have since developed professional expertise in software and data engineering. My formal education includes an MSc of Bioinformatics in Systems & Synthetic Biology. This combination of long-term programming experience and scientific training enables effective work at the intersection of life sciences and advanced computing. + +As an American raised in France, I possess native fluency in English, French, and Spanish, with additional fluency in Italian and Russian. This linguistic capability facilitates work in international scientific contexts. My professional focus includes high-performance computing, data infrastructure development, and scientific software creation. I specialize in transforming complex scientific and financial problems into data-driven solutions. + +[Consulting/Contract work](/pages/consulting.qmd) + +## Showcase + +### [Dereck's Notes](https://www.derecksnotes.com){target="_blank"} + +Dereck's Notes[^1] began in 2017 as a personal project, an attempt to integrate and condense everything I had learned in university. I have always been a prolific note taker, and I wanted to create a platform to share my knowledge with others. The project has since evolved into a knowledge distribution platform, scientific dictionary, scientific journal, and blog. + +::: {.content-visible when-format="html"} +[![derecksnotes.com](/images/portfolio/derecksnotes.png){.column-margin #fig-cover}](https://www.derecksnotes.com){target="_blank"} +::: + +Early versions were in PHP, version 4.0 of the project demonstrates a dern technical stack to integrate advanced features and improve maintainability. I strongly focused one a polished frontend and backend, as well as strong DevOps + CI/CD. + +Key technical aspects: + +- Frontend: Next.js 14 (app dir), React, TypeScript, MDX +- Backend: Express, Mongoose, Redis +- Infrastructure: Nginx, Linode, MongoDB, Redis +- CI/CD: GitHub Actions, Docker + +Notable features: + +- User account functionality +- Interactive commenting system +- Blog post filtering +- Dictionary search functionality + +[^1]: [Dereck's Notes GitHub Repo](https://github.com/derecksprojects/derecksnotes.com){target="_blank"} + +### [dmplot](https://github.com/dereckmezquita/dmplot) + +My interest in algorithmic trading and financial data analysis originated during my Master's degree. This academic pursuit led to a personal project: developing an algorithmic trading bot. From this, the `dmplot`[^2] [^3] package emerged as a comprehensive R framework for financial and time series data analysis. + +The `dmplot` package addresses the need for efficient processing and analysis of large financial datasets. It achieves this by combining high-performance C++ implementations with `ggplot2` for data visualisation. Key features include: + +- High-performance C++ implementations of financial indicators (e.g., Bollinger Bands, EMA, MACD) +- Custom `ggplot2` stats for financial data visualisation (e.g., candlesticks, Bollinger Bands) +- Monte Carlo simulation implemented in high-performance C++ + +Developing `dmplot` significantly enhanced my skills in financial data analysis and visualisation, R package development, and C++ integration. + +[^2]: [dmplot GitHub Repo](https://github.com/derecksprojects/dmplot){target="_blank"} +[^3]: [dmplot documentation](https://dereckmezquita.github.io/dmplot){target="_blank"} + +## Research and Publications + +My scientific research focuses on applying bioinformatics, statistics, and high-performance computing to address complex scientific problems. Key areas of study include rheumatoid arthritis, breast cancer, and broader investigations in genomics, metabolomics, and proteomics. + +::: {.content-visible when-format="html"} +![Inference of an integrative, executable network for rheumatoid arthritis combining data-driven machine learning approaches and a state-of-the-art mechanistic disease map](/images/portfolio/jpm-11-00785-with-cover.png){.column-margin #fig-cover} +::: + +*Notable publication:* + +- [Metabolomic Rewiring Promotes Endocrine Therapy Resistance in Breast Cancer](https://aacrjournals.org/cancerres/article-abstract/84/2/291/733113/Metabolomic-Rewiring-Promotes-Endocrine-Therapy){target="_blank"} (Cancer Research, 2024) +- [Inference of an integrative, executable network for rheumatoid arthritis combining data-driven machine learning approaches and a state-of-the-art mechanistic disease map](https://www.mdpi.com/2075-4426/11/8/785){target="_blank"} (Journal of Personalized Medicine, 2021) + +These publications exemplify my approach to leveraging computational methods for advancing understanding in life sciences. For a comprehensive list of my research contributions, please refer to my [Google Scholar profile](https://scholar.google.com/citations?user=3mWWedgAAAAJ&hl=en){target="_blank"}. + +## Find me + +[Consulting/Contract work](/pages/consulting.qmd) + +- GitHub: + - [github.com/dereckmezquita](https://github.com/dereckmezquita){target="_blank"} + - [github.com/derecksprojects](https://github.com/derecksprojects){target="_blank"} +- [YouTube](https://youtube.com/@derecksyoutube){target="_blank"} +- [derecksnotes.com](https://derecksnotes.com){target="_blank"} +- [Google Scholar](https://scholar.google.com/citations?user=3mWWedgAAAAJ&hl=en){target="_blank"} diff --git a/pages/acknowledgements.qmd b/pages/acknowledgements.qmd new file mode 100644 index 0000000..b2a028d --- /dev/null +++ b/pages/acknowledgements.qmd @@ -0,0 +1,3 @@ +# Acknowledgements {.unlisted .unnumbered} + +Many thanks to my parents for having supported me throughout my studies, for having instilled a sense of curiosity and grandiosity. diff --git a/pages/consulting.qmd b/pages/consulting.qmd new file mode 100644 index 0000000..686bbe1 --- /dev/null +++ b/pages/consulting.qmd @@ -0,0 +1,61 @@ +--- +title: Consulting +--- + +:::{.panel-tabset} + +## Single Consultation + + + + + +## Ongoing Projects + + + + + +::: + +I offer specialised services in software engineering, bioinformatics, and data science. My interdisciplinary background enables me to tackle complex projects across various domains. + +## Key Services + +1. **Software Engineering** + - Full-stack web development (React, Next.js, Express) + - High-performance computing solutions + - R, Python, TypeScript/JavaScript development and optimization + - Scientific software development and code review + +2. **Data Engineering and Analytics** + - Data processing pipeline design and implementation + - Statistical analysis and complex data modeling + - Data visualization and dashboard development + +3. **Bioinformatics and Computational Biology** + - Genomic data analysis and variant calling + - Single-cell RNA sequencing analysis + - Custom bioinformatics pipeline development + - Machine learning integration with biological data + +4. **Financial Technology** + - Algorithmic trading strategy development + - Quantitative model implementation + +5. **Technical Writing and Consulting** + - Scientific publication preparation + - Technical documentation development + - Code review and best practices consultation + +## Technical Expertise + +- Languages: R, Python, TypeScript, C++ +- Web: React, Next.js, Express +- Databases: MongoDB, SQL +- DevOps: Docker, CI/CD, AWS (EC2, S3, Lambda) +- Analysis: Statistical methods, Machine learning + +If you have an interesting project that aligns with these areas, I'm eager to contribute my expertise. My multilingual capabilities facilitate collaboration in international contexts. diff --git a/pages/references.qmd b/pages/references.qmd new file mode 100644 index 0000000..44ddddf --- /dev/null +++ b/pages/references.qmd @@ -0,0 +1,4 @@ +# References {.unnumbered .unlisted} + +::: {#refs} +::: \ No newline at end of file diff --git a/references.bib b/references.bib new file mode 100644 index 0000000..f1477ba --- /dev/null +++ b/references.bib @@ -0,0 +1,36 @@ +@book{Tufte:vdqi, + abstract = {The classic book on statistical graphics, charts, tables. Theory and practice in the design of data graphics, 250 illustrations of the best (and a few of the worst) statistical graphics, with detailed analysis of how to display data for precise, effective, quick analysis. Design of the high-resolution displays, small multiples. Editing and improving graphics. The data-ink ratio. Time-series, relational graphics, data maps, multivariate designs. Detection of graphical deception: design variation vs. data variation. Sources of deception. Aesthetics and data graphical displays. This new edition provides excellent color reproductions of the many graphics of William Playfair, adds color to other images, and includes all the changes and corrections accumulated during 17 printings of the first edition.}, + added-at = {2017-06-17T22:10:30.000+0200}, + address = {Cheshire, CT}, + author = {Tufte, Edward R.}, + biburl = {https://www.bibsonomy.org/bibtex/29c028ebcb336380cb02e2a4beaa14d54/flint63}, + description = {Edition 1 1992 ISBN 978-0-9613921-0-9}, + edition = {2nd ed.}, + file = {Graphics Press Product page:http\://www.edwardtufte.com/tufte/books_vdqi:URL;Amazon Search inside:http\://www.amazon.de/gp/reader/0961392142/:URL}, + groups = {public}, + interhash = {9900880e451150c1b06ede3c780c062b}, + intrahash = {9c028ebcb336380cb02e2a4beaa14d54}, + isbn = {978-0-9613921-4-7}, + keywords = {01624 101 book shelf information graphics design cognitive science}, + publisher = {Graphics Press}, + timestamp = {2017-07-13T17:06:47.000+0200}, + title = {The Visual Display of Quantitative Information}, + username = {flint63}, + year = 2001 +} + +@book{Tufte:ve, + title={Visual explanations: Images and quantities, evidence and narrative}, + author={Tufte, Edward R and McKay, Susan R and Christian, Wolfgang and Matey, James R}, + year={1998}, + publisher={American Institute of Physics} +} + +@book{Tufte:en, + title={Envisioning information}, + author={Tufte, Edward R and Goeler, Nora Hillman and Benson, Richard}, + volume={126}, + year={1990}, + publisher={Graphics press Cheshire, CT} +} + diff --git a/tufte-book.cls b/tufte-book.cls new file mode 100644 index 0000000..f733ce2 --- /dev/null +++ b/tufte-book.cls @@ -0,0 +1,88 @@ +\NeedsTeXFormat{LaTeX2e}[1994/06/01] + +\ProvidesClass{tufte-book}[2015/06/30 v3.5.3 Tufte-book class] + +%% +% Declare we're tufte-book +\newcommand{\@tufte@class}{book}% the base LaTeX class (defaults to the book style) +\newcommand{\@tufte@pkgname}{tufte-book}% the name of the package (defaults to tufte-handout) + +%% +% Load the common style elements +\input{tufte-common.def} + + +%% +% Set up any book-specific stuff now + +%% +% The front matter in Tufte's /Beautiful Evidence/ contains everything up +% to the opening page of Chapter 1. The running heads, when they appear, +% contain only the (arabic) page number in the outside corner. +%\newif\if@mainmatter \@mainmattertrue +\renewcommand\frontmatter{% + \if@openright% + \cleardoublepage% + \else% + \clearpage% + \fi% + \@mainmatterfalse% + \pagenumbering{arabic}% + %\pagestyle{plain}% + \fancyhf{}% + \ifthenelse{\boolean{@tufte@twoside}}% + {\fancyhead[LE,RO]{\thepage}}% + {\fancyhead[RE,RO]{\thepage}}% +} + + +%% +% The main matter in Tufte's /Beautiful Evidence/ doesn't restart the page +% numbering---it continues where it left off in the front matter. +\renewcommand\mainmatter{% + \if@openright% + \cleardoublepage% + \else% + \clearpage% + \fi% + \@mainmattertrue% + \fancyhf{}% + \ifthenelse{\boolean{@tufte@twoside}}% + {% two-side + \renewcommand{\chaptermark}[1]{\markboth{##1}{}}% + \fancyhead[LE]{\thepage\quad\smallcaps{\newlinetospace{\plaintitle}}}% book title + \fancyhead[RO]{\smallcaps{\newlinetospace{\leftmark}}\quad\thepage}% chapter title + }% + {% one-side + \fancyhead[RE,RO]{\smallcaps{\newlinetospace{\plaintitle}}\quad\thepage}% book title + }% +} + + +%% +% The back matter contains appendices, indices, glossaries, endnotes, +% bibliographies, list of contributors, illustration credits, etc. +\renewcommand\backmatter{% + \if@openright% + \cleardoublepage% + \else% + \clearpage% + \fi% + \@mainmatterfalse% +} + +%% +% Only show the chapter titles in the table of contents +\setcounter{tocdepth}{0} + +%% +% If there is a `tufte-book-local.sty' file, load it. + +\IfFileExists{tufte-book-local.tex}{% + \@tufte@info@noline{Loading tufte-book-local.tex}% + \input{tufte-book-local}% +}{} + +%% +% End of file +\endinput