From 7cda3a1cc32bd43dab837e2b73046dab2aeaec98 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Thu, 31 Aug 2023 03:01:22 +0000 Subject: CTAN sync 202308310301 --- FILES.byname | 338 +- FILES.byname.gz | Bin 2544072 -> 2544973 bytes FILES.last07days | 316 +- biblio/bibtex/bibtex-x/ChangeLog | 5 + biblio/bibtex/bibtex-x/tests/bibtex8u-mem.test | 4 +- biblio/bibtex/bibtex-x/tests/bibtexu-char.test | 4 +- biblio/ctan-bibdata/ctan.bib | 35 +- biblio/ctan-bibdata/ctan.pdf | Bin 3701894 -> 3700823 bytes fonts/metsymb/AUTHORS | 1 + fonts/metsymb/CHANGELOG | 27 + fonts/metsymb/CODE_OF_CONDUCT.md | 76 + fonts/metsymb/CONTRIBUTING.md | 182 + fonts/metsymb/LICENSE | 11 + fonts/metsymb/README.md | 104 + fonts/metsymb/source/metsymb.afm | 66 + fonts/metsymb/source/metsymb.dtx | 532 +++ fonts/metsymb/source/metsymb.enc | 258 ++ fonts/metsymb/source/metsymb.ins | 43 + fonts/metsymb/source/metsymb.map | 1 + fonts/metsymb/source/metsymb.otf | Bin 0 -> 14904 bytes fonts/metsymb/source/metsymb.pdf | Bin 0 -> 332267 bytes fonts/metsymb/source/metsymb.pfb | Bin 0 -> 8625 bytes fonts/metsymb/source/metsymb.sfd | 1379 ++++++++ fonts/metsymb/source/metsymb.tfm | Bin 0 -> 420 bytes fonts/metsymb/source/metsymb_mwe.mplstyle | 2 + fonts/metsymb/source/metsymb_mwe.pdf | Bin 0 -> 32716 bytes fonts/metsymb/source/metsymb_mwe.py | 35 + fonts/metsymb/source/testfont.pdf | Bin 0 -> 49177 bytes fonts/metsymb/source/umetsymb.fd | 3 + fonts/parsianfonts/Parsian/Parsian-Bold.ttf | Bin 267260 -> 264888 bytes fonts/parsianfonts/Parsian/Parsian-BoldItalic.ttf | Bin 284460 -> 282088 bytes fonts/parsianfonts/Parsian/Parsian-Italic.ttf | Bin 281980 -> 279608 bytes fonts/parsianfonts/Parsian/Parsian-Regular.ttf | Bin 272060 -> 269688 bytes .../parsianfonts/ParsianMono/ParsianMono-Bold.ttf | Bin 289640 -> 287268 bytes .../ParsianMono/ParsianMono-BoldItalic.ttf | Bin 326232 -> 323860 bytes .../ParsianMono/ParsianMono-Italic.ttf | Bin 328704 -> 326332 bytes .../ParsianMono/ParsianMono-Regular.ttf | Bin 268772 -> 266400 bytes .../ParsianNaskh/ParsianNaskh-Bold.ttf | Bin 275400 -> 273028 bytes .../ParsianNaskh/ParsianNaskh-BoldItalic.ttf | Bin 293892 -> 291520 bytes .../ParsianNaskh/ParsianNaskh-Italic.ttf | Bin 291176 -> 288804 bytes .../ParsianNaskh/ParsianNaskh-Regular.ttf | Bin 279208 -> 276836 bytes .../parsianfonts/ParsianSans/ParsianSans-Bold.ttf | Bin 201568 -> 199196 bytes .../ParsianSans/ParsianSans-BoldItalic.ttf | Bin 214604 -> 212232 bytes .../ParsianSans/ParsianSans-Italic.ttf | Bin 211508 -> 209136 bytes .../ParsianSans/ParsianSans-Regular.ttf | Bin 197880 -> 195508 bytes fonts/parsianfonts/ParsianTeX/ParsianTeX-Bold.ttf | Bin 176944 -> 174528 bytes .../ParsianTeX/ParsianTeX-BoldItalic.ttf | Bin 227712 -> 225296 bytes .../parsianfonts/ParsianTeX/ParsianTeX-Italic.ttf | Bin 220560 -> 218144 bytes .../parsianfonts/ParsianTeX/ParsianTeX-Regular.ttf | Bin 181032 -> 178616 bytes .../ParsianTeXClassic/ParsianTeXClassic-Bold.ttf | Bin 201200 -> 198784 bytes .../ParsianTeXClassic-BoldItalic.ttf | Bin 253524 -> 251108 bytes .../ParsianTeXClassic/ParsianTeXClassic-Italic.ttf | Bin 234484 -> 232068 bytes .../ParsianTeXClassic-Regular.ttf | Bin 200500 -> 198084 bytes .../ParsianTitle/ParsianTitle-Italic.ttf | Bin 294088 -> 291716 bytes .../ParsianTitle/ParsianTitle-Regular.ttf | Bin 278080 -> 275708 bytes fonts/parsianfonts/README.md | 60 +- fonts/parsianfonts/parsianfonts-samples.pdf | Bin 347174 -> 347762 bytes fonts/parsianfonts/parsianfonts-samples.tex | 74 +- graphics/pgf/contrib/hobby/README | 14 + graphics/pgf/contrib/hobby/README.txt | 14 - graphics/pgf/contrib/hobby/hobby.dtx | 3500 ------------------- graphics/pgf/contrib/hobby/hobby.pdf | Bin 523036 -> 506560 bytes graphics/pgf/contrib/hobby/hobby.tex | 919 +++++ graphics/pgf/contrib/hobby/hobby_code.dtx | 3614 ++++++++++++++++++++ graphics/pgf/contrib/hobby/hobby_code.pdf | Bin 444339 -> 514512 bytes graphics/pgf/contrib/hobby/hobby_doc.tex | 917 ----- macros/latex/contrib/jwjournal/README.md | 10 +- .../latex/contrib/jwjournal/jwjournal-demo-cn.tex | 8 +- .../latex/contrib/jwjournal/jwjournal-demo-en.tex | 8 +- .../latex/contrib/jwjournal/jwjournal-demo-fr.tex | 8 +- macros/latex/contrib/jwjournal/jwjournal.cls | 119 +- macros/latex/contrib/mathastext/README.md | 12 +- macros/latex/contrib/mathastext/mathastext.dtx | 318 +- macros/latex/contrib/mathastext/mathastext.pdf | Bin 578580 -> 574466 bytes macros/latex/contrib/mitthesis/MIT-Thesis.pdf | Bin 489188 -> 490683 bytes .../mitthesis/MIT-thesis-template/MIT-Thesis.tex | 127 +- .../mitthesis/MIT-thesis-template/chapter1.tex | 4 +- macros/latex/contrib/mitthesis/README.md | 16 +- .../latex_sources/No_cc_license.tex | 75 +- .../latex_sources/One_author_one_degree.tex | 61 +- .../latex_sources/One_author_two_degrees.tex | 61 +- .../One_author_two_degrees_from_one_department.tex | 62 +- .../latex_sources/Two_authors_one_degree.tex | 61 +- .../latex_sources/Two_authors_two_degrees.tex | 63 +- .../examples/font_samples/Defaultfonts.pdf | Bin 490288 -> 490687 bytes .../examples/font_samples/Fira_Newtxsf.pdf | Bin 319041 -> 323017 bytes .../examples/font_samples/Heros-Stix2.pdf | Bin 151460 -> 151029 bytes .../mitthesis/examples/font_samples/Libertine.pdf | Bin 454847 -> 458937 bytes .../mitthesis/examples/font_samples/Lucida.pdf | Bin 169955 -> 169261 bytes .../examples/font_samples/Newtx-sans-text.pdf | Bin 270252 -> 274790 bytes .../mitthesis/examples/font_samples/Newtx.pdf | Bin 316127 -> 320067 bytes .../mitthesis/examples/font_samples/Stix2.pdf | Bin 159625 -> 159311 bytes .../examples/font_samples/Termes-Stix2.pdf | Bin 161691 -> 0 bytes .../examples/font_samples/Termes-stix2.pdf | Bin 0 -> 161163 bytes .../mitthesis/examples/font_samples/Termes.pdf | Bin 157894 -> 157329 bytes .../font_samples/latex_sources/Defaultfonts.tex | 151 +- .../font_samples/latex_sources/Fira_Newtxsf.tex | 151 +- .../font_samples/latex_sources/Heros-Stix2.tex | 137 +- .../font_samples/latex_sources/Libertine.tex | 137 +- .../examples/font_samples/latex_sources/Lucida.tex | 137 +- .../font_samples/latex_sources/Newtx-sans-text.tex | 137 +- .../examples/font_samples/latex_sources/Newtx.tex | 137 +- .../examples/font_samples/latex_sources/Stix2.tex | 139 +- .../font_samples/latex_sources/Termes-Stix2.tex | 287 -- .../font_samples/latex_sources/Termes-stix2.tex | 264 ++ .../examples/font_samples/latex_sources/Termes.tex | 138 +- .../mitthesis/fontsets/mitthesis-fira-newtxsf.tex | 8 +- .../mitthesis/mitthesis-doc/mitthesis-doc.pdf | Bin 81325 -> 82805 bytes .../mitthesis/mitthesis-doc/mitthesis-doc.tex | 26 +- macros/latex/contrib/mitthesis/mitthesis.cls | 1072 +++--- macros/xetex/latex/xepersian/README | 4 +- .../xetex/latex/xepersian/xepersian-doc-intro.ltx | 2 +- .../xetex/latex/xepersian/xepersian-doc-title.ltx | 4 +- macros/xetex/latex/xepersian/xepersian-doc.ltx | 2 +- macros/xetex/latex/xepersian/xepersian-doc.pdf | Bin 243977 -> 236376 bytes macros/xetex/latex/xepersian/xepersian.dtx | 142 +- macros/xetex/latex/xepersian/xepersian.pdf | Bin 784492 -> 777229 bytes .../texlive/tlnet/tlpkg/installer/ctan-mirrors.pl | 2 +- systems/texlive/tlnet/tlpkg/texlive.tlpdb | 110 +- systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 | 2 +- systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 | 2 +- .../texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc | 16 +- systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz | Bin 2467840 -> 2467656 bytes timestamp | 2 +- 124 files changed, 9805 insertions(+), 6951 deletions(-) create mode 100644 fonts/metsymb/AUTHORS create mode 100644 fonts/metsymb/CHANGELOG create mode 100644 fonts/metsymb/CODE_OF_CONDUCT.md create mode 100644 fonts/metsymb/CONTRIBUTING.md create mode 100644 fonts/metsymb/LICENSE create mode 100644 fonts/metsymb/README.md create mode 100644 fonts/metsymb/source/metsymb.afm create mode 100644 fonts/metsymb/source/metsymb.dtx create mode 100644 fonts/metsymb/source/metsymb.enc create mode 100644 fonts/metsymb/source/metsymb.ins create mode 100644 fonts/metsymb/source/metsymb.map create mode 100644 fonts/metsymb/source/metsymb.otf create mode 100644 fonts/metsymb/source/metsymb.pdf create mode 100644 fonts/metsymb/source/metsymb.pfb create mode 100644 fonts/metsymb/source/metsymb.sfd create mode 100644 fonts/metsymb/source/metsymb.tfm create mode 100644 fonts/metsymb/source/metsymb_mwe.mplstyle create mode 100644 fonts/metsymb/source/metsymb_mwe.pdf create mode 100755 fonts/metsymb/source/metsymb_mwe.py create mode 100644 fonts/metsymb/source/testfont.pdf create mode 100644 fonts/metsymb/source/umetsymb.fd create mode 100644 graphics/pgf/contrib/hobby/README delete mode 100644 graphics/pgf/contrib/hobby/README.txt delete mode 100644 graphics/pgf/contrib/hobby/hobby.dtx create mode 100644 graphics/pgf/contrib/hobby/hobby.tex create mode 100644 graphics/pgf/contrib/hobby/hobby_code.dtx delete mode 100644 graphics/pgf/contrib/hobby/hobby_doc.tex delete mode 100644 macros/latex/contrib/mitthesis/examples/font_samples/Termes-Stix2.pdf create mode 100644 macros/latex/contrib/mitthesis/examples/font_samples/Termes-stix2.pdf delete mode 100644 macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes-Stix2.tex create mode 100644 macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes-stix2.tex diff --git a/FILES.byname b/FILES.byname index 06ecc03c10..a8d53cd9ae 100644 --- a/FILES.byname +++ b/FILES.byname @@ -2056,12 +2056,12 @@ 2023/07/04 | 1675 | biblio/citation-style-language/README.md 2023/07/04 | 12878 | biblio/citation-style-language/vancouver.csl 2023/07/04 | 4522435 | biblio/citation-style-language.zip -2023/08/29 | 1678 | biblio/ctan-bibdata/biblatex-ctan/ctan.bbx +2023/08/30 | 1678 | biblio/ctan-bibdata/biblatex-ctan/ctan.bbx 2022/10/08 | 127 | biblio/ctan-bibdata/biblatex-ctan/ctan.cbx -2023/08/29 | 2806563 | biblio/ctan-bibdata/ctan.bib -2023/08/29 | 3701009 | biblio/ctan-bibdata/ctan.pdf +2023/08/30 | 2806562 | biblio/ctan-bibdata/ctan.bib +2023/08/30 | 3701894 | biblio/ctan-bibdata/ctan.pdf 2023/01/16 | 1489 | biblio/ctan-bibdata/README -2023/08/29 | 4102573 | biblio/ctan-bibdata.zip +2023/08/30 | 4102144 | biblio/ctan-bibdata.zip 2023/02/23 | 3126 | biblio/pbibtex/pbibtex-base/cpp.awk 2023/02/23 | 1009 | biblio/pbibtex/pbibtex-base/generate.sh 2023/02/23 | 22362 | biblio/pbibtex/pbibtex-base/jabbrv.bst @@ -5421,7 +5421,7 @@ 1990/10/02 | 5440 | dviware/vutex/vaxvms.hlp 1990/10/02 | 812 | dviware/vutex/vaxvms.ins 1990/10/02 | 127576 | dviware/vutex/vutex.web -2023/08/29 | 62867 | FILES.last07days +2023/08/30 | 63612 | FILES.last07days 2021/07/24 | 1139410 | fonts/aboensis/Aboensis.glyphs 2021/07/24 | 18907382 | fonts/aboensis/aboensis.pdf 2021/07/24 | 137860 | fonts/aboensis/Aboensis-Regular.otf @@ -76160,6 +76160,28 @@ 2020/08/30 | 1724 | fonts/merriweather/vf/MerriwthrSans-Regular-tosf-t1.vf 2020/08/30 | 588 | fonts/merriweather/vf/MerriwthrSans-Regular-tosf-ts1.vf 2022/09/20 | 9261964 | fonts/merriweather.zip +2023/08/30 | 66 | fonts/metsymb/AUTHORS +2023/08/30 | 938 | fonts/metsymb/CHANGELOG +2023/08/30 | 3359 | fonts/metsymb/CODE_OF_CONDUCT.md +2023/08/30 | 9208 | fonts/metsymb/CONTRIBUTING.md +2023/08/30 | 1494 | fonts/metsymb/LICENSE +2023/08/30 | 5101 | fonts/metsymb/README.md +2023/08/30 | 2650 | fonts/metsymb/source/metsymb.afm +2023/08/30 | 18969 | fonts/metsymb/source/metsymb.dtx +2023/08/30 | 2590 | fonts/metsymb/source/metsymb.enc +2023/08/30 | 1237 | fonts/metsymb/source/metsymb.ins +2023/08/30 | 28 | fonts/metsymb/source/metsymb.map +2023/08/30 | 60 | fonts/metsymb/source/metsymb_mwe.mplstyle +2023/08/30 | 32716 | fonts/metsymb/source/metsymb_mwe.pdf +2023/08/30 | 934 | fonts/metsymb/source/metsymb_mwe.py +2023/08/30 | 14904 | fonts/metsymb/source/metsymb.otf +2023/08/30 | 332267 | fonts/metsymb/source/metsymb.pdf +2023/08/30 | 8625 | fonts/metsymb/source/metsymb.pfb +2023/08/30 | 61129 | fonts/metsymb/source/metsymb.sfd +2023/08/30 | 420 | fonts/metsymb/source/metsymb.tfm +2023/08/30 | 49177 | fonts/metsymb/source/testfont.pdf +2023/08/30 | 110 | fonts/metsymb/source/umetsymb.fd +2023/08/30 | 455333 | fonts/metsymb.zip 1999/03/18 | 2126 | fonts/mflogo/Makefile 1999/03/18 | 402 | fonts/mflogo/mf/logosl8.mf 1999/08/25 | 992 | fonts/mflogo/ps-type1/hoekwater/afm/logo10.afm @@ -112123,36 +112145,36 @@ 2014/09/13 | 690388 | fonts/parisa/source/parisa-regular.sfd 2014/09/13 | 1618746 | fonts/parisa/source/parisa-shadow.sfd 2014/09/13 | 5749842 | fonts/parisa.zip -2023/08/29 | 347174 | fonts/parsianfonts/parsianfonts-samples.pdf -2023/08/29 | 4300 | fonts/parsianfonts/parsianfonts-samples.tex -2023/08/29 | 326232 | fonts/parsianfonts/ParsianMono/ParsianMono-BoldItalic.ttf -2023/08/29 | 289640 | fonts/parsianfonts/ParsianMono/ParsianMono-Bold.ttf -2023/08/29 | 328704 | fonts/parsianfonts/ParsianMono/ParsianMono-Italic.ttf -2023/08/29 | 268772 | fonts/parsianfonts/ParsianMono/ParsianMono-Regular.ttf -2023/08/29 | 293892 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-BoldItalic.ttf -2023/08/29 | 275400 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Bold.ttf -2023/08/29 | 291176 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Italic.ttf -2023/08/29 | 279208 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Regular.ttf -2023/08/29 | 284460 | fonts/parsianfonts/Parsian/Parsian-BoldItalic.ttf -2023/08/29 | 267260 | fonts/parsianfonts/Parsian/Parsian-Bold.ttf -2023/08/29 | 281980 | fonts/parsianfonts/Parsian/Parsian-Italic.ttf -2023/08/29 | 272060 | fonts/parsianfonts/Parsian/Parsian-Regular.ttf -2023/08/29 | 214604 | fonts/parsianfonts/ParsianSans/ParsianSans-BoldItalic.ttf -2023/08/29 | 201568 | fonts/parsianfonts/ParsianSans/ParsianSans-Bold.ttf -2023/08/29 | 211508 | fonts/parsianfonts/ParsianSans/ParsianSans-Italic.ttf -2023/08/29 | 197880 | fonts/parsianfonts/ParsianSans/ParsianSans-Regular.ttf -2023/08/29 | 253524 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-BoldItalic.ttf -2023/08/29 | 201200 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Bold.ttf -2023/08/29 | 234484 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Italic.ttf -2023/08/29 | 200500 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Regular.ttf -2023/08/29 | 227712 | fonts/parsianfonts/ParsianTeX/ParsianTeX-BoldItalic.ttf -2023/08/29 | 176944 | fonts/parsianfonts/ParsianTeX/ParsianTeX-Bold.ttf -2023/08/29 | 220560 | fonts/parsianfonts/ParsianTeX/ParsianTeX-Italic.ttf -2023/08/29 | 181032 | fonts/parsianfonts/ParsianTeX/ParsianTeX-Regular.ttf -2023/08/29 | 294088 | fonts/parsianfonts/ParsianTitle/ParsianTitle-Italic.ttf -2023/08/29 | 278080 | fonts/parsianfonts/ParsianTitle/ParsianTitle-Regular.ttf -2023/08/29 | 1759 | fonts/parsianfonts/README.md -2023/08/29 | 3099712 | fonts/parsianfonts.zip +2023/08/30 | 347762 | fonts/parsianfonts/parsianfonts-samples.pdf +2023/08/30 | 4485 | fonts/parsianfonts/parsianfonts-samples.tex +2023/08/30 | 323860 | fonts/parsianfonts/ParsianMono/ParsianMono-BoldItalic.ttf +2023/08/30 | 287268 | fonts/parsianfonts/ParsianMono/ParsianMono-Bold.ttf +2023/08/30 | 326332 | fonts/parsianfonts/ParsianMono/ParsianMono-Italic.ttf +2023/08/30 | 266400 | fonts/parsianfonts/ParsianMono/ParsianMono-Regular.ttf +2023/08/30 | 291520 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-BoldItalic.ttf +2023/08/30 | 273028 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Bold.ttf +2023/08/30 | 288804 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Italic.ttf +2023/08/30 | 276836 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Regular.ttf +2023/08/30 | 282088 | fonts/parsianfonts/Parsian/Parsian-BoldItalic.ttf +2023/08/30 | 264888 | fonts/parsianfonts/Parsian/Parsian-Bold.ttf +2023/08/30 | 279608 | fonts/parsianfonts/Parsian/Parsian-Italic.ttf +2023/08/30 | 269688 | fonts/parsianfonts/Parsian/Parsian-Regular.ttf +2023/08/30 | 212232 | fonts/parsianfonts/ParsianSans/ParsianSans-BoldItalic.ttf +2023/08/30 | 199196 | fonts/parsianfonts/ParsianSans/ParsianSans-Bold.ttf +2023/08/30 | 209136 | fonts/parsianfonts/ParsianSans/ParsianSans-Italic.ttf +2023/08/30 | 195508 | fonts/parsianfonts/ParsianSans/ParsianSans-Regular.ttf +2023/08/30 | 251108 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-BoldItalic.ttf +2023/08/30 | 198784 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Bold.ttf +2023/08/30 | 232068 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Italic.ttf +2023/08/30 | 198084 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Regular.ttf +2023/08/30 | 225296 | fonts/parsianfonts/ParsianTeX/ParsianTeX-BoldItalic.ttf +2023/08/30 | 174528 | fonts/parsianfonts/ParsianTeX/ParsianTeX-Bold.ttf +2023/08/30 | 218144 | fonts/parsianfonts/ParsianTeX/ParsianTeX-Italic.ttf +2023/08/30 | 178616 | fonts/parsianfonts/ParsianTeX/ParsianTeX-Regular.ttf +2023/08/30 | 291716 | fonts/parsianfonts/ParsianTitle/ParsianTitle-Italic.ttf +2023/08/30 | 275708 | fonts/parsianfonts/ParsianTitle/ParsianTitle-Regular.ttf +2023/08/30 | 3195 | fonts/parsianfonts/README.md +2023/08/30 | 3081151 | fonts/parsianfonts.zip 2011/01/07 | 740 | fonts/pcarl/pcarl.bib 2011/01/11 | 13268 | fonts/pcarl/pcarl.dtx 2011/01/07 | 1888 | fonts/pcarl/pcarl.ins @@ -160147,12 +160169,12 @@ 2014/07/25 | 124608 | graphics/pgf/contrib/hf-tikz/hf-tikz.pdf 2014/07/25 | 499 | graphics/pgf/contrib/hf-tikz/README 2014/07/26 | 133052 | graphics/pgf/contrib/hf-tikz.zip -2017/06/01 | 444339 | graphics/pgf/contrib/hobby/hobby_code.pdf -2015/09/12 | 42686 | graphics/pgf/contrib/hobby/hobby_doc.tex -2017/06/01 | 111178 | graphics/pgf/contrib/hobby/hobby.dtx -2017/06/01 | 523036 | graphics/pgf/contrib/hobby/hobby.pdf -2017/06/01 | 638 | graphics/pgf/contrib/hobby/README.txt -2017/06/01 | 990379 | graphics/pgf/contrib/hobby.zip +2023/08/30 | 114625 | graphics/pgf/contrib/hobby/hobby_code.dtx +2023/08/30 | 514512 | graphics/pgf/contrib/hobby/hobby_code.pdf +2023/08/30 | 506560 | graphics/pgf/contrib/hobby/hobby.pdf +2023/08/30 | 43450 | graphics/pgf/contrib/hobby/hobby.tex +2023/08/30 | 638 | graphics/pgf/contrib/hobby/README +2023/08/30 | 1038831 | graphics/pgf/contrib/hobby.zip 2022/03/22 | 808805 | graphics/pgf/contrib/istgame/istgame-doc.pdf 2022/03/22 | 31586 | graphics/pgf/contrib/istgame/istgame-doc.tex 2022/03/22 | 291467 | graphics/pgf/contrib/istgame/istgame-doc-v2.1.tex @@ -194682,7 +194704,7 @@ 2015/02/17 | 92757 | install/macros/xetex/latex/interchar.tds.zip 2021/08/19 | 464024 | install/macros/xetex/latex/mynsfc.tds.zip 2022/08/05 | 2009524 | install/macros/xetex/latex/xecjk.tds.zip -2023/08/26 | 1305051 | install/macros/xetex/latex/xepersian.tds.zip +2023/08/30 | 1288932 | install/macros/xetex/latex/xepersian.tds.zip 2008/06/20 | 3954 | install/macros/xetex/plain/xetexfontinfo.tds.zip 2013/01/04 | 36361 | install/support/adhocfilelist.tds.zip 2023/01/27 | 5226546 | install/support/albatross.tds.zip @@ -227250,17 +227272,17 @@ 2011/10/28 | 1485 | macros/latex/contrib/jvlisting/README 2011/11/17 | 8454 | macros/latex/contrib/jvlisting/test.tex 2011/11/18 | 202406 | macros/latex/contrib/jvlisting.zip -2023/08/29 | 12 | macros/latex/contrib/jwjournal/DEPENDS.txt -2023/08/29 | 10972 | macros/latex/contrib/jwjournal/jwjournal.cls -2023/08/29 | 70876 | macros/latex/contrib/jwjournal/jwjournal-demo-cn.pdf -2023/08/29 | 2525 | macros/latex/contrib/jwjournal/jwjournal-demo-cn.tex -2023/08/29 | 34389 | macros/latex/contrib/jwjournal/jwjournal-demo-en.pdf -2023/08/29 | 2599 | macros/latex/contrib/jwjournal/jwjournal-demo-en.tex -2023/08/29 | 35287 | macros/latex/contrib/jwjournal/jwjournal-demo-fr.pdf -2023/08/29 | 3024 | macros/latex/contrib/jwjournal/jwjournal-demo-fr.tex -2023/08/29 | 19106 | macros/latex/contrib/jwjournal/LICENSE -2023/08/29 | 8719 | macros/latex/contrib/jwjournal/README.md -2023/08/29 | 153693 | macros/latex/contrib/jwjournal.zip +2023/08/30 | 12 | macros/latex/contrib/jwjournal/DEPENDS.txt +2023/08/30 | 14210 | macros/latex/contrib/jwjournal/jwjournal.cls +2023/08/30 | 70876 | macros/latex/contrib/jwjournal/jwjournal-demo-cn.pdf +2023/08/30 | 2630 | macros/latex/contrib/jwjournal/jwjournal-demo-cn.tex +2023/08/30 | 34389 | macros/latex/contrib/jwjournal/jwjournal-demo-en.pdf +2023/08/30 | 2692 | macros/latex/contrib/jwjournal/jwjournal-demo-en.tex +2023/08/30 | 35287 | macros/latex/contrib/jwjournal/jwjournal-demo-fr.pdf +2023/08/30 | 3117 | macros/latex/contrib/jwjournal/jwjournal-demo-fr.tex +2023/08/30 | 19106 | macros/latex/contrib/jwjournal/LICENSE +2023/08/30 | 8893 | macros/latex/contrib/jwjournal/README.md +2023/08/30 | 154028 | macros/latex/contrib/jwjournal.zip 2018/09/21 | 71114 | macros/latex/contrib/kalendarium/kalendarium.dtx 2018/09/21 | 2343 | macros/latex/contrib/kalendarium/kalendarium.ins 2018/09/21 | 399783 | macros/latex/contrib/kalendarium/kalendarium.pdf @@ -229206,10 +229228,10 @@ 2019/05/20 | 84 | macros/latex/contrib/mathalpha/tex/mathalfa.sty 2021/11/18 | 57446 | macros/latex/contrib/mathalpha/tex/mathalpha.sty 2021/11/18 | 1892013 | macros/latex/contrib/mathalpha.zip -2022/11/04 | 430631 | macros/latex/contrib/mathastext/mathastext.dtx -2022/11/04 | 578580 | macros/latex/contrib/mathastext/mathastext.pdf -2022/11/04 | 5300 | macros/latex/contrib/mathastext/README.md -2022/11/04 | 694246 | macros/latex/contrib/mathastext.zip +2023/08/30 | 431339 | macros/latex/contrib/mathastext/mathastext.dtx +2023/08/30 | 574466 | macros/latex/contrib/mathastext/mathastext.pdf +2023/08/30 | 5461 | macros/latex/contrib/mathastext/README.md +2023/08/30 | 690418 | macros/latex/contrib/mathastext.zip 2021/06/07 | 1509 | macros/latex/contrib/mathcommand/makefile 2021/06/07 | 52877 | macros/latex/contrib/mathcommand/mathcommand.dtx 2021/06/07 | 2223 | macros/latex/contrib/mathcommand/mathcommand.ins @@ -229947,41 +229969,41 @@ 2019/01/09 | 1839 | macros/latex/contrib/mi-solns/mi-solns.ins 2019/01/09 | 365 | macros/latex/contrib/mi-solns/README.md 2019/01/09 | 471865 | macros/latex/contrib/mi-solns.zip -2023/07/21 | 6801 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/No_cc_license.tex -2023/07/21 | 6800 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_one_degree.tex -2023/07/21 | 6783 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees_from_one_department.tex -2023/07/21 | 6908 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees.tex -2023/07/21 | 6902 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_one_degree.tex -2023/07/21 | 6807 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_two_degrees.tex +2023/08/29 | 6043 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/No_cc_license.tex +2023/08/29 | 5926 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_one_degree.tex +2023/08/29 | 5907 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees_from_one_department.tex +2023/08/29 | 6034 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees.tex +2023/08/29 | 6028 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_one_degree.tex +2023/08/29 | 5931 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_two_degrees.tex 2023/07/21 | 105510 | macros/latex/contrib/mitthesis/examples/cover_page_samples/No_cc_license.pdf 2023/07/21 | 106895 | macros/latex/contrib/mitthesis/examples/cover_page_samples/One_author_one_degree.pdf 2023/07/21 | 107250 | macros/latex/contrib/mitthesis/examples/cover_page_samples/One_author_two_degrees_from_one_department.pdf 2023/07/21 | 107382 | macros/latex/contrib/mitthesis/examples/cover_page_samples/One_author_two_degrees.pdf 2023/07/21 | 108222 | macros/latex/contrib/mitthesis/examples/cover_page_samples/Two_authors_one_degree.pdf 2023/07/21 | 131063 | macros/latex/contrib/mitthesis/examples/cover_page_samples/Two_authors_two_degrees.pdf -2023/07/22 | 490288 | macros/latex/contrib/mitthesis/examples/font_samples/Defaultfonts.pdf -2023/07/22 | 319041 | macros/latex/contrib/mitthesis/examples/font_samples/Fira_Newtxsf.pdf -2023/07/22 | 151460 | macros/latex/contrib/mitthesis/examples/font_samples/Heros-Stix2.pdf -2023/07/22 | 11400 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Defaultfonts.tex -2023/07/22 | 11400 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Fira_Newtxsf.tex -2023/07/22 | 11881 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Heros-Stix2.tex -2023/07/22 | 11879 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Libertine.tex -2023/07/22 | 11876 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Lucida.tex -2023/07/22 | 11885 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx-sans-text.tex -2023/07/22 | 11875 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx.tex +2023/08/29 | 490687 | macros/latex/contrib/mitthesis/examples/font_samples/Defaultfonts.pdf +2023/08/30 | 323017 | macros/latex/contrib/mitthesis/examples/font_samples/Fira_Newtxsf.pdf +2023/08/29 | 151029 | macros/latex/contrib/mitthesis/examples/font_samples/Heros-Stix2.pdf +2023/08/29 | 11660 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Defaultfonts.tex +2023/08/29 | 11673 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Fira_Newtxsf.tex +2023/08/29 | 11672 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Heros-Stix2.tex +2023/08/29 | 11670 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Libertine.tex +2023/08/29 | 11667 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Lucida.tex +2023/08/29 | 11676 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx-sans-text.tex +2023/08/29 | 11666 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx.tex 2023/06/20 | 282 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/README_font_sample_sources.txt -2023/07/22 | 11874 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Stix2.tex -2023/07/22 | 11882 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes-Stix2.tex -2023/07/22 | 11905 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes.tex -2023/07/22 | 454847 | macros/latex/contrib/mitthesis/examples/font_samples/Libertine.pdf -2023/07/22 | 169955 | macros/latex/contrib/mitthesis/examples/font_samples/Lucida.pdf -2023/07/22 | 316127 | macros/latex/contrib/mitthesis/examples/font_samples/Newtx.pdf -2023/07/22 | 270252 | macros/latex/contrib/mitthesis/examples/font_samples/Newtx-sans-text.pdf -2023/07/22 | 159625 | macros/latex/contrib/mitthesis/examples/font_samples/Stix2.pdf -2023/07/22 | 157894 | macros/latex/contrib/mitthesis/examples/font_samples/Termes.pdf -2023/07/22 | 161691 | macros/latex/contrib/mitthesis/examples/font_samples/Termes-Stix2.pdf +2023/08/29 | 11666 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Stix2.tex +2023/08/29 | 11673 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes-stix2.tex +2023/08/29 | 11667 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes.tex +2023/08/29 | 458937 | macros/latex/contrib/mitthesis/examples/font_samples/Libertine.pdf +2023/08/29 | 169261 | macros/latex/contrib/mitthesis/examples/font_samples/Lucida.pdf +2023/08/29 | 320067 | macros/latex/contrib/mitthesis/examples/font_samples/Newtx.pdf +2023/08/29 | 274790 | macros/latex/contrib/mitthesis/examples/font_samples/Newtx-sans-text.pdf +2023/08/29 | 159311 | macros/latex/contrib/mitthesis/examples/font_samples/Stix2.pdf +2023/08/29 | 157329 | macros/latex/contrib/mitthesis/examples/font_samples/Termes.pdf +2023/08/29 | 161163 | macros/latex/contrib/mitthesis/examples/font_samples/Termes-stix2.pdf 2023/07/03 | 654 | macros/latex/contrib/mitthesis/fontsets/mitthesis-defaultfonts.tex -2023/07/03 | 991 | macros/latex/contrib/mitthesis/fontsets/mitthesis-fira-newtxsf.tex +2023/08/30 | 990 | macros/latex/contrib/mitthesis/fontsets/mitthesis-fira-newtxsf.tex 2023/07/03 | 2857 | macros/latex/contrib/mitthesis/fontsets/mitthesis-heros-stix2.tex 2023/07/03 | 2332 | macros/latex/contrib/mitthesis/fontsets/mitthesis-libertine.tex 2023/07/03 | 5639 | macros/latex/contrib/mitthesis/fontsets/mitthesis-lucida.tex @@ -229990,20 +230012,20 @@ 2023/07/03 | 2318 | macros/latex/contrib/mitthesis/fontsets/mitthesis-stix2.tex 2023/07/03 | 2980 | macros/latex/contrib/mitthesis/fontsets/mitthesis-termes-stix2.tex 2023/07/03 | 2378 | macros/latex/contrib/mitthesis/fontsets/mitthesis-termes.tex -2023/07/22 | 30391 | macros/latex/contrib/mitthesis/mitthesis.cls -2023/07/21 | 81325 | macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.pdf -2023/07/21 | 27848 | macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.tex -2023/07/22 | 489188 | macros/latex/contrib/mitthesis/MIT-Thesis.pdf -2023/06/19 | 1161 | macros/latex/contrib/mitthesis/MIT-thesis-template/abstract.tex +2023/08/29 | 41629 | macros/latex/contrib/mitthesis/mitthesis.cls +2023/08/29 | 82805 | macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.pdf +2023/08/29 | 28615 | macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.tex +2023/08/30 | 490683 | macros/latex/contrib/mitthesis/MIT-Thesis.pdf +2023/08/27 | 1161 | macros/latex/contrib/mitthesis/MIT-thesis-template/abstract.tex 2023/06/17 | 253 | macros/latex/contrib/mitthesis/MIT-thesis-template/acknowledgments.tex 2023/07/05 | 1889 | macros/latex/contrib/mitthesis/MIT-thesis-template/appendixa.tex 2023/06/13 | 1759 | macros/latex/contrib/mitthesis/MIT-thesis-template/biography.tex -2023/07/22 | 7973 | macros/latex/contrib/mitthesis/MIT-thesis-template/chapter1.tex -2023/06/30 | 11511 | macros/latex/contrib/mitthesis/MIT-thesis-template/mitthesis-sample.bib -2023/07/22 | 11978 | macros/latex/contrib/mitthesis/MIT-thesis-template/MIT-Thesis.tex +2023/08/25 | 7973 | macros/latex/contrib/mitthesis/MIT-thesis-template/chapter1.tex +2023/08/26 | 11511 | macros/latex/contrib/mitthesis/MIT-thesis-template/mitthesis-sample.bib +2023/08/30 | 11660 | macros/latex/contrib/mitthesis/MIT-thesis-template/MIT-Thesis.tex 2023/06/17 | 2340 | macros/latex/contrib/mitthesis/MIT-thesis-template/mydesign.tex -2023/07/22 | 4807 | macros/latex/contrib/mitthesis/README.md -2023/07/22 | 3602045 | macros/latex/contrib/mitthesis.zip +2023/08/30 | 5416 | macros/latex/contrib/mitthesis/README.md +2023/08/30 | 3617458 | macros/latex/contrib/mitthesis.zip 2016/12/14 | 23727 | macros/latex/contrib/mkstmpdad/aeb_dad.dtx 2016/08/21 | 2010 | macros/latex/contrib/mkstmpdad/aeb_dad.ins 2016/12/14 | 740061 | macros/latex/contrib/mkstmpdad/doc/mkstmpdad_man.pdf @@ -255996,9 +256018,9 @@ 2014/12/05 | 4915 | macros/xetex/latex/xeindex/xeindex.sty 2014/12/05 | 19009 | macros/xetex/latex/xeindex/xeindex.tex 2014/12/05 | 79942 | macros/xetex/latex/xeindex.zip -2023/08/26 | 15976 | macros/xetex/latex/xepersian/dkun-0.3.py -2023/08/26 | 15867 | macros/xetex/latex/xepersian/dkun-0.4.py -2023/08/26 | 38725 | macros/xetex/latex/xepersian/ftxe-0.12.py +2023/08/30 | 15976 | macros/xetex/latex/xepersian/dkun-0.3.py +2023/08/30 | 15867 | macros/xetex/latex/xepersian/dkun-0.4.py +2023/08/30 | 38725 | macros/xetex/latex/xepersian/ftxe-0.12.py 2020/09/04 | 13130 | macros/xetex/latex/xepersian-hm/doc-ligature-xepersian-hm.pdf 2020/09/04 | 10104 | macros/xetex/latex/xepersian-hm/doc-ligature-xep.pdf 2020/09/04 | 63436 | macros/xetex/latex/xepersian-hm/doc-samples-glyph.pdf @@ -256020,26 +256042,26 @@ 2020/09/04 | 106056 | macros/xetex/latex/xepersian-hm/xepersian-XB.pdf 2020/09/04 | 2945 | macros/xetex/latex/xepersian-hm/xepersian-XB.tex 2020/09/04 | 2217805 | macros/xetex/latex/xepersian-hm.zip -2023/08/26 | 18304 | macros/xetex/latex/xepersian/img/ireland.jpg -2023/08/26 | 13088 | macros/xetex/latex/xepersian/img/weather/clouds.jpg -2023/08/26 | 14616 | macros/xetex/latex/xepersian/img/weather/rain.jpg -2023/08/26 | 10896 | macros/xetex/latex/xepersian/img/weather/sun.jpg -2023/08/26 | 1390 | macros/xetex/latex/xepersian/README -2023/08/26 | 13804 | macros/xetex/latex/xepersian/undk-0.6.py -2023/08/26 | 12348 | macros/xetex/latex/xepersian/unldk-0.2.py -2023/08/26 | 71387 | macros/xetex/latex/xepersian/xepersian-doc-basics.ltx -2023/08/26 | 410 | macros/xetex/latex/xepersian/xepersian-doc-boolean.ltx -2023/08/26 | 3099 | macros/xetex/latex/xepersian/xepersian-doc-captions.ltx -2023/08/26 | 5447 | macros/xetex/latex/xepersian/xepersian-doc-envcs.ltx -2023/08/26 | 2609 | macros/xetex/latex/xepersian/xepersian-doc-intro.ltx -2023/08/26 | 454 | macros/xetex/latex/xepersian/xepersian-doc.ltx -2023/08/26 | 243977 | macros/xetex/latex/xepersian/xepersian-doc.pdf -2023/08/26 | 25876 | macros/xetex/latex/xepersian/xepersian-doc-pkgs.ltx -2023/08/26 | 4149 | macros/xetex/latex/xepersian/xepersian-doc-preamble.ltx -2023/08/26 | 2108 | macros/xetex/latex/xepersian/xepersian-doc-title.ltx -2023/08/26 | 346697 | macros/xetex/latex/xepersian/xepersian.dtx -2023/08/26 | 784492 | macros/xetex/latex/xepersian/xepersian.pdf -2023/08/26 | 1139332 | macros/xetex/latex/xepersian.zip +2023/08/30 | 18304 | macros/xetex/latex/xepersian/img/ireland.jpg +2023/08/30 | 13088 | macros/xetex/latex/xepersian/img/weather/clouds.jpg +2023/08/30 | 14616 | macros/xetex/latex/xepersian/img/weather/rain.jpg +2023/08/30 | 10896 | macros/xetex/latex/xepersian/img/weather/sun.jpg +2023/08/30 | 1390 | macros/xetex/latex/xepersian/README +2023/08/30 | 13804 | macros/xetex/latex/xepersian/undk-0.6.py +2023/08/30 | 12348 | macros/xetex/latex/xepersian/unldk-0.2.py +2023/08/30 | 71387 | macros/xetex/latex/xepersian/xepersian-doc-basics.ltx +2023/08/30 | 410 | macros/xetex/latex/xepersian/xepersian-doc-boolean.ltx +2023/08/30 | 3099 | macros/xetex/latex/xepersian/xepersian-doc-captions.ltx +2023/08/30 | 5447 | macros/xetex/latex/xepersian/xepersian-doc-envcs.ltx +2023/08/30 | 2609 | macros/xetex/latex/xepersian/xepersian-doc-intro.ltx +2023/08/30 | 454 | macros/xetex/latex/xepersian/xepersian-doc.ltx +2023/08/30 | 236376 | macros/xetex/latex/xepersian/xepersian-doc.pdf +2023/08/30 | 25876 | macros/xetex/latex/xepersian/xepersian-doc-pkgs.ltx +2023/08/30 | 4149 | macros/xetex/latex/xepersian/xepersian-doc-preamble.ltx +2023/08/30 | 2108 | macros/xetex/latex/xepersian/xepersian-doc-title.ltx +2023/08/30 | 343316 | macros/xetex/latex/xepersian/xepersian.dtx +2023/08/30 | 777229 | macros/xetex/latex/xepersian/xepersian.pdf +2023/08/30 | 1123565 | macros/xetex/latex/xepersian.zip 2021/03/29 | 142 | macros/xetex/latex/xesoul/README 2021/03/29 | 3942 | macros/xetex/latex/xesoul/xesoul.dtx 2021/03/29 | 1517 | macros/xetex/latex/xesoul/xesoul.ins @@ -290807,7 +290829,7 @@ 2021/02/07 | 136588 | systems/texlive/tlnet/archive/babel-danish.doc.r57642.tar.xz 2021/02/07 | 2488 | systems/texlive/tlnet/archive/babel-danish.r57642.tar.xz 2021/02/07 | 5792 | systems/texlive/tlnet/archive/babel-danish.source.r57642.tar.xz -2023/07/17 | 1014460 | systems/texlive/tlnet/archive/babel.doc.r67653.tar.xz +2023/08/30 | 1021980 | systems/texlive/tlnet/archive/babel.doc.r68111.tar.xz 2021/08/30 | 157392 | systems/texlive/tlnet/archive/babel-dutch.doc.r60362.tar.xz 2021/08/30 | 2920 | systems/texlive/tlnet/archive/babel-dutch.r60362.tar.xz 2021/08/30 | 7968 | systems/texlive/tlnet/archive/babel-dutch.source.r60362.tar.xz @@ -290896,7 +290918,7 @@ 2021/07/10 | 146580 | systems/texlive/tlnet/archive/babel-portuges.doc.r59883.tar.xz 2021/07/10 | 2828 | systems/texlive/tlnet/archive/babel-portuges.r59883.tar.xz 2021/07/10 | 6692 | systems/texlive/tlnet/archive/babel-portuges.source.r59883.tar.xz -2023/07/17 | 208988 | systems/texlive/tlnet/archive/babel.r67653.tar.xz +2023/08/30 | 213460 | systems/texlive/tlnet/archive/babel.r68111.tar.xz 2021/04/07 | 113056 | systems/texlive/tlnet/archive/babel-romanian.doc.r58776.tar.xz 2021/04/07 | 2124 | systems/texlive/tlnet/archive/babel-romanian.r58776.tar.xz 2021/04/07 | 4308 | systems/texlive/tlnet/archive/babel-romanian.source.r58776.tar.xz @@ -290927,7 +290949,7 @@ 2021/11/07 | 209804 | systems/texlive/tlnet/archive/babel-sorbian.doc.r60975.tar.xz 2021/11/07 | 3156 | systems/texlive/tlnet/archive/babel-sorbian.r60975.tar.xz 2021/11/07 | 6328 | systems/texlive/tlnet/archive/babel-sorbian.source.r60975.tar.xz -2023/07/17 | 787100 | systems/texlive/tlnet/archive/babel.source.r67653.tar.xz +2023/08/30 | 813792 | systems/texlive/tlnet/archive/babel.source.r68111.tar.xz 2021/05/28 | 183140 | systems/texlive/tlnet/archive/babel-spanish.doc.r59367.tar.xz 2021/05/28 | 8876 | systems/texlive/tlnet/archive/babel-spanish.r59367.tar.xz 2021/05/28 | 29800 | systems/texlive/tlnet/archive/babel-spanish.source.r59367.tar.xz @@ -295633,8 +295655,8 @@ 2019/02/28 | 24892 | systems/texlive/tlnet/archive/hustthesis.source.r42547.tar.xz 2021/06/02 | 150588 | systems/texlive/tlnet/archive/hvarabic.doc.r59423.tar.xz 2021/06/02 | 1468 | systems/texlive/tlnet/archive/hvarabic.r59423.tar.xz -2023/08/26 | 1131856 | systems/texlive/tlnet/archive/hvextern.doc.r68056.tar.xz -2023/08/26 | 8312 | systems/texlive/tlnet/archive/hvextern.r68056.tar.xz +2023/08/30 | 1136200 | systems/texlive/tlnet/archive/hvextern.doc.r68104.tar.xz +2023/08/30 | 8436 | systems/texlive/tlnet/archive/hvextern.r68104.tar.xz 2023/05/19 | 10222436 | systems/texlive/tlnet/archive/hvfloat.doc.r67149.tar.xz 2023/05/19 | 13380 | systems/texlive/tlnet/archive/hvfloat.r67149.tar.xz 2019/02/28 | 76336 | systems/texlive/tlnet/archive/hvindex.doc.r46051.tar.xz @@ -296137,8 +296159,8 @@ 2019/02/28 | 197100 | systems/texlive/tlnet/archive/jvlisting.doc.r24638.tar.xz 2019/02/28 | 2552 | systems/texlive/tlnet/archive/jvlisting.r24638.tar.xz 2019/02/28 | 6744 | systems/texlive/tlnet/archive/jvlisting.source.r24638.tar.xz -2023/08/28 | 91232 | systems/texlive/tlnet/archive/jwjournal.doc.r68088.tar.xz -2023/08/28 | 2668 | systems/texlive/tlnet/archive/jwjournal.r68088.tar.xz +2023/08/30 | 123856 | systems/texlive/tlnet/archive/jwjournal.doc.r68105.tar.xz +2023/08/30 | 3164 | systems/texlive/tlnet/archive/jwjournal.r68105.tar.xz 2019/02/28 | 365480 | systems/texlive/tlnet/archive/kalendarium.doc.r48744.tar.xz 2019/02/28 | 3540 | systems/texlive/tlnet/archive/kalendarium.r48744.tar.xz 2019/02/28 | 16432 | systems/texlive/tlnet/archive/kalendarium.source.r48744.tar.xz @@ -296359,9 +296381,9 @@ 2023/05/12 | 3498172 | systems/texlive/tlnet/archive/l3experimental.doc.r67074.tar.xz 2023/05/12 | 23660 | systems/texlive/tlnet/archive/l3experimental.r67074.tar.xz 2023/05/12 | 80176 | systems/texlive/tlnet/archive/l3experimental.source.r67074.tar.xz -2023/08/12 | 11995468 | systems/texlive/tlnet/archive/l3kernel.doc.r67891.tar.xz -2023/08/12 | 173512 | systems/texlive/tlnet/archive/l3kernel.r67891.tar.xz -2023/08/12 | 597464 | systems/texlive/tlnet/archive/l3kernel.source.r67891.tar.xz +2023/08/30 | 12007176 | systems/texlive/tlnet/archive/l3kernel.doc.r68106.tar.xz +2023/08/30 | 173872 | systems/texlive/tlnet/archive/l3kernel.r68106.tar.xz +2023/08/30 | 598548 | systems/texlive/tlnet/archive/l3kernel.source.r68106.tar.xz 2023/02/04 | 1831688 | systems/texlive/tlnet/archive/l3packages.doc.r65722.tar.xz 2023/02/04 | 21928 | systems/texlive/tlnet/archive/l3packages.r65722.tar.xz 2023/02/04 | 45696 | systems/texlive/tlnet/archive/l3packages.source.r65722.tar.xz @@ -299101,9 +299123,9 @@ 2022/10/30 | 314616 | systems/texlive/tlnet/archive/pdflscape.doc.r64851.tar.xz 2022/10/30 | 2612 | systems/texlive/tlnet/archive/pdflscape.r64851.tar.xz 2022/10/30 | 6508 | systems/texlive/tlnet/archive/pdflscape.source.r64851.tar.xz -2023/08/22 | 8467948 | systems/texlive/tlnet/archive/pdfmanagement-testphase.doc.r68005.tar.xz -2023/08/22 | 53660 | systems/texlive/tlnet/archive/pdfmanagement-testphase.r68005.tar.xz -2023/08/22 | 137332 | systems/texlive/tlnet/archive/pdfmanagement-testphase.source.r68005.tar.xz +2023/08/30 | 8746688 | systems/texlive/tlnet/archive/pdfmanagement-testphase.doc.r68107.tar.xz +2023/08/30 | 53708 | systems/texlive/tlnet/archive/pdfmanagement-testphase.r68107.tar.xz +2023/08/30 | 137424 | systems/texlive/tlnet/archive/pdfmanagement-testphase.source.r68107.tar.xz 2019/02/28 | 381552 | systems/texlive/tlnet/archive/pdfmarginpar.doc.r23492.tar.xz 2019/02/28 | 2424 | systems/texlive/tlnet/archive/pdfmarginpar.r23492.tar.xz 2023/03/22 | 234168 | systems/texlive/tlnet/archive/pdfmsym.doc.r66618.tar.xz @@ -299648,9 +299670,9 @@ 2019/02/28 | 317360 | systems/texlive/tlnet/archive/ppr-prv.doc.r15878.tar.xz 2019/02/28 | 5596 | systems/texlive/tlnet/archive/ppr-prv.r15878.tar.xz 2019/02/28 | 9460 | systems/texlive/tlnet/archive/ppr-prv.source.r15878.tar.xz -2022/12/04 | 788536 | systems/texlive/tlnet/archive/ppt-slides.doc.r65194.tar.xz -2022/12/04 | 4160 | systems/texlive/tlnet/archive/ppt-slides.r65194.tar.xz -2022/12/04 | 6308 | systems/texlive/tlnet/archive/ppt-slides.source.r65194.tar.xz +2023/08/30 | 788860 | systems/texlive/tlnet/archive/ppt-slides.doc.r68108.tar.xz +2023/08/30 | 4172 | systems/texlive/tlnet/archive/ppt-slides.r68108.tar.xz +2023/08/30 | 6364 | systems/texlive/tlnet/archive/ppt-slides.source.r68108.tar.xz 2022/01/24 | 386136 | systems/texlive/tlnet/archive/pracjourn.doc.r61719.tar.xz 2022/01/24 | 4628 | systems/texlive/tlnet/archive/pracjourn.r61719.tar.xz 2022/01/24 | 15248 | systems/texlive/tlnet/archive/pracjourn.source.r61719.tar.xz @@ -300179,8 +300201,8 @@ 2022/06/27 | 8644 | systems/texlive/tlnet/archive/pwebmac.r63731.tar.xz 2023/02/27 | 167592 | systems/texlive/tlnet/archive/pxbase.doc.r66187.tar.xz 2023/02/27 | 12464 | systems/texlive/tlnet/archive/pxbase.r66187.tar.xz -2023/08/19 | 326908 | systems/texlive/tlnet/archive/pxchfon.doc.r67972.tar.xz -2023/08/19 | 20228 | systems/texlive/tlnet/archive/pxchfon.r67972.tar.xz +2023/08/30 | 336476 | systems/texlive/tlnet/archive/pxchfon.doc.r68103.tar.xz +2023/08/30 | 19976 | systems/texlive/tlnet/archive/pxchfon.r68103.tar.xz 2022/07/24 | 211444 | systems/texlive/tlnet/archive/pxcjkcat.doc.r63967.tar.xz 2022/07/24 | 10196 | systems/texlive/tlnet/archive/pxcjkcat.r63967.tar.xz 2019/02/28 | 421672 | systems/texlive/tlnet/archive/pxfonts.doc.r15878.tar.xz @@ -300663,9 +300685,9 @@ 2022/10/18 | 2340 | systems/texlive/tlnet/archive/schola-otf.r64734.tar.xz 2022/02/02 | 341700 | systems/texlive/tlnet/archive/scholax.doc.r61836.tar.xz 2022/02/02 | 1884328 | systems/texlive/tlnet/archive/scholax.r61836.tar.xz -2023/01/28 | 516488 | systems/texlive/tlnet/archive/schooldocs.doc.r65650.tar.xz -2023/01/28 | 3008 | systems/texlive/tlnet/archive/schooldocs.r65650.tar.xz -2023/01/28 | 10576 | systems/texlive/tlnet/archive/schooldocs.source.r65650.tar.xz +2023/08/30 | 514716 | systems/texlive/tlnet/archive/schooldocs.doc.r68109.tar.xz +2023/08/30 | 3028 | systems/texlive/tlnet/archive/schooldocs.r68109.tar.xz +2023/08/30 | 10996 | systems/texlive/tlnet/archive/schooldocs.source.r68109.tar.xz 2023/03/22 | 3855300 | systems/texlive/tlnet/archive/schule.doc.r66635.tar.xz 2023/03/22 | 40112 | systems/texlive/tlnet/archive/schule.r66635.tar.xz 2023/06/22 | 299636 | systems/texlive/tlnet/archive/schulmathematik.doc.r67426.tar.xz @@ -301786,12 +301808,12 @@ 2019/02/28 | 340 | systems/texlive/tlnet/archive/texfot.amd64-freebsd.r33155.tar.xz 2019/02/28 | 336 | systems/texlive/tlnet/archive/texfot.amd64-netbsd.r33155.tar.xz 2019/02/28 | 336 | systems/texlive/tlnet/archive/texfot.armhf-linux.r33155.tar.xz -2023/01/16 | 33500 | systems/texlive/tlnet/archive/texfot.doc.r65545.tar.xz +2023/08/30 | 35164 | systems/texlive/tlnet/archive/texfot.doc.r68110.tar.xz 2019/02/28 | 340 | systems/texlive/tlnet/archive/texfot.i386-freebsd.r33155.tar.xz 2019/02/28 | 340 | systems/texlive/tlnet/archive/texfot.i386-linux.r33155.tar.xz 2019/02/28 | 336 | systems/texlive/tlnet/archive/texfot.i386-netbsd.r33155.tar.xz 2019/02/28 | 340 | systems/texlive/tlnet/archive/texfot.i386-solaris.r33155.tar.xz -2023/01/16 | 6688 | systems/texlive/tlnet/archive/texfot.r65545.tar.xz +2023/08/30 | 6936 | systems/texlive/tlnet/archive/texfot.r68110.tar.xz 2021/02/25 | 340 | systems/texlive/tlnet/archive/texfot.universal-darwin.r57908.tar.xz 2023/02/20 | 2304 | systems/texlive/tlnet/archive/texfot.windows.r65891.tar.xz 2019/02/28 | 340 | systems/texlive/tlnet/archive/texfot.x86_64-cygwin.r33557.tar.xz @@ -301876,7 +301898,7 @@ 2022/09/13 | 600 | systems/texlive/tlnet/archive/texlive-scripts.amd64-freebsd.r64356.tar.xz 2022/09/13 | 596 | systems/texlive/tlnet/archive/texlive-scripts.amd64-netbsd.r64356.tar.xz 2022/09/13 | 596 | systems/texlive/tlnet/archive/texlive-scripts.armhf-linux.r64356.tar.xz -2023/08/29 | 428856 | systems/texlive/tlnet/archive/texlive-scripts.doc.r68095.tar.xz +2023/08/30 | 428804 | systems/texlive/tlnet/archive/texlive-scripts.doc.r68102.tar.xz 2020/01/27 | 916 | systems/texlive/tlnet/archive/texlive-scripts-extra.aarch64-linux.r53577.tar.xz 2020/01/27 | 924 | systems/texlive/tlnet/archive/texlive-scripts-extra.amd64-freebsd.r53577.tar.xz 2020/01/27 | 916 | systems/texlive/tlnet/archive/texlive-scripts-extra.amd64-netbsd.r53577.tar.xz @@ -301898,7 +301920,7 @@ 2022/09/13 | 592 | systems/texlive/tlnet/archive/texlive-scripts.i386-linux.r64356.tar.xz 2022/09/13 | 596 | systems/texlive/tlnet/archive/texlive-scripts.i386-netbsd.r64356.tar.xz 2022/09/13 | 596 | systems/texlive/tlnet/archive/texlive-scripts.i386-solaris.r64356.tar.xz -2023/08/29 | 114116 | systems/texlive/tlnet/archive/texlive-scripts.r68095.tar.xz +2023/08/30 | 114120 | systems/texlive/tlnet/archive/texlive-scripts.r68102.tar.xz 2022/09/13 | 580 | systems/texlive/tlnet/archive/texlive-scripts.universal-darwin.r64356.tar.xz 2023/05/14 | 60312 | systems/texlive/tlnet/archive/texlive-scripts.windows.r67095.tar.xz 2022/09/13 | 596 | systems/texlive/tlnet/archive/texlive-scripts.x86_64-cygwin.r64356.tar.xz @@ -303769,16 +303791,16 @@ 2020/07/18 | 47816 | systems/texlive/tlnet/archive/zztex.doc.r55862.tar.xz 2020/07/18 | 101724 | systems/texlive/tlnet/archive/zztex.r55862.tar.xz 2023/08/07 | 125713 | systems/texlive/tlnet/install-tl -2023/08/29 | 5740575 | systems/texlive/tlnet/install-tl-unx.tar.gz -2023/08/29 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512 -2023/08/29 | 488 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc +2023/08/30 | 5741159 | systems/texlive/tlnet/install-tl-unx.tar.gz +2023/08/30 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512 +2023/08/30 | 488 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc 2023/05/13 | 5083 | systems/texlive/tlnet/install-tl-windows.bat -2023/08/29 | 21038354 | systems/texlive/tlnet/install-tl-windows.exe -2023/08/29 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512 -2023/08/29 | 488 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc -2023/08/29 | 26028701 | systems/texlive/tlnet/install-tl.zip -2023/08/29 | 145 | systems/texlive/tlnet/install-tl.zip.sha512 -2023/08/29 | 488 | systems/texlive/tlnet/install-tl.zip.sha512.asc +2023/08/30 | 21039180 | systems/texlive/tlnet/install-tl-windows.exe +2023/08/30 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512 +2023/08/30 | 488 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc +2023/08/30 | 26028712 | systems/texlive/tlnet/install-tl.zip +2023/08/30 | 145 | systems/texlive/tlnet/install-tl.zip.sha512 +2023/08/30 | 488 | systems/texlive/tlnet/install-tl.zip.sha512.asc 2023/03/19 | 1229 | systems/texlive/tlnet/README.md 2023/03/19 | 0 | systems/texlive/tlnet/TEXLIVE_2023 2023/01/17 | 8401 | systems/texlive/tlnet/tlpkg/gpg/pubring.gpg @@ -303788,7 +303810,7 @@ 2023/01/17 | 1280 | systems/texlive/tlnet/tlpkg/gpg/trustdb.gpg 2023/08/03 | 50576 | systems/texlive/tlnet/tlpkg/installer/config.guess 2010/11/11 | 11651 | systems/texlive/tlnet/tlpkg/installer/COPYING.MinGW-runtime.txt -2023/08/27 | 7312 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl +2023/08/29 | 7372 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl 2023/08/23 | 221470 | systems/texlive/tlnet/tlpkg/installer/curl/curl-ca-bundle.crt 2020/04/15 | 2606592 | systems/texlive/tlnet/tlpkg/installer/curl/curl.exe 2017/04/16 | 2629 | systems/texlive/tlnet/tlpkg/installer/installer-options.txt @@ -303830,12 +303852,12 @@ 2023/02/21 | 20371 | systems/texlive/tlnet/tlpkg/TeXLive/TLCrypto.pm 2021/12/21 | 5429 | systems/texlive/tlnet/tlpkg/TeXLive/TLDownload.pm 2023/04/08 | 28167 | systems/texlive/tlnet/tlpkg/TeXLive/TLPaper.pm -2023/08/29 | 18219224 | systems/texlive/tlnet/tlpkg/texlive.tlpdb -2023/08/29 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 +2023/08/30 | 18220056 | systems/texlive/tlnet/tlpkg/texlive.tlpdb +2023/08/30 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 2023/02/20 | 86803 | systems/texlive/tlnet/tlpkg/TeXLive/TLPDB.pm -2023/08/29 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 -2023/08/29 | 488 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc -2023/08/29 | 2464888 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz +2023/08/30 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 +2023/08/30 | 488 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc +2023/08/30 | 2467840 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz 2023/02/20 | 58928 | systems/texlive/tlnet/tlpkg/TeXLive/TLPOBJ.pm 2023/06/11 | 42749 | systems/texlive/tlnet/tlpkg/TeXLive/TLPSRC.pm 2023/02/21 | 16138 | systems/texlive/tlnet/tlpkg/TeXLive/TLTREE.pm @@ -314524,7 +314546,7 @@ 2014/07/05 | 611 | systems/win32/yandy/README 2014/07/05 | 1004628 | systems/win32/yandy/yandy-src.tar.xz 2014/07/05 | 1012416 | systems/win32/yandy.zip -2023/08/30 | 186 | timestamp +2023/08/31 | 186 | timestamp 2002/08/26 | 61898 | usergrps/dante/antrag.pdf 2002/08/26 | 118217 | usergrps/dante/antrag.ps 2021/11/11 | 917 | usergrps/dante/dtk/doc/beispiel.bib diff --git a/FILES.byname.gz b/FILES.byname.gz index 2c7a6b7e1c..04cb11907c 100644 Binary files a/FILES.byname.gz and b/FILES.byname.gz differ diff --git a/FILES.last07days b/FILES.last07days index 75e256a379..3a5f7d7174 100644 --- a/FILES.last07days +++ b/FILES.last07days @@ -1,3 +1,149 @@ +2023/08/30 | 990 | macros/latex/contrib/mitthesis/fontsets/mitthesis-fira-newtxsf.tex +2023/08/30 | 938 | fonts/metsymb/CHANGELOG +2023/08/30 | 934 | fonts/metsymb/source/metsymb_mwe.py +2023/08/30 | 9208 | fonts/metsymb/CONTRIBUTING.md +2023/08/30 | 8893 | macros/latex/contrib/jwjournal/README.md +2023/08/30 | 8746688 | systems/texlive/tlnet/archive/pdfmanagement-testphase.doc.r68107.tar.xz +2023/08/30 | 8625 | fonts/metsymb/source/metsymb.pfb +2023/08/30 | 8436 | systems/texlive/tlnet/archive/hvextern.r68104.tar.xz +2023/08/30 | 813792 | systems/texlive/tlnet/archive/babel.source.r68111.tar.xz +2023/08/30 | 788860 | systems/texlive/tlnet/archive/ppt-slides.doc.r68108.tar.xz +2023/08/30 | 777229 | macros/xetex/latex/xepersian/xepersian.pdf +2023/08/30 | 71387 | macros/xetex/latex/xepersian/xepersian-doc-basics.ltx +2023/08/30 | 70876 | macros/latex/contrib/jwjournal/jwjournal-demo-cn.pdf +2023/08/30 | 6936 | systems/texlive/tlnet/archive/texfot.r68110.tar.xz +2023/08/30 | 690418 | macros/latex/contrib/mathastext.zip +2023/08/30 | 66 | fonts/metsymb/AUTHORS +2023/08/30 | 638 | graphics/pgf/contrib/hobby/README +2023/08/30 | 6364 | systems/texlive/tlnet/archive/ppt-slides.source.r68108.tar.xz +2023/08/30 | 61129 | fonts/metsymb/source/metsymb.sfd +2023/08/30 | 60 | fonts/metsymb/source/metsymb_mwe.mplstyle +2023/08/30 | 598548 | systems/texlive/tlnet/archive/l3kernel.source.r68106.tar.xz +2023/08/30 | 574466 | macros/latex/contrib/mathastext/mathastext.pdf +2023/08/30 | 5741159 | systems/texlive/tlnet/install-tl-unx.tar.gz +2023/08/30 | 5461 | macros/latex/contrib/mathastext/README.md +2023/08/30 | 5447 | macros/xetex/latex/xepersian/xepersian-doc-envcs.ltx +2023/08/30 | 5416 | macros/latex/contrib/mitthesis/README.md +2023/08/30 | 53708 | systems/texlive/tlnet/archive/pdfmanagement-testphase.r68107.tar.xz +2023/08/30 | 514716 | systems/texlive/tlnet/archive/schooldocs.doc.r68109.tar.xz +2023/08/30 | 514512 | graphics/pgf/contrib/hobby/hobby_code.pdf +2023/08/30 | 5101 | fonts/metsymb/README.md +2023/08/30 | 506560 | graphics/pgf/contrib/hobby/hobby.pdf +2023/08/30 | 49177 | fonts/metsymb/source/testfont.pdf +2023/08/30 | 490683 | macros/latex/contrib/mitthesis/MIT-Thesis.pdf +2023/08/30 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 +2023/08/30 | 488 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc +2023/08/30 | 488 | systems/texlive/tlnet/install-tl.zip.sha512.asc +2023/08/30 | 488 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc +2023/08/30 | 488 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc +2023/08/30 | 455333 | fonts/metsymb.zip +2023/08/30 | 454 | macros/xetex/latex/xepersian/xepersian-doc.ltx +2023/08/30 | 4485 | fonts/parsianfonts/parsianfonts-samples.tex +2023/08/30 | 43450 | graphics/pgf/contrib/hobby/hobby.tex +2023/08/30 | 431339 | macros/latex/contrib/mathastext/mathastext.dtx +2023/08/30 | 428804 | systems/texlive/tlnet/archive/texlive-scripts.doc.r68102.tar.xz +2023/08/30 | 420 | fonts/metsymb/source/metsymb.tfm +2023/08/30 | 4172 | systems/texlive/tlnet/archive/ppt-slides.r68108.tar.xz +2023/08/30 | 4149 | macros/xetex/latex/xepersian/xepersian-doc-preamble.ltx +2023/08/30 | 410 | macros/xetex/latex/xepersian/xepersian-doc-boolean.ltx +2023/08/30 | 4102144 | biblio/ctan-bibdata.zip +2023/08/30 | 38725 | macros/xetex/latex/xepersian/ftxe-0.12.py +2023/08/30 | 3701894 | biblio/ctan-bibdata/ctan.pdf +2023/08/30 | 3617458 | macros/latex/contrib/mitthesis.zip +2023/08/30 | 35287 | macros/latex/contrib/jwjournal/jwjournal-demo-fr.pdf +2023/08/30 | 35164 | systems/texlive/tlnet/archive/texfot.doc.r68110.tar.xz +2023/08/30 | 347762 | fonts/parsianfonts/parsianfonts-samples.pdf +2023/08/30 | 34389 | macros/latex/contrib/jwjournal/jwjournal-demo-en.pdf +2023/08/30 | 343316 | macros/xetex/latex/xepersian/xepersian.dtx +2023/08/30 | 336476 | systems/texlive/tlnet/archive/pxchfon.doc.r68103.tar.xz +2023/08/30 | 3359 | fonts/metsymb/CODE_OF_CONDUCT.md +2023/08/30 | 332267 | fonts/metsymb/source/metsymb.pdf +2023/08/30 | 32716 | fonts/metsymb/source/metsymb_mwe.pdf +2023/08/30 | 326332 | fonts/parsianfonts/ParsianMono/ParsianMono-Italic.ttf +2023/08/30 | 323860 | fonts/parsianfonts/ParsianMono/ParsianMono-BoldItalic.ttf +2023/08/30 | 323017 | macros/latex/contrib/mitthesis/examples/font_samples/Fira_Newtxsf.pdf +2023/08/30 | 3195 | fonts/parsianfonts/README.md +2023/08/30 | 3164 | systems/texlive/tlnet/archive/jwjournal.r68105.tar.xz +2023/08/30 | 3117 | macros/latex/contrib/jwjournal/jwjournal-demo-fr.tex +2023/08/30 | 3099 | macros/xetex/latex/xepersian/xepersian-doc-captions.ltx +2023/08/30 | 3081151 | fonts/parsianfonts.zip +2023/08/30 | 3028 | systems/texlive/tlnet/archive/schooldocs.r68109.tar.xz +2023/08/30 | 291716 | fonts/parsianfonts/ParsianTitle/ParsianTitle-Italic.ttf +2023/08/30 | 291520 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-BoldItalic.ttf +2023/08/30 | 28 | fonts/metsymb/source/metsymb.map +2023/08/30 | 288804 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Italic.ttf +2023/08/30 | 287268 | fonts/parsianfonts/ParsianMono/ParsianMono-Bold.ttf +2023/08/30 | 282088 | fonts/parsianfonts/Parsian/Parsian-BoldItalic.ttf +2023/08/30 | 2806562 | biblio/ctan-bibdata/ctan.bib +2023/08/30 | 279608 | fonts/parsianfonts/Parsian/Parsian-Italic.ttf +2023/08/30 | 276836 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Regular.ttf +2023/08/30 | 275708 | fonts/parsianfonts/ParsianTitle/ParsianTitle-Regular.ttf +2023/08/30 | 273028 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Bold.ttf +2023/08/30 | 269688 | fonts/parsianfonts/Parsian/Parsian-Regular.ttf +2023/08/30 | 2692 | macros/latex/contrib/jwjournal/jwjournal-demo-en.tex +2023/08/30 | 266400 | fonts/parsianfonts/ParsianMono/ParsianMono-Regular.ttf +2023/08/30 | 2650 | fonts/metsymb/source/metsymb.afm +2023/08/30 | 264888 | fonts/parsianfonts/Parsian/Parsian-Bold.ttf +2023/08/30 | 2630 | macros/latex/contrib/jwjournal/jwjournal-demo-cn.tex +2023/08/30 | 2609 | macros/xetex/latex/xepersian/xepersian-doc-intro.ltx +2023/08/30 | 26028712 | systems/texlive/tlnet/install-tl.zip +2023/08/30 | 2590 | fonts/metsymb/source/metsymb.enc +2023/08/30 | 25876 | macros/xetex/latex/xepersian/xepersian-doc-pkgs.ltx +2023/08/30 | 251108 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-BoldItalic.ttf +2023/08/30 | 2467840 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz +2023/08/30 | 236376 | macros/xetex/latex/xepersian/xepersian-doc.pdf +2023/08/30 | 232068 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Italic.ttf +2023/08/30 | 225296 | fonts/parsianfonts/ParsianTeX/ParsianTeX-BoldItalic.ttf +2023/08/30 | 218144 | fonts/parsianfonts/ParsianTeX/ParsianTeX-Italic.ttf +2023/08/30 | 213460 | systems/texlive/tlnet/archive/babel.r68111.tar.xz +2023/08/30 | 212232 | fonts/parsianfonts/ParsianSans/ParsianSans-BoldItalic.ttf +2023/08/30 | 2108 | macros/xetex/latex/xepersian/xepersian-doc-title.ltx +2023/08/30 | 21039180 | systems/texlive/tlnet/install-tl-windows.exe +2023/08/30 | 209136 | fonts/parsianfonts/ParsianSans/ParsianSans-Italic.ttf +2023/08/30 | 19976 | systems/texlive/tlnet/archive/pxchfon.r68103.tar.xz +2023/08/30 | 199196 | fonts/parsianfonts/ParsianSans/ParsianSans-Bold.ttf +2023/08/30 | 198784 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Bold.ttf +2023/08/30 | 198084 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Regular.ttf +2023/08/30 | 195508 | fonts/parsianfonts/ParsianSans/ParsianSans-Regular.ttf +2023/08/30 | 19106 | macros/latex/contrib/jwjournal/LICENSE +2023/08/30 | 18969 | fonts/metsymb/source/metsymb.dtx +2023/08/30 | 18304 | macros/xetex/latex/xepersian/img/ireland.jpg +2023/08/30 | 18220056 | systems/texlive/tlnet/tlpkg/texlive.tlpdb +2023/08/30 | 178616 | fonts/parsianfonts/ParsianTeX/ParsianTeX-Regular.ttf +2023/08/30 | 174528 | fonts/parsianfonts/ParsianTeX/ParsianTeX-Bold.ttf +2023/08/30 | 173872 | systems/texlive/tlnet/archive/l3kernel.r68106.tar.xz +2023/08/30 | 1678 | biblio/ctan-bibdata/biblatex-ctan/ctan.bbx +2023/08/30 | 15976 | macros/xetex/latex/xepersian/dkun-0.3.py +2023/08/30 | 15867 | macros/xetex/latex/xepersian/dkun-0.4.py +2023/08/30 | 154028 | macros/latex/contrib/jwjournal.zip +2023/08/30 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512 +2023/08/30 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512 +2023/08/30 | 1494 | fonts/metsymb/LICENSE +2023/08/30 | 14904 | fonts/metsymb/source/metsymb.otf +2023/08/30 | 14616 | macros/xetex/latex/xepersian/img/weather/rain.jpg +2023/08/30 | 145 | systems/texlive/tlnet/install-tl.zip.sha512 +2023/08/30 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 +2023/08/30 | 14210 | macros/latex/contrib/jwjournal/jwjournal.cls +2023/08/30 | 1390 | macros/xetex/latex/xepersian/README +2023/08/30 | 13804 | macros/xetex/latex/xepersian/undk-0.6.py +2023/08/30 | 137424 | systems/texlive/tlnet/archive/pdfmanagement-testphase.source.r68107.tar.xz +2023/08/30 | 13088 | macros/xetex/latex/xepersian/img/weather/clouds.jpg +2023/08/30 | 12 | macros/latex/contrib/jwjournal/DEPENDS.txt +2023/08/30 | 1288932 | install/macros/xetex/latex/xepersian.tds.zip +2023/08/30 | 123856 | systems/texlive/tlnet/archive/jwjournal.doc.r68105.tar.xz +2023/08/30 | 1237 | fonts/metsymb/source/metsymb.ins +2023/08/30 | 12348 | macros/xetex/latex/xepersian/unldk-0.2.py +2023/08/30 | 12007176 | systems/texlive/tlnet/archive/l3kernel.doc.r68106.tar.xz +2023/08/30 | 11660 | macros/latex/contrib/mitthesis/MIT-thesis-template/MIT-Thesis.tex +2023/08/30 | 114625 | graphics/pgf/contrib/hobby/hobby_code.dtx +2023/08/30 | 114120 | systems/texlive/tlnet/archive/texlive-scripts.r68102.tar.xz +2023/08/30 | 1136200 | systems/texlive/tlnet/archive/hvextern.doc.r68104.tar.xz +2023/08/30 | 1123565 | macros/xetex/latex/xepersian.zip +2023/08/30 | 110 | fonts/metsymb/source/umetsymb.fd +2023/08/30 | 10996 | systems/texlive/tlnet/archive/schooldocs.source.r68109.tar.xz +2023/08/30 | 10896 | macros/xetex/latex/xepersian/img/weather/sun.jpg +2023/08/30 | 1038831 | graphics/pgf/contrib/hobby.zip +2023/08/30 | 1021980 | systems/texlive/tlnet/archive/babel.doc.r68111.tar.xz 2023/08/29 | 9999 | macros/latex/contrib/l3kernel/l3news10.tex 2023/08/29 | 9953 | macros/latex/contrib/pdfmanagement-testphase/CHANGELOG.md 2023/08/29 | 98663 | macros/latex/contrib/l3kernel/l3seq.dtx @@ -14,11 +160,11 @@ 2023/08/29 | 88833 | macros/latex/contrib/l3kernel/l3expan.dtx 2023/08/29 | 88106 | macros/latex/contrib/l3kernel/l3coffins.dtx 2023/08/29 | 87744 | macros/latex/contrib/l3kernel/l3box.dtx -2023/08/29 | 8719 | macros/latex/contrib/jwjournal/README.md 2023/08/29 | 8481 | macros/latex/contrib/l3kernel/l3news11.tex 2023/08/29 | 84789 | macros/latex/contrib/l3kernel/l3fp-basics.dtx 2023/08/29 | 84537 | macros/latex/contrib/l3packages/xparse-2018-04-12.sty 2023/08/29 | 83077 | macros/latex/contrib/l3kernel/l3clist.dtx +2023/08/29 | 82805 | macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.pdf 2023/08/29 | 81941 | macros/latex/contrib/l3kernel/l3prefixes.pdf 2023/08/29 | 815200 | macros/latex/contrib/pdfmanagement-testphase/l3pdfmeta.pdf 2023/08/29 | 81263 | macros/latex/contrib/l3kernel/l3msg.dtx @@ -35,8 +181,8 @@ 2023/08/29 | 7412 | macros/latex/contrib/l3packages/CHANGELOG.md 2023/08/29 | 73835 | macros/latex/contrib/l3kernel/l3fp-trig.dtx 2023/08/29 | 7374 | macros/latex/contrib/l3packages/xfp.dtx +2023/08/29 | 7372 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl 2023/08/29 | 7369566 | macros/latex/contrib/l3kernel/source3.pdf -2023/08/29 | 70876 | macros/latex/contrib/jwjournal/jwjournal-demo-cn.pdf 2023/08/29 | 7079 | macros/latex/contrib/l3kernel/l3term-glossary.tex 2023/08/29 | 70679 | macros/latex/contrib/l3kernel/l3fp.dtx 2023/08/29 | 70538 | macros/latex/contrib/l3kernel/expl3.dtx @@ -56,12 +202,17 @@ 2023/08/29 | 6224 | macros/latex/contrib/l3kernel/l3.ins 2023/08/29 | 621883 | macros/latex/contrib/l3kernel/expl3.pdf 2023/08/29 | 6195 | macros/latex/contrib/l3packages/xparse-2020-10-01.sty +2023/08/29 | 6043 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/No_cc_license.tex +2023/08/29 | 6034 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees.tex +2023/08/29 | 6028 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_one_degree.tex 2023/08/29 | 59625 | macros/latex/contrib/l3packages/xparse.dtx +2023/08/29 | 5931 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_two_degrees.tex 2023/08/29 | 593117 | macros/latex/contrib/pdfmanagement-testphase/l3pdffield-radiobutton.pdf +2023/08/29 | 5926 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_one_degree.tex 2023/08/29 | 59104 | systems/texlive/tlnet/archive/penlightplus.doc.r68098.tar.xz +2023/08/29 | 5907 | macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees_from_one_department.tex 2023/08/29 | 590756 | macros/latex/contrib/pdfmanagement-testphase/ltdocinit.pdf 2023/08/29 | 588613 | macros/latex/contrib/pdfmanagement-testphase/l3pdfannot.pdf -2023/08/29 | 5740575 | systems/texlive/tlnet/install-tl-unx.tar.gz 2023/08/29 | 57404 | macros/latex/contrib/l3kernel/l3prop.dtx 2023/08/29 | 567314 | macros/latex/contrib/pdfmanagement-testphase/l3pdffile.pdf 2023/08/29 | 559157 | macros/latex/contrib/pdfmanagement-testphase/l3pdffield-action.pdf @@ -82,12 +233,8 @@ 2023/08/29 | 49600 | macros/latex/contrib/l3kernel/l3text.dtx 2023/08/29 | 4937 | macros/latex/contrib/l3kernel/l3news01.tex 2023/08/29 | 49311 | macros/latex/contrib/l3kernel/l3fp-expo.dtx -2023/08/29 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 +2023/08/29 | 490687 | macros/latex/contrib/mitthesis/examples/font_samples/Defaultfonts.pdf 2023/08/29 | 4890 | macros/latex/contrib/l3kernel/l3news.tex -2023/08/29 | 488 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc -2023/08/29 | 488 | systems/texlive/tlnet/install-tl.zip.sha512.asc -2023/08/29 | 488 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc -2023/08/29 | 488 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc 2023/08/29 | 483310 | macros/latex/contrib/l3packages/xfrac.pdf 2023/08/29 | 476 | systems/texlive/tlnet/archive/latex4wp.r68096.tar.xz 2023/08/29 | 4761 | macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.ins @@ -96,17 +243,16 @@ 2023/08/29 | 46584 | macros/latex/contrib/l3kernel/l3prefixes.csv 2023/08/29 | 464671 | macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.pdf 2023/08/29 | 460392 | systems/texlive/tlnet/archive/lwarp.source.r68097.tar.xz +2023/08/29 | 458937 | macros/latex/contrib/mitthesis/examples/font_samples/Libertine.pdf 2023/08/29 | 4574 | macros/latex/contrib/l3kernel/l3legacy.dtx 2023/08/29 | 456 | systems/texlive/tlnet/archive/collection-langarabic.r68099.tar.xz 2023/08/29 | 45420 | macros/latex/contrib/hvextern/latex/hvextern.sty 2023/08/29 | 450948 | macros/latex/contrib/l3packages/xtemplate.pdf 2023/08/29 | 440217 | macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-firstaid.pdf 2023/08/29 | 43225 | macros/latex/contrib/l3kernel/l3debug.dtx -2023/08/29 | 4300 | fonts/parsianfonts/parsianfonts-samples.tex -2023/08/29 | 428856 | systems/texlive/tlnet/archive/texlive-scripts.doc.r68095.tar.xz 2023/08/29 | 427837 | macros/latex/contrib/pdfmanagement-testphase/l3pdfxform.pdf +2023/08/29 | 41629 | macros/latex/contrib/mitthesis/mitthesis.cls 2023/08/29 | 412937 | macros/latex/contrib/l3packages/l3keys2e.pdf -2023/08/29 | 4102573 | biblio/ctan-bibdata.zip 2023/08/29 | 40728 | macros/latex/contrib/l3kernel/l3sort.dtx 2023/08/29 | 406368 | macros/latex/required/babel/base/babel.pdf 2023/08/29 | 4041 | macros/latex/contrib/pdfmanagement-testphase/l3ref-tmp.sty @@ -116,126 +262,87 @@ 2023/08/29 | 39366 | macros/latex/contrib/l3packages/xfrac.dtx 2023/08/29 | 386566 | macros/latex/contrib/pdfmanagement-testphase/output-patches-tmp-ltx.pdf 2023/08/29 | 37040 | support/texfot.zip -2023/08/29 | 3701009 | biblio/ctan-bibdata/ctan.pdf 2023/08/29 | 35894 | macros/latex/contrib/l3kernel/l3sys.dtx 2023/08/29 | 35675 | macros/latex/contrib/l3kernel/l3unicode.dtx 2023/08/29 | 35441 | macros/latex/contrib/l3kernel/l3quark.dtx -2023/08/29 | 35287 | macros/latex/contrib/jwjournal/jwjournal-demo-fr.pdf 2023/08/29 | 3526 | macros/latex/required/babel/base/bbidxglo.dtx -2023/08/29 | 347174 | fonts/parsianfonts/parsianfonts-samples.pdf -2023/08/29 | 34389 | macros/latex/contrib/jwjournal/jwjournal-demo-en.pdf 2023/08/29 | 3435473 | install/macros/latex/required/babel-base.tds.zip 2023/08/29 | 34001 | support/texfot/texfot.pdf 2023/08/29 | 33709 | macros/latex/contrib/l3kernel/l3cctab.dtx 2023/08/29 | 3333 | macros/latex/contrib/l3packages/README.md 2023/08/29 | 332628 | macros/latex/contrib/l3packages/xfp.pdf -2023/08/29 | 328704 | fonts/parsianfonts/ParsianMono/ParsianMono-Italic.ttf -2023/08/29 | 326232 | fonts/parsianfonts/ParsianMono/ParsianMono-BoldItalic.ttf 2023/08/29 | 3260656 | systems/texlive/tlnet/archive/lwarp.doc.r68097.tar.xz -2023/08/29 | 3099712 | fonts/parsianfonts.zip +2023/08/29 | 320067 | macros/latex/contrib/mitthesis/examples/font_samples/Newtx.pdf 2023/08/29 | 30678 | macros/latex/contrib/pdfmanagement-testphase/l3pdffield-radiobutton.dtx 2023/08/29 | 3058 | macros/latex/contrib/l3kernel/README.md 2023/08/29 | 305576 | macros/latex/contrib/l3kernel/l3regex.dtx 2023/08/29 | 30508 | macros/latex/contrib/l3kernel/l3intarray.dtx -2023/08/29 | 3024 | macros/latex/contrib/jwjournal/jwjournal-demo-fr.tex 2023/08/29 | 29765 | macros/latex/contrib/pdfmanagement-testphase/l3pdffile.dtx 2023/08/29 | 296645 | macros/latex/contrib/l3kernel/l3styleguide.pdf -2023/08/29 | 294088 | fonts/parsianfonts/ParsianTitle/ParsianTitle-Italic.ttf -2023/08/29 | 293892 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-BoldItalic.ttf -2023/08/29 | 291176 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Italic.ttf -2023/08/29 | 289640 | fonts/parsianfonts/ParsianMono/ParsianMono-Bold.ttf 2023/08/29 | 2882 | macros/latex/contrib/pdfmanagement-testphase/colorspace-patches-tmp-ltx.sty 2023/08/29 | 28627 | macros/latex/contrib/pdfmanagement-testphase/l3pdfannot.dtx -2023/08/29 | 284460 | fonts/parsianfonts/Parsian/Parsian-BoldItalic.ttf +2023/08/29 | 28615 | macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.tex 2023/08/29 | 2835 | macros/latex/contrib/pdfmanagement-testphase/xcolor-patches-tmp-ltx.sty 2023/08/29 | 2821 | macros/latex/contrib/l3kernel/l3prefixes.tex -2023/08/29 | 281980 | fonts/parsianfonts/Parsian/Parsian-Italic.ttf -2023/08/29 | 2806563 | biblio/ctan-bibdata/ctan.bib -2023/08/29 | 279208 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Regular.ttf -2023/08/29 | 278080 | fonts/parsianfonts/ParsianTitle/ParsianTitle-Regular.ttf -2023/08/29 | 275400 | fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Bold.ttf +2023/08/29 | 274790 | macros/latex/contrib/mitthesis/examples/font_samples/Newtx-sans-text.pdf 2023/08/29 | 27270 | macros/latex/contrib/l3kernel/l3kernel-functions.dtx 2023/08/29 | 272287 | macros/jptex/latex/pxchfon/pxchfon.pdf -2023/08/29 | 272060 | fonts/parsianfonts/Parsian/Parsian-Regular.ttf -2023/08/29 | 268772 | fonts/parsianfonts/ParsianMono/ParsianMono-Regular.ttf -2023/08/29 | 267260 | fonts/parsianfonts/Parsian/Parsian-Bold.ttf 2023/08/29 | 26550 | macros/latex/contrib/pdfmanagement-testphase/l3pdffield-action.dtx 2023/08/29 | 26540 | macros/latex/contrib/pdfmanagement-testphase/l3pdffield-pushbutton.dtx 2023/08/29 | 2640 | macros/latex/contrib/ppt-slides/ppt-slides.ins -2023/08/29 | 26028701 | systems/texlive/tlnet/install-tl.zip -2023/08/29 | 2599 | macros/latex/contrib/jwjournal/jwjournal-demo-en.tex -2023/08/29 | 253524 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-BoldItalic.ttf -2023/08/29 | 2525 | macros/latex/contrib/jwjournal/jwjournal-demo-cn.tex 2023/08/29 | 25249 | macros/latex/contrib/l3kernel/l3deprecation.dtx 2023/08/29 | 250127 | macros/latex/contrib/l3kernel/l3news09.pdf 2023/08/29 | 24792 | macros/latex/contrib/l3kernel/source3body.tex -2023/08/29 | 2464888 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz 2023/08/29 | 243279 | macros/latex/contrib/l3kernel/l3syntax-changes.pdf 2023/08/29 | 2390 | macros/latex/contrib/l3kernel/l3docstrip.dtx 2023/08/29 | 23866 | macros/latex/contrib/l3kernel/l3luatex.dtx 2023/08/29 | 23574 | macros/latex/contrib/l3kernel/l3fp-random.dtx -2023/08/29 | 234484 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Italic.ttf 2023/08/29 | 23009 | macros/latex/contrib/l3kernel/l3fp-logic.dtx -2023/08/29 | 227712 | fonts/parsianfonts/ParsianTeX/ParsianTeX-BoldItalic.ttf 2023/08/29 | 2259049 | install/macros/latex/contrib/l3packages.tds.zip 2023/08/29 | 2240059 | macros/latex/contrib/l3packages.zip 2023/08/29 | 2229 | macros/latex/contrib/l3kernel/source3.tex 2023/08/29 | 2215 | macros/latex/required/babel/base/README.md 2023/08/29 | 2210881 | macros/latex/required/babel/base.zip -2023/08/29 | 220560 | fonts/parsianfonts/ParsianTeX/ParsianTeX-Italic.ttf 2023/08/29 | 21991 | macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.dtx 2023/08/29 | 21890 | macros/latex/required/babel/base/bbcompat.dtx 2023/08/29 | 218431 | macros/latex/contrib/l3kernel/l3term-glossary.pdf 2023/08/29 | 2162 | macros/latex/contrib/hvextern/Changes -2023/08/29 | 214604 | fonts/parsianfonts/ParsianSans/ParsianSans-BoldItalic.ttf 2023/08/29 | 213032 | systems/texlive/tlnet/archive/lwarp.r68097.tar.xz -2023/08/29 | 211508 | fonts/parsianfonts/ParsianSans/ParsianSans-Italic.ttf -2023/08/29 | 21038354 | systems/texlive/tlnet/install-tl-windows.exe 2023/08/29 | 204992 | macros/latex/contrib/l3kernel/l3news12.pdf 2023/08/29 | 20464 | macros/latex/contrib/l3kernel/l3text-purify.dtx 2023/08/29 | 20430 | macros/latex/contrib/pdfmanagement-testphase/l3pdffield-choice.dtx 2023/08/29 | 2038 | macros/latex/contrib/l3kernel/interface3.tex -2023/08/29 | 201568 | fonts/parsianfonts/ParsianSans/ParsianSans-Bold.ttf -2023/08/29 | 201200 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Bold.ttf -2023/08/29 | 200500 | fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Regular.ttf -2023/08/29 | 197880 | fonts/parsianfonts/ParsianSans/ParsianSans-Regular.ttf 2023/08/29 | 19641 | macros/latex/contrib/l3kernel/l3fp-convert.dtx 2023/08/29 | 19342 | macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.dtx -2023/08/29 | 19106 | macros/latex/contrib/jwjournal/LICENSE 2023/08/29 | 18732 | macros/latex/contrib/ppt-slides/ppt-slides.dtx 2023/08/29 | 18532 | macros/latex/contrib/l3kernel/l3fp-round.dtx -2023/08/29 | 18219224 | systems/texlive/tlnet/tlpkg/texlive.tlpdb 2023/08/29 | 18170 | macros/latex/contrib/pdfmanagement-testphase/l3pdffield-checkbox.dtx -2023/08/29 | 181032 | fonts/parsianfonts/ParsianTeX/ParsianTeX-Regular.ttf 2023/08/29 | 17809 | macros/latex/contrib/l3kernel/l3pdf.dtx -2023/08/29 | 176944 | fonts/parsianfonts/ParsianTeX/ParsianTeX-Bold.ttf 2023/08/29 | 176281 | macros/latex/contrib/pdfmanagement-testphase/hyperref-generic.dtx -2023/08/29 | 1759 | fonts/parsianfonts/README.md 2023/08/29 | 17304 | macros/latex/contrib/pdfmanagement-testphase/l3pdfdict.dtx 2023/08/29 | 1722092 | macros/latex/contrib/l3kernel/interface3.pdf 2023/08/29 | 17112 | macros/latex/contrib/pdfmanagement-testphase/l3pdftools.dtx 2023/08/29 | 170069 | macros/latex/contrib/l3kernel/l3news11.pdf -2023/08/29 | 1678 | biblio/ctan-bibdata/biblatex-ctan/ctan.bbx +2023/08/29 | 169261 | macros/latex/contrib/mitthesis/examples/font_samples/Lucida.pdf 2023/08/29 | 16709 | macros/latex/contrib/l3kernel/l3candidates.dtx 2023/08/29 | 16633 | macros/latex/contrib/l3kernel/l3text-map.dtx 2023/08/29 | 16347 | support/texfot/texfot.pl 2023/08/29 | 163456 | macros/latex/contrib/l3kernel/l3news08.pdf 2023/08/29 | 1620 | macros/latex/contrib/ppt-slides/README.md +2023/08/29 | 161163 | macros/latex/contrib/mitthesis/examples/font_samples/Termes-stix2.pdf +2023/08/29 | 159311 | macros/latex/contrib/mitthesis/examples/font_samples/Stix2.pdf +2023/08/29 | 157329 | macros/latex/contrib/mitthesis/examples/font_samples/Termes.pdf 2023/08/29 | 1561 | macros/latex/contrib/l3packages/xtemplate.ins 2023/08/29 | 156194 | macros/latex/contrib/l3kernel/l3doc.dtx -2023/08/29 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512 -2023/08/29 | 153693 | macros/latex/contrib/jwjournal.zip -2023/08/29 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512 2023/08/29 | 152101 | macros/latex/contrib/l3kernel/l3docstrip.pdf 2023/08/29 | 151569 | macros/latex/contrib/l3kernel/l3news06.pdf +2023/08/29 | 151029 | macros/latex/contrib/mitthesis/examples/font_samples/Heros-Stix2.pdf 2023/08/29 | 150675 | macros/latex/contrib/l3kernel/l3news02.pdf 2023/08/29 | 150282 | macros/latex/contrib/l3kernel/l3news10.pdf 2023/08/29 | 14913 | macros/latex/contrib/l3kernel/l3news12.tex 2023/08/29 | 148704 | macros/latex/contrib/l3kernel/l3news03.pdf 2023/08/29 | 1484026 | macros/latex/contrib/hvextern/doc/hvextern.pdf -2023/08/29 | 145 | systems/texlive/tlnet/install-tl.zip.sha512 2023/08/29 | 145905 | macros/latex/contrib/l3kernel/l3tl.dtx -2023/08/29 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 2023/08/29 | 1444 | macros/latex/contrib/l3packages/l3keys2e-demo.tex 2023/08/29 | 1420 | macros/latex/contrib/ppt-slides/ppt-schemes/ppt-light.tex 2023/08/29 | 1420 | macros/latex/contrib/ppt-slides/ppt-schemes/ppt-light-mono.tex @@ -249,7 +356,6 @@ 2023/08/29 | 13309 | macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-firstaid.dtx 2023/08/29 | 131482 | macros/latex/contrib/l3kernel/l3basics.dtx 2023/08/29 | 1306 | macros/latex/contrib/l3packages/xfrac.ins -2023/08/29 | 12 | macros/latex/contrib/jwjournal/DEPENDS.txt 2023/08/29 | 1290324 | systems/texlive/tlnet/archive/latex4wp.doc.r68096.tar.xz 2023/08/29 | 128317 | macros/latex/contrib/l3kernel/l3news07.pdf 2023/08/29 | 12806 | macros/latex/contrib/l3kernel/l3bootstrap.dtx @@ -265,13 +371,21 @@ 2023/08/29 | 119072 | macros/latex/contrib/l3kernel/l3token.dtx 2023/08/29 | 11884 | macros/latex/contrib/l3kernel/l3styleguide.tex 2023/08/29 | 11781 | macros/latex/contrib/l3kernel/l3fparray.dtx +2023/08/29 | 11676 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx-sans-text.tex +2023/08/29 | 11673 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes-stix2.tex +2023/08/29 | 11673 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Fira_Newtxsf.tex +2023/08/29 | 11672 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Heros-Stix2.tex +2023/08/29 | 11670 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Libertine.tex +2023/08/29 | 11667 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes.tex +2023/08/29 | 11667 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Lucida.tex +2023/08/29 | 11666 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Stix2.tex +2023/08/29 | 11666 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx.tex +2023/08/29 | 11660 | macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Defaultfonts.tex 2023/08/29 | 114591 | macros/latex/contrib/l3kernel/l3news04.pdf -2023/08/29 | 114116 | systems/texlive/tlnet/archive/texlive-scripts.r68095.tar.xz 2023/08/29 | 11391006 | macros/latex/contrib/pdfmanagement-testphase.zip 2023/08/29 | 113435 | macros/latex/contrib/l3kernel/l3str-convert.dtx 2023/08/29 | 112487 | macros/latex/contrib/l3kernel/l3news05.pdf 2023/08/29 | 112274 | macros/latex/contrib/l3kernel/l3color.dtx -2023/08/29 | 10972 | macros/latex/contrib/jwjournal/jwjournal.cls 2023/08/29 | 1078 | macros/latex/contrib/ppt-slides/LICENSE.txt 2023/08/29 | 107383 | macros/latex/contrib/l3kernel/l3news09.tex 2023/08/29 | 105012 | macros/latex/contrib/l3kernel/l3fp-parse.dtx @@ -279,7 +393,6 @@ 2023/08/29 | 1019225 | macros/latex/contrib/ppt-slides.zip 2023/08/29 | 101005 | macros/latex/contrib/l3packages/xtemplate.dtx 2023/08/28 | 940 | macros/latex/contrib/schooldocs/README.md -2023/08/28 | 91232 | systems/texlive/tlnet/archive/jwjournal.doc.r68088.tar.xz 2023/08/28 | 89 | macros/latex/contrib/lwarp/lwarp_baseline_marker.png 2023/08/28 | 751 | info/latex4wp/HOW-TO-TYPESET 2023/08/28 | 719 | macros/latex/contrib/lwarp/lwarp_baseline_marker.eps @@ -300,7 +413,6 @@ 2023/08/28 | 2947 | macros/latex/contrib/lwarp/lwarp_tutorial.txt 2023/08/28 | 2854154 | macros/latex/contrib/lwarp/lwarp.dtx 2023/08/28 | 275488 | systems/texlive/tlnet/archive/niceframe-type1.r68091.tar.xz -2023/08/28 | 2668 | systems/texlive/tlnet/archive/jwjournal.r68088.tar.xz 2023/08/28 | 246932 | indexing/makeindexk.zip 2023/08/28 | 2200 | systems/texlive/tlnet/archive/creationboites.r68087.tar.xz 2023/08/28 | 1997 | macros/latex/contrib/schooldocs/schooldocs.ins @@ -324,7 +436,6 @@ 2023/08/27 | 75740 | systems/texlive/tlnet/archive/xepersian.source.r68076.tar.xz 2023/08/27 | 7479 | macros/jptex/latex/pxchfon/README.md 2023/08/27 | 7332 | macros/latex/contrib/proflycee/tex/ProfLycee.sty -2023/08/27 | 7312 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl 2023/08/27 | 7025 | macros/latex/contrib/proflycee/tex/proflycee-tools-piton.tex 2023/08/27 | 6792716 | systems/texlive/tlnet/archive/newtx.r68071.tar.xz 2023/08/27 | 6665 | macros/latex/contrib/proflycee/doc/ProfLycee-exemples-pyluatex.tex @@ -357,6 +468,7 @@ 2023/08/27 | 13286 | fonts/utilities/ps2pk/ChangeLog 2023/08/27 | 11899 | macros/jptex/latex/pxchfon/README-ja.md 2023/08/27 | 116557832 | macros/context/latest/cont-tmf.zip +2023/08/27 | 1161 | macros/latex/contrib/mitthesis/MIT-thesis-template/abstract.tex 2023/08/27 | 11611 | macros/luatex/generic/penlightplus/penlightplus.tex 2023/08/27 | 1132 | macros/luatex/generic/penlightplus/README.md 2023/08/27 | 1117812 | systems/texlive/tlnet/archive/teubner.doc.r68074.tar.xz @@ -365,49 +477,34 @@ 2023/08/27 | 1020040 | systems/texlive/tlnet/archive/xepersian.doc.r68076.tar.xz 2023/08/26 | 906615 | macros/luatex/latex/piton.zip 2023/08/26 | 881931 | macros/luatex/latex/piton/piton.pdf -2023/08/26 | 8312 | systems/texlive/tlnet/archive/hvextern.r68056.tar.xz -2023/08/26 | 784492 | macros/xetex/latex/xepersian/xepersian.pdf 2023/08/26 | 76979 | macros/luatex/latex/piton/piton-french.tex -2023/08/26 | 71387 | macros/xetex/latex/xepersian/xepersian-doc-basics.ltx 2023/08/26 | 617 | info/xetexref/Makefile 2023/08/26 | 582032 | systems/texlive/tlnet/archive/evangelion-jfm.doc.r68059.tar.xz 2023/08/26 | 5758284 | systems/texlive/tlnet/archive/bib2gls.doc.r68060.tar.xz 2023/08/26 | 560 | systems/texlive/tlnet/archive/antique-spanish-units.r68055.tar.xz -2023/08/26 | 5447 | macros/xetex/latex/xepersian/xepersian-doc-envcs.ltx 2023/08/26 | 5087915 | fonts/newpx.zip 2023/08/26 | 5066232 | macros/luatex/latex/novel.zip 2023/08/26 | 45605 | fonts/newtx/README -2023/08/26 | 454 | macros/xetex/latex/xepersian/xepersian-doc.ltx 2023/08/26 | 4154 | macros/latex/contrib/creationboites/tex/CreationBoites.sty -2023/08/26 | 4149 | macros/xetex/latex/xepersian/xepersian-doc-preamble.ltx -2023/08/26 | 410 | macros/xetex/latex/xepersian/xepersian-doc-boolean.ltx -2023/08/26 | 38725 | macros/xetex/latex/xepersian/ftxe-0.12.py 2023/08/26 | 369685 | macros/luatex/latex/piton/piton-french.pdf -2023/08/26 | 346697 | macros/xetex/latex/xepersian/xepersian.dtx 2023/08/26 | 3460 | systems/texlive/tlnet/archive/evangelion-jfm.r68059.tar.xz 2023/08/26 | 3324 | fonts/newpx/tfm/zplbmi1.tfm 2023/08/26 | 3320 | fonts/newpx/tfm/zplbmi.tfm 2023/08/26 | 33028 | systems/texlive/tlnet/archive/photobook.r68057.tar.xz 2023/08/26 | 3260 | fonts/newpx/tfm/zplmi.tfm 2023/08/26 | 3256 | fonts/newpx/tfm/zplmi1.tfm -2023/08/26 | 3099 | macros/xetex/latex/xepersian/xepersian-doc-captions.ltx 2023/08/26 | 2668 | fonts/newpx/vf/zplbmi.vf 2023/08/26 | 2668 | fonts/newpx/vf/zplbmi1.vf -2023/08/26 | 2609 | macros/xetex/latex/xepersian/xepersian-doc-intro.ltx -2023/08/26 | 25876 | macros/xetex/latex/xepersian/xepersian-doc-pkgs.ltx 2023/08/26 | 258126 | macros/latex/contrib/exesheet.zip 2023/08/26 | 2556 | fonts/newpx/vf/zplmi.vf 2023/08/26 | 2552 | fonts/newpx/vf/zplmi1.vf -2023/08/26 | 243977 | macros/xetex/latex/xepersian/xepersian-doc.pdf 2023/08/26 | 22964 | fonts/newpx/README 2023/08/26 | 2288 | fonts/newpx/tfm/zplbmia.tfm 2023/08/26 | 2220 | fonts/newpx/tfm/zplmia.tfm 2023/08/26 | 219369 | macros/luatex/latex/piton/piton.dtx 2023/08/26 | 211872 | systems/texlive/tlnet/archive/antique-spanish-units.doc.r68055.tar.xz -2023/08/26 | 2108 | macros/xetex/latex/xepersian/xepersian-doc-title.ltx 2023/08/26 | 1907100 | systems/texlive/tlnet/archive/bib2gls.r68060.tar.xz 2023/08/26 | 18801 | macros/latex/contrib/creationboites/doc/CreationBoites-doc.tex -2023/08/26 | 18304 | macros/xetex/latex/xepersian/img/ireland.jpg 2023/08/26 | 1799016 | systems/texlive/tlnet/archive/bib2gls.source.r68060.tar.xz 2023/08/26 | 1760 | fonts/newpx/vf/zplbmia.vf 2023/08/26 | 1748 | fonts/newpx/vf/zplmia.vf @@ -417,24 +514,14 @@ 2023/08/26 | 163490 | info/xetexref.zip 2023/08/26 | 160811 | macros/latex/contrib/creationboites.zip 2023/08/26 | 1600 | fonts/newpx/tfm/zplbsym.tfm -2023/08/26 | 15976 | macros/xetex/latex/xepersian/dkun-0.3.py -2023/08/26 | 15867 | macros/xetex/latex/xepersian/dkun-0.4.py 2023/08/26 | 158107 | macros/latex/contrib/creationboites/doc/CreationBoites-doc.pdf 2023/08/26 | 1572 | fonts/newtx/tfm/ntxbsym.tfm 2023/08/26 | 1572 | fonts/newpx/tfm/zplsym.tfm 2023/08/26 | 1560 | fonts/newtx/tfm/ntxsym.tfm 2023/08/26 | 155292 | systems/texlive/tlnet/archive/photobook.doc.r68057.tar.xz 2023/08/26 | 1495202 | macros/luatex/latex/novel/doc/extras/novel-scripts.zip -2023/08/26 | 14616 | macros/xetex/latex/xepersian/img/weather/rain.jpg -2023/08/26 | 1390 | macros/xetex/latex/xepersian/README -2023/08/26 | 13804 | macros/xetex/latex/xepersian/undk-0.6.py -2023/08/26 | 13088 | macros/xetex/latex/xepersian/img/weather/clouds.jpg -2023/08/26 | 1305051 | install/macros/xetex/latex/xepersian.tds.zip -2023/08/26 | 12348 | macros/xetex/latex/xepersian/unldk-0.2.py 2023/08/26 | 1166577 | macros/latex/contrib/teubner.zip -2023/08/26 | 1139332 | macros/xetex/latex/xepersian.zip -2023/08/26 | 1131856 | systems/texlive/tlnet/archive/hvextern.doc.r68056.tar.xz -2023/08/26 | 10896 | macros/xetex/latex/xepersian/img/weather/sun.jpg +2023/08/26 | 11511 | macros/latex/contrib/mitthesis/MIT-thesis-template/mitthesis-sample.bib 2023/08/26 | 10629314 | fonts/newtx.zip 2023/08/26 | 1008 | systems/texlive/tlnet/archive/collection-luatex.r68053.tar.xz 2023/08/25 | 9856 | macros/luatex/latex/novel/doc/html-resources/graytext.png @@ -457,6 +544,7 @@ 2023/08/25 | 8187 | macros/luatex/latex/novel/doc/html-resources/headfont-default.png 2023/08/25 | 8144 | macros/luatex/latex/novel/doc/html-resources/fpaper.png 2023/08/25 | 80977 | macros/luatex/latex/novel/doc/html-resources/novel-color-sampler.png +2023/08/25 | 7973 | macros/latex/contrib/mitthesis/MIT-thesis-template/chapter1.tex 2023/08/25 | 7940 | macros/luatex/latex/novel/doc/html-resources/headfont-roboto.png 2023/08/25 | 7616 | macros/luatex/latex/novel/doc/html-resources/Iboxcap.png 2023/08/25 | 7562 | macros/luatex/latex/novel/lualatex/novel-DropCap.sty @@ -792,51 +880,3 @@ 2023/08/24 | 10389 | macros/latex/contrib/photobook/Makefile 2023/08/24 | 103396 | macros/latex/contrib/siunitx/siunitx-unit.dtx 2023/08/24 | 1031 | support/bib2gls/examples/baseunits.bib -2023/08/23 | 92866 | macros/generic/expex-acro.zip -2023/08/23 | 88970 | macros/generic/expex-acro/expex-acro.pdf -2023/08/23 | 876764 | systems/texlive/tlnet/archive/mathfont.doc.r68018.tar.xz -2023/08/23 | 851616 | systems/texlive/tlnet/archive/verifiche.doc.r68023.tar.xz -2023/08/23 | 7624 | systems/texlive/tlnet/archive/numerica-tables.r68020.tar.xz -2023/08/23 | 745 | dviware/dviasm/README -2023/08/23 | 6576 | macros/luatex/latex/luamaths/luamaths-fractions.lua -2023/08/23 | 628988 | systems/texlive/tlnet/archive/numerica-tables.doc.r68020.tar.xz -2023/08/23 | 62576 | systems/texlive/tlnet/archive/mathfont.source.r68018.tar.xz -2023/08/23 | 606932 | systems/texlive/tlnet/archive/numerica-plus.doc.r68019.tar.xz -2023/08/23 | 6052 | systems/texlive/tlnet/archive/numerica-plus.r68019.tar.xz -2023/08/23 | 5740 | dviware/dvidvi/ChangeLog -2023/08/23 | 567192 | systems/texlive/tlnet/archive/xstring.doc.r68015.tar.xz -2023/08/23 | 55881 | graphics/pgf/contrib/profsio/doc/ProfSio-doc-fr.tex -2023/08/23 | 5336 | systems/texlive/tlnet/archive/verifiche.r68023.tar.xz -2023/08/23 | 466 | macros/generic/expex-acro/README.md -2023/08/23 | 44625 | graphics/pgf/contrib/profsio/tex/ProfSio.sty -2023/08/23 | 44570 | dviware/dviasm/dviasm.py -2023/08/23 | 43999 | macros/luatex/latex/lualinalg/lualinalg.tex -2023/08/23 | 4348 | dviware/dviasm/dviasm.1 -2023/08/23 | 427424 | systems/texlive/tlnet/archive/notomath.doc.r68014.tar.xz -2023/08/23 | 400176 | systems/texlive/tlnet/archive/babel-hebrew.doc.r68016.tar.xz -2023/08/23 | 38363 | macros/luatex/latex/lualinalg/lualinalg.sty -2023/08/23 | 36792 | macros/generic/expex-acro/expex-acro.dtx -2023/08/23 | 324818 | graphics/pgf/contrib/profsio.zip -2023/08/23 | 31404 | systems/texlive/tlnet/archive/babel-hebrew.source.r68016.tar.xz -2023/08/23 | 312717 | graphics/pgf/contrib/profsio/doc/ProfSio-doc-fr.pdf -2023/08/23 | 269684 | macros/luatex/latex/lualinalg/lualinalg.pdf -2023/08/23 | 221470 | systems/texlive/tlnet/tlpkg/installer/curl/curl-ca-bundle.crt -2023/08/23 | 2182 | macros/luatex/latex/luamaths/luamaths.sty -2023/08/23 | 21460 | systems/texlive/tlnet/archive/mathfont.r68018.tar.xz -2023/08/23 | 213708 | systems/texlive/tlnet/archive/notomath.r68014.tar.xz -2023/08/23 | 212308 | macros/luatex/latex/lualinalg.zip -2023/08/23 | 21096 | systems/texlive/tlnet/archive/numerica.r68021.tar.xz -2023/08/23 | 21096 | systems/texlive/tlnet/archive/bibtexperllibs.r68024.tar.xz -2023/08/23 | 2090 | macros/luatex/latex/lualinalg/README.txt -2023/08/23 | 18680 | systems/texlive/tlnet/archive/verifiche.source.r68023.tar.xz -2023/08/23 | 1794 | macros/generic/expex-acro/expex-acro.ins -2023/08/23 | 146829 | macros/luatex/latex/luamaths/luamaths.pdf -2023/08/23 | 14005 | dviware/dviasm.zip -2023/08/23 | 139376 | systems/texlive/tlnet/archive/bibtexperllibs.source.r68024.tar.xz -2023/08/23 | 13787 | macros/luatex/latex/luamaths/luamaths.tex -2023/08/23 | 121419 | macros/luatex/latex/luamaths.zip -2023/08/23 | 12044 | systems/texlive/tlnet/archive/babel-hebrew.r68016.tar.xz -2023/08/23 | 11536 | systems/texlive/tlnet/archive/xstring.r68015.tar.xz -2023/08/23 | 1127 | dviware/dvidvi/dvidvi.test -2023/08/23 | 1124712 | systems/texlive/tlnet/archive/numerica.doc.r68021.tar.xz -2023/08/23 | 1047 | macros/luatex/latex/luamaths/README.txt diff --git a/biblio/bibtex/bibtex-x/ChangeLog b/biblio/bibtex/bibtex-x/ChangeLog index f881b19602..d9e4e352ca 100644 --- a/biblio/bibtex/bibtex-x/ChangeLog +++ b/biblio/bibtex/bibtex-x/ChangeLog @@ -1,3 +1,8 @@ +2023-08-30 TANAKA Takuji + + * tests/{bibtex8u-mem,bibtexu-char}.test: + Tweak for portability. + 2023-08-20 TANAKA Takuji * bibtex.c, sysdep.h: Avoid compiler warnings on Windows. diff --git a/biblio/bibtex/bibtex-x/tests/bibtex8u-mem.test b/biblio/bibtex/bibtex-x/tests/bibtex8u-mem.test index 4e936537a8..91eedf7b2d 100755 --- a/biblio/bibtex/bibtex-x/tests/bibtex8u-mem.test +++ b/biblio/bibtex/bibtex-x/tests/bibtex8u-mem.test @@ -69,14 +69,14 @@ for t in 1 2 3; do TEXMFCNF=$srcdir/../kpathsea \ BSTINPUTS=$srcdir/../web2c/tests'\;'$srcdir/csf \ BIBINPUTS=./tests \ - $_bibtex8 -s tests/memtest$t || exit $((10 + t)) + $_bibtex8 -s tests/memtest$t || exit `expr 10 + $t` cp -p tests/memtest$t.aux tests/memtestu$t.aux eval $env \ TEXMFCNF=$srcdir/../kpathsea \ BSTINPUTS=$srcdir/../web2c/tests \ BIBINPUTS=./tests \ - $_bibtexu -s tests/memtestu$t || exit $((20 + t)) + $_bibtexu -s tests/memtestu$t || exit `expr 20 + $t` done diff --git a/biblio/bibtex/bibtex-x/tests/bibtexu-char.test b/biblio/bibtex/bibtex-x/tests/bibtexu-char.test index db392b9799..e4250d02ef 100755 --- a/biblio/bibtex/bibtex-x/tests/bibtexu-char.test +++ b/biblio/bibtex/bibtex-x/tests/bibtexu-char.test @@ -1,5 +1,5 @@ #! /bin/sh -vx -# $Id: bibtexu-char.test 67915 2023-08-13 13:51:40Z takuji $ +# $Id: bibtexu-char.test 68115 2023-08-30 11:16:53Z takuji $ # Copyright 2022-2023 TANAKA Takuji # You may freely use, modify and/or distribute this file. @@ -19,7 +19,7 @@ BIBINPUTS=$srcdir/tests; export BIBINPUTS rc=0 -if [ "$(expr substr $(uname -s) 1 5)" == "MINGW" ]; then +if [ "$(expr substr $(uname -s) 1 5)" = "MINGW" ]; then echo "*** skip test $0 on MinGW" exit 77 fi diff --git a/biblio/ctan-bibdata/ctan.bib b/biblio/ctan-bibdata/ctan.bib index c0c9d755d1..773532576c 100644 --- a/biblio/ctan-bibdata/ctan.bib +++ b/biblio/ctan-bibdata/ctan.bib @@ -1,7 +1,7 @@ %% bib file of all CTAN packages %% (C) Herbert Voß %% -%% created at 30-08-2023, 02:00:50 +%% created at 31-08-2023, 02:06:01 %% %% This file is provided under the terms of the LPPL v1.3 or @@ -31895,8 +31895,8 @@ title = {The \texttt{hobby} package}, subtitle = {An implementation of Hobby’s algorithm for PGF/TikZ}, author = {Andrew Stacey}, - date = {2017-06-01}, - version = {1.8}, + date = {2023-08-30}, + version = {1.10}, license = {lppl1.3}, mirror = {https://mirror.ctan.org/graphics/pgf/contrib/hobby}, url = {https://ctan.org/pkg/hobby}, @@ -35630,7 +35630,7 @@ title = {The \texttt{jwjournal} package}, subtitle = {A personal class for writing journals}, author = {Jinwen XU}, - date = {2023-08-29}, + date = {2023-08-30}, version = {}, license = {lppl1.3c}, mirror = {https://mirror.ctan.org/macros/latex/contrib/jwjournal}, @@ -43249,8 +43249,8 @@ title = {The \texttt{mathastext} package}, subtitle = {Use the text font in maths mode}, author = {Jean-François Burnol}, - date = {2022-11-04}, - version = {1.3y}, + date = {2023-08-30}, + version = {1.3z}, license = {lppl1.3}, mirror = {https://mirror.ctan.org/macros/latex/contrib/mathastext}, url = {https://ctan.org/pkg/mathastext}, @@ -44664,6 +44664,17 @@ url = {https://ctan.org/pkg/metrix}, } +@manual{ctan-metsymb, + title = {The \texttt{metsymb} package}, + subtitle = {The package provides dedicated \TeX{} commands to generate (vectorial) meteorological symbols}, + author = {Frédéric P.A. Vogt}, + date = {2023-08-30}, + version = {1.2.0}, + license = {bsd3}, + mirror = {https://mirror.ctan.org/fonts/metsymb}, + url = {https://ctan.org/pkg/metsymb}, +} + @manual{ctan-mewltx, title = {The \texttt{mewltx} package}, subtitle = {MicroEmacs for Windows \LaTeX{} interface}, @@ -45570,8 +45581,8 @@ title = {The \texttt{mitthesis} package}, subtitle = {A \LaTeX{} template for MIT theses}, author = {John H. Lienhard}, - date = {2023-07-22}, - version = {1.05}, + date = {2023-08-30}, + version = {1.06}, license = {mit}, mirror = {https://mirror.ctan.org/macros/latex/contrib/mitthesis}, url = {https://ctan.org/pkg/mitthesis}, @@ -51174,8 +51185,8 @@ title = {The \texttt{parsianfonts} package}, subtitle = {Some of the most used fonts among Persian language users}, author = {Sajad Kazemi}, - date = {2023-08-29}, - version = {1.0.2}, + date = {2023-08-30}, + version = {1.0.3}, license = {lppl1.3c}, mirror = {https://mirror.ctan.org/fonts/parsianfonts}, url = {https://ctan.org/pkg/parsianfonts}, @@ -76830,8 +76841,8 @@ title = {The \texttt{XePersian} package}, subtitle = {Persian for \LaTeX{}, using XeTeX}, author = {Vafa Khalighi and {bidi-tex GitHub Organisation}}, - date = {2023-08-26}, - version = {24.9}, + date = {2023-08-30}, + version = {25.0}, license = {lppl1.3c}, mirror = {https://mirror.ctan.org/macros/xetex/latex/xepersian}, url = {https://ctan.org/pkg/xepersian}, diff --git a/biblio/ctan-bibdata/ctan.pdf b/biblio/ctan-bibdata/ctan.pdf index 0d18b37e75..3c88246ee4 100644 Binary files a/biblio/ctan-bibdata/ctan.pdf and b/biblio/ctan-bibdata/ctan.pdf differ diff --git a/fonts/metsymb/AUTHORS b/fonts/metsymb/AUTHORS new file mode 100644 index 0000000000..dc0bdc9b27 --- /dev/null +++ b/fonts/metsymb/AUTHORS @@ -0,0 +1 @@ +Original author: Frédéric P.A. Vogt, frederic.vogt@meteoswiss.ch \ No newline at end of file diff --git a/fonts/metsymb/CHANGELOG b/fonts/metsymb/CHANGELOG new file mode 100644 index 0000000000..a7d5a31d8c --- /dev/null +++ b/fonts/metsymb/CHANGELOG @@ -0,0 +1,27 @@ +All notable changes to metsymb will be documented in this file. + +The format is inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +## [v1.2.0] +### Added: + - [fpavogt, 2022-10-07] Added first design of Cl, Cm, Ch cloud symbols. + - [fpavogt, 2022-10-07] Prepare the CTAN release (+ .gitattributes, doc cleanup) +### Fixed: +### Changed: + - [fpavogt, 2022-10-10] Small modifications of the cloud genera symbols to match the cl-cm-ch design (radius, slope). +### Deprecated: +### Removed: +### Security: + +## [v1.1.0] +### Added: + - [fpavogt, 2022-09-10] Added dedicated (and unique) CHANGELOG. +### Changed: + - [fpavogt, 2022-09-10] Moved glyph design from Fontforge to LaTeX/TikZ. + - [fpavogt, 2022-09-10] Cleaned-up the documentation. + +## [v1.0.0] +### Added: + - [fpavogt, 2021-08-26] Initial version, with symbols of oktas and cloud genera. diff --git a/fonts/metsymb/CODE_OF_CONDUCT.md b/fonts/metsymb/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..b1544d8723 --- /dev/null +++ b/fonts/metsymb/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at frederic.vogt@meteoswiss.ch. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/fonts/metsymb/CONTRIBUTING.md b/fonts/metsymb/CONTRIBUTING.md new file mode 100644 index 0000000000..04a87a2ed5 --- /dev/null +++ b/fonts/metsymb/CONTRIBUTING.md @@ -0,0 +1,182 @@ +# Contributing guidelines + +## Table of contents + +- [Code of conduct](#code-of-conduct) +- [Scope](#essential-things-to-know-about-metsymb) +- [Package content](#package-content) +- [Contributing new symbols](#contributing-new-symbols) +- [Updating the metsymb font (maintainers)](#updating-the-metsymb-font) +- [Releasing new symbols (maintainers)](#releasing-new-symbols) + + +## Code of conduct +This project and everyone participating in it is governed by the [metsymb Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [frederic.vogt@meteoswiss.ch](mailto:frederic.vogt@meteoswiss.ch). + + +## Scope + +metsymb is being developed inside a dedicated [Github repository](https://github.io/MeteoSwiss/metsymb) under the [MeteoSwiss organization](https://github.io/MeteoSwiss). + +User contributions are welcome and will be examined in details. So are bug reports and suggestions for new symbols, which are **best submitted as [Github Issues](https://github.com/MeteoSwiss/metsymb/issues)**. + +metsymb is meant to ease the access to vectorial definitions of meteorological symbols used by scientists and engineers. In order to be included in metsymb, symbols should be: + * formally defined and/or approved by a renowned scientific authority, such as the World Meteorological Organization, + * used and recognized internationally, and + * regularly employed in a professional context. + +A [dedicated Github issue template](https://github.com/MeteoSwiss/metsymb/blob/develop_vof/.github/ISSUE_TEMPLATE/symbol_suggestion.md) was created to make sure [new symbol requests](https://github.com/MeteoSwiss/metsymb/issues?q=is%3Aissue+%5BSYMB%5D+) are properly motivated. + + +## Package content + +What follows is a (brief) description of the more "exotic" files included in the metsymb repo: + - `.github/`: contains all the Github-related magic, including custom issue templates, custom + pull-request templates, and specific Actions for CI/CD purposes. + + - `source/`: contains the actual metsymb TeX package files. These include: + * `manual_install.sh`: a crude, basic, absolutely-not-to-be-trusted bash script to automate the manual installation of the metsymb TeX package. + * `metsymb.sfd`: the FontForge save file, used to assign glyphs to characters of the metsymb font. + * `metsymb.afm`, `metsymb.enc`, `metsymb.pfb`, `metsymb.tfm`, and `metsymb.otf`: the different font files required by LaTeX, generated using FontForge. + * `umetsymb.fd`, `metsymb.map`, `metsymb.ins`, `metsymb.dtx`: the actual LaTeX package files. + * `metsymb_mwe.py`, and `metsymb_mwe.mplstyle`: demo files to illustrate the use of metsymb with `matpolotlib`. With metsymb successfully installed, running `metsymb_mwe.py` will generate + `metsymb_mwe.png` and `metsymb_mwe.pdf`. + * `metsymb.pdf`: the compiled documentation of the metsymb TeX package. + * `testfont.pdf`: the metsymb font table (see below). + + - `tickz_glyphs/`: contains all the individual TikZ reference codes for the metsymb glyphs. Each + glyph is designed inside a dedited `.tex` file, which gets compiled in a matching `.pdf` file. + The latter is then converted manually (see below) to a matching `.svg` file, that is used to load + the symbol inside FontForge. + + - `.gitattributes`: fine-tunes which files get included in the Github releases' `.zip`, to ensure these are CTAN-ready. + + +## Contributing new symbols +The addition of new symbols (or the modification of existing ones) is a three phase process: + * Creation/modification of the symbol in a stand-alone, custom, LaTeX document using TikZ syntax. + * Inclusion into the metsymb OpenType font via FontForge. + * Creation of dedicated LaTeX commands in the metsymb package. + +The first step is the hardest one, but also the one where user contributions are the easiest. Here is a detailed walkthrough of what it entails: + +0. Fork the metsymb Github repository. + +1. [For a new symbol] Create a file `symbol_name.tex` by copying [`tikz_glyphs/blank/blank.tex`](https://github.com/MeteoSwiss/metsymb/tree/master/tikz_glyphs/blank/blank.tex). + +2. Use [TikZ commands](https://en.wikipedia.org/wiki/PGF/TikZ) to draw the new symbol. This is the hardest part ! Use custom styles with parsimony. If warranted, new styles should be defined in [`ref_styles.tex`](https://github.com/MeteoSwiss/metsymb/tree/master/tikz_glyphs/ref_styles.tex), in order to make them available to all other symbols, and ease the maintenance of the package. + +3. Compile `symbol_name.tex`: + ``` + pdflatex symbol_name.tex + ``` + +4. Convert the resulting PDF to SVG: + ``` + pdf2svg symbol_name.pdf symbol_name.svg + ``` + +5. Submit a Pull Request (that should include `symbol_name.tex`, `symbol_name.pdf`, and `symbol_name.svg`) against the develop branch of the repo. + + +Once a Pull Request is issued, the metsymb devs will be notified automatically. + + +## Updating the metsymb font + +When a new set of symbols has been assembled, the package maintainers will need to include them in the OpenType metsymb font, and tie them to shortcuts in the metsymb LaTeX package. Here's a step-by-step walkthrough of these tasks: + + +1. Modify `metsymb.sfd` directly with FontForge. + + 1.0. Choose a new/existing glyph, and open the corresponding editor. + + 1.1. Import the SVG file of the symbol generated using LaTeX/TikZ. Under `Options`, ensure that + `Scale to Fit` is selected. + + 1.2. Cleanup the glyph via `Element -> Overlap -> Remove Overlap` (after selecting all nodes). + :warning: If certain elements are "white", their order must first be reversed via `Element -> Reverse Order`. + + 1.3. Check the glyph validity via `Elements -> Find Problems ...`. Make sure to tick the box `Paths -> Intersecting paths & Check missing extrema`. + + 1.4. Repeat steps 1.1 to 1.3 for each new/updated glyph. + + 1.5. Update the font version under `Element -> Font info -> PS Names`. + + 1.6. Keep the encoding to `TeX Base (8r)` under `Encoding -> Reencode`. + +2. Create the `.tfm`, `.enc`, `.pfb`, `.asm` files by exporting the font via `File -> Generate Fonts ... -> PS Type1 (Binary)` with `Options -> Output TFM & ENC`. + +3. Create the `.otf` file by exporting the font via `File -> Generate Fonts... -> OpenType (CFF)` + +4. Update `metsymb.dtx`: + + 4.1. For new symbols, add new macros under the *Implementation* section. + + 4.2. For new symbols, add a dedicated table under the *Usage* section. + + 4.3. For new symbols, update the abstract. + + 4.4. Adjust the version in `metsymb.dtx` around l.19. + +5. Run `latex metsymb.ins`. + +6. Copy the following files in the appropriate location of your Tex-tree, in my case (OS X 10.15): + ``` + cp metsymb.tfm /usr/local/texlive/2020/texmf-dist/fonts/tfm/public/metsymb/ + cp metsymb.afm /usr/local/texlive/2020/texmf-dist/fonts/afm/public/metsymb/ + cp metsymb.pfb /usr/local/texlive/2020/texmf-dist/fonts/type1/public/metsymb/ + cp metsymb.otf /usr/local/texlive/2020/texmf-dist/fonts/opentype/public/metsymb/ + cp umetsymb.fd /usr/local/texlive/2020/texmf-dist/tex/latex/metsymb/ + cp metsymb.sty /usr/local/texlive/2020/texmf-dist/tex/latex/metsymb/ + cp metsymb.map /usr/local/texlive/2020/texmf-dist/fonts/map/dvips/metsymb/ + cp metsymb.enc /usr/local/texlive/2020/texmf-dist/fonts/enc/dvips/metsymb/ + ``` + +7. Tell TeX about these new files: + ``` + sudo mktexlsr + sudo updmap-sys --enable Map metsymb.map + sudo updmap-sys + ``` + +8. Create the font table: + ``` + pdftex testfont + ``` + When prompted for the font name, type `metsymb`, then request a `\sample`, and `\bye`. + +9. Run the Python example via `python metsymb_mwe.py`. + +10. Generate the pdf of the documentation via `pdflatex metsymb.dtx`, and check it carefully. + + :warning: when adding new symbols, the checksum will likely need to be adjusted in `metsymb.dtx`. This value corresponds to the number of `\` in the code. If/when things blow up in your face when compiling the `.dtx` file, just update the checksum value with the one in the error message. + +:wave: The bash file `manual_install.sh` can be used to automate steps 5-10 with the command `sh manual_install.sh`. **Mind the TeX-tree paths in there, that will most certainly need to be adjusted to your needs !** + + +## Releasing new symbols + +It is unlikely that metsymb will be subject to a regular release cycle. +As a consequence, the release procedure is --for now at least-- rather manual (:scream:). +Here are the steps to follow, should a new release be warranted: + +1. If warranted, update the copyright years in the following files: + + README, LICENSE, metsymb.ins, metsymb.dtx, and metsymb.sfd (via FontForge) + + :warning: Mind the multiple copyright entries in some of these files ! + +2. Follow all the steps of the previous Section to update all files. + +3. If warranted, update the list of authors in `AUTHORS`. + +4. Update the CHANGELOG. + +5. Issue a Pull Request on Github onto the `master` branch, that will be reviewed by the metsymb devs. + + :warning: Direct commits to `master` are forbidden ! + +6. Once all has been reviewed and merged, create a new release on Github. + +7. Upload the release's `.zip` onto CTAN. diff --git a/fonts/metsymb/LICENSE b/fonts/metsymb/LICENSE new file mode 100644 index 0000000000..a3409c87f8 --- /dev/null +++ b/fonts/metsymb/LICENSE @@ -0,0 +1,11 @@ +Copyright 2021-2023 MeteoSwiss, contributors listed under AUTHORS + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/fonts/metsymb/README.md b/fonts/metsymb/README.md new file mode 100644 index 0000000000..4feae5bf61 --- /dev/null +++ b/fonts/metsymb/README.md @@ -0,0 +1,104 @@ +# metsymb + +metsymb is a **LaTeX package** that introduces vectorial definitions of professional meteorological symbols. Individual symbols are first designed using [TikZ](https://www.ctan.org/pkg/pgf). They are then bundled into a dedicated font with [FontForge](https://fontforge.org/en-US/), and eventually tied to dedicted LaTeX commands. The metsymb **OpenType font** is a side-product that can be used on its own. + +This README contains information about the metsymb source code and repository. + +**For the description of the metsymb LaTeX package, see [this file](source/metsymb.pdf).** + + +## Table of contents + +- [License and Copyright](#license-and-copyright) +- [Installation](#installation) +- [Troubleshooting and bug reports](#troubleshooting-and-bug-reports) +- [Suggesting new symbols](#suggesting-new-symbols) +- [Contributing](#contributing) + + +## License and Copyright + +The metsymb package is released under the terms of the BSD-3-Clause license. The terms of this license are available at https://opensource.org/licenses/BSD-3-Clause, and in the LICENSE file included in the package. + +The copyright (C) 2021-2023 of metsymb is owned by MeteoSwiss. The contributors to the code are listed in AUTHORS. + + +## Installation + +Depending on your needs, you may want to install metsymb: +- [as a LaTeX package](#install-metsymb-as-a-latex-package), or +- [as an OpenType font](#install-metsymb-as-an-opentype-font) + + +### Install metsymb as a LaTeX package +Since metsymb includes a new font, its manual installation is a bit hairier (:scream:) than regular packages. **It is thus strongly recommended to use your favorite TeX package +manager to install metsymb, given that it lives on CTAN**. + +Should you be willing/requireds to install the package manually nonetheless, here are some guidelines: + + 1. Download the latest metsymb [release](https://github.com/MeteoSwiss/metsymb/releases). + If you are interested in the latest changes, you can also clone the [metsymb Github repo](https://github.com/MeteoSwiss/metsymb) directly. + + 2. Create the TeX `.sty` file: + ``` + cd some/path/to/metsymb/source/ + latex metsymb.ins + ``` + + 3. Many of the package files will need to be placed under specific locations within your TeX-tree, + which I shall call `tex_loc` for simplicity. + + In my case (Mac OSX 10.15), `tex_loc = /usr/local/texlive/2020/texmf-dist/`. To find your own `tex_loc`, you can try the following command: `kpsewhich --var-value=TEXMFLOCAL`. In case of trouble, the following resources may prove useful: + * https://tex.stackexchange.com/questions/88423/manual-font-installation + * https://tug.org/fonts/fontinstall.html + + Having identified your `tex_loc`, place the following files where they belong in the tree: + ``` + cp metsymb.tfm tex_loc/fonts/tfm/public/metsymb/ + cp metsymb.afm tex_loc/fonts/afm/public/metsymb/ + cp metsymb.pfb tex_loc/fonts/type1/public/metsymb/ + cp metsymb.otf tex_loc/fonts/opentype/public/metsymb/ + cp umetsymb.fd tex_loc/tex/latex/metsymb/ + cp metsymb.sty tex_loc/tex/latex/metsymb/ + cp metsymb.map tex_loc/fonts/map/dvips/metsymb/ + cp metsymb.enc tex_loc/fonts/enc/dvips/metsymb/ + ``` + + 4. At this point, we need to tell TeX about these new files. Run the following commands to do so: + ``` + sudo mktexlsr + sudo updmap-sys --enable Map metsymb.map + sudo updmap-sys + ``` + :warning: `sudo` is required under OS X, but not necessarily elsewhere ? + + :wave: The bash file `manual_install.sh` can be used to automate these different steps with the command `sh manual_install.sh`. Before you run it blindly, **mind the TeX-tree paths in there, that will most certainly need to be adjusted to your needs !** + +And that's it ! + +You should now be able to compile the metsymb documentation with the command: `pdflatex metsymb.dtx`. + +You should also be able to run the Python example with the command: `python metsymb_mwe.py`. + +If these two commands work, you have successfully installed the metsymb package manually, and can now access it in your LateX documents and matplotlib figures. :tada: + + +### Installing metsymb as an OpenType font + +Deploy the [`metsymb.otf`](https://github.com/MeteoSwiss/metsymb/blob/develop/metsymb/metsymb.otf) file on your system like you would any other OpenType font, and you should +have access to its symbols in your favorite text editor. + + +## Troubleshooting and bug reports + +If you encounter any issue when installing or using metsymb, you can check if it has already been reported [here](https://github.com/MeteoSwiss/metsymb/issues?q=is%3Aissue). If not, please create a new [Github Issue](https://github.com/MeteoSwiss/metsymb/issues) to report it and get help. + + +## Suggesting new symbols + +If your favorite meteorological symbol is not yet included in metsymb, +you can suggest its inclusion by creating a new [Github Issue](https://github.com/MeteoSwiss/metsymb/). + +## Contributing + +If you simply cannot wait to see your favorite symbol included inside metsymb, you should check our [contributing guidelines](CONTRIBUTING.md). diff --git a/fonts/metsymb/source/metsymb.afm b/fonts/metsymb/source/metsymb.afm new file mode 100644 index 0000000000..b98018ab11 --- /dev/null +++ b/fonts/metsymb/source/metsymb.afm @@ -0,0 +1,66 @@ +StartFontMetrics 2.0 +Comment Generated by FontForge 20201107 +Comment Creation Date: Mon Oct 10 11:49:05 2022 +FontName metsymb +FullName metsymb +FamilyName metsymb +Weight Regular +Notice (Copyright (c) 2021-2022, MeteoSwiss. Created by F.P.A. Vogt; frederic.vogt@meteoswiss.ch) +ItalicAngle 0 +IsFixedPitch true +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.200 +EncodingScheme TeX-Base-Encoding +FontBBox 49 -101 964 801 +CapHeight 525 +StartCharMetrics 47 +C 33 ; WX 1000 ; N exclam ; B 49 -100 951 801 ; +C 34 ; WX 1000 ; N quotedbl ; B 49 -100 951 801 ; +C 35 ; WX 1000 ; N numbersign ; B 49 -100 951 801 ; +C 36 ; WX 1000 ; N dollar ; B 49 -100 951 801 ; +C 37 ; WX 1000 ; N percent ; B 49 -100 951 801 ; +C 38 ; WX 1000 ; N ampersand ; B 49 -100 951 801 ; +C 39 ; WX 1000 ; N quoteright ; B 49 -100 951 801 ; +C 40 ; WX 1000 ; N parenleft ; B 49 -101 951 801 ; +C 41 ; WX 1000 ; N parenright ; B 50 -101 951 800 ; +C 42 ; WX 1000 ; N asterisk ; B 49 -100 951 801 ; +C 43 ; WX 1000 ; N plus ; B 50 80 951 620 ; +C 44 ; WX 1000 ; N comma ; B 156 -76 845 775 ; +C 45 ; WX 1000 ; N hyphen ; B 49 -100 951 695 ; +C 46 ; WX 1000 ; N period ; B 49 249 951 700 ; +C 47 ; WX 1000 ; N slash ; B 49 -100 964 515 ; +C 48 ; WX 1000 ; N zero ; B 49 -101 964 515 ; +C 49 ; WX 1000 ; N one ; B 50 109 951 591 ; +C 50 ; WX 1000 ; N two ; B 50 325 951 376 ; +C 51 ; WX 1000 ; N three ; B 49 -101 951 556 ; +C 52 ; WX 1000 ; N four ; B 49 -101 951 576 ; +C 53 ; WX 1000 ; N five ; B 49 -101 951 350 ; +C 54 ; WX 1000 ; N six ; B 49 -101 951 556 ; +C 55 ; WX 1000 ; N seven ; B 49 -101 951 556 ; +C 56 ; WX 1000 ; N eight ; B 50 109 951 606 ; +C 57 ; WX 1000 ; N nine ; B 50 109 951 326 ; +C 58 ; WX 1000 ; N colon ; B 50 325 951 376 ; +C 59 ; WX 1000 ; N semicolon ; B 50 325 951 376 ; +C 60 ; WX 1000 ; N less ; B 49 -101 951 626 ; +C 61 ; WX 1000 ; N equal ; B 49 -101 951 576 ; +C 62 ; WX 1000 ; N greater ; B 49 -100 964 515 ; +C 63 ; WX 1000 ; N question ; B 49 -100 964 515 ; +C 64 ; WX 1000 ; N at ; B 49 -88 950 150 ; +C 65 ; WX 1000 ; N A ; B 49 -88 964 740 ; +C 66 ; WX 1000 ; N B ; B 49 -88 964 740 ; +C 67 ; WX 1000 ; N C ; B 49 -101 951 526 ; +C 68 ; WX 1000 ; N D ; B 49 -88 964 740 ; +C 69 ; WX 1000 ; N E ; B 262 -101 738 526 ; +C 70 ; WX 1000 ; N F ; B 49 -88 864 613 ; +C 71 ; WX 1000 ; N G ; B 50 325 951 620 ; +C 72 ; WX 1000 ; N H ; B 50 325 951 620 ; +C 73 ; WX 1000 ; N I ; B 50 -26 951 376 ; +C 74 ; WX 1000 ; N J ; B 61 -96 951 695 ; +C 75 ; WX 1000 ; N K ; B 49 -100 951 343 ; +C 76 ; WX 1000 ; N L ; B 49 -100 951 695 ; +C 77 ; WX 1000 ; N M ; B 49 -100 951 343 ; +C 78 ; WX 1000 ; N N ; B 50 -100 951 343 ; +C 79 ; WX 1000 ; N O ; B 49 -88 951 763 ; +EndCharMetrics +EndFontMetrics diff --git a/fonts/metsymb/source/metsymb.dtx b/fonts/metsymb/source/metsymb.dtx new file mode 100644 index 0000000000..ea8ed26f71 --- /dev/null +++ b/fonts/metsymb/source/metsymb.dtx @@ -0,0 +1,532 @@ +% \iffalse meta-comment +% +% Copyright (C) 2021-2023 MeteoSwiss, originally written by Frédéric P.A. Vogt +% +% This file may be distributed and/or modified under the +% conditions of the BSD-3-Clause License. +% The terms of this license are available at: +% +% https://opensource.org/licenses/BSD-3-Clause +% +% SPDX-License-Identifier: BSD-3-Clause +% +% +% \fi +% +% \iffalse +%\NeedsTeXFormat{LaTeX2e}[2005/12/01] +%\ProvidesPackage{metsymb} +% [2022/09/10 v1.2 The meteorological symbols package] +% +%<*driver> +\documentclass{ltxdoc} +\usepackage[margin=1.2in]{geometry} % For more reasonable margins +\usepackage{tocloft} % For a better table of content in the doc +\renewcommand{\cftsecleader}{\cftdotfill{\cftdotsep}} % Idem +\usepackage{color} % For using colors +\usepackage{tabularx} % For the tables +\usepackage{graphicx} % For the demo Python plot +\usepackage{listings}% For including code +\lstset{ + basicstyle=\footnotesize, % the size of the fonts that are used for the code + frame=single, % add a frame around code + } +\usepackage{hyperref} % For the colored table of contents +\hypersetup{ + colorlinks=true, + linkcolor=red, + %filecolor=magenta, + urlcolor=blue, + %pdftitle={Overleaf Example}, + %pdfpagemode=FullScreen, + } +\usepackage{amsmath} % For proper mathematical notations +\usepackage{metsymb} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\begin{document} +\DocInput{metsymb.dtx} +\end{document} +% +% \fi +% +% \CheckSum{188} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% +% \changes{v1.1}{2022/09/10}{Changelog moved to https://github.com/MeteoSwiss/metsymb} +% \changes{v1.0}{2021/08/26}{Initial version, with okta and cloud symbols.} +% +% \GetFileInfo{metsymb.sty} +% +% \DoNotIndex{} +% +% \title{The \textsf{metsymb} package\thanks{This document +% corresponds to \textsf{metsymb}~\fileversion, +% dated \filedate.}} +% \author{Frédéric P.A. Vogt \\ \texttt{frederic.vogt@meteoswiss.ch}} +% +% \maketitle +% +% \begin{abstract} +% \noindent This package introduces commands to generate professional meteorological symbols with vectorial quality. As of \today, these include: oktas (\zerookta, \oneokta, \twooktas, \ldots), cloud genera (\cirrus, \cirrostratus, \nimbostratus, ...), and C$_\text{L}$--C$_\text{M}$--C$_\text{H}$ cloud codes (\clIII, \cmVI, \chIX, \ldots). This package essentially introduces a new font in which each symbol is assigned to a glyph, which can then be called individually from \LaTeX\ documents via dedicated commands. +% \end{abstract} +% +% \tableofcontents +% +% \section{Why \textsf{metsymb} ?} +% +% The creation of this package was motivated by the fact that in 2021, there were no dedicated Unicode elements for \href{https://en.wikipedia.org/wiki/Okta}{okta} and \href{https://cloudatlas.wmo.int/en/abbr-and-symbols-of-clouds-table-genera-species.html}{cloud genera} symbols. To the best of my knowledge, no \LaTeX\ package provides a uniform set of these symbols either\footnote{If you know of one, please let me know and I shall list it here !}.\\ +% +% \noindent This package is a direct attempt to remedy to this unfortunate state of affair. Individual symbols are designed using TikZ\footnote{\url{https://www.ctan.org/pkg/pgf}}. They are then bundled into a dedicated font with FontForge\footnote{\url{https://fontforge.org/en-US/}}. Individual glyphs of this metsymb font are then tied to dedicted \LaTeX\ commands via this package.\\ +% +% \noindent One key element of the metsymb symbols is that they are \textbf{designed using explicit (mathematical) TikZ commands}. This evidently helps to maintain a uniform look between the symbols, but also --and perhaps more importantly-- it ensures that each symbol can be faithfully reproduced with different software in the future (should the need arise). +% \section{Usage} +% +% Using the \textsf{metsymb} package is straightforward. By importing it via a not-so-surprising \texttt{\textbackslash usepackage\{metsymb\}} in the preamble of your documents, you will gain access to the commands listed in Tables~\ref{tbl:oktas} to \ref{tbl:clcmch}. +% +% \begin{table}[htb!] +% \centering +% \caption{\textsf{metsymb} commands for the okta symbols.}\label{tbl:oktas} +% \vspace{5pt} +% \begin{tabular}{c l c l} +% \zerookta & |\zerookta| & \fiveoktas & |\fiveoktas|\\ +% \oneokta & |\oneokta| & \sixoktas & |\sixoktas|\\ +% \twooktas & |\twooktas| & \sevenoktas & |\sevenoktas|\\ +% \threeoktas & |\threeoktas| & \eightoktas & |\eightoktas|\\ +% \fouroktas & |\fouroktas| & \nineoktas & |\nineoktas| +% \end{tabular} +%\end{table} +% +% \begin{table}[htb!] +% \centering +% \caption{\textsf{metsymb} commands for the cloud genera symbols.}\label{tbl:clouds} +% \vspace{5pt} +% \begin{tabular}{c l c l} +% \cirrus & |\cirrus| & \nimbostratus & |\nimbostratus|\\ +% \cirrocumulus & |\cirrocumulus| & \stratocumulus & |\stratocumulus|\\ +% \cirrostratus & |\cirrostratus| & \stratus & |\stratus|\\ +% \altocumulus & |\altocumulus| & \cumulus & |\cumulus|\\ +% \altostratus & |\altostratus| & \cumulonimbus & |\cumulonimbus| +% \end{tabular} +%\end{table} +% +% \begin{table}[htb!] +% \centering +% \caption{\textsf{metsymb} commands for the C$_\text{L}$, C$_\text{M}$, and C$_\text{H}$ cloud symbols.}\label{tbl:clcmch} +% \vspace{5pt} +% \begin{tabular}{c l c l c l} +% \clI & |\clI| & \cmI & |\cmI| & \chI & |\chI| \\ +% \clII & |\clII| & \cmII & |\cmII| & \chII & |\chII| \\ +% \clIII & |\clIII| & \cmIII & |\cmIII| & \chIII & |\chIII| \\ +% \clIV & |\clIV| & \cmIV & |\cmIV| & \chIV & |\chIV| \\ +% \clV & |\clV| & \cmV & |\cmV| & \chV & |\chV| \\ +% \clVI & |\clVI| & \cmVI & |\cmVI| & \chVI & |\chVI| \\ +% \clVII & |\clVII| & \cmVII & |\cmVII| & \chVII & |\chVII| \\ +% \clVIII & |\clVIII| & \cmVIII & |\cmVIII| & \chVIII & |\chVIII| \\ +% \clIX & |\clIX| & \cmIX & |\cmIX| & \chIX & |\chIX| +% \end{tabular} +%\end{table} +% +% \newpage +% \subsection{Using \textsf{metsymb} with \textsf{matplotlib}} +% +% \noindent \textsf{metsymb} can be used to include meteorological symbols inside Python plots, provided that the use of a system-wide \LaTeX\ installation is enabled via the setting \texttt{text.usetex} in your rcParams\footnote{\url{https://matplotlib.org/stable/tutorials/text/usetex.html}}. In fact, the assembly of a dedicated vectorial font to store the \textsf{metsymb} symbols\footnote{instead of a simpler TikZ approach, \href{https://tex.stackexchange.com/questions/610992/creating-new-symbols-with-full-font-metrics-and-vector-quality}{for example}} is directly motivated by the fact that \textsf{matplotlib} \href{https://stackoverflow.com/questions/68769147/tikzpicture-cropped-from-dvi-when-used-in-matplotlib-plt-text}{requires proper font metrics} to include symbols in Python plots.\\ +% +%\noindent The following minimal working example, stored in \texttt{metsymb\_mwe.py} inside the \textsf{metsymb} Github repository, illustrates how one can couple \textsf{metsymb} and \textsf{matplotlib} (see Fig.~\ref{fig:mwe} for the result): +% +% \lstinputlisting[language=Python]{metsymb_mwe.py} +% +% \noindent where \texttt{metsymb\_mwe.mplstyle} contains: +% +% \lstinputlisting[language=Python]{metsymb_mwe.mplstyle} +% +% \begin{figure}[htb!] +% \centerline{\includegraphics{metsymb_mwe.pdf}} +% \caption{Result of the \texttt{metsymb\_mwe.py} demonstration script, illustrating how the \textsf{metsymb} package can be used with \textsf{matplotlib}.}\label{fig:mwe} +% \end{figure} +% +% +% \section{Code development and bug reports} +% The \textsf{metsymb} package is being developed inside a dedicated Github repository under the MeteoSwiss organization, located at: \url{https://github.com/MeteoSwiss/metsymb}. User contributions are welcome and will be examined in details. So are bug reports and suggestions for new symbols, which are best submitted as \textit{Github Issues} directly on the code's repo at: \url{https://github.com/MeteoSwiss/metsymb/issues} +% +% \section{License and copyright} +% The copyright (2021-2023) of \textsf{metsymb} is owned by MeteoSwiss. The code, originally written by Frédéric P.A. Vogt, is released under the terms of the BSD-3-Clause License, available at \url{https://opensource.org/licenses/BSD-3-Clause}. +% +% \section{Ackowledgments} +% The following resources proved immensely useful to assemble the first version of this package: +% \begin{itemize} +% \item \textit{How to Package Your \LaTeX Package}, Scott Pakin (2015): \url{https://mirror.foobar.to/CTAN/info/dtxtut/dtxtut.pdf} +% \item The FontForge documentation, and in particular the \textit{FontForge and TeX} article: \url{https://fontforge.org/docs/techref/PfaEdit-TeX.html} +%\item The \textit{\TeX\ font errors: Cheatsheet}: \url{https://texdoc.org/serve/tex-font-errors-cheatsheet/0} +% \end{itemize} +% +% \noindent Several StackOverflow users also proved extremely helpful when building \textsf{metsymb}, in particular: +% \begin{itemize} +% \item those that provided clarifications and help \href{https://tex.stackexchange.com/questions/610992}{in this post}, \href{https://stackoverflow.com/questions/68769147}{in that post}, and \href{https://tex.stackexchange.com/questions/611746}{in that other post}. +% \end{itemize} +% +% \noindent Thank you also to jklymak and anntzer.lee from the \textsf{matplotlib} discourse community for their clarifications in \href{https://discourse.matplotlib.org/t/tikzpicture-cropped-from-dvi-before-ingestion-in-figure-via-plt-text/22249}{this post}. +% +% \section{Font table} +% +% The complete font table for \textsf{metsymb}, generated via the command \texttt{pdftex testfont} with the \texttt{\textbackslash sample} call, is visible in Fig.~\ref{fig:testfont}. +% +% \begin{figure}[htb!] +% \centerline{\includegraphics[scale=0.7]{testfont.pdf}} +% \caption{Complete font table for \textsf{metsymb}.}\label{fig:testfont} +% \end{figure} +% +% \StopEventually{\PrintIndex\PrintChanges} +% +% \section{Implementation} +% +% The \textsf{metsymb} package very simply defines new commands to fetch individual glyphs from the \texttt{metsymb} font. As such, its \LaTeX\ side is rather simple. +% +% \begin{macro}{\zerookta} +% The 0 okta symbol: +% \begin{macrocode} +\newcommand{\zerookta}{{\usefont{U}{metsymb}{m}{n} \char33 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\oneokta} +% The 1 okta symbol: +% \begin{macrocode} +\newcommand{\oneokta}{{\usefont{U}{metsymb}{m}{n} \char34 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\twooktas} +% The 2 oktas symbol: +% \begin{macrocode} +\newcommand{\twooktas}{{\usefont{U}{metsymb}{m}{n} \char35 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\threeoktas} +% The 3 oktas symbol: +% \begin{macrocode} +\newcommand{\threeoktas}{{\usefont{U}{metsymb}{m}{n} \char36 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fouroktas} +% The 4 oktas symbol: +% \begin{macrocode} +\newcommand{\fouroktas}{{\usefont{U}{metsymb}{m}{n} \char37 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fiveoktas} +% The 5 oktas symbol: +% \begin{macrocode} +\newcommand{\fiveoktas}{{\usefont{U}{metsymb}{m}{n} \char38 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\sixoktas} +% The 6 oktas symbol: +% \begin{macrocode} +\newcommand{\sixoktas}{{\usefont{U}{metsymb}{m}{n} \char39 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\sevenoktas} +% The 7 oktas symbol: +% \begin{macrocode} +\newcommand{\sevenoktas}{{\usefont{U}{metsymb}{m}{n} \char40 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eightoktas} +% The 8 oktas symbol: +% \begin{macrocode} +\newcommand{\eightoktas}{{\usefont{U}{metsymb}{m}{n} \char41 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\nineoktas} +% The 9 oktas symbol: +% \begin{macrocode} +\newcommand{\nineoktas}{{\usefont{U}{metsymb}{m}{n} \char42 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cirrus} +% The cirrus symbol: +% \begin{macrocode} +\newcommand{\cirrus}{{\usefont{U}{metsymb}{m}{n} \char43 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cirrocumulus} +% The cirrocumulus symbol: +% \begin{macrocode} +\newcommand{\cirrocumulus}{{\usefont{U}{metsymb}{m}{n} \char44 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cirrostratus} +% The cirrostratus symbol: +% \begin{macrocode} +\newcommand{\cirrostratus}{{\usefont{U}{metsymb}{m}{n} \char45 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\altocumulus} +% The altocumulus symbol: +% \begin{macrocode} +\newcommand{\altocumulus}{{\usefont{U}{metsymb}{m}{n} \char46 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\altostratus} +% The altostratus symbol: +% \begin{macrocode} +\newcommand{\altostratus}{{\usefont{U}{metsymb}{m}{n} \char47 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\nimbostratus} +% The nimbostratus symbol: +% \begin{macrocode} +\newcommand{\nimbostratus}{{\usefont{U}{metsymb}{m}{n} \char48 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\stratocumulus} +% The stratocumulus symbol: +% \begin{macrocode} +\newcommand{\stratocumulus}{{\usefont{U}{metsymb}{m}{n} \char49 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\stratus} +% The stratus symbol: +% \begin{macrocode} +\newcommand{\stratus}{{\usefont{U}{metsymb}{m}{n} \char50 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cumulus} +% The cumulus symbol: +% \begin{macrocode} +\newcommand{\cumulus}{{\usefont{U}{metsymb}{m}{n} \char51 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cumulonimbus} +% The cumulonimbus symbol: +% \begin{macrocode} +\newcommand{\cumulonimbus}{{\usefont{U}{metsymb}{m}{n} \char52 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clI} +% The C$_\text{L}=1$ cloud symbol: +% \begin{macrocode} +\newcommand{\clI}{{\usefont{U}{metsymb}{m}{n} \char53 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clII} +% The C$_\text{L}=2$ cloud symbol: +% \begin{macrocode} +\newcommand{\clII}{{\usefont{U}{metsymb}{m}{n} \char54 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clIII} +% The C$_\text{L}=3$ cloud symbol: +% \begin{macrocode} +\newcommand{\clIII}{{\usefont{U}{metsymb}{m}{n} \char55 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clIV} +% The C$_\text{L}=4$ cloud symbol: +% \begin{macrocode} +\newcommand{\clIV}{{\usefont{U}{metsymb}{m}{n} \char56 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clV} +% The C$_\text{L}=5$ cloud symbol: +% \begin{macrocode} +\newcommand{\clV}{{\usefont{U}{metsymb}{m}{n} \char57 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clVI} +% The C$_\text{L}=6$ cloud symbol: +% \begin{macrocode} +\newcommand{\clVI}{{\usefont{U}{metsymb}{m}{n} \char58 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clVII} +% The C$_\text{L}=7$ cloud symbol: +% \begin{macrocode} +\newcommand{\clVII}{{\usefont{U}{metsymb}{m}{n} \char59 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clVIII} +% The C$_\text{L}=8$ cloud symbol: +% \begin{macrocode} +\newcommand{\clVIII}{{\usefont{U}{metsymb}{m}{n} \char60 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clIX} +% The C$_\text{L}=9$ cloud symbol: +% \begin{macrocode} +\newcommand{\clIX}{{\usefont{U}{metsymb}{m}{n} \char61 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cmI} +% The C$_\text{M}=1$ cloud symbol: +% \begin{macrocode} +\newcommand{\cmI}{{\usefont{U}{metsymb}{m}{n} \char62 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cmII} +% The C$_\text{M}=2$ cloud symbol: +% \begin{macrocode} +\newcommand{\cmII}{{\usefont{U}{metsymb}{m}{n} \char63 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cmIII} +% The C$_\text{M}=3$ cloud symbol: +% \begin{macrocode} +\newcommand{\cmIII}{{\usefont{U}{metsymb}{m}{n} \char64 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cmIV} +% The C$_\text{M}=4$ cloud symbol: +% \begin{macrocode} +\newcommand{\cmIV}{{\usefont{U}{metsymb}{m}{n} \char65 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cmV} +% The C$_\text{M}=5$ cloud symbol: +% \begin{macrocode} +\newcommand{\cmV}{{\usefont{U}{metsymb}{m}{n} \char66 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cmVI} +% The C$_\text{M}=6$ cloud symbol: +% \begin{macrocode} +\newcommand{\cmVI}{{\usefont{U}{metsymb}{m}{n} \char67 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cmVII} +% The C$_\text{M}=7$ cloud symbol: +% \begin{macrocode} +\newcommand{\cmVII}{{\usefont{U}{metsymb}{m}{n} \char68 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cmVIII} +% The C$_\text{M}=8$ cloud symbol: +% \begin{macrocode} +\newcommand{\cmVIII}{{\usefont{U}{metsymb}{m}{n} \char69 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cmIX} +% The C$_\text{M}=9$ cloud symbol: +% \begin{macrocode} +\newcommand{\cmIX}{{\usefont{U}{metsymb}{m}{n} \char70 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\chI} +% The C$_\text{H}=1$ cloud symbol: +% \begin{macrocode} +\newcommand{\chI}{{\usefont{U}{metsymb}{m}{n} \char71 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\chII} +% The C$_\text{H}=2$ cloud symbol: +% \begin{macrocode} +\newcommand{\chII}{{\usefont{U}{metsymb}{m}{n} \char72 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\chIII} +% The C$_\text{H}=3$ cloud symbol: +% \begin{macrocode} +\newcommand{\chIII}{{\usefont{U}{metsymb}{m}{n} \char73 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\chIV} +% The C$_\text{H}=4$ cloud symbol: +% \begin{macrocode} +\newcommand{\chIV}{{\usefont{U}{metsymb}{m}{n} \char74 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\chV} +% The C$_\text{H}=5$ cloud symbol: +% \begin{macrocode} +\newcommand{\chV}{{\usefont{U}{metsymb}{m}{n} \char75 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\chVI} +% The C$_\text{H}=6$ cloud symbol: +% \begin{macrocode} +\newcommand{\chVI}{{\usefont{U}{metsymb}{m}{n} \char76 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\chVII} +% The C$_\text{H}=7$ cloud symbol: +% \begin{macrocode} +\newcommand{\chVII}{{\usefont{U}{metsymb}{m}{n} \char77 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\chVIII} +% The C$_\text{H}=8$ cloud symbol: +% \begin{macrocode} +\newcommand{\chVIII}{{\usefont{U}{metsymb}{m}{n} \char78 }}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\chIX} +% The C$_\text{H}=9$ cloud symbol: +% \begin{macrocode} +\newcommand{\chIX}{{\usefont{U}{metsymb}{m}{n} \char79 }}% +% \end{macrocode} +% \end{macro} +% +% \Finale +\endinput \ No newline at end of file diff --git a/fonts/metsymb/source/metsymb.enc b/fonts/metsymb/source/metsymb.enc new file mode 100644 index 0000000000..1150104058 --- /dev/null +++ b/fonts/metsymb/source/metsymb.enc @@ -0,0 +1,258 @@ +/TeX-Base-Encoding [ + /.notdef % 0x00 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x10 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x20 + /exclam + /quotedbl + /numbersign + /dollar + /percent + /ampersand + /quoteright + /parenleft + /parenright + /asterisk + /plus + /comma + /hyphen + /period + /slash + /zero % 0x30 + /one + /two + /three + /four + /five + /six + /seven + /eight + /nine + /colon + /semicolon + /less + /equal + /greater + /question + /at % 0x40 + /A + /B + /C + /D + /E + /F + /G + /H + /I + /J + /K + /L + /M + /N + /O + /.notdef % 0x50 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x60 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x70 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x80 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0x90 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xa0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xb0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xc0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xd0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xe0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef % 0xf0 + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef + /.notdef +] def diff --git a/fonts/metsymb/source/metsymb.ins b/fonts/metsymb/source/metsymb.ins new file mode 100644 index 0000000000..2025e5a12d --- /dev/null +++ b/fonts/metsymb/source/metsymb.ins @@ -0,0 +1,43 @@ +%% +%% Copyright (C) 2021-2023 MeteoSwiss, originally written by Frédéric P.A. Vogt +%% +%% This file may be distributed and/or modified under the +%% conditions of the BSD-3-Clause License. +%% The terms of this license are available at: +%% +%% https://opensource.org/licenses/BSD-3-Clause +%% +%% SPDX-License-Identifier: BSD-3-Clause +%% +%% +\input docstrip.tex +\keepsilent +\usedir{tex/latex/metsymb} +\preamble +This is a generated file. + +Copyright (C) 2021-2023 MeteoSwiss, originally written by Frédéric P.A. Vogt. + +This file may be distributed and/or modified under the +conditions of the BSD-3-Clause License. +The terms of this license are available at: + +https://opensource.org/licenses/BSD-3-Clause + +SPDX-License-Identifier: BSD-3-Clause + +\endpreamble +\generate{\file{metsymb.sty}{\from{metsymb.dtx}{package}}} +\Msg{*********************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the} +\Msg{* following file into a directory searched by TeX:} +\Msg{*} +\Msg{* \space\space metsymb.sty} +\Msg{*} +\Msg{* To produce the documentation run the file metsymb.dtx} +\Msg{* through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*********************************************************} +\endbatchfile \ No newline at end of file diff --git a/fonts/metsymb/source/metsymb.map b/fonts/metsymb/source/metsymb.map new file mode 100644 index 0000000000..27b7e2af49 --- /dev/null +++ b/fonts/metsymb/source/metsymb.map @@ -0,0 +1 @@ +metsymb metsymb +VStem: 900.09 50.0039<-100.021 -99.9424 -49.9395 268.601> +LayerCount: 2 +Fore +SplineSet +950.09375 360.671875 m 1 + 950.09375 207.107421875 950.09375 53.54296875 950.09375 -100.021484375 c 1 + 900.08984375 -100.021484375 l 1 + 900.08984375 -99.9423828125 l 1 + 74.966796875 -99.9423828125 l 2 + 61.16796875 -99.9423828125 49.96484375 -88.740234375 49.96484375 -74.94140625 c 0 + 49.96484375 -66.1513671875 54.5107421875 -58.4150390625 61.376953125 -53.9560546875 c 2 + 936.4453125 514.217773438 l 1 + 963.624023438 472.249023438 l 1 + 159.381835938 -49.939453125 l 1 + 317.545451175 -49.939453125 l 1 + 528.394577238 86.9309895833 739.244642488 223.801432292 950.09375 360.671875 c 1 +900.08984375 -49.939453125 m 1 + 900.08984375 268.600585938 l 1 + 409.377785428 -49.939453125 l 1 + 900.08984375 -49.939453125 l 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: exclam +Encoding: 33 33 1 +Width: 1000 +HStem: -99.9424 50.0029<374.232 625.752> 750.045 50.0039<374.232 625.752> +VStem: 49.9648 50.0029<224.274 475.781> 900.09 50.0039<224.274 475.781> +LayerCount: 2 +Fore +SplineSet +925.091796875 350.052734375 m 1025 +900.08984375 350.052734375 m 0 + 900.08984375 570.939453125 720.994140625 750.044921875 499.959960938 750.044921875 c 0 + 279.0703125 750.044921875 99.9677734375 570.942382812 99.9677734375 350.052734375 c 0 + 99.9677734375 129.026367188 279.063476562 -49.939453125 499.959960938 -49.939453125 c 0 + 721.001953125 -49.939453125 900.08984375 129.030273438 900.08984375 350.052734375 c 0 +950.09375 350.052734375 m 0 + 950.09375 101.432617188 748.5625 -99.9423828125 499.959960938 -99.9423828125 c 0 + 251.490234375 -99.9423828125 49.96484375 101.436523438 49.96484375 350.052734375 c 0 + 49.96484375 598.530273438 251.482421875 800.048828125 499.959960938 800.048828125 c 0 + 748.569335938 800.048828125 950.09375 598.534179688 950.09375 350.052734375 c 0 +EndSplineSet +Validated: 1 +EndChar + +StartChar: quotedbl +Encoding: 34 34 2 +Width: 1000 +Flags: W +HStem: -99.9424 50.7712<376.788 474.959 524.962 623.19> 749.276 50.7727<376.785 474.959 524.962 623.192> +VStem: 49.9648 50.0029<226.576 473.479> 474.959 50.0029<-49.1712 749.276> 900.09 50.0039<226.575 473.48> +LayerCount: 2 +Fore +SplineSet +950.09375 350.052734375 m 0 + 950.09375 101.432617188 748.5625 -99.9423828125 499.959960938 -99.9423828125 c 0 + 251.490234375 -99.9423828125 49.96484375 101.436523438 49.96484375 350.052734375 c 0 + 49.96484375 598.530273438 251.482421875 800.048828125 499.959960938 800.048828125 c 0 + 748.569335938 800.048828125 950.09375 598.534179688 950.09375 350.052734375 c 0 +524.961914062 -49.1721349261 m 1 + 734.350038417 -36.2812131617 900.08984375 137.426566619 900.08984375 350.052734375 c 0 + 900.08984375 562.548037825 734.34324306 736.376304383 524.961914062 749.276987556 c 1 + 524.961914062 -49.1721349261 l 1 +474.958984375 -49.1712298946 m 1 + 474.958984375 749.276084052 l 1 + 265.712859255 736.368295221 99.9677734375 562.545829824 99.9677734375 350.052734375 c 0 + 99.9677734375 137.427872842 265.706914073 -36.2732246255 474.958984375 -49.1712298946 c 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: numbersign +Encoding: 35 35 3 +Width: 1000 +HStem: -99.9424 50.0029<374.232 623.45> 325.051 474.998<476.807 633.819> +VStem: 49.9648 50.0029<224.274 473.479> 474.959 475.135<326.888 483.851> +LayerCount: 2 +Fore +SplineSet +950.09375 350.052734375 m 0 + 950.09375 101.432617188 748.5625 -99.9423828125 499.959960938 -99.9423828125 c 0 + 251.490234375 -99.9423828125 49.96484375 101.436523438 49.96484375 350.052734375 c 0 + 49.96484375 598.530273438 251.482421875 800.048828125 499.959960938 800.048828125 c 0 + 748.569335938 800.048828125 950.09375 598.534179688 950.09375 350.052734375 c 0 +899.321863134 325.05078125 m 1 + 474.958984375 325.05078125 l 1 + 474.958984375 749.276084052 l 1 + 265.712859255 736.368295221 99.9677734375 562.545829824 99.9677734375 350.052734375 c 0 + 99.9677734375 129.026367188 279.063476562 -49.939453125 499.959960938 -49.939453125 c 0 + 712.604023841 -49.939453125 886.421306635 115.68960245 899.321863134 325.05078125 c 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: dollar +Encoding: 36 36 4 +Width: 1000 +HStem: -99.9424 50.7712<376.788 474.959 524.962 623.19> 325.051 474.998<524.962 633.819> +VStem: 49.9648 50.0029<226.576 473.479> 474.959 475.135<326.888 483.851> 474.959 50.0029<-49.1712 325.051> +LayerCount: 2 +Fore +SplineSet +950.09375 350.052734375 m 0xf0 + 950.09375 101.432617188 748.5625 -99.9423828125 499.959960938 -99.9423828125 c 0 + 251.490234375 -99.9423828125 49.96484375 101.436523438 49.96484375 350.052734375 c 0 + 49.96484375 598.530273438 251.482421875 800.048828125 499.959960938 800.048828125 c 0 + 748.569335938 800.048828125 950.09375 598.534179688 950.09375 350.052734375 c 0xf0 +524.961914062 325.05078125 m 1xe8 + 524.961914062 -49.1721349261 l 1 + 726.080730337 -36.7903108187 886.930732691 123.957000805 899.321863134 325.05078125 c 1 + 524.961914062 325.05078125 l 1xe8 +474.958984375 -49.1712298946 m 1 + 474.958984375 749.276084052 l 1 + 265.712859255 736.368295221 99.9677734375 562.545829824 99.9677734375 350.052734375 c 0 + 99.9677734375 137.427872842 265.706914073 -36.2732246255 474.958984375 -49.1712298946 c 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: percent +Encoding: 37 37 5 +Width: 1000 +HStem: -99.9424 899.991<476.808 633.816> +VStem: 49.9648 50.0029<226.576 473.479> 474.959 475.135<216.203 483.851> +LayerCount: 2 +Fore +SplineSet +950.09375 350.052734375 m 0 + 950.09375 101.432617188 748.5625 -99.9423828125 499.959960938 -99.9423828125 c 0 + 251.490234375 -99.9423828125 49.96484375 101.436523438 49.96484375 350.052734375 c 0 + 49.96484375 598.530273438 251.482421875 800.048828125 499.959960938 800.048828125 c 0 + 748.569335938 800.048828125 950.09375 598.534179688 950.09375 350.052734375 c 0 +474.958984375 -49.1712298946 m 1 + 474.958984375 749.276084052 l 1 + 265.712859255 736.368295221 99.9677734375 562.545829824 99.9677734375 350.052734375 c 0 + 99.9677734375 137.427872842 265.706914073 -36.2732246255 474.958984375 -49.1712298946 c 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: ampersand +Encoding: 38 38 6 +Width: 1000 +HStem: -99.9424 899.991<476.808 633.816> 325.051 50.0039<100.737 474.959> +VStem: 49.9648 50.7709<226.829 325.051 375.055 473.228> +LayerCount: 2 +Fore +SplineSet +950.09375 350.052734375 m 0xa0 + 950.09375 101.432617188 748.5625 -99.9423828125 499.959960938 -99.9423828125 c 0 + 251.490234375 -99.9423828125 49.96484375 101.436523438 49.96484375 350.052734375 c 0 + 49.96484375 598.530273438 251.482421875 800.048828125 499.959960938 800.048828125 c 0 + 748.569335938 800.048828125 950.09375 598.534179688 950.09375 350.052734375 c 0xa0 +474.958984375 325.05078125 m 1x60 + 100.735753658 325.05078125 l 1 + 113.126716139 123.958718117 273.970908554 -36.7826056998 474.958984375 -49.1712298946 c 1 + 474.958984375 325.05078125 l 1x60 +474.958984375 375.0546875 m 1 + 474.958984375 749.276084052 l 1 + 273.981435438 736.878359793 113.134876642 576.032106437 100.736671503 375.0546875 c 1 + 474.958984375 375.0546875 l 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: quoteright +Encoding: 39 8217 7 +Width: 1000 +HStem: -99.9424 474.997<366.166 474.959> +VStem: 474.959 475.135<375.055 483.851> +LayerCount: 2 +Fore +SplineSet +950.09375 350.052734375 m 0 + 950.09375 101.432617188 748.5625 -99.9423828125 499.959960938 -99.9423828125 c 0 + 251.490234375 -99.9423828125 49.96484375 101.436523438 49.96484375 350.052734375 c 0 + 49.96484375 598.530273438 251.482421875 800.048828125 499.959960938 800.048828125 c 0 + 748.569335938 800.048828125 950.09375 598.534179688 950.09375 350.052734375 c 0 +100.736671503 375.0546875 m 1 + 474.958984375 375.0546875 l 1 + 474.958984375 749.276084052 l 1 + 273.981435438 736.878359793 113.134876642 576.032106437 100.736671503 375.0546875 c 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: parenleft +Encoding: 40 40 8 +Width: 1000 +HStem: -100.012 50.0723<450.772 549.197> 750.045 50.0039<452.341 547.591> +VStem: 49.9648 399.991<215.572 483.85> 549.965 400.129<210.687 483.851> +LayerCount: 2 +Fore +SplineSet +925.091796875 350.052734375 m 1025 +950.03515625 350.063476562 m 1024 +449.956054688 746.948873553 m 1 + 449.956054688 -46.845797688 l 1 + 466.337123291 -48.8876743002 483.025710904 -49.939453125 499.959960938 -49.939453125 c 0 + 516.895076524 -49.939453125 533.583927966 -48.8889282686 549.96484375 -46.8494525727 c 1 + 549.96484375 746.952523342 l 1 + 533.58386246 748.993534722 516.895005582 750.044921875 499.959960938 750.044921875 c 0 + 483.02577309 750.044921875 466.337180709 748.992282137 449.956054688 746.948873553 c 1 +193.89945394 20.1553839351 m 0 + 105.371176931 102.319966647 49.9648443106 219.692762567 49.96484375 350.052734375 c 0 + 49.96484375 598.530273438 251.482421875 800.048828125 499.959960938 800.048828125 c 0 + 748.569335938 800.048828125 950.09375 598.534179688 950.09375 350.052734375 c 0 + 950.09375 220.321606853 895.220807386 103.45438309 807.420130668 21.3493736798 c 0 + 726.968430827 -53.9303462207 618.854032788 -100.011718025 499.959960938 -100.01171875 c 0 + 381.761733179 -100.01171875 274.197883229 -54.4173128592 193.89945394 20.1553839351 c 0 +EndSplineSet +Validated: 1 +EndChar + +StartChar: parenright +Encoding: 41 41 9 +Width: 1000 +HStem: -100.012 900.012<366.173 633.811> +VStem: 50.0234 900.012<216.213 483.85> +LayerCount: 2 +Fore +SplineSet +950.03515625 350.063476562 m 0 + 950.03515625 101.4609375 748.5625 -100.01171875 499.959960938 -100.01171875 c 0 + 251.49609375 -100.01171875 50.0234375 101.4609375 50.0234375 350.063476562 c 0 + 50.0234375 598.52734375 251.49609375 800 499.959960938 800 c 0 + 748.5625 800 950.03515625 598.52734375 950.03515625 350.063476562 c 0 +950.03515625 350.063476562 m 1024 +EndSplineSet +Validated: 1 +EndChar + +StartChar: asterisk +Encoding: 42 42 10 +Width: 1000 +HStem: -99.9424 50.0029<376.788 623.19> 750.045 50.0039<374.904 625.083> +VStem: 49.9648 50.0029<224.913 475.149> 900.09 50.0039<226.828 473.229> +LayerCount: 2 +Fore +SplineSet +925.091796875 350.052734375 m 1025 +950.09375 350.052734375 m 0 + 950.09375 101.432617188 748.5625 -99.9423828125 499.959960938 -99.9423828125 c 0 + 251.490234375 -99.9423828125 49.96484375 101.436523438 49.96484375 350.052734375 c 0 + 49.96484375 598.530273438 251.482421875 800.048828125 499.959960938 800.048828125 c 0 + 748.569335938 800.048828125 950.09375 598.534179688 950.09375 350.052734375 c 0 +500.029067097 385.407629099 m 1 + 764.62236874 650.061554561 l 1 + 694.093873327 712.286281978 601.44760804 750.044921875 499.959960938 750.044921875 c 0 + 398.543508709 750.044921875 305.935687728 712.290498424 235.426299364 650.07145289 c 1 + 500.029067097 385.407629099 l 1 +535.375805699 350.052734375 m 1 + 800.011389675 85.3560867688 l 1 + 862.299410651 155.866610586 900.08984375 248.522769909 900.08984375 350.052734375 c 0 + 900.08984375 451.533585295 862.287897614 544.195617369 799.984328209 614.722314271 c 1 + 535.375805699 350.052734375 l 1 +464.682271058 350.052734375 m 1 + 200.06690249 614.728731818 l 1 + 137.773034103 544.201660243 99.9677734375 451.537443447 99.9677734375 350.052734375 c 0 + 99.9677734375 248.518648232 137.761587639 155.860422682 200.039836489 85.34966473 c 1 + 464.682271058 350.052734375 l 1 +500.029067097 314.697839651 m 1 + 235.400166738 50.0078772039 l 1 + 305.911821693 -12.2055099823 398.529160744 -49.939453125 499.959960938 -49.939453125 c 0 + 601.462225622 -49.939453125 694.117891807 -12.2012283611 764.648511583 50.0177653562 c 1 + 500.029067097 314.697839651 l 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: plus +Encoding: 43 43 11 +Width: 1000 +HStem: 80.0635 48.2871<836.974 865.265> 325.051 50.0039<50.0234 861.771> 571.603 48.3203<836.924 865.229> +VStem: 900.09 50.0039<163.72 286.8 413.305 536.316> +LayerCount: 2 +Fore +SplineSet +50.0234375 325.05078125 m 1 + 50.0234375 375.0546875 l 1 + 799.963867188 375.0546875 l 2 + 855.240234375 375.0546875 900.08984375 419.830078125 900.08984375 475.04296875 c 0 + 900.08984375 520.245117188 869.678710938 559.911132812 825.890625 571.602539062 c 1 + 838.79296875 619.922851562 l 1 + 904.435546875 602.396484375 950.09375 542.841796875 950.09375 475.04296875 c 0 + 950.09375 422.859317753 923.397234848 376.91956885 882.949533907 350.052734375 c 1 + 923.397234848 323.1858999 950.09375 277.246150997 950.09375 225.0625 c 0 + 950.09375 157.115234375 904.409179688 97.7294921875 838.862304688 80.0634765625 c 1 + 825.834960938 128.350585938 l 1 + 869.705078125 140.173828125 900.08984375 179.733398438 900.08984375 225.0625 c 0 + 900.08984375 280.275390625 855.240234375 325.05078125 799.963867188 325.05078125 c 2 + 50.0234375 325.05078125 l 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: comma +Encoding: 44 44 12 +Width: 1000 +HStem: -75.0195 50.0029<244.849 332.993> 715.586 21G<642.453 658.595> 724.992 50.0039<644.892 755.934> +VStem: 156.021 49.8139<12.7281 136.882> 794.221 49.8157<563.148 686.652> +LayerCount: 2 +Fore +SplineSet +251.590820312 158.884765625 m 2xb8 + 222.818537969 140.18230996 205.835398832 108.21924941 205.835398832 74.8838310171 c 0 + 205.835398832 56.506770883 210.996688335 37.7126420275 222.189453125 20.4931640625 c 0 + 240.873046875 -8.3173828125 272.700195312 -25.0166015625 305.981445312 -25.0166015625 c 0 + 314.5625 -25.0166015625 323.296875 -23.90234375 331.962890625 -21.576171875 c 1 + 344.940429688 -69.8759765625 l 1 + 332.047851562 -73.3369140625 318.967773438 -75.01953125 305.981445312 -75.01953125 c 0 + 256.053710938 -75.01953125 208.361328125 -50.0810546875 180.204101562 -6.662109375 c 0 + 163.84765625 18.501953125 156.021484375 46.783203125 156.021484375 74.8232421875 c 0 + 156.021484375 123.8828125 180.092773438 172.045898438 224.391601562 200.83984375 c 2 + 486.365234375 371.034179688 l 1 + 486.365234375 371.034179688 487.22780311 369.706465799 488.645670862 367.52337717 c 1 + 486.370117188 371.037109375 l 1 + 748.502929688 541.244140625 l 2 + 777.257903328 559.86625939 794.22136968 591.79703774 794.22136968 625.104143092 c 0 + 794.22136968 643.468417148 789.064473945 662.251094773 777.883789062 679.452148438 c 0 + 758.899414062 708.658203125 726.915039062 724.9921875 693.981445312 724.9921875 c 0xb8 + 679.831054688 724.9921875 665.421875 721.961914062 651.768554688 715.5859375 c 1xd8 + 651.768554688 715.5859375 630.654222314 760.799335498 630.654222314 760.91871613 c 0 + 630.654222314 760.918845604 630.65424715 760.918922036 630.654296875 760.918945312 c 0 + 651.005859375 770.422851562 672.583984375 774.99609375 693.981445312 774.99609375 c 0 + 743.3359375 774.99609375 791.283203125 750.583984375 819.83984375 706.65234375 c 0 + 836.196289062 681.48828125 844.037109375 653.185546875 844.037109375 625.151367188 c 0 + 844.037109375 576.103515625 819.961914062 527.951171875 775.631835938 499.2421875 c 2 + 513.554754179 329.071573154 l 1 + 513.5546875 329.071289062 l 1 + 251.590820312 158.884765625 l 2xb8 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: hyphen +Encoding: 45 45 13 +Width: 1000 +HStem: -99.9424 50.0029<159.375 950.035> 635.511 21G<748.428 764.556> 644.901 50.0029<750.866 861.954> +VStem: 900.234 49.8099<482.989 606.569> +LayerCount: 2 +Fore +SplineSet +950.03515625 -99.9423828125 m 1xb0 + 74.966796875 -99.9423828125 l 2 + 61.16796875 -99.9423828125 49.96484375 -88.740234375 49.96484375 -74.94140625 c 0 + 49.96484375 -66.1513671875 54.509765625 -58.4150390625 61.3759765625 -53.95703125 c 2 + 854.462890625 461.033203125 l 2 + 883.27686253 479.717056627 900.234089376 511.632068394 900.234089376 544.934012478 c 0 + 900.234089376 563.331869343 895.058615426 582.153028445 883.84765625 599.400390625 c 0 + 864.948242188 628.517578125 832.953125 644.901367188 799.944335938 644.901367188 c 0xb0 + 785.801757812 644.901367188 771.390625 641.87890625 757.720703125 635.510742188 c 1xd0 + 757.720703125 635.510742188 736.648362791 680.743434254 736.648362791 680.863051227 c 0 + 736.648362791 680.863181215 736.648387676 680.863257928 736.6484375 680.86328125 c 0 + 757.004882812 690.346679688 778.5703125 694.904296875 799.944335938 694.904296875 c 0 + 849.369140625 694.904296875 897.3359375 670.458007812 925.821289062 626.573242188 c 0 + 942.192382812 601.38671875 950.043945312 573.06640625 950.043945312 544.991210938 c 0 + 950.043945312 495.962890625 925.989257812 447.8203125 881.6171875 419.047851562 c 2 + 159.375 -49.939453125 l 1 + 950.03515625 -49.939453125 l 1 + 950.03515625 -99.9423828125 l 1xb0 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: period +Encoding: 46 46 14 +Width: 1000 +HStem: 249.946 50.0039<374.232 625.752> 679.942 20G<49.9648 99.9678 900.09 950.094> +VStem: 49.9648 50.0029<576.768 699.942> 900.09 50.0039<576.766 699.942> +LayerCount: 2 +Fore +SplineSet +49.96484375 699.942382812 m 1 + 99.9677734375 699.942382812 l 1 + 99.9677734375 479.052734375 279.0703125 299.950195312 499.959960938 299.950195312 c 0 + 720.994140625 299.950195312 900.08984375 479.055664062 900.08984375 699.942382812 c 1 + 950.09375 699.942382812 l 1 + 950.09375 451.4609375 748.569335938 249.946289062 499.959960938 249.946289062 c 0 + 251.482421875 249.946289062 49.96484375 451.46484375 49.96484375 699.942382812 c 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: slash +Encoding: 47 47 15 +Width: 1000 +HStem: -99.9424 50.0029<159.382 317.545 409.371 950.035> +LayerCount: 2 +Fore +SplineSet +950.03515625 -99.9423828125 m 1 + 74.966796875 -99.9423828125 l 2 + 61.16796875 -99.9423828125 49.96484375 -88.740234375 49.96484375 -74.94140625 c 0 + 49.96484375 -66.1513671875 54.5107421875 -58.4150390625 61.376953125 -53.9560546875 c 2 + 936.4453125 514.217773438 l 1 + 963.624023438 472.249023438 l 1 + 159.381835938 -49.939453125 l 1 + 317.545279453 -49.939453125 l 1 + 661.385742188 173.286132812 l 1 + 661.385742188 173.286132812 688.562568246 131.425242631 688.562568246 131.31562562 c 0 + 688.562568246 131.315525361 688.562545511 131.315460028 688.5625 131.315429688 c 2 + 409.370656837 -49.939453125 l 1 + 950.03515625 -49.939453125 l 1 + 950.03515625 -99.9423828125 l 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: one +Encoding: 49 49 16 +Width: 1000 +HStem: 109.725 50.0039<415.689 578.726> 275.027 50.0039<50.0234 285.761 707.775 950.035> 375.074 50.0039<50.0234 285.773 707.765 950.035> 540.337 50.0039<415.832 578.744> +LayerCount: 2 +Fore +SplineSet +50.0234375 375.07421875 m 1 + 50.0234375 425.078125 l 1 + 280.014648438 425.078125 l 1 + 306.872070312 523.090820312 396.481445312 590.340820312 496.73828125 590.340820312 c 0 + 509.7265625 590.340820312 522.861328125 589.213867188 536.020507812 586.895507812 c 0 + 622.10546875 571.712890625 691.078125 508.0859375 713.958007812 425.078125 c 1 + 950.03515625 425.078125 l 1 + 950.03515625 375.07421875 l 1 + 857.6953125 375.07421875 765.35546875 375.07421875 673.015625 375.07421875 c 1 + 669.37109375 395.704101562 l 2 + 656.580078125 468.108398438 599.844726562 524.856445312 527.291015625 537.65234375 c 0 + 516.990234375 539.467773438 506.779296875 540.336914062 496.73828125 540.336914062 c 0 + 413.455078125 540.336914062 339.584960938 480.625 324.625976562 395.715820312 c 2 + 320.989257812 375.07421875 l 1 + 230.66796875 375.07421875 140.345703125 375.07421875 50.0234375 375.07421875 c 1 +50.0234375 275.02734375 m 1 + 50.0234375 325.03125 l 1 + 140.346679688 325.03125 230.670898438 325.03125 320.994140625 325.03125 c 1 + 324.626953125 304.383789062 l 2 + 339.580078125 219.401367188 413.35546875 159.728515625 496.537109375 159.728515625 c 0 + 506.6328125 159.728515625 516.970703125 160.62109375 527.330078125 162.459960938 c 0 + 599.842773438 175.127929688 656.573242188 231.840820312 669.370117188 304.39453125 c 2 + 673.009765625 325.03125 l 1 + 765.3515625 325.03125 857.693359375 325.03125 950.03515625 325.03125 c 1 + 950.03515625 275.02734375 l 1 + 713.965820312 275.02734375 l 1 + 691.094726562 191.90625 622.111328125 128.250976562 535.981445312 113.203125 c 0 + 522.744140625 110.854492188 509.600585938 109.724609375 496.537109375 109.724609375 c 0 + 396.338867188 109.724609375 306.836914062 176.984375 280.008789062 275.02734375 c 1 + 50.0234375 275.02734375 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: two +Encoding: 50 50 17 +Width: 1000 +HStem: 325.051 50.0039<50.0234 409.973 589.947 950.035> +LayerCount: 2 +Fore +SplineSet +50.0234375 325.05078125 m 1 + 50.0234375 375.0546875 l 1 + 409.97265625 375.0546875 l 1 + 409.97265625 325.05078125 l 1 + 50.0234375 325.05078125 l 1 +589.947265625 325.05078125 m 1 + 589.947265625 375.0546875 l 1 + 950.03515625 375.0546875 l 1 + 950.03515625 325.05078125 l 1 + 589.947265625 325.05078125 l 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: three +Encoding: 51 51 18 +Width: 1000 +HStem: 299.971 50.0029<371.679 628.312> 505.065 50.0039<418.323 582.805> +VStem: 49.9648 50.0029<-100.021 28.2599> 275.017 50.0039<315.115 412.738> 675.031 49.9771<315.076 411.708> 900.09 50.0039<-100.021 28.2584> +LayerCount: 2 +Fore +SplineSet +99.9677734375 -100.021484375 m 1 + 49.96484375 -100.021484375 l 1 + 49.96484375 67.8807974739 141.978408783 214.341012284 278.318671084 291.672292303 c 1 + 276.099898252 304.444877194 275.016601567 317.251206303 275.016601562 329.969726562 c 0 + 275.016601562 421.83203125 331.669921875 508.145507812 423.041015625 541.393554688 c 0 + 448.39453125 550.65234375 474.41015625 555.069335938 500.067382812 555.069335938 c 0 + 591.92578125 555.069335938 678.193359375 498.305664062 711.42578125 406.975585938 c 0 + 720.480957031 382.131347656 725.008544922 356.066650391 725.008544922 330.002075195 c 0 + 725.008544922 317.172668986 723.911615464 304.343292352 721.717756547 291.65950271 c 1 + 858.087703868 214.325360007 950.09375 67.8730691749 950.09375 -100.021484375 c 1 + 900.08984375 -100.021484375 l 1 + 900.08984375 120.864257812 720.994140625 299.970703125 499.959960938 299.970703125 c 0 + 279.0703125 299.970703125 99.9677734375 120.868164062 99.9677734375 -100.021484375 c 1 +325.671825426 314.962636956 m 1 + 379.278972219 337.51095094 438.167367312 349.973632818 499.959960938 349.973632812 c 0 + 561.805657478 349.973632812 620.737510795 337.502939813 674.377945999 314.940812516 c 1 + 674.81364476 319.952686833 675.031494141 324.977506847 675.031494141 330.002319336 c 0 + 675.031494141 350.240478516 671.497558594 370.478515625 664.4296875 389.870117188 c 0 + 638.591796875 460.875976562 571.5234375 505.065429688 500.067382812 505.065429688 c 0 + 480.252929688 505.065429688 460.022460938 501.65625 440.17578125 494.407226562 c 0 + 369.1640625 468.568359375 325.020507812 401.474609375 325.020507812 329.969726562 c 0 + 325.020507812 324.98931995 325.235365914 319.982720171 325.671825426 314.962636956 c 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: four +Encoding: 52 52 19 +Width: 1000 +HStem: 299.971 50.0029<370.885 629.117> 525.008 50.0029<195.755 804.186> +VStem: 49.9648 50.0029<-100.021 28.2599> 900.09 50.0039<-100.021 28.2584> +LayerCount: 2 +Fore +SplineSet +104.110351562 575.010742188 m 1 + 895.790039062 575.010742188 l 1 + 835.748182627 481.645146196 775.786182508 388.403493862 715.720551858 295.000190596 c 1 + 855.383332975 218.594350684 950.09375 70.3226950594 950.09375 -100.021484375 c 1 + 900.08984375 -100.021484375 l 1 + 900.08984375 120.864257812 720.994140625 299.970703125 499.959960938 299.970703125 c 0 + 279.0703125 299.970703125 99.9677734375 120.868164062 99.9677734375 -100.021484375 c 1 + 49.96484375 -100.021484375 l 1 + 49.96484375 70.3314499998 144.68401695 218.611825172 284.316799782 295.014077575 c 1 + 104.110351562 575.010742188 l 1 +670.207774924 316.670148108 m 1 + 804.185546875 525.0078125 l 1 + 195.754882812 525.0078125 l 1 + 329.83051463 316.687282781 l 1 + 382.318810134 338.145578023 439.761230349 349.973632812 499.959960938 349.973632812 c 0 + 560.207026959 349.973632812 617.688940944 338.139309725 670.207774924 316.670148108 c 1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: five +Encoding: 53 53 20 +Width: 1000 +HStem: -99.9424 50.0029<103.074 896.984> 299.971 50.0029<374.58 625.403> +LayerCount: 2 +Fore +SplineSet +99.9677734375 -100.021484375 m 1 + 49.96484375 -100.021484375 l 1 + 49.96484375 148.456054688 251.482421875 349.973632812 499.959960938 349.973632812 c 0 + 748.569335938 349.973632812 950.09375 148.458984375 950.09375 -100.021484375 c 1 + 900.08984375 -100.021484375 l 1 + 900.08984375 -99.9951165921 900.089836094 -99.9687494045 900.089836094 -99.9423828125 c 1 + 99.9677810936 -99.9423828125 l 1 + 99.9677810936 -99.9687494044 99.9677734375 -99.995116592 99.9677734375 -100.021484375 c 1 +896.983995651 -49.939453125 m 1 + 872.338252164 147.314176689 704.021668716 299.970703125 499.959960938 299.970703125 c 0 + 296.03142204 299.970703125 127.719086072 147.317110385 103.073575003 -49.939453125 c 1 + 896.983995651 -49.939453125 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: six +Encoding: 54 54 21 +Width: 1000 +HStem: -99.9424 50.0029<103.074 896.984> 299.971 50.0029<372.376 627.614> 505.065 50.0039<418.323 582.805> +VStem: 275.017 50.0039<315.115 412.738> 675.031 49.9771<315.076 411.708> +LayerCount: 2 +Fore +SplineSet +99.9677734375 -100.021484375 m 1 + 49.96484375 -100.021484375 l 1 + 49.96484375 67.8807974739 141.978408783 214.341012284 278.318671084 291.672292303 c 1 + 276.099898252 304.444877194 275.016601567 317.251206303 275.016601562 329.969726562 c 0 + 275.016601562 421.83203125 331.669921875 508.145507812 423.041015625 541.393554688 c 0 + 448.39453125 550.65234375 474.41015625 555.069335938 500.067382812 555.069335938 c 0 + 591.92578125 555.069335938 678.193359375 498.305664062 711.42578125 406.975585938 c 0 + 720.480957031 382.131347657 725.008544922 356.066650393 725.008544922 330.002075199 c 0 + 725.008544922 317.172668989 723.911615463 304.343292353 721.717756547 291.65950271 c 1 + 858.087703868 214.325360007 950.09375 67.8730691749 950.09375 -100.021484375 c 1 + 900.08984375 -100.021484375 l 1 + 900.08984375 -99.9951165921 900.089836094 -99.9687494045 900.089836094 -99.9423828125 c 1 + 99.9677810936 -99.9423828125 l 1 + 99.9677810936 -99.9687494044 99.9677734375 -99.995116592 99.9677734375 -100.021484375 c 1 +896.983995651 -49.939453125 m 1 + 872.338252164 147.314176689 704.021668716 299.970703125 499.959960938 299.970703125 c 0 + 296.03142204 299.970703125 127.719086072 147.317110385 103.073575003 -49.939453125 c 1 + 896.983995651 -49.939453125 l 1 +325.671825426 314.962636956 m 1 + 379.278972219 337.51095094 438.167367312 349.973632818 499.959960938 349.973632812 c 0 + 561.805657478 349.973632812 620.737510795 337.502939813 674.377945999 314.940812516 c 1 + 674.81364476 319.952686834 675.03149414 324.977506848 675.03149414 330.002319338 c 0 + 675.03149414 350.240478517 671.497558594 370.478515626 664.4296875 389.870117188 c 0 + 638.591796875 460.875976562 571.5234375 505.065429688 500.067382812 505.065429688 c 0 + 480.252929688 505.065429688 460.022460938 501.65625 440.17578125 494.407226562 c 0 + 369.1640625 468.568359375 325.020507812 401.474609375 325.020507812 329.969726562 c 0 + 325.020507812 324.98931995 325.235365914 319.982720171 325.671825426 314.962636956 c 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: seven +Encoding: 55 55 22 +Width: 1000 +HStem: -99.9424 50.0029<103.074 896.984> 299.202 50.0886<371.166 474.959 524.962 628.814> 535.069 20G<487.239 545.997> +VStem: 275.017 50.0039<315.115 412.738> 474.959 50.0029<129.977 299.202 347.786 503.232> 675.031 49.9771<315.076 411.802> +LayerCount: 2 +Fore +SplineSet +99.9677734375 -100.021484375 m 1 + 49.96484375 -100.021484375 l 1 + 49.96484375 67.8807974739 141.978408783 214.341012284 278.318671084 291.672292303 c 1 + 276.099898252 304.444877194 275.016601567 317.251206303 275.016601562 329.969726562 c 0 + 275.016601562 421.83203125 331.669921875 508.145507812 423.041015625 541.393554688 c 0 + 448.39453125 550.65234375 474.41015625 555.069335938 500.067382812 555.069335938 c 0 + 591.92578125 555.069335938 678.193359375 498.305664062 711.42578125 406.975585938 c 0 + 720.480957031 382.131347657 725.008544922 356.066650393 725.008544922 330.002075199 c 0 + 725.008544922 317.172668989 723.911615463 304.343292353 721.717756547 291.65950271 c 1 + 858.087703868 214.325360007 950.09375 67.8730691749 950.09375 -100.021484375 c 1 + 900.08984375 -100.021484375 l 1 + 900.08984375 -99.9951165921 900.089836094 -99.9687494045 900.089836094 -99.9423828125 c 1 + 99.9677810936 -99.9423828125 l 1 + 99.9677810936 -99.9687494044 99.9677734375 -99.995116592 99.9677734375 -100.021484375 c 1 +896.983995651 -49.939453125 m 1 + 873.352409776 139.197307734 717.630648307 287.331738422 524.961914062 299.202764739 c 1 + 524.961914062 129.9765625 l 1 + 474.958984375 129.9765625 l 1 + 474.958984375 299.201865302 l 1 + 282.414796988 287.324370748 126.70433188 139.195269289 103.073575003 -49.939453125 c 1 + 896.983995651 -49.939453125 l 1 +474.958984375 349.290456033 m 1 + 474.958984375 503.232130952 l 1 + 463.339540017 501.527498715 451.693037953 498.613918316 440.17578125 494.407226562 c 0 + 369.1640625 468.568359375 325.020507812 401.474609375 325.020507812 329.969726562 c 0 + 325.020507812 324.98931995 325.235365914 319.982720171 325.671825426 314.962636956 c 1 + 372.001085197 334.449715797 422.27493546 346.403786104 474.958984375 349.290456033 c 1 +524.961914062 349.291120189 m 1 + 577.696905441 346.404546262 628.014021561 334.442309124 674.377945999 314.940812516 c 1 + 674.81364476 319.952686834 675.03149414 324.977506848 675.03149414 330.002319338 c 0 + 675.03149414 350.240478517 671.497558594 370.478515626 664.4296875 389.870117188 c 0 + 641.621315577 452.550468028 586.684274702 494.334247352 524.961914062 503.270910933 c 1 + 524.961914062 349.291120189 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: eight +Encoding: 56 56 23 +Width: 1000 +HStem: 109.725 50.0039<414.242 579.985> 275.027 50.0039<50.0234 198.643 246.287 285.761 707.775 753.771 801.415 950.035> 555.05 50.0029<400.435 599.56> +VStem: 196.084 50.203<325.031 402.419> 753.771 50.2029<325.031 402.421> +LayerCount: 2 +Fore +SplineSet +50.0234375 275.02734375 m 1 + 50.0234375 325.03125 l 1 + 196.084122386 325.03125 l 1 + 208.796888582 481.7436879 339.955234253 605.052734375 499.959960938 605.052734375 c 0 + 660.087375242 605.052734375 791.260799911 481.747748107 803.97443811 325.03125 c 1 + 950.03515625 325.03125 l 1 + 950.03515625 275.02734375 l 1 + 713.965820312 275.02734375 l 1 + 691.094726562 191.90625 622.111328125 128.250976562 535.981445312 113.203125 c 0 + 522.744140625 110.854492188 509.600585938 109.724609375 496.537109375 109.724609375 c 0 + 396.338867188 109.724609375 306.836914062 176.984375 280.008789062 275.02734375 c 1 + 50.0234375 275.02734375 l 1 +246.28708095 325.03125 m 1 + 320.994140625 325.03125 l 1 + 324.626953125 304.383789062 l 2 + 339.580078125 219.401367188 413.35546875 159.728515625 496.537109375 159.728515625 c 0 + 506.6328125 159.728515625 516.970703125 160.62109375 527.330078125 162.459960938 c 0 + 599.842773438 175.127929688 656.573242188 231.840820312 669.370117188 304.39453125 c 2 + 673.009765625 325.03125 l 1 + 753.771491345 325.03125 l 1 + 741.219736184 454.133768138 632.476564205 555.049804688 499.959960938 555.049804688 c 0 + 367.582585875 555.049804688 258.838937333 454.138461709 246.28708095 325.03125 c 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: nine +Encoding: 57 57 24 +Width: 1000 +HStem: 109.725 50.0039<415.689 578.726> 275.027 50.0039<50.0234 285.761 707.775 950.035> +LayerCount: 2 +Fore +SplineSet +50.0234375 275.02734375 m 1 + 50.0234375 325.03125 l 1 + 140.346679688 325.03125 230.670898438 325.03125 320.994140625 325.03125 c 1 + 324.626953125 304.383789062 l 2 + 339.580078125 219.401367188 413.35546875 159.728515625 496.537109375 159.728515625 c 0 + 506.6328125 159.728515625 516.970703125 160.62109375 527.330078125 162.459960938 c 0 + 599.842773438 175.127929688 656.573242188 231.840820312 669.370117188 304.39453125 c 2 + 673.009765625 325.03125 l 1 + 765.3515625 325.03125 857.693359375 325.03125 950.03515625 325.03125 c 1 + 950.03515625 275.02734375 l 1 + 713.965820312 275.02734375 l 1 + 691.094726562 191.90625 622.111328125 128.250976562 535.981445312 113.203125 c 0 + 522.744140625 110.854492188 509.600585938 109.724609375 496.537109375 109.724609375 c 0 + 396.338867188 109.724609375 306.836914062 176.984375 280.008789062 275.02734375 c 1 + 50.0234375 275.02734375 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: colon +Encoding: 58 58 25 +Width: 1000 +HStem: 325.051 50.0039<50.0234 950.035> +LayerCount: 2 +Fore +SplineSet +50.0234375 325.05078125 m 1 + 50.0234375 375.0546875 l 1 + 950.03515625 375.0546875 l 1 + 950.03515625 325.05078125 l 1 + 50.0234375 325.05078125 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: semicolon +Encoding: 59 59 26 +Width: 1000 +HStem: 325.051 50.0039<50.0234 300.004 374.971 624.95 700.055 950.035> +LayerCount: 2 +Fore +SplineSet +700.0546875 325.05078125 m 1 + 700.0546875 375.0546875 l 1 + 950.03515625 375.0546875 l 1 + 950.03515625 325.05078125 l 1 + 700.0546875 325.05078125 l 1 +374.970703125 325.05078125 m 1 + 374.970703125 375.0546875 l 1 + 624.950195312 375.0546875 l 1 + 624.950195312 325.05078125 l 1 + 374.970703125 325.05078125 l 1 +50.0234375 325.05078125 m 1 + 50.0234375 375.0546875 l 1 + 300.00390625 375.0546875 l 1 + 300.00390625 325.05078125 l 1 + 50.0234375 325.05078125 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: less +Encoding: 60 60 27 +Width: 1000 +HStem: -99.9424 50.0029<103.074 896.984> 299.971 50.0029<374.58 625.403> 409.729 50.0039<415.689 578.741> 575.031 50.0039<50.0234 285.761 707.773 950.035> +LayerCount: 2 +Fore +SplineSet +496.537109375 409.728515625 m 0 + 396.338867188 409.728515625 306.836914062 476.98828125 280.008789062 575.03125 c 1 + 50.0234375 575.03125 l 1 + 50.0234375 625.03515625 l 1 + 140.346679688 625.03515625 230.670898438 625.03515625 320.994140625 625.03515625 c 1 + 324.626953125 604.387695312 l 2 + 339.580078125 519.404296875 413.35546875 459.732421875 496.537109375 459.732421875 c 0 + 506.6328125 459.732421875 516.930664062 460.618164062 527.291015625 462.45703125 c 0 + 599.866210938 475.256835938 656.577148438 531.8671875 669.370117188 604.3984375 c 2 + 673.009765625 625.03515625 l 1 + 765.3515625 625.03515625 857.693359375 625.03515625 950.03515625 625.03515625 c 1 + 950.03515625 575.03125 l 1 + 713.96484375 575.03125 l 1 + 691.088867188 491.913085938 622.092773438 428.39453125 536.020507812 413.213867188 c 0 + 522.783203125 410.865234375 509.600585938 409.728515625 496.537109375 409.728515625 c 0 +99.9677734375 -100.021484375 m 1 + 49.96484375 -100.021484375 l 1 + 49.96484375 148.456054688 251.482421875 349.973632812 499.959960938 349.973632812 c 0 + 748.569335938 349.973632812 950.09375 148.458984375 950.09375 -100.021484375 c 1 + 900.08984375 -100.021484375 l 1 + 900.08984375 -99.9951165921 900.089836094 -99.9687494045 900.089836094 -99.9423828125 c 1 + 99.9677810936 -99.9423828125 l 1 + 99.9677810936 -99.9687494044 99.9677734375 -99.995116592 99.9677734375 -100.021484375 c 1 +896.983995651 -49.939453125 m 1 + 872.338252164 147.314176689 704.021668716 299.970703125 499.959960938 299.970703125 c 0 + 296.03142204 299.970703125 127.719086072 147.317110385 103.073575003 -49.939453125 c 1 + 896.983995651 -49.939453125 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: equal +Encoding: 61 61 28 +Width: 1000 +HStem: -99.9424 50.0029<103.074 896.984> 299.971 50.0029<371.234 628.768> 525.008 50.0029<195.755 804.186> +LayerCount: 2 +Fore +SplineSet +104.110351562 575.010742188 m 1 + 895.790039062 575.010742188 l 1 + 835.748182627 481.645146196 775.786182508 388.403493862 715.720551858 295.000190596 c 1 + 855.383332975 218.594350684 950.09375 70.3226950594 950.09375 -100.021484375 c 1 + 900.08984375 -100.021484375 l 1 + 900.08984375 -99.9951165921 900.089836094 -99.9687494045 900.089836094 -99.9423828125 c 1 + 99.9677810936 -99.9423828125 l 1 + 99.9677810936 -99.9687494044 99.9677734375 -99.995116592 99.9677734375 -100.021484375 c 1 + 49.96484375 -100.021484375 l 1 + 49.96484375 70.3314499998 144.68401695 218.611825172 284.316799782 295.014077575 c 1 + 104.110351562 575.010742188 l 1 +103.073575003 -49.939453125 m 1 + 896.983995651 -49.939453125 l 1 + 872.338252164 147.314176689 704.021668716 299.970703125 499.959960938 299.970703125 c 0 + 296.03142204 299.970703125 127.719086072 147.317110385 103.073575003 -49.939453125 c 1 +670.207774924 316.670148108 m 1 + 804.185546875 525.0078125 l 1 + 195.754882812 525.0078125 l 1 + 329.83051463 316.687282781 l 1 + 382.318810134 338.145578023 439.761230349 349.973632812 499.959960938 349.973632812 c 0 + 560.207026959 349.973632812 617.688940944 338.139309725 670.207774924 316.670148108 c 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: greater +Encoding: 62 62 29 +Width: 1000 +HStem: -99.9424 50.0029<159.382 950.035> 494.218 20G<905.642 949.397> +LayerCount: 2 +Fore +SplineSet +950.03515625 -99.9423828125 m 1 + 74.966796875 -99.9423828125 l 2 + 61.16796875 -99.9423828125 49.96484375 -88.740234375 49.96484375 -74.94140625 c 0 + 49.96484375 -66.1513671875 54.5107421875 -58.4150390625 61.376953125 -53.9560546875 c 2 + 936.4453125 514.217773438 l 1 + 936.4453125 514.217773438 963.624023438 472.359375 963.624023438 472.249023438 c 2 + 159.381835938 -49.939453125 l 1 + 950.03515625 -49.939453125 l 1 + 950.03515625 -99.9423828125 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: question +Encoding: 63 63 30 +Width: 1000 +HStem: -99.9424 50.0029<159.382 317.544 409.365 950.035> 494.218 20G<905.642 949.397> +LayerCount: 2 +Fore +SplineSet +950.03515625 -99.9423828125 m 1 + 74.966796875 -99.9423828125 l 2 + 61.16796875 -99.9423828125 49.96484375 -88.740234375 49.96484375 -74.94140625 c 0 + 49.96484375 -66.1513671875 54.5107421875 -58.4150390625 61.376953125 -53.9560546875 c 2 + 936.4453125 514.217773438 l 1 + 963.624023438 472.249023438 l 1 + 159.381835938 -49.939453125 l 1 + 317.54394841 -49.939453125 l 1 + 936.446289062 351.8828125 l 1 + 963.624023438 309.913085938 l 1 + 409.365094134 -49.939453125 l 1 + 950.03515625 -49.939453125 l 1 + 950.03515625 -99.9423828125 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: at +Encoding: 64 64 31 +Width: 1000 +HStem: -87.54 50.0029<201.279 373.409 626.569 798.7> +VStem: 49.9648 50.0029<64.6349 149.958> 474.959 50.0029<64.6349 149.958> 899.952 50.0039<64.6285 149.958> +LayerCount: 2 +Fore +SplineSet +49.96484375 149.958007812 m 1 + 99.9677734375 149.958007812 l 1 + 99.9677734375 46.4853515625 183.990234375 -37.537109375 287.463867188 -37.537109375 c 0 + 391.072265625 -37.537109375 474.958984375 46.470703125 474.958984375 149.958007812 c 1 + 524.961914062 149.958007812 l 1 + 524.961914062 46.4853515625 608.983398438 -37.537109375 712.45703125 -37.537109375 c 0 + 816.065429688 -37.537109375 899.952148438 46.470703125 899.952148438 149.958007812 c 1 + 949.956054688 149.958007812 l 1 + 949.956054688 18.900390625 843.669921875 -87.5400390625 712.45703125 -87.5400390625 c 0 + 619.51953125 -87.5400390625 538.973632812 -34.0341796875 499.971679688 43.826171875 c 1 + 461.000976562 -34.029296875 380.498046875 -87.5400390625 287.463867188 -87.5400390625 c 0 + 156.390625 -87.5400390625 49.96484375 18.8857421875 49.96484375 149.958007812 c 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: A +Encoding: 65 65 32 +Width: 1000 +HStem: -87.54 50.0029<201.001 373.707> 719.254 20G<788.697 949.398> +VStem: 474.959 50.0029<64.6285 149.958> +LayerCount: 2 +Fore +SplineSet +474.958984375 149.958007812 m 1 + 524.961914062 149.958007812 l 1 + 524.961914062 18.900390625 418.676757812 -87.5400390625 287.463867188 -87.5400390625 c 0 + 156.390625 -87.5400390625 49.96484375 18.8857421875 49.96484375 149.958007812 c 2 + 49.96484375 163.53125 l 1 + 345.458007812 355.438476562 640.950195312 547.346679688 936.443359375 739.25390625 c 1 + 936.443359375 739.25390625 963.627021354 697.39689598 963.627021354 697.287305222 c 0 + 963.627021354 697.287205012 963.626998625 697.287139708 963.626953125 697.287109375 c 2 + 100.431640625 136.686523438 l 1 + 107.250976562 39.3955078125 188.452148438 -37.537109375 287.463867188 -37.537109375 c 0 + 391.072265625 -37.537109375 474.958984375 46.470703125 474.958984375 149.958007812 c 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: B +Encoding: 66 66 33 +Width: 1000 +HStem: -87.54 50.0029<201.001 373.436 626.648 798.779> 719.254 20G<788.697 949.398> +VStem: 475.097 50.0029<64.6379 149.958> 900.09 50.0039<64.6349 149.958> +LayerCount: 2 +Fore +SplineSet +900.08984375 149.958007812 m 1 + 950.09375 149.958007812 l 1 + 950.09375 18.8857421875 843.666992188 -87.5400390625 712.594726562 -87.5400390625 c 0 + 619.55859375 -87.5400390625 539.0546875 -34.02734375 500.084960938 43.830078125 c 1 + 461.073242188 -34.0341796875 380.4921875 -87.5400390625 287.463867188 -87.5400390625 c 0 + 156.390625 -87.5400390625 49.96484375 18.8857421875 49.96484375 149.958007812 c 2 + 49.96484375 163.53125 l 1 + 345.458007812 355.438476562 640.950195312 547.346679688 936.443359375 739.25390625 c 1 + 936.443359375 739.25390625 963.627021354 697.39689598 963.627021354 697.287305222 c 0 + 963.627021354 697.287205012 963.626998625 697.287139708 963.626953125 697.287109375 c 2 + 100.431640625 136.686523438 l 1 + 107.250976562 39.3955078125 188.452148438 -37.537109375 287.463867188 -37.537109375 c 0 + 391.086914062 -37.537109375 475.096679688 46.4921875 475.096679688 149.958007812 c 1 + 525.099609375 149.958007812 l 1 + 525.099609375 46.470703125 608.986328125 -37.537109375 712.594726562 -37.537109375 c 0 + 816.068359375 -37.537109375 900.08984375 46.4853515625 900.08984375 149.958007812 c 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: C +Encoding: 67 67 34 +Width: 1000 +HStem: 299.971 50.0029<447.003 552.96> 505.066 20G<49.9648 99.9678 474.959 524.962 899.952 949.956> +VStem: 49.9648 50.0029<-100.021 26.4665 441.167 525.066> 474.959 50.0029<439.684 525.066> 900.09 50.0039<-100.021 26.4696 441.188 525.066> +LayerCount: 2 +Fore +SplineSet +49.96484375 525.06640625 m 1 + 99.9677734375 525.06640625 l 1 + 99.9677734375 421.458007812 183.975585938 337.571289062 287.463867188 337.571289062 c 0 + 391.0859375 337.571289062 474.958984375 421.443359375 474.958984375 525.06640625 c 1 + 524.961914062 525.06640625 l 1 + 524.961914062 421.458007812 608.969726562 337.571289062 712.45703125 337.571289062 c 0 + 816.080078125 337.571289062 899.952148438 421.443359375 899.952148438 525.06640625 c 1 + 949.956054688 525.06640625 l 1 + 949.956054688 399.070620699 851.919402778 296.036906607 727.941987019 288.063746844 c 1 + 860.879840325 209.841672273 950.09375 65.3058677582 950.09375 -100.021484375 c 1 + 900.08984375 -100.021484375 l 1 + 900.08984375 120.864257812 720.994140625 299.970703125 499.959960938 299.970703125 c 0 + 279.0703125 299.970703125 99.9677734375 120.868164062 99.9677734375 -100.021484375 c 1 + 49.96484375 -100.021484375 l 1 + 49.96484375 65.3010953105 139.172680404 209.835431292 272.065914765 288.05908456 c 1 + 148.169008669 295.996106026 49.9648437268 399.032282305 49.96484375 525.06640625 c 1 +555.846735762 346.538802394 m 1 + 532.86332032 366.716060493 513.804523422 391.260383563 499.971679688 418.877929688 c 1 + 486.149961558 391.262546228 467.104426805 366.719230235 444.129287224 346.542237177 c 1 + 462.422304818 348.807144956 481.055218638 349.973632712 499.959960938 349.973632812 c 0 + 518.884424036 349.973632812 537.536055739 348.805966497 555.846735762 346.538802394 c 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: D +Encoding: 68 68 35 +Width: 1000 +HStem: -87.54 50.0029<200.714 374 626.084 799.344> 124.957 50.0029<159.364 473.44 526.753 898.435> 719.254 20G<788.697 949.398> +LayerCount: 2 +Fore +SplineSet +712.594726562 -37.537109375 m 0 + 807.591796875 -37.537109375 886.194335938 33.283203125 898.434570312 124.95703125 c 1 + 526.752929688 124.95703125 l 1 + 538.973632812 33.2724609375 617.47265625 -37.537109375 712.594726562 -37.537109375 c 0 +287.463867188 -37.537109375 m 0 + 382.59765625 -37.537109375 461.200195312 33.2880859375 473.440429688 124.95703125 c 1 + 101.624023438 124.95703125 l 1 + 113.864257812 33.283203125 192.465820312 -37.537109375 287.463867188 -37.537109375 c 0 +49.96484375 149.958007812 m 2 + 49.96484375 163.53125 l 1 + 345.458007812 355.438476562 640.950195312 547.346679688 936.443359375 739.25390625 c 1 + 936.443359375 739.25390625 963.627021354 697.39689598 963.627021354 697.287305222 c 0 + 963.627021354 697.287205012 963.626998625 697.287139708 963.626953125 697.287109375 c 2 + 159.364257812 174.959960938 l 1 + 422.940429688 174.959960938 686.517578125 174.959960938 950.09375 174.959960938 c 1 + 950.09375 149.958007812 l 2 + 950.09375 18.8857421875 843.666992188 -87.5400390625 712.594726562 -87.5400390625 c 0 + 619.55859375 -87.5400390625 539.0546875 -34.02734375 500.084960938 43.830078125 c 1 + 461.073242188 -34.0341796875 380.4921875 -87.5400390625 287.463867188 -87.5400390625 c 0 + 156.390625 -87.5400390625 49.96484375 18.8857421875 49.96484375 149.958007812 c 2 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: E +Encoding: 69 69 36 +Width: 1000 +HStem: 287.567 50.0039<413.478 586.488> 505.066 20G<262.462 312.465 687.455 737.459> +VStem: 262.462 50.0029<-100.021 379.294 439.684 525.066> 687.455 50.0039<-100.021 379.245 439.677 525.066> +LayerCount: 2 +Fore +SplineSet +687.455078125 525.06640625 m 1 + 737.458984375 525.06640625 l 1 + 737.458984375 -100.021484375 l 1 + 687.455078125 -100.021484375 l 1 + 687.455078125 379.245117188 l 1 + 644.002929688 323.447265625 576.18359375 287.567382812 499.959960938 287.567382812 c 0 + 423.79296875 287.567382812 355.94140625 323.466796875 312.46484375 379.293945312 c 1 + 312.46484375 -100.021484375 l 1 + 262.461914062 -100.021484375 l 1 + 262.461914062 525.06640625 l 1 + 312.46484375 525.06640625 l 1 + 312.46484375 421.458007812 396.47265625 337.571289062 499.959960938 337.571289062 c 0 + 603.583007812 337.571289062 687.455078125 421.443359375 687.455078125 525.06640625 c 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: F +Encoding: 70 70 37 +Width: 1000 +HStem: -87.54 50.0029<201.279 373.707> 8.09668 50.0039<228.818 345.948> 592.196 20G<721.263 849.351> +VStem: 49.9648 50.0029<64.6349 149.958> 379.459 50.0039<91.595 149.958> 474.959 50.0029<64.6285 149.958> +LayerCount: 2 +Fore +SplineSet +379.458984375 149.958007812 m 1 + 429.462890625 149.958007812 l 1 + 429.462890625 71.65234375 365.87109375 8.0966796875 287.463867188 8.0966796875 c 0 + 209.170898438 8.0966796875 145.602539062 71.666015625 145.602539062 149.958007812 c 2 + 145.602539062 163.53125 l 1 + 375.866210938 313.0859375 606.130859375 462.640625 836.395507812 612.196289062 c 1 + 836.395507812 612.196289062 863.580146352 570.34025083 863.580146352 570.230664584 c 0 + 863.580146352 570.230564382 863.580123623 570.230499082 863.580078125 570.23046875 c 2 + 196.517578125 136.978515625 l 1 + 202.83203125 92.4208984375 241.174804688 58.1005859375 287.463867188 58.1005859375 c 0 + 338.318359375 58.1005859375 379.458984375 99.2783203125 379.458984375 149.958007812 c 1 +474.958984375 149.958007812 m 1 + 524.961914062 149.958007812 l 1 + 524.961914062 18.900390625 418.676757812 -87.5400390625 287.463867188 -87.5400390625 c 0 + 156.390625 -87.5400390625 49.96484375 18.8857421875 49.96484375 149.958007812 c 1 + 99.9677734375 149.958007812 l 1 + 99.9677734375 46.4853515625 183.990234375 -37.537109375 287.463867188 -37.537109375 c 0 + 391.072265625 -37.537109375 474.958984375 46.470703125 474.958984375 149.958007812 c 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: G +Encoding: 71 71 38 +Width: 1000 +HStem: 325.051 50.0039<50.0234 861.701> 571.603 48.3203<836.924 865.229> +VStem: 900.09 50.0039<413.309 536.316> +LayerCount: 2 +Fore +SplineSet +50.0234375 325.05078125 m 1 + 50.0234375 375.0546875 l 1 + 799.963867188 375.0546875 l 2 + 855.240234375 375.0546875 900.08984375 419.830078125 900.08984375 475.04296875 c 0 + 900.08984375 520.245117188 869.678710938 559.911132812 825.890625 571.602539062 c 1 + 838.79296875 619.922851562 l 1 + 904.435546875 602.396484375 950.09375 542.841796875 950.09375 475.04296875 c 0 + 950.09375 392.173828125 882.76953125 325.05078125 799.963867188 325.05078125 c 2 + 50.0234375 325.05078125 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: H +Encoding: 72 72 39 +Width: 1000 +HStem: 325.051 50.0039<50.0234 711.775 761.831 861.701> 571.606 48.3125<687.002 715.262 836.925 865.229> +VStem: 750.02 50.0029<413.047 536.317> 900.09 50.0039<413.309 536.316> +LayerCount: 2 +Fore +SplineSet +50.0234375 325.05078125 m 1 + 50.0234375 375.0546875 l 1 + 650.03125 375.0546875 l 2 + 705.28125 375.0546875 750.01953125 419.79296875 750.01953125 475.04296875 c 0 + 750.01953125 520.25390625 719.586914062 559.923828125 675.943359375 571.606445312 c 1 + 688.875 619.918945312 l 1 + 754.385742188 602.3828125 800.022460938 542.833007812 800.022460938 475.04296875 c 0 + 800.022460938 436.631835938 785.581054688 401.590820312 761.831054688 375.0546875 c 1 + 799.963867188 375.0546875 l 2 + 855.240234375 375.0546875 900.08984375 419.830078125 900.08984375 475.04296875 c 0 + 900.08984375 520.245117188 869.678710938 559.911132812 825.890625 571.602539062 c 1 + 838.79296875 619.922851562 l 1 + 904.435546875 602.396484375 950.09375 542.841796875 950.09375 475.04296875 c 0 + 950.09375 392.173828125 882.76953125 325.05078125 799.963867188 325.05078125 c 0 + 549.984375 325.05078125 300.00390625 325.05078125 50.0234375 325.05078125 c 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: I +Encoding: 73 73 40 +Width: 1000 +HStem: -25.0557 21G<649.973 699.976> 74.9326 50.0039<738.24 861.717> 325.051 50.0039<50.0234 861.701> +VStem: 649.973 50.0029<-25.0557 36.6689> 900.09 50.0039<163.29 286.797> +LayerCount: 2 +Fore +SplineSet +50.0234375 325.05078125 m 1 + 50.0234375 375.0546875 l 1 + 799.963867188 375.0546875 l 2 + 882.76953125 375.0546875 950.09375 307.931640625 950.09375 225.0625 c 0 + 950.09375 142.220703125 882.806640625 74.9326171875 799.963867188 74.9326171875 c 0 + 744.713867188 74.9326171875 699.975585938 30.1943359375 699.975585938 -25.0556640625 c 1 + 649.97265625 -25.0556640625 l 1 + 649.97265625 57.7763671875 717.1328125 124.936523438 799.963867188 124.936523438 c 0 + 855.203125 124.936523438 900.08984375 169.823242188 900.08984375 225.0625 c 0 + 900.08984375 280.275390625 855.240234375 325.05078125 799.963867188 325.05078125 c 2 + 50.0234375 325.05078125 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: J +Encoding: 74 74 41 +Width: 1000 +HStem: 635.511 21G<748.428 764.556> 644.901 50.0029<750.866 859.461> +VStem: 900.234 49.8099<482.989 605.351> +LayerCount: 2 +Fore +SplineSet +799.944335938 694.904296875 m 0x60 + 876.312599924 694.904296875 950.043945312 631.792684618 950.043945312 544.991210938 c 0 + 950.043945312 495.962890625 925.989257812 447.8203125 881.6171875 419.047851562 c 2 + 88.556640625 -95.9248046875 l 1 + 88.556640625 -95.9248046875 61.3759083259 -54.0658530885 61.3759765625 -53.95703125 c 2 + 854.462890625 461.033203125 l 2 + 883.27686253 479.717056627 900.234089376 511.632068394 900.234089376 544.934012478 c 0 + 900.234089376 602.28999499 850.960383691 644.901367188 799.944335938 644.901367188 c 0x60 + 785.801757812 644.901367188 771.390625 641.87890625 757.720703125 635.510742188 c 1xa0 + 757.720703125 635.510742188 736.648362791 680.743434254 736.6484375 680.86328125 c 0 + 757.004882812 690.346679688 778.5703125 694.904296875 799.944335938 694.904296875 c 0x60 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: K +Encoding: 75 75 42 +Width: 1000 +HStem: -99.9424 50.0029<159.37 950.035> 292.204 50.0039<207.78 318.904> +VStem: 357.13 49.8209<130.268 253.795> +LayerCount: 2 +Fore +SplineSet +950.03515625 -49.939453125 m 1 + 950.03515625 -99.9423828125 l 1 + 74.966796875 -99.9423828125 l 2 + 61.16796875 -99.9423828125 49.96484375 -88.740234375 49.96484375 -74.94140625 c 0 + 49.96484375 -66.15234375 54.509765625 -58.416015625 61.3759765625 -53.95703125 c 2 + 311.405273438 108.41015625 l 2 + 340.21166489 127.021147218 357.130269135 158.889538355 357.130269135 192.152992431 c 0 + 357.130269135 210.558961684 351.950060787 229.392077087 340.737304688 246.642578125 c 0 + 321.845703125 275.825195312 289.91015625 292.204101562 256.966796875 292.204101562 c 0 + 242.805664062 292.204101562 228.370117188 289.163085938 214.671875 282.748046875 c 1 + 214.671875 282.748046875 193.509688039 327.937179507 193.509688039 328.059330582 c 0 + 193.509688039 328.059465568 193.509713882 328.059545518 193.509765625 328.059570312 c 0 + 213.912109375 337.61328125 235.53515625 342.208007812 256.966796875 342.208007812 c 0 + 306.375 342.208007812 354.295898438 317.708984375 382.744140625 273.764648438 c 0 + 399.115234375 248.578125 406.951171875 220.284179688 406.951171875 192.213867188 c 0 + 406.951171875 143.197265625 382.891601562 95.0673828125 338.48828125 66.37890625 c 2 + 159.370117188 -49.939453125 l 1 + 950.03515625 -49.939453125 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: L +Encoding: 76 76 43 +Width: 1000 +HStem: -99.9424 50.0029<159.375 450.074> 635.511 21G<748.428 764.556> 644.901 50.0029<750.866 861.954> +VStem: 900.234 49.8099<482.989 606.569> +LayerCount: 2 +Fore +SplineSet +450.07421875 -99.9423828125 m 1xb0 + 74.966796875 -99.9423828125 l 2 + 61.16796875 -99.9423828125 49.96484375 -88.740234375 49.96484375 -74.94140625 c 0 + 49.96484375 -66.1513671875 54.509765625 -58.4150390625 61.3759765625 -53.95703125 c 2 + 854.462890625 461.033203125 l 2 + 883.27686253 479.717056627 900.234089376 511.632068394 900.234089376 544.934012478 c 0 + 900.234089376 563.331869343 895.058615426 582.153028445 883.84765625 599.400390625 c 0 + 864.948242188 628.517578125 832.953125 644.901367188 799.944335938 644.901367188 c 0xb0 + 785.801757812 644.901367188 771.390625 641.87890625 757.720703125 635.510742188 c 1xd0 + 757.720703125 635.510742188 736.648362791 680.743434254 736.648362791 680.863051227 c 0 + 736.648362791 680.863181215 736.648387676 680.863257928 736.6484375 680.86328125 c 0 + 757.004882812 690.346679688 778.5703125 694.904296875 799.944335938 694.904296875 c 0 + 849.369140625 694.904296875 897.3359375 670.458007812 925.821289062 626.573242188 c 0 + 942.192382812 601.38671875 950.043945312 573.06640625 950.043945312 544.991210938 c 0 + 950.043945312 495.962890625 925.989257812 447.8203125 881.6171875 419.047851562 c 2 + 159.375 -49.939453125 l 1 + 450.07421875 -49.939453125 l 1 + 450.07421875 -99.9423828125 l 1xb0 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: M +Encoding: 77 77 44 +Width: 1000 +HStem: -99.9424 50.0029<159.37 840.649> 292.204 50.0039<207.78 318.904 681.155 792.295> +VStem: 357.13 49.8209<130.268 253.795> 593.102 49.8288<130.257 253.79> +LayerCount: 2 +Fore +SplineSet +549.984375 -49.939453125 m 1 + 840.649414062 -49.939453125 l 1 + 661.409179688 66.3935546875 l 2 + 617.109375 95.0830078125 593.1015625 143.188476562 593.1015625 192.178710938 c 0 + 593.1015625 220.2578125 600.934570312 248.564453125 617.314453125 273.764648438 c 0 + 645.762695312 317.708984375 693.68359375 342.208007812 743.091796875 342.208007812 c 0 + 764.5234375 342.208007812 786.146484375 337.61328125 806.595703125 328.037109375 c 1 + 785.38671875 282.748046875 l 1 + 771.688476562 289.163085938 757.252929688 292.204101562 743.091796875 292.204101562 c 0 + 710.1484375 292.204101562 678.212890625 275.825195312 659.3203125 246.642578125 c 0 + 648.108915255 229.393658794 642.930401162 210.549255978 642.930401162 192.129052843 c 0 + 642.930401162 158.873719861 659.809098803 127.001010934 688.5390625 108.395507812 c 2 + 938.677734375 -53.9541015625 l 2 + 945.545898438 -58.412109375 950.09375 -66.1494140625 950.09375 -74.94140625 c 0 + 950.09375 -88.740234375 938.890625 -99.9423828125 925.091796875 -99.9423828125 c 2 + 549.984375 -99.9423828125 l 1 + 74.966796875 -99.9423828125 l 2 + 61.16796875 -99.9423828125 49.96484375 -88.740234375 49.96484375 -74.94140625 c 0 + 49.96484375 -66.15234375 54.509765625 -58.416015625 61.3759765625 -53.95703125 c 2 + 311.405273438 108.41015625 l 2 + 340.21166489 127.021147218 357.130269135 158.889538355 357.130269135 192.152992431 c 0 + 357.130269135 210.558961684 351.950060787 229.392077087 340.737304688 246.642578125 c 0 + 321.845703125 275.825195312 289.91015625 292.204101562 256.966796875 292.204101562 c 0 + 242.805664062 292.204101562 228.370117188 289.163085938 214.671875 282.748046875 c 1 + 214.671875 282.748046875 193.509688039 327.937179507 193.509688039 328.059330582 c 0 + 193.509688039 328.059465568 193.509713882 328.059545518 193.509765625 328.059570312 c 0 + 213.912109375 337.61328125 235.53515625 342.208007812 256.966796875 342.208007812 c 0 + 306.375 342.208007812 354.295898438 317.708984375 382.744140625 273.764648438 c 0 + 399.115234375 248.578125 406.951171875 220.284179688 406.951171875 192.213867188 c 0 + 406.951171875 143.197265625 382.891601562 95.0673828125 338.48828125 66.37890625 c 2 + 159.370117188 -49.939453125 l 1 + 549.984375 -49.939453125 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: N +Encoding: 78 78 45 +Width: 1000 +HStem: -99.9424 50.0029<50.0234 840.649> 292.204 50.0039<681.155 792.295> +VStem: 593.102 49.8288<130.257 253.79> +LayerCount: 2 +Fore +SplineSet +50.0234375 -99.9423828125 m 1 + 50.0234375 -49.939453125 l 1 + 840.649414062 -49.939453125 l 1 + 661.409179688 66.3935546875 l 2 + 617.109375 95.0830078125 593.1015625 143.188476562 593.1015625 192.178710938 c 0 + 593.1015625 220.2578125 600.934570312 248.564453125 617.314453125 273.764648438 c 0 + 645.762695312 317.708984375 693.68359375 342.208007812 743.091796875 342.208007812 c 0 + 764.5234375 342.208007812 786.146484375 337.61328125 806.595703125 328.037109375 c 1 + 785.38671875 282.748046875 l 2 + 771.688476562 289.163085938 757.252929688 292.204101562 743.091796875 292.204101562 c 0 + 710.1484375 292.204101562 678.212890625 275.825195312 659.3203125 246.642578125 c 0 + 648.108915255 229.393658794 642.930401162 210.549255978 642.930401162 192.129052843 c 0 + 642.930401162 158.873719861 659.809098803 127.001010934 688.5390625 108.395507812 c 2 + 938.677734375 -53.9541015625 l 2 + 945.545898438 -58.412109375 950.09375 -66.1494140625 950.09375 -74.94140625 c 0 + 950.09375 -88.740234375 938.890625 -99.9423828125 925.091796875 -99.9423828125 c 2 + 50.0234375 -99.9423828125 l 1 +EndSplineSet +Validated: 524289 +EndChar + +StartChar: O +Encoding: 79 79 46 +Width: 1000 +HStem: -87.54 50.0029<201.001 373.436 626.648 798.779> 702.622 21G<505.338 521.466> 712.013 50.0029<507.776 618.864> +VStem: 475.097 50.0029<64.6379 149.958> 657.144 49.8099<550.101 673.681> 900.09 50.0039<64.6349 149.958> +LayerCount: 2 +Fore +SplineSet +900.08984375 149.958007812 m 1xbc + 950.09375 149.958007812 l 1 + 950.09375 18.8857421875 843.666992188 -87.5400390625 712.594726562 -87.5400390625 c 0 + 619.55859375 -87.5400390625 539.0546875 -34.02734375 500.084960938 43.830078125 c 1 + 461.073242188 -34.0341796875 380.4921875 -87.5400390625 287.463867188 -87.5400390625 c 0 + 156.390625 -87.5400390625 49.96484375 18.8857421875 49.96484375 149.958007812 c 2 + 49.96484375 163.53125 l 1 + 237.100585938 285.069335938 424.237304688 406.606445312 611.373046875 528.14453125 c 0 + 640.18701878 546.829013796 657.144245626 578.743844222 657.144245626 612.045579582 c 0 + 657.144245626 630.443321135 651.968771676 649.26435657 640.7578125 666.51171875 c 0 + 621.858398438 695.62890625 589.86328125 712.012695312 556.854492188 712.012695312 c 0xbc + 542.711914062 712.012695312 528.30078125 708.990234375 514.630859375 702.622070312 c 1xdc + 514.630859375 702.622070312 493.558519041 747.855736822 493.558519041 747.975355911 c 0 + 493.558519041 747.975485902 493.558543926 747.975562616 493.55859375 747.975585938 c 0 + 513.915039062 757.458007812 535.48046875 762.015625 556.854492188 762.015625 c 0 + 606.279296875 762.015625 654.24609375 737.5703125 682.731445312 693.684570312 c 0 + 699.102539062 668.498046875 706.954101562 640.177734375 706.954101562 612.102539062 c 0 + 706.954101562 563.07421875 682.899414062 514.932617188 638.52734375 486.159179688 c 2 + 100.431640625 136.686523438 l 1 + 107.250976562 39.3955078125 188.452148438 -37.537109375 287.463867188 -37.537109375 c 0 + 391.086914062 -37.537109375 475.096679688 46.4921875 475.096679688 149.958007812 c 1 + 525.099609375 149.958007812 l 1 + 525.099609375 46.470703125 608.986328125 -37.537109375 712.594726562 -37.537109375 c 0 + 816.068359375 -37.537109375 900.08984375 46.4853515625 900.08984375 149.958007812 c 1xbc +EndSplineSet +Validated: 524289 +EndChar +EndChars +EndSplineFont diff --git a/fonts/metsymb/source/metsymb.tfm b/fonts/metsymb/source/metsymb.tfm new file mode 100644 index 0000000000..25b5cb5d3f Binary files /dev/null and b/fonts/metsymb/source/metsymb.tfm differ diff --git a/fonts/metsymb/source/metsymb_mwe.mplstyle b/fonts/metsymb/source/metsymb_mwe.mplstyle new file mode 100644 index 0000000000..1066d88ec3 --- /dev/null +++ b/fonts/metsymb/source/metsymb_mwe.mplstyle @@ -0,0 +1,2 @@ +text.usetex: True +text.latex.preamble: \usepackage{metsymb} diff --git a/fonts/metsymb/source/metsymb_mwe.pdf b/fonts/metsymb/source/metsymb_mwe.pdf new file mode 100644 index 0000000000..bf7209680b Binary files /dev/null and b/fonts/metsymb/source/metsymb_mwe.pdf differ diff --git a/fonts/metsymb/source/metsymb_mwe.py b/fonts/metsymb/source/metsymb_mwe.py new file mode 100755 index 0000000000..fd815162fa --- /dev/null +++ b/fonts/metsymb/source/metsymb_mwe.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +""" +Copyright (C) 2021 MeteoSwiss, +originally written by F.P.A. Vogt; frederic.vogt@meteoswiss.ch + +This file may be distributed and/or modified under the conditions +of the BSD-3-Clause License. +The terms of this license are available at: + +https://opensource.org/licenses/BSD-3-Clause + +SPDX-License-Identifier: BSD-3-Clause + +Module content: minimal working example of the metsymb LaTeX package +with matplotlib figures. +""" + +# Import matplotlib +from matplotlib import pyplot as plt + +# Set the proper rcparams elements +plt.style.use('./metsymb_mwe.mplstyle') + +# Create a basic figure with some demo text in the center. +plt.close(1) +plt.figure(1, figsize=(4, 0.5)) +plt.text(0.5, 0.5, + r'\LARGE Hello World: \threeoktas \nimbostratus \chIX', + ha='center') +plt.axis('off') + +# Export to different format and display on-screen. +plt.savefig('metsymb_mwe.pdf') +plt.savefig('metsymb_mwe.png') +#plt.show() diff --git a/fonts/metsymb/source/testfont.pdf b/fonts/metsymb/source/testfont.pdf new file mode 100644 index 0000000000..03b29a5474 Binary files /dev/null and b/fonts/metsymb/source/testfont.pdf differ diff --git a/fonts/metsymb/source/umetsymb.fd b/fonts/metsymb/source/umetsymb.fd new file mode 100644 index 0000000000..4e376dfc60 --- /dev/null +++ b/fonts/metsymb/source/umetsymb.fd @@ -0,0 +1,3 @@ +\ProvidesFile{umetsymb.fd} +\DeclareFontFamily{U}{metsymb}{} +\DeclareFontShape{U}{metsymb}{m}{n}{<-> metsymb}{} \ No newline at end of file diff --git a/fonts/parsianfonts/Parsian/Parsian-Bold.ttf b/fonts/parsianfonts/Parsian/Parsian-Bold.ttf index 5cd7bd1b5a..0ef7a18f85 100644 Binary files a/fonts/parsianfonts/Parsian/Parsian-Bold.ttf and b/fonts/parsianfonts/Parsian/Parsian-Bold.ttf differ diff --git a/fonts/parsianfonts/Parsian/Parsian-BoldItalic.ttf b/fonts/parsianfonts/Parsian/Parsian-BoldItalic.ttf index f6686df0b1..d0f17988bb 100644 Binary files a/fonts/parsianfonts/Parsian/Parsian-BoldItalic.ttf and b/fonts/parsianfonts/Parsian/Parsian-BoldItalic.ttf differ diff --git a/fonts/parsianfonts/Parsian/Parsian-Italic.ttf b/fonts/parsianfonts/Parsian/Parsian-Italic.ttf index 704fcedb99..c53487218a 100644 Binary files a/fonts/parsianfonts/Parsian/Parsian-Italic.ttf and b/fonts/parsianfonts/Parsian/Parsian-Italic.ttf differ diff --git a/fonts/parsianfonts/Parsian/Parsian-Regular.ttf b/fonts/parsianfonts/Parsian/Parsian-Regular.ttf index 766d2b9ae6..daccea57d6 100644 Binary files a/fonts/parsianfonts/Parsian/Parsian-Regular.ttf and b/fonts/parsianfonts/Parsian/Parsian-Regular.ttf differ diff --git a/fonts/parsianfonts/ParsianMono/ParsianMono-Bold.ttf b/fonts/parsianfonts/ParsianMono/ParsianMono-Bold.ttf index 57afb44e5d..bbac97874f 100644 Binary files a/fonts/parsianfonts/ParsianMono/ParsianMono-Bold.ttf and b/fonts/parsianfonts/ParsianMono/ParsianMono-Bold.ttf differ diff --git a/fonts/parsianfonts/ParsianMono/ParsianMono-BoldItalic.ttf b/fonts/parsianfonts/ParsianMono/ParsianMono-BoldItalic.ttf index 34370373e8..2255f13f2b 100644 Binary files a/fonts/parsianfonts/ParsianMono/ParsianMono-BoldItalic.ttf and b/fonts/parsianfonts/ParsianMono/ParsianMono-BoldItalic.ttf differ diff --git a/fonts/parsianfonts/ParsianMono/ParsianMono-Italic.ttf b/fonts/parsianfonts/ParsianMono/ParsianMono-Italic.ttf index 823e83383b..206c5e6ada 100644 Binary files a/fonts/parsianfonts/ParsianMono/ParsianMono-Italic.ttf and b/fonts/parsianfonts/ParsianMono/ParsianMono-Italic.ttf differ diff --git a/fonts/parsianfonts/ParsianMono/ParsianMono-Regular.ttf b/fonts/parsianfonts/ParsianMono/ParsianMono-Regular.ttf index 8ef3e30884..5721bc23e9 100644 Binary files a/fonts/parsianfonts/ParsianMono/ParsianMono-Regular.ttf and b/fonts/parsianfonts/ParsianMono/ParsianMono-Regular.ttf differ diff --git a/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Bold.ttf b/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Bold.ttf index e2e0aa7e36..ca53d2f112 100644 Binary files a/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Bold.ttf and b/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Bold.ttf differ diff --git a/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-BoldItalic.ttf b/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-BoldItalic.ttf index 6ed24efd98..50a32bfab6 100644 Binary files a/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-BoldItalic.ttf and b/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-BoldItalic.ttf differ diff --git a/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Italic.ttf b/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Italic.ttf index 714aced7af..c0d59cebe4 100644 Binary files a/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Italic.ttf and b/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Italic.ttf differ diff --git a/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Regular.ttf b/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Regular.ttf index 70361cce69..4520de5ca8 100644 Binary files a/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Regular.ttf and b/fonts/parsianfonts/ParsianNaskh/ParsianNaskh-Regular.ttf differ diff --git a/fonts/parsianfonts/ParsianSans/ParsianSans-Bold.ttf b/fonts/parsianfonts/ParsianSans/ParsianSans-Bold.ttf index 2a2e2eacca..e6864e3f0a 100644 Binary files a/fonts/parsianfonts/ParsianSans/ParsianSans-Bold.ttf and b/fonts/parsianfonts/ParsianSans/ParsianSans-Bold.ttf differ diff --git a/fonts/parsianfonts/ParsianSans/ParsianSans-BoldItalic.ttf b/fonts/parsianfonts/ParsianSans/ParsianSans-BoldItalic.ttf index 0a794f5cd8..7d9a27a662 100644 Binary files a/fonts/parsianfonts/ParsianSans/ParsianSans-BoldItalic.ttf and b/fonts/parsianfonts/ParsianSans/ParsianSans-BoldItalic.ttf differ diff --git a/fonts/parsianfonts/ParsianSans/ParsianSans-Italic.ttf b/fonts/parsianfonts/ParsianSans/ParsianSans-Italic.ttf index 2876a8c533..297eeb71f3 100644 Binary files a/fonts/parsianfonts/ParsianSans/ParsianSans-Italic.ttf and b/fonts/parsianfonts/ParsianSans/ParsianSans-Italic.ttf differ diff --git a/fonts/parsianfonts/ParsianSans/ParsianSans-Regular.ttf b/fonts/parsianfonts/ParsianSans/ParsianSans-Regular.ttf index a14f6343d0..c0f490eed6 100644 Binary files a/fonts/parsianfonts/ParsianSans/ParsianSans-Regular.ttf and b/fonts/parsianfonts/ParsianSans/ParsianSans-Regular.ttf differ diff --git a/fonts/parsianfonts/ParsianTeX/ParsianTeX-Bold.ttf b/fonts/parsianfonts/ParsianTeX/ParsianTeX-Bold.ttf index 426d2927dd..826bd7e346 100644 Binary files a/fonts/parsianfonts/ParsianTeX/ParsianTeX-Bold.ttf and b/fonts/parsianfonts/ParsianTeX/ParsianTeX-Bold.ttf differ diff --git a/fonts/parsianfonts/ParsianTeX/ParsianTeX-BoldItalic.ttf b/fonts/parsianfonts/ParsianTeX/ParsianTeX-BoldItalic.ttf index f7bfd38088..0cbbd09a6b 100644 Binary files a/fonts/parsianfonts/ParsianTeX/ParsianTeX-BoldItalic.ttf and b/fonts/parsianfonts/ParsianTeX/ParsianTeX-BoldItalic.ttf differ diff --git a/fonts/parsianfonts/ParsianTeX/ParsianTeX-Italic.ttf b/fonts/parsianfonts/ParsianTeX/ParsianTeX-Italic.ttf index fd143f22e1..00337bc30c 100644 Binary files a/fonts/parsianfonts/ParsianTeX/ParsianTeX-Italic.ttf and b/fonts/parsianfonts/ParsianTeX/ParsianTeX-Italic.ttf differ diff --git a/fonts/parsianfonts/ParsianTeX/ParsianTeX-Regular.ttf b/fonts/parsianfonts/ParsianTeX/ParsianTeX-Regular.ttf index 7335cc8e49..2cd3937c51 100644 Binary files a/fonts/parsianfonts/ParsianTeX/ParsianTeX-Regular.ttf and b/fonts/parsianfonts/ParsianTeX/ParsianTeX-Regular.ttf differ diff --git a/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Bold.ttf b/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Bold.ttf index b82bde8e12..83aaa937e6 100644 Binary files a/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Bold.ttf and b/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Bold.ttf differ diff --git a/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-BoldItalic.ttf b/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-BoldItalic.ttf index 1ebf321e52..3fee60764c 100644 Binary files a/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-BoldItalic.ttf and b/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-BoldItalic.ttf differ diff --git a/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Italic.ttf b/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Italic.ttf index c33fa603d2..3789b69a1d 100644 Binary files a/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Italic.ttf and b/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Italic.ttf differ diff --git a/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Regular.ttf b/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Regular.ttf index 8bf8d2defd..404b6dfd1c 100644 Binary files a/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Regular.ttf and b/fonts/parsianfonts/ParsianTeXClassic/ParsianTeXClassic-Regular.ttf differ diff --git a/fonts/parsianfonts/ParsianTitle/ParsianTitle-Italic.ttf b/fonts/parsianfonts/ParsianTitle/ParsianTitle-Italic.ttf index b42bed7982..a0dfb1de7b 100644 Binary files a/fonts/parsianfonts/ParsianTitle/ParsianTitle-Italic.ttf and b/fonts/parsianfonts/ParsianTitle/ParsianTitle-Italic.ttf differ diff --git a/fonts/parsianfonts/ParsianTitle/ParsianTitle-Regular.ttf b/fonts/parsianfonts/ParsianTitle/ParsianTitle-Regular.ttf index fcfe8aaca2..6d30119471 100644 Binary files a/fonts/parsianfonts/ParsianTitle/ParsianTitle-Regular.ttf and b/fonts/parsianfonts/ParsianTitle/ParsianTitle-Regular.ttf differ diff --git a/fonts/parsianfonts/README.md b/fonts/parsianfonts/README.md index cf1c57e8ca..1f5fa1904a 100644 --- a/fonts/parsianfonts/README.md +++ b/fonts/parsianfonts/README.md @@ -1,14 +1,52 @@ # parsianfonts -Version 1.0.2 +Version 1.0.3 +August 30, 2023 -This package containg seven persian font families - - Parsian. This font is based on the "Nazli" font, which itself is a free edition of the popular Nazanin font. - - Parsian Sans. A font based on the "Roya" font. The name of this font was chosen because of its similar structure to "Nazanin" font and its modern appearance. - - Parsian Mono. One of the best monospace fonts you can find that supports Persian language! Unlike other fonts that are based on other fonts, this one is designed by the author himself. - - Parsian TeX. Persian language support for TeX's default font, "Persian Modern". - - Parsian TeX Classic. One of the oldest Persian fonts used for typesetting scientific and academic texts is the default font of TeX-e-Parsi software. Some publishing houses still type their books with this font. The Parsian TeX Classic font allows you to use this old font in the latest versions of TeX and LaTeX. - - Parsian Title. Based on "Titr", which is a title font and is widely used in Persian printed texts. - - Parsian Naskh. The "Naskh" script provides good readability when used for official Persian texts. This font is based on "Yas" which is one of the most used fonts among TeX/LaTeX users. +This package containg seven persian font families. + ++ Parsian (GNU GPLv3) + - I used "XB Kayhan" (GNU GPLv3) for the Persian part with some modifications. More info at [1]. + - I used "FreeSerif" (GNU GPLv3) for the Latin/Greek/Cyrillic part with some modifications. More info at [2]. + ++ Parsian Sans (GNU GPLv3) + - I used "XB Roya" (GNU GPLv3) for the Persian part with some modifications. More info at [3]. + - I used "FreeSans" (GNU GPLv3) for the Latin/Greek/Cyrillic part with some modifications. More info at [4]. + ++ Parsian Mono (GNU GPLv3) + - I designed a complete Persian character set from scratch (GNU GPLv3). More info at [5]. + - I used "FreeMono" (GNU GPLv3) for the Latin/Greek/Cyrillic part with some modifications. More info at [6]. + ++ Parsian TeX (SIL OFLv1.1) + - I used "Parastoo" (SIL OFLv1.1) for the Persian part with some modifications. More info at [7]. + - I used "Computer Modern Unicode" (SIL OFLv1.1) for the Latin/Greek/Cyrillic part with some modifications. More info at [8]. + ++ Parsian TeX Classic (SIL OFLv1.1) + - I used "Farvardin" (SIL OFLv1.1) for the Persian part with some modifications. More info at [9]. + - I used "Computer Modern Unicode" (SIL OFLv1.1) for the Latin/Greek/Cyrillic part with some modifications. More info at [10]. + ++ Parsian Naskh (GNU GPLv3) + - I used "XB Yas" (GNU GPLv3) for the Persian part with some modifications. More info at [11]. + - I used "FreeSerif" (GNU GPLv3) for the Latin/Greek/Cyrillic part with some modifications. More info at [12]. + ++ Parsian Title (GNU GPLv3) + - I used "XB Titre" (GNU GPLv3) for the Persian part with some modifications. More info at [13]. + - I used "FreeSerif" (GNU GPLv3) for the Latin/Greek/Cyrillic part with some modifications. More info at [14]. + + + [1]: https://fontlibrary.org/en/font/xb-kayhan + [2]: https://www.fontsquirrel.com/fonts/gnu-free-font + [3]: https://fontlibrary.org/en/font/xb-roya + [4]: https://www.fontsquirrel.com/fonts/gnu-free-font + [5]: https://www.gnu.org/licenses/gpl-3.0.en.html + [6]: https://www.fontsquirrel.com/fonts/gnu-free-font + [7]: https://github.com/rastikerdar/parastoo-font/blob/master/LICENSE + [8]: https://ctan.org/pkg/cm-unicode + [9]: https://web.archive.org/web/20140712020048/http://www.scict.ir/portal/Home/Default.aspx?CategoryID=387eee4e-1cf4-48c7-a23e-034f9f840e3f + [10]: https://ctan.org/pkg/cm-unicode + [11]: https://fontlibrary.org/en/font/xb-yas + [12]: https://www.fontsquirrel.com/fonts/gnu-free-font + [13]: https://fontlibrary.org/en/font/xb-titre + [14]: https://www.fontsquirrel.com/fonts/gnu-free-font ============================================================ @@ -24,6 +62,8 @@ This material is subject to the LaTeX Project Public License. See https://ctan.org/license/lppl1.3c -for the details of that license. +for the details of that license. + +=========================================================== To get help, please visit or emai the author at . \ No newline at end of file diff --git a/fonts/parsianfonts/parsianfonts-samples.pdf b/fonts/parsianfonts/parsianfonts-samples.pdf index 9d121fae03..7b0bf83f36 100644 Binary files a/fonts/parsianfonts/parsianfonts-samples.pdf and b/fonts/parsianfonts/parsianfonts-samples.pdf differ diff --git a/fonts/parsianfonts/parsianfonts-samples.tex b/fonts/parsianfonts/parsianfonts-samples.tex index c504a6a6cf..e32b446c30 100644 --- a/fonts/parsianfonts/parsianfonts-samples.tex +++ b/fonts/parsianfonts/parsianfonts-samples.tex @@ -11,7 +11,7 @@ \settextfont{Parsian} \setlatintextfont{Parsian} -\title{\lr{``Parsian'' Font Samples (version 1.0.2)}} +\title{\lr{``Parsian'' Font Samples (version 1.0.3)}} \author{\lr{Sajad Kazemi} \\ \lr{\texttt{sajad.kazemi.ctan@gmail.com}} \\ \lr{\texttt{https://github.com/SajadKazemi}}} @@ -31,7 +31,7 @@ Empowering the world to develope technology through collective knowledge. 012345 \end{center} } -\newcommand{\setfont}[2]{% +\newcommand{\setfont}[1]{% \settextfont{#1}% \setlatintextfont{#1}% } @@ -43,33 +43,35 @@ Empowering the world to develope technology through collective knowledge. 012345 \vspace*{2cm} + \begin{latin} {\large \textbf{Font list}} -\begin{itemize}[labelindent=0pt,leftmargin=10pt] -\item \textbf{Parsian:} Nazli (Persian) + FreeSerif (Latin, Cyrillic, Greek) -\item \textbf{Parsian Sans:} Roya (Persian) + FreeSans (Latin, Cyrillic, Greek) -\item \textbf{Parsian Mono:} Rubik (Persian) + FreeMono (Latin, Cyrillic, Greek) -\item \textbf{Parsian TeX:} Parastoo (Persian) + Computer Modern (Latin, Cyrillic, Greek) -\item \textbf{Parsian TeX Classic:} Farvardin (of TeX-e-Parsi) (Persian) + Computer Modern (Latin, Cyrillic, Greek) -\item \textbf{Parsian Naskh:} Yas (Persian) + FreeSerif (Latin, Cyrillic, Greek) -\item \textbf{Parsian Title:} Titr (Persian) + FreeSerif (Latin, Cyrillic, Greek) +\begin{itemize}[labelindent=10pt,leftmargin=10pt] +\item \textbf{Parsian:} Serif text font -- Regular, Italic, Bold, BoldItalic. +\item \textbf{Parsian Sans:} Sans Serif text font -- Regular, Italic, Bold, BoldItalic. +\item \textbf{Parsian Mono:} Mono-spaced text font -- Regular, Italic, Bold, BoldItalic. +\item \textbf{Parsian TeX:} Persian support for \TeX\ font -- Regular, Italic, Bold, BoldItalic. +\item \textbf{Parsian TeX Classic:} Persian support for \TeX\ font with a classic look -- Regular, Italic, Bold, BoldItalic. +\item \textbf{Parsian Naskh:} Serif text font using Naskh\footnote{\rl{نَسخ}} style for Persian -- Regular, Italic, Bold, BoldItalic. +\item \textbf{Parsian Title:} Display font suitable for headings and titles -- Regular, Italic. \end{itemize} \end{latin} + \newpage \section*{پارسیان (\lr{Parsian})} -\subsection*{عادی (\lr{Regular})} +\subsubsection*{عادی (\lr{Regular})} {\sample} -\subsection*{خوابیده به راست (\lr{Italic})} +\subsubsection*{خوابیده به راست (\lr{Italic})} {\itshape \sample} -\subsection*{پررنگ (\lr{Bold})} +\subsubsection*{پررنگ (\lr{Bold})} {\bfseries \sample} -\subsection*{خوابیده به راست پررنگ (\lr{Bold Italic})} +\subsubsection*{خوابیده به راست پررنگ (\lr{Bold Italic})} {\bfseries \itshape \sample} @@ -80,16 +82,16 @@ Empowering the world to develope technology through collective knowledge. 012345 \section*{پارسیان سنس (\lr{Parsian Sans})} -\subsection*{عادی (\lr{Regular})} +\subsubsection*{عادی (\lr{Regular})} {\sample} -\subsection*{خوابیده به راست (\lr{Italic})} +\subsubsection*{خوابیده به راست (\lr{Italic})} {\itshape \sample} -\subsection*{پررنگ (\lr{Bold})} +\subsubsection*{پررنگ (\lr{Bold})} {\bfseries \sample} -\subsection*{خوابیده به راست پررنگ (\lr{Bold Italic})} +\subsubsection*{خوابیده به راست پررنگ (\lr{Bold Italic})} {\bfseries \itshape \sample} @@ -98,16 +100,16 @@ Empowering the world to develope technology through collective knowledge. 012345 \section*{پارسیان مونو (\lr{Parsian Mono})} -\subsection*{عادی (\lr{Regular})} +\subsubsection*{عادی (\lr{Regular})} {\sample} -\subsection*{خوابیده به راست (\lr{Italic})} +\subsubsection*{خوابیده به راست (\lr{Italic})} {\itshape \sample} -\subsection*{پررنگ (\lr{Bold})} +\subsubsection*{پررنگ (\lr{Bold})} {\bfseries \sample} -\subsection*{خوابیده به راست پررنگ (\lr{Bold Italic})} +\subsubsection*{خوابیده به راست پررنگ (\lr{Bold Italic})} {\bfseries \itshape \sample} @@ -116,16 +118,16 @@ Empowering the world to develope technology through collective knowledge. 012345 \section*{پارسیان تِک (\lr{Parsian TeX})} -\subsection*{عادی (\lr{Regular})} +\subsubsection*{عادی (\lr{Regular})} {\sample} -\subsection*{خوابیده به راست (\lr{Italic})} +\subsubsection*{خوابیده به راست (\lr{Italic})} {\itshape \sample} -\subsection*{پررنگ (\lr{Bold})} +\subsubsection*{پررنگ (\lr{Bold})} {\bfseries \sample} -\subsection*{خوابیده به راست پررنگ (\lr{Bold Italic})} +\subsubsection*{خوابیده به راست پررنگ (\lr{Bold Italic})} {\bfseries \itshape \sample} @@ -134,16 +136,16 @@ Empowering the world to develope technology through collective knowledge. 012345 \section*{پارسیان تِک کلاسیک (\lr{Parsian TeX Classic})} -\subsection*{عادی (\lr{Regular})} +\subsubsection*{عادی (\lr{Regular})} {\sample} -\subsection*{خوابیده به راست (\lr{Italic})} +\subsubsection*{خوابیده به راست (\lr{Italic})} {\itshape \sample} -\subsection*{پررنگ (\lr{Bold})} +\subsubsection*{پررنگ (\lr{Bold})} {\bfseries \sample} -\subsection*{خوابیده به راست پررنگ (\lr{Bold Italic})} +\subsubsection*{خوابیده به راست پررنگ (\lr{Bold Italic})} {\bfseries \itshape \sample} \newpage @@ -151,16 +153,16 @@ Empowering the world to develope technology through collective knowledge. 012345 \section*{پارسیان نسخ (\lr{Parsian Naskh})} -\subsection*{عادی (\lr{Regular})} +\subsubsection*{عادی (\lr{Regular})} {\sample} -\subsection*{خوابیده به راست (\lr{Italic})} +\subsubsection*{خوابیده به راست (\lr{Italic})} {\itshape \sample} -\subsection*{پررنگ (\lr{Bold})} +\subsubsection*{پررنگ (\lr{Bold})} {\bfseries \sample} -\subsection*{خوابیده به راست پررنگ (\lr{Bold Italic})} +\subsubsection*{خوابیده به راست پررنگ (\lr{Bold Italic})} {\bfseries \itshape \sample} \newpage @@ -168,10 +170,10 @@ Empowering the world to develope technology through collective knowledge. 012345 \section*{پارسیان عنوان (\lr{Parsian Title})} -\subsection*{عادی (\lr{Regular})} +\subsubsection*{عادی (\lr{Regular})} {\sample} -\subsection*{خوابیده به راست (\lr{Italic})} +\subsubsection*{خوابیده به راست (\lr{Italic})} {\itshape \sample} diff --git a/graphics/pgf/contrib/hobby/README b/graphics/pgf/contrib/hobby/README new file mode 100644 index 0000000000..04af0731d6 --- /dev/null +++ b/graphics/pgf/contrib/hobby/README @@ -0,0 +1,14 @@ +---------------------------------------------------------------- +hobby --- a TikZ/PGF library for drawing smooth(ish) curves using + Hobby's algorithm (implemented in LaTeX3) +E-mail: loopspace@mathforge.org +Released under the LaTeX Project Public License v1.3c or later +See http://www.latex-project.org/lppl.txt +---------------------------------------------------------------- + +This package defines a path generation function for TikZ/PGF +which implements Hobby's algorithm for a path built out of Bezier +curves which passes through a given set of points. + +The implementation is in LaTeX3. It can be used as as a TikZ +`to path`. diff --git a/graphics/pgf/contrib/hobby/README.txt b/graphics/pgf/contrib/hobby/README.txt deleted file mode 100644 index 04af0731d6..0000000000 --- a/graphics/pgf/contrib/hobby/README.txt +++ /dev/null @@ -1,14 +0,0 @@ ----------------------------------------------------------------- -hobby --- a TikZ/PGF library for drawing smooth(ish) curves using - Hobby's algorithm (implemented in LaTeX3) -E-mail: loopspace@mathforge.org -Released under the LaTeX Project Public License v1.3c or later -See http://www.latex-project.org/lppl.txt ----------------------------------------------------------------- - -This package defines a path generation function for TikZ/PGF -which implements Hobby's algorithm for a path built out of Bezier -curves which passes through a given set of points. - -The implementation is in LaTeX3. It can be used as as a TikZ -`to path`. diff --git a/graphics/pgf/contrib/hobby/hobby.dtx b/graphics/pgf/contrib/hobby/hobby.dtx deleted file mode 100644 index d555a5b2f3..0000000000 --- a/graphics/pgf/contrib/hobby/hobby.dtx +++ /dev/null @@ -1,3500 +0,0 @@ -% \iffalse meta-comment -%<*internal> -\iffalse -% -%<*readme> ----------------------------------------------------------------- -hobby --- a TikZ/PGF library for drawing smooth(ish) curves using - Hobby's algorithm (implemented in LaTeX3) -E-mail: loopspace@mathforge.org -Released under the LaTeX Project Public License v1.3c or later -See http://www.latex-project.org/lppl.txt ----------------------------------------------------------------- - -This package defines a path generation function for TikZ/PGF -which implements Hobby's algorithm for a path built out of Bezier -curves which passes through a given set of points. - -The implementation is in LaTeX3. It can be used as as a TikZ -`to path`. -% -%<*internal> -\fi -\def\nameofplainTeX{plain} -\ifx\fmtname\nameofplainTeX\else - \expandafter\begingroup -\fi -% -%<*install> -\input docstrip.tex -\keepsilent -\askforoverwritefalse -\preamble ----------------------------------------------------------------- -hobby --- a TikZ/PGF library for drawing smooth(ish) curves using - Hobby's algorithm (implemented in LaTeX3) -E-mail: loopspace@mathforge.org -Released under the LaTeX Project Public License v1.3c or later -See http://www.latex-project.org/lppl.txt ----------------------------------------------------------------- - -\endpreamble -\postamble - -Copyright (C) 2012 by Andrew Stacey - -This file may be distributed and/or modified under the conditions -of the LaTeX Project Public License, either version 1.3 of this -license or (at your option) any later version. -The latest version of this license is in: - - http://www.latex-project.org/lppl.txt - -and version 1.3 or later is part of all distributions of LaTeX -version 2005/12/01 or later. - -This work is "maintained" (as per LPPL maintenance status) by -Andrew Stacey. - -This work consists of the files hobby.dtx - hobby_doc.tex -and the derived files hobby.code.tex - pgflibraryhobby.code.tex - tikzlibraryhobby.code.tex - pml3array.sty - hobby.ins - hobby.pdf - hobby_code.pdf - README.txt - -\endpostamble -\usedir{tex/latex/hobby} -\generate{\file{tikzlibraryhobby.code.tex} {\from{hobby.dtx}{tikzlibrary}}} -\generate{\file{pgflibraryhobby.code.tex} {\from{hobby.dtx}{pgflibrary}}} -\generate{\file{hobby.code.tex} -{\from{hobby.dtx}{hobby}}} -\generate{\file{pml3array.sty} -{\from{hobby.dtx}{array}}} -% -%\endbatchfile -%<*internal> -\usedir{source/latex/hobby} -\generate{ - \file{\jobname.ins}{\from{\jobname.dtx}{install}} -} -\nopreamble\nopostamble -\generate{ - \file{README.txt}{\from{\jobname.dtx}{readme}} -} -\ifx\fmtname\nameofplainTeX - \expandafter\endbatchfile -\else - \expandafter\endgroup -\fi -% -%<*driver> -\documentclass[full]{l3doc} -\usepackage[T1]{fontenc} -\usepackage{csquotes} -\usepackage{lmodern} -\usepackage{tikz} -\usepackage{amsmath} -\usetikzlibrary{hobby,decorations.pathreplacing} -\usepackage[margin=3cm]{geometry} -\EnableCrossrefs -\CodelineIndex -\RecordChanges -\addtolength{\hoffset}{.4in} -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -% -% \fi -% -% \CheckSum{3382} -% -% \CharacterTable -% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z -% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z -% Digits \0\1\2\3\4\5\6\7\8\9 -% Exclamation \! Double quote \" Hash (number) \# -% Dollar \$ Percent \% Ampersand \& -% Acute accent \' Left paren \( Right paren \) -% Asterisk \* Plus \+ Comma \, -% Minus \- Point \. Solidus \/ -% Colon \: Semicolon \; Less than \< -% Equals \= Greater than \> Question mark \? -% Commercial at \@ Left bracket \[ Backslash \\ -% Right bracket \] Circumflex \^ Underscore \_ -% Grave accent \` Left brace \{ Vertical bar \| -% Right brace \} Tilde \~} -% -% -% -% \DoNotIndex{\newcommand,\newenvironment} -% -% \providecommand*{\url}{\texttt} -% \title{The \textsf{Hobby} package: code} -% \author{Andrew Stacey \\ \url{loopspace@mathforge.org}} -% \date{\hobbyVersion\ from\ \hobbyDate} -% \maketitle -% -% -% \StopEventually{\PrintChanges} -% \section{Implementation} -% -% \subsection{Main Code} -% -% \iffalse -%<*hobby> -% \fi -% -% We use \LaTeX3 syntax so need to load the requisite packages -% \begin{macrocode} -\RequirePackage{expl3} -\RequirePackage{xparse} -\RequirePackage{pml3array} -\ExplSyntaxOn -% \end{macrocode} -% -% \begin{macrocode} -\cs_generate_variant:Nn \fp_set:Nn {Nx} -\cs_generate_variant:Nn \tl_if_eq:nnTF {VnTF} -\cs_generate_variant:Nn \tl_if_eq:nnTF {xnTF} -% \end{macrocode} -% -% \subsubsection{Initialisation} -% -% We declare all our variables. -% -% Start with version and date, together with a check to see if we've been loaded twice (fail gracefully if so). -% -% \begin{macrocode} -\tl_clear:N \l_tmpa_tl -\tl_if_exist:NT \g__hobby_version -{ - \tl_set:Nn \l_tmpa_tl { - \ExplSyntaxOff - \tl_clear:N \l_tmpa_tl - \endinput - } -} -\tl_use:N \l_tmpa_tl - -\tl_new:N \g__hobby_version -\tl_new:N \g__hobby_date -\tl_set:Nn \g__hobby_version {1.8} -\tl_set:Nn \g__hobby_date {2017-06-01} -\DeclareDocumentCommand \hobbyVersion {} -{ - \tl_use:N \g__hobby_version -} -\DeclareDocumentCommand \hobbyDate {} -{ - \tl_use:N \g__hobby_date -} -% \end{macrocode} -% -% The function for computing the lengths of the control points depends on three parameters. -% These are set to \(a = \sqrt{2}\), \(b = 1/16\), and \(c = \frac{3 - \sqrt{5}}{2}\). -% \begin{macrocode} -\fp_new:N \g_hobby_parama_fp -\fp_new:N \g_hobby_paramb_fp -\fp_new:N \g_hobby_paramc_fp -\fp_gset:Nn \g_hobby_parama_fp {2^.5} -\fp_gset:Nn \g_hobby_paramb_fp {1/16} -\fp_gset:Nn \g_hobby_paramc_fp {(3-5^.5)/2} -% \end{macrocode} -% -% Now we define our objects for use in generating the path. -% -% \begin{macro}{\l_hobby_closed_bool} -% \Verb+\l_hobby_closed_bool+ is \Verb+true+ if the path is closed. -% \begin{macrocode} -\bool_new:N \l_hobby_closed_bool -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_disjoint_bool} -% \Verb+\l_hobby_disjoint_bool+ is \Verb+true+ if the path should start with a \Verb+moveto+ command. -% \begin{macrocode} -\bool_new:N \l_hobby_disjoint_bool -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_save_aux_bool} -% \Verb+\l_hobby_save_aux_bool+ is \Verb+true+ if when saving paths then they should be saved to the \Verb+aux+ file. -% \begin{macrocode} -\bool_new:N \l_hobby_save_aux_bool -\bool_set_true:N \l_hobby_save_aux_bool -\DeclareDocumentCommand \HobbyDisableAux {} -{ - \bool_set_false:N \l_hobby_save_aux_bool -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_points_array} -% \Verb+\l_hobby_points_array+ is an array holding the specified points on the path. -% In the \LaTeX3 code, a ``point'' is a token list of the form \Verb+x = , y = +. -% This gives us the greatest flexibility in passing points back and forth between the \LaTeX3 code and any calling code. -% The array is indexed by integers beginning with \(0\). -% In the documentation, we will use the notation \(z_k\) to refer to the \(k\)th point. -% \begin{macrocode} -\array_new:N \l_hobby_points_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_points_x_array} -% \Verb+\l_hobby_points_x_array+ is an array holding the \(x\)--{}coordinates of the specified points. -% \begin{macrocode} -\array_new:N \l_hobby_points_x_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_points_y_array} -% \Verb+\l_hobby_points_y_array+ is an array holding the \(y\)--{}coordinates of the specified points. -% \begin{macrocode} -\array_new:N \l_hobby_points_y_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_actions_array} -% \Verb+\l_hobby_actions_array+ is an array holding the (encoded) action to be taken out on the segment of the path ending at that point. -% \begin{macrocode} -\array_new:N \l_hobby_actions_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_angles_array} -% \Verb+\l_hobby_angles_array+ is an array holding the angles of the lines between the points. -% Specifically, the angle indexed by \(k\) is the angle in radians of the line from \(z_k\) to \(z_{k+1}\). -% \begin{macrocode} -\array_new:N \l_hobby_angles_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_distances_array} -% \Verb+\l_hobby_distances_array+ is an array holding the distances between the points. -% Specifically, the distance indexed by \(k\), which we will write as \(d_k\), is the length of the line from \(z_k\) to \(z_{k+1}\). -% \begin{macrocode} -\array_new:N \l_hobby_distances_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_tension_out_array} -% \Verb+\l_hobby_tension_out_array+ is an array holding the tension for the path as it leaves each point. -% This is a parameter that controls how much the curve ``flexes'' as it leaves the point. -% In the following, this will be written \(\tau_k\). -% \begin{macrocode} -\array_new:N \l_hobby_tension_out_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_tension_in_array} -% \Verb+\l_hobby_tension_in_array+ is an array holding the tension for the path as it arrives at each point. -% This is a parameter that controls how much the curve ``flexes'' as it gets to the point. -% In the following, this will be written \(\overline{\tau}_k\). -% \begin{macrocode} -\array_new:N \l_hobby_tension_in_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_matrix_a_array} -% \Verb+\l_hobby_matrix_a_array+ is an array holding the subdiagonal of the linear system that has to be solved to find the angles of the control points. -% In the following, this will be denoted by \(A_i\). -% The first index is \(1\). -% \begin{macrocode} -\array_new:N \l_hobby_matrix_a_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_matrix_b_array} -% \Verb+\l_hobby_matrix_b_array+ is an array holding the diagonal of the linear system that has to be solved to find the angles of the control points. -% In the following, this will be denoted by \(B_i\). -% The first index is \(0\). -% \begin{macrocode} -\array_new:N \l_hobby_matrix_b_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_matrix_c_array} -% \Verb+\l_hobby_matrix_c_array+ is an array holding the superdiagonal of the linear system that has to be solved to find the angles of the control points. -% In the following, this will be denoted by \(C_i\). -% The first index is \(0\). -% \begin{macrocode} -\array_new:N \l_hobby_matrix_c_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_matrix_d_array} -% \Verb+\l_hobby_matrix_d_array+ is an array holding the target vector of the linear system that has to be solved to find the angles of the control points. -% In the following, this will be denoted by \(D_i\). -% The first index is \(1\). -% \begin{macrocode} -\array_new:N \l_hobby_matrix_d_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_vector_u_array} -% \Verb+\l_hobby_vector_u_array+ is an array holding the perturbation of the linear system for closed paths. -% The coefficient matrix for an \emph{open} path is tridiagonal and that means that Gaussian elimination runs faster than expected (\(O(n)\) instead of \(O(n^3)\)). -% The matrix for a closed path is not tridiagonal but is not far off. -% It can be solved by perturbing it to a tridiagonal matrix and then modifying the result. -% This array represents a utility vector in that perturbation. -% In the following, the vector will be denoted by \(u\). -% The first index is \(1\). -% \begin{macrocode} -\array_new:N \l_hobby_vector_u_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_excess_angle_array} -% \Verb+\l_hobby_excess_angle_array+ is an array that allows the user to say that the algorithm should add a multiple of \(2 \pi\) to the angle differences. -% This is because these angles are wrapped to the interval \((-\pi,\pi]\) but the wrapping might go wrong near the end points due to computation accuracy. -% The first index is \(1\). -% \begin{macrocode} -\array_new:N \l_hobby_excess_angle_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_psi_array} -% \Verb+\l_hobby_psi_array+ is an array holding the difference of the angles of the lines entering and exiting a point. -% That is, \(\psi_k\) is the angle between the lines joining \(z_k\) to \(z_{k-1}\) and \(z_{k+1}\). -% The first index is \(1\). -% \begin{macrocode} -\array_new:N \l_hobby_psi_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_theta_array} -% \Verb+\l_hobby_theta_array+ is an array holding the angles of the outgoing control points for the generated path. -% These are measured relative to the line joining the point to the next point on the path. -% The first index is \(0\). -% \begin{macrocode} -\array_new:N \l_hobby_theta_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_phi_array} -% \Verb+\l_hobby_phi_array+ is an array holding the angles of the incoming control points for the generated path. -% These are measured relative to the line joining the point to the previous point on the path. -% The first index is \(1\). -% \begin{macrocode} -\array_new:N \l_hobby_phi_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_sigma_array} -% \Verb+\l_hobby_sigma_array+ is an array holding the lengths of the outgoing control points for the generated path. -% The units are such that the length of the line to the next specified point is one unit. -% \begin{macrocode} -\array_new:N \l_hobby_sigma_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_rho_array} -% \Verb+\l_hobby_rho_array+ is an array holding the lengths of the incoming control points for the generated path. -% The units are such that the length of the line to the previous specified point is one unit. -% \begin{macrocode} -\array_new:N \l_hobby_rho_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_controla_array} -% \Verb+\l_hobby_controla_array+ is an array holding the coordinates of the first control points on the curves. -% The format is the same as for \Verb+\l_hobby_points_array+. -% \begin{macrocode} -\array_new:N \l_hobby_controla_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_controlb_array} -% \Verb+\l_hobby_controlb_array+ is an array holding the coordinates of the second control points on the curves. -% The format is the same as for \Verb+\l_hobby_points_array+. -% \begin{macrocode} -\array_new:N \l_hobby_controlb_array -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_matrix_v_fp} -% \Verb+\l_hobby_matrix_v_fp+ is a number which is used when doing the perturbation of the solution of the linear system for a closed curve. -% There is actually a vector, \(v\), that this corresponds to but that vector only has one component that needs computation. -% \begin{macrocode} -\fp_new:N \l_hobby_matrix_v_fp -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_tempa_fp} -% \Verb+\l_hobby_tempa_fp+ is a temporary variable of type \Verb+fp+. -% \begin{macrocode} -\fp_new:N \l_hobby_tempa_fp -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_tempb_fp} -% \Verb+\l_hobby_tempb_fp+ is a temporary variable of type \Verb+fp+. -% \begin{macrocode} -\fp_new:N \l_hobby_tempb_fp -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_tempc_fp} -% \Verb+\l_hobby_tempc_fp+ is a temporary variable of type \Verb+fp+. -% \begin{macrocode} -\fp_new:N \l_hobby_tempc_fp -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_tempd_fp} -% \Verb+\l_hobby_tempd_fp+ is a temporary variable of type \Verb+fp+. -% \begin{macrocode} -\fp_new:N \l_hobby_tempd_fp -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_temps_fp} -% \Verb+\l_hobby_temps_fp+ is a temporary variable of type \Verb+fp+. -% \begin{macrocode} -\fp_new:N \l_hobby_temps_fp -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_in_curl_fp} -% \Verb+\l_hobby_in_curl_fp+ is the ``curl'' at the end of an open path. -% This is used if the angle at the end is not specified. -% \begin{macrocode} -\fp_new:N \l_hobby_in_curl_fp -\fp_set:Nn \l_hobby_in_curl_fp {1} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_out_curl_fp} -% \Verb+\l_hobby_out_curl_fp+ is the ``curl'' at the start of an open path. -% This is used if the angle at the start is not specified. -% \begin{macrocode} -\fp_new:N \l_hobby_out_curl_fp -\fp_set:Nn \l_hobby_out_curl_fp {1} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_in_angle_fp} -% \Verb+\l_hobby_in_angle_fp+ is the angle at the end of an open path. -% If this is not specified, it will be computed automatically. -% It is set to \Verb+\c_inf_fp+ to allow easy detection of when it has been specified. -% \begin{macrocode} -\fp_new:N \l_hobby_in_angle_fp -\fp_set_eq:NN \l_hobby_in_angle_fp \c_inf_fp -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_out_angle_fp} -% \Verb+\l_hobby_out_angle_fp+ is the angle at the start of an open path. -% If this is not specified, it will be computed automatically. -% It is set to \Verb+\c_inf_fp+ to allow easy detection of when it has been specified. -% \begin{macrocode} -\fp_new:N \l_hobby_out_angle_fp -\fp_set_eq:NN \l_hobby_out_angle_fp \c_inf_fp -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_npoints_int} -% \Verb+\l_hobby_npoints_int+ is one less than the number of points on the curve. -% As our list of points starts at \(0\), this is the index of the last point. -% In the algorithm for a closed curve, some points are repeated whereupon this is incremented so that it is always the index of the last point. -% \begin{macrocode} -\int_new:N \l_hobby_npoints_int -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_hobby_draw_int} -% \begin{macrocode} -\int_new:N \l_hobby_draw_int -% \end{macrocode} -% \end{macro} -% -% A ``point'' is a key-value list setting the x-value, the y-value, and the tensions at that point. -% Using keys makes it easier to pass points from the algorithm code to the calling code and vice versa without either knowing too much about the other. -% \begin{macrocode} -\keys_define:nn {hobby / read in all} { - x .fp_set:N = \l_hobby_tempa_fp, - y .fp_set:N = \l_hobby_tempb_fp, - tension~out .fp_set:N = \l_hobby_tempc_fp, - tension~in .fp_set:N = \l_hobby_tempd_fp, - excess~angle .fp_set:N = \l_hobby_temps_fp, - break .tl_set:N = \l_tmpb_tl, - blank .tl_set:N = \l_tmpa_tl, - tension .meta:n = { tension~out=#1, tension~in=#1 }, - break .default:n = false, - blank .default:n = false, - invert~soft~blanks .choice:, - invert~soft~blanks / true .code:n = { - \int_gset:Nn \l_hobby_draw_int {0} - }, - invert~soft~blanks / false .code:n = { - \int_gset:Nn \l_hobby_draw_int {1} - }, - invert~soft~blanks .default:n = true, - tension~out .default:n = 1, - tension~in .default:n = 1, - excess~angle .default:n = 0, - in~angle .fp_gset:N = \l_hobby_in_angle_fp, - out~angle .fp_gset:N = \l_hobby_out_angle_fp, - in~curl .fp_gset:N = \l_hobby_in_curl_fp, - out~curl .fp_gset:N = \l_hobby_out_curl_fp, - closed .bool_gset:N = \l_hobby_closed_bool, - closed .default:n = true, - disjoint .bool_gset:N = \l_hobby_disjoint_bool, - disjoint .default:n = true, - break~default .code:n = { - \keys_define:nn { hobby / read in all } - { - break .default:n = #1 - } - }, - blank~default .code:n = { - \keys_define:nn { hobby / read in all } - { - blank .default:n = #1 - } - }, -} -% \end{macrocode} -% There are certain other parameters that can be set for a given curve. -% \begin{macrocode} -\keys_define:nn { hobby / read in params} { - in~angle .fp_gset:N = \l_hobby_in_angle_fp, - out~angle .fp_gset:N = \l_hobby_out_angle_fp, - in~curl .fp_gset:N = \l_hobby_in_curl_fp, - out~curl .fp_gset:N = \l_hobby_out_curl_fp, - closed .bool_gset:N = \l_hobby_closed_bool, - closed .default:n = true, - disjoint .bool_gset:N = \l_hobby_disjoint_bool, - disjoint .default:n = true, - break~default .code:n = { - \keys_define:nn { hobby / read in all } - { - break .default:n = #1 - } - }, - blank~default .code:n = { - \keys_define:nn { hobby / read in all } - { - blank .default:n = #1 - } - }, - invert~soft~blanks .choice:, - invert~soft~blanks / true .code:n = { - \int_gset:Nn \l_hobby_draw_int {0} - }, - invert~soft~blanks / false .code:n = { - \int_gset:Nn \l_hobby_draw_int {1} - }, - invert~soft~blanks .default:n = true, -} -% \end{macrocode} -% \begin{macro}{\hobby_distangle:n} -% Computes the distance and angle between successive points. -% The argument given is the index of the current point. -% Assumptions: the points are in \Verb+\l_hobby_points_x_array+ and \Verb+\l_hobby_points_y_array+ and the index of the last point is \Verb+\l_hobby_npoints_int+. -% \begin{macrocode} -\cs_set:Nn \hobby_distangle:n { - \fp_set:Nn \l_hobby_tempa_fp { - (\array_get:Nn \l_hobby_points_x_array {#1 + 1}) - - (\array_get:Nn \l_hobby_points_x_array {#1})} - - \fp_set:Nn \l_hobby_tempb_fp { - (\array_get:Nn \l_hobby_points_y_array {#1 + 1}) - - (\array_get:Nn \l_hobby_points_y_array {#1})} - - \fp_set:Nn \l_hobby_tempc_fp { atan ( \l_hobby_tempb_fp, \l_hobby_tempa_fp ) } - \fp_veclen:NVV \l_hobby_tempd_fp \l_hobby_tempa_fp \l_hobby_tempb_fp - - \array_push:Nx \l_hobby_angles_array {\fp_to_tl:N \l_hobby_tempc_fp} - \array_push:Nx \l_hobby_distances_array {\fp_to_tl:N \l_hobby_tempd_fp} - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\fp_veclen:NVV} -% Computes the length of the vector specified by the latter two arguments, storing the answer in the first. -% \begin{macrocode} -\cs_new:Nn \fp_veclen:Nnn { - \fp_set:Nn #1 {((#2)^2 + (#3)^2)^.5} -} -\cs_generate_variant:Nn \fp_veclen:Nnn {NVV} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby_ctrllen:Nnn} -% Computes the length of the control point vector from the two angles, storing the answer in the first argument given. -% \begin{macrocode} -\cs_new:Nn \hobby_ctrllen:Nnn { - \fp_set:Nn #1 {(2 - \g_hobby_parama_fp - * ( sin(#2) - \g_hobby_paramb_fp * sin(#3) ) - * ( sin(#3) - \g_hobby_paramb_fp * sin(#2) ) - * ( cos(#2) - cos(#3) ) ) - / ( 1 + (1 - \g_hobby_paramc_fp) * cos(#3) + \g_hobby_paramc_fp * cos(#2))} -} -\cs_generate_variant:Nn \hobby_ctrllen:Nnn {NVV} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby_append_point_copy:n} -% This function adds a copy of the point (numbered by its argument) to the end of the list of points, copying all the relevant data (coordinates, tension, etc.). -% -% Originally from Bruno Le Foch on TeX-SX. -% \begin{macrocode} -\cs_new_protected:Npn \hobby_append_point_copy:n #1 - { - \hobby_append_point_copy_aux:Nn \l_hobby_points_array {#1} - \hobby_append_point_copy_aux:Nn \l_hobby_points_x_array {#1} - \hobby_append_point_copy_aux:Nn \l_hobby_points_y_array {#1} - \hobby_append_point_copy_aux:Nn \l_hobby_tension_in_array {#1} - \hobby_append_point_copy_aux:Nn \l_hobby_tension_out_array {#1} - \hobby_append_point_copy_aux:Nn \l_hobby_excess_angle_array {#1} - \hobby_append_point_copy_aux:Nn \l_hobby_actions_array {#1} - } -\cs_new_protected:Npn \hobby_append_point_copy_aux:Nn #1#2 - { \array_gpush:Nx #1 { \array_get:Nn #1 {#2} } } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby_gen_path:} -% This is the curve generation function. -% We assume at the start that we have an array containing all the points that the curve must go through, and the various curve parameters have been initialised. -% So these must be set up by a wrapper function which then calls this one. -% The list of required information is: -% \begin{enumerate} -% \item \Verb+\l_hobby_points_x_array+ -% \item \Verb+\l_hobby_points_y_array+ -% \item \Verb+\l_hobby_tension_out_array+ -% \item \Verb+\l_hobby_tension_in_array+ -% \item \Verb+\l_hobby_excess_angle_array+ -% \item \Verb+\l_hobby_in_curl_fp+ -% \item \Verb+\l_hobby_out_curl_fp+ -% \item \Verb+\l_hobby_in_angle_fp+ -% \item \Verb+\l_hobby_out_angle_fp+ -% \item \Verb+\l_hobby_closed_bool+ -% \item \Verb+\l_hobby_actions_array+ -% \end{enumerate} -% -% \begin{macrocode} -\cs_new:Nn \hobby_gen_path: -{ -% \end{macrocode} -% For much of the time, we can pretend that a closed path is the same as an open path. -% To do this, we need to make the end node an internal node by repeating the \(z_1\) node as the \(z_{n+1}\)th node. -% We also check that the last (\(z_n\)) and first (\(z_0\)) nodes are the same, otherwise we repeat the \(z_0\) node as well. -% \begin{macrocode} -\bool_if:NT \l_hobby_closed_bool { -% \end{macrocode} -% Are the \(x\)-values of the first and last points different? -% \begin{macrocode} - \fp_compare:nTF {(\array_get:Nn \l_hobby_points_x_array {0}) - = - (\array_top:N \l_hobby_points_x_array)} - { -% \end{macrocode} -% No, so compare the \(y\)-values. -% Are the \(y\)-values of the first and last points different? -% \begin{macrocode} - \fp_compare:nF { - \array_get:Nn \l_hobby_points_y_array {0} - = - \array_top:N \l_hobby_points_y_array - } - { -% \end{macrocode} -% Yes, so we need to duplicate the first point, with all of its data. -% \begin{macrocode} - \hobby_append_point_copy:n {0} - } - } - { -% \end{macrocode} -% Yes, so we need to duplicate the first point, with all of its data. -% \begin{macrocode} - \hobby_append_point_copy:n {0} - } -% \end{macrocode} -% Now that we are sure that the first and last points are identical, we need to duplicate the first-but-one point (and all of its data). -% \begin{macrocode} - \hobby_append_point_copy:n {1} -} -% \end{macrocode} -% -% Set \Verb+\l_hobby_npoints_int+ to the number of points (minus one). -% \begin{macrocode} -\int_gset:Nn \l_hobby_npoints_int {\array_length:N \l_hobby_points_y_array} -% \end{macrocode} -% At this point, we need to decide what to do. -% This will depend on whether we have any intermediate points. -% \begin{macrocode} -\int_compare:nNnTF {\l_hobby_npoints_int} = {0} { -% \end{macrocode} -% Only one point, do nothing -% \begin{macrocode} -} -{ - \int_compare:nNnTF {\l_hobby_npoints_int} = {1} { -% \end{macrocode} -% Only two points, skip processing. -% Just need to set the incoming and outgoing angles -% \begin{macrocode} -\hobby_distangle:n {0} -\fp_compare:nF { \l_hobby_out_angle_fp == \c_inf_fp } -{ - \fp_set:Nn \l_hobby_tempa_fp { \l_hobby_out_angle_fp - - \array_get:Nn \l_hobby_angles_array {0}} -% \end{macrocode} -% We want to ensure that these angles lie in the range \((-\pi,\pi]\). -% So if the angle is bigger than \(\pi\), we subtract \(2 \pi\). -% (It shouldn't be that we can get bigger than \(3 \pi\) - check this) -% \begin{macrocode} - \fp_compare:nT {\l_hobby_tempa_fp > \c_pi_fp } - { - \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} - } -% \end{macrocode} -% Similarly, we check to see if the angle is less than \(-\pi\). -% \begin{macrocode} - \fp_compare:nT {\l_hobby_tempa_fp < -\c_pi_fp } - { - \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} - } - \array_put:Nnx \l_hobby_theta_array {0} {\fp_to_tl:N \l_hobby_tempa_fp} - \fp_compare:nT { \l_hobby_in_angle_fp == \c_inf_fp } - { -%^^A \fp_mul:Nn \l_hobby_tempa_fp {-1} - \array_put:Nnx \l_hobby_phi_array {1}{ \fp_to_tl:N \l_hobby_tempa_fp} - } - } -\fp_compare:nTF { \l_hobby_in_angle_fp == \c_inf_fp } -{ - \fp_compare:nT { \l_hobby_out_angle_fp == \c_inf_fp } - { - \array_put:Nnx \l_hobby_phi_array {1} {0} - \array_put:Nnx \l_hobby_theta_array {0} {0} - } -} -{ - \fp_set:Nn \l_hobby_tempa_fp { - \l_hobby_in_angle_fp + \c_pi_fp -+ (\array_get:Nn \l_hobby_angles_array {0})} - \fp_compare:nT {\l_hobby_tempa_fp > \c_pi_fp } - { - \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} - } - \fp_compare:nT {\l_hobby_tempa_fp < -\c_pi_fp } - { - \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} - } - - \array_put:Nnx \l_hobby_phi_array {1} - {\fp_to_tl:N \l_hobby_tempa_fp} - \fp_compare:nT { \l_hobby_out_angle_fp == \c_inf_fp } - { -%^^A \fp_mul:Nn \l_hobby_tempa_fp {-1} - \array_put:Nnx \l_hobby_theta_array {0}{ \fp_to_tl:N \l_hobby_tempa_fp} - } -} - - } - { -% \end{macrocode} -% Got enough points, go on with processing -% \begin{macrocode} - \hobby_compute_path: - } - \hobby_build_path: -} -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\hobby_compute_path:} -% This is the path builder where we have enough points to run the algorithm. -% \begin{macrocode} -\cs_new:Nn \hobby_compute_path: -{ -% \end{macrocode} -% Our first step is to go through the list of points and compute the distances and angles between successive points. -% Thus \(d_i\) is the distance from \(z_i\) to \(z_{i+1}\) and the angle is the angle of the line from \(z_i\) to \(z_{i+1}\). -% \begin{macrocode} -\int_step_function:nnnN {0} {1} {\l_hobby_npoints_int - 1} \hobby_distangle:n -% \end{macrocode} -% -% For the majority of the code, we're only really interested in the differences of the angles. -% So for each internal point we compute the differences in the angles. -% \begin{macrocode} - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} { - \fp_set:Nx \l_hobby_tempa_fp { - \array_get:Nn \l_hobby_angles_array {##1} - - \array_get:Nn \l_hobby_angles_array {##1 - 1}} -% \end{macrocode} -% We want to ensure that these angles lie in the range \((-\pi,\pi]\). -% So if the angle is bigger than \(\pi\), we subtract \(2 \pi\). -% (It shouldn't be that we can get bigger than \(3 \pi\) - check this.) -% \begin{macrocode} - \fp_compare:nTF {\l_hobby_tempa_fp > \c_pi_fp } - { - \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} - } - {} -% \end{macrocode} -% Similarly, we check to see if the angle is less than \(-\pi\). -% \begin{macrocode} - \fp_compare:nTF {\l_hobby_tempa_fp <= -\c_pi_fp } - { - \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} - } - {} -% \end{macrocode} -% The wrapping routine might not get it right at the edges so we add in the override. -% \begin{macrocode} -\array_get:NnNTF \l_hobby_excess_angle_array {##1} \l_tmpa_tl { - \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp * \l_tmpa_tl} - }{} -% \end{macrocode} -% \begin{macrocode} - \array_put:Nnx \l_hobby_psi_array {##1}{\fp_to_tl:N \l_hobby_tempa_fp} - } -% \end{macrocode} -% -% Next, we generate the matrix. -% We start with the subdiagonal. -% This is indexed from \(1\) to \(n-1\). -% \begin{macrocode} - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} { - \array_put:Nnx \l_hobby_matrix_a_array {##1} {\fp_to_tl:n { - \array_get:Nn \l_hobby_tension_in_array {##1}^2 - * \array_get:Nn \l_hobby_distances_array {##1} - * \array_get:Nn \l_hobby_tension_in_array {##1 + 1} - }} -} -% \end{macrocode} -% -% Next, we attack main diagonal. -% We might need to adjust the first and last terms, but we'll do that in a minute. -% \begin{macrocode} - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} { - - \array_put:Nnx \l_hobby_matrix_b_array {##1} {\fp_to_tl:n -{(3 * (\array_get:Nn \l_hobby_tension_in_array {##1 + 1}) - 1) * - (\array_get:Nn \l_hobby_tension_out_array {##1})^2 * -(\array_get:Nn \l_hobby_tension_out_array {##1 - 1}) -* ( \array_get:Nn \l_hobby_distances_array {##1 - 1}) -+ -(3 * (\array_get:Nn \l_hobby_tension_out_array {##1 - 1}) - 1) -* (\array_get:Nn \l_hobby_tension_in_array {##1})^2 -* (\array_get:Nn \l_hobby_tension_in_array {##1 + 1}) -* (\array_get:Nn \l_hobby_distances_array {##1})} -} -} -% \end{macrocode} -% -% Next, the superdiagonal. -% \begin{macrocode} - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 2} { - - \array_put:Nnx \l_hobby_matrix_c_array {##1} {\fp_to_tl:n -{(\array_get:Nn \l_hobby_tension_in_array {##1})^2 -* (\array_get:Nn \l_hobby_tension_in_array {##1 - 1}) -* (\array_get:Nn \l_hobby_distances_array {##1 - 1}) -}} - -} -% \end{macrocode} -% -% Lastly (before the adjustments), the target vector. -% \begin{macrocode} - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 2} { - - \array_put:Nnx \l_hobby_matrix_d_array {##1} {\fp_to_tl:n -{ -- (\array_get:Nn \l_hobby_psi_array {##1 + 1}) -* (\array_get:Nn \l_hobby_tension_out_array {##1})^2 -* (\array_get:Nn \l_hobby_tension_out_array {##1 - 1}) -* (\array_get:Nn \l_hobby_distances_array {##1 - 1}) -- (3 * (\array_get:Nn \l_hobby_tension_out_array {##1 - 1}) - 1) -* (\array_get:Nn \l_hobby_psi_array {##1}) -* (\array_get:Nn \l_hobby_tension_in_array {##1})^2 -* (\array_get:Nn \l_hobby_tension_in_array {##1 + 1}) -* (\array_get:Nn \l_hobby_distances_array {##1}) -} -} -} -% \end{macrocode} -% -% Next, there are some adjustments at the ends. -% These differ depending on whether the path is open or closed. -% \begin{macrocode} -\bool_if:NTF \l_hobby_closed_bool { -% \end{macrocode} -% Closed path -% \begin{macrocode} -\array_put:Nnx \l_hobby_matrix_c_array {0} {\fp_to_tl:n { -- (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int - 2}) -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 2}) -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^2 -}} - -\array_put:Nnn \l_hobby_matrix_b_array {0} {1} -\array_put:Nnn \l_hobby_matrix_d_array {0} {0} - -\array_put:Nnx \l_hobby_matrix_b_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { -(\array_get:Nn \l_hobby_matrix_b_array {\l_hobby_npoints_int - 1}) -+ 1 -}} - - \array_put:Nnx \l_hobby_matrix_d_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { -- (\array_get:Nn \l_hobby_psi_array {1}) -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int -1})^2 -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int -2}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int - 2}) -- (3 * (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 2}) - 1) -* (\array_get:Nn \l_hobby_psi_array {\l_hobby_npoints_int - 1}) -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int - 1})^2 -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int -1}) -} -} -% \end{macrocode} -% We also need to populate the \(u\)-vector -% \begin{macrocode} - \array_put:Nnn \l_hobby_vector_u_array {0} {1} -\array_put:Nnn \l_hobby_vector_u_array {\l_hobby_npoints_int - 1} {1} - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 2} { - \array_put:Nnn \l_hobby_vector_u_array {##1} {0} - } -% \end{macrocode} -% And define the significant entry in the \(v\)-vector. -% \begin{macrocode} -\fp_set:Nn \l_hobby_matrix_v_fp { -(\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int -1})^2 -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int -2}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int -2}) -} -} -{ -% \end{macrocode} -% Open path. -% First, we test to see if \(\theta_0\) has been specified. -% \begin{macrocode} -\fp_compare:nTF { \l_hobby_out_angle_fp == \c_inf_fp } -{ - \array_put:Nnx \l_hobby_matrix_b_array {0} {\fp_to_tl:n { - (\array_get:Nn \l_hobby_tension_in_array {1})^3 -* \l_hobby_in_curl_fp -+ -(3 * (\array_get:Nn \l_hobby_tension_in_array {1}) - 1) -* (\array_get:Nn \l_hobby_tension_out_array {0})^3 -}} - - \array_put:Nnx \l_hobby_matrix_c_array {0} {\fp_to_tl:n { - (\array_get:Nn \l_hobby_tension_out_array {0})^3 -+ -(3 * (\array_get:Nn \l_hobby_tension_out_array {0}) - 1) -* (\array_get:Nn \l_hobby_tension_in_array {1})^3 -* \l_hobby_in_curl_fp -}} - - \array_put:Nnx \l_hobby_matrix_d_array {0} {\fp_to_tl:n { --( (\array_get:Nn \l_hobby_tension_out_array {0})^3 -+ -(3 * (\array_get:Nn \l_hobby_tension_out_array {0}) - 1) -* (\array_get:Nn \l_hobby_tension_in_array {1})^3 -* \l_hobby_in_curl_fp) -* (\array_get:Nn \l_hobby_psi_array {1}) -}} - -} -{ - \array_put:Nnn \l_hobby_matrix_b_array {0} {1} - \array_put:Nnn \l_hobby_matrix_c_array {0} {0} - \fp_set:Nn \l_hobby_tempa_fp { \l_hobby_out_angle_fp - - \array_get:Nn \l_hobby_angles_array {0}} -% \end{macrocode} -% We want to ensure that these angles lie in the range \((-\pi,\pi]\). -% So if the angle is bigger than \(\pi\), we subtract \(2 \pi\). -% (It shouldn't be that we can get bigger than \(3 \pi\) - check this) -% \begin{macrocode} - \fp_compare:nT {\l_hobby_tempa_fp > \c_pi_fp } - { - \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} - } -% \end{macrocode} -% Similarly, we check to see if the angle is less than \(-\pi\). -% \begin{macrocode} - \fp_compare:nT {\l_hobby_tempa_fp < -\c_pi_fp } - { - \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} - } - \array_put:Nnx \l_hobby_matrix_d_array {0} {\fp_to_tl:N \l_hobby_tempa_fp} -} -% \end{macrocode} -% -% Next, if \(\phi_n\) has been given. -% \begin{macrocode} -\fp_compare:nTF { \l_hobby_in_angle_fp == \c_inf_fp } -{ - - \array_put:Nnx \l_hobby_matrix_b_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { -\array_get:Nn \l_hobby_matrix_b_array {\l_hobby_npoints_int - 1} -- (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^2 -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 2}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int - 2}) -* -((3 * (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int} ) - 1) -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^3 \l_tmpa_tl -* \l_hobby_out_curl_fp -+ -(\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int })^3) -/ -((3 * (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int -2}) - 1) -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int})^3 -+ -( \array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^3 -* \l_hobby_out_curl_fp) -}} - - \array_put:Nnx \l_hobby_matrix_d_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { -- (3 * (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 2}) - 1) -* (\array_get:Nn \l_hobby_psi_array {\l_hobby_npoints_int - 1}) -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int - 1})^2 -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int - 1}) -}} - -} -{ - \fp_set:Nn \l_hobby_tempa_fp { - \l_hobby_in_angle_fp + \c_pi_fp -+ (\array_get:Nn \l_hobby_angles_array {\l_hobby_npoints_int - 1})} - \fp_compare:nT {\l_hobby_tempa_fp > \c_pi_fp } - { - \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} - } - \fp_compare:nT {\l_hobby_tempa_fp < -\c_pi_fp } - { - \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} - } - - \array_put:Nnx \l_hobby_phi_array {\l_hobby_npoints_int} - {\fp_to_tl:N \l_hobby_tempa_fp} - - \array_put:Nnx \l_hobby_matrix_d_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { - \l_hobby_tempa_fp - * (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^2 -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 2}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int - 2}) -- -(3 * ( \array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 2}) - 1) -* (\array_get:Nn \l_hobby_psi_array {\l_hobby_npoints_int - 1}) -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int - 1})^2 -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int - 1}) }} -} -% \end{macrocode} -% End of adjustments for open paths. -% \begin{macrocode} -} -% \end{macrocode} -% -% Now we have the tridiagonal matrix in place, we implement the solution. -% We start with the forward eliminations. -% \begin{macrocode} -\int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} { - - \array_put:Nnx \l_hobby_matrix_b_array {##1} {\fp_to_tl:n { - (\array_get:Nn \l_hobby_matrix_b_array {##1 - 1}) -* (\array_get:Nn \l_hobby_matrix_b_array {##1}) -- -(\array_get:Nn \l_hobby_matrix_c_array {##1 - 1}) -* (\array_get:Nn \l_hobby_matrix_a_array {##1}) -}} -% \end{macrocode} -% The last time, we don't touch the \(C\)-vector. -% \begin{macrocode} - \int_compare:nT {##1 < \l_hobby_npoints_int - 1} { - - \array_put:Nnx \l_hobby_matrix_c_array {##1} {\fp_to_tl:n { -(\array_get:Nn \l_hobby_matrix_b_array {##1 - 1}) - * (\array_get:Nn \l_hobby_matrix_c_array {##1}) -}} - } - - \array_put:Nnx \l_hobby_matrix_d_array {##1} {\fp_to_tl:n { -(\array_get:Nn \l_hobby_matrix_b_array {##1 - 1}) - * (\array_get:Nn \l_hobby_matrix_d_array {##1}) -- - (\array_get:Nn \l_hobby_matrix_d_array {##1 - 1}) - * (\array_get:Nn \l_hobby_matrix_a_array {##1}) -}} -% \end{macrocode} -% On a closed path, we also want to know \(M^{-1} u\) so need to do the elimination steps on \(u\) as well. -% \begin{macrocode} - \bool_if:NT \l_hobby_closed_bool { - \array_put:Nnx \l_hobby_vector_u_array {##1} {\fp_to_tl:n { -(\array_get:Nn \l_hobby_matrix_b_array {##1 - 1}) -* (\array_get:Nn \l_hobby_vector_u_array {##1}) -- -(\array_get:Nn \l_hobby_vector_u_array {##1 - 1}) -* (\array_get:Nn \l_hobby_matrix_a_array {##1}) -}} -} -} -% \end{macrocode} -% Now we start the back substitution. -% The first step is slightly different to the general step. -% \begin{macrocode} - \array_put:Nnx \l_hobby_theta_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { -(\array_get:Nn \l_hobby_matrix_d_array {\l_hobby_npoints_int - 1}) -/ (\array_get:Nn \l_hobby_matrix_b_array {\l_hobby_npoints_int - 1}) -}} -% \end{macrocode} -% For a closed path, we need to work with \(u\) as well. -% \begin{macrocode} -\bool_if:NT \l_hobby_closed_bool { - \array_put:Nnx \l_hobby_vector_u_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { - (\array_get:Nn \l_hobby_vector_u_array {\l_hobby_npoints_int - 1}) -/ (\array_get:Nn \l_hobby_matrix_b_array {\l_hobby_npoints_int - 1}) -}} -} -% \end{macrocode} -% Now we iterate over the vectors, doing the remaining back substitutions. -% \begin{macrocode} -\int_step_inline:nnnn {\l_hobby_npoints_int - 2} {-1} {0} { - - \array_put:Nnx \l_hobby_theta_array {##1} {\fp_to_tl:n { -( (\array_get:Nn \l_hobby_matrix_d_array {##1}) - - (\array_get:Nn \l_hobby_theta_array {##1 + 1}) - * (\array_get:Nn \l_hobby_matrix_c_array {##1}) -) / (\array_get:Nn \l_hobby_matrix_b_array {##1}) -}} -} -\bool_if:NT \l_hobby_closed_bool { -% \end{macrocode} -% On a closed path, we also need to work out \(M^{-1} u\). -% \begin{macrocode} -\int_step_inline:nnnn {\l_hobby_npoints_int - 2} {-1} {0} { - \array_put:Nnx \l_hobby_vector_u_array {##1} {\fp_to_tl:n -{ - ((\array_get:Nn \l_hobby_vector_u_array {##1}) - - (\array_get:Nn \l_hobby_vector_u_array {##1 + 1}) - * (\array_get:Nn \l_hobby_matrix_c_array {##1}) - ) / (\array_get:Nn \l_hobby_matrix_b_array {##1}) -}} -} -% \end{macrocode} -% Then we compute \(v^\top M^{-1}u\) and \(v^\top M^{-1} \theta\). -% As \(v\) has a particularly simple form, these inner products are easy to compute. -% \begin{macrocode} - -\fp_set:Nn \l_hobby_tempb_fp { -((\array_get:Nn \l_hobby_theta_array {1}) -* \l_hobby_matrix_v_fp -- (\array_get:Nn \l_hobby_theta_array {\l_hobby_npoints_int - 1}) -) / ( -(\array_get:Nn \l_hobby_vector_u_array {1}) -* \l_hobby_matrix_v_fp -- (\array_get:Nn \l_hobby_vector_u_array {\l_hobby_npoints_int - 1}) -+ 1 -)} - -\int_step_inline:nnnn {0} {1} {\l_hobby_npoints_int - 1} { - - \array_put:Nnx \l_hobby_theta_array {##1} {\fp_to_tl:n { - (\array_get:Nn \l_hobby_theta_array {##1}) - - (\array_get:Nn \l_hobby_vector_u_array {##1}) - * \l_hobby_tempb_fp -}} -} -} -% \end{macrocode} -% -% Now that we have computed the \(\theta_i\)s, we can quickly compute the \(\phi_i\)s. -% -% \begin{macrocode} -\int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} { - - \array_put:Nnx \l_hobby_phi_array {##1} {\fp_to_tl:n { - - (\array_get:Nn \l_hobby_psi_array {##1}) - - (\array_get:Nn \l_hobby_theta_array {##1}) - }} - } -% \end{macrocode} -% -% If the path is open, this works for all except \(\phi_n\). -% If the path is closed, we can drop our added point. -% Cheaply, of course. -% \begin{macrocode} -\bool_if:NTF \l_hobby_closed_bool { - \int_gdecr:N \l_hobby_npoints_int -}{ -% \end{macrocode} -% If \(\phi_n\) was not given, we compute it from \(\theta_{n-1}\). -% \begin{macrocode} -\fp_compare:nT { \l_hobby_in_angle_fp == \c_inf_fp } -{ - \array_put:Nnx \l_hobby_phi_array {\l_hobby_npoints_int} {\fp_to_tl:n { -((3 * (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int}) - 1) -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^3 -* \l_hobby_out_curl_fp -+ -(\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int })^3) -/ -((3 * (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int -2}) - 1) -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int})^3 \l_tmpa_tl -+ -(\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^3 -* \l_hobby_out_curl_fp) -* -(\array_get:Nn \l_hobby_theta_array {\l_hobby_npoints_int -1}) -}} -} -} -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\hobby_build_path:} -% Once we've computed the angles, we build the actual path. -% \begin{macrocode} -\cs_new:Nn \hobby_build_path: -{ -% \end{macrocode} -% Next task is to compute the \(\rho_i\) and \(\sigma_i\). -% \begin{macrocode} -\int_step_inline:nnnn {0} {1} {\l_hobby_npoints_int - 1} { - - \fp_set:Nn \l_hobby_tempa_fp {\array_get:Nn \l_hobby_theta_array {##1}} - - \fp_set:Nn \l_hobby_tempb_fp {\array_get:Nn \l_hobby_phi_array {##1 + 1}} - - \hobby_ctrllen:NVV \l_hobby_temps_fp \l_hobby_tempa_fp \l_hobby_tempb_fp - - \array_put:Nnx \l_hobby_sigma_array {##1 + 1} {\fp_to_tl:N \l_hobby_temps_fp} - - \hobby_ctrllen:NVV \l_hobby_temps_fp \l_hobby_tempb_fp \l_hobby_tempa_fp - - \array_put:Nnx \l_hobby_rho_array {##1} {\fp_to_tl:N \l_hobby_temps_fp} - - } -% \end{macrocode} -% Lastly, we generate the coordinates of the control points. -% \begin{macrocode} -\int_step_inline:nnnn {0} {1} {\l_hobby_npoints_int - 1} { -\array_gput:Nnx \l_hobby_controla_array {##1 + 1} {x = \fp_eval:n { -(\array_get:Nn \l_hobby_points_x_array {##1}) -+ - (\array_get:Nn \l_hobby_distances_array {##1}) * - (\array_get:Nn \l_hobby_rho_array {##1}) * -cos ( (\array_get:Nn \l_hobby_angles_array {##1}) -+ - (\array_get:Nn \l_hobby_theta_array {##1})) -/3 -}, y = \fp_eval:n { -( \array_get:Nn \l_hobby_points_y_array {##1}) + - (\array_get:Nn \l_hobby_distances_array {##1}) * - (\array_get:Nn \l_hobby_rho_array {##1}) * -sin ( (\array_get:Nn \l_hobby_angles_array {##1}) -+ - (\array_get:Nn \l_hobby_theta_array {##1})) -/3 -} -} -} -\int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int} { - \array_gput:Nnx \l_hobby_controlb_array {##1} { - x = \fp_eval:n {\array_get:Nn \l_hobby_points_x_array {##1} -- (\array_get:Nn \l_hobby_distances_array {##1 - 1}) -* (\array_get:Nn \l_hobby_sigma_array {##1}) -* cos((\array_get:Nn \l_hobby_angles_array {##1 - 1}) -- (\array_get:Nn \l_hobby_phi_array {##1}))/3 -}, y = \fp_eval:n { - (\array_get:Nn \l_hobby_points_y_array {##1}) -- (\array_get:Nn \l_hobby_distances_array {##1 - 1}) -* (\array_get:Nn \l_hobby_sigma_array {##1}) -* sin((\array_get:Nn \l_hobby_angles_array {##1 - 1}) -- (\array_get:Nn \l_hobby_phi_array {##1}))/3 -} } - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobbyinit} -% Initialise the settings for Hobby's algorithm -% \begin{macrocode} -\NewDocumentCommand \hobbyinit {m m m} { - \hobby_set_cmds:nnn#1#2#3 - \hobby_clear_path: -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobbyaddpoint} -% This adds a point, possibly with tensions, to the current stack. -% \begin{macrocode} -\NewDocumentCommand \hobbyaddpoint { m } { - \keys_set:nn { hobby/read in all } - { - tension~out, - tension~in, - excess~angle, - blank, - break, - #1 - } - \tl_if_eq:VnTF {\l_tmpa_tl} {true} - {\tl_set:Nn \l_tmpa_tl {2}} - { - \tl_if_eq:VnTF {\l_tmpa_tl} {soft} - {\tl_set:Nn \l_tmpa_tl {0}} - {\tl_set:Nn \l_tmpa_tl {1}} - } - \tl_if_eq:VnTF {\l_tmpb_tl} {true} - {\tl_put_right:Nn \l_tmpa_tl {1}} - {\tl_put_right:Nn \l_tmpa_tl {0}} - \array_gpush:Nx \l_hobby_actions_array {\l_tmpa_tl} - \array_gpush:Nx \l_hobby_tension_out_array {\fp_to_tl:N \l_hobby_tempc_fp} - \array_gpush:Nx \l_hobby_tension_in_array {\fp_to_tl:N \l_hobby_tempd_fp} - \array_gpush:Nx \l_hobby_excess_angle_array {\fp_to_tl:N \l_hobby_temps_fp} - \array_gpush:Nx \l_hobby_points_array { - x = \fp_use:N \l_hobby_tempa_fp, - y = \fp_use:N \l_hobby_tempb_fp } - \array_gpush:Nx \l_hobby_points_x_array {\fp_to_tl:N \l_hobby_tempa_fp} - \array_gpush:Nx \l_hobby_points_y_array {\fp_to_tl:N \l_hobby_tempb_fp} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobbysetparams} -% This sets the parameters for the curve. -% \begin{macrocode} -\NewDocumentCommand \hobbysetparams { m } { - \keys_set:nn { hobby / read in params } - { - #1 - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby_set_cmds:nnn} -% The path-generation code doesn't know what to actually do with the path so the initialisation code will set some macros to do that. -% This is an auxiliary command that sets these macros. -% \begin{macrocode} -\cs_new:Npn \hobby_moveto:nnn #1#2#3 {} -\cs_new:Npn \hobby_curveto:nnn #1#2#3 {} -\cs_new:Npn \hobby_close:n #1 {} -\cs_generate_variant:Nn \hobby_moveto:nnn {VVV,nnV} -\cs_generate_variant:Nn \hobby_curveto:nnn {VVV} -\cs_generate_variant:Nn \hobby_close:n {V} -\cs_new:Nn \hobby_set_cmds:nnn { - \cs_gset_eq:NN \hobby_moveto:nnn #1 - \cs_gset_eq:NN \hobby_curveto:nnn #2 - \cs_gset_eq:NN \hobby_close:n #3 -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobbygenpath} -% This is the user (well, sort of) command that generates the curve. -% \begin{macrocode} -\NewDocumentCommand \hobbygenpath { } { - \array_if_empty:NF \l_hobby_points_array { - \hobby_gen_path: - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobbygenifnecpath} -% If the named path doesn't exist, it is generated and named. -% If it does exist, we restore it. -% Either way, we save it to the aux file. -% \begin{macrocode} -\NewDocumentCommand \hobbygenifnecpath { m } { - \tl_if_exist:cTF {g_hobby_#1_path} - { - \tl_use:c {g_hobby_#1_path} - } - { - \hobby_gen_path: - } - \hobby_save_path:n {#1} - \hobby_save_path_to_aux:x {#1} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobbygenifnecusepath} -% If the named path doesn't exist, it is generated and named. -% If it does exist, we restore it. -% Either way, we save it to the aux file. -% \begin{macrocode} -\NewDocumentCommand \hobbygenuseifnecpath { m } { - \tl_if_exist:cTF {g_hobby_#1_path} - { - \tl_use:c {g_hobby_#1_path} - } - { - \hobby_gen_path: - } - \hobby_save_path:n {#1} - \hobby_save_path_to_aux:x {#1} - \hobby_use_path: -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobbyusepath} -% This is the user (well, sort of) command that uses the last generated curve. -% \begin{macrocode} -\NewDocumentCommand \hobbyusepath { m } { - \hobbysetparams{#1} - \hobby_use_path: -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobbysavepath} -% This is the user (well, sort of) command that uses the last generated curve. -% \begin{macrocode} -\NewDocumentCommand \hobbysavepath { m } { - \hobby_save_path:n {#1} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobbyrestorepath} -% This is the user (well, sort of) command that uses the last generated curve. -% \begin{macrocode} -\NewDocumentCommand \hobbyrestorepath { m } { - \tl_if_exist:cT {g_hobby_#1_path} { - \tl_use:c {g_hobby_#1_path} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobbyshowpath} -% This is the user (well, sort of) command that uses the last generated curve. -% \begin{macrocode} -\NewDocumentCommand \hobbyshowpath { m } { - \tl_if_exist:cT {g_hobby_#1_path} { - \tl_show:c {g_hobby_#1_path} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobbygenusepath} -% This is the user (well, sort of) command that generates a curve and uses it. -% \begin{macrocode} -\NewDocumentCommand \hobbygenusepath { } { - \array_if_empty:NF \l_hobby_points_array { - \hobby_gen_path: - \hobby_use_path: - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobbyclearpath} -% This is the user (well, sort of) command that generates a curve and uses it. -% \begin{macrocode} -\NewDocumentCommand \hobbyclearpath { } { - \hobby_clear_path: -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby_use_path:} -% This is the command that uses the curve. -% As the curve data is stored globally, the same data can be reused by calling this function more than once without calling the generating function. -% \begin{macrocode} -\tl_new:N \l_tmpc_tl -\cs_new:Nn \hobby_use_path: { - \bool_if:NT \l_hobby_disjoint_bool { - \array_get:NnN \l_hobby_points_array {0} \l_tmpa_tl - \hobby_moveto:nnV {} {} \l_tmpa_tl - } - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int} { - \array_get:NnN \l_hobby_controla_array {##1} \l_tmpa_tl - \array_get:NnN \l_hobby_controlb_array {##1} \l_tmpb_tl - \array_get:NnN \l_hobby_points_array {##1} \l_tmpc_tl - \array_get:NnN \l_hobby_actions_array {##1} \l_tmpd_tl - \int_compare:nNnTF {\tl_item:Nn \l_tmpd_tl {1}} = {\l_hobby_draw_int} { - \hobby_curveto:VVV \l_tmpa_tl \l_tmpb_tl \l_tmpc_tl - }{ - \bool_gset_false:N \l_hobby_closed_bool - \hobby_moveto:VVV \l_tmpa_tl \l_tmpb_tl \l_tmpc_tl - } - \tl_if_eq:xnTF {\tl_item:Nn \l_tmpd_tl {2}} {1} { - \bool_gset_false:N \l_hobby_closed_bool - \hobby_moveto:VVV \l_tmpa_tl \l_tmpb_tl \l_tmpc_tl - }{} - } - \bool_if:NT \l_hobby_closed_bool { - \array_get:NnN \l_hobby_points_array {0} \l_tmpa_tl - \hobby_close:V \l_tmpa_tl - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby_save_path:n} -% This command saves all the data needed to reinvoke the curve in a global token list that can be used to restore it afterwards. -% \begin{macrocode} -\cs_new:Nn \hobby_save_path:n { - \tl_clear:N \l_tmpa_tl - \tl_put_right:Nn \l_tmpa_tl {\int_gset:Nn \l_hobby_npoints_int} - \tl_put_right:Nx \l_tmpa_tl {{\int_use:N \l_hobby_npoints_int}} - \bool_if:NTF \l_hobby_disjoint_bool { - \tl_put_right:Nn \l_tmpa_tl {\bool_gset_true:N} - }{ - \tl_put_right:Nn \l_tmpa_tl {\bool_gset_false:N} - } - \tl_put_right:Nn \l_tmpa_tl {\l_hobby_disjoint_bool} - \bool_if:NTF \l_hobby_closed_bool { - \tl_put_right:Nn \l_tmpa_tl {\bool_gset_true:N} - }{ - \tl_put_right:Nn \l_tmpa_tl {\bool_gset_false:N} - } - \tl_put_right:Nn \l_tmpa_tl {\l_hobby_closed_bool} - \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \l_hobby_points_array} - \array_map_inline:Nn \l_hobby_points_array { - \tl_put_right:Nn \l_tmpa_tl { - \array_gput:Nnn \l_hobby_points_array {##1} {##2} - } - } - \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \l_hobby_actions_array} - \array_map_inline:Nn \l_hobby_actions_array { - \tl_put_right:Nn \l_tmpa_tl { - \array_gput:Nnn \l_hobby_actions_array {##1} {##2} - } - } - \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \l_hobby_controla_array} - \array_map_inline:Nn \l_hobby_controla_array { - \tl_put_right:Nn \l_tmpa_tl { - \array_gput:Nnn \l_hobby_controla_array {##1} {##2} - } - } - \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \l_hobby_controlb_array} - \array_map_inline:Nn \l_hobby_controlb_array { - \tl_put_right:Nn \l_tmpa_tl { - \array_gput:Nnn \l_hobby_controlb_array {##1} {##2} - } - } - \tl_gclear_new:c {g_hobby_#1_path} - \tl_gset_eq:cN {g_hobby_#1_path} \l_tmpa_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby_save_path_to_aux:n} -% \begin{macrocode} -\int_set:Nn \l_tmpa_int {\char_value_catcode:n {`@}} -\char_set_catcode_letter:N @ -\cs_new:Npn \hobby_save_path_to_aux:n #1 { - \bool_if:nT { - \tl_if_exist_p:c {g_hobby_#1_path} - && - ! \tl_if_exist_p:c {g_hobby_#1_path_saved} - && - \l_hobby_save_aux_bool - } - { - \tl_clear:N \l_tmpa_tl - \tl_put_right:Nn \l_tmpa_tl { - \ExplSyntaxOn - \tl_gclear_new:c {g_hobby_#1_path} - \tl_gput_right:cn {g_hobby_#1_path} - } - \tl_put_right:Nx \l_tmpa_tl { - {\tl_to_str:c {g_hobby_#1_path}} - } - \tl_put_right:Nn \l_tmpa_tl { - \ExplSyntaxOff - } - \protected@write\@auxout{}{ - \tl_to_str:N \l_tmpa_tl - } - \tl_new:c {g_hobby_#1_path_saved} - } -} -\char_set_catcode:nn {`@} {\l_tmpa_int} -\cs_generate_variant:Nn \hobby_save_path_to_aux:n {x} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby_clear_path:} -% \begin{macrocode} -\cs_new:Nn \hobby_clear_path: -{ -\array_gclear:N \l_hobby_points_array -\array_gclear:N \l_hobby_points_x_array -\array_gclear:N \l_hobby_points_y_array -\array_gclear:N \l_hobby_angles_array -\array_gclear:N \l_hobby_actions_array -\array_gclear:N \l_hobby_distances_array -\array_gclear:N \l_hobby_tension_out_array -\array_gclear:N \l_hobby_tension_in_array -\array_gclear:N \l_hobby_excess_angle_array -\array_gclear:N \l_hobby_matrix_a_array -\array_gclear:N \l_hobby_matrix_b_array -\array_gclear:N \l_hobby_matrix_c_array -\array_gclear:N \l_hobby_matrix_d_array -\array_gclear:N \l_hobby_vector_u_array -\array_gclear:N \l_hobby_psi_array -\array_gclear:N \l_hobby_theta_array -\array_gclear:N \l_hobby_phi_array -\array_gclear:N \l_hobby_sigma_array -\array_gclear:N \l_hobby_rho_array -\array_gclear:N \l_hobby_controla_array -\array_gclear:N \l_hobby_controlb_array -\bool_gset_false:N \l_hobby_closed_bool -\bool_gset_false:N \l_hobby_disjoint_bool - - \int_gset:Nn \l_hobby_npoints_int {-1} - \int_gset:Nn \l_hobby_draw_int {1} - \fp_gset_eq:NN \l_hobby_in_angle_fp \c_inf_fp - \fp_gset_eq:NN \l_hobby_out_angle_fp \c_inf_fp - \fp_gset_eq:NN \l_hobby_in_curl_fp \c_one_fp - \fp_gset_eq:NN \l_hobby_out_curl_fp \c_one_fp -} -% \end{macrocode} -% \end{macro} -% \begin{macrocode} -\ExplSyntaxOff -% \end{macrocode} -% \iffalse -% -% \fi -% -% \subsection{PGF Library} -% -% \iffalse -%<*pgflibrary> -% \fi -% -% The PGF level is very simple. -% All we do is set up the path-construction commands that get passed to the path-generation function. -% \begin{macrocode} -\input{hobby.code.tex} -% \end{macrocode} -% Points are communicated as key-pairs. -% These keys translate from the \LaTeX3 style points to PGF points. -% \begin{macrocode} -\pgfkeys{ - /pgf/hobby/.is family, - /pgf/hobby/.cd, - x/.code={\pgf@x=#1cm}, - y/.code={\pgf@y=#1cm} -} -% \end{macrocode} -% -% \begin{macro}{hobbyatan2} -% The original PGF version of \Verb+atan2+ had the arguments the wrong way around. -% This was fixed in the CVS version in July 2013, but as old versions are likely to be in use for some time, we define a wrapper function that ensures that the arguments are correct. -% \begin{macrocode} -\pgfmathparse{atan2(0,1)} -\def\hobby@temp{0.0} -\ifx\pgfmathresult\hobby@temp - \pgfmathdeclarefunction{hobbyatan2}{2}{% - \pgfmathatantwo@{#1}{#2}% - } -\else - \pgfmathdeclarefunction{hobbyatan2}{2}{% - \pgfmathatantwo@{#2}{#1}% - } -\fi -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@curveto} -% This is passed to the path-generation code to translate the path into a PGF path. -% \begin{macrocode} -\def\hobby@curveto#1#2#3{% - \pgfpathcurveto{\hobby@topgf{#1}}{\hobby@topgf{#2}}{\hobby@topgf{#3}}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@moveto} -% This is passed to the path-generation code to translate the path into a PGF path. -% \begin{macrocode} -\def\hobby@moveto#1#2#3{% - \pgfpathmoveto{\hobby@topgf{#3}}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@topgf} -% Translates a \LaTeX3 point to a PGF point. -% \begin{macrocode} -\def\hobby@topgf#1{% - \pgfqkeys{/pgf/hobby}{#1}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@close} -% Closes a path. -% \begin{macrocode} -\def\hobby@close#1{% - \pgfpathclose -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pgfpathhobby} -% Low-level interface to the hobby construction. -% This sets up the commands and starts the iterator. -% \begin{macrocode} -\def\pgfpathhobby{% - \pgfutil@ifnextchar\bgroup{\pgfpath@hobby}{\pgfpath@hobby{}}} -\def\pgfpath@hobby#1{% - \hobbyinit\hobby@moveto\hobby@curveto\hobby@close - \hobbysetparams{#1}% - \pgfmathsetmacro\hobby@x{\the\pgf@path@lastx/1cm}% - \pgfmathsetmacro\hobby@y{\the\pgf@path@lasty/1cm}% - \hobbyaddpoint{x = \hobby@x, y = \hobby@y}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pgfpathhobbypt} -% Adds a point to the construction -% \begin{macrocode} -\def\pgfpathhobbypt#1{% - #1% - \pgfmathsetmacro\hobby@x{\the\pgf@x/1cm}% - \pgfmathsetmacro\hobby@y{\the\pgf@y/1cm}% - \pgfutil@ifnextchar\bgroup{\pgfpathhobbyptparams}{\pgfpathhobbyptparams{}}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pgfpathhobbyptparams} -% \begin{macrocode} -\def\pgfpathhobbyptparams#1{% - \hobbyaddpoint{#1,x = \hobby@x, y = \hobby@y}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pgfpathhobbyend} -% \begin{macrocode} -\def\pgfpathhobbyend{% - \ifhobby@externalise - \ifx\hobby@path@name\pgfutil@empty - \hobbygenusepath - \else - \hobbygenuseifnecpath{\hobby@path@name}% - \fi - \else - \hobbygenusepath - \fi - \ifx\hobby@path@name\pgfutil@empty - \else - \hobbysavepath{\hobby@path@name}% - \fi - \global\let\hobby@path@name=\pgfutil@empty -} -% \end{macrocode} -% \end{macro} -% -% -% Plot handlers -% -% \begin{macro}{\pgfplothanderhobby} -% Basic plot handler; uses full algorithm but therefore expensive -% \begin{macrocode} -\def\pgfplothandlerhobby{% - \def\pgf@plotstreamstart{% - \hobbyinit\hobby@moveto\hobby@curveto\hobby@close - \global\let\pgf@plotstreampoint=\pgf@plot@hobby@firstpt - \global\let\pgf@plotstreamspecial=\pgfutil@gobble - \gdef\pgf@plotstreamend{% - \ifhobby@externalise - \ifx\hobby@path@name\pgfutil@empty - \hobbygenusepath - \else - \hobbygenuseifnecpath{\hobby@path@name}% - \fi - \else - \hobbygenusepath - \fi - \ifx\hobby@path@name\pgfutil@empty - \else - \hobbysavepath{\hobby@path@name}% - \fi - \global\let\hobby@path@name=\pgfutil@empty - }% - \let\tikz@scan@point@options=\pgfutil@empty - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pgfplothandlerclosedhobby} -% Same as above but produces a closed curve -% \begin{macrocode} -\def\pgfplothandlerclosedhobby{% - \def\pgf@plotstreamstart{% - \hobbyinit\hobby@moveto\hobby@curveto\hobby@close - \hobbysetparams{closed=true,disjoint=true}% - \global\let\pgf@plotstreampoint=\pgf@plot@hobby@firstpt - \global\let\pgf@plotstreamspecial=\pgfutil@gobble - \gdef\pgf@plotstreamend{% - \ifhobby@externalise - \ifx\hobby@path@name\pgfutil@empty - \hobbygenusepath - \else - \hobbygenuseifnecpath{\hobby@path@name}% - \fi - \else - \hobbygenusepath - \fi - \ifx\hobby@path@name\pgfutil@empty - \else - \hobbysavepath{\hobby@path@name}% - \fi - \global\let\hobby@path@name=\pgfutil@empty - }% - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pgf@plot@hobby@firstpt} -% First point, move or line as appropriate and then start the algorithm. -% \begin{macrocode} -\def\pgf@plot@hobby@firstpt#1{% - \pgf@plot@first@action{#1}% - \pgf@plot@hobby@handler{#1}% - \global\let\pgf@plotstreampoint=\pgf@plot@hobby@handler -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pgf@plot@hobby@handler} -% Add points to the array for the algorithm to work on. -% \begin{macrocode} -\def\pgf@plot@hobby@handler#1{% - #1% - \pgfmathsetmacro\hobby@x{\the\pgf@x/1cm}% - \pgfmathsetmacro\hobby@y{\the\pgf@y/1cm}% - \hobbyaddpoint{x = \hobby@x, y = \hobby@y}% - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pgfplothandlerquickhobby} -% Uses the ``quick'' algorithm. -% \begin{macrocode} -\def\pgfplothandlerquickhobby{% - \def\pgf@plotstreamstart{% - \global\let\hobby@quick@curveto=\pgfpathcurveto - \global\let\pgf@plotstreampoint=\pgf@plot@qhobby@firstpt - \global\let\pgf@plotstreamspecial=\pgfutil@gobble - \global\let\pgf@plotstreamend=\pgf@plot@qhobby@end - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pgf@plot@qhobby@firstpt} -% Carry out first action (move or line) and save point. -% \begin{macrocode} -\def\pgf@plot@qhobby@firstpt#1{% - #1% - \edef\hobby@temp{\noexpand\pgf@plot@first@action{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}\hobby@temp% - \xdef\hobby@qpoints{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \gdef\hobby@qpointa{}% - \gdef\hobby@angle{}% - \global\let\pgf@plotstreampoint=\pgf@plot@qhobby@secondpt -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pgf@plot@qhobby@secondpt} -% Also need to save second point. -% \begin{macrocode} -\def\pgf@plot@qhobby@secondpt#1{% - #1% - \xdef\hobby@qpointa{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \global\let\pgf@plotstreampoint=\pgf@plot@qhobby@handler -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pgf@plot@qhobby@handler} -% Wrapper around the computation macro that saves the variables globally. -% \begin{macrocode} -\def\pgf@plot@qhobby@handler#1{% - #1 - \edef\hobby@temp{\noexpand\hobby@quick@compute{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}\hobby@temp - \global\let\hobby@qpointa=\hobby@qpointa - \global\let\hobby@qpoints=\hobby@qpoints - \global\let\hobby@angle=\hobby@angle -% \end{macrocode} -% Also need to save some data for the last point -% \begin{macrocode} - \global\let\hobby@thetaone=\hobby@thetaone - \global\let\hobby@phitwo=\hobby@phitwo - \global\let\hobby@done=\hobby@done - \global\let\hobby@omegaone=\hobby@omegaone -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\pgf@plot@qhobby@end} -% Wrapper around the finalisation step. -% \begin{macrocode} -\def\pgf@plot@qhobby@end{% - \hobby@quick@computeend -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@sf} -% Working with points leads to computations out of range so we scale to get them into the computable arena. -% \begin{macrocode} -\pgfmathsetmacro\hobby@sf{10cm} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\hobby@quick@compute} -% This is the macro that does all the work of computing the control points. -% The argument is the current point, \Verb+\hobby@qpointa+ is the middle point, and \Verb+\hobby@qpoints+ is the first point. -% \begin{macrocode} -\def\hobby@quick@compute#1{% -% \end{macrocode} -% Save the current (second - counting from zero) point in \Verb+\pgf@xb+ and \Verb+\pgf@yb+. -% \begin{macrocode} - #1% - \pgf@xb=\pgf@x - \pgf@yb=\pgf@y -% \end{macrocode} -% Save the previous (first) point in \Verb+\pgf@xa+ and \Verb+\pgf@ya+. -% \begin{macrocode} - \hobby@qpointa - \pgf@xa=\pgf@x - \pgf@ya=\pgf@y -% \end{macrocode} -% Adjust so that \Verb+(\pgf@xb,\pgf@yb)+ is the vector from second to third. -% Then compute and store the distance and angle of this vector. -% We view this as the vector \emph{from} the midpoint and everything to do with that point has the suffix \Verb+one+. -% Note that we divide by the scale factor here. -% \begin{macrocode} - \advance\pgf@xb by -\pgf@xa - \advance\pgf@yb by -\pgf@ya - \pgfmathsetmacro\hobby@done{sqrt((\pgf@xb/\hobby@sf)^2 + (\pgf@yb/\hobby@sf)^2)}% - \pgfmathsetmacro\hobby@omegaone{rad(hobbyatan2(\pgf@yb,\pgf@xb))}% -% \end{macrocode} -% Now we do the same with the vector from the zeroth to the first point. -% \begin{macrocode} - \hobby@qpoints - \advance\pgf@xa by -\pgf@x - \advance\pgf@ya by -\pgf@y - \pgfmathsetmacro\hobby@dzero{sqrt((\pgf@xa/\hobby@sf)^2 + (\pgf@ya/\hobby@sf)^2)}% - \pgfmathsetmacro\hobby@omegazero{rad(hobbyatan2(\pgf@ya,\pgf@xa))}% -% \end{macrocode} -% \Verb+\hobby@psi+ is the angle subtended at the midpoint. -% We adjust to ensure that it is in the right range. -% \begin{macrocode} - \pgfmathsetmacro\hobby@psi{\hobby@omegaone - \hobby@omegazero}% - \pgfmathsetmacro\hobby@psi{\hobby@psi > pi ? \hobby@psi - 2*pi : \hobby@psi}% - \pgfmathsetmacro\hobby@psi{\hobby@psi < -pi ? \hobby@psi + 2*pi : \hobby@psi}% -% \end{macrocode} -% Now we test to see if we're on the first run or not. -% If the first, we have no incoming angle. -% \begin{macrocode} - \ifx\hobby@angle\pgfutil@empty -% \end{macrocode} -% First. -% \begin{macrocode} - \pgfmathsetmacro\hobby@thetaone{-\hobby@psi * \hobby@done% -/(\hobby@done + \hobby@dzero)}% - \pgfmathsetmacro\hobby@thetazero{-\hobby@psi - \hobby@thetaone}% - \let\hobby@phione=\hobby@thetazero - \let\hobby@phitwo=\hobby@thetaone - \else -% \end{macrocode} -% Second or later. -% \begin{macrocode} - \let\hobby@thetazero=\hobby@angle - \pgfmathsetmacro\hobby@thetaone{% - -(2 * \hobby@psi + \hobby@thetazero) * \hobby@done% - / (2 * \hobby@done + \hobby@dzero)}% - \pgfmathsetmacro\hobby@phione{-\hobby@psi - \hobby@thetaone}% - \let\hobby@phitwo=\hobby@thetaone - \fi -% \end{macrocode} -% Save the outgoing angle. -% \begin{macrocode} - \let\hobby@angle=\hobby@thetaone -% \end{macrocode} -% Compute the control points from the angles. -% \begin{macrocode} - \hobby@quick@ctrlpts{\hobby@thetazero}{\hobby@phione}{\hobby@qpoints}{\hobby@qpointa}{\hobby@dzero}{\hobby@omegazero}% -% \end{macrocode} -% Now call the call-back function -% \begin{macrocode} - \edef\hobby@temp{\noexpand\hobby@quick@curveto{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}% -\hobby@temp -% \end{macrocode} -% Cycle the points round for the next iteration. -% \begin{macrocode} - \global\let\hobby@qpoints=\hobby@qpointa - #1 - \xdef\hobby@qpointa{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% -% \end{macrocode} -% Save needed values in global macros -% \begin{macrocode} - \global\let\hobby@angle=\hobby@angle - \global\let\hobby@phitwo=\hobby@phitwo - \global\let\hobby@thetaone=\hobby@thetaone -\global\let\hobby@done=\hobby@done -\global\let\hobby@omegaone=\hobby@omegaone -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@wuick@computeend} -% This is the additional code for the final run. -% \begin{macrocode} -\def\hobby@quick@computeend{% -% \end{macrocode} -% Compute the control points for the second part of the curve and add that to the path. -% \begin{macrocode} - \hobby@quick@ctrlpts{\hobby@thetaone}{\hobby@phitwo}{\hobby@qpoints}{\hobby@qpointa}{\hobby@done}{\hobby@omegaone}% -% \end{macrocode} -% Now call the call-back function -% \begin{macrocode} - \edef\hobby@temp{\noexpand\hobby@quick@curveto{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}% -\hobby@temp -}% -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@quick@ctrlpts} -% Compute the control points from the angles and points given. -% \begin{macrocode} -\def\hobby@quick@ctrlpts#1#2#3#4#5#6{% - \pgfmathsetmacro\hobby@alpha{% - sqrt(2) * (sin(#1 r) - 1/16 * sin(#2 r))% -* (sin(#2 r) - 1/16 * sin(#1 r))% - * (cos(#1 r) - cos(#2 r))}% - \pgfmathsetmacro\hobby@rho{% - (2 + \hobby@alpha)/(1 + (1 - (3 - sqrt(5))/2)% - * cos(#1 r) + (3 - sqrt(5))/2 * cos(#2 r))}% - \pgfmathsetmacro\hobby@sigma{% - (2 - \hobby@alpha)/(1 + (1 - (3 - sqrt(5))/2)% - * cos(#2 r) + (3 - sqrt(5))/2 * cos(#1 r))}% - #3% - \pgf@xa=\pgf@x - \pgf@ya=\pgf@y - \pgfmathsetlength\pgf@xa{% - \pgf@xa + #5 * \hobby@rho% - * cos((#1 + #6) r)/3*\hobby@sf}% - \pgfmathsetlength\pgf@ya{% - \pgf@ya + #5 * \hobby@rho% - * sin((#1 + #6) r)/3*\hobby@sf}% - #4% - \pgf@xb=\pgf@x - \pgf@yb=\pgf@y - \pgfmathsetlength\pgf@xb{% - \pgf@xb - #5 * \hobby@sigma% - * cos((-#2 + #6) r)/3*\hobby@sf}% - \pgfmathsetlength\pgf@yb{% - \pgf@yb - #5 * \hobby@sigma% - * sin((-#2 + #6) r)/3*\hobby@sf}% - #4% -} -% \end{macrocode} -% \end{macro} -% -% \iffalse -% -% \fi -% -% \subsection{TikZ Library} -% -% \iffalse -%<*tikzlibrary> -% \fi -% -% \begin{macrocode} -\usepgflibrary{hobby} -\let\hobby@this@opts=\pgfutil@empty -\let\hobby@next@opts=\pgfutil@empty -\let\hobby@action=\pgfutil@empty -\let\hobby@path@name=\pgfutil@empty -\newif\ifhobby@externalise -% \end{macrocode} -% -% We set various TikZ keys. -% These include the \Verb+to path+ constructor and all the various parameters that will eventually get passed to the path-generation code. -% \begin{macrocode} -\def\hobby@point@options{}% -\tikzset{ - curve through/.style={ - to path={ - \pgfextra{ - \expandafter\curvethrough\expandafter[\hobby@next@opts]{% - (\tikztostart) .. #1 .. (\tikztotarget)% - } - } - } - }, - tension in/.code = {% - \expandafter\gdef\expandafter\hobby@point@options\expandafter% - {\hobby@point@options,tension in=#1}% - }, - tension out/.code = {% - \expandafter\gdef\expandafter\hobby@point@options\expandafter% - {\hobby@point@options,tension out=#1}% - }, - tension/.code = {% - \expandafter\gdef\expandafter\hobby@point@options\expandafter% - {\hobby@point@options,tension=#1}% - }, - excess angle/.code = {% - \expandafter\gdef\expandafter\hobby@point@options\expandafter% - {\hobby@point@options,excess angle=#1}% - }, - break/.code = {% - \expandafter\gdef\expandafter\hobby@point@options\expandafter% - {\hobby@point@options,break=#1}% - }, - blank/.code = {% - \expandafter\gdef\expandafter\hobby@point@options\expandafter% - {\hobby@point@options,blank=#1}% - }, - designated Hobby path/.initial={next}, - clear next Hobby path options/.code={% - \gdef\hobby@next@opts{}% - }, - clear this Hobby path options/.code={% - \gdef\hobby@this@opts{}% - }, - clear Hobby path options/.style={% - clear \pgfkeysvalueof{/tikz/designated Hobby path} Hobby path options - }, - add option to this Hobby path/.code={% - \expandafter\gdef\expandafter\hobby@this@opts\expandafter{\hobby@this@opts#1,}% - }, - add option to next Hobby path/.code={% - \expandafter\gdef\expandafter\hobby@next@opts\expandafter{\hobby@next@opts#1,}% - }, - add option to Hobby path/.style={% - add option to \pgfkeysvalueof{/tikz/designated Hobby path} Hobby path={#1}% - }, - closed/.style = {% - add option to Hobby path={closed=#1,disjoint=#1}% - }, - invert blank/.style = {% - add option to Hobby path={invert blank=#1}% - }, - closed/.default = true, - blank/.default = true, - break/.default = true, - invert blank/.default = true, - in angle/.code = {% - \pgfmathparse{(#1)*pi/180}% - \edef\@temp{in angle=\pgfmathresult,}% - \pgfkeysalso{add option to Hobby path/.expand once=\@temp}% - }, - out angle/.code = {% - \pgfmathparse{(#1)*pi/180}% - \edef\@temp{out angle=\pgfmathresult,}% - \pgfkeysalso{add option to Hobby path/.expand once=\@temp}% - }, - in curl/.style = {% - add option to Hobby path={in curl=#1}% - }, - out curl/.code = {% - add option to Hobby path={out curl=#1}% - }, - use Hobby shortcut/.code={% - \let\tikz@curveto@auto=\hobby@curveto@override - \global\let\hobby@curveto@delegate=\hobby@curveto@auto - }, - use quick Hobby shortcut/.code={% - \let\tikz@curveto@auto=\hobby@curveto@override - \global\let\hobby@curveto@delegate=\hobby@qcurveto@auto - }, - use previous Hobby path/.code={% - \pgfextra{\hobbyusepath{#1}} - }, - use previous Hobby path/.default={},% - save Hobby path/.code={% - \xdef\hobby@path@name{#1}% - }, - restore Hobby path/.code={% - \pgfextra{% - \hobbyinit\hobby@tikz@moveto\hobby@tikz@curveto\hobby@tikz@close - \global\let\hobby@collected@onpath\pgfutil@empty - \hobbyrestorepath{#1}} - }, - restore and use Hobby path/.code 2 args={% - \pgfextra{% - \hobbyinit\hobby@tikz@moveto\hobby@tikz@curveto\hobby@tikz@close - \global\let\hobby@collected@onpath\pgfutil@empty - \hobbyrestorepath{#1}% - \hobbyusepath{#2}% - } - }, - show Hobby path/.code={% - \pgfextra{\hobbyshowpath{#1}} - }, - Hobby action/.code={% - \expandafter\gdef\expandafter\hobby@action\expandafter{\hobby@action#1}% - }, - Hobby finish/.style={% - Hobby action=\hobby@finish% - }, - Hobby externalise/.is if=hobby@externalise, - Hobby externalize/.is if=hobby@externalise -} -% \end{macrocode} -% -% \begin{macro}{\hobby@tikz@curveto} -% This is passed to the path-generation code to translate the path into a PGF path. -% \begin{macrocode} -\def\hobby@tikz@curveto#1#2#3{% - \pgfutil@ifundefined{tikz@timer@start}{% - \expandafter\hobby@topgf\expandafter{\hobby@initial@pt}% - \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - }{}% - \hobby@topgf{#1}% - \edef\tikz@timer@cont@one{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \hobby@topgf{#2}% - \edef\tikz@timer@cont@two{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \hobby@topgf{#3}% - \let\tikz@timer=\tikz@timer@curve - \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \ifx\hobby@collected@onpath\pgfutil@empty - \else - \expandafter\hobby@nodes@onpath\hobby@collected@onpath\relax\relax - \fi - \pgfpathcurveto{\hobby@topgf{#1}}{\hobby@topgf{#2}}{\hobby@topgf{#3}}% - \hobby@topgf{#3}% - \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@tikz@moveto} -% This is passed to the path-generation code to translate the path into a PGF path. -% \begin{macrocode} -\def\hobby@tikz@moveto#1#2#3{% - \pgfutil@ifundefined{tikz@timer@start}{% - \expandafter\hobby@topgf\expandafter{\hobby@initial@pt}% - \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - }{}% - \hobby@topgf{#3}% - \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \def\pgf@temp{#1}% - \ifx\pgf@temp\pgfutil@empty - \let\tikz@timer=\tikz@timer@line - \expandafter\def\expandafter\hobby@collected@onpath\expandafter{\expandafter{\expandafter}\hobby@collected@onpath} - \else - \hobby@topgf{#1}% - \edef\tikz@timer@cont@one{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \hobby@topgf{#2}% - \edef\tikz@timer@cont@two{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \let\tikz@timer=\tikz@timer@curve - \fi - \ifx\hobby@collected@onpath\pgfutil@empty - \else - \expandafter\hobby@nodes@onpath\hobby@collected@onpath\relax\relax - \fi - \pgfpathmoveto{\hobby@topgf{#3}}% - \hobby@topgf{#3}% - \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@tikz@close} -% Closes a path. -% \begin{macrocode} -\def\hobby@tikz@close#1{% - \hobby@topgf{#1}% - \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \let\tikz@timer=\tikz@timer@line - \ifx\hobby@collected@onpath\pgfutil@empty - \else - \expandafter\hobby@nodes@onpath\hobby@collected@onpath\relax\relax - \fi - \pgfpathclose -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@nodes@onpath} -% \begin{macrocode} -\def\hobby@nodes@onpath#1#2\relax{% - \gdef\hobby@collected@onpath{#2}% - \def\pgf@temp{#1}% - \ifx\pgf@temp\pgfutil@empty - \else - \def\@gtempa{\relax} - \ifx\pgf@temp\@gtempa - \else - \tikz@node@is@a@labeltrue - \tikz@scan@next@command#1\pgf@stop - \tikz@node@is@a@labelfalse - \fi - \fi -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\curvethrough} -% This is the parent command. -% We initialise the path-generation code, set any parameters, and then hand over control to the point processing macro. -% \begin{macrocode} -\newcommand\curvethrough[2][]{% - \hobbyinit\hobby@tikz@moveto\hobby@tikz@curveto\hobby@tikz@close - \global\let\hobby@collected@onpath\pgfutil@empty - \let\hobby@initial@pt\pgfutil@empty - \hobbysetparams{#1}% - \tikzset{designated Hobby path=this}% - \global\let\hobby@this@opts=\pgfutil@empty - \global\let\hobby@next@opts=\pgfutil@empty - \let\tikz@scan@point@options=\pgfutil@empty - \def\hobby@point@options{}% - \tikz@scan@one@point\hobby@processpt #2 \relax% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@processpt} -% This processes a list of points in the format \Verb+(0,0) [..] (1,1)+. -% Each point is scanned by TikZ and then added to the stack to be built into the path. -% If there are any remaining points, we call ourself again with them. -% Otherwise, we hand over control to the path-generation code. -% \begin{macrocode} -\newcommand\hobby@processpt[1]{% - #1% - \pgfmathsetmacro\hobby@x{\the\pgf@x/1cm}% - \pgfmathsetmacro\hobby@y{\the\pgf@y/1cm}% - \ifx\hobby@initial@pt\pgfutil@empty - \xdef\hobby@initial@pt{x = \hobby@x, y = \hobby@y}% - \fi - \expandafter\hobbyaddpoint\expandafter{\hobby@point@options,% - x = \hobby@x, y = \hobby@y}% - \def\hobby@point@options{}% - \let\tikz@scan@point@options=\pgfutil@empty - \pgfutil@ifnextchar\relax{% - \expandafter\hobbysetparams\expandafter{\hobby@this@opts}% - \ifhobby@externalise - \ifx\hobby@path@name\pgfutil@empty - \hobbygenusepath - \else - \hobbygenuseifnecpath{\hobby@path@name}% - \fi - \else - \hobbygenusepath - \fi - \ifx\hobby@path@name\pgfutil@empty - \else - \hobbysavepath{\hobby@path@name}% - \fi - \global\let\hobby@path@name=\pgfutil@empty - }{% - \pgfutil@ifnextchar.{% - \hobby@swallowdots}{% - \tikz@scan@one@point\hobby@processpt}}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@swallowdots} -% Remove dots from the input stream. -% \begin{macrocode} -\def\hobby@swallowdots.{% - \pgfutil@ifnextchar.{% - \hobby@swallowdots}{% - \tikz@scan@one@point\hobby@processpt}} -% \end{macrocode} -% \end{macro} -% -% There is a ``spare hook'' in the TikZ path processing code. -% If TikZ encounters a path of the form \Verb+(0,0) .. (1,1)+ then it calls a macro \Verb+\tikz@curveto@auto+. -% However, that macro is not defined in the TikZ code. -% The following code provides a suitable definition. -% To play nice, we don't install it by default but define a key (defined above) that installs it. -% -% \begin{macro}{\hobby@curveto@override} -% \begin{macrocode} -\def\hobby@curveto@override{% - \hobby@curveto@delegate} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@curveto@auto} -% When we're called by TikZ, we initialise the path generation code and start adding points. -% To ensure that the generation code is called, we add a lot of hooks to lots of TikZ commands. -% \begin{macrocode} -\def\hobby@curveto@auto{% - \hobbyinit\hobby@tikz@moveto\hobby@tikz@curveto\hobby@tikz@close - \expandafter\gdef\expandafter\hobby@collected@onpath\expandafter{\expandafter{\tikz@collected@onpath} }% - \let\tikz@collected@onpath=\pgfutil@empty - \pgfmathsetmacro\hobby@x{\the\tikz@lastx/1cm}% - \pgfmathsetmacro\hobby@y{\the\tikz@lasty/1cm}% - \xdef\hobby@initial@pt{x = \hobby@x, y = \hobby@y}% - \expandafter\hobbysetparams\expandafter{\hobby@next@opts}% - \expandafter\hobbyaddpoint\expandafter{\hobby@point@options,% - x = \hobby@x, y = \hobby@y}% - \hobby@init@tikz@commands - \tikzset{designated Hobby path=this}% - \let\tikz@scan@point@options=\pgfutil@empty - \global\let\hobby@action=\pgfutil@empty - \global\let\hobby@this@opts=\pgfutil@empty - \global\let\hobby@next@opts=\pgfutil@empty - \global\let\hobby@point@options=\pgfutil@empty - \tikz@scan@one@point\hobby@addfromtikz% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@addfromtikz} -% This adds our current point to the stack. -% \begin{macrocode} -\def\hobby@addfromtikz#1{% - #1% - \tikz@make@last@position{#1}% - \pgfmathsetmacro\hobby@x{\the\pgf@x/1cm}% - \pgfmathsetmacro\hobby@y{\the\pgf@y/1cm}% - \expandafter\hobbysetparams\expandafter{\hobby@this@opts}% - \expandafter\hobbyaddpoint\expandafter{\hobby@point@options,% - x = \hobby@x, y = \hobby@y}% - \hobby@action - \global\let\hobby@this@opts=\pgfutil@empty - \global\let\hobby@action=\pgfutil@empty - \global\let\hobby@point@options=\pgfutil@empty - \tikz@scan@next@command% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@init@tikz@commands} -% \begin{macrocode} -\def\hobby@init@tikz@commands{% - \hobby@init@tikz@modcmd\tikz@movetoabs - \hobby@init@tikz@modcmd\tikz@movetorel - \hobby@init@tikz@modcmd\tikz@lineto - \hobby@init@tikz@modcmd\tikz@rect - \hobby@init@tikz@modcmd\tikz@cchar - \hobby@init@tikz@modcmd\tikz@finish - \hobby@init@tikz@modcmd\tikz@arcA - \hobby@init@tikz@modcmd\tikz@e@char - \hobby@init@tikz@modcmd\tikz@g@char - \hobby@init@tikz@modcmd\tikz@schar - \hobby@init@tikz@modcmd\tikz@vh@lineto - \hobby@init@tikz@modcmd\tikz@pchar - \hobby@init@tikz@modcmd\tikz@to - \hobby@init@tikz@modcmd\pgf@stop - \hobby@init@tikz@modcmd\tikz@decoration - \global\let\hobby@curveto@delegate=\hobby@midcurveto@auto -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@restore@tikz@commands} -% \begin{macrocode} -\def\hobby@restore@tikz@commands{% - \hobby@restore@tikz@modcmd\tikz@movetoabs - \hobby@restore@tikz@modcmd\tikz@movetorel - \hobby@restore@tikz@modcmd\tikz@lineto - \hobby@restore@tikz@modcmd\tikz@rect - \hobby@restore@tikz@modcmd\tikz@cchar - \hobby@restore@tikz@modcmd\tikz@finish - \hobby@restore@tikz@modcmd\tikz@arcA - \hobby@restore@tikz@modcmd\tikz@e@char - \hobby@restore@tikz@modcmd\tikz@g@char - \hobby@restore@tikz@modcmd\tikz@schar - \hobby@restore@tikz@modcmd\tikz@vh@lineto - \hobby@restore@tikz@modcmd\tikz@pchar - \hobby@restore@tikz@modcmd\tikz@to - \hobby@restore@tikz@modcmd\pgf@stop - \hobby@restore@tikz@modcmd\tikz@decoration - \global\let\hobby@curveto@delegate=\hobby@curveto@auto -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@init@tikz@modcmd} -% \begin{macrocode} -\def\hobby@init@tikz@modcmd#1{% - \expandafter\global\expandafter\let\csname hobby@orig@\string#1\endcsname=#1% - \gdef#1{\hobby@finish#1}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@restore@tikz@modcmd} -% \begin{macrocode} -\def\hobby@restore@tikz@modcmd#1{% - \expandafter\global\expandafter\let\expandafter#1\csname hobby@orig@\string#1\endcsname% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@midcurveto@auto} -% \begin{macrocode} -\def\hobby@midcurveto@auto{% - \expandafter\expandafter\expandafter\gdef\expandafter\expandafter\expandafter\hobby@collected@onpath\expandafter\expandafter\expandafter{\expandafter\hobby@collected@onpath\expandafter{\tikz@collected@onpath} }% - \let\tikz@collected@onpath=\pgfutil@empty - \let\tikz@scan@point@options=\pgfutil@empty - \global\let\hobby@action=\pgfutil@empty - \global\let\hobby@this@opts=\pgfutil@empty - \global\let\hobby@point@options=\pgfutil@empty - \tikz@scan@one@point\hobby@addfromtikz% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@finish} -% \begin{macrocode} -\def\hobby@finish{% - \hobby@restore@tikz@commands - \ifhobby@externalise - \ifx\hobby@path@name\pgfutil@empty - \hobbygenusepath - \else - \hobbygenuseifnecpath{\hobby@path@name}% - \fi - \else - \hobbygenusepath - \fi - \ifx\hobby@path@name\pgfutil@empty - \else - \hobbysavepath{\hobby@path@name}% - \fi - \global\let\hobby@path@name=\pgfutil@empty - \tikzset{designated Hobby path=next}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{quick curve through} -% The \Verb+quick curve through+ is a \Verb+to path+ which does the ``quick'' version of Hobby's algorithm. -% The syntax is as with the \Verb+curve through+: to pass the midpoints as the argument to the style. -% We need to pass three points to the auxiliary macro. -% These are passed as \Verb+\hobby@qpoints+, \Verb+\hobby@qpointa+, and the current point. -% Then these get cycled round for the next triple. -% The path gets built up and stored as \Verb+\hobby@quick@path+. -% We also have to remember the angle computed for the next round. -% \begin{macrocode} -\tikzset{ - quick curve through/.style={% - to path={% - \pgfextra{% -% \end{macrocode} -% Scan the starting point and store the coordinates in \Verb+\hobby@qpointa+ -% \begin{macrocode} - \let\hobby@next@qbreak=\relax - \let\hobby@next@qblank=\relax - \tikz@scan@one@point\pgfutil@firstofone(\tikztostart)% - \tikz@make@last@position{\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \edef\hobby@qpoints{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% -% \end{macrocode} -% Blank the path and auxiliary macros. -% \begin{macrocode} - \def\hobby@qpointa{}% - \def\hobby@quick@path{}% - \def\hobby@angle{}% - \let\hobby@quick@curveto=\hobby@quick@makepath -% \end{macrocode} -% Now start parsing the rest of the coordinates. -% \begin{macrocode} - \tikz@scan@one@point\hobby@quickfirst #1 (\tikztotarget)\relax - } -% \end{macrocode} -% Invoke the path -% \begin{macrocode} - \hobby@quick@path - } - }, - quick hobby/blank curve/.is choice, - quick hobby/blank curve/true/.code={% - \gdef\hobby@next@qblank{% - \qhobby@blanktrue - \global\let\hobby@next@qblank=\relax - }% - }, - quick hobby/blank curve/false/.code={% - \gdef\hobby@next@qblank{% - \qhobby@blankfalse - \global\let\hobby@next@qblank=\relax - }% - }, - quick hobby/blank curve/once/.code={% - \gdef\hobby@next@qblank{% - \qhobby@blanktrue - \gdef\hobby@next@qblank{% - \qhobby@blankfalse - \global\let\hobby@next@qblank=\relax - }% - }% - }, - quick hobby/blank curve/.default=true, - quick hobby/break curve/.is choice, - quick hobby/break curve/true/.code={% - \gdef\hobby@next@qbreak{% - \qhobby@breaktrue - \global\let\hobby@next@qbreak=\relax - }% - }, - quick hobby/break curve/false/.code={% - \gdef\hobby@next@qbreak{% - \qhobby@breakfalse - \global\let\hobby@next@qbreak=\relax - }% - }, - quick hobby/break curve/once/.code={% - \gdef\hobby@next@qbreak{% - \qhobby@breaktrue - \gdef\hobby@next@qbreak{% - \qhobby@breakfalse - \global\let\hobby@next@qbreak=\relax - }% - }% - }, - quick hobby/break curve/.default=true, -} -\newif\ifqhobby@break -\newif\ifqhobby@blank -% \end{macrocode} -% \end{macro} -% -% Add plot handlers -% \begin{macrocode} -\tikzoption{hobby}[]{\let\tikz@plot@handler=\pgfplothandlerhobby} -\tikzoption{quick hobby}[]{\let\tikz@plot@handler=\pgfplothandlerquickhobby} -\tikzoption{closed hobby}[]{\let\tikz@plot@handler=\pgfplothandlerclosedhobby} -% \end{macrocode} -% -% \begin{macro}{\hobby@quickfirst} -% The first time around we just set the next point. -% \begin{macrocode} -\def\hobby@quickfirst#1{% - #1% - \xdef\hobby@qpointa{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \tikz@make@last@position{\hobby@qpointa}% -% \end{macrocode} -% Now a check to ensure that we have more points. -% \begin{macrocode} - \pgfutil@ifnextchar\relax{% -% \end{macrocode} -% Ooops, no more points. -% That's not good. -% Bail-out. -% \begin{macrocode} - \xdef\hobby@quick@path{ -- (\the\pgf@x,\the\pgf@y)}% - }{% -% \end{macrocode} -% Okay, have more points. -% Phew. -% Call the next round. -% If we have dots, swallow them. -% \begin{macrocode} - \pgfutil@ifnextchar.{% - \hobby@qswallowdots}{% - \tikz@scan@one@point\hobby@quick}}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@qswallowdots} -% Remove dots from the input stream. -% \begin{macrocode} -\def\hobby@qswallowdots.{% - \pgfutil@ifnextchar.{% - \hobby@qswallowdots}{% - \tikz@scan@one@point\hobby@quick}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@quick} -% This is our wrapper function that handles the loop. -% \begin{macrocode} -\def\hobby@quick#1{% - \hobby@quick@compute{#1}% - \tikz@make@last@position{\hobby@qpointa}% - \pgfutil@ifnextchar\relax{% -% \end{macrocode} -% End of loop -% \begin{macrocode} - \hobby@quick@computeend% - }{% -% \end{macrocode} -% More to go, scan in the next coordinate and off we go again. -% \begin{macrocode} - \pgfutil@ifnextchar.{% - \hobby@qswallowdots}{% - \tikz@scan@one@point\hobby@quick}}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@quick@makepath} -% Path constructor for \Verb+to path+ use. -% \begin{macrocode} -\def\hobby@quick@makepath#1#2#3{% - #1% - \pgf@xa=\pgf@x\relax - \pgf@ya=\pgf@y\relax - #2% - \pgf@xb=\pgf@x\relax - \pgf@yb=\pgf@y\relax - #3% - \ifqhobby@blank - \xdef\hobby@quick@path{\hobby@quick@path (\the\pgf@x,\the\pgf@y)}% - \else - \xdef\hobby@quick@path{\hobby@quick@path .. controls% - (\the\pgf@xa,\the\pgf@ya) and (\the\pgf@xb,\the\pgf@yb) .. (\the\pgf@x,\the\pgf@y) }% - \fi - \ifqhobby@break - \xdef\hobby@quick@path{\hobby@quick@path +(0,0)}% - \fi - \hobby@next@qbreak - \hobby@next@qblank -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@qcurveto@auto} -% Uses the ``quick'' method for the shortcut syntax. -% \begin{macrocode} -\def\hobby@qcurveto@auto{% - \global\let\hobby@next@qbreak=\relax - \global\let\hobby@next@qblank=\relax - \xdef\hobby@qpoints{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% - \gdef\hobby@qpointa{}% - \gdef\hobby@quick@path{}% - \gdef\hobby@angle{}% - \global\let\hobby@quick@curveto=\hobby@quick@makepathauto - \hobby@qinit@tikz@commands - \let\tikz@scan@point@options=\pgfutil@empty - \global\let\hobby@action=\pgfutil@empty - \global\let\hobby@point@options=\pgfutil@empty - \tikz@scan@one@point\hobby@qfirst@auto} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@qmidcurveto@auto} -% \begin{macrocode} -\def\hobby@qmidcurveto@auto{% - \let\tikz@scan@point@options=\pgfutil@empty - \global\let\hobby@action=\pgfutil@empty - \global\let\hobby@point@options=\pgfutil@empty - \tikz@scan@one@point\hobby@qaddfromtikz} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@qfirst@auto} -% \begin{macrocode} -\def\hobby@qfirst@auto#1{% - #1% - \xdef\hobby@qpointa{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \tikz@make@last@position{\hobby@qpointa}% - \tikz@scan@next@command% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@quick@makepathauto} -% Path constructor for shortcut method to use. -% \begin{macrocode} -\def\hobby@quick@makepathauto#1#2#3{% - #1% - \pgf@xa=\pgf@x\relax - \pgf@ya=\pgf@y\relax - #2% - \pgf@xb=\pgf@x\relax - \pgf@yb=\pgf@y\relax - #3% - \ifqhobby@blank - \edef\hobby@temp{% - \noexpand\pgfpathmoveto{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - }% - \hobby@temp - \else - \edef\hobby@temp{% - \noexpand\pgfpathcurveto{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% - {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}% - {\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - }% - \hobby@temp - \fi - \ifqhobby@break - #3% - \edef\hobby@temp{% - \noexpand\pgfpathmoveto{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - }% - \hobby@temp - \fi - \hobby@next@qbreak - \hobby@next@qblank -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@qaddfromtikz} -% This adds our current point to the stack. -% \begin{macrocode} -\def\hobby@qaddfromtikz#1{% - \hobby@quick@compute{#1}% - \tikz@make@last@position{\hobby@qpointa}% - \tikz@scan@next@command% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@qinit@tikz@commands} -% \begin{macrocode} -\def\hobby@qinit@tikz@commands{% - \hobby@qinit@tikz@modcmd\tikz@movetoabs - \hobby@qinit@tikz@modcmd\tikz@movetorel - \hobby@qinit@tikz@modcmd\tikz@lineto - \hobby@qinit@tikz@modcmd\tikz@rect - \hobby@qinit@tikz@modcmd\tikz@cchar - \hobby@qinit@tikz@modcmd\tikz@finish - \hobby@qinit@tikz@modcmd\tikz@arcA - \hobby@qinit@tikz@modcmd\tikz@e@char - \hobby@qinit@tikz@modcmd\tikz@g@char - \hobby@qinit@tikz@modcmd\tikz@schar - \hobby@qinit@tikz@modcmd\tikz@vh@lineto - \hobby@qinit@tikz@modcmd\tikz@pchar - \hobby@qinit@tikz@modcmd\tikz@to - \hobby@qinit@tikz@modcmd\pgf@stop - \hobby@qinit@tikz@modcmd\tikz@decoration - \hobby@qinit@tikz@modcmd\tikz@@close - \global\let\hobby@curveto@delegate=\hobby@qmidcurveto@auto -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@qrestore@tikz@commands} -% \begin{macrocode} -\def\hobby@qrestore@tikz@commands{% - \hobby@restore@tikz@modcmd\tikz@movetoabs - \hobby@restore@tikz@modcmd\tikz@movetorel - \hobby@restore@tikz@modcmd\tikz@lineto - \hobby@restore@tikz@modcmd\tikz@rect - \hobby@restore@tikz@modcmd\tikz@cchar - \hobby@restore@tikz@modcmd\tikz@finish - \hobby@restore@tikz@modcmd\tikz@arcA - \hobby@restore@tikz@modcmd\tikz@e@char - \hobby@restore@tikz@modcmd\tikz@g@char - \hobby@restore@tikz@modcmd\tikz@schar - \hobby@restore@tikz@modcmd\tikz@vh@lineto - \hobby@restore@tikz@modcmd\tikz@pchar - \hobby@restore@tikz@modcmd\tikz@to - \hobby@restore@tikz@modcmd\pgf@stop - \hobby@restore@tikz@modcmd\tikz@decoration - \hobby@restore@tikz@modcmd\tikz@@close - \global\let\hobby@curveto@delegate=\hobby@qcurveto@auto -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@qinit@tikz@modcmd} -% \begin{macrocode} -\def\hobby@qinit@tikz@modcmd#1{% - \expandafter\global\expandafter\let\csname hobby@orig@\string#1\endcsname=#1% - \gdef#1{\hobby@qfinish#1}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hobby@qfinish} -% \begin{macrocode} -\def\hobby@qfinish{% - \hobby@quick@computeend - \hobby@qrestore@tikz@commands -} -% \end{macrocode} -% \end{macro} - -% \iffalse -% -% \fi -% -% \subsection{Arrays} -% -% \iffalse -%<*array> -% \fi -% -% -% A lot of our data structures are really arrays. -% These are implemented as \LaTeX3 ``property lists''. -% For ease of use, an array is a property list with numeric entries together with entries ``base'' and ``top'' which hold the lowest and highest indices that have been set. -% -% \begin{macrocode} -\RequirePackage{expl3} -\ExplSyntaxOn -% \end{macrocode} -% Some auxiliary variables. -% \begin{macrocode} -\tl_new:N \l_array_tmp_tl -\tl_new:N \l_array_show_tl -\int_new:N \l_array_base_int -\int_new:N \l_array_top_int -\int_new:N \l_array_tmp_int -% \end{macrocode} -% The global variable \Verb+\g_array_base_int+ says what index a blank array should start with when pushed or unshifted. -% \begin{macrocode} -\int_new:N \g_array_base_int -\int_set:Nn \g_array_base_int {0} -% \end{macrocode} -% \begin{macro}{\array_adjust_ends:Nn} -% This ensures that the ``base'' and ``top'' are big enough to include the given index. -% \begin{macrocode} -\cs_new:Npn \array_adjust_ends:Nn #1#2 { - \prop_get:NnNTF #1 {base} \l_tmpa_tl - { - \int_compare:nNnTF {\l_tmpa_tl} > {#2} - { - \prop_put:Nnx #1 {base} {\int_eval:n {#2}} - } - {} - } - { - \prop_put:Nnx #1 {base} {\int_eval:n {#2}} - } - \prop_get:NnNTF #1 {top} \l_tmpa_tl - { - \int_compare:nNnTF {\l_tmpa_tl} < {#2} - { - \prop_put:Nnx #1 {top} {\int_eval:n {#2}} - } - {} - } - { - \prop_put:Nnx #1 {top} {\int_eval:n {#2}} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_gadjust_ends:Nn} -% This ensures that the ``base'' and ``top'' are big enough to include the given index. -% (Global version) -% \begin{macrocode} -\cs_new:Npn \array_gadjust_ends:Nn #1#2 { - \prop_get:NnNTF #1 {base} \l_tmpa_tl - { - \int_compare:nNnTF {\l_tmpa_tl} > {#2} - { - \prop_gput:Nnx #1 {base} {\int_eval:n {#2}} - } - {} - } - { - \prop_gput:Nnx #1 {base} {\int_eval:n {#2}} - } - \prop_get:NnNTF #1 {top} \l_tmpa_tl - { - \int_compare:nNnTF {\l_tmpa_tl} < {#2} - { - \prop_gput:Nnx #1 {top} {\int_eval:n {#2}} - } - {} - } - { - \prop_gput:Nnx #1 {top} {\int_eval:n {#2}} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_put:Nnn} -% When adding a value to an array we have to adjust the ends. -% \begin{macrocode} -\cs_new:Npn \array_put:Nnn #1#2#3 { - \exp_args:NNx \prop_put:Nnn #1 {\int_eval:n {#2}} {#3} - \array_adjust_ends:Nn #1{#2} -} -\cs_generate_variant:Nn \array_put:Nnn {Nnx} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_gput:Nnn} -% When adding a value to an array we have to adjust the ends. -% (Global version) -% \begin{macrocode} -\cs_new:Npn \array_gput:Nnn #1#2#3 { - \exp_args:NNx \prop_gput:Nnn #1 {\int_eval:n {#2}} {#3} - \array_gadjust_ends:Nn #1{#2} -} -\cs_generate_variant:Nn \array_gput:Nnn {Nnx} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_get:NnN} -% \begin{macrocode} -\cs_new:Npn \array_get:NnN #1#2#3 { - \exp_args:NNx \prop_get:NnN #1 {\int_eval:n {#2}} #3 -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[EXP]{\array_get:Nn} -% \begin{macrocode} -\cs_new:Npn \array_get:Nn #1#2 { - \exp_args:NNf \prop_item:Nn #1 { \int_eval:n {#2} } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_get:NnNTF} -% \begin{macrocode} -\cs_new:Npn \array_get:NnNTF #1#2#3#4#5 { - \exp_args:NNx \prop_get:NnNTF #1 {\int_eval:n {#2}} #3 {#4}{#5} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_if_empty:NTF} -% \begin{macrocode} -\prg_new_conditional:Npnn \array_if_empty:N #1 { p, T, F, TF } -{ - \if_meaning:w #1 \c_empty_prop - \prg_return_true: - \else: - \prg_return_false: - \fi: -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_if_exist:NTF} -% \begin{macrocode} -\prg_new_eq_conditional:NNn \array_if_exist:N \cs_if_exist:N { p, T, F, TF } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_new:N} -% \begin{macrocode} -\cs_new_eq:NN \array_new:N \prop_new:N -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_clear:N} -% \begin{macrocode} -\cs_new_eq:NN \array_clear:N \prop_clear:N -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_gclear:N} -% \begin{macrocode} -\cs_new_eq:NN \array_gclear:N \prop_gclear:N -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_map_function} -% When stepping through an array, we want to iterate in order so a simple wrapper to \Verb+\prop_map_function+ is not enough. -% This maps through every value from the base to the top so the function should be prepared to deal with a \Verb+\q_no_value+. -% \begin{macrocode} -\cs_new:Npn \array_map_function:NN #1#2 -{ - \array_if_empty:NTF #1 {} { - \prop_get:NnNTF #1 {base} \l_array_tmp_tl { - \int_set:Nn \l_array_base_int {\l_array_tmp_tl} - }{ - \int_set:Nn \l_array_base_int {0} - } - \prop_get:NnNTF #1 {top} \l_array_tmp_tl { - \int_set:Nn \l_array_top_int {\l_array_tmp_tl} - }{ - \int_set:Nn \l_array_top_int {0} - } - \int_step_inline:nnnn {\l_array_base_int} {1} {\l_array_top_int} { - \array_get:NnN #1 {##1} \l_array_tmp_tl - \exp_args:NnV #2 {##1} \l_array_tmp_tl -} -} {} -} -\cs_generate_variant:Nn \array_map_function:NN { Nc } -\cs_generate_variant:Nn \array_map_function:NN { c , cc } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_reverse_map_function} -% This steps through the array in reverse order. -% \begin{macrocode} -\cs_new:Npn \array_reverse_map_function:NN #1#2 -{ - \array_if_empty:NTF #1 {} { - \prop_get:NnNTF #1 {base} \l_array_tmp_tl { - \int_set:Nn \l_array_base_int {\l_array_tmp_tl} - }{ - \int_set:Nn \l_array_base_int {0} - } - \prop_get:NnNTF #1 {top} \l_array_tmp_tl { - \int_set:Nn \l_array_top_int {\l_array_tmp_tl} - }{ - \int_set:Nn \l_array_top_int {0} - } - \int_step_inline:nnnn {\l_array_top_int} {-1} {\l_array_base_int} { - \array_get:NnN #1 {##1} \l_array_tmp_tl - \exp_args:Nno #2 {##1} \l_array_tmp_tl -} -} {} -} -\cs_generate_variant:Nn \array_reverse_map_function:NN { Nc } -\cs_generate_variant:Nn \array_reverse_map_function:NN { c , cc } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_map_inline:Nn} -% Inline version of the above. -% \begin{macrocode} -\cs_new_protected:Npn \array_map_inline:Nn #1#2 - { - \int_gincr:N \g__prg_map_int - \cs_gset:cpn { array_map_inline_ \int_use:N \g__prg_map_int :nn } - ##1##2 {#2} - \exp_args:NNc \array_map_function:NN #1 - { array_map_inline_ \int_use:N \g__prg_map_int :nn } - \__prg_break_point:Nn \array_map_break: { \int_gdecr:N \g__prg_map_int } - } -\cs_generate_variant:Nn \array_map_inline:Nn { c } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_reverse_map_inline:Nn} -% Inline version of the above. -% \begin{macrocode} -\cs_new_protected:Npn \array_reverse_map_inline:Nn #1#2 - { - \int_gincr:N \g__prg_map_int - \cs_gset:cpn { array_map_inline_ \int_use:N \g__prg_map_int :nn } - ##1##2 {#2} - \exp_args:NNc \array_reverse_map_function:NN #1 - { array_map_inline_ \int_use:N \g__prg_map_int :nn } - \__prg_break_point:Nn \array_map_break: { \int_gdecr:N \g__prg_map_int } - } -\cs_generate_variant:Nn \array_reverse_map_inline:Nn { c } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_map_break:} -% \begin{macrocode} -\cs_new_nopar:Npn \array_map_break: - { \__prg_map_break:Nn \array_map_break: { } } -\cs_new_nopar:Npn \array_map_break:n - { \__prg_map_break:Nn \array_map_break: } -% \end{macrocode} -% \end{macro} -% -% For displaying arrays, we need some messages. -% \begin{macrocode} -\msg_new:nnn { kernel } { show-array } - { - The~array~\token_to_str:N #1~ - \array_if_empty:NTF #1 - { is~empty } - { contains~the~items~(without~outer~braces): } - } -% \end{macrocode} -% -% \begin{macro}{\array_show:N} -% Mapping through an array isn't expandable so we have to set a token list to its contents first before passing it to the message handler. -% \begin{macrocode} -\cs_new_protected:Npn \array_show:N #1 - { - \__msg_show_variable:NNNnn - #1 - \array_if_exist:NTF - \array_if_empty:NTF - { array } - { \array_map_function:NN #1 \__msg_show_item:nn } - } -\cs_generate_variant:Nn \array_show:N { c } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_push:Nn} -% \begin{macrocode} -\cs_new_protected:Npn \array_push:Nn #1#2 -{ - \prop_get:NnNTF #1 {top} \l_array_tmp_tl - { - \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} - \int_incr:N \l_array_tmp_int - \array_put:Nnn #1 {\l_array_tmp_int} {#2} - } - { - \array_put:Nnn #1 {\g_array_base_int} {#2} - } -} -\cs_generate_variant:Nn \array_push:Nn {Nx} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_gpush:Nn}b -% \begin{macrocode} -\cs_new_protected:Npn \array_gpush:Nn #1#2 -{ - \prop_get:NnNTF #1 {top} \l_array_tmp_tl - { - \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} - \int_incr:N \l_array_tmp_int - \array_gput:Nnn #1 {\l_array_tmp_int} {#2} - } - { - \array_gput:Nnn #1 {\g_array_base_int} {#2} - } -} -\cs_generate_variant:Nn \array_gpush:Nn {Nx} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_unshift:Nn} -% \begin{macrocode} -\cs_new_protected:Npn \array_unshift:Nn #1#2 -{ - \prop_get:NnNTF #1 {base} \l_array_tmp_tl - { - \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} - \int_decr:N \l_array_tmp_int - \array_put:Nnn #1 {\l_array_tmp_int} {#2} - } - { - \array_put:Nnn #1 {\g_array_base_int} {#2} - } -} -\cs_generate_variant:Nn \array_unshift:Nn {Nx} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_gunshift:Nn} -% \begin{macrocode} -\cs_new_protected:Npn \array_gunshift:Nn #1#2 -{ - \prop_get:NnNTF #1 {base} \l_array_tmp_tl - { - \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} - \int_decr:N \l_array_tmp_int - \array_gput:Nnn #1 {\l_array_tmp_int} {#2} - } - { - \array_gput:Nnn #1 {\g_array_base_int} {#2} - } -} -\cs_generate_variant:Nn \array_gunshift:Nn {Nx} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_pop:NN} -% \begin{macrocode} -\cs_new_protected:Npn \array_pop:NN #1#2 -{ - \prop_get:NnN #1 {top} \l_array_tmp_tl - \array_get:NnN #1 {\l_array_tmp_tl} #2 - \array_del:Nn #1 {\l_array_tmp_tl} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_gpop:NN} -% \begin{macrocode} -\cs_new_protected:Npn \array_gpop:NN #1#2 -{ - \prop_get:NnN #1 {top} \l_array_tmp_tl - \array_get:NnN #1 {\l_array_tmp_tl} #2 - \array_gdel:Nn #1 {\l_array_tmp_tl} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_shift:NN} -% \begin{macrocode} -\cs_new_protected:Npn \array_shift:NN #1#2 -{ - \prop_get:NnN #1 {base} \l_array_tmp_tl - \array_get:NnN #1 {\l_array_tmp_tl} #2 - \array_del:Nn #1 {\l_array_tmp_tl} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_gshift:NN} -% \begin{macrocode} -\cs_new_protected:Npn \array_gshift:NN #1#2 -{ - \prop_get:NnN #1 {base} \l_array_tmp_tl - \array_get:NnN #1 {\l_array_tmp_tl} #2 - \array_gdel:Nn #1 {\l_array_tmp_tl} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_top:NN} -% \begin{macrocode} -\cs_new_protected:Npn \array_top:NN #1#2 -{ - \prop_get:NnN #1 {top} \l_array_tmp_tl - \array_get:NnN #1 {\l_array_tmp_tl} #2 -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_base:NN} -% \begin{macrocode} -\cs_new_protected:Npn \array_base:NN #1#2 -{ - \prop_get:NnN #1 {base} \l_array_tmp_tl - \array_get:NnN #1 {\l_array_tmp_tl} #2 -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_top:N} -% \begin{macrocode} -\cs_new:Npn \array_top:N #1 -{ - \array_get:Nn #1 {\prop_item:Nn #1 {top}} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_base:N} -% \begin{macrocode} -\cs_new:Npn \array_base:N #1 -{ - \array_get:Nn #1 {\prop_item:Nn #1 {base}} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_del:Nn} -% \begin{macrocode} -\cs_new_protected:Npn \array_del:Nn #1#2 -{ - \exp_args:NNx \prop_pop:Nn #1 {\int_eval:n {#2}} - \int_set:Nn \l_array_tmp_int {0} - \array_map_inline:Nn #1 { - \tl_if_eq:NNTF {##2} {\q_no_value} {} - { - \int_incr:N \l_array_tmp_int - } - } - \int_compare:nNnTF {\l_array_tmp_int} = {0} - { - \prop_clear:N #1 - } - { - \prop_get:NnN #1 {top} \l_array_tmp_tl - \int_compare:nNnTF {#2} = {\l_array_tmp_tl} { - \prop_get:NnN #1 {base} \l_array_tmp_tl - \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} - \array_map_inline:Nn #1 { - \tl_if_eq:NNTF {##2} {\q_no_value} {} - { - \int_compare:nNnTF {\l_array_tmp_int} < {##1} { - \int_set:Nn \l_array_tmp_int {##1} - }{} - } - } - \prop_put:Nnx #1 {top} {\int_use:N \l_array_tmp_int} - }{} - \prop_get:NnN #1 {base} \l_array_tmp_tl - \int_compare:nNnTF {#2} = {\l_array_tmp_tl} { - \prop_get:NnN #1 {top} \l_array_tmp_tl - \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} - \array_map_inline:Nn #1 { - \tl_if_eq:NNTF {##2} {\q_no_value} {} - { - \int_compare:nNnTF {\l_array_tmp_int} > {##1} { - \int_set:Nn \l_array_tmp_int {##1} - }{} - } - } - \prop_put:Nnx #1 {base} {\int_use:N \l_array_tmp_int} - }{} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_gdel:Nn} -% \begin{macrocode} -\cs_new_protected:Npn \array_gdel:Nn #1#2 -{ - \exp_args:NNx \prop_gpop:Nn #1 {\int_eval:n {#2}} - \int_set:Nn \l_array_tmp_int {0} - \array_map_inline:Nn #1 { - \tl_if_eq:NNTF {##2} {\q_no_value} {} - { - \int_incr:N \l_array_tmp_int - } - } - \int_compare:nNnTF {\l_array_tmp_int} = {0} - { - \prop_gclear:N #1 - } - { - \prop_get:NnN #1 {top} \l_array_tmp_tl - \int_compare:nNnTF {#2} = {\l_array_tmp_tl} { - \prop_get:NnN #1 {base} \l_array_tmp_tl - \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} - \array_map_inline:Nn #1 { - \tl_if_eq:NNTF {##2} {\q_no_value} {} - { - \int_compare:nNnTF {\l_array_tmp_int} < {##1} { - \int_set:Nn \l_array_tmp_int {##1} - }{} - } - } - \prop_gput:Nnx #1 {top} {\int_use:N \l_array_tmp_int} - }{} - \prop_get:NnN #1 {base} \l_array_tmp_tl - \int_compare:nNnTF {#2} = {\l_array_tmp_tl} { - \prop_get:NnN #1 {top} \l_array_tmp_tl - \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} - \array_map_inline:Nn #1 { - \tl_if_eq:NNTF {##2} {\q_no_value} {} - { - \int_compare:nNnTF {\l_array_tmp_int} > {##1} { - \int_set:Nn \l_array_tmp_int {##1} - }{} - } - } - \prop_gput:Nnx #1 {base} {\int_use:N \l_array_tmp_int} - }{} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\array_length:N} -% \begin{macrocode} -\cs_new_protected:Npn \array_length:N #1 -{ - \int_eval:n {\prop_item:Nn #1 {top} - \prop_item:Nn #1 {base}} -} -% \end{macrocode} -% \end{macro} -% \begin{macrocode} -\ExplSyntaxOff -% \end{macrocode} -% -% \iffalse -% -% \fi -% -%\Finale diff --git a/graphics/pgf/contrib/hobby/hobby.pdf b/graphics/pgf/contrib/hobby/hobby.pdf index 1235aa74c1..7b6065ea02 100644 Binary files a/graphics/pgf/contrib/hobby/hobby.pdf and b/graphics/pgf/contrib/hobby/hobby.pdf differ diff --git a/graphics/pgf/contrib/hobby/hobby.tex b/graphics/pgf/contrib/hobby/hobby.tex new file mode 100644 index 0000000000..f116a3d274 --- /dev/null +++ b/graphics/pgf/contrib/hobby/hobby.tex @@ -0,0 +1,919 @@ +%\immediate\write18{tex hobby.dtx} +\documentclass{ltxdoc} +\usepackage[T1]{fontenc} +\usepackage{csquotes} +\usepackage{lmodern} +\usepackage{tikz} +\usepackage{pgfplots} +\usepackage{amsmath} +\usepackage{fancyvrb} +\usetikzlibrary{hobby,decorations.pathreplacing} +\usepackage{listings} +\usepackage{hyperref} +\pgfplotsset{compat=1.9} + +\lstset{ + breakatwhitespace=true, + breaklines=true, + language=[LaTeX]TeX, + basicstyle=\small\ttfamily, + keepspaces=true, + columns=fullflexible +} +% hobby specific keywords (we can't put keywords with spaces :() +\lstset{ + emphstyle={\color{red}}, + emph={and,angle,blank,blanks,closed,controls,curl,curve,designated,disjoint,excess,finish,Hobby,hobby,in,invert,next,out,path,previous,quick,restore,save,shortcut,show,soft,tension,through,use} +} +% tikz keywords used in this documentation +\lstset{ + emphstyle={[2]\color{blue!70!black}}, + emph={[2]addplot,axis,blue,coordinates,distance,double,draw,every,foreach,grid,help,line,lines,plot,postaction,red,rotate,scale smooth,scale,smooth,style,thick,tikz,tikzpicture,to,ultra,white,width,xshift,yellow} +} + +\EnableCrossrefs +\CodelineIndex +\RecordChanges + +\newenvironment{example} + {\VerbatimEnvironment + \begin{VerbatimOut}{example.out}} + {\end{VerbatimOut} + \begin{center} + \setlength{\parindent}{0pt} + \fbox{\begin{minipage}{.9\linewidth} + \lstinputlisting[]{example.out} + \end{minipage}} + \fbox{\begin{minipage}{.9\linewidth} + \centering + \input{example.out} + \end{minipage}} +\end{center} +} + + + +\tikzset{ + show curve controls/.style={ + decoration={ + show path construction, + curveto code={ + \draw [blue, dashed] + (\tikzinputsegmentfirst) -- (\tikzinputsegmentsupporta) + node [at end, draw, solid, red, inner sep=2pt]{}; + \draw [blue, dashed] + (\tikzinputsegmentsupportb) -- (\tikzinputsegmentlast) + node [at start, draw, solid, red, inner sep=2pt]{}; + } + },decorate + }, +} + +%\bibliographystyle{plain} + +\renewcommand{\thefootnote}{\fnsymbol{footnote}} + +\providecommand*{\url}{\texttt} +\title{The \textsf{Hobby} package} +\author{Andrew Stacey \\ \url{loopspace@mathforge.org}} +\date{\hobbyVersion\ from\ \hobbyDate} +\begin{document} +\maketitle + +\section{Introduction} + +John Hobby's algorithm, \cite{MR834054}, produces a curve through a given set of points. +The curve is constructed as a list of cubic B\'ezier curves with endpoints at subsequent points in the list. +The parameters of the curves are chosen so that the joins are ``smooth''. +The algorithm was devised as part of the MetaPost program. + +TikZ/PGF has the ability to draw a curve through a given set of points but its algorithm is somewhat simpler than Hobby's and consequently does not produce as aesthetically pleasing curve as Hobby's algorithm does. +This package implements Hobby's algorithm in \TeX{} so that TikZ/PGF can make use of it and thus produce nicer curves through a given set of points. + +Hobby's algorithm allows for considerable customisation in that it can take into account various parameters. +These are all allowed in this implementation. + +There is also a ``quick'' version presented here. +This is a modification of Hobby's algorithm with the feature that any point only influences a finite number (in fact, two) of the previous segments (in Hobby's algorithm the influence of a point dies out exponentially but never completely). +This is achieved by applying Hobby's algorithm to subpaths. +The resulting path produced with this ``quick'' version is not as ideal as that produced by Hobby's full algorithm, but is still much better than that produced by the \Verb+plot[smooth]+ method in TikZ/PGF, as can be seen in Figure~\ref{fig:comparison}. +As this is intended as a simpler method, it does not (at present) admit the same level of customisation as the full implementation. +The ``quick'' algorithm is described in full in Section~\ref{sec:quick}. + +The full algorithm is implemented in \LaTeX3 with no reference to TikZ or PGF. +It makes extensive use of the \Verb+fp+ and \Verb+prop+ libraries for the computation steps. +The TikZ library is simply a wrapper that takes the user's input, converts it into the right format for the \LaTeX3 code, and then calls that code to generate the path. +The ``quick'' version does not use \LaTeX3 and relies instead on the \Verb+PGFMath+ library for the computation. + + +Figure~\ref{fig:comparison} is a comparison of the three methods. +The red curve is drawn using Hobby's algorithm. +The blue curve is drawn with the \Verb+plot[smooth]+ method from TikZ/PGF. +The green curve uses the ``quick'' version. +Figure~\ref{fig:metapost} compares the implementation with that given by MetaPost. + +\begin{figure} +\centering +\begin{tikzpicture}[scale=.5] +\draw[red,line width=5pt] (0,0) to[curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); +\draw[ultra thick,blue] plot[smooth] coordinates {(0,0) (6,4) (4,9) (1,7) (3,5)}; +\draw[green,line width=2pt] (0,0) to[quick curve through={(6,4) (4,9) (1,7)}] (3,5); +\end{tikzpicture} +\caption{Comparison of the three algorithms} +\label{fig:comparison} +\end{figure} + + +\begin{figure} +\centering +\begin{tikzpicture}[scale=.5] + \draw[scale=.1,postaction=show curve controls,line width=1mm,red] (0,0) + .. controls (26.76463,-1.84543) and (51.4094,14.58441) .. (60,40) + .. controls (67.09875,61.00188) and (59.76253,84.57518) .. (40,90) + .. controls (25.35715,94.01947) and (10.48064,84.5022) .. (10,70) + .. controls (9.62895,58.80421) and (18.80421,49.62895) .. (30,50); + \fill[green] (0,0) circle[radius=2pt] + (6,4) circle[radius=2pt] + (4,9) circle[radius=2pt] + (1,7) circle[radius=2pt] + (3,5) circle[radius=2pt]; + \draw[postaction=show curve controls,thick] (0,0) to[curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); + \begin{scope}[xshift=10cm] + \draw[scale=.1,postaction=show curve controls,line width=1mm,red] (0,0) + .. controls (5.18756,-26.8353) and (60.36073,-18.40036) .. (60,40) + .. controls (59.87714,59.889) and (57.33896,81.64203) .. (40,90) + .. controls (22.39987,98.48387) and (4.72404,84.46368) .. (10,70) + .. controls (13.38637,60.7165) and (26.35591,59.1351) .. (30,50) + .. controls (39.19409,26.95198) and (-4.10555,21.23804) .. (0,0); % + \fill[green] (0,0) circle[radius=2pt] + (6,4) circle[radius=2pt] + (4,9) circle[radius=2pt] + (1,7) circle[radius=2pt] + (3,5) circle[radius=2pt]; + \draw[postaction=show curve controls,thick] (0,0) to[closed,curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); + \end{scope} +\end{tikzpicture} +\caption{Hobby's algorithm in TikZ overlaying the output of MetaPost} +\label{fig:metapost} +\end{figure} + +\section{Usage} +The package is provided in form of a TikZ library. +It can be loaded with +\begin{verbatim} +\usetikzlibrary{hobby} +\end{verbatim} + +\textbf{Warning}: This package makes extensive use of \LaTeX3. +On occasion, updates to \LaTeX3 packages have resulted in this package behaving oddly or not working at all. +The most up to date version of this package can be obtained from my \href{https://github.org/loopspace/hobby}{github page} (download \Verb+hobby.dtx+ and run \Verb+tex hobby.dtx+ to generate the files). +Often, such issues are reported on the \href{http://tex.stackexchange.com}{TeX-SX} site and workarounds quickly found so it is worth checking there as well. + +\bigskip + +There are a variety of ways of specifying the data to the algorithm to generate the curve. + +\subsection{As a \textsf{to path}.} + +The key \Verb+curve through={}+ installs a \Verb+to path+ which draws a smooth curve through the given points. +The points should be specified as a list which can be optionally separated by dots. +The purpose of allowing the dots is to make it simpler to switch between the \Verb+to path+ method and the \Verb+shortcut+ method (described in Section~\ref{sec:shortcut}). +However, note that the two methods are not completely synonymous due to how one can specify options so care must still be taken when switching. + +\begin{example} +\begin{tikzpicture}[scale=.5] + \draw (0,0) to[curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); +\end{tikzpicture} +\end{example} + +\begin{example} +\begin{tikzpicture}[scale=.5] + \draw (0,0) to[curve through={(6,4) (4,9) (1,7)}] (3,5); +\end{tikzpicture} +\end{example} + +There is a corresponding key \Verb+quick curve through={}+ which uses the ``quick'' algorithm. +Again, the dots are optional. + +\begin{example} +\begin{tikzpicture}[scale=.5] + \draw (0,0) to[quick curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); +\end{tikzpicture} +\end{example} + +\subsection{The \textsf{shortcut} Method} +\label{sec:shortcut} + +There is also the facility to subvert TikZ's path processor and define curves simply using the \Verb+..+ separator between points. +Note that this relies on something a little special in TikZ: the syntax \Verb+(0,0) .. (2,3)+ is currently detected and processed but there is no action assigned to that syntax. +As a later version of TikZ may assign some action to that syntax, this package makes its override optional via the key \Verb+use Hobby shortcut+ (which can be set globally if so desired). + +\begin{example} +\begin{tikzpicture}[scale=.5,use Hobby shortcut] + \draw (-3,0) -- (0,0) .. (6,4) .. (4,9) .. (1,7) .. (3,5) -- ++(2,0); +\end{tikzpicture} +\end{example} + +\begin{example} +\begin{tikzpicture}[scale=.5,use quick Hobby shortcut] + \draw (-3,0) -- (0,0) .. (6,4) .. (4,9) .. (1,7) .. (3,5) -- ++(2,0); +\end{tikzpicture} +\end{example} + +\subsection{The \textsf{Plot Handler} Method} + +The algorithms can also be used via the \Verb+plot handler+ syntax. +This library registers three plot handlers: \Verb+hobby+, \Verb+closed hobby+, and \Verb+quick hobby+. +The first is an open curve through the points using the full algorithm, the second is a closed curve, and the third uses the quick algorithm (and is thus an open curve). + +\begin{example} + \tikz[smooth] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; + + \tikz[hobby] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; + + \tikz[closed hobby] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; + + \tikz[quick hobby] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; +\end{example} + +This has the side effect that these can be used with the \Verb+pgfplots+ package. +However, the Hobby algorithm is designed to draw a curve in 2D-{}space and does not take into account the fact that when plotting a graph then the two dimensions are treated differently. + +\begin{example} +\begin{tikzpicture} + \begin{axis} + \addplot +[smooth] {rnd}; + \addplot +[hobby] {rnd}; + \end{axis} +\end{tikzpicture} +\end{example} + +\subsection{Basic Level PGF Commands} + +(Suggested by the question \href{http://tex.stackexchange.com/q/159896/86}{How to combine Hobby paths with PGF Basic Layer commands?} on TeX-SX.) + +In some circumstances, it is convenient to bypass TikZ and use more basic PGF commands for building a path. +It is possible to add a path built using Hobby's algorithm in this fashion. +The commands are: + +\begin{itemize} +\item \Verb+\pgfpathhobby+ to initialise the path. +If this is followed by a braced group then the contents of that are taken as options to the algorithm. + +\item \Verb+\pgfpathhobbypt{}+ to add a point to the path. +If this is followed by a braced group then the contents of that are taken as options for that point. + +\item \Verb+\pgfpathhobbyend+ finalises the path. +This applies the algorithm to the set of specified points and adds it to the current path. +\end{itemize} + +\begin{example} +\begin{tikzpicture} + \pgfpathmoveto{\pgfpoint{0}{0}} + \pgfpathlineto{\pgfpoint{1cm}{0}} + \pgfpathhobby{closed=true} + \pgfpathhobbypt{\pgfpoint{1cm}{2cm}}{tension in=2} + \pgfpathhobbypt{\pgfpoint{2cm}{1cm}} + \pgfpathhobbypt{\pgfpoint{3cm}{0cm}} + \pgfpathhobbyend + \pgfusepath{stroke} +\end{tikzpicture} +\end{example} + +\section{Customisation} + +There are various ways to customise the path generated by the Hobby algorithms. +The full algorithm has a variety of parameters which can be varied to produce different paths through the same points. +These vary from specifying that the path be open or closed, to specifying ``tensions'' at each point to change how the path approaches or leaves it. + +\subsection{Algorithm Customisations} + +The main algorithm (i.e., not the ``quick'' variant) can deal with open or closed paths, it is possible to vary the ``tensions'' between the specified points of the paths, and for an open path it is possible to specify the incoming and outgoing angles either directly or via certain ``curl'' parameters. +When using the \Verb+to path+ specification, the parameters can be specified before or after the \Verb+curve through+ key or as options to the coordinates. +When using the \Verb+shortcut+ specification, the parameters can be given on the path or on coordinates. + +On occasion, it is ambiguous which curve an option belongs to. +This is most likely if a coordinate happens to belong to two curves, or if a coordinate is parsed before TikZ knows that it is constructing a curve using this library. +The simplest solution is to move the option to a place where there is no ambiguity. +Other solutions to this problem will be detailed later. + +Let us start with the customisations to the algorithm. + +\begin{itemize} +\item Basic curve. +\begin{example} +\begin{tikzpicture} + \draw[postaction=show curve controls] (0,0) to[curve through={(1,.5) .. (2,0) .. (3,.5)}] (4,0); + \draw[xshift=5cm,use Hobby shortcut,postaction=show curve controls] (0,0) .. (1,.5) .. (2,0) .. (3,.5) .. (4,0); +\end{tikzpicture} +\end{example} + +\item The path can be open, as above, or closed. +%% +\begin{example} +\begin{tikzpicture}[scale=.5] + \draw[postaction=show curve controls] (0,0) to[closed,curve through={(1,.5) .. (2,0) .. (3,.5)}] (4,0); + \draw[xshift=5cm,use Hobby shortcut,postaction=show curve controls] ([closed]0,0) .. (1,.5) .. (2,0) .. (3,.5) .. (4,0); +\end{tikzpicture} +\end{example} + +\item Specifying the angle at which the curve goes \emph{out} and at which it comes \emph{in}. +The angles given are absolute. +\begin{example} +\begin{tikzpicture} + \draw[postaction=show curve controls] (0,0) to[out angle=0,in angle=180,curve through={(1,.5) .. (2,0) .. (3,.5)}] (4,0); + \draw[xshift=5cm,use Hobby shortcut,postaction=show curve controls] ([out angle=0,in angle=180]0,0) .. (1,.5) .. (2,0) .. (3,.5) .. (4,0); +\end{tikzpicture} +\end{example} + +\item Applying tension as the curve comes in to a point. +\begin{example} +\begin{tikzpicture} + \draw[postaction=show curve controls] (0,0) to[curve through={(1,.5) .. ([tension in=2]2,0) .. (3,.5)}] (4,0); + \draw[xshift=5cm,use Hobby shortcut,postaction=show curve controls] (0,0) .. (1,.5) .. ([tension in=2]2,0) .. (3,.5) .. (4,0); +\end{tikzpicture} +\end{example} + +\item Applying the same tension as a curve comes in and goes out of a point. +\begin{example} +\begin{tikzpicture} + \draw[postaction=show curve controls] (0,0) to[curve through={(1,.5) .. ([tension=2]2,0) .. (3,.5)}] (4,0); +\end{tikzpicture} +\end{example} + +\item Specifying the \emph{curl} parameters. +\begin{example} +\begin{tikzpicture} + \draw[postaction=show curve controls] (0,0) to[in curl=.1,out curl=3,curve through={(1,.5) .. (2,0) .. (3,.5)}] (4,0); + \draw[xshift=5cm,use Hobby shortcut,postaction=show curve controls] (0,0) .. ([in curl=.1,out curl=3]1,.5) .. (2,0) .. (3,.5) .. (4,0); +\end{tikzpicture} +\end{example} +\end{itemize} + +\subsection{Edge Cases} + +Angles are constrained to lie in the interval \((-\pi,\pi]\). +This can introduce edge cases as there is a point where we have to compare an angle with \(-\pi\) and if it is equal, add \(2 \pi\). +This will occur if the path ``doubles back'' on itself as in the next example. +By nudging the repeated point slightly, the behaviour changes drastically. + +\begin{example} +\begin{tikzpicture}[use Hobby shortcut] + \draw (0,0) .. (1,0) .. (0,0) .. (0,-1); + \draw[xshift=2cm] (0,0) .. (1,0) .. (0,0.1) .. (0,-1); + \draw[xshift=4cm] (0,0) .. (1,0) .. (0,-0.1) .. (0,-1); +\end{tikzpicture} +\end{example} + +Due to the precision of the computations, it is not possible to always get this test correct. +The simplest solution is to nudge the repeated point in one direction or the other. +Experimenting shows that the ``nudge factor'' can be extremely small (note that it will be proportional to the distance between the specified points). +It is best to nudge it in the direction most normal to the line between the specified points as the goal is to nudge the difference of the angles. +An alternative solution is to add an additional point for the curve to go through. +\begin{example} +\begin{tikzpicture}[use Hobby shortcut] + \draw (0,0) .. (1,0) .. (0,0) .. (0,-1); + \draw[xshift=2cm] (0,0) .. (1,0) .. (0,0.002) .. (0,-1); + \draw[xshift=4cm] (0,0) .. (1,0) .. (0,-0.002) .. (0,-1); +\end{tikzpicture} +\end{example} + +Lastly, it is possible to add an \Verb+excess angle+ key to a coordinate. +This will add the corresponding multiple of \(2\pi\) to the angle difference. +\begin{example} +\begin{tikzpicture}[use Hobby shortcut] + \draw (0,0) .. (1,0) .. (0,0) .. (0,-1); + \draw[xshift=2cm] (0,0) .. ([excess angle=1]1,0) .. (0,0) .. (0,-1); + \draw[xshift=4cm] (0,0) .. ([excess angle=-1]1,0) .. (0,0) .. (0,-1); +\end{tikzpicture} +\end{example} + +Although this is intended to be an integer, no check is done and so some quite odd curves can result from changing this parameter. + +\subsection{Reusing Paths} + +Although the (full) algorithm has good theoretical computation time, using \TeX\ for its implementation does not provide for fast runs. +The externalisation library of TikZ/PGF can be used to save whole pictures, but it can be useful to save a generated path within a single \Verb+tikzpicture+ for later use within that same picture. +The implementation allows for this by separating the generation of the path from its use. + +\begin{example} +\begin{tikzpicture} + \draw[line width=3mm,red,use Hobby shortcut,save Hobby path={saved}] (0,0) .. (1,1) .. (2,0); + \draw[xshift=2cm,ultra thick,yellow] (0,0) [restore and use Hobby path={saved}{}]; +\end{tikzpicture} +\end{example} +% + +Note that the key \Verb+restore and use Hobby path+ is given \emph{after} the initial \Verb+(0,0)+. +This is because by default the path generated by the Hobby algorithm does not start with an explicit \Verb+moveto+ since that is the standard behaviour of all of PGF's path construction macros. +So the \Verb+(0,0)+ ensures that our path is well-{}formed by issuing an initial \Verb+moveto+. +An alternative would be to use the key \Verb+disjoint+ which does add an initial \Verb+moveto+. + +\begin{example} +\begin{tikzpicture} + \draw[line width=3mm,red,use Hobby shortcut,save Hobby path={saved}] (0,0) .. (1,1) .. (2,0); + \draw[xshift=2cm,ultra thick,yellow,restore and use Hobby path={saved}{disjoint}]; +\end{tikzpicture} +\end{example} +% + +An example of where this is useful is in drawing knot diagrams. +When so doing, it is sometimes convenient to draw a path (or segment of a path) twice in order to get the under/over crossings correct. +For this situation, it can be useful to designate certain parts of the path as \Verb+blank+, whereby we mean to redraw them later. +The point of a blank segment of a curve is that it is still taken into account when computing the algorithm but is left blank when it comes to rendering. +A path can then be redrawn with the blank/non-{}blank segments reversed. +As it might be desired to have only some blank segments drawn the second time, there are two types of blank. +Only a \Verb+soft+ blank will be reversed in these circumstances. + +\begin{example} +\begin{tikzpicture}[use Hobby shortcut,line width=1mm,rotate=90] + \draw[blue,save Hobby path={left}] ([out angle=90,in angle=-90]1,0) .. (1,1) .. ([blank=soft]0,2) .. (1,3) .. (1,4); + \draw[red] ([out angle=90,in angle=-90]0,0) .. (0,1) .. (1,2) .. (0,3) .. (0,4); + \draw[blue,restore and use Hobby path={left}{disjoint,invert soft blanks}]; +\end{tikzpicture} +\end{example} +% + +This can be taken a step further. +The generated data can be saved to the \Verb+aux+ file and read back in, avoiding the need to regenerate it on each run. +To engage this facility, the Hobby path has to be named (via \Verb+save Hobby path+) and the key \Verb+Hobby externalise+ (or \Verb+Hobby externalize+) must be given in a context that applies (such as on the path or on the surrounding scope). + +\bigskip + + +The relevant keys are the following. + +\begin{itemize} +\item \Verb+use previous Hobby path[=]+. +This (re)uses the previously generated Hobby path. +As all the data is globally stored, this can technically be in a different \Verb+tikzpicture+. +The \Verb++ will be applied, in so far as they are options that can be applied after the algorithm has run. + +\item \Verb+save Hobby path=+. +Saves a path for later use. +The path is saved in a global macro so can be reused in another picture. + +\item \Verb+restore Hobby path=+. +This restores the named Hobby path (if it exists). +It does not \emph{use} it. +After this key, \Verb+use previous Hobby path+ will use the restored path. + +\item \Verb+restore and use Hobby path={}{}+. +This restores the named path and uses it with \Verb++ applied. + +\item \Verb+Hobby externalise+ or \Verb+Hobby externalize+. +This puts in place the code for saving the generated data to the \Verb+aux+ file. +On subsequent runs, it uses the saved data rather than the current data. +For a curve to make use of this, it has to be named via the \Verb+save Hobby path+ key. +So to regenerate the data, either delete the \Verb+aux+ file, remove the \Verb+save Hobby path+ key for one compilation run, or issue the command \Verb+\HobbyDisableAux+ which disables writing paths to the \Verb+aux+ file (note that the paths will be regenerated on the run \emph{after} the first run with this command issued). +\end{itemize} + +The options that can be applied are those that affect the rendering of the curve but not its generation. +When the curve is rendered (or \emph{used}, in the above parlance), \TeX\ steps along the coordinates of the generated curve and carries out an action for each piece. +This action can be modified after the curve has been generated. +The action will be one of: +% +\begin{itemize} +\item Move to the end point (ignoring the control points). +\item Draw a Bezier curve to the end point through the control points. +\item Draw a Bezier curve to the end point through the control points and then move to the end point. +\end{itemize} +% +The last is subtle: the move doesn't actually go anywhere but it ``breaks'' the curve at the designated point. +In particular, a later \Verb+cycle+ would return to this point (or a later break) rather than to the start of the curve. + +These actions are triggered by the keys \Verb+blank+ and \Verb+break+. +Each should be specified to the coordinate at the \emph{end} of the segment under consideration. +The \Verb+blank+ key can be given the argument \Verb+soft+. +The effect of this is seen when the key \Verb+invert soft blanks+ is used. +This swaps the drawing action so that non-{}blank segments are skipped and \emph{soft} blanks are drawn. +Non-{}soft-{}blank segments are still not drawn. + +\begin{example} +\begin{tikzpicture}[use Hobby shortcut] + \draw (0,0) .. (1,1) .. ([blank=soft]2,0) .. (3,1) .. ([blank]4,0) .. (5,1); + \draw[red,use previous Hobby path={invert soft blanks,disjoint}]; +\end{tikzpicture} +\end{example} +% + +As a more practical application, consider the following rendering of a trefoil knot. + +\begin{example} +\begin{tikzpicture}[ + use Hobby shortcut, + every path/.style={ + line width=1mm, + white, + double=red, + double distance=.5mm + } +] + \draw ([closed]0,2) .. ([blank=soft]210:.5) .. (-30:2) .. ([blank=soft]0,.5) .. (210:2) .. ([blank=soft]-30:.5); + \draw[use previous Hobby path={invert soft blanks,disjoint}]; +\end{tikzpicture} +\end{example} +% + +This could easily be generalised using the \Verb+\foreach+ command, as demonstrated in the next code. + +\begin{example} +\begin{tikzpicture}[ + use Hobby shortcut, + every path/.style={ + line width=1mm, + white, + double=red, + double distance=.5mm + } +] +\def\nfoil{9} + \draw ([closed]0,2) + foreach \k in {1,...,\nfoil}{ + .. ([blank=soft]90+360*\k/\nfoil-180/\nfoil:-.5) .. (90+360*\k/\nfoil:2) + }; + \draw[use previous Hobby path={invert soft blanks,disjoint}]; +\end{tikzpicture} +\end{example} +% + +\subsection{Breaking the Path} + +One issue with the shortcut notation is that it is not possible (using this notation) to have two sets of curves following directly on from each other because there is no clear demarcation of the boundary. +To make this possible, there is a key \Verb+Hobby action+, which installs an action to be taken after the point has been processed. +The general key \Verb+Hobby action={code}+ can install arbitrary code. +Probably the more useful variant is \Verb+Hobby finish+ which runs the algorithm on the points gathered so far. +An example of the use of this is to make it possible to specify tangencies at certain points. +Technically, once a tangent direction has been specified, the Hobby algorithm splits the set of points there and works on each piece separately. +The following key implements this, the technicalities are due to the fact that the tangent angle has to be used twice: once to specify the angle of the path coming in to that point and once to specify the angle of the path coming out. +Note that specifying the tangent vector at every point means that the algorithm is not actually being used. +However, Hobby's formulae for the lengths of the control points is still being used. + +\begin{example} +\begin{tikzpicture}[ + use Hobby shortcut, + tangent/.style={% + in angle={(180+#1)}, + Hobby finish, + designated Hobby path=next, + out angle=#1, + }, +] + \draw[help lines] (-5,-5) grid (5,5); + \draw (-5,0) -- (5,0) (0,-5) -- (0,5); + \draw[thick] (-5,2) .. ([tangent=0]-3,3) .. (-1,1) .. (0,-1.3) .. ([tangent=0]1,-2) .. ([tangent=45]2,-1.5) .. ([tangent=0]3,-2) .. (5,-4); +\end{tikzpicture} +\end{example} +% + + + +\section{Implementing Hobby's Algorithm} +We start with a list of \(n+1\) points, \(z_0, \dotsc, z_n\). +The base code assumes that these are already stored in two arrays\footnote{Arrays are thinly disguised property lists.}: the \(x\)--coordinates in \Verb+\l_hobby_points_x_array+ and the \(y\)--coordinates in \Verb+\l_hobby_points_y_array+. +As our arrays are \(0\)--indexed, the actual number of points is one more than this. +For a closed curve, we have \(z_n = z_0\)\footnote{Note that there is a difference between a closed curve and an open curve whose endpoints happen to overlap.}. +For closed curves it will be convenient to add an additional point at \(z_1\): thus \(z_{n+1} = z_1\). +This makes \(z_n\) an internal point and makes the algorithms for closed paths and open paths agree longer than they would otherwise. +The number of apparent points is stored as \Verb+\l_hobby_npoints_int+. +Thus for an open path, \Verb+\l_hobby_npoints_int+ is \(n\), whilst for a closed path, it is \(n+1\)\footnote{In fact, we allow for the case where the user specifies a closed path but with \(z_n \ne z_0\). +In that case, we assume that the user meant to repeat \(z_0\). +This adds another point to the list.}. +Following Hobby, let us write \(n'\) for \(n\) if the path is open and \(n+1\) if closed. +From this we compute the distances and angles between successive points, storing these again as arrays. +These are \Verb+\l_hobby_distances_array+ and \Verb+\l_hobby_angles_array+. +The term indexed by \(k\) is the distance (or angle) of the line between the \(k\)th point and the \(k+1\)th point. +For the internal nodes\footnote{Hobby calls the specified points \emph{knots}.}, we store the difference in the angles in \Verb+\l_hobby_psi_array+. +The \(k\)th value on this is the angle subtended at the \(k\)th node. +This is thus indexed from \(1\) to \(n'-1\). +The bulk of the work consists in setting up a linear system to compute the angles of the control points. +At a node, say \(z_i\), we have various pieces of information: +\begin{enumerate} +\item The angle of the incoming curve, \(\phi_i\), relative to the straight line from \(z_{i-1}\) to \(z_i\) +\item The angle of the outgoing curve, \(\theta_i\), relative to the straight line from \(z_i\) to \(z_{i+1}\) +\item The tension of the incoming curve, \(\overline{\tau}_i\) +\item The tension of the outgoing curve, \(\tau_i\) +\item The speed of the incoming curve, \(\sigma_i\) +\item The speed of the outgoing curve, \(\rho_i\) +\end{enumerate} +The tensions are known at the start. +The speeds are computed from the angles. +Thus the key thing to compute is the angles. +This is done by imposing a ``mock curvature'' condition. +The formula for the mock curvature is: +%% +\[ +\hat{k}(\theta,\phi,\tau,\overline{\tau}) = \tau^2 \left( \frac{2(\theta + \phi)}{\overline{\tau}} - 6\theta\right) +\] +%% +and the condition that the mock curvatures have to satisfy is that at each \emph{internal} node, the curvatures must match: +% +\[ +\hat{k}(\phi_i,\theta_{i-1},\overline{\tau}_i,\tau_{i-1})/d_{i-1} = \hat{k}(\theta_i,\phi_{i+1},\tau_i,\overline{\tau}_{i+1})/d_i. +\] +%% +Substituting in yields: +%% +\[ +\frac{\overline{\tau}_i^2}{d_{i-1}} \left( \frac{2(\phi_i + \theta_{i-1})}{\tau_{i-1}} - 6\phi_i\right) = \frac{\tau_i^2}{d_i} \left( \frac{2(\theta_i + \phi_{i+1})}{\overline{\tau}_{i+1}} - 6\theta_i \right). +\] +%% +Let us rearrange that to the following: +%% +\begin{align*} +d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 &\theta_{i-1} \\ +%% +{}+ +d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (1 - 3 \tau_{i-1}) &\phi_i \\ +%% +{}- +d_{i-1} \tau_{i-1} \tau_i^2 (1 - 3 \overline{\tau}_{i+1}) &\theta_i \\ +%% +{}- +d_{i-1} \tau_{i-1} \tau_i^2 &\phi_{i+1} \\ +%% +&\qquad = +0 +\end{align*} +%% +For both open and closed paths this holds for \(i=1\) to \(i=n' - 1\). +We also have the condition that \(\theta_i + \phi_i = -\psi_i\) where \(\psi_i\) is the angle subtended at a node by the lines to the adjacent nodes. +This holds for the internal nodes\footnote{Recall that by dint of repetition, all nodes are effectively internal for a closed path.}. +Therefore for \(i=1\) to \(n'-1\) the above simplifies to the following: +% +\begin{align*} +d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 &\theta_{i-1} \\ +{}+ +(d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (3 \tau_{i-1} - 1) +{}+ +d_{i-1} \tau_{i-1} \tau_i^2 (3 \overline{\tau}_{i+1} - 1)) &\theta_i \\ +{}+ +d_{i-1} \tau_{i-1} \tau_i^2 & \theta_{i+1} \\ += +- d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (3 \tau_{i-1} - 1) &\psi_i \\ +{}- d_{i-1} \tau_{i-1} \tau_i^2& \psi_{i+1} +\end{align*} +For an open path we have two more equations. +One involves \(\theta_0\). +The other is the above for \(i = n'-1 = n-1\) with additional information regarding \(\psi_n\). +It may be that one or either of \(\theta_0\) or \(\phi_n\) is specified in advance. +If so, we shall write the given values with a bar: \(\overline{\theta}_0\) and \(\overline{\phi}_n\). +In that case, the first equation is simply setting \(\theta_0\) to that value and the last equation involves substituting the value for \(\phi_n\) into the above. +If not, they are given by formulae involving ``curl'' parameters \(\chi_0\) and \(\chi_n\) and result in the equations: +% +\begin{align*} +\theta_0 &= \frac{\tau_0^3 + \chi_0 \overline{\tau}_1^3(3 \tau_0 - 1)}{\tau_0^3(3 \overline{\tau}_1 - 1) + \chi_0 \overline{\tau}_1^3} \phi_1 \\ +\phi_n &= \frac{\overline{\tau}_n^3 + \chi_n \tau_{n-1}^3(3 \overline{\tau}_n - 1)}{\overline{\tau}_n^3(3 \tau_{n-1} - 1) + \chi_n \tau_{n-1}^3} \theta_{n-1} +\end{align*} +%% +Using \(\phi_1 = - \psi_1 - \theta_1\), the first rearranges to: +%% +\[ +(\tau_0^3(3 \overline{\tau}_1 - 1) + \chi_0 \overline{\tau}_1^3) \theta_0 + (\tau_0^3 + \chi_0 \overline{\tau}_1^3(3 \tau_0 - 1)) \theta_1 = - (\tau_0^3 + \chi_0 \overline{\tau}_1^3(3 \tau_0 - 1)) \psi_1. +\] +%% +The second should be substituted in to the general equation with \(i = n-1\). +This yields: +%% +\begin{align*} +d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 &\theta_{n-2} \\ +{}+ +\big(d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 (3 \tau_{n-2} - 1) +{}+ +d_{n-2} \tau_{n-2} \tau_{n-1}^2 (3 \overline{\tau}_{n} - 1) \\ +{}- d_{n-2} \tau_{n-2} \tau_{n-1}^2 \frac{\overline{\tau}_n^3 + \chi_n \tau_{n-1}^3(3 \overline{\tau}_n - 1)}{\overline{\tau}_n^3(3 \tau_{n-1} - 1) + \chi_n \tau_{n-1}^3}\big) & \theta_{n-1} \\ += +- d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 (3 \tau_{n-2} - 1) &\psi_{n-1} +\end{align*} +%% +This gives \(n'\) equations in \(n'\) unknowns (\(\theta_0\) to \(\theta_{n-1}\)). +The coefficient matrix is tridiagonal. +It is more natural to index the entries from \(0\). +Let us write \(A_i\) for the subdiagonal, \(B_i\) for the main diagonal, and \(C_i\) for the superdiagonal. +Let us write \(D_i\) for the target vector. +Then for an open path we have the following formulae: +%% +\begin{align*} +A_i &= d_i \overline{\tau}_{i+1} \overline{\tau}^2_i \\ +B_0 &= \begin{cases} +1 & \text{if}\; \overline{\theta}_0\; \text{given} \\ +\tau_0^3(3 \overline{\tau}_1 - 1) + \chi_0 \overline{\tau}^3_1 & \text{otherwise} +\end{cases} \\ +B_i &= d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (3 \tau_{i-1} -1) + d_{i-1} \tau_{i-1} \tau_i^2(3 \overline{\tau}_{i+1} - 1) \\ +B_{n-1} &= \begin{cases} d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 (3 \tau_{n-2} - 1) + d_{n-2} \tau_{n-2} \tau_{n-1}^2(3 \overline{\tau}_{n} - 1) & \text{if}\; \overline{\phi}_n\; \text{given} \\ +d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 (3 \tau_{n-2} - 1) + d_{n-2} \tau_{n-2} \tau_{n-1}^2(3 \overline{\tau}_{n} - 1) +\\ +- d_{n-2} \tau_{n-2} \tau_{n-1}^2 \frac{\overline{\tau}_n^3 + \chi_n \tau_{n-1}^3(3 \overline{\tau}_n - 1)}{\overline{\tau}_n^3(3 \tau_{n-1} - 1) + \chi_n \tau_{n-1}^3}) & \text{otherwise} +\end{cases} \\ +C_0 &= \begin{cases} +0 & \text{if}\; \overline{\theta}_0\; \text{given} \\ +\tau_0^3 + \chi_0 \overline{\tau}_1^3(3\tau_0 - 1) & \text{otherwise} +\end{cases} \\ +C_i &= d_{i-1} \tau_{i-1} \tau_i^2 \\ +D_0 &= \begin{cases} +\overline{\theta}_0 & \text{if}\; \overline{\theta}_0\; \text{given} \\ +- (\tau_0^3 + \chi_0 \overline{\tau}_1^3(3 \tau_0 - 1)) \psi_1 & \text{otherwise} +\end{cases} \\ +D_i &= - d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (3 \tau_{i-1} - 1) \psi_i +- d_{i-1} \tau_{i-1} \tau_i^2 \psi_{i+1} \\ +D_{n-1} &= \begin{cases} +- d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 (3 \tau_{n-2} - 1) \psi_{n-1} - d_{n-2} \tau_{n-2} \tau_{n-1}^2 \overline{\phi}_n & \text{if}\; \overline{\phi}_n\; \text{given} \\ +- d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 (3 \tau_{n-2} - 1) \psi_{n-1} & \text{otherwise} +\end{cases} +\end{align*} +For a closed path, we have \(n\) equations in \(n+2\) unknowns (\(\theta_0\) to \(\theta_{n+1}\)). +However, we have not included all the information. +Since we have repeated points, we need to identify \(\theta_0\) with \(\theta_n\) and \(\theta_1\) with \(\theta_{n+1}\). +To get a system with \(n'\) equations in \(n'\) unknowns, we add the equation \(\theta_0 - \theta_n = 0\) and substitute in \(\theta_{n+1} = \theta_1\). +The resulting matrix is not quite tridiagonal but has extra entries on the off-corners. +However, it can be written in the form \(M + u v^\top\) with \(M\) tridiagonal. +There is some freedom in choosing \(u\) and \(v\). +For simplest computation, we take \(u = e_0 + e_{n'-1}\). +This means that \(v = d_{n'-2} \tau_{n'-2} \tau_{n'-1}^2 e_1 - e_{n'-1}\). +With the same notation as above, the matrix \(M\) is given by the following formulae: +%% +\begin{align*} +A_i &= d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 \\ +%% +B_0 &= 1 \\ +%% +B_i &= d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (3 \tau_{i-1} -1) + d_{i-1} \tau_{i-1} \tau_i^2(3 \overline{\tau}_{i+1} - 1) \\ +%% +B_{n'-1} &= d_{n'-1} \overline{\tau}_{n'} \overline{\tau}_{n'-1}^2 (3 \tau_{n'-2} -1) + d_{n'-2} \tau_{n'-2} \tau_{n'-1}^2(3 \overline{\tau}_{n'} - 1) + 1\\ +%% +C_0 &= - d_{n'-2} \tau_{n'-2} \tau_{n'-1}^2 \\ +%% +C_i &= d_{i-1} \tau_{i-1} \tau_i^2 \\ +%% +D_0 &= 0 \\ +%% +D_i &= - d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (3 \tau_{i-1} - 1) \psi_i +- d_{i-1} \tau_{i-1} \tau_i^2 \psi_{i+1} \\ +%% +D_{n'-1} &= - d_{n'-1} \overline{\tau}_{n'} \overline{\tau}_{n'-1}^2 (3 \tau_{n'-2} - 1) \psi_{n'-1} +- d_{n'-2} \tau_{n'-2} \tau_{n'-1}^2 \psi_1 +\end{align*} +The next step in the implementation is to compute these coefficients and store them in appropriate arrays. +Having done that, we need to solve the resulting tridiagonal system. +This is done by looping through the arrays doing the following substitutions (starting at \(i = 1\)): +% +\begin{align*} +B_i' &= B_{i-1}' B_i - A_i C_{i-1}' \\ +C_i' &= B_{i-1}' C_i \\ +D_i' &= B_{i-1}' D_i - A_i D_{i-1}' +\end{align*} +%% +followed by back-substitution: +%% +\begin{align*} +\theta_{n-1} &= D_{n-1}'/B_{n-1}' \\ +\theta_i &= (D_i' - C_i' \theta_{i+1})/B_i' +\end{align*} +%% +For a closed path, we run this both with the vector \(D\) and the vector \(u = e_0 + e_{n'-1}\). +Then to get the real answer, we use the Sherman--{}Morrison formula: +%% +\[ +(M + u v^\top)^{-1} D = M^{-1} D - \frac{M^{-1} u v^\top M^{-1} D}{1 + v^\top M^{-1} u}. +\] +%% +This leaves us with the values for \(\theta_i\). +We now substitute these into Hobby's formulae for the lengths: +%% +\begin{align*} +\rho_i &= \frac{2 + \alpha_i}{1 + (1 - c) \cos \theta_i + c \cos \phi_{i+1}} \\ +\sigma_{i+1} &= \frac{2 - \alpha_i}{1 + (1 - c) \cos \phi_{i+1} + c \cos \theta_i} \\ +\text{where} \;\alpha_i &= a (\sin \theta_i - b \sin \phi_{i+1})(\sin \phi_{i+1} - b \sin \theta_i)(\cos \theta_i - \cos \phi_{i+1}) +\end{align*} +%% +and \(a = \sqrt{2}\), \(b = 1/16\), and \(c = (3 - \sqrt{5})/2\). +These are actually the \emph{relative} lengths so need to be adjusted by a factor of \(d_i/3\). +Now \(\theta_i\) is the angle relative to the line from \(z_i\) to \(z_{i+1}\), so to get the true angle we need to add back that angle. +Fortunately, we stored those angles at the start. +So the control points are: +%% +\begin{gather*} +d_i \rho_i (\cos (\theta_i + \omega_i), \sin (\theta_i + \omega_i))/3 + z_i \\ +- d_i \sigma_{i+1} (\cos(\omega_i - \phi_{i+1}), \sin(\omega_i - \phi_{i+1}))/3 + z_{i+1} +\end{gather*} + +\section{A Piecewise Version of Hobby's Algorithm} +\label{sec:quick} +Here we present a variant of Hobby's algorithm. +One difficulty with Hobby's algorithm is that it works with the path as a whole. +It is therefore not possible to build up a path piecewise. +We therefore modify it to correct for this. +Obviously, the resulting path will be less ``ideal'', but will have the property that adding new points will not affect earlier segments. +The method we use is to employ Hobby's algorithm on two-{}segment subpaths. +When applied to a two-{}segment subpath, the algorithm provides two cubic Bezier curves: one from the \(k\)th point to the \(k+1\)st point and the second from the \(k+1\)st to the \(k+2\)nd. +Of this data, we keep the first segment and use that for the path between the \(k\)th and \(k+1\)st points. +We also remember the outgoing angle of the first segment and use that as the incoming angle on the next computation (which will involve the \(k+1\)st, \(k+2\)nd, and \(k+3\)rd points). +The two ends are slightly different to the middle segments. +On the first segment, we might have no incoming angle. +On the last segment, we render both pieces. +This means that for the initial segment, we have a \(2 \times 2\) linear system: +%% +\[ +\begin{bmatrix} +B_0 & C_0 \\ +A_1 & B_1 +\end{bmatrix} +\Theta = \begin{bmatrix} +D_0 \\ D_1 +\end{bmatrix} +\] +%% +This has solution: +%% +\[ +\Theta = \frac{1}{B_0 B_1 - C_0 A_1} \begin{bmatrix} B_1 & - C_0 \\ -A_1 & B_0 \end{bmatrix} \begin{bmatrix} D_0 \\ D_1 \end{bmatrix} = \frac{1}{B_0 B_1 - C_0 A_1} \begin{bmatrix} B_1 D_0 - C_0 D_1 \\ B_0 D_1 - A_1 D_0 \end{bmatrix} +\] +Now we have the following values for the constants: +%% +\begin{align*} +A_1 &= d_1 \overline{\tau}_2 \overline{\tau}_1^2 \\ +%% +B_0 &= \tau_0^3 (3 \overline{\tau}_1 - 1) + \chi_0 \overline{\tau}_1^3 \\ +%% +B_1 &= d_1 \overline{\tau}_2 \overline{\tau}_1^2 (3 \tau_0 - 1) + d_0 \tau_0 \tau_1^2(3 \overline{\tau}_2 - 1) - d_0 \tau_0 \tau_1^2 \frac{\overline{\tau}_2^3 + \chi_2 \tau_1^3 (3 \overline{\tau}_2 - 1)}{\overline{\tau}_2^3 (3 \tau_1 - 1) + \chi_2 \tau_1^3} \\ +%% +C_0 &= \tau_0^3 + \chi_0 \overline{\tau}_1^3 (3 \tau_0 - 1) \\ +%% +D_0 &= - (\tau_0^3 + \chi_0 \overline{\tau}_1^3 ( 3 \tau_0 - 1)) \psi_1 \\ +%% +D_1 &= - d_1 \overline{\tau}_2 \overline{\tau}_1^2 (3 \tau_0 - 1) \psi_1 +\end{align*} + +Let us, as we are aiming for simplicity, assume that the tensions and curls are all \(1\). +Then we have \(A_1 = d_1\), \(B_0 = 3\), \(B_1 = 2 d_1 + 2 d_0 - d_0 = 2 d_1 + d_0\), \(C_0 = 3\), \(D_0 = - 3 \psi_1\), \(D_1 = - 2 d_1 \psi_1\). +Thus the linear system is: +%% +\[ +\begin{bmatrix} +3 & 3 \\ +d_1 & 2 d_1 + d_0 +\end{bmatrix} +\Theta = - \psi_1 \begin{bmatrix} +3 \\ 2 d_1 +\end{bmatrix} +\] +%% +which we can row reduce to: +%% +\[ +\begin{bmatrix} +1 & 1 \\ +0 & d_1 + d_0 +\end{bmatrix} +\Theta = -\psi_1 \begin{bmatrix} +1 \\ d_1 +\end{bmatrix} +\] +%% +whence \(\theta_1 = -\psi_1 \frac{d_1}{d_0 + d_1}\) and \(\theta_0 = -\psi_1 - \theta_1 = -\psi_1\frac{d_0 }{d_0 + d_1}\). +We also compute \(\phi_1 = -\psi_1 - \theta_1 = \theta_0\) and \(\phi_2 = \theta_1\) (in the simple version). +We use \(\theta_0\) and \(\phi_1\) to compute the bezier curve of the first segment, make a note of \(\theta_1\), and -- assuming there are more segments -- throw away \(\phi_2\). + +For the inner segments, we have the system: +%% +\[ +\begin{bmatrix} +1 & 0 \\ +A_1 & B_1 +\end{bmatrix} +\Theta = \begin{bmatrix} +\theta_0 \\ +D_1 +\end{bmatrix} +\] +%% +which has the solution \(\theta_1 = (D_1 - A_1 \theta_0)/B_1\). +The values of the constants in this case are: +%% +\begin{align*} +A_1 &= d_1 \overline{\tau}_2 \overline{\tau}_1^2 \\ +%% +B_1 &= d_1 \overline{\tau}_2 \overline{\tau}_1^2 (3 \tau_0 - 1) + d_0 \tau_0 \tau_1^2(3 \overline{\tau}_2 - 1) - d_0 \tau_0 \tau_1^2 \frac{\overline{\tau}_2^3 + \chi_2 \tau_1^3 (3 \overline{\tau}_2 - 1)}{\overline{\tau}_2^3 (3 \tau_1 - 1) + \chi_2 \tau_1^3} \\ +%% +D_1 &= - d_1 \overline{\tau}_2 \overline{\tau}_1^2 (3 \tau_0 - 1) \psi_1 +\end{align*} +Again, let us consider the simpler case. +Then \(A_1 = d_1\), \(B_1 = 2 d_1 + d_0\), and \(D_1 = - 2 d_1 \psi_1\). +Thus \(\theta_1 = (-2 d_1 \psi_1 - d_1 \theta_0)/(2 d_1 + d_0) = - (2 \psi_1 + \theta_0) \frac{d_1}{2 d_1 + d_0}\). +We compute \(\phi_1 = -\psi_1 - \theta_1 = \frac{- \psi_1 d_0 + \theta_0 d_1}{2 d_1 + d_0}\) and \(\phi_2 = \theta_1\). +Then we store \(\theta_1\) for the next iteration. + +The actual curves are then produced from the angles using the same formulae for the lengths of the control points as in the main algorithm. + +At the last stage, we render both segments of the generated curve. + +\section{Acknowledgements} + +This package began life as an answer to the question \href{http://tex.stackexchange.com/q/54771/86}{Curve through a sequence of points with Metapost and TikZ}. +Once released upon the unsuspecting world, various questions on the \href{http://tex.stackexchange.com}{TeX-SX} site have prompted new features (and bug-fixes). +Most of these can be found by looking at the \href{http://tex.stackexchange.com/questions/tagged/hobby}{list of questions tagged ``hobby''} on that site. + + +\begin{thebibliography}{1} \bibitem{MR834054} John~D. Hobby. \newblock Smooth, easy to compute interpolating splines. \newblock {\em Discrete Comput. Geom.}, 1:123--140, 1986. \end{thebibliography} + +\end{document} diff --git a/graphics/pgf/contrib/hobby/hobby_code.dtx b/graphics/pgf/contrib/hobby/hobby_code.dtx new file mode 100644 index 0000000000..03eb60574c --- /dev/null +++ b/graphics/pgf/contrib/hobby/hobby_code.dtx @@ -0,0 +1,3614 @@ +% \iffalse meta-comment +%<*internal> +\iffalse +% +%<*readme> +---------------------------------------------------------------- +hobby --- a TikZ/PGF library for drawing smooth(ish) curves using + Hobby's algorithm (implemented in LaTeX3) +E-mail: loopspace@mathforge.org +Released under the LaTeX Project Public License v1.3c or later +See http://www.latex-project.org/lppl.txt +---------------------------------------------------------------- + +This package defines a path generation function for TikZ/PGF +which implements Hobby's algorithm for a path built out of Bezier +curves which passes through a given set of points. + +The implementation is in LaTeX3. It can be used as as a TikZ +`to path`. +% +%<*internal> +\fi +\def\nameofplainTeX{plain} +\ifx\fmtname\nameofplainTeX\else + \expandafter\begingroup +\fi +% +%<*install> +\input docstrip.tex +\keepsilent +\askforoverwritefalse +\preamble +---------------------------------------------------------------- +hobby --- a TikZ/PGF library for drawing smooth(ish) curves using + Hobby's algorithm (implemented in LaTeX3) +E-mail: loopspace@mathforge.org +Released under the LaTeX Project Public License v1.3c or later +See http://www.latex-project.org/lppl.txt +---------------------------------------------------------------- + +\endpreamble +\postamble + +Copyright (C) 2012-2021 by Andrew Stacey + +This file may be distributed and/or modified under the conditions +of the LaTeX Project Public License, either version 1.3 of this +license or (at your option) any later version. +The latest version of this license is in: + + http://www.latex-project.org/lppl.txt + +and version 1.3 or later is part of all distributions of LaTeX +version 2005/12/01 or later. + +This work is "maintained" (as per LPPL maintenance status) by +Andrew Stacey. + +This work consists of the files hobby.dtx + hobby_doc.tex +and the derived files hobby.code.tex + pgflibraryhobby.code.tex + tikzlibraryhobby.code.tex + pml3array.sty + hobby-l3draw.sty + hobby.ins + hobby.pdf + hobby_code.pdf + README.txt + +\endpostamble +\usedir{tex/latex/hobby} +\generate{\file{tikzlibraryhobby.code.tex} {\from{hobby.dtx}{tikzlibrary}}} +\generate{\file{pgflibraryhobby.code.tex} {\from{hobby.dtx}{pgflibrary}}} +\generate{\file{hobby.code.tex} {\from{hobby.dtx}{hobby}}} +\generate{\file{pml3array.sty} {\from{hobby.dtx}{array}}} +\generate{\file{hobby-l3draw.sty} {\from{hobby.dtx}{l3hobby}}} +% +%\endbatchfile +%<*internal> +\usedir{source/latex/hobby} +\generate{ + \file{\jobname.ins}{\from{\jobname.dtx}{install}} +} +\nopreamble\nopostamble +\generate{ + \file{README.txt}{\from{\jobname.dtx}{readme}} +} +\ifx\fmtname\nameofplainTeX + \expandafter\endbatchfile +\else + \expandafter\endgroup +\fi +% +%<*driver> +\documentclass[full]{l3doc} +\usepackage[T1]{fontenc} +\usepackage{csquotes} +\usepackage{lmodern} +\usepackage{tikz} +\usepackage{amsmath} +\usetikzlibrary{hobby,decorations.pathreplacing} +\usepackage[margin=3cm]{geometry} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\addtolength{\hoffset}{.4in} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +% +% \fi +% +% \CheckSum{3427} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% +% +% \DoNotIndex{\newcommand,\newenvironment} +% +% \providecommand*{\url}{\texttt} +% \title{The \textsf{Hobby} package: code} +% \author{Andrew Stacey \\ \url{loopspace@mathforge.org}} +% \date{\hobbyVersion\ from\ \hobbyDate} +% \maketitle +% +% +% \StopEventually{\PrintChanges} +% \section{Implementation} +% +% \subsection{Main Code} +% +% \iffalse +%<*hobby> +% \fi +% +% We use \LaTeX3 syntax so need to load the requisite packages +% \begin{macrocode} +\RequirePackage{pml3array} +\ExplSyntaxOn +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \fp_set:Nn {Nx} +\cs_generate_variant:Nn \tl_if_eq:nnTF {VnTF} +\cs_generate_variant:Nn \tl_if_eq:nnTF {xnTF} +% \end{macrocode} +% +% \subsubsection{Initialisation} +% +% We declare all our variables. +% +% Start with version and date, together with a check to see if we've been loaded twice (fail gracefully if so). +% +% \begin{macrocode} +\tl_clear:N \l_tmpa_tl +\tl_if_exist:NT \g__hobby_version +{ + \tl_set:Nn \l_tmpa_tl { + \ExplSyntaxOff + \tl_clear:N \l_tmpa_tl + \endinput + } +} +\tl_use:N \l_tmpa_tl + +\tl_new:N \g__hobby_version +\tl_new:N \g__hobby_date +\tl_gset:Nn \g__hobby_version {1.10} +\tl_gset:Nn \g__hobby_date {2023-08-30} +\DeclareDocumentCommand \hobbyVersion {} +{ + \tl_use:N \g__hobby_version +} +\DeclareDocumentCommand \hobbyDate {} +{ + \tl_use:N \g__hobby_date +} +% \end{macrocode} +% +% The function for computing the lengths of the control points depends on three parameters. +% These are set to \(a = \sqrt{2}\), \(b = 1/16\), and \(c = \frac{3 - \sqrt{5}}{2}\). +% \begin{macrocode} +\fp_new:N \g_hobby_parama_fp +\fp_new:N \g_hobby_paramb_fp +\fp_new:N \g_hobby_paramc_fp +\fp_gset:Nn \g_hobby_parama_fp {2^.5} +\fp_gset:Nn \g_hobby_paramb_fp {1/16} +\fp_gset:Nn \g_hobby_paramc_fp {(3-5^.5)/2} +% \end{macrocode} +% +% Now we define our objects for use in generating the path. +% +% \begin{macro}{\l_hobby_closed_bool} +% \Verb+\l_hobby_closed_bool+ is \Verb+true+ if the path is closed. +% \begin{macrocode} +\bool_new:N \l_hobby_closed_bool +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_hobby_disjoint_bool} +% \Verb+\l_hobby_disjoint_bool+ is \Verb+true+ if the path should start with a \Verb+moveto+ command. +% \begin{macrocode} +\bool_new:N \l_hobby_disjoint_bool +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_hobby_save_aux_bool} +% \Verb+\l_hobby_save_aux_bool+ is \Verb+true+ if when saving paths then they should be saved to the \Verb+aux+ file. +% \begin{macrocode} +\bool_new:N \l_hobby_save_aux_bool +\bool_set_true:N \l_hobby_save_aux_bool +\DeclareDocumentCommand \HobbyDisableAux {} +{ + \bool_set_false:N \l_hobby_save_aux_bool +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_points_array} +% \Verb+\g__hobby_points_array+ is an array holding the specified points on the path. +% In the \LaTeX3 code, a ``point'' is a token list of the form \Verb+, +. +% This gives us the greatest flexibility in passing points back and forth between the \LaTeX3 code and any calling code. +% The array is indexed by integers beginning with \(0\). +% In the documentation, we will use the notation \(z_k\) to refer to the \(k\)th point. +% \begin{macrocode} +\array_new:N \g__hobby_points_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_points_x_array} +% \Verb+\g__hobby_points_x_array+ is an array holding the \(x\)--{}coordinates of the specified points. +% \begin{macrocode} +\array_new:N \g__hobby_points_x_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_hobby_points_y_array} +% \Verb+\g__hobby_points_y_array+ is an array holding the \(y\)--{}coordinates of the specified points. +% \begin{macrocode} +\array_new:N \g__hobby_points_y_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_actions_array} +% \Verb+\g__hobby_actions_array+ is an array holding the (encoded) action to be taken out on the segment of the path ending at that point. +% \begin{macrocode} +\array_new:N \g__hobby_actions_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_angles_array} +% \Verb+\g__hobby_angles_array+ is an array holding the angles of the lines between the points. +% Specifically, the angle indexed by \(k\) is the angle in radians of the line from \(z_k\) to \(z_{k+1}\). +% \begin{macrocode} +\array_new:N \g__hobby_angles_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_distances_array} +% \Verb+\g__hobby_distances_array+ is an array holding the distances between the points. +% Specifically, the distance indexed by \(k\), which we will write as \(d_k\), is the length of the line from \(z_k\) to \(z_{k+1}\). +% \begin{macrocode} +\array_new:N \g__hobby_distances_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_tension_out_array} +% \Verb+\g__hobby_tension_out_array+ is an array holding the tension for the path as it leaves each point. +% This is a parameter that controls how much the curve ``flexes'' as it leaves the point. +% In the following, this will be written \(\tau_k\). +% \begin{macrocode} +\array_new:N \g__hobby_tension_out_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_tension_in_array} +% \Verb+\g__hobby_tension_in_array+ is an array holding the tension for the path as it arrives at each point. +% This is a parameter that controls how much the curve ``flexes'' as it gets to the point. +% In the following, this will be written \(\overline{\tau}_k\). +% \begin{macrocode} +\array_new:N \g__hobby_tension_in_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_matrix_a_array} +% \Verb+\g__hobby_matrix_a_array+ is an array holding the subdiagonal of the linear system that has to be solved to find the angles of the control points. +% In the following, this will be denoted by \(A_i\). +% The first index is \(1\). +% \begin{macrocode} +\array_new:N \g__hobby_matrix_a_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_matrix_b_array} +% \Verb+\g__hobby_matrix_b_array+ is an array holding the diagonal of the linear system that has to be solved to find the angles of the control points. +% In the following, this will be denoted by \(B_i\). +% The first index is \(0\). +% \begin{macrocode} +\array_new:N \g__hobby_matrix_b_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_matrix_c_array} +% \Verb+\g__hobby_matrix_c_array+ is an array holding the superdiagonal of the linear system that has to be solved to find the angles of the control points. +% In the following, this will be denoted by \(C_i\). +% The first index is \(0\). +% \begin{macrocode} +\array_new:N \g__hobby_matrix_c_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_matrix_d_array} +% \Verb+\g__hobby_matrix_d_array+ is an array holding the target vector of the linear system that has to be solved to find the angles of the control points. +% In the following, this will be denoted by \(D_i\). +% The first index is \(1\). +% \begin{macrocode} +\array_new:N \g__hobby_matrix_d_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_vector_u_array} +% \Verb+\g__hobby_vector_u_array+ is an array holding the perturbation of the linear system for closed paths. +% The coefficient matrix for an \emph{open} path is tridiagonal and that means that Gaussian elimination runs faster than expected (\(O(n)\) instead of \(O(n^3)\)). +% The matrix for a closed path is not tridiagonal but is not far off. +% It can be solved by perturbing it to a tridiagonal matrix and then modifying the result. +% This array represents a utility vector in that perturbation. +% In the following, the vector will be denoted by \(u\). +% The first index is \(1\). +% \begin{macrocode} +\array_new:N \g__hobby_vector_u_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_excess_angle_array} +% \Verb+\g__hobby_excess_angle_array+ is an array that allows the user to say that the algorithm should add a multiple of \(2 \pi\) to the angle differences. +% This is because these angles are wrapped to the interval \((-\pi,\pi]\) but the wrapping might go wrong near the end points due to computation accuracy. +% The first index is \(1\). +% \begin{macrocode} +\array_new:N \g__hobby_excess_angle_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_psi_array} +% \Verb+\g__hobby_psi_array+ is an array holding the difference of the angles of the lines entering and exiting a point. +% That is, \(\psi_k\) is the angle between the lines joining \(z_k\) to \(z_{k-1}\) and \(z_{k+1}\). +% The first index is \(1\). +% \begin{macrocode} +\array_new:N \g__hobby_psi_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_theta_array} +% \Verb+\g__hobby_theta_array+ is an array holding the angles of the outgoing control points for the generated path. +% These are measured relative to the line joining the point to the next point on the path. +% The first index is \(0\). +% \begin{macrocode} +\array_new:N \g__hobby_theta_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_phi_array} +% \Verb+\g__hobby_phi_array+ is an array holding the angles of the incoming control points for the generated path. +% These are measured relative to the line joining the point to the previous point on the path. +% The first index is \(1\). +% \begin{macrocode} +\array_new:N \g__hobby_phi_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_sigma_array} +% \Verb+\g__hobby_sigma_array+ is an array holding the lengths of the outgoing control points for the generated path. +% The units are such that the length of the line to the next specified point is one unit. +% \begin{macrocode} +\array_new:N \g__hobby_sigma_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_rho_array} +% \Verb+\g__hobby_rho_array+ is an array holding the lengths of the incoming control points for the generated path. +% The units are such that the length of the line to the previous specified point is one unit. +% \begin{macrocode} +\array_new:N \g__hobby_rho_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_controla_array} +% \Verb+\g__hobby_controla_array+ is an array holding the coordinates of the first control points on the curves. +% The format is the same as for \Verb+\g__hobby_points_array+. +% \begin{macrocode} +\array_new:N \g__hobby_controla_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_controlb_array} +% \Verb+\g__hobby_controlb_array+ is an array holding the coordinates of the second control points on the curves. +% The format is the same as for \Verb+\g__hobby_points_array+. +% \begin{macrocode} +\array_new:N \g__hobby_controlb_array +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_hobby_matrix_v_fp} +% \Verb+\l_hobby_matrix_v_fp+ is a number which is used when doing the perturbation of the solution of the linear system for a closed curve. +% There is actually a vector, \(v\), that this corresponds to but that vector only has one component that needs computation. +% \begin{macrocode} +\fp_new:N \l_hobby_matrix_v_fp +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_hobby_tempa_tl} +% \Verb+\l_hobby_tempa_tl+ is a temporary variable of type \Verb+tl+. +% \begin{macrocode} +\fp_new:N \l_hobby_tempa_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_hobby_tempb_tl} +% \Verb+\l_hobby_tempb_tl+ is a temporary variable of type \Verb+tl+. +% \begin{macrocode} +\fp_new:N \l_hobby_tempb_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_hobby_tempa_fp} +% \Verb+\l_hobby_tempa_fp+ is a temporary variable of type \Verb+fp+. +% \begin{macrocode} +\fp_new:N \l_hobby_tempa_fp +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_hobby_tempb_fp} +% \Verb+\l_hobby_tempb_fp+ is a temporary variable of type \Verb+fp+. +% \begin{macrocode} +\fp_new:N \l_hobby_tempb_fp +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_hobby_tempc_fp} +% \Verb+\l_hobby_tempc_fp+ is a temporary variable of type \Verb+fp+. +% \begin{macrocode} +\fp_new:N \l_hobby_tempc_fp +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_hobby_tempd_fp} +% \Verb+\l_hobby_tempd_fp+ is a temporary variable of type \Verb+fp+. +% \begin{macrocode} +\fp_new:N \l_hobby_tempd_fp +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_hobby_temps_fp} +% \Verb+\l_hobby_temps_fp+ is a temporary variable of type \Verb+fp+. +% \begin{macrocode} +\fp_new:N \l_hobby_temps_fp +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_in_curl_fp} +% \Verb+\g__hobby_in_curl_fp+ is the ``curl'' at the end of an open path. +% This is used if the angle at the end is not specified. +% \begin{macrocode} +\fp_new:N \g__hobby_in_curl_fp +\fp_gset:Nn \g__hobby_in_curl_fp {1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_out_curl_fp} +% \Verb+\g__hobby_out_curl_fp+ is the ``curl'' at the start of an open path. +% This is used if the angle at the start is not specified. +% \begin{macrocode} +\fp_new:N \g__hobby_out_curl_fp +\fp_gset:Nn \g__hobby_out_curl_fp {1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_in_angle_fp} +% \Verb+\g__hobby_in_angle_fp+ is the angle at the end of an open path. +% If this is not specified, it will be computed automatically. +% It is set to \Verb+\c_inf_fp+ to allow easy detection of when it has been specified. +% \begin{macrocode} +\fp_new:N \g__hobby_in_angle_fp +\fp_gset_eq:NN \g__hobby_in_angle_fp \c_inf_fp +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_out_angle_fp} +% \Verb+\g__hobby_out_angle_fp+ is the angle at the start of an open path. +% If this is not specified, it will be computed automatically. +% It is set to \Verb+\c_inf_fp+ to allow easy detection of when it has been specified. +% \begin{macrocode} +\fp_new:N \g__hobby_out_angle_fp +\fp_gset_eq:NN \g__hobby_out_angle_fp \c_inf_fp +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_npoints_int} +% \Verb+\g__hobby_npoints_int+ is one less than the number of points on the curve. +% As our list of points starts at \(0\), this is the index of the last point. +% In the algorithm for a closed curve, some points are repeated whereupon this is incremented so that it is always the index of the last point. +% \begin{macrocode} +\int_new:N \g__hobby_npoints_int +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g__hobby_draw_int} +% \begin{macrocode} +\int_new:N \g__hobby_draw_int +% \end{macrocode} +% \end{macro} +% +% A ``point'' is a key-value list setting the x-value, the y-value, and the tensions at that point. +% Using keys makes it easier to pass points from the algorithm code to the calling code and vice versa without either knowing too much about the other. +% \begin{macrocode} +\keys_define:nn {hobby / read in all} { + point .code:n = { + \fp_set:Nn \l_hobby_tempa_fp {\clist_item:nn {#1} {1}} + \fp_set:Nn \l_hobby_tempb_fp {\clist_item:nn {#1} {2}} + }, + tension~out .fp_set:N = \l_hobby_tempc_fp, + tension~in .fp_set:N = \l_hobby_tempd_fp, + excess~angle .fp_set:N = \l_hobby_temps_fp, + break .tl_set:N = \l_tmpb_tl, + blank .tl_set:N = \l_tmpa_tl, + tension .meta:n = { tension~out=#1, tension~in=#1 }, + break .default:n = false, + blank .default:n = false, + invert~soft~blanks .choice:, + invert~soft~blanks / true .code:n = { + \int_gset:Nn \g__hobby_draw_int {0} + }, + invert~soft~blanks / false .code:n = { + \int_gset:Nn \g__hobby_draw_int {1} + }, + invert~soft~blanks .default:n = true, + tension~out .default:n = 1, + tension~in .default:n = 1, + excess~angle .default:n = 0, + in~angle .fp_gset:N = \g__hobby_in_angle_fp, + out~angle .fp_gset:N = \g__hobby_out_angle_fp, + in~curl .fp_gset:N = \g__hobby_in_curl_fp, + out~curl .fp_gset:N = \g__hobby_out_curl_fp, + closed .bool_gset:N = \g__hobby_closed_bool, + closed .default:n = true, + disjoint .bool_gset:N = \g__hobby_disjoint_bool, + disjoint .default:n = true, + break~default .code:n = { + \keys_define:nn { hobby / read in all } + { + break .default:n = #1 + } + }, + blank~default .code:n = { + \keys_define:nn { hobby / read in all } + { + blank .default:n = #1 + } + }, +} +% \end{macrocode} +% There are certain other parameters that can be set for a given curve. +% \begin{macrocode} +\keys_define:nn { hobby / read in params} { + in~angle .fp_gset:N = \g__hobby_in_angle_fp, + out~angle .fp_gset:N = \g__hobby_out_angle_fp, + in~curl .fp_gset:N = \g__hobby_in_curl_fp, + out~curl .fp_gset:N = \g__hobby_out_curl_fp, + closed .bool_gset:N = \g__hobby_closed_bool, + closed .default:n = true, + disjoint .bool_gset:N = \g__hobby_disjoint_bool, + disjoint .default:n = true, + break~default .code:n = { + \keys_define:nn { hobby / read in all } + { + break .default:n = #1 + } + }, + blank~default .code:n = { + \keys_define:nn { hobby / read in all } + { + blank .default:n = #1 + } + }, + invert~soft~blanks .choice:, + invert~soft~blanks / true .code:n = { + \int_gset:Nn \g__hobby_draw_int {0} + }, + invert~soft~blanks / false .code:n = { + \int_gset:Nn \g__hobby_draw_int {1} + }, + invert~soft~blanks .default:n = true, +} +% \end{macrocode} +% \begin{macro}{\hobby_distangle:n} +% Computes the distance and angle between successive points. +% The argument given is the index of the current point. +% Assumptions: the points are in \Verb+\g__hobby_points_x_array+ and \Verb+\g__hobby_points_y_array+ and the index of the last point is \Verb+\g__hobby_npoints_int+. +% \begin{macrocode} +\cs_set:Nn \hobby_distangle:n { + \fp_set:Nn \l_hobby_tempa_fp { + (\array_get:Nn \g__hobby_points_x_array {#1 + 1}) + - (\array_get:Nn \g__hobby_points_x_array {#1})} + + \fp_set:Nn \l_hobby_tempb_fp { + (\array_get:Nn \g__hobby_points_y_array {#1 + 1}) + - (\array_get:Nn \g__hobby_points_y_array {#1})} + + \fp_set:Nn \l_hobby_tempc_fp { atan ( \l_hobby_tempb_fp, \l_hobby_tempa_fp ) } + \fp_veclen:NVV \l_hobby_tempd_fp \l_hobby_tempa_fp \l_hobby_tempb_fp + + \array_gpush:Nx \g__hobby_angles_array {\fp_to_tl:N \l_hobby_tempc_fp} + \array_gpush:Nx \g__hobby_distances_array {\fp_to_tl:N \l_hobby_tempd_fp} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fp_veclen:NVV} +% Computes the length of the vector specified by the latter two arguments, storing the answer in the first. +% \begin{macrocode} +\cs_new:Nn \fp_veclen:Nnn { + \fp_set:Nn #1 {((#2)^2 + (#3)^2)^.5} +} +\cs_generate_variant:Nn \fp_veclen:Nnn {NVV} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_ctrllen:Nnn} +% Computes the length of the control point vector from the two angles, storing the answer in the first argument given. +% \begin{macrocode} +\cs_new:Nn \hobby_ctrllen:Nnn { + \fp_set:Nn #1 {(2 - \g_hobby_parama_fp + * ( sin(#2) - \g_hobby_paramb_fp * sin(#3) ) + * ( sin(#3) - \g_hobby_paramb_fp * sin(#2) ) + * ( cos(#2) - cos(#3) ) ) + / ( 1 + (1 - \g_hobby_paramc_fp) * cos(#3) + \g_hobby_paramc_fp * cos(#2))} +} +\cs_generate_variant:Nn \hobby_ctrllen:Nnn {NVV} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_append_point_copy:n} +% This function adds a copy of the point (numbered by its argument) to the end of the list of points, copying all the relevant data (coordinates, tension, etc.). +% +% Originally from Bruno Le Foch on TeX-SX. +% \begin{macrocode} +\cs_new_protected:Npn \hobby_append_point_copy:n #1 + { + \hobby_append_point_copy_aux:Nn \g__hobby_points_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_points_x_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_points_y_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_tension_in_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_tension_out_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_excess_angle_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_actions_array {#1} + } +\cs_new_protected:Npn \hobby_append_point_copy_aux:Nn #1#2 + { \array_gpush:Nx #1 { \array_get:Nn #1 {#2} } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_gen_path:} +% This is the curve generation function. +% We assume at the start that we have an array containing all the points that the curve must go through, and the various curve parameters have been initialised. +% So these must be set up by a wrapper function which then calls this one. +% The list of required information is: +% \begin{enumerate} +% \item \Verb+\g__hobby_points_x_array+ +% \item \Verb+\g__hobby_points_y_array+ +% \item \Verb+\g__hobby_tension_out_array+ +% \item \Verb+\g__hobby_tension_in_array+ +% \item \Verb+\g__hobby_excess_angle_array+ +% \item \Verb+\g__hobby_in_curl_fp+ +% \item \Verb+\g__hobby_out_curl_fp+ +% \item \Verb+\g__hobby_in_angle_fp+ +% \item \Verb+\g__hobby_out_angle_fp+ +% \item \Verb+\g__hobby_closed_bool+ +% \item \Verb+\g__hobby_actions_array+ +% \end{enumerate} +% +% \begin{macrocode} +\cs_new:Nn \hobby_gen_path: +{ +% \end{macrocode} +% For much of the time, we can pretend that a closed path is the same as an open path. +% To do this, we need to make the end node an internal node by repeating the \(z_1\) node as the \(z_{n+1}\)th node. +% We also check that the last (\(z_n\)) and first (\(z_0\)) nodes are the same, otherwise we repeat the \(z_0\) node as well. +% \begin{macrocode} +\bool_if:NT \g__hobby_closed_bool { +% \end{macrocode} +% Are the \(x\)-values of the first and last points different? +% \begin{macrocode} + \fp_compare:nTF {(\array_get:Nn \g__hobby_points_x_array {0}) + = + (\array_top:N \g__hobby_points_x_array)} + { +% \end{macrocode} +% No, so compare the \(y\)-values. +% Are the \(y\)-values of the first and last points different? +% \begin{macrocode} + \fp_compare:nF { + \array_get:Nn \g__hobby_points_y_array {0} + = + \array_top:N \g__hobby_points_y_array + } + { +% \end{macrocode} +% Yes, so we need to duplicate the first point, with all of its data. +% \begin{macrocode} + \hobby_append_point_copy:n {0} + } + } + { +% \end{macrocode} +% Yes, so we need to duplicate the first point, with all of its data. +% \begin{macrocode} + \hobby_append_point_copy:n {0} + } +% \end{macrocode} +% Now that we are sure that the first and last points are identical, we need to duplicate the first-but-one point (and all of its data). +% \begin{macrocode} + \hobby_append_point_copy:n {1} +} +% \end{macrocode} +% +% Set \Verb+\g__hobby_npoints_int+ to the number of points (minus one). +% \begin{macrocode} +\int_gset:Nn \g__hobby_npoints_int {\array_length:N \g__hobby_points_y_array} +% \end{macrocode} +% At this point, we need to decide what to do. +% This will depend on whether we have any intermediate points. +% \begin{macrocode} +\int_compare:nNnTF {\g__hobby_npoints_int} = {0} { +% \end{macrocode} +% Only one point, do nothing +% \begin{macrocode} +} +{ + \int_compare:nNnTF {\g__hobby_npoints_int} = {1} { +% \end{macrocode} +% Only two points, skip processing. +% Just need to set the incoming and outgoing angles +% \begin{macrocode} +\hobby_distangle:n {0} +\fp_compare:nF { \g__hobby_out_angle_fp == \c_inf_fp } +{ + \fp_set:Nn \l_hobby_tempa_fp { \g__hobby_out_angle_fp + - \array_get:Nn \g__hobby_angles_array {0}} +% \end{macrocode} +% We want to ensure that these angles lie in the range \((-\pi,\pi]\). +% So if the angle is bigger than \(\pi\), we subtract \(2 \pi\). +% (It shouldn't be that we can get bigger than \(3 \pi\) - check this) +% \begin{macrocode} + \fp_compare:nT {\l_hobby_tempa_fp > \c_pi_fp } + { + \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} + } +% \end{macrocode} +% Similarly, we check to see if the angle is less than \(-\pi\). +% \begin{macrocode} + \fp_compare:nT {\l_hobby_tempa_fp < -\c_pi_fp } + { + \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} + } + \array_gput:Nnx \g__hobby_theta_array {0} {\fp_to_tl:N \l_hobby_tempa_fp} + \fp_compare:nT { \g__hobby_in_angle_fp == \c_inf_fp } + { +%^^A \fp_mul:Nn \l_hobby_tempa_fp {-1} + \array_gput:Nnx \g__hobby_phi_array {1}{ \fp_to_tl:N \l_hobby_tempa_fp} + } + } +\fp_compare:nTF { \g__hobby_in_angle_fp == \c_inf_fp } +{ + \fp_compare:nT { \g__hobby_out_angle_fp == \c_inf_fp } + { + \array_gput:Nnx \g__hobby_phi_array {1} {0} + \array_gput:Nnx \g__hobby_theta_array {0} {0} + } +} +{ + \fp_set:Nn \l_hobby_tempa_fp { - \g__hobby_in_angle_fp + \c_pi_fp ++ (\array_get:Nn \g__hobby_angles_array {0})} + \fp_compare:nT {\l_hobby_tempa_fp > \c_pi_fp } + { + \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} + } + \fp_compare:nT {\l_hobby_tempa_fp < -\c_pi_fp } + { + \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} + } + + \array_gput:Nnx \g__hobby_phi_array {1} + {\fp_to_tl:N \l_hobby_tempa_fp} + \fp_compare:nT { \g__hobby_out_angle_fp == \c_inf_fp } + { +%^^A \fp_mul:Nn \l_hobby_tempa_fp {-1} + \array_gput:Nnx \g__hobby_theta_array {0}{ \fp_to_tl:N \l_hobby_tempa_fp} + } +} + + } + { +% \end{macrocode} +% Got enough points, go on with processing +% \begin{macrocode} + \hobby_compute_path: + } + \hobby_build_path: +} +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\hobby_compute_path:} +% This is the path builder where we have enough points to run the algorithm. +% \begin{macrocode} +\cs_new:Nn \hobby_compute_path: +{ +% \end{macrocode} +% Our first step is to go through the list of points and compute the distances and angles between successive points. +% Thus \(d_i\) is the distance from \(z_i\) to \(z_{i+1}\) and the angle is the angle of the line from \(z_i\) to \(z_{i+1}\). +% \begin{macrocode} +\int_step_function:nnnN {0} {1} {\g__hobby_npoints_int - 1} \hobby_distangle:n +% \end{macrocode} +% +% For the majority of the code, we're only really interested in the differences of the angles. +% So for each internal point we compute the differences in the angles. +% \begin{macrocode} + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 1} { + \fp_set:Nx \l_hobby_tempa_fp { + \array_get:Nn \g__hobby_angles_array {##1} + - \array_get:Nn \g__hobby_angles_array {##1 - 1}} +% \end{macrocode} +% We want to ensure that these angles lie in the range \((-\pi,\pi]\). +% So if the angle is bigger than \(\pi\), we subtract \(2 \pi\). +% (It shouldn't be that we can get bigger than \(3 \pi\) - check this.) +% \begin{macrocode} + \fp_compare:nTF {\l_hobby_tempa_fp > \c_pi_fp } + { + \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} + } + {} +% \end{macrocode} +% Similarly, we check to see if the angle is less than \(-\pi\). +% \begin{macrocode} + \fp_compare:nTF {\l_hobby_tempa_fp <= -\c_pi_fp } + { + \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} + } + {} +% \end{macrocode} +% The wrapping routine might not get it right at the edges so we add in the override. +% \begin{macrocode} +\array_get:NnNTF \g__hobby_excess_angle_array {##1} \l_tmpa_tl { + \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp * \l_tmpa_tl} + }{} +% \end{macrocode} +% \begin{macrocode} + \array_gput:Nnx \g__hobby_psi_array {##1}{\fp_to_tl:N \l_hobby_tempa_fp} + } +% \end{macrocode} +% +% Next, we generate the matrix. +% We start with the subdiagonal. +% This is indexed from \(1\) to \(n-1\). +% \begin{macrocode} + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 1} { + \array_gput:Nnx \g__hobby_matrix_a_array {##1} {\fp_to_tl:n { + \array_get:Nn \g__hobby_tension_in_array {##1}^2 + * \array_get:Nn \g__hobby_distances_array {##1} + * \array_get:Nn \g__hobby_tension_in_array {##1 + 1} + }} +} +% \end{macrocode} +% +% Next, we attack main diagonal. +% We might need to adjust the first and last terms, but we'll do that in a minute. +% \begin{macrocode} + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 1} { + + \array_gput:Nnx \g__hobby_matrix_b_array {##1} {\fp_to_tl:n +{(3 * (\array_get:Nn \g__hobby_tension_in_array {##1 + 1}) - 1) * + (\array_get:Nn \g__hobby_tension_out_array {##1})^2 * +(\array_get:Nn \g__hobby_tension_out_array {##1 - 1}) +* ( \array_get:Nn \g__hobby_distances_array {##1 - 1}) ++ +(3 * (\array_get:Nn \g__hobby_tension_out_array {##1 - 1}) - 1) +* (\array_get:Nn \g__hobby_tension_in_array {##1})^2 +* (\array_get:Nn \g__hobby_tension_in_array {##1 + 1}) +* (\array_get:Nn \g__hobby_distances_array {##1})} +} +} +% \end{macrocode} +% +% Next, the superdiagonal. +% \begin{macrocode} + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 2} { + + \array_gput:Nnx \g__hobby_matrix_c_array {##1} {\fp_to_tl:n +{(\array_get:Nn \g__hobby_tension_in_array {##1})^2 +* (\array_get:Nn \g__hobby_tension_in_array {##1 - 1}) +* (\array_get:Nn \g__hobby_distances_array {##1 - 1}) +}} + +} +% \end{macrocode} +% +% Lastly (before the adjustments), the target vector. +% \begin{macrocode} + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 2} { + + \array_gput:Nnx \g__hobby_matrix_d_array {##1} {\fp_to_tl:n +{ +- (\array_get:Nn \g__hobby_psi_array {##1 + 1}) +* (\array_get:Nn \g__hobby_tension_out_array {##1})^2 +* (\array_get:Nn \g__hobby_tension_out_array {##1 - 1}) +* (\array_get:Nn \g__hobby_distances_array {##1 - 1}) +- (3 * (\array_get:Nn \g__hobby_tension_out_array {##1 - 1}) - 1) +* (\array_get:Nn \g__hobby_psi_array {##1}) +* (\array_get:Nn \g__hobby_tension_in_array {##1})^2 +* (\array_get:Nn \g__hobby_tension_in_array {##1 + 1}) +* (\array_get:Nn \g__hobby_distances_array {##1}) +} +} +} +% \end{macrocode} +% +% Next, there are some adjustments at the ends. +% These differ depending on whether the path is open or closed. +% \begin{macrocode} +\bool_if:NTF \g__hobby_closed_bool { +% \end{macrocode} +% Closed path +% \begin{macrocode} +\array_gput:Nnx \g__hobby_matrix_c_array {0} {\fp_to_tl:n { +- (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int - 2}) +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 2}) +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^2 +}} + +\array_gput:Nnn \g__hobby_matrix_b_array {0} {1} +\array_gput:Nnn \g__hobby_matrix_d_array {0} {0} + +\array_gput:Nnx \g__hobby_matrix_b_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { +(\array_get:Nn \g__hobby_matrix_b_array {\g__hobby_npoints_int - 1}) ++ 1 +}} + + \array_gput:Nnx \g__hobby_matrix_d_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { +- (\array_get:Nn \g__hobby_psi_array {1}) +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int -1})^2 +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int -2}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int - 2}) +- (3 * (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 2}) - 1) +* (\array_get:Nn \g__hobby_psi_array {\g__hobby_npoints_int - 1}) +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int - 1})^2 +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int -1}) +} +} +% \end{macrocode} +% We also need to populate the \(u\)-vector +% \begin{macrocode} + \array_gput:Nnn \g__hobby_vector_u_array {0} {1} +\array_gput:Nnn \g__hobby_vector_u_array {\g__hobby_npoints_int - 1} {1} + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 2} { + \array_gput:Nnn \g__hobby_vector_u_array {##1} {0} + } +% \end{macrocode} +% And define the significant entry in the \(v\)-vector. +% \begin{macrocode} +\fp_set:Nn \l_hobby_matrix_v_fp { +(\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int -1})^2 +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int -2}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int -2}) +} +} +{ +% \end{macrocode} +% Open path. +% First, we test to see if \(\theta_0\) has been specified. +% \begin{macrocode} +\fp_compare:nTF { \g__hobby_out_angle_fp == \c_inf_fp } +{ + \array_gput:Nnx \g__hobby_matrix_b_array {0} {\fp_to_tl:n { + (\array_get:Nn \g__hobby_tension_in_array {1})^3 +* \g__hobby_in_curl_fp ++ +(3 * (\array_get:Nn \g__hobby_tension_in_array {1}) - 1) +* (\array_get:Nn \g__hobby_tension_out_array {0})^3 +}} + + \array_gput:Nnx \g__hobby_matrix_c_array {0} {\fp_to_tl:n { + (\array_get:Nn \g__hobby_tension_out_array {0})^3 ++ +(3 * (\array_get:Nn \g__hobby_tension_out_array {0}) - 1) +* (\array_get:Nn \g__hobby_tension_in_array {1})^3 +* \g__hobby_in_curl_fp +}} + + \array_gput:Nnx \g__hobby_matrix_d_array {0} {\fp_to_tl:n { +-( (\array_get:Nn \g__hobby_tension_out_array {0})^3 ++ +(3 * (\array_get:Nn \g__hobby_tension_out_array {0}) - 1) +* (\array_get:Nn \g__hobby_tension_in_array {1})^3 +* \g__hobby_in_curl_fp) +* (\array_get:Nn \g__hobby_psi_array {1}) +}} + +} +{ + \array_gput:Nnn \g__hobby_matrix_b_array {0} {1} + \array_gput:Nnn \g__hobby_matrix_c_array {0} {0} + \fp_set:Nn \l_hobby_tempa_fp { \g__hobby_out_angle_fp + - \array_get:Nn \g__hobby_angles_array {0}} +% \end{macrocode} +% We want to ensure that these angles lie in the range \((-\pi,\pi]\). +% So if the angle is bigger than \(\pi\), we subtract \(2 \pi\). +% (It shouldn't be that we can get bigger than \(3 \pi\) - check this) +% \begin{macrocode} + \fp_compare:nT {\l_hobby_tempa_fp > \c_pi_fp } + { + \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} + } +% \end{macrocode} +% Similarly, we check to see if the angle is less than \(-\pi\). +% \begin{macrocode} + \fp_compare:nT {\l_hobby_tempa_fp < -\c_pi_fp } + { + \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} + } + \array_gput:Nnx \g__hobby_matrix_d_array {0} {\fp_to_tl:N \l_hobby_tempa_fp} +} +% \end{macrocode} +% +% Next, if \(\phi_n\) has been given. +% \begin{macrocode} +\fp_compare:nTF { \g__hobby_in_angle_fp == \c_inf_fp } +{ + + \array_gput:Nnx \g__hobby_matrix_b_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { +\array_get:Nn \g__hobby_matrix_b_array {\g__hobby_npoints_int - 1} +- (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^2 +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 2}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int - 2}) +* +((3 * (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int} ) - 1) +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^3 \l_tmpa_tl +* \g__hobby_out_curl_fp ++ +(\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int })^3) +/ +((3 * (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int -2}) - 1) +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int})^3 ++ +( \array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^3 +* \g__hobby_out_curl_fp) +}} + + \array_gput:Nnx \g__hobby_matrix_d_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { +- (3 * (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 2}) - 1) +* (\array_get:Nn \g__hobby_psi_array {\g__hobby_npoints_int - 1}) +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int - 1})^2 +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int - 1}) +}} + +} +{ + \fp_set:Nn \l_hobby_tempa_fp { - \g__hobby_in_angle_fp + \c_pi_fp ++ (\array_get:Nn \g__hobby_angles_array {\g__hobby_npoints_int - 1})} + \fp_compare:nT {\l_hobby_tempa_fp > \c_pi_fp } + { + \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} + } + \fp_compare:nT {\l_hobby_tempa_fp < -\c_pi_fp } + { + \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} + } + + \array_gput:Nnx \g__hobby_phi_array {\g__hobby_npoints_int} + {\fp_to_tl:N \l_hobby_tempa_fp} + + \array_gput:Nnx \g__hobby_matrix_d_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { + \l_hobby_tempa_fp + * (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^2 +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 2}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int - 2}) +- +(3 * ( \array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 2}) - 1) +* (\array_get:Nn \g__hobby_psi_array {\g__hobby_npoints_int - 1}) +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int - 1})^2 +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int - 1}) }} +} +% \end{macrocode} +% End of adjustments for open paths. +% \begin{macrocode} +} +% \end{macrocode} +% +% Now we have the tridiagonal matrix in place, we implement the solution. +% We start with the forward eliminations. +% \begin{macrocode} +\int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 1} { + + \array_gput:Nnx \g__hobby_matrix_b_array {##1} {\fp_to_tl:n { + (\array_get:Nn \g__hobby_matrix_b_array {##1 - 1}) +* (\array_get:Nn \g__hobby_matrix_b_array {##1}) +- +(\array_get:Nn \g__hobby_matrix_c_array {##1 - 1}) +* (\array_get:Nn \g__hobby_matrix_a_array {##1}) +}} +% \end{macrocode} +% The last time, we don't touch the \(C\)-vector. +% \begin{macrocode} + \int_compare:nT {##1 < \g__hobby_npoints_int - 1} { + + \array_gput:Nnx \g__hobby_matrix_c_array {##1} {\fp_to_tl:n { +(\array_get:Nn \g__hobby_matrix_b_array {##1 - 1}) + * (\array_get:Nn \g__hobby_matrix_c_array {##1}) +}} + } + + \array_gput:Nnx \g__hobby_matrix_d_array {##1} {\fp_to_tl:n { +(\array_get:Nn \g__hobby_matrix_b_array {##1 - 1}) + * (\array_get:Nn \g__hobby_matrix_d_array {##1}) +- + (\array_get:Nn \g__hobby_matrix_d_array {##1 - 1}) + * (\array_get:Nn \g__hobby_matrix_a_array {##1}) +}} +% \end{macrocode} +% On a closed path, we also want to know \(M^{-1} u\) so need to do the elimination steps on \(u\) as well. +% \begin{macrocode} + \bool_if:NT \g__hobby_closed_bool { + \array_gput:Nnx \g__hobby_vector_u_array {##1} {\fp_to_tl:n { +(\array_get:Nn \g__hobby_matrix_b_array {##1 - 1}) +* (\array_get:Nn \g__hobby_vector_u_array {##1}) +- +(\array_get:Nn \g__hobby_vector_u_array {##1 - 1}) +* (\array_get:Nn \g__hobby_matrix_a_array {##1}) +}} +} +} +% \end{macrocode} +% Now we start the back substitution. +% The first step is slightly different to the general step. +% \begin{macrocode} + \array_gput:Nnx \g__hobby_theta_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { +(\array_get:Nn \g__hobby_matrix_d_array {\g__hobby_npoints_int - 1}) +/ (\array_get:Nn \g__hobby_matrix_b_array {\g__hobby_npoints_int - 1}) +}} +% \end{macrocode} +% For a closed path, we need to work with \(u\) as well. +% \begin{macrocode} +\bool_if:NT \g__hobby_closed_bool { + \array_gput:Nnx \g__hobby_vector_u_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { + (\array_get:Nn \g__hobby_vector_u_array {\g__hobby_npoints_int - 1}) +/ (\array_get:Nn \g__hobby_matrix_b_array {\g__hobby_npoints_int - 1}) +}} +} +% \end{macrocode} +% Now we iterate over the vectors, doing the remaining back substitutions. +% \begin{macrocode} +\int_step_inline:nnnn {\g__hobby_npoints_int - 2} {-1} {0} { + + \array_gput:Nnx \g__hobby_theta_array {##1} {\fp_to_tl:n { +( (\array_get:Nn \g__hobby_matrix_d_array {##1}) + - (\array_get:Nn \g__hobby_theta_array {##1 + 1}) + * (\array_get:Nn \g__hobby_matrix_c_array {##1}) +) / (\array_get:Nn \g__hobby_matrix_b_array {##1}) +}} +} +\bool_if:NT \g__hobby_closed_bool { +% \end{macrocode} +% On a closed path, we also need to work out \(M^{-1} u\). +% \begin{macrocode} +\int_step_inline:nnnn {\g__hobby_npoints_int - 2} {-1} {0} { + \array_gput:Nnx \g__hobby_vector_u_array {##1} {\fp_to_tl:n +{ + ((\array_get:Nn \g__hobby_vector_u_array {##1}) + - (\array_get:Nn \g__hobby_vector_u_array {##1 + 1}) + * (\array_get:Nn \g__hobby_matrix_c_array {##1}) + ) / (\array_get:Nn \g__hobby_matrix_b_array {##1}) +}} +} +% \end{macrocode} +% Then we compute \(v^\top M^{-1}u\) and \(v^\top M^{-1} \theta\). +% As \(v\) has a particularly simple form, these inner products are easy to compute. +% \begin{macrocode} + +\fp_set:Nn \l_hobby_tempb_fp { +((\array_get:Nn \g__hobby_theta_array {1}) +* \l_hobby_matrix_v_fp +- (\array_get:Nn \g__hobby_theta_array {\g__hobby_npoints_int - 1}) +) / ( +(\array_get:Nn \g__hobby_vector_u_array {1}) +* \l_hobby_matrix_v_fp +- (\array_get:Nn \g__hobby_vector_u_array {\g__hobby_npoints_int - 1}) ++ 1 +)} + +\int_step_inline:nnnn {0} {1} {\g__hobby_npoints_int - 1} { + + \array_gput:Nnx \g__hobby_theta_array {##1} {\fp_to_tl:n { + (\array_get:Nn \g__hobby_theta_array {##1}) + - (\array_get:Nn \g__hobby_vector_u_array {##1}) + * \l_hobby_tempb_fp +}} +} +} +% \end{macrocode} +% +% Now that we have computed the \(\theta_i\)s, we can quickly compute the \(\phi_i\)s. +% +% \begin{macrocode} +\int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 1} { + + \array_gput:Nnx \g__hobby_phi_array {##1} {\fp_to_tl:n { + - (\array_get:Nn \g__hobby_psi_array {##1}) + - (\array_get:Nn \g__hobby_theta_array {##1}) + }} + } +% \end{macrocode} +% +% If the path is open, this works for all except \(\phi_n\). +% If the path is closed, we can drop our added point. +% Cheaply, of course. +% \begin{macrocode} +\bool_if:NTF \g__hobby_closed_bool { + \int_gdecr:N \g__hobby_npoints_int +}{ +% \end{macrocode} +% If \(\phi_n\) was not given, we compute it from \(\theta_{n-1}\). +% \begin{macrocode} +\fp_compare:nT { \g__hobby_in_angle_fp == \c_inf_fp } +{ + \array_gput:Nnx \g__hobby_phi_array {\g__hobby_npoints_int} {\fp_to_tl:n { +((3 * (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int}) - 1) +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^3 +* \g__hobby_out_curl_fp ++ +(\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int })^3) +/ +((3 * (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int -2}) - 1) +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int})^3 \l_tmpa_tl ++ +(\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^3 +* \g__hobby_out_curl_fp) +* +(\array_get:Nn \g__hobby_theta_array {\g__hobby_npoints_int -1}) +}} +} +} +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\hobby_build_path:} +% Once we've computed the angles, we build the actual path. +% \begin{macrocode} +\cs_new:Nn \hobby_build_path: +{ +% \end{macrocode} +% Next task is to compute the \(\rho_i\) and \(\sigma_i\). +% \begin{macrocode} +\int_step_inline:nnnn {0} {1} {\g__hobby_npoints_int - 1} { + + \fp_set:Nn \l_hobby_tempa_fp {\array_get:Nn \g__hobby_theta_array {##1}} + + \fp_set:Nn \l_hobby_tempb_fp {\array_get:Nn \g__hobby_phi_array {##1 + 1}} + + \hobby_ctrllen:NVV \l_hobby_temps_fp \l_hobby_tempa_fp \l_hobby_tempb_fp + + \array_gput:Nnx \g__hobby_sigma_array {##1 + 1} {\fp_to_tl:N \l_hobby_temps_fp} + + \hobby_ctrllen:NVV \l_hobby_temps_fp \l_hobby_tempb_fp \l_hobby_tempa_fp + + \array_gput:Nnx \g__hobby_rho_array {##1} {\fp_to_tl:N \l_hobby_temps_fp} + + } +% \end{macrocode} +% Lastly, we generate the coordinates of the control points. +% \begin{macrocode} +\int_step_inline:nnnn {0} {1} {\g__hobby_npoints_int - 1} { +\array_gput:Nnx \g__hobby_controla_array {##1 + 1} {\fp_eval:n { +(\array_get:Nn \g__hobby_points_x_array {##1}) ++ + (\array_get:Nn \g__hobby_distances_array {##1}) * + (\array_get:Nn \g__hobby_rho_array {##1}) * +cos ( (\array_get:Nn \g__hobby_angles_array {##1}) ++ + (\array_get:Nn \g__hobby_theta_array {##1})) +/3 +}, \fp_eval:n { +( \array_get:Nn \g__hobby_points_y_array {##1}) + + (\array_get:Nn \g__hobby_distances_array {##1}) * + (\array_get:Nn \g__hobby_rho_array {##1}) * +sin ( (\array_get:Nn \g__hobby_angles_array {##1}) ++ + (\array_get:Nn \g__hobby_theta_array {##1})) +/3 +} +} +} +\int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int} { + \array_gput:Nnx \g__hobby_controlb_array {##1} { + \fp_eval:n {\array_get:Nn \g__hobby_points_x_array {##1} +- (\array_get:Nn \g__hobby_distances_array {##1 - 1}) +* (\array_get:Nn \g__hobby_sigma_array {##1}) +* cos((\array_get:Nn \g__hobby_angles_array {##1 - 1}) +- (\array_get:Nn \g__hobby_phi_array {##1}))/3 +}, \fp_eval:n { + (\array_get:Nn \g__hobby_points_y_array {##1}) +- (\array_get:Nn \g__hobby_distances_array {##1 - 1}) +* (\array_get:Nn \g__hobby_sigma_array {##1}) +* sin((\array_get:Nn \g__hobby_angles_array {##1 - 1}) +- (\array_get:Nn \g__hobby_phi_array {##1}))/3 +} } + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobbyinit} +% Initialise the settings for Hobby's algorithm +% \begin{macrocode} +\NewDocumentCommand \hobbyinit {m m m} { + \hobby_set_cmds:NNN #1#2#3 + \hobby_clear_path: +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobbyaddpoint} +% This adds a point, possibly with tensions, to the current stack. +% \begin{macrocode} +\NewDocumentCommand \hobbyaddpoint { m } { + \keys_set:nn { hobby/read in all } + { + tension~out, + tension~in, + excess~angle, + blank, + break, + #1 + } + \tl_if_eq:VnTF \l_tmpa_tl {true} + {\tl_set:Nn \l_tmpa_tl {2}} + { + \tl_if_eq:VnTF \l_tmpa_tl {soft} + {\tl_set:Nn \l_tmpa_tl {0}} + {\tl_set:Nn \l_tmpa_tl {1}} + } + \tl_if_eq:VnTF \l_tmpb_tl {true} + {\tl_put_right:Nn \l_tmpa_tl {1}} + {\tl_put_right:Nn \l_tmpa_tl {0}} + \tl_set:Nx \l_hobby_tempa_tl {\fp_use:N \l_hobby_tempa_fp} + \tl_set:Nx \l_hobby_tempb_tl {\fp_use:N \l_hobby_tempb_fp} + \hobby_add_point:VVVVVV \l_hobby_tempa_tl \l_hobby_tempb_tl \l_hobby_tempc_fp \l_hobby_tempd_fp \l_hobby_temps_fp \l_tmpa_tl +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_add_point:n} +% \begin{macrocode} +\cs_new_nopar:Npn \hobby_add_point:nnnnnn #1#2#3#4#5#6 +{ + \array_gpush:Nn \g__hobby_actions_array { #6 } + \array_gpush:Nn \g__hobby_tension_out_array { #3 } + \array_gpush:Nn \g__hobby_tension_in_array { #4 } + \array_gpush:Nn \g__hobby_excess_angle_array { #5 } + \array_gpush:Nn \g__hobby_points_array { #1, #2 } + \array_gpush:Nn \g__hobby_points_x_array { #1 } + \array_gpush:Nn \g__hobby_points_y_array { #2 } +} +\cs_generate_variant:Nn \hobby_add_point:nnnnnn {VVVVVV} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobbysetparams} +% This sets the parameters for the curve. +% \begin{macrocode} +\NewDocumentCommand \hobbysetparams { m } { + \keys_set:nn { hobby / read in params } + { + #1 + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_set_cmds:NNN} +% The path-generation code doesn't know what to actually do with the path so the initialisation code will set some macros to do that. +% This is an auxiliary command that sets these macros. +% \begin{macrocode} +\cs_new:Npn \hobby_moveto:nnn #1#2#3 {} +\cs_new:Npn \hobby_curveto:nnn #1#2#3 {} +\cs_new:Npn \hobby_close:n #1 {} +\cs_generate_variant:Nn \hobby_moveto:nnn {VVV,nnV} +\cs_generate_variant:Nn \hobby_curveto:nnn {VVV} +\cs_generate_variant:Nn \hobby_close:n {V} +\cs_new:Nn \hobby_set_cmds:NNN { + \cs_gset_eq:NN \hobby_moveto:nnn #1 + \cs_gset_eq:NN \hobby_curveto:nnn #2 + \cs_gset_eq:NN \hobby_close:n #3 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobbygenpath} +% This is the user (well, sort of) command that generates the curve. +% \begin{macrocode} +\NewDocumentCommand \hobbygenpath { } { + \array_if_empty:NF \g__hobby_points_array { + \hobby_gen_path: + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobbygenifnecpath} +% If the named path doesn't exist, it is generated and named. +% If it does exist, we restore it. +% Either way, we save it to the aux file. +% \begin{macrocode} +\NewDocumentCommand \hobbygenifnecpath { m } { + \tl_if_exist:cTF {g_hobby_#1_path} + { + \tl_use:c {g_hobby_#1_path} + } + { + \hobby_gen_path: + } + \hobby_save_path:n {#1} + \hobby_save_path_to_aux:x {#1} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobbygenifnecusepath} +% If the named path doesn't exist, it is generated and named. +% If it does exist, we restore it. +% Either way, we save it to the aux file. +% \begin{macrocode} +\NewDocumentCommand \hobbygenuseifnecpath { m } { + \tl_if_exist:cTF {g_hobby_#1_path} + { + \tl_use:c {g_hobby_#1_path} + } + { + \hobby_gen_path: + } + \hobby_save_path:n {#1} + \hobby_save_path_to_aux:x {#1} + \hobby_use_path: +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobbyusepath} +% This is the user (well, sort of) command that uses the last generated curve. +% \begin{macrocode} +\NewDocumentCommand \hobbyusepath { m } { + \hobbysetparams{#1} + \hobby_use_path: +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobbysavepath} +% This is the user (well, sort of) command that uses the last generated curve. +% \begin{macrocode} +\NewDocumentCommand \hobbysavepath { m } { + \hobby_save_path:n {#1} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobbyrestorepath} +% This is the user (well, sort of) command that uses the last generated curve. +% \begin{macrocode} +\NewDocumentCommand \hobbyrestorepath { m } { + \tl_if_exist:cT {g_hobby_#1_path} { + \tl_use:c {g_hobby_#1_path} + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobbyshowpath} +% This is the user (well, sort of) command that uses the last generated curve. +% \begin{macrocode} +\NewDocumentCommand \hobbyshowpath { m } { + \tl_if_exist:cT {g_hobby_#1_path} { + \tl_show:c {g_hobby_#1_path} + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobbygenusepath} +% This is the user (well, sort of) command that generates a curve and uses it. +% \begin{macrocode} +\NewDocumentCommand \hobbygenusepath { } { + \array_if_empty:NF \g__hobby_points_array { + \hobby_gen_path: + \hobby_use_path: + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobbyclearpath} +% This is the user (well, sort of) command that generates a curve and uses it. +% \begin{macrocode} +\NewDocumentCommand \hobbyclearpath { } { + \hobby_clear_path: +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_use_path:} +% This is the command that uses the curve. +% As the curve data is stored globally, the same data can be reused by calling this function more than once without calling the generating function. +% \begin{macrocode} +\tl_new:N \l_tmpc_tl +\tl_new:N \l_tmpd_tl +\cs_new:Nn \hobby_use_path: { + \bool_if:NT \g__hobby_disjoint_bool { + \array_get:NnN \g__hobby_points_array {0} \l_tmpa_tl + \hobby_moveto:nnV {} {} \l_tmpa_tl + } + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int} { + \array_get:NnN \g__hobby_controla_array {##1} \l_tmpa_tl + \array_get:NnN \g__hobby_controlb_array {##1} \l_tmpb_tl + \array_get:NnN \g__hobby_points_array {##1} \l_tmpc_tl + \array_get:NnN \g__hobby_actions_array {##1} \l_tmpd_tl + \int_compare:nNnTF {\tl_item:Nn \l_tmpd_tl {1}} = {\g__hobby_draw_int} { + \hobby_curveto:VVV \l_tmpa_tl \l_tmpb_tl \l_tmpc_tl + }{ + \bool_gset_false:N \g__hobby_closed_bool + \hobby_moveto:VVV \l_tmpa_tl \l_tmpb_tl \l_tmpc_tl + } + \tl_if_eq:xnTF {\tl_item:Nn \l_tmpd_tl {2}} {1} { + \bool_gset_false:N \g__hobby_closed_bool + \hobby_moveto:VVV \l_tmpa_tl \l_tmpb_tl \l_tmpc_tl + }{} + } + \bool_if:NT \g__hobby_closed_bool { + \array_get:NnN \g__hobby_points_array {0} \l_tmpa_tl + \hobby_close:V \l_tmpa_tl + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_save_path:n} +% This command saves all the data needed to reinvoke the curve in a global token list that can be used to restore it afterwards. +% \begin{macrocode} +\cs_new:Nn \hobby_save_path:n { + \tl_clear:N \l_tmpa_tl + \tl_put_right:Nn \l_tmpa_tl {\int_gset:Nn \g__hobby_npoints_int} + \tl_put_right:Nx \l_tmpa_tl {{\int_use:N \g__hobby_npoints_int}} + \bool_if:NTF \g__hobby_disjoint_bool { + \tl_put_right:Nn \l_tmpa_tl {\bool_gset_true:N} + }{ + \tl_put_right:Nn \l_tmpa_tl {\bool_gset_false:N} + } + \tl_put_right:Nn \l_tmpa_tl {\g__hobby_disjoint_bool} + \bool_if:NTF \g__hobby_closed_bool { + \tl_put_right:Nn \l_tmpa_tl {\bool_gset_true:N} + }{ + \tl_put_right:Nn \l_tmpa_tl {\bool_gset_false:N} + } + \tl_put_right:Nn \l_tmpa_tl {\g__hobby_closed_bool} + \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \g__hobby_points_array} + \array_map_inline:Nn \g__hobby_points_array { + \tl_put_right:Nn \l_tmpa_tl { + \array_gput:Nnn \g__hobby_points_array {##1} {##2} + } + } + \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \g__hobby_actions_array} + \array_map_inline:Nn \g__hobby_actions_array { + \tl_put_right:Nn \l_tmpa_tl { + \array_gput:Nnn \g__hobby_actions_array {##1} {##2} + } + } + \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \g__hobby_controla_array} + \array_map_inline:Nn \g__hobby_controla_array { + \tl_put_right:Nn \l_tmpa_tl { + \array_gput:Nnn \g__hobby_controla_array {##1} {##2} + } + } + \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \g__hobby_controlb_array} + \array_map_inline:Nn \g__hobby_controlb_array { + \tl_put_right:Nn \l_tmpa_tl { + \array_gput:Nnn \g__hobby_controlb_array {##1} {##2} + } + } + \tl_gclear_new:c {g_hobby_#1_path} + \tl_gset_eq:cN {g_hobby_#1_path} \l_tmpa_tl +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_save_path_to_aux:n} +% \begin{macrocode} +\int_set:Nn \l_tmpa_int {\char_value_catcode:n {`@}} +\char_set_catcode_letter:N @ +\cs_new:Npn \hobby_save_path_to_aux:n #1 { + \bool_if:nT { + \tl_if_exist_p:c {g_hobby_#1_path} + && + ! \tl_if_exist_p:c {g_hobby_#1_path_saved} + && + \l_hobby_save_aux_bool + } + { + \tl_clear:N \l_tmpa_tl + \tl_put_right:Nn \l_tmpa_tl { + \ExplSyntaxOn + \tl_gclear_new:c {g_hobby_#1_path} + \tl_gput_right:cn {g_hobby_#1_path} + } + \tl_put_right:Nx \l_tmpa_tl { + {\tl_to_str:c {g_hobby_#1_path}} + } + \tl_put_right:Nn \l_tmpa_tl { + \ExplSyntaxOff + } + \protected@write\@auxout{}{ + \tl_to_str:N \l_tmpa_tl + } + \tl_new:c {g_hobby_#1_path_saved} + } +} +\char_set_catcode:nn {`@} {\l_tmpa_int} +\cs_generate_variant:Nn \hobby_save_path_to_aux:n {x} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_clear_path:} +% \begin{macrocode} +\cs_new:Nn \hobby_clear_path: +{ +\array_gclear:N \g__hobby_points_array +\array_gclear:N \g__hobby_points_x_array +\array_gclear:N \g__hobby_points_y_array +\array_gclear:N \g__hobby_angles_array +\array_gclear:N \g__hobby_actions_array +\array_gclear:N \g__hobby_distances_array +\array_gclear:N \g__hobby_tension_out_array +\array_gclear:N \g__hobby_tension_in_array +\array_gclear:N \g__hobby_excess_angle_array +\array_gclear:N \g__hobby_matrix_a_array +\array_gclear:N \g__hobby_matrix_b_array +\array_gclear:N \g__hobby_matrix_c_array +\array_gclear:N \g__hobby_matrix_d_array +\array_gclear:N \g__hobby_vector_u_array +\array_gclear:N \g__hobby_psi_array +\array_gclear:N \g__hobby_theta_array +\array_gclear:N \g__hobby_phi_array +\array_gclear:N \g__hobby_sigma_array +\array_gclear:N \g__hobby_rho_array +\array_gclear:N \g__hobby_controla_array +\array_gclear:N \g__hobby_controlb_array +\bool_gset_false:N \g__hobby_closed_bool +\bool_gset_false:N \g__hobby_disjoint_bool + + \int_gset:Nn \g__hobby_npoints_int {-1} + \int_gset:Nn \g__hobby_draw_int {1} + \fp_gset_eq:NN \g__hobby_in_angle_fp \c_inf_fp + \fp_gset_eq:NN \g__hobby_out_angle_fp \c_inf_fp + \fp_gset_eq:NN \g__hobby_in_curl_fp \c_one_fp + \fp_gset_eq:NN \g__hobby_out_curl_fp \c_one_fp +} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% \iffalse +% +% \fi +% +% \subsection{PGF Library} +% +% \iffalse +%<*pgflibrary> +% \fi +% +% The PGF level is very simple. +% All we do is set up the path-construction commands that get passed to the path-generation function. +% \begin{macrocode} +\input{hobby.code.tex} +% \end{macrocode} +% Points are communicated as key-pairs. +% These keys translate from the \LaTeX3 style points to PGF points. +% \begin{macrocode} +\pgfkeys{ + /pgf/hobby/.is family, + /pgf/hobby/.cd, + point/.code={% + \hobby@parse@pt#1\relax} +} +\def\hobby@parse@pt#1,#2\relax{% + \pgf@x=#1cm\relax + \pgf@y=#2cm\relax +} +% \end{macrocode} +% +% \begin{macro}{hobbyatan2} +% The original PGF version of \Verb+atan2+ had the arguments the wrong way around. +% This was fixed in the CVS version in July 2013, but as old versions are likely to be in use for some time, we define a wrapper function that ensures that the arguments are correct. +% \begin{macrocode} +\pgfmathparse{atan2(0,1)} +\def\hobby@temp{0.0} +\ifx\pgfmathresult\hobby@temp + \pgfmathdeclarefunction{hobbyatan2}{2}{% + \pgfmathatantwo@{#1}{#2}% + } +\else + \pgfmathdeclarefunction{hobbyatan2}{2}{% + \pgfmathatantwo@{#2}{#1}% + } +\fi +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@curveto} +% This is passed to the path-generation code to translate the path into a PGF path. +% \begin{macrocode} +\def\hobby@curveto#1#2#3{% + \pgfpathcurveto{\hobby@topgf{#1}}{\hobby@topgf{#2}}{\hobby@topgf{#3}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@moveto} +% This is passed to the path-generation code to translate the path into a PGF path. +% \begin{macrocode} +\def\hobby@moveto#1#2#3{% + \pgfpathmoveto{\hobby@topgf{#3}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@topgf} +% Translates a \LaTeX3 point to a PGF point. +% \begin{macrocode} +\def\hobby@topgf#1{% + \pgfqkeys{/pgf/hobby}{point={#1}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@close} +% Closes a path. +% \begin{macrocode} +\def\hobby@close#1{% + \pgfpathclose +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pgfpathhobby} +% Low-level interface to the hobby construction. +% This sets up the commands and starts the iterator. +% \begin{macrocode} +\def\pgfpathhobby{% + \pgfutil@ifnextchar\bgroup{\pgfpath@hobby}{\pgfpath@hobby{}}} +\def\pgfpath@hobby#1{% + \hobbyinit\hobby@moveto\hobby@curveto\hobby@close + \hobbysetparams{#1}% + \pgfmathsetmacro\hobby@x{\the\pgf@path@lastx/1cm}% + \pgfmathsetmacro\hobby@y{\the\pgf@path@lasty/1cm}% + \hobbyaddpoint{point={\hobby@x, \hobby@y}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pgfpathhobbypt} +% Adds a point to the construction +% \begin{macrocode} +\def\pgfpathhobbypt#1{% + #1% + \pgfmathsetmacro\hobby@x{\the\pgf@x/1cm}% + \pgfmathsetmacro\hobby@y{\the\pgf@y/1cm}% + \pgfutil@ifnextchar\bgroup{\pgfpathhobbyptparams}{\pgfpathhobbyptparams{}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pgfpathhobbyptparams} +% \begin{macrocode} +\def\pgfpathhobbyptparams#1{% + \hobbyaddpoint{#1,point={\hobby@x, \hobby@y}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pgfpathhobbyend} +% \begin{macrocode} +\def\pgfpathhobbyend{% + \ifhobby@externalise + \ifx\hobby@path@name\pgfutil@empty + \hobbygenusepath + \else + \hobbygenuseifnecpath{\hobby@path@name}% + \fi + \else + \hobbygenusepath + \fi + \ifx\hobby@path@name\pgfutil@empty + \else + \hobbysavepath{\hobby@path@name}% + \fi + \global\let\hobby@path@name=\pgfutil@empty +} +% \end{macrocode} +% \end{macro} +% +% +% Plot handlers +% +% \begin{macro}{\pgfplothanderhobby} +% Basic plot handler; uses full algorithm but therefore expensive +% \begin{macrocode} +\def\pgfplothandlerhobby{% + \def\pgf@plotstreamstart{% + \hobbyinit\hobby@moveto\hobby@curveto\hobby@close + \global\let\pgf@plotstreampoint=\pgf@plot@hobby@firstpt + \global\let\pgf@plotstreamspecial=\pgfutil@gobble + \gdef\pgf@plotstreamend{% + \ifhobby@externalise + \ifx\hobby@path@name\pgfutil@empty + \hobbygenusepath + \else + \hobbygenuseifnecpath{\hobby@path@name}% + \fi + \else + \hobbygenusepath + \fi + \ifx\hobby@path@name\pgfutil@empty + \else + \hobbysavepath{\hobby@path@name}% + \fi + \global\let\hobby@path@name=\pgfutil@empty + }% + \let\tikz@scan@point@options=\pgfutil@empty + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pgfplothandlerclosedhobby} +% Same as above but produces a closed curve +% \begin{macrocode} +\def\pgfplothandlerclosedhobby{% + \def\pgf@plotstreamstart{% + \hobbyinit\hobby@moveto\hobby@curveto\hobby@close + \hobbysetparams{closed=true,disjoint=true}% + \global\let\pgf@plotstreampoint=\pgf@plot@hobby@firstpt + \global\let\pgf@plotstreamspecial=\pgfutil@gobble + \gdef\pgf@plotstreamend{% + \ifhobby@externalise + \ifx\hobby@path@name\pgfutil@empty + \hobbygenusepath + \else + \hobbygenuseifnecpath{\hobby@path@name}% + \fi + \else + \hobbygenusepath + \fi + \ifx\hobby@path@name\pgfutil@empty + \else + \hobbysavepath{\hobby@path@name}% + \fi + \global\let\hobby@path@name=\pgfutil@empty + }% + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pgf@plot@hobby@firstpt} +% First point, move or line as appropriate and then start the algorithm. +% \begin{macrocode} +\def\pgf@plot@hobby@firstpt#1{% + \pgf@plot@first@action{#1}% + \pgf@plot@hobby@handler{#1}% + \global\let\pgf@plotstreampoint=\pgf@plot@hobby@handler +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pgf@plot@hobby@handler} +% Add points to the array for the algorithm to work on. +% \begin{macrocode} +\def\pgf@plot@hobby@handler#1{% + #1% + \pgfmathsetmacro\hobby@x{\the\pgf@x/1cm}% + \pgfmathsetmacro\hobby@y{\the\pgf@y/1cm}% + \hobbyaddpoint{point={\hobby@x, \hobby@y}}% + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pgfplothandlerquickhobby} +% Uses the ``quick'' algorithm. +% \begin{macrocode} +\def\pgfplothandlerquickhobby{% + \def\pgf@plotstreamstart{% + \global\let\hobby@quick@curveto=\pgfpathcurveto + \global\let\pgf@plotstreampoint=\pgf@plot@qhobby@firstpt + \global\let\pgf@plotstreamspecial=\pgfutil@gobble + \global\let\pgf@plotstreamend=\pgf@plot@qhobby@end + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pgf@plot@qhobby@firstpt} +% Carry out first action (move or line) and save point. +% \begin{macrocode} +\def\pgf@plot@qhobby@firstpt#1{% + #1% + \edef\hobby@temp{\noexpand\pgf@plot@first@action{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}\hobby@temp% + \xdef\hobby@qpoints{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \gdef\hobby@qpointa{}% + \gdef\hobby@angle{}% + \global\let\pgf@plotstreampoint=\pgf@plot@qhobby@secondpt +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pgf@plot@qhobby@secondpt} +% Also need to save second point. +% \begin{macrocode} +\def\pgf@plot@qhobby@secondpt#1{% + #1% + \xdef\hobby@qpointa{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \global\let\pgf@plotstreampoint=\pgf@plot@qhobby@handler +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pgf@plot@qhobby@handler} +% Wrapper around the computation macro that saves the variables globally. +% \begin{macrocode} +\def\pgf@plot@qhobby@handler#1{% + #1 + \edef\hobby@temp{\noexpand\hobby@quick@compute{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}\hobby@temp + \global\let\hobby@qpointa=\hobby@qpointa + \global\let\hobby@qpoints=\hobby@qpoints + \global\let\hobby@angle=\hobby@angle +% \end{macrocode} +% Also need to save some data for the last point +% \begin{macrocode} + \global\let\hobby@thetaone=\hobby@thetaone + \global\let\hobby@phitwo=\hobby@phitwo + \global\let\hobby@done=\hobby@done + \global\let\hobby@omegaone=\hobby@omegaone +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pgf@plot@qhobby@end} +% Wrapper around the finalisation step. +% \begin{macrocode} +\def\pgf@plot@qhobby@end{% + \hobby@quick@computeend +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@sf} +% Working with points leads to computations out of range so we scale to get them into the computable arena. +% \begin{macrocode} +\pgfmathsetmacro\hobby@sf{10cm} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\hobby@quick@compute} +% This is the macro that does all the work of computing the control points. +% The argument is the current point, \Verb+\hobby@qpointa+ is the middle point, and \Verb+\hobby@qpoints+ is the first point. +% \begin{macrocode} +\def\hobby@quick@compute#1{% +% \end{macrocode} +% Save the current (second - counting from zero) point in \Verb+\pgf@xb+ and \Verb+\pgf@yb+. +% \begin{macrocode} + #1% + \pgf@xb=\pgf@x + \pgf@yb=\pgf@y +% \end{macrocode} +% Save the previous (first) point in \Verb+\pgf@xa+ and \Verb+\pgf@ya+. +% \begin{macrocode} + \hobby@qpointa + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y +% \end{macrocode} +% Adjust so that \Verb+(\pgf@xb,\pgf@yb)+ is the vector from second to third. +% Then compute and store the distance and angle of this vector. +% We view this as the vector \emph{from} the midpoint and everything to do with that point has the suffix \Verb+one+. +% Note that we divide by the scale factor here. +% \begin{macrocode} + \advance\pgf@xb by -\pgf@xa + \advance\pgf@yb by -\pgf@ya + \pgfmathsetmacro\hobby@done{sqrt((\pgf@xb/\hobby@sf)^2 + (\pgf@yb/\hobby@sf)^2)}% + \pgfmathsetmacro\hobby@omegaone{rad(hobbyatan2(\pgf@yb,\pgf@xb))}% +% \end{macrocode} +% Now we do the same with the vector from the zeroth to the first point. +% \begin{macrocode} + \hobby@qpoints + \advance\pgf@xa by -\pgf@x + \advance\pgf@ya by -\pgf@y + \pgfmathsetmacro\hobby@dzero{sqrt((\pgf@xa/\hobby@sf)^2 + (\pgf@ya/\hobby@sf)^2)}% + \pgfmathsetmacro\hobby@omegazero{rad(hobbyatan2(\pgf@ya,\pgf@xa))}% +% \end{macrocode} +% \Verb+\hobby@psi+ is the angle subtended at the midpoint. +% We adjust to ensure that it is in the right range. +% \begin{macrocode} + \pgfmathsetmacro\hobby@psi{\hobby@omegaone - \hobby@omegazero}% + \pgfmathsetmacro\hobby@psi{\hobby@psi > pi ? \hobby@psi - 2*pi : \hobby@psi}% + \pgfmathsetmacro\hobby@psi{\hobby@psi < -pi ? \hobby@psi + 2*pi : \hobby@psi}% +% \end{macrocode} +% Now we test to see if we're on the first run or not. +% If the first, we have no incoming angle. +% \begin{macrocode} + \ifx\hobby@angle\pgfutil@empty +% \end{macrocode} +% First. +% \begin{macrocode} + \pgfmathsetmacro\hobby@thetaone{-\hobby@psi * \hobby@done% +/(\hobby@done + \hobby@dzero)}% + \pgfmathsetmacro\hobby@thetazero{-\hobby@psi - \hobby@thetaone}% + \let\hobby@phione=\hobby@thetazero + \let\hobby@phitwo=\hobby@thetaone + \else +% \end{macrocode} +% Second or later. +% \begin{macrocode} + \let\hobby@thetazero=\hobby@angle + \pgfmathsetmacro\hobby@thetaone{% + -(2 * \hobby@psi + \hobby@thetazero) * \hobby@done% + / (2 * \hobby@done + \hobby@dzero)}% + \pgfmathsetmacro\hobby@phione{-\hobby@psi - \hobby@thetaone}% + \let\hobby@phitwo=\hobby@thetaone + \fi +% \end{macrocode} +% Save the outgoing angle. +% \begin{macrocode} + \let\hobby@angle=\hobby@thetaone +% \end{macrocode} +% Compute the control points from the angles. +% \begin{macrocode} + \hobby@quick@ctrlpts{\hobby@thetazero}{\hobby@phione}{\hobby@qpoints}{\hobby@qpointa}{\hobby@dzero}{\hobby@omegazero}% +% \end{macrocode} +% Now call the call-back function +% \begin{macrocode} + \edef\hobby@temp{\noexpand\hobby@quick@curveto{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}% +\hobby@temp +% \end{macrocode} +% Cycle the points round for the next iteration. +% \begin{macrocode} + \global\let\hobby@qpoints=\hobby@qpointa + #1 + \xdef\hobby@qpointa{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% +% \end{macrocode} +% Save needed values in global macros +% \begin{macrocode} + \global\let\hobby@angle=\hobby@angle + \global\let\hobby@phitwo=\hobby@phitwo + \global\let\hobby@thetaone=\hobby@thetaone +\global\let\hobby@done=\hobby@done +\global\let\hobby@omegaone=\hobby@omegaone +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@wuick@computeend} +% This is the additional code for the final run. +% \begin{macrocode} +\def\hobby@quick@computeend{% +% \end{macrocode} +% Compute the control points for the second part of the curve and add that to the path. +% \begin{macrocode} + \hobby@quick@ctrlpts{\hobby@thetaone}{\hobby@phitwo}{\hobby@qpoints}{\hobby@qpointa}{\hobby@done}{\hobby@omegaone}% +% \end{macrocode} +% Now call the call-back function +% \begin{macrocode} + \edef\hobby@temp{\noexpand\hobby@quick@curveto{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}% +\hobby@temp +}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@quick@ctrlpts} +% Compute the control points from the angles and points given. +% \begin{macrocode} +\def\hobby@quick@ctrlpts#1#2#3#4#5#6{% + \pgfmathsetmacro\hobby@alpha{% + sqrt(2) * (sin(#1 r) - 1/16 * sin(#2 r))% +* (sin(#2 r) - 1/16 * sin(#1 r))% + * (cos(#1 r) - cos(#2 r))}% + \pgfmathsetmacro\hobby@rho{% + (2 + \hobby@alpha)/(1 + (1 - (3 - sqrt(5))/2)% + * cos(#1 r) + (3 - sqrt(5))/2 * cos(#2 r))}% + \pgfmathsetmacro\hobby@sigma{% + (2 - \hobby@alpha)/(1 + (1 - (3 - sqrt(5))/2)% + * cos(#2 r) + (3 - sqrt(5))/2 * cos(#1 r))}% + #3% + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \pgfmathsetlength\pgf@xa{% + \pgf@xa + #5 * \hobby@rho% + * cos((#1 + #6) r)/3*\hobby@sf}% + \pgfmathsetlength\pgf@ya{% + \pgf@ya + #5 * \hobby@rho% + * sin((#1 + #6) r)/3*\hobby@sf}% + #4% + \pgf@xb=\pgf@x + \pgf@yb=\pgf@y + \pgfmathsetlength\pgf@xb{% + \pgf@xb - #5 * \hobby@sigma% + * cos((-#2 + #6) r)/3*\hobby@sf}% + \pgfmathsetlength\pgf@yb{% + \pgf@yb - #5 * \hobby@sigma% + * sin((-#2 + #6) r)/3*\hobby@sf}% + #4% +} +% \end{macrocode} +% \end{macro} +% +% \iffalse +% +% \fi +% +% \subsection{TikZ Library} +% +% \iffalse +%<*tikzlibrary> +% \fi +% +% \begin{macrocode} +\usepgflibrary{hobby} +\let\hobby@this@opts=\pgfutil@empty +\let\hobby@next@opts=\pgfutil@empty +\let\hobby@action=\pgfutil@empty +\let\hobby@path@name=\pgfutil@empty +\newif\ifhobby@externalise +% \end{macrocode} +% +% We set various TikZ keys. +% These include the \Verb+to path+ constructor and all the various parameters that will eventually get passed to the path-generation code. +% \begin{macrocode} +\def\hobby@point@options{}% +\tikzset{ + curve through/.style={ + to path={ + \pgfextra{ + \expandafter\curvethrough\expandafter[\hobby@next@opts]{% + (\tikztostart) .. #1 .. (\tikztotarget)% + } + } + } + }, + tension in/.code = {% + \expandafter\gdef\expandafter\hobby@point@options\expandafter% + {\hobby@point@options,tension in=#1}% + }, + tension out/.code = {% + \expandafter\gdef\expandafter\hobby@point@options\expandafter% + {\hobby@point@options,tension out=#1}% + }, + tension/.append code = {% + \expandafter\gdef\expandafter\hobby@point@options\expandafter% + {\hobby@point@options,tension=#1}% + }, + excess angle/.code = {% + \expandafter\gdef\expandafter\hobby@point@options\expandafter% + {\hobby@point@options,excess angle=#1}% + }, + break/.code = {% + \expandafter\gdef\expandafter\hobby@point@options\expandafter% + {\hobby@point@options,break=#1}% + }, + blank/.code = {% + \expandafter\gdef\expandafter\hobby@point@options\expandafter% + {\hobby@point@options,blank=#1}% + }, + designated Hobby path/.initial={next}, + clear next Hobby path options/.code={% + \gdef\hobby@next@opts{}% + }, + clear this Hobby path options/.code={% + \gdef\hobby@this@opts{}% + }, + clear Hobby path options/.style={% + clear \pgfkeysvalueof{/tikz/designated Hobby path} Hobby path options + }, + add option to this Hobby path/.code={% + \expandafter\gdef\expandafter\hobby@this@opts\expandafter{\hobby@this@opts#1,}% + }, + add option to next Hobby path/.code={% + \expandafter\gdef\expandafter\hobby@next@opts\expandafter{\hobby@next@opts#1,}% + }, + add option to Hobby path/.style={% + add option to \pgfkeysvalueof{/tikz/designated Hobby path} Hobby path={#1}% + }, + closed/.style = {% + add option to Hobby path={closed=#1,disjoint=#1}% + }, + invert blank/.style = {% + add option to Hobby path={invert blank=#1}% + }, + closed/.default = true, + blank/.default = true, + break/.default = true, + invert blank/.default = true, + in angle/.code = {% + \pgfmathparse{(#1)*pi/180}% + \edef\@temp{in angle=\pgfmathresult,}% + \pgfkeysalso{add option to Hobby path/.expand once=\@temp}% + }, + out angle/.code = {% + \pgfmathparse{(#1)*pi/180}% + \edef\@temp{out angle=\pgfmathresult,}% + \pgfkeysalso{add option to Hobby path/.expand once=\@temp}% + }, + in curl/.style = {% + add option to Hobby path={in curl=#1}% + }, + out curl/.style = {% + add option to Hobby path={out curl=#1}% + }, + use Hobby shortcut/.code={% + \let\tikz@curveto@auto=\hobby@curveto@override + \global\let\hobby@curveto@delegate=\hobby@curveto@auto + }, + use quick Hobby shortcut/.code={% + \let\tikz@curveto@auto=\hobby@curveto@override + \global\let\hobby@curveto@delegate=\hobby@qcurveto@auto + }, + use previous Hobby path/.code={% + \hobbyusepath{#1}% + }, + use previous Hobby path/.default={},% + save Hobby path/.code={% + \xdef\hobby@path@name{#1}% + }, + restore Hobby path/.code={% + \hobbyinit\hobby@tikz@moveto\hobby@tikz@curveto\hobby@tikz@close + \global\let\hobby@collected@onpath\pgfutil@empty + \hobbyrestorepath{#1}% + }, + restore and use Hobby path/.code 2 args={% + \hobbyinit\hobby@tikz@moveto\hobby@tikz@curveto\hobby@tikz@close + \global\let\hobby@collected@onpath\pgfutil@empty + \hobbyrestorepath{#1}% + \hobbyusepath{#2}% + }, + show Hobby path/.code={% + \hobbyshowpath{#1}% + }, + Hobby action/.code={% + \expandafter\gdef\expandafter\hobby@action\expandafter{\hobby@action#1}% + }, + Hobby finish/.style={% + Hobby action=\hobby@finish% + }, + Hobby externalise/.is if=hobby@externalise, + Hobby externalize/.is if=hobby@externalise +} +% \end{macrocode} +% +% \begin{macro}{\hobby@tikz@curveto} +% This is passed to the path-generation code to translate the path into a PGF path. +% \begin{macrocode} +\def\hobby@tikz@curveto#1#2#3{% + \pgfutil@ifundefined{tikz@timer@start}{% + \expandafter\hobby@topgf\expandafter{\hobby@initial@pt}% + \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + }{}% + \hobby@topgf{#1}% + \edef\tikz@timer@cont@one{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \hobby@topgf{#2}% + \edef\tikz@timer@cont@two{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \hobby@topgf{#3}% + \let\tikz@timer=\tikz@timer@curve + \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \ifx\hobby@collected@onpath\pgfutil@empty + \else + \expandafter\hobby@nodes@onpath\hobby@collected@onpath\relax\relax + \fi + \pgfpathcurveto{\hobby@topgf{#1}}{\hobby@topgf{#2}}{\hobby@topgf{#3}}% + \hobby@topgf{#3}% + \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@tikz@moveto} +% This is passed to the path-generation code to translate the path into a PGF path. +% \begin{macrocode} +\def\hobby@tikz@moveto#1#2#3{% + \pgfutil@ifundefined{tikz@timer@start}{% + \expandafter\hobby@topgf\expandafter{\hobby@initial@pt}% + \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + }{}% + \hobby@topgf{#3}% + \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgfutil@empty + \let\tikz@timer=\tikz@timer@line + \expandafter\def\expandafter\hobby@collected@onpath\expandafter{\expandafter{\expandafter}\hobby@collected@onpath} + \else + \hobby@topgf{#1}% + \edef\tikz@timer@cont@one{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \hobby@topgf{#2}% + \edef\tikz@timer@cont@two{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \let\tikz@timer=\tikz@timer@curve + \fi + \ifx\hobby@collected@onpath\pgfutil@empty + \else + \expandafter\hobby@nodes@onpath\hobby@collected@onpath\relax\relax + \fi + \pgfpathmoveto{\hobby@topgf{#3}}% + \hobby@topgf{#3}% + \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@tikz@close} +% Closes a path. +% \begin{macrocode} +\def\hobby@tikz@close#1{% + \hobby@topgf{#1}% + \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \let\tikz@timer=\tikz@timer@line + \ifx\hobby@collected@onpath\pgfutil@empty + \else + \expandafter\hobby@nodes@onpath\hobby@collected@onpath\relax\relax + \fi + \pgfpathclose +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@nodes@onpath} +% \begin{macrocode} +\def\hobby@nodes@onpath#1#2\relax{% + \gdef\hobby@collected@onpath{#2}% + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgfutil@empty + \else + \def\@gtempa{\relax} + \ifx\pgf@temp\@gtempa + \else + \tikz@node@is@a@labeltrue + \tikz@scan@next@command#1\pgf@stop + \tikz@node@is@a@labelfalse + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\curvethrough} +% This is the parent command. +% We initialise the path-generation code, set any parameters, and then hand over control to the point processing macro. +% \begin{macrocode} +\newcommand\curvethrough[2][]{% + \hobbyinit\hobby@tikz@moveto\hobby@tikz@curveto\hobby@tikz@close + \global\let\hobby@collected@onpath\pgfutil@empty + \let\hobby@initial@pt\pgfutil@empty + \hobbysetparams{#1}% + \tikzset{designated Hobby path=this}% + \global\let\hobby@this@opts=\pgfutil@empty + \global\let\hobby@next@opts=\pgfutil@empty + \let\tikz@scan@point@options=\pgfutil@empty + \def\hobby@point@options{}% + \tikz@scan@one@point\hobby@processpt #2 \relax% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@processpt} +% This processes a list of points in the format \Verb+(0,0) [..] (1,1)+. +% Each point is scanned by TikZ and then added to the stack to be built into the path. +% If there are any remaining points, we call ourself again with them. +% Otherwise, we hand over control to the path-generation code. +% \begin{macrocode} +\newcommand\hobby@processpt[1]{% + #1% + \pgfmathsetmacro\hobby@x{\the\pgf@x/1cm}% + \pgfmathsetmacro\hobby@y{\the\pgf@y/1cm}% + \ifx\hobby@initial@pt\pgfutil@empty + \xdef\hobby@initial@pt{\hobby@x, \hobby@y}% + \fi + \expandafter\hobbyaddpoint\expandafter{\hobby@point@options,% + point={\hobby@x, \hobby@y}}% + \def\hobby@point@options{}% + \let\tikz@scan@point@options=\pgfutil@empty + \pgfutil@ifnextchar\relax{% + \expandafter\hobbysetparams\expandafter{\hobby@this@opts}% + \ifhobby@externalise + \ifx\hobby@path@name\pgfutil@empty + \hobbygenusepath + \else + \hobbygenuseifnecpath{\hobby@path@name}% + \fi + \else + \hobbygenusepath + \fi + \ifx\hobby@path@name\pgfutil@empty + \else + \hobbysavepath{\hobby@path@name}% + \fi + \global\let\hobby@path@name=\pgfutil@empty + }{% + \pgfutil@ifnextchar.{% + \hobby@swallowdots}{% + \tikz@scan@one@point\hobby@processpt}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@swallowdots} +% Remove dots from the input stream. +% \begin{macrocode} +\def\hobby@swallowdots.{% + \pgfutil@ifnextchar.{% + \hobby@swallowdots}{% + \tikz@scan@one@point\hobby@processpt}} +% \end{macrocode} +% \end{macro} +% +% There is a ``spare hook'' in the TikZ path processing code. +% If TikZ encounters a path of the form \Verb+(0,0) .. (1,1)+ then it calls a macro \Verb+\tikz@curveto@auto+. +% However, that macro is not defined in the TikZ code. +% The following code provides a suitable definition. +% To play nice, we don't install it by default but define a key (defined above) that installs it. +% +% \begin{macro}{\hobby@curveto@override} +% \begin{macrocode} +\def\hobby@curveto@override{% + \hobby@curveto@delegate} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@curveto@auto} +% When we're called by TikZ, we initialise the path generation code and start adding points. +% To ensure that the generation code is called, we add a lot of hooks to lots of TikZ commands. +% \begin{macrocode} +\def\hobby@curveto@auto{% + \hobbyinit\hobby@tikz@moveto\hobby@tikz@curveto\hobby@tikz@close + \expandafter\gdef\expandafter\hobby@collected@onpath\expandafter{\expandafter{\tikz@collected@onpath} }% + \let\tikz@collected@onpath=\pgfutil@empty + \pgfmathsetmacro\hobby@x{\the\tikz@lastx/1cm}% + \pgfmathsetmacro\hobby@y{\the\tikz@lasty/1cm}% + \xdef\hobby@initial@pt{\hobby@x, \hobby@y}% + \expandafter\hobbysetparams\expandafter{\hobby@next@opts}% + \expandafter\hobbyaddpoint\expandafter{\hobby@point@options,% + point={\hobby@x, \hobby@y} }% + \hobby@init@tikz@commands + \tikzset{designated Hobby path=this}% + \let\tikz@scan@point@options=\pgfutil@empty + \global\let\hobby@action=\pgfutil@empty + \global\let\hobby@this@opts=\pgfutil@empty + \global\let\hobby@next@opts=\pgfutil@empty + \global\let\hobby@point@options=\pgfutil@empty + \tikz@scan@one@point\hobby@addfromtikz% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@addfromtikz} +% This adds our current point to the stack. +% \begin{macrocode} +\def\hobby@addfromtikz#1{% + #1% + \tikz@make@last@position{#1}% + \pgfmathsetmacro\hobby@x{\the\pgf@x/1cm}% + \pgfmathsetmacro\hobby@y{\the\pgf@y/1cm}% + \expandafter\hobbysetparams\expandafter{\hobby@this@opts}% + \expandafter\hobbyaddpoint\expandafter{\hobby@point@options,% + point={\hobby@x, \hobby@y}}% + \hobby@action + \global\let\hobby@this@opts=\pgfutil@empty + \global\let\hobby@action=\pgfutil@empty + \global\let\hobby@point@options=\pgfutil@empty + \tikz@scan@next@command% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@init@tikz@commands} +% \begin{macrocode} +\def\hobby@init@tikz@commands{% + \hobby@init@tikz@modcmd\tikz@movetoabs + \hobby@init@tikz@modcmd\tikz@movetorel + \hobby@init@tikz@modcmd\tikz@lineto + \hobby@init@tikz@modcmd\tikz@rect + \hobby@init@tikz@modcmd\tikz@cchar + \hobby@init@tikz@modcmd\tikz@finish + \hobby@init@tikz@modcmd\tikz@arcA + \hobby@init@tikz@modcmd\tikz@e@char + \hobby@init@tikz@modcmd\tikz@g@char + \hobby@init@tikz@modcmd\tikz@schar + \hobby@init@tikz@modcmd\tikz@vh@lineto + \hobby@init@tikz@modcmd\tikz@pchar + \hobby@init@tikz@modcmd\tikz@to + \hobby@init@tikz@modcmd\pgf@stop + \hobby@init@tikz@modcmd\tikz@decoration + \global\let\hobby@curveto@delegate=\hobby@midcurveto@auto +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@restore@tikz@commands} +% \begin{macrocode} +\def\hobby@restore@tikz@commands{% + \hobby@restore@tikz@modcmd\tikz@movetoabs + \hobby@restore@tikz@modcmd\tikz@movetorel + \hobby@restore@tikz@modcmd\tikz@lineto + \hobby@restore@tikz@modcmd\tikz@rect + \hobby@restore@tikz@modcmd\tikz@cchar + \hobby@restore@tikz@modcmd\tikz@finish + \hobby@restore@tikz@modcmd\tikz@arcA + \hobby@restore@tikz@modcmd\tikz@e@char + \hobby@restore@tikz@modcmd\tikz@g@char + \hobby@restore@tikz@modcmd\tikz@schar + \hobby@restore@tikz@modcmd\tikz@vh@lineto + \hobby@restore@tikz@modcmd\tikz@pchar + \hobby@restore@tikz@modcmd\tikz@to + \hobby@restore@tikz@modcmd\pgf@stop + \hobby@restore@tikz@modcmd\tikz@decoration + \global\let\hobby@curveto@delegate=\hobby@curveto@auto +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@init@tikz@modcmd} +% \begin{macrocode} +\def\hobby@init@tikz@modcmd#1{% + \expandafter\global\expandafter\let\csname hobby@orig@\string#1\endcsname=#1% + \gdef#1{\hobby@finish#1}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@restore@tikz@modcmd} +% \begin{macrocode} +\def\hobby@restore@tikz@modcmd#1{% + \expandafter\global\expandafter\let\expandafter#1\csname hobby@orig@\string#1\endcsname% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@midcurveto@auto} +% \begin{macrocode} +\def\hobby@midcurveto@auto{% + \expandafter\expandafter\expandafter\gdef\expandafter\expandafter\expandafter\hobby@collected@onpath\expandafter\expandafter\expandafter{\expandafter\hobby@collected@onpath\expandafter{\tikz@collected@onpath} }% + \let\tikz@collected@onpath=\pgfutil@empty + \let\tikz@scan@point@options=\pgfutil@empty + \global\let\hobby@action=\pgfutil@empty + \global\let\hobby@this@opts=\pgfutil@empty + \global\let\hobby@point@options=\pgfutil@empty + \tikz@scan@one@point\hobby@addfromtikz% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@finish} +% \begin{macrocode} +\def\hobby@finish{% + \hobby@restore@tikz@commands + \ifhobby@externalise + \ifx\hobby@path@name\pgfutil@empty + \hobbygenusepath + \else + \hobbygenuseifnecpath{\hobby@path@name}% + \fi + \else + \hobbygenusepath + \fi + \ifx\hobby@path@name\pgfutil@empty + \else + \hobbysavepath{\hobby@path@name}% + \fi + \global\let\hobby@path@name=\pgfutil@empty + \tikzset{designated Hobby path=next}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{quick curve through} +% The \Verb+quick curve through+ is a \Verb+to path+ which does the ``quick'' version of Hobby's algorithm. +% The syntax is as with the \Verb+curve through+: to pass the midpoints as the argument to the style. +% We need to pass three points to the auxiliary macro. +% These are passed as \Verb+\hobby@qpoints+, \Verb+\hobby@qpointa+, and the current point. +% Then these get cycled round for the next triple. +% The path gets built up and stored as \Verb+\hobby@quick@path+. +% We also have to remember the angle computed for the next round. +% \begin{macrocode} +\tikzset{ + quick curve through/.style={% + to path={% + \pgfextra{% +% \end{macrocode} +% Scan the starting point and store the coordinates in \Verb+\hobby@qpointa+ +% \begin{macrocode} + \let\hobby@next@qbreak=\relax + \let\hobby@next@qblank=\relax + \tikz@scan@one@point\pgfutil@firstofone(\tikztostart)% + \tikz@make@last@position{\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \edef\hobby@qpoints{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% +% \end{macrocode} +% Blank the path and auxiliary macros. +% \begin{macrocode} + \def\hobby@qpointa{}% + \def\hobby@quick@path{}% + \def\hobby@angle{}% + \let\hobby@quick@curveto=\hobby@quick@makepath +% \end{macrocode} +% Now start parsing the rest of the coordinates. +% \begin{macrocode} + \tikz@scan@one@point\hobby@quickfirst #1 (\tikztotarget)\relax + } +% \end{macrocode} +% Invoke the path +% \begin{macrocode} + \hobby@quick@path + } + }, + quick hobby/blank curve/.is choice, + quick hobby/blank curve/true/.code={% + \gdef\hobby@next@qblank{% + \qhobby@blanktrue + \global\let\hobby@next@qblank=\relax + }% + }, + quick hobby/blank curve/false/.code={% + \gdef\hobby@next@qblank{% + \qhobby@blankfalse + \global\let\hobby@next@qblank=\relax + }% + }, + quick hobby/blank curve/once/.code={% + \gdef\hobby@next@qblank{% + \qhobby@blanktrue + \gdef\hobby@next@qblank{% + \qhobby@blankfalse + \global\let\hobby@next@qblank=\relax + }% + }% + }, + quick hobby/blank curve/.default=true, + quick hobby/break curve/.is choice, + quick hobby/break curve/true/.code={% + \gdef\hobby@next@qbreak{% + \qhobby@breaktrue + \global\let\hobby@next@qbreak=\relax + }% + }, + quick hobby/break curve/false/.code={% + \gdef\hobby@next@qbreak{% + \qhobby@breakfalse + \global\let\hobby@next@qbreak=\relax + }% + }, + quick hobby/break curve/once/.code={% + \gdef\hobby@next@qbreak{% + \qhobby@breaktrue + \gdef\hobby@next@qbreak{% + \qhobby@breakfalse + \global\let\hobby@next@qbreak=\relax + }% + }% + }, + quick hobby/break curve/.default=true, +} +\newif\ifqhobby@break +\newif\ifqhobby@blank +% \end{macrocode} +% \end{macro} +% +% Add plot handlers +% \begin{macrocode} +\tikzoption{hobby}[]{\let\tikz@plot@handler=\pgfplothandlerhobby} +\tikzoption{quick hobby}[]{\let\tikz@plot@handler=\pgfplothandlerquickhobby} +\tikzoption{closed hobby}[]{\let\tikz@plot@handler=\pgfplothandlerclosedhobby} +% \end{macrocode} +% +% \begin{macro}{\hobby@quickfirst} +% The first time around we just set the next point. +% \begin{macrocode} +\def\hobby@quickfirst#1{% + #1% + \xdef\hobby@qpointa{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \tikz@make@last@position{\hobby@qpointa}% +% \end{macrocode} +% Now a check to ensure that we have more points. +% \begin{macrocode} + \pgfutil@ifnextchar\relax{% +% \end{macrocode} +% Ooops, no more points. +% That's not good. +% Bail-out. +% \begin{macrocode} + \xdef\hobby@quick@path{ -- (\the\pgf@x,\the\pgf@y)}% + }{% +% \end{macrocode} +% Okay, have more points. +% Phew. +% Call the next round. +% If we have dots, swallow them. +% \begin{macrocode} + \pgfutil@ifnextchar.{% + \hobby@qswallowdots}{% + \tikz@scan@one@point\hobby@quick}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@qswallowdots} +% Remove dots from the input stream. +% \begin{macrocode} +\def\hobby@qswallowdots.{% + \pgfutil@ifnextchar.{% + \hobby@qswallowdots}{% + \tikz@scan@one@point\hobby@quick}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@quick} +% This is our wrapper function that handles the loop. +% \begin{macrocode} +\def\hobby@quick#1{% + \hobby@quick@compute{#1}% + \tikz@make@last@position{\hobby@qpointa}% + \pgfutil@ifnextchar\relax{% +% \end{macrocode} +% End of loop +% \begin{macrocode} + \hobby@quick@computeend% + }{% +% \end{macrocode} +% More to go, scan in the next coordinate and off we go again. +% \begin{macrocode} + \pgfutil@ifnextchar.{% + \hobby@qswallowdots}{% + \tikz@scan@one@point\hobby@quick}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@quick@makepath} +% Path constructor for \Verb+to path+ use. +% \begin{macrocode} +\def\hobby@quick@makepath#1#2#3{% + #1% + \pgf@xa=\pgf@x\relax + \pgf@ya=\pgf@y\relax + #2% + \pgf@xb=\pgf@x\relax + \pgf@yb=\pgf@y\relax + #3% + \ifqhobby@blank + \xdef\hobby@quick@path{\hobby@quick@path (\the\pgf@x,\the\pgf@y)}% + \else + \xdef\hobby@quick@path{\hobby@quick@path .. controls% + (\the\pgf@xa,\the\pgf@ya) and (\the\pgf@xb,\the\pgf@yb) .. (\the\pgf@x,\the\pgf@y) }% + \fi + \ifqhobby@break + \xdef\hobby@quick@path{\hobby@quick@path +(0,0)}% + \fi + \hobby@next@qbreak + \hobby@next@qblank +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@qcurveto@auto} +% Uses the ``quick'' method for the shortcut syntax. +% \begin{macrocode} +\def\hobby@qcurveto@auto{% + \global\let\hobby@next@qbreak=\relax + \global\let\hobby@next@qblank=\relax + \xdef\hobby@qpoints{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% + \gdef\hobby@qpointa{}% + \gdef\hobby@quick@path{}% + \gdef\hobby@angle{}% + \global\let\hobby@quick@curveto=\hobby@quick@makepathauto + \hobby@qinit@tikz@commands + \let\tikz@scan@point@options=\pgfutil@empty + \global\let\hobby@action=\pgfutil@empty + \global\let\hobby@point@options=\pgfutil@empty + \tikz@scan@one@point\hobby@qfirst@auto} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@qmidcurveto@auto} +% \begin{macrocode} +\def\hobby@qmidcurveto@auto{% + \let\tikz@scan@point@options=\pgfutil@empty + \global\let\hobby@action=\pgfutil@empty + \global\let\hobby@point@options=\pgfutil@empty + \tikz@scan@one@point\hobby@qaddfromtikz} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@qfirst@auto} +% \begin{macrocode} +\def\hobby@qfirst@auto#1{% + #1% + \xdef\hobby@qpointa{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \tikz@make@last@position{\hobby@qpointa}% + \tikz@scan@next@command% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@quick@makepathauto} +% Path constructor for shortcut method to use. +% \begin{macrocode} +\def\hobby@quick@makepathauto#1#2#3{% + #1% + \pgf@xa=\pgf@x\relax + \pgf@ya=\pgf@y\relax + #2% + \pgf@xb=\pgf@x\relax + \pgf@yb=\pgf@y\relax + #3% + \ifqhobby@blank + \edef\hobby@temp{% + \noexpand\pgfpathmoveto{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + }% + \hobby@temp + \else + \edef\hobby@temp{% + \noexpand\pgfpathcurveto{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}% + {\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + }% + \hobby@temp + \fi + \ifqhobby@break + #3% + \edef\hobby@temp{% + \noexpand\pgfpathmoveto{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + }% + \hobby@temp + \fi + \hobby@next@qbreak + \hobby@next@qblank +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@qaddfromtikz} +% This adds our current point to the stack. +% \begin{macrocode} +\def\hobby@qaddfromtikz#1{% + \hobby@quick@compute{#1}% + \tikz@make@last@position{\hobby@qpointa}% + \tikz@scan@next@command% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@qinit@tikz@commands} +% \begin{macrocode} +\def\hobby@qinit@tikz@commands{% + \hobby@qinit@tikz@modcmd\tikz@movetoabs + \hobby@qinit@tikz@modcmd\tikz@movetorel + \hobby@qinit@tikz@modcmd\tikz@lineto + \hobby@qinit@tikz@modcmd\tikz@rect + \hobby@qinit@tikz@modcmd\tikz@cchar + \hobby@qinit@tikz@modcmd\tikz@finish + \hobby@qinit@tikz@modcmd\tikz@arcA + \hobby@qinit@tikz@modcmd\tikz@e@char + \hobby@qinit@tikz@modcmd\tikz@g@char + \hobby@qinit@tikz@modcmd\tikz@schar + \hobby@qinit@tikz@modcmd\tikz@vh@lineto + \hobby@qinit@tikz@modcmd\tikz@pchar + \hobby@qinit@tikz@modcmd\tikz@to + \hobby@qinit@tikz@modcmd\pgf@stop + \hobby@qinit@tikz@modcmd\tikz@decoration + \hobby@qinit@tikz@modcmd\tikz@@close + \global\let\hobby@curveto@delegate=\hobby@qmidcurveto@auto +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@qrestore@tikz@commands} +% \begin{macrocode} +\def\hobby@qrestore@tikz@commands{% + \hobby@restore@tikz@modcmd\tikz@movetoabs + \hobby@restore@tikz@modcmd\tikz@movetorel + \hobby@restore@tikz@modcmd\tikz@lineto + \hobby@restore@tikz@modcmd\tikz@rect + \hobby@restore@tikz@modcmd\tikz@cchar + \hobby@restore@tikz@modcmd\tikz@finish + \hobby@restore@tikz@modcmd\tikz@arcA + \hobby@restore@tikz@modcmd\tikz@e@char + \hobby@restore@tikz@modcmd\tikz@g@char + \hobby@restore@tikz@modcmd\tikz@schar + \hobby@restore@tikz@modcmd\tikz@vh@lineto + \hobby@restore@tikz@modcmd\tikz@pchar + \hobby@restore@tikz@modcmd\tikz@to + \hobby@restore@tikz@modcmd\pgf@stop + \hobby@restore@tikz@modcmd\tikz@decoration + \hobby@restore@tikz@modcmd\tikz@@close + \global\let\hobby@curveto@delegate=\hobby@qcurveto@auto +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@qinit@tikz@modcmd} +% \begin{macrocode} +\def\hobby@qinit@tikz@modcmd#1{% + \expandafter\global\expandafter\let\csname hobby@orig@\string#1\endcsname=#1% + \gdef#1{\hobby@qfinish#1}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby@qfinish} +% \begin{macrocode} +\def\hobby@qfinish{% + \hobby@quick@computeend + \hobby@qrestore@tikz@commands +} +% \end{macrocode} +% \end{macro} + +% \iffalse +% +% \fi +% +% \subsection{Arrays} +% +% \iffalse +%<*array> +% \fi +% +% +% A lot of our data structures are really arrays. +% These are implemented as \LaTeX3 ``property lists''. +% For ease of use, an array is a property list with numeric entries together with entries ``base'' and ``top'' which hold the lowest and highest indices that have been set. +% +% \begin{macrocode} +\RequirePackage{expl3} +\ExplSyntaxOn +% \end{macrocode} +% Some auxiliary variables. +% \begin{macrocode} +\tl_new:N \l_array_tmp_tl +\tl_new:N \l_array_show_tl +\int_new:N \l_array_base_int +\int_new:N \l_array_top_int +\int_new:N \l_array_tmp_int +\int_new:N \g_array_map_int +% \end{macrocode} +% The global variable \Verb+\g_array_base_int+ says what index a blank array should start with when pushed or unshifted. +% \begin{macrocode} +\int_new:N \g_array_base_int +\int_gset:Nn \g_array_base_int {0} +% \end{macrocode} +% \begin{macro}{\array_adjust_ends:Nn} +% This ensures that the ``base'' and ``top'' are big enough to include the given index. +% \begin{macrocode} +\cs_new:Npn \array_adjust_ends:Nn #1#2 { + \prop_get:NnNTF #1 {base} \l_tmpa_tl + { + \int_compare:nNnTF {\l_tmpa_tl} > {#2} + { + \prop_put:Nnx #1 {base} {\int_eval:n {#2}} + } + {} + } + { + \prop_put:Nnx #1 {base} {\int_eval:n {#2}} + } + \prop_get:NnNTF #1 {top} \l_tmpa_tl + { + \int_compare:nNnTF {\l_tmpa_tl} < {#2} + { + \prop_put:Nnx #1 {top} {\int_eval:n {#2}} + } + {} + } + { + \prop_put:Nnx #1 {top} {\int_eval:n {#2}} + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_gadjust_ends:Nn} +% This ensures that the ``base'' and ``top'' are big enough to include the given index. +% (Global version) +% \begin{macrocode} +\cs_new:Npn \array_gadjust_ends:Nn #1#2 { + \prop_get:NnNTF #1 {base} \l_tmpa_tl + { + \int_compare:nNnTF {\l_tmpa_tl} > {#2} + { + \prop_gput:Nnx #1 {base} {\int_eval:n {#2}} + } + {} + } + { + \prop_gput:Nnx #1 {base} {\int_eval:n {#2}} + } + \prop_get:NnNTF #1 {top} \l_tmpa_tl + { + \int_compare:nNnTF {\l_tmpa_tl} < {#2} + { + \prop_gput:Nnx #1 {top} {\int_eval:n {#2}} + } + {} + } + { + \prop_gput:Nnx #1 {top} {\int_eval:n {#2}} + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_put:Nnn} +% When adding a value to an array we have to adjust the ends. +% \begin{macrocode} +\cs_new:Npn \array_put:Nnn #1#2#3 { + \exp_args:NNx \prop_put:Nnn #1 {\int_eval:n {#2}} {#3} + \array_adjust_ends:Nn #1{#2} +} +\cs_generate_variant:Nn \array_put:Nnn {Nnx} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_gput:Nnn} +% When adding a value to an array we have to adjust the ends. +% (Global version) +% \begin{macrocode} +\cs_new:Npn \array_gput:Nnn #1#2#3 { + \exp_args:NNx \prop_gput:Nnn #1 {\int_eval:n {#2}} {#3} + \array_gadjust_ends:Nn #1{#2} +} +\cs_generate_variant:Nn \array_gput:Nnn {Nnx} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_get:NnN} +% \begin{macrocode} +\cs_new:Npn \array_get:NnN #1#2#3 { + \exp_args:NNx \prop_get:NnN #1 {\int_eval:n {#2}} #3 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\array_get:Nn} +% \begin{macrocode} +\cs_new:Npn \array_get:Nn #1#2 { + \exp_args:NNf \prop_item:Nn #1 { \int_eval:n {#2} } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_get:NnNTF} +% \begin{macrocode} +\cs_new:Npn \array_get:NnNTF #1#2#3#4#5 { + \exp_args:NNx \prop_get:NnNTF #1 {\int_eval:n {#2}} #3 {#4}{#5} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_if_empty:NTF} +% \begin{macrocode} +\prg_new_conditional:Npnn \array_if_empty:N #1 { p, T, F, TF } +{ + \if_meaning:w #1 \c_empty_prop + \prg_return_true: + \else: + \prg_return_false: + \fi: +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_if_exist:NTF} +% \begin{macrocode} +\prg_new_eq_conditional:NNn \array_if_exist:N \cs_if_exist:N { p, T, F, TF } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_new:N} +% \begin{macrocode} +\cs_new_eq:NN \array_new:N \prop_new:N +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_clear:N} +% \begin{macrocode} +\cs_new_eq:NN \array_clear:N \prop_clear:N +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_gclear:N} +% \begin{macrocode} +\cs_new_eq:NN \array_gclear:N \prop_gclear:N +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_map_function} +% When stepping through an array, we want to iterate in order so a simple wrapper to \Verb+\prop_map_function+ is not enough. +% This maps through every value from the base to the top so the function should be prepared to deal with a \Verb+\q_no_value+. +% \begin{macrocode} +\cs_new:Npn \array_map_function:NN #1#2 +{ + \array_if_empty:NTF #1 {} { + \prop_get:NnNTF #1 {base} \l_array_tmp_tl { + \int_set:Nn \l_array_base_int {\l_array_tmp_tl} + }{ + \int_set:Nn \l_array_base_int {0} + } + \prop_get:NnNTF #1 {top} \l_array_tmp_tl { + \int_set:Nn \l_array_top_int {\l_array_tmp_tl} + }{ + \int_set:Nn \l_array_top_int {0} + } + \int_step_inline:nnnn {\l_array_base_int} {1} {\l_array_top_int} { + \array_get:NnN #1 {##1} \l_array_tmp_tl + \exp_args:NnV #2 {##1} \l_array_tmp_tl +} +} {} +} +\cs_generate_variant:Nn \array_map_function:NN { Nc } +\cs_generate_variant:Nn \array_map_function:NN { c , cc } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_reverse_map_function} +% This steps through the array in reverse order. +% \begin{macrocode} +\cs_new:Npn \array_reverse_map_function:NN #1#2 +{ + \array_if_empty:NTF #1 {} { + \prop_get:NnNTF #1 {base} \l_array_tmp_tl { + \int_set:Nn \l_array_base_int {\l_array_tmp_tl} + }{ + \int_set:Nn \l_array_base_int {0} + } + \prop_get:NnNTF #1 {top} \l_array_tmp_tl { + \int_set:Nn \l_array_top_int {\l_array_tmp_tl} + }{ + \int_set:Nn \l_array_top_int {0} + } + \int_step_inline:nnnn {\l_array_top_int} {-1} {\l_array_base_int} { + \array_get:NnN #1 {##1} \l_array_tmp_tl + \exp_args:Nno #2 {##1} \l_array_tmp_tl +} +} {} +} +\cs_generate_variant:Nn \array_reverse_map_function:NN { Nc } +\cs_generate_variant:Nn \array_reverse_map_function:NN { c , cc } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_map_inline:Nn} +% Inline version of the above. +% \begin{macrocode} +\cs_new_protected:Npn \array_map_inline:Nn #1#2 + { + \int_gincr:N \g_array_map_int + \cs_gset:cpn { array_map_inline_ \int_use:N \g_array_map_int :nn } + ##1##2 {#2} + \exp_args:NNc \array_map_function:NN #1 + { array_map_inline_ \int_use:N \g_array_map_int :nn } + \prg_break_point:Nn \array_map_break: { \int_gdecr:N \g_array_map_int } + } +\cs_generate_variant:Nn \array_map_inline:Nn { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_reverse_map_inline:Nn} +% Inline version of the above. +% \begin{macrocode} +\cs_new_protected:Npn \array_reverse_map_inline:Nn #1#2 + { + \int_gincr:N \g_array_map_int + \cs_gset:cpn { array_map_inline_ \int_use:N \g_array_map_int :nn } + ##1##2 {#2} + \exp_args:NNc \array_reverse_map_function:NN #1 + { array_map_inline_ \int_use:N \g_array_map_int :nn } + \prg_break_point:Nn \array_map_break: { \int_gdecr:N \g_array_map_int } + } +\cs_generate_variant:Nn \array_reverse_map_inline:Nn { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_map_break:} +% \begin{macrocode} +\cs_new_nopar:Npn \array_map_break: + { \prg_map_break:Nn \array_map_break: { } } +\cs_new_nopar:Npn \array_map_break:n + { \prg_map_break:Nn \array_map_break: } +% \end{macrocode} +% \end{macro} +% +% For displaying arrays, we need some messages. +% \begin{macrocode} +\msg_new:nnn { kernel } { show-array } + { + The~array~\token_to_str:N #1~ + \array_if_empty:NTF #1 + { is~empty } + { contains~the~items~(without~outer~braces): } + } +% \end{macrocode} +% +% \begin{macro}{\array_show:N} +% Mapping through an array isn't expandable so we have to set a token list to its contents first before passing it to the message handler. +% \begin{macrocode} +\cs_new_protected:Npn \array_show:N #1 + { + \__msg_show_variable:NNNnn + #1 + \array_if_exist:NTF + \array_if_empty:NTF + { array } + { \array_map_function:NN #1 \__msg_show_item:nn } + } +\cs_generate_variant:Nn \array_show:N { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_push:Nn} +% \begin{macrocode} +\cs_new_protected:Npn \array_push:Nn #1#2 +{ + \prop_get:NnNTF #1 {top} \l_array_tmp_tl + { + \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} + \int_incr:N \l_array_tmp_int + \array_put:Nnn #1 {\l_array_tmp_int} {#2} + } + { + \array_put:Nnn #1 {\g_array_base_int} {#2} + } +} +\cs_generate_variant:Nn \array_push:Nn {Nx} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_gpush:Nn} +% \begin{macrocode} +\cs_new_protected:Npn \array_gpush:Nn #1#2 +{ + \prop_get:NnNTF #1 {top} \l_array_tmp_tl + { + \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} + \int_incr:N \l_array_tmp_int + \array_gput:Nnn #1 {\l_array_tmp_int} {#2} + } + { + \array_gput:Nnn #1 {\g_array_base_int} {#2} + } +} +\cs_generate_variant:Nn \array_gpush:Nn {Nx} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_unshift:Nn} +% \begin{macrocode} +\cs_new_protected:Npn \array_unshift:Nn #1#2 +{ + \prop_get:NnNTF #1 {base} \l_array_tmp_tl + { + \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} + \int_decr:N \l_array_tmp_int + \array_put:Nnn #1 {\l_array_tmp_int} {#2} + } + { + \array_put:Nnn #1 {\g_array_base_int} {#2} + } +} +\cs_generate_variant:Nn \array_unshift:Nn {Nx} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_gunshift:Nn} +% \begin{macrocode} +\cs_new_protected:Npn \array_gunshift:Nn #1#2 +{ + \prop_get:NnNTF #1 {base} \l_array_tmp_tl + { + \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} + \int_decr:N \l_array_tmp_int + \array_gput:Nnn #1 {\l_array_tmp_int} {#2} + } + { + \array_gput:Nnn #1 {\g_array_base_int} {#2} + } +} +\cs_generate_variant:Nn \array_gunshift:Nn {Nx} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_pop:NN} +% \begin{macrocode} +\cs_new_protected:Npn \array_pop:NN #1#2 +{ + \prop_get:NnN #1 {top} \l_array_tmp_tl + \array_get:NnN #1 {\l_array_tmp_tl} #2 + \array_del:Nn #1 {\l_array_tmp_tl} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_gpop:NN} +% \begin{macrocode} +\cs_new_protected:Npn \array_gpop:NN #1#2 +{ + \prop_get:NnN #1 {top} \l_array_tmp_tl + \array_get:NnN #1 {\l_array_tmp_tl} #2 + \array_gdel:Nn #1 {\l_array_tmp_tl} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_shift:NN} +% \begin{macrocode} +\cs_new_protected:Npn \array_shift:NN #1#2 +{ + \prop_get:NnN #1 {base} \l_array_tmp_tl + \array_get:NnN #1 {\l_array_tmp_tl} #2 + \array_del:Nn #1 {\l_array_tmp_tl} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_gshift:NN} +% \begin{macrocode} +\cs_new_protected:Npn \array_gshift:NN #1#2 +{ + \prop_get:NnN #1 {base} \l_array_tmp_tl + \array_get:NnN #1 {\l_array_tmp_tl} #2 + \array_gdel:Nn #1 {\l_array_tmp_tl} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_top:NN} +% \begin{macrocode} +\cs_new_protected:Npn \array_top:NN #1#2 +{ + \prop_get:NnN #1 {top} \l_array_tmp_tl + \array_get:NnN #1 {\l_array_tmp_tl} #2 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_base:NN} +% \begin{macrocode} +\cs_new_protected:Npn \array_base:NN #1#2 +{ + \prop_get:NnN #1 {base} \l_array_tmp_tl + \array_get:NnN #1 {\l_array_tmp_tl} #2 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_top:N} +% \begin{macrocode} +\cs_new:Npn \array_top:N #1 +{ + \array_get:Nn #1 {\prop_item:Nn #1 {top}} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_base:N} +% \begin{macrocode} +\cs_new:Npn \array_base:N #1 +{ + \array_get:Nn #1 {\prop_item:Nn #1 {base}} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_del:Nn} +% \begin{macrocode} +\cs_new_protected:Npn \array_del:Nn #1#2 +{ + \exp_args:NNx \prop_pop:Nn #1 {\int_eval:n {#2}} + \int_set:Nn \l_array_tmp_int {0} + \array_map_inline:Nn #1 { + \tl_if_eq:NNTF {##2} {\q_no_value} {} + { + \int_incr:N \l_array_tmp_int + } + } + \int_compare:nNnTF {\l_array_tmp_int} = {0} + { + \prop_clear:N #1 + } + { + \prop_get:NnN #1 {top} \l_array_tmp_tl + \int_compare:nNnTF {#2} = {\l_array_tmp_tl} { + \prop_get:NnN #1 {base} \l_array_tmp_tl + \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} + \array_map_inline:Nn #1 { + \tl_if_eq:NNTF {##2} {\q_no_value} {} + { + \int_compare:nNnTF {\l_array_tmp_int} < {##1} { + \int_set:Nn \l_array_tmp_int {##1} + }{} + } + } + \prop_put:Nnx #1 {top} {\int_use:N \l_array_tmp_int} + }{} + \prop_get:NnN #1 {base} \l_array_tmp_tl + \int_compare:nNnTF {#2} = {\l_array_tmp_tl} { + \prop_get:NnN #1 {top} \l_array_tmp_tl + \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} + \array_map_inline:Nn #1 { + \tl_if_eq:NNTF {##2} {\q_no_value} {} + { + \int_compare:nNnTF {\l_array_tmp_int} > {##1} { + \int_set:Nn \l_array_tmp_int {##1} + }{} + } + } + \prop_put:Nnx #1 {base} {\int_use:N \l_array_tmp_int} + }{} + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_gdel:Nn} +% \begin{macrocode} +\cs_new_protected:Npn \array_gdel:Nn #1#2 +{ + \exp_args:NNx \prop_gremove:Nn #1 {\int_eval:n {#2}} + \int_set:Nn \l_array_tmp_int {0} + \array_map_inline:Nn #1 { + \tl_if_eq:NNTF {##2} {\q_no_value} {} + { + \int_incr:N \l_array_tmp_int + } + } + \int_compare:nNnTF {\l_array_tmp_int} = {0} + { + \prop_gclear:N #1 + } + { + \prop_get:NnN #1 {top} \l_array_tmp_tl + \int_compare:nNnTF {#2} = {\l_array_tmp_tl} { + \prop_get:NnN #1 {base} \l_array_tmp_tl + \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} + \array_map_inline:Nn #1 { + \tl_if_eq:NNTF {##2} {\q_no_value} {} + { + \int_compare:nNnTF {\l_array_tmp_int} < {##1} { + \int_set:Nn \l_array_tmp_int {##1} + }{} + } + } + \prop_gput:Nnx #1 {top} {\int_use:N \l_array_tmp_int} + }{} + \prop_get:NnN #1 {base} \l_array_tmp_tl + \int_compare:nNnTF {#2} = {\l_array_tmp_tl} { + \prop_get:NnN #1 {top} \l_array_tmp_tl + \int_set:Nn \l_array_tmp_int {\l_array_tmp_tl} + \array_map_inline:Nn #1 { + \tl_if_eq:NNTF {##2} {\q_no_value} {} + { + \int_compare:nNnTF {\l_array_tmp_int} > {##1} { + \int_set:Nn \l_array_tmp_int {##1} + }{} + } + } + \prop_gput:Nnx #1 {base} {\int_use:N \l_array_tmp_int} + }{} + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\array_length:N} +% \begin{macrocode} +\cs_new_protected:Npn \array_length:N #1 +{ + \int_eval:n {\prop_item:Nn #1 {top} - \prop_item:Nn #1 {base}} +} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% \iffalse +% +% \fi +% +% \iffalse +%<*l3hobby> +% \fi +% +% \begin{macrocode} +\RequirePackage{expl3} +% \end{macrocode} +% +% Load the hobby core +% \begin{macrocode} +\input{hobby.code.tex} +% \end{macrocode} +% +% Register as an expl3 package +% \begin{macrocode} +\ProvidesExplPackage {hobby-l3draw} {2018/02/20} {1.0} {Interface for l3draw and hobby} +% \end{macrocode} +% +% Load the l3draw package +% \begin{macrocode} +\RequirePackage{l3draw} +% \end{macrocode} +% +% +% \begin{macro}{\hobby_draw_moveto:nnn} +% This provides our interface between hobby's moveto and l3draw's moveto +% \begin{macrocode} +\cs_new_protected:Npn \hobby_draw_moveto:nnn #1#2#3 +{ + \draw_path_canvas_moveto:n {#3} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_draw_curveto:nnn} +% This provides our interface between hobby's curveto and l3draw's curveto +% \begin{macrocode} +\cs_set_eq:NN \hobby_draw_curveto:nnn \draw_path_canvas_curveto:nnn +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_draw_close:n} +% This provides our interface between hobby's close and l3draw's close +% \begin{macrocode} +\cs_new_protected:Npn \hobby_draw_close:n #1 +{ + \draw_path_close: +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_draw_addpoint:n} +% This processes a point and passes it one more step towards the hobby algorithm +% \begin{macrocode} +\cs_new_protected:Npn \hobby_draw_addpoint:n #1 +{ + \__draw_point_process:nn + { \__hobby_draw_addpoint:nn } + { \draw_point_transform:n {#1} } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\__hobby_draw_curveto:nn} +% This provides our interface between l3draw's points and hobby's syntax +% \begin{macrocode} +\cs_new_protected:Npn \__hobby_draw_addpoint:nn #1#2 +{ + \hobby_add_point:nnnnnn {#1} {#2} {1} {1} {0} {10} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_draw_init:} +% This initialises hobby's algorithm with the l3draw commands +% \begin{macrocode} +\cs_new_protected:Npn \hobby_draw_init: +{ + \hobby_set_cmds:NNN \hobby_draw_moveto:nnn \hobby_draw_curveto:nnn \hobby_draw_close:n + \hobby_clear_path: +} +% \end{macrocode} +% \end{macro} +% +% \iffalse +% +% \fi +%\Finale diff --git a/graphics/pgf/contrib/hobby/hobby_code.pdf b/graphics/pgf/contrib/hobby/hobby_code.pdf index 9b8f4973b9..f58e42fcfc 100644 Binary files a/graphics/pgf/contrib/hobby/hobby_code.pdf and b/graphics/pgf/contrib/hobby/hobby_code.pdf differ diff --git a/graphics/pgf/contrib/hobby/hobby_doc.tex b/graphics/pgf/contrib/hobby/hobby_doc.tex deleted file mode 100644 index 6e487bfb18..0000000000 --- a/graphics/pgf/contrib/hobby/hobby_doc.tex +++ /dev/null @@ -1,917 +0,0 @@ -\immediate\write18{tex hobby.dtx} -\documentclass{ltxdoc} -\usepackage[T1]{fontenc} -\usepackage{csquotes} -\usepackage{lmodern} -\usepackage{tikz} -\usepackage{pgfplots} -\usepackage{amsmath} -\usepackage{fancyvrb} -\usetikzlibrary{hobby,decorations.pathreplacing} -\usepackage{listings} -\usepackage{hyperref} -\pgfplotsset{compat=1.9} -\lstloadlanguages{[LaTeX]TeX} -\lstset{breakatwhitespace=true,breaklines=true,language=TeX} - -\EnableCrossrefs -\CodelineIndex -\RecordChanges - -\newenvironment{example} - {\VerbatimEnvironment - \begin{VerbatimOut}{example.out}} - {\end{VerbatimOut} - \begin{center} - \setlength{\parindent}{0pt} - \fbox{\begin{minipage}{.9\linewidth} - \lstset{breakatwhitespace=true,breaklines=true,language=TeX,basicstyle=\small} - \lstinputlisting[]{example.out} - \end{minipage}} - \fbox{\begin{minipage}{.9\linewidth} - \centering - \input{example.out} - \end{minipage}} -\end{center} -} - - - -\tikzset{ - show curve controls/.style={ - decoration={ - show path construction, - curveto code={ - \draw [blue, dashed] - (\tikzinputsegmentfirst) -- (\tikzinputsegmentsupporta) - node [at end, draw, solid, red, inner sep=2pt]{}; - \draw [blue, dashed] - (\tikzinputsegmentsupportb) -- (\tikzinputsegmentlast) - node [at start, draw, solid, red, inner sep=2pt]{}; - } - },decorate - }, -} - -%\bibliographystyle{plain} - -\renewcommand{\thefootnote}{\fnsymbol{footnote}} - -\providecommand*{\url}{\texttt} -\title{The \textsf{Hobby} package} -\author{Andrew Stacey \\ \url{loopspace@mathforge.org}} -\date{\hobbyVersion\ from\ \hobbyDate} -\begin{document} -\maketitle - -\section{Introduction} - -John Hobby's algorithm, \cite{MR834054}, produces a curve through a given set of points. -The curve is constructed as a list of cubic B\'ezier curves with endpoints at subsequent points in the list. -The parameters of the curves are chosen so that the joins are ``smooth''. -The algorithm was devised as part of the MetaPost program. - -TikZ/PGF has the ability to draw a curve through a given set of points but its algorithm is somewhat simpler than Hobby's and consequently does not produce as aesthetically pleasing curve as Hobby's algorithm does. -This package implements Hobby's algorithm in \TeX{} so that TikZ/PGF can make use of it and thus produce nicer curves through a given set of points. - -Hobby's algorithm allows for considerable customisation in that it can take into account various parameters. -These are all allowed in this implementation. - -There is also a ``quick'' version presented here. -This is a modification of Hobby's algorithm with the feature that any point only influences a finite number (in fact, two) of the previous segments (in Hobby's algorithm the influence of a point dies out exponentially but never completely). -This is achieved by applying Hobby's algorithm to subpaths. -The resulting path produced with this ``quick'' version is not as ideal as that produced by Hobby's full algorithm, but is still much better than that produced by the \Verb+plot[smooth]+ method in TikZ/PGF, as can be seen in Figure~\ref{fig:comparison}. -As this is intended as a simpler method, it does not (at present) admit the same level of customisation as the full implementation. -The ``quick'' algorithm is described in full in Section~\ref{sec:quick}. - -The full algorithm is implemented in \LaTeX3 with no reference to TikZ or PGF. -It makes extensive use of the \Verb+fp+ and \Verb+prop+ libraries for the computation steps. -The TikZ library is simply a wrapper that takes the user's input, converts it into the right format for the \LaTeX3 code, and then calls that code to generate the path. -The ``quick'' version does not use \LaTeX3 and relies instead on the \Verb+PGFMath+ library for the computation. - - -Figure~\ref{fig:comparison} is a comparison of the three methods. -The red curve is drawn using Hobby's algorithm. -The blue curve is drawn with the \Verb+plot[smooth]+ method from TikZ/PGF. -The green curve uses the ``quick'' version. -Figure~\ref{fig:metapost} compares the implementation with that given by MetaPost. - -\begin{figure} -\centering -\begin{tikzpicture}[scale=.5] -\draw[red,line width=5pt] (0,0) to[curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); -\draw[ultra thick,blue] plot[smooth] coordinates {(0,0) (6,4) (4,9) (1,7) (3,5)}; -\draw[green,line width=2pt] (0,0) to[quick curve through={(6,4) (4,9) (1,7)}] (3,5); -\end{tikzpicture} -\caption{Comparison of the three algorithms} -\label{fig:comparison} -\end{figure} - - -\begin{figure} -\centering -\begin{tikzpicture}[scale=.5] -\draw[scale=.1,postaction=show curve controls,line width=1mm,red] (0,0) -.. controls (26.76463,-1.84543) and (51.4094,14.58441) .. (60,40) -.. controls (67.09875,61.00188) and (59.76253,84.57518) .. (40,90) -.. controls (25.35715,94.01947) and (10.48064,84.5022) .. (10,70) -.. controls (9.62895,58.80421) and (18.80421,49.62895) .. (30,50); -\fill[green] (0,0) circle[radius=2pt] -(6,4) circle[radius=2pt] -(4,9) circle[radius=2pt] -(1,7) circle[radius=2pt] -(3,5) circle[radius=2pt]; -\draw[postaction=show curve controls,thick] (0,0) to[curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); -\begin{scope}[xshift=10cm] -\draw[scale=.1,postaction=show curve controls,line width=1mm,red] (0,0) -.. controls (5.18756,-26.8353) and (60.36073,-18.40036) .. (60,40) -.. controls (59.87714,59.889) and (57.33896,81.64203) .. (40,90) -.. controls (22.39987,98.48387) and (4.72404,84.46368) .. (10,70) -.. controls (13.38637,60.7165) and (26.35591,59.1351) .. (30,50) -.. controls (39.19409,26.95198) and (-4.10555,21.23804) .. (0,0); % -\fill[green] (0,0) circle[radius=2pt] -(6,4) circle[radius=2pt] -(4,9) circle[radius=2pt] -(1,7) circle[radius=2pt] -(3,5) circle[radius=2pt]; -\draw[postaction=show curve controls,thick] (0,0) to[closed,curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); -\end{scope} -\end{tikzpicture} -\caption{Hobby's algorithm in TikZ overlaying the output of MetaPost} -\label{fig:metapost} -\end{figure} - -\section{Usage} -The package is provided in form of a TikZ library. -It can be loaded with -\begin{verbatim} -\usetikzlibrary{hobby} -\end{verbatim} - -\textbf{Warning}: This package makes extensive use of \LaTeX3. -On occasion, updates to \LaTeX3 packages have resulted in this package behaving oddly or not working at all. -The most up to date version of this package can be obtained from the \href{http://bazaar.launchpad.net/~tex-sx/tex-sx/development/files}{TeX-SX Launchpad page} (download \Verb+hobby.dtx+ and run \Verb+tex hobby.dtx+ to generate the files). -Often, such issues are reported on the \href{http://tex.stackexchange.com}{TeX-SX} site and workarounds quickly found so it is worth checking there as well. - -\bigskip - -There are a variety of ways of specifying the data to the algorithm to generate the curve. - -\subsection{As a \textsf{to path}.} - -The key \Verb+curve through={}+ installs a \Verb+to path+ which draws a smooth curve through the given points. -The points should be specified as a list which can be optionally separated by dots. -The purpose of allowing the dots is to make it simpler to switch between the \Verb+to path+ method and the \Verb+shortcut+ method (described in Section~\ref{sec:shortcut}). -However, note that the two methods are not completely synonymous due to how one can specify options so care must still be taken when switching. - -\begin{example} -\begin{tikzpicture}[scale=.5] -\draw (0,0) to[curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); -\end{tikzpicture} -\end{example} - -\begin{example} -\begin{tikzpicture}[scale=.5] -\draw (0,0) to[curve through={(6,4) (4,9) (1,7)}] (3,5); -\end{tikzpicture} -\end{example} - -There is a corresponding key \Verb+quick curve through={}+ which uses the ``quick'' algorithm. -Again, the dots are optional. - -\begin{example} -\begin{tikzpicture}[scale=.5] -\draw (0,0) to[quick curve through={(6,4) .. (4,9) .. (1,7)}] (3,5); -\end{tikzpicture} -\end{example} - -\subsection{The \textsf{shortcut} Method} -\label{sec:shortcut} - -There is also the facility to subvert TikZ's path processor and define curves simply using the \Verb+..+ separator between points. -Note that this relies on something a little special in TikZ: the syntax \Verb+(0,0) .. (2,3)+ is currently detected and processed but there is no action assigned to that syntax. -As a later version of TikZ may assign some action to that syntax, this package makes its override optional via the key \Verb+use Hobby shortcut+ (which can be set globally if so desired). - -\begin{example} -\begin{tikzpicture}[scale=.5,use Hobby shortcut] -\draw (-3,0) -- (0,0) .. (6,4) .. (4,9) .. (1,7) .. (3,5) -- ++(2,0); -\end{tikzpicture} -\end{example} - -\begin{example} -\begin{tikzpicture}[scale=.5,use quick Hobby shortcut] -\draw (-3,0) -- (0,0) .. (6,4) .. (4,9) .. (1,7) .. (3,5) -- ++(2,0); -\end{tikzpicture} -\end{example} - -\subsection{The \textsf{Plot Handler} Method} - -The algorithms can also be used via the \Verb+plot handler+ syntax. -This library registers three plot handlers: \Verb+hobby+, \Verb+closed hobby+, and \Verb+quick hobby+. -The first is an open curve through the points using the full algorithm, the second is a closed curve, and the third uses the quick algorithm (and is thus an open curve). - -\begin{example} -\tikz[smooth] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; - -\tikz[hobby] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; - -\tikz[closed hobby] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; - -\tikz[quick hobby] \draw plot coordinates {(0,0) (1,1) (2,0) (3,1) (2,1) (10:2cm)}; -\end{example} - -This has the side effect that these can be used with the \Verb+pgfplots+ package. -However, the Hobby algorithm is designed to draw a curve in 2D-{}space and does not take into account the fact that when plotting a graph then the two dimensions are treated differently. - -\begin{example} -\begin{tikzpicture} -\begin{axis} -\addplot +[smooth] {rnd}; -\addplot +[hobby] {rnd}; -\end{axis} -\end{tikzpicture} -\end{example} - -\subsection{Basic Level PGF Commands} - -(Suggested by the question \href{http://tex.stackexchange.com/q/159896/86}{How to combine Hobby paths with PGF Basic Layer commands?} on TeX-SX.) - -In some circumstances, it is convenient to bypass TikZ and use more basic PGF commands for building a path. -It is possible to add a path built using Hobby's algorithm in this fashion. -The commands are: - -\begin{itemize} -\item \Verb+\pgfpathhobby+ to initialise the path. -If this is followed by a braced group then the contents of that are taken as options to the algorithm. - -\item \Verb+\pgfpathhobbypt{}+ to add a point to the path. -If this is followed by a braced group then the contents of that are taken as options for that point. - -\item \Verb+\pgfpathhobbyend+ finalises the path. -This applies the algorithm to the set of specified points and adds it to the current path. -\end{itemize} - -\begin{example} -\begin{tikzpicture} -\pgfpathmoveto{\pgfpoint{0}{0}} -\pgfpathlineto{\pgfpoint{1cm}{0}} -\pgfpathhobby{closed=true} -\pgfpathhobbypt{\pgfpoint{1cm}{2cm}}{tension in=2} -\pgfpathhobbypt{\pgfpoint{2cm}{1cm}} -\pgfpathhobbypt{\pgfpoint{3cm}{0cm}} -\pgfpathhobbyend -\pgfusepath{stroke} -\end{tikzpicture} -\end{example} - -\section{Customisation} - -There are various ways to customise the path generated by the Hobby algorithms. -The full algorithm has a variety of parameters which can be varied to produce different paths through the same points. -These vary from specifying that the path be open or closed, to specifying ``tensions'' at each point to change how the path approaches or leaves it. - -\subsection{Algorithm Customisations} - -The main algorithm (i.e., not the ``quick'' variant) can deal with open or closed paths, it is possible to vary the ``tensions'' between the specified points of the paths, and for an open path it is possible to specify the incoming and outgoing angles either directly or via certain ``curl'' parameters. -When using the \Verb+to path+ specification, the parameters can be specified before or after the \Verb+curve through+ key or as options to the coordinates. -When using the \Verb+shortcut+ specification, the parameters can be given on the path or on coordinates. - -On occasion, it is ambiguous which curve an option belongs to. -This is most likely if a coordinate happens to belong to two curves, or if a coordinate is parsed before TikZ knows that it is constructing a curve using this library. -The simplest solution is to move the option to a place where there is no ambiguity. -Other solutions to this problem will be detailed later. - -Let us start with the customisations to the algorithm. - -\begin{itemize} -\item Basic curve. -\begin{example} -\begin{tikzpicture} -\draw[postaction=show curve controls] -(0,0) to[curve through={(1,.5) .. (2,0) .. (3,.5)}] (4,0); -\draw[xshift=5cm,use Hobby shortcut,postaction=show curve controls] -(0,0) .. (1,.5) .. (2,0) .. (3,.5) .. (4,0); -\end{tikzpicture} -\end{example} - -\item The path can be open, as above, or closed. -%% -\begin{example} -\begin{tikzpicture}[scale=.5] -\draw[postaction=show curve controls] -(0,0) to[closed,curve through={(1,.5) .. (2,0) .. (3,.5)}] (4,0); -\draw[xshift=5cm,use Hobby shortcut,postaction=show curve controls] -([closed]0,0) .. (1,.5) .. (2,0) .. (3,.5) .. (4,0); -\end{tikzpicture} -\end{example} - -\item Specifying the angle at which the curve goes \emph{out} and at which it comes \emph{in}. -The angles given are absolute. -\begin{example} -\begin{tikzpicture} -\draw[postaction=show curve controls] -(0,0) to[out angle=0,in angle=180,curve through={(1,.5) .. (2,0) .. (3,.5)}] (4,0); -\draw[xshift=5cm,use Hobby shortcut,postaction=show curve controls] -([out angle=0,in angle=180]0,0) .. (1,.5) .. (2,0) .. (3,.5) .. (4,0); -\end{tikzpicture} -\end{example} - -\item Applying tension as the curve comes in to a point. -\begin{example} -\begin{tikzpicture} -\draw[postaction=show curve controls] -(0,0) to[curve through={(1,.5) .. ([tension in=2]2,0) .. (3,.5)}] (4,0); -\draw[xshift=5cm,use Hobby shortcut,postaction=show curve controls] -(0,0) .. (1,.5) .. ([tension in=2]2,0) .. (3,.5) .. (4,0); -\end{tikzpicture} -\end{example} - -\item Applying the same tension as a curve comes in and goes out of a point. -\begin{example} -\begin{tikzpicture} -\draw[postaction=show curve controls] -(0,0) to[curve through={(1,.5) .. ([tension=2]2,0) .. (3,.5)}] (4,0); -\end{tikzpicture} -\end{example} - -\item Specifying the \emph{curl} parameters. -\begin{example} -\begin{tikzpicture} -\draw[postaction=show curve controls] -(0,0) to[in curl=.1,out curl=3,curve through={(1,.5) .. (2,0) .. (3,.5)}] (4,0); -\draw[xshift=5cm,use Hobby shortcut,postaction=show curve controls] -(0,0) .. ([in curl=.1,out curl=3]1,.5) .. (2,0) .. (3,.5) .. (4,0); -\end{tikzpicture} -\end{example} -\end{itemize} - -\subsection{Edge Cases} - -Angles are constrained to lie in the interval \((-\pi,\pi]\). -This can introduce edge cases as there is a point where we have to compare an angle with \(-\pi\) and if it is equal, add \(2 \pi\). -This will occur if the path ``doubles back'' on itself as in the next example. -By nudging the repeated point slightly, the behaviour changes drastically. - -\begin{example} -\begin{tikzpicture}[use Hobby shortcut] -\draw (0,0) .. (1,0) .. (0,0) .. (0,-1); -\draw[xshift=2cm] (0,0) .. (1,0) .. (0,0.1) .. (0,-1); -\draw[xshift=4cm] (0,0) .. (1,0) .. (0,-0.1) .. (0,-1); -\end{tikzpicture} -\end{example} - -Due to the precision of the computations, it is not possible to always get this test correct. -The simplest solution is to nudge the repeated point in one direction or the other. -Experimenting shows that the ``nudge factor'' can be extremely small (note that it will be proportional to the distance between the specified points). -It is best to nudge it in the direction most normal to the line between the specified points as the goal is to nudge the difference of the angles. -An alternative solution is to add an additional point for the curve to go through. -\begin{example} -\begin{tikzpicture}[use Hobby shortcut] -\draw (0,0) .. (1,0) .. (0,0) .. (0,-1); -\draw[xshift=2cm] (0,0) .. (1,0) .. (0,0.002) .. (0,-1); -\draw[xshift=4cm] (0,0) .. (1,0) .. (0,-0.002) .. (0,-1); -\end{tikzpicture} -\end{example} - -Lastly, it is possible to add an \Verb+excess angle+ key to a coordinate. -This will add the corresponding multiple of \(2\pi\) to the angle difference. -\begin{example} -\begin{tikzpicture}[use Hobby shortcut] -\draw (0,0) .. (1,0) .. (0,0) .. (0,-1); -\draw[xshift=2cm] (0,0) .. ([excess angle=1]1,0) .. (0,0) .. (0,-1); -\draw[xshift=4cm] (0,0) .. ([excess angle=-1]1,0) .. (0,0) .. (0,-1); -\end{tikzpicture} -\end{example} - -Although this is intended to be an integer, no check is done and so some quite odd curves can result from changing this parameter. - -\subsection{Reusing Paths} - -Although the (full) algorithm has good theoretical computation time, using \TeX\ for its implementation does not provide for fast runs. -The externalisation library of TikZ/PGF can be used to save whole pictures, but it can be useful to save a generated path within a single \Verb+tikzpicture+ for later use within that same picture. -The implementation allows for this by separating the generation of the path from its use. - -\begin{example} -\begin{tikzpicture} -\draw[line width=3mm,red,use Hobby shortcut,save Hobby path={saved}] (0,0) .. (1,1) .. (2,0); -\draw[xshift=2cm,ultra thick,yellow] (0,0) [restore and use Hobby path={saved}{}]; -\end{tikzpicture} -\end{example} -% - -Note that the key \Verb+restore and use Hobby path+ is given \emph{after} the initial \Verb+(0,0)+. -This is because by default the path generated by the Hobby algorithm does not start with an explicit \Verb+moveto+ since that is the standard behaviour of all of PGF's path construction macros. -So the \Verb+(0,0)+ ensures that our path is well-{}formed by issuing an initial \Verb+moveto+. -An alternative would be to use the key \Verb+disjoint+ which does add an initial \Verb+moveto+. - -\begin{example} -\begin{tikzpicture} -\draw[line width=3mm,red,use Hobby shortcut,save Hobby path={saved}] (0,0) .. (1,1) .. (2,0); -\draw[xshift=2cm,ultra thick,yellow,restore and use Hobby path={saved}{disjoint}]; -\end{tikzpicture} -\end{example} -% - -An example of where this is useful is in drawing knot diagrams. -When so doing, it is sometimes convenient to draw a path (or segment of a path) twice in order to get the under/over crossings correct. -For this situation, it can be useful to designate certain parts of the path as \Verb+blank+, whereby we mean to redraw them later. -The point of a blank segment of a curve is that it is still taken into account when computing the algorithm but is left blank when it comes to rendering. -A path can then be redrawn with the blank/non-{}blank segments reversed. -As it might be desired to have only some blank segments drawn the second time, there are two types of blank. -Only a \Verb+soft+ blank will be reversed in these circumstances. - -\begin{example} -\begin{tikzpicture}[use Hobby shortcut,line width=1mm,rotate=90] -\draw[blue,save Hobby path={left}] - ([out angle=90,in angle=-90]1,0) .. (1,1) .. ([blank=soft]0,2) .. (1,3) .. (1,4); -\draw[red] ([out angle=90,in angle=-90]0,0) .. (0,1) .. (1,2) .. (0,3) .. (0,4); -\draw[blue,restore and use Hobby path={left}{disjoint,invert soft blanks}]; -\end{tikzpicture} -\end{example} -% - -This can be taken a step further. -The generated data can be saved to the \Verb+aux+ file and read back in, avoiding the need to regenerate it on each run. -To engage this facility, the Hobby path has to be named (via \Verb+save Hobby path+) and the key \Verb+Hobby externalise+ (or \Verb+Hobby externalize+) must be given in a context that applies (such as on the path or on the surrounding scope). - -\bigskip - - -The relevant keys are the following. - -\begin{itemize} -\item \Verb+use previous Hobby path[=]+. -This (re)uses the previously generated Hobby path. -As all the data is globally stored, this can technically be in a different \Verb+tikzpicture+. -The \Verb++ will be applied, in so far as they are options that can be applied after the algorithm has run. - -\item \Verb+save Hobby path=+. -Saves a path for later use. -The path is saved in a global macro so can be reused in another picture. - -\item \Verb+restore Hobby path=+. -This restores the named Hobby path (if it exists). -It does not \emph{use} it. -After this key, \Verb+use previous Hobby path+ will use the restored path. - -\item \Verb+restore and use Hobby path={}{}+. -This restores the named path and uses it with \Verb++ applied. - -\item \Verb+Hobby externalise+ or \Verb+Hobby externalize+. -This puts in place the code for saving the generated data to the \Verb+aux+ file. -On subsequent runs, it uses the saved data rather than the current data. -For a curve to make use of this, it has to be named via the \Verb+save Hobby path+ key. -So to regenerate the data, either delete the \Verb+aux+ file, remove the \Verb+save Hobby path+ key for one compilation run, or issue the command \Verb+\HobbyDisableAux+ which disables writing paths to the \Verb+aux+ file (note that the paths will be regenerated on the run \emph{after} the first run with this command issued). -\end{itemize} - -The options that can be applied are those that affect the rendering of the curve but not its generation. -When the curve is rendered (or \emph{used}, in the above parlance), \TeX\ steps along the coordinates of the generated curve and carries out an action for each piece. -This action can be modified after the curve has been generated. -The action will be one of: -% -\begin{itemize} -\item Move to the end point (ignoring the control points). -\item Draw a Bezier curve to the end point through the control points. -\item Draw a Bezier curve to the end point through the control points and then move to the end point. -\end{itemize} -% -The last is subtle: the move doesn't actually go anywhere but it ``breaks'' the curve at the designated point. -In particular, a later \Verb+cycle+ would return to this point (or a later break) rather than to the start of the curve. - -These actions are triggered by the keys \Verb+blank+ and \Verb+break+. -Each should be specified to the coordinate at the \emph{end} of the segment under consideration. -The \Verb+blank+ key can be given the argument \Verb+soft+. -The effect of this is seen when the key \Verb+invert soft blanks+ is used. -This swaps the drawing action so that non-{}blank segments are skipped and \emph{soft} blanks are drawn. -Non-{}soft-{}blank segments are still not drawn. - -\begin{example} -\begin{tikzpicture}[use Hobby shortcut] -\draw (0,0) .. (1,1) .. ([blank=soft]2,0) .. (3,1) .. ([blank]4,0) .. (5,1); -\draw[red,use previous Hobby path={invert soft blanks,disjoint}]; -\end{tikzpicture} -\end{example} -% - -As a more practical application, consider the following rendering of a trefoil knot. - -\begin{example} -\begin{tikzpicture}[ - use Hobby shortcut, - every path/.style={ - line width=1mm, - white, - double=red, - double distance=.5mm - } -] -\draw ([closed]0,2) .. ([blank=soft]210:.5) .. (-30:2) .. -([blank=soft]0,.5) .. (210:2) .. ([blank=soft]-30:.5); -\draw[use previous Hobby path={invert soft blanks,disjoint}]; -\end{tikzpicture} -\end{example} -% - -This could easily be generalised using the \Verb+\foreach+ command, as demonstrated in the next code. - -\begin{example} -\begin{tikzpicture}[ - use Hobby shortcut, - every path/.style={ - line width=1mm, - white, - double=red, - double distance=.5mm - } -] -\def\nfoil{9} -\draw ([closed]0,2) -\foreach \k in {1,...,\nfoil} { - .. ([blank=soft]90+360*\k/\nfoil-180/\nfoil:-.5) .. (90+360*\k/\nfoil:2) -}; -\draw[use previous Hobby path={invert soft blanks,disjoint}]; -\end{tikzpicture} -\end{example} -% - -\subsection{Breaking the Path} - -One issue with the shortcut notation is that it is not possible (using this notation) to have two sets of curves following directly on from each other because there is no clear demarcation of the boundary. -To make this possible, there is a key \Verb+Hobby action+, which installs an action to be taken after the point has been processed. -The general key \Verb+Hobby action={code}+ can install arbitrary code. -Probably the more useful variant is \Verb+Hobby finish+ which runs the algorithm on the points gathered so far. -An example of the use of this is to make it possible to specify tangencies at certain points. -Technically, once a tangent direction has been specified, the Hobby algorithm splits the set of points there and works on each piece separately. -The following key implements this, the technicalities are due to the fact that the tangent angle has to be used twice: once to specify the angle of the path coming in to that point and once to specify the angle of the path coming out. -Note that specifying the tangent vector at every point means that the algorithm is not actually being used. -However, Hobby's formulae for the lengths of the control points is still being used. - -\begin{example} -\begin{tikzpicture}[ - use Hobby shortcut, - tangent/.style={% - in angle={(180+#1)}, - Hobby finish, - designated Hobby path=next, - out angle=#1, - }, -] -\draw[help lines] (-5,-5) grid (5,5); -\draw (-5,0) -- (5,0) (0,-5) -- (0,5); -\draw[thick] (-5,2) .. ([tangent=0]-3,3) .. (-1,1) .. (0,-1.3) .. % -([tangent=0]1,-2) .. ([tangent=45]2,-1.5) .. ([tangent=0]3,-2) .. (5,-4); -\end{tikzpicture} -\end{example} -% - - - -\section{Implementing Hobby's Algorithm} -We start with a list of \(n+1\) points, \(z_0, \dotsc, z_n\). -The base code assumes that these are already stored in two arrays\footnote{Arrays are thinly disguised property lists.}: the \(x\)--coordinates in \Verb+\l_hobby_points_x_array+ and the \(y\)--coordinates in \Verb+\l_hobby_points_y_array+. -As our arrays are \(0\)--indexed, the actual number of points is one more than this. -For a closed curve, we have \(z_n = z_0\)\footnote{Note that there is a difference between a closed curve and an open curve whose endpoints happen to overlap.}. -For closed curves it will be convenient to add an additional point at \(z_1\): thus \(z_{n+1} = z_1\). -This makes \(z_n\) an internal point and makes the algorithms for closed paths and open paths agree longer than they would otherwise. -The number of apparent points is stored as \Verb+\l_hobby_npoints_int+. -Thus for an open path, \Verb+\l_hobby_npoints_int+ is \(n\), whilst for a closed path, it is \(n+1\)\footnote{In fact, we allow for the case where the user specifies a closed path but with \(z_n \ne z_0\). -In that case, we assume that the user meant to repeat \(z_0\). -This adds another point to the list.}. -Following Hobby, let us write \(n'\) for \(n\) if the path is open and \(n+1\) if closed. -From this we compute the distances and angles between successive points, storing these again as arrays. -These are \Verb+\l_hobby_distances_array+ and \Verb+\l_hobby_angles_array+. -The term indexed by \(k\) is the distance (or angle) of the line between the \(k\)th point and the \(k+1\)th point. -For the internal nodes\footnote{Hobby calls the specified points \emph{knots}.}, we store the difference in the angles in \Verb+\l_hobby_psi_array+. -The \(k\)th value on this is the angle subtended at the \(k\)th node. -This is thus indexed from \(1\) to \(n'-1\). -The bulk of the work consists in setting up a linear system to compute the angles of the control points. -At a node, say \(z_i\), we have various pieces of information: -\begin{enumerate} -\item The angle of the incoming curve, \(\phi_i\), relative to the straight line from \(z_{i-1}\) to \(z_i\) -\item The angle of the outgoing curve, \(\theta_i\), relative to the straight line from \(z_i\) to \(z_{i+1}\) -\item The tension of the incoming curve, \(\overline{\tau}_i\) -\item The tension of the outgoing curve, \(\tau_i\) -\item The speed of the incoming curve, \(\sigma_i\) -\item The speed of the outgoing curve, \(\rho_i\) -\end{enumerate} -The tensions are known at the start. -The speeds are computed from the angles. -Thus the key thing to compute is the angles. -This is done by imposing a ``mock curvature'' condition. -The formula for the mock curvature is: -%% -\[ -\hat{k}(\theta,\phi,\tau,\overline{\tau}) = \tau^2 \left( \frac{2(\theta + \phi)}{\overline{\tau}} - 6\theta\right) -\] -%% -and the condition that the mock curvatures have to satisfy is that at each \emph{internal} node, the curvatures must match: -% -\[ -\hat{k}(\phi_i,\theta_{i-1},\overline{\tau}_i,\tau_{i-1})/d_{i-1} = \hat{k}(\theta_i,\phi_{i+1},\tau_i,\overline{\tau}_{i+1})/d_i. -\] -%% -Substituting in yields: -%% -\[ -\frac{\overline{\tau}_i^2}{d_{i-1}} \left( \frac{2(\phi_i + \theta_{i-1})}{\tau_{i-1}} - 6\phi_i\right) = \frac{\tau_i^2}{d_i} \left( \frac{2(\theta_i + \phi_{i+1})}{\overline{\tau}_{i+1}} - 6\theta_i \right). -\] -%% -Let us rearrange that to the following: -%% -\begin{align*} -d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 &\theta_{i-1} \\ -%% -{}+ -d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (1 - 3 \tau_{i-1}) &\phi_i \\ -%% -{}- -d_{i-1} \tau_{i-1} \tau_i^2 (1 - 3 \overline{\tau}_{i+1}) &\theta_i \\ -%% -{}- -d_{i-1} \tau_{i-1} \tau_i^2 &\phi_{i+1} \\ -%% -&\qquad = -0 -\end{align*} -%% -For both open and closed paths this holds for \(i=1\) to \(i=n' - 1\). -We also have the condition that \(\theta_i + \phi_i = -\psi_i\) where \(\psi_i\) is the angle subtended at a node by the lines to the adjacent nodes. -This holds for the internal nodes\footnote{Recall that by dint of repetition, all nodes are effectively internal for a closed path.}. -Therefore for \(i=1\) to \(n'-1\) the above simplifies to the following: -% -\begin{align*} -d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 &\theta_{i-1} \\ -{}+ -(d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (3 \tau_{i-1} - 1) -{}+ -d_{i-1} \tau_{i-1} \tau_i^2 (3 \overline{\tau}_{i+1} - 1)) &\theta_i \\ -{}+ -d_{i-1} \tau_{i-1} \tau_i^2 & \theta_{i+1} \\ -= -- d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (3 \tau_{i-1} - 1) &\psi_i \\ -{}- d_{i-1} \tau_{i-1} \tau_i^2& \psi_{i+1} -\end{align*} -For an open path we have two more equations. -One involves \(\theta_0\). -The other is the above for \(i = n'-1 = n-1\) with additional information regarding \(\psi_n\). -It may be that one or either of \(\theta_0\) or \(\phi_n\) is specified in advance. -If so, we shall write the given values with a bar: \(\overline{\theta}_0\) and \(\overline{\phi}_n\). -In that case, the first equation is simply setting \(\theta_0\) to that value and the last equation involves substituting the value for \(\phi_n\) into the above. -If not, they are given by formulae involving ``curl'' parameters \(\chi_0\) and \(\chi_n\) and result in the equations: -% -\begin{align*} -\theta_0 &= \frac{\tau_0^3 + \chi_0 \overline{\tau}_1^3(3 \tau_0 - 1)}{\tau_0^3(3 \overline{\tau}_1 - 1) + \chi_0 \overline{\tau}_1^3} \phi_1 \\ -\phi_n &= \frac{\overline{\tau}_n^3 + \chi_n \tau_{n-1}^3(3 \overline{\tau}_n - 1)}{\overline{\tau}_n^3(3 \tau_{n-1} - 1) + \chi_n \tau_{n-1}^3} \theta_{n-1} -\end{align*} -%% -Using \(\phi_1 = - \psi_1 - \theta_1\), the first rearranges to: -%% -\[ -(\tau_0^3(3 \overline{\tau}_1 - 1) + \chi_0 \overline{\tau}_1^3) \theta_0 + (\tau_0^3 + \chi_0 \overline{\tau}_1^3(3 \tau_0 - 1)) \theta_1 = - (\tau_0^3 + \chi_0 \overline{\tau}_1^3(3 \tau_0 - 1)) \psi_1. -\] -%% -The second should be substituted in to the general equation with \(i = n-1\). -This yields: -%% -\begin{align*} -d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 &\theta_{n-2} \\ -{}+ -\big(d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 (3 \tau_{n-2} - 1) -{}+ -d_{n-2} \tau_{n-2} \tau_{n-1}^2 (3 \overline{\tau}_{n} - 1) \\ -{}- d_{n-2} \tau_{n-2} \tau_{n-1}^2 \frac{\overline{\tau}_n^3 + \chi_n \tau_{n-1}^3(3 \overline{\tau}_n - 1)}{\overline{\tau}_n^3(3 \tau_{n-1} - 1) + \chi_n \tau_{n-1}^3}\big) & \theta_{n-1} \\ -= -- d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 (3 \tau_{n-2} - 1) &\psi_{n-1} -\end{align*} -%% -This gives \(n'\) equations in \(n'\) unknowns (\(\theta_0\) to \(\theta_{n-1}\)). -The coefficient matrix is tridiagonal. -It is more natural to index the entries from \(0\). -Let us write \(A_i\) for the subdiagonal, \(B_i\) for the main diagonal, and \(C_i\) for the superdiagonal. -Let us write \(D_i\) for the target vector. -Then for an open path we have the following formulae: -%% -\begin{align*} -A_i &= d_i \overline{\tau}_{i+1} \overline{\tau}^2_i \\ -B_0 &= \begin{cases} -1 & \text{if}\; \overline{\theta}_0\; \text{given} \\ -\tau_0^3(3 \overline{\tau}_1 - 1) + \chi_0 \overline{\tau}^3_1 & \text{otherwise} -\end{cases} \\ -B_i &= d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (3 \tau_{i-1} -1) + d_{i-1} \tau_{i-1} \tau_i^2(3 \overline{\tau}_{i+1} - 1) \\ -B_{n-1} &= \begin{cases} d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 (3 \tau_{n-2} - 1) + d_{n-2} \tau_{n-2} \tau_{n-1}^2(3 \overline{\tau}_{n} - 1) & \text{if}\; \overline{\phi}_n\; \text{given} \\ -d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 (3 \tau_{n-2} - 1) + d_{n-2} \tau_{n-2} \tau_{n-1}^2(3 \overline{\tau}_{n} - 1) -\\ -- d_{n-2} \tau_{n-2} \tau_{n-1}^2 \frac{\overline{\tau}_n^3 + \chi_n \tau_{n-1}^3(3 \overline{\tau}_n - 1)}{\overline{\tau}_n^3(3 \tau_{n-1} - 1) + \chi_n \tau_{n-1}^3}) & \text{otherwise} -\end{cases} \\ -C_0 &= \begin{cases} -0 & \text{if}\; \overline{\theta}_0\; \text{given} \\ -\tau_0^3 + \chi_0 \overline{\tau}_1^3(3\tau_0 - 1) & \text{otherwise} -\end{cases} \\ -C_i &= d_{i-1} \tau_{i-1} \tau_i^2 \\ -D_0 &= \begin{cases} -\overline{\theta}_0 & \text{if}\; \overline{\theta}_0\; \text{given} \\ -- (\tau_0^3 + \chi_0 \overline{\tau}_1^3(3 \tau_0 - 1)) \psi_1 & \text{otherwise} -\end{cases} \\ -D_i &= - d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (3 \tau_{i-1} - 1) \psi_i -- d_{i-1} \tau_{i-1} \tau_i^2 \psi_{i+1} \\ -D_{n-1} &= \begin{cases} -- d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 (3 \tau_{n-2} - 1) \psi_{n-1} - d_{n-2} \tau_{n-2} \tau_{n-1}^2 \overline{\phi}_n & \text{if}\; \overline{\phi}_n\; \text{given} \\ -- d_{n-1} \overline{\tau}_{n} \overline{\tau}_{n-1}^2 (3 \tau_{n-2} - 1) \psi_{n-1} & \text{otherwise} -\end{cases} -\end{align*} -For a closed path, we have \(n\) equations in \(n+2\) unknowns (\(\theta_0\) to \(\theta_{n+1}\)). -However, we have not included all the information. -Since we have repeated points, we need to identify \(\theta_0\) with \(\theta_n\) and \(\theta_1\) with \(\theta_{n+1}\). -To get a system with \(n'\) equations in \(n'\) unknowns, we add the equation \(\theta_0 - \theta_n = 0\) and substitute in \(\theta_{n+1} = \theta_1\). -The resulting matrix is not quite tridiagonal but has extra entries on the off-corners. -However, it can be written in the form \(M + u v^\top\) with \(M\) tridiagonal. -There is some freedom in choosing \(u\) and \(v\). -For simplest computation, we take \(u = e_0 + e_{n'-1}\). -This means that \(v = d_{n'-2} \tau_{n'-2} \tau_{n'-1}^2 e_1 - e_{n'-1}\). -With the same notation as above, the matrix \(M\) is given by the following formulae: -%% -\begin{align*} -A_i &= d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 \\ -%% -B_0 &= 1 \\ -%% -B_i &= d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (3 \tau_{i-1} -1) + d_{i-1} \tau_{i-1} \tau_i^2(3 \overline{\tau}_{i+1} - 1) \\ -%% -B_{n'-1} &= d_{n'-1} \overline{\tau}_{n'} \overline{\tau}_{n'-1}^2 (3 \tau_{n'-2} -1) + d_{n'-2} \tau_{n'-2} \tau_{n'-1}^2(3 \overline{\tau}_{n'} - 1) + 1\\ -%% -C_0 &= - d_{n'-2} \tau_{n'-2} \tau_{n'-1}^2 \\ -%% -C_i &= d_{i-1} \tau_{i-1} \tau_i^2 \\ -%% -D_0 &= 0 \\ -%% -D_i &= - d_i \overline{\tau}_{i+1} \overline{\tau}_i^2 (3 \tau_{i-1} - 1) \psi_i -- d_{i-1} \tau_{i-1} \tau_i^2 \psi_{i+1} \\ -%% -D_{n'-1} &= - d_{n'-1} \overline{\tau}_{n'} \overline{\tau}_{n'-1}^2 (3 \tau_{n'-2} - 1) \psi_{n'-1} -- d_{n'-2} \tau_{n'-2} \tau_{n'-1}^2 \psi_1 -\end{align*} -The next step in the implementation is to compute these coefficients and store them in appropriate arrays. -Having done that, we need to solve the resulting tridiagonal system. -This is done by looping through the arrays doing the following substitutions (starting at \(i = 1\)): -% -\begin{align*} -B_i' &= B_{i-1}' B_i - A_i C_{i-1}' \\ -C_i' &= B_{i-1}' C_i \\ -D_i' &= B_{i-1}' D_i - A_i D_{i-1}' -\end{align*} -%% -followed by back-substitution: -%% -\begin{align*} -\theta_{n-1} &= D_{n-1}'/B_{n-1}' \\ -\theta_i &= (D_i' - C_i' \theta_{i+1})/B_i' -\end{align*} -%% -For a closed path, we run this both with the vector \(D\) and the vector \(u = e_0 + e_{n'-1}\). -Then to get the real answer, we use the Sherman--{}Morrison formula: -%% -\[ -(M + u v^\top)^{-1} D = M^{-1} D - \frac{M^{-1} u v^\top M^{-1} D}{1 + v^\top M^{-1} u}. -\] -%% -This leaves us with the values for \(\theta_i\). -We now substitute these into Hobby's formulae for the lengths: -%% -\begin{align*} -\rho_i &= \frac{2 + \alpha_i}{1 + (1 - c) \cos \theta_i + c \cos \phi_{i+1}} \\ -\sigma_{i+1} &= \frac{2 - \alpha_i}{1 + (1 - c) \cos \phi_{i+1} + c \cos \theta_i} \\ -\text{where} \;\alpha_i &= a (\sin \theta_i - b \sin \phi_{i+1})(\sin \phi_{i+1} - b \sin \theta_i)(\cos \theta_i - \cos \phi_{i+1}) -\end{align*} -%% -and \(a = \sqrt{2}\), \(b = 1/16\), and \(c = (3 - \sqrt{5})/2\). -These are actually the \emph{relative} lengths so need to be adjusted by a factor of \(d_i/3\). -Now \(\theta_i\) is the angle relative to the line from \(z_i\) to \(z_{i+1}\), so to get the true angle we need to add back that angle. -Fortunately, we stored those angles at the start. -So the control points are: -%% -\begin{gather*} -d_i \rho_i (\cos (\theta_i + \omega_i), \sin (\theta_i + \omega_i))/3 + z_i \\ -- d_i \sigma_{i+1} (\cos(\omega_i - \phi_{i+1}), \sin(\omega_i - \phi_{i+1}))/3 + z_{i+1} -\end{gather*} - -\section{A Piecewise Version of Hobby's Algorithm} -\label{sec:quick} -Here we present a variant of Hobby's algorithm. -One difficulty with Hobby's algorithm is that it works with the path as a whole. -It is therefore not possible to build up a path piecewise. -We therefore modify it to correct for this. -Obviously, the resulting path will be less ``ideal'', but will have the property that adding new points will not affect earlier segments. -The method we use is to employ Hobby's algorithm on two-{}segment subpaths. -When applied to a two-{}segment subpath, the algorithm provides two cubic Bezier curves: one from the \(k\)th point to the \(k+1\)st point and the second from the \(k+1\)st to the \(k+2\)nd. -Of this data, we keep the first segment and use that for the path between the \(k\)th and \(k+1\)st points. -We also remember the outgoing angle of the first segment and use that as the incoming angle on the next computation (which will involve the \(k+1\)st, \(k+2\)nd, and \(k+3\)rd points). -The two ends are slightly different to the middle segments. -On the first segment, we might have no incoming angle. -On the last segment, we render both pieces. -This means that for the initial segment, we have a \(2 \times 2\) linear system: -%% -\[ -\begin{bmatrix} -B_0 & C_0 \\ -A_1 & B_1 -\end{bmatrix} -\Theta = \begin{bmatrix} -D_0 \\ D_1 -\end{bmatrix} -\] -%% -This has solution: -%% -\[ -\Theta = \frac{1}{B_0 B_1 - C_0 A_1} \begin{bmatrix} B_1 & - C_0 \\ -A_1 & B_0 \end{bmatrix} \begin{bmatrix} D_0 \\ D_1 \end{bmatrix} = \frac{1}{B_0 B_1 - C_0 A_1} \begin{bmatrix} B_1 D_0 - C_0 D_1 \\ B_0 D_1 - A_1 D_0 \end{bmatrix} -\] -Now we have the following values for the constants: -%% -\begin{align*} -A_1 &= d_1 \overline{\tau}_2 \overline{\tau}_1^2 \\ -%% -B_0 &= \tau_0^3 (3 \overline{\tau}_1 - 1) + \chi_0 \overline{\tau}_1^3 \\ -%% -B_1 &= d_1 \overline{\tau}_2 \overline{\tau}_1^2 (3 \tau_0 - 1) + d_0 \tau_0 \tau_1^2(3 \overline{\tau}_2 - 1) - d_0 \tau_0 \tau_1^2 \frac{\overline{\tau}_2^3 + \chi_2 \tau_1^3 (3 \overline{\tau}_2 - 1)}{\overline{\tau}_2^3 (3 \tau_1 - 1) + \chi_2 \tau_1^3} \\ -%% -C_0 &= \tau_0^3 + \chi_0 \overline{\tau}_1^3 (3 \tau_0 - 1) \\ -%% -D_0 &= - (\tau_0^3 + \chi_0 \overline{\tau}_1^3 ( 3 \tau_0 - 1)) \psi_1 \\ -%% -D_1 &= - d_1 \overline{\tau}_2 \overline{\tau}_1^2 (3 \tau_0 - 1) \psi_1 -\end{align*} - -Let us, as we are aiming for simplicity, assume that the tensions and curls are all \(1\). -Then we have \(A_1 = d_1\), \(B_0 = 3\), \(B_1 = 2 d_1 + 2 d_0 - d_0 = 2 d_1 + d_0\), \(C_0 = 3\), \(D_0 = - 3 \psi_1\), \(D_1 = - 2 d_1 \psi_1\). -Thus the linear system is: -%% -\[ -\begin{bmatrix} -3 & 3 \\ -d_1 & 2 d_1 + d_0 -\end{bmatrix} -\Theta = - \psi_1 \begin{bmatrix} -3 \\ 2 d_1 -\end{bmatrix} -\] -%% -which we can row reduce to: -%% -\[ -\begin{bmatrix} -1 & 1 \\ -0 & d_1 + d_0 -\end{bmatrix} -\Theta = -\psi_1 \begin{bmatrix} -1 \\ d_1 -\end{bmatrix} -\] -%% -whence \(\theta_1 = -\psi_1 \frac{d_1}{d_0 + d_1}\) and \(\theta_0 = -\psi_1 - \theta_1 = -\psi_1\frac{d_0 }{d_0 + d_1}\). -We also compute \(\phi_1 = -\psi_1 - \theta_1 = \theta_0\) and \(\phi_2 = \theta_1\) (in the simple version). -We use \(\theta_0\) and \(\phi_1\) to compute the bezier curve of the first segment, make a note of \(\theta_1\), and -- assuming there are more segments -- throw away \(\phi_2\). - -For the inner segments, we have the system: -%% -\[ -\begin{bmatrix} -1 & 0 \\ -A_1 & B_1 -\end{bmatrix} -\Theta = \begin{bmatrix} -\theta_0 \\ -D_1 -\end{bmatrix} -\] -%% -which has the solution \(\theta_1 = (D_1 - A_1 \theta_0)/B_1\). -The values of the constants in this case are: -%% -\begin{align*} -A_1 &= d_1 \overline{\tau}_2 \overline{\tau}_1^2 \\ -%% -B_1 &= d_1 \overline{\tau}_2 \overline{\tau}_1^2 (3 \tau_0 - 1) + d_0 \tau_0 \tau_1^2(3 \overline{\tau}_2 - 1) - d_0 \tau_0 \tau_1^2 \frac{\overline{\tau}_2^3 + \chi_2 \tau_1^3 (3 \overline{\tau}_2 - 1)}{\overline{\tau}_2^3 (3 \tau_1 - 1) + \chi_2 \tau_1^3} \\ -%% -D_1 &= - d_1 \overline{\tau}_2 \overline{\tau}_1^2 (3 \tau_0 - 1) \psi_1 -\end{align*} -Again, let us consider the simpler case. -Then \(A_1 = d_1\), \(B_1 = 2 d_1 + d_0\), and \(D_1 = - 2 d_1 \psi_1\). -Thus \(\theta_1 = (-2 d_1 \psi_1 - d_1 \theta_0)/(2 d_1 + d_0) = - (2 \psi_1 + \theta_0) \frac{d_1}{2 d_1 + d_0}\). -We compute \(\phi_1 = -\psi_1 - \theta_1 = \frac{- \psi_1 d_0 + \theta_0 d_1}{2 d_1 + d_0}\) and \(\phi_2 = \theta_1\). -Then we store \(\theta_1\) for the next iteration. - -The actual curves are then produced from the angles using the same formulae for the lengths of the control points as in the main algorithm. - -At the last stage, we render both segments of the generated curve. - -\section{Acknowledgements} - -This package began life as an answer to the question \href{http://tex.stackexchange.com/q/54771/86}{Curve through a sequence of points with Metapost and TikZ}. -Once released upon the unsuspecting world, various questions on the \href{http://tex.stackexchange.com}{TeX-SX} site have prompted new features (and bug-fixes). -Most of these can be found by looking at the \href{http://tex.stackexchange.com/questions/tagged/hobby}{list of questions tagged ``hobby''} on that site. - - -\begin{thebibliography}{1} \bibitem{MR834054} John~D. Hobby. \newblock Smooth, easy to compute interpolating splines. \newblock {\em Discrete Comput. Geom.}, 1:123--140, 1986. \end{thebibliography} - -\end{document} diff --git a/macros/latex/contrib/jwjournal/README.md b/macros/latex/contrib/jwjournal/README.md index 4114691820..996d0376a0 100644 --- a/macros/latex/contrib/jwjournal/README.md +++ b/macros/latex/contrib/jwjournal/README.md @@ -65,10 +65,10 @@ And there are only three major syntaxes for the main text: The space(s) between `[Note]` and the text following it would be ignored. > You may also use `【` and `】`, which is especially useful when writing Chinese. 3) Displayed images can be included via one of the following ways: - - `|| [] {}`: show image in the middle. - - `(( [] {}`: show image on the left. - - `)) [] {}`: show image on the right. - > The `[]` is optional. Here `` is a number like `0.75`, the unit is `\linewidth`. When `[]` is not given, the width would be full `\linewidth`. + - `|| <⟨width⟩> {⟨image file name⟩}` or `|| {⟨image file name⟩} <⟨width⟩>`: show image in the middle. + - `(( <⟨width⟩> {⟨image file name⟩}` or `(( {⟨image file name⟩} <⟨width⟩>`: show image on the left. + - `)) <⟨width⟩> {⟨image file name⟩}` or `)) {⟨image file name⟩} <⟨width⟩>`: show image on the right. + > The `<⟨width⟩>` is optional. Here `⟨width⟩` is a number like `0.75`, the unit is `\linewidth`. When `<⟨width⟩>` is not given, the width would be full `\linewidth`. With a few more for icing on the cake: - `|`: The first vertical bar would be interpreted as `\hfill`. This allows you to write the title line as @@ -96,7 +96,7 @@ With a few more for icing on the cake: >> (Some remark) >> (Another remark) ``` -- `->` and `<-`: Skip or retrieve certain vertical space, by default half of `\baselineskip`. You may specify the exact spacing in the unit of `\baselineskip`: for example, `-> [0.3]` would be skipping `0.3\baselineskip`, while `<- [.75]` means retrieving `0.75\baselineskip`. +- `->` and `<-`: Skip or retrieve certain vertical space, by default half of `\baselineskip`. You may specify the exact spacing in the unit of `\baselineskip`: for example, `-> <0.3>` would be skipping `0.3\baselineskip`, while `<- <.75>` means retrieving `0.75\baselineskip`. - `+++`: If a single sentence or a few words fall to the next page, you may write a `+++` before that entry to enlarge the current page by one line. > You may write this `+++` several times if necessary, but do make sure that the number of the `+` sign is a multiple of 3. - `===`: Three or more equal signs `=` would simply be ignored. This is for improving the readability of the code, allowing you to write your journal like: diff --git a/macros/latex/contrib/jwjournal/jwjournal-demo-cn.tex b/macros/latex/contrib/jwjournal/jwjournal-demo-cn.tex index 81647136b9..5ed5d23589 100644 --- a/macros/latex/contrib/jwjournal/jwjournal-demo-cn.tex +++ b/macros/latex/contrib/jwjournal/jwjournal-demo-cn.tex @@ -19,14 +19,14 @@ 图片这可以这样引入: - || [.4] {example-image-a} + || <.4> {example-image-a} % 或者 || {example-image-a} <.4> >> (图片的注释) >> (更多注释) 也可以靠左或者靠右显示: - (( [.4] {example-image-a} - -> [.3] % 加入一点竖直间距,例如这里是 0.3\baselineskip - )) [.4] {example-image-a} + (( <.4> {example-image-a} % 或者 (( {example-image-a} <.4> + -> <.3> % 加入一点竖直间距,例如这里是 0.3\baselineskip + )) <.4> {example-image-a} % 或者 )) {example-image-a} <.4> diff --git a/macros/latex/contrib/jwjournal/jwjournal-demo-en.tex b/macros/latex/contrib/jwjournal/jwjournal-demo-en.tex index f0b85fc484..5a5d8740c9 100644 --- a/macros/latex/contrib/jwjournal/jwjournal-demo-en.tex +++ b/macros/latex/contrib/jwjournal/jwjournal-demo-en.tex @@ -16,14 +16,14 @@ Images can be included via: - || [.4] {example-image-a} + || <.4> {example-image-a} % or || {example-image-a} <.4> >> (Remark on the image) >> (More remark...) You may also show the image on the left or on the right: - (( [.4] {example-image-a} - -> [.3] % add some vertical spacing, here is 0.3\baselineskip - )) [.4] {example-image-a} + (( <.4> {example-image-a} % or (( {example-image-a} <.4> + -> <.3> % add some vertical spacing, here is 0.3\baselineskip + )) <.4> {example-image-a} % or )) {example-image-a} <.4> diff --git a/macros/latex/contrib/jwjournal/jwjournal-demo-fr.tex b/macros/latex/contrib/jwjournal/jwjournal-demo-fr.tex index d8c6413bc8..865402e254 100644 --- a/macros/latex/contrib/jwjournal/jwjournal-demo-fr.tex +++ b/macros/latex/contrib/jwjournal/jwjournal-demo-fr.tex @@ -18,14 +18,14 @@ Les images peuvent être incluses via : - || [.4] {example-image-a} + || <.4> {example-image-a} % ou || {example-image-a} <.4> >> (Remarque sur l'image) >> (Plus de remarque...) Vous pouvez également afficher l'image à gauche ou à droite : - (( [.4] {example-image-a} - -> [.3] % ajouter un certain espace vertical, ici c'est 0.3\baselineskip - )) [.4] {example-image-a} + (( <.4> {example-image-a} % ou (( {example-image-a} <.4> + -> <.3> % ajouter un certain espace vertical, ici c'est 0.3\baselineskip + )) <.4> {example-image-a} % ou )) {example-image-a} <.4> diff --git a/macros/latex/contrib/jwjournal/jwjournal.cls b/macros/latex/contrib/jwjournal/jwjournal.cls index f7d1da7f64..bf03993158 100644 --- a/macros/latex/contrib/jwjournal/jwjournal.cls +++ b/macros/latex/contrib/jwjournal/jwjournal.cls @@ -12,7 +12,7 @@ \NeedsTeXFormat{LaTeX2e}[2022-06-01] \ProvidesExplClass {jwjournal} - {2023/08/29} {} + {2023/08/30} {} {JW's journal class} \keys_define:nn { jwjournal } @@ -119,15 +119,17 @@ \end{description} } -\NewDocumentCommand \JWJournalSkip { O{.5} } +\NewDocumentCommand \JWJournalSkip { D<>{.5} } { % \vspace{#1\baselineskip} - \vskip#1\baselineskip + % \vskip#1\baselineskip + \par\vspace{#1\baselineskip} } -\NewDocumentCommand \JWJournalBack { O{.5} } +\NewDocumentCommand \JWJournalBack { D<>{.5} } { % \vspace{-#1\baselineskip} - \vskip-#1\baselineskip + % \vskip-#1\baselineskip + \par\vspace{-#1\baselineskip} } \newenvironment{JWJournalCompactCenter} @@ -148,22 +150,61 @@ #1 \end{JWJournalCompactCenter} } -\NewDocumentCommand \JWJournalShowImageCenter { O{1} m } +\NewDocumentCommand \JWJournalShowImageCenter { D<>{*} m D<>{*} } { + \str_if_eq:nnTF { #1 } { * } + { + \str_if_eq:nnTF { #3 } { * } + { + \tl_set:Nn \l_tmpa_tl { 1 } + } + { + \tl_set:Nn \l_tmpa_tl { #3 } + } + } + { + \tl_set:Nn \l_tmpa_tl { #1 } + } \begin{JWJournalCenter} - \includegraphics[width=#1\linewidth]{#2} + \includegraphics[width= \tl_use:N \l_tmpa_tl \linewidth]{#2} \end{JWJournalCenter} } -\NewDocumentCommand \JWJournalShowImageLeft { O{1} m } +\NewDocumentCommand \JWJournalShowImageLeft { D<>{*} m D<>{*} } { + \str_if_eq:nnTF { #1 } { * } + { + \str_if_eq:nnTF { #3 } { * } + { + \tl_set:Nn \l_tmpa_tl { 1 } + } + { + \tl_set:Nn \l_tmpa_tl { #3 } + } + } + { + \tl_set:Nn \l_tmpa_tl { #1 } + } \begin{JWJournalLeft} - \includegraphics[width=#1\linewidth]{#2} + \includegraphics[width= \tl_use:N \l_tmpa_tl \linewidth]{#2} \end{JWJournalLeft} } -\NewDocumentCommand \JWJournalShowImageRight { O{1} m } +\NewDocumentCommand \JWJournalShowImageRight { D<>{*} m D<>{*} } { + \str_if_eq:nnTF { #1 } { * } + { + \str_if_eq:nnTF { #3 } { * } + { + \tl_set:Nn \l_tmpa_tl { 1 } + } + { + \tl_set:Nn \l_tmpa_tl { #3 } + } + } + { + \tl_set:Nn \l_tmpa_tl { #1 } + } \begin{JWJournalRight} - \includegraphics[width=#1\linewidth]{#2} + \includegraphics[width= \tl_use:N \l_tmpa_tl \linewidth]{#2} \end{JWJournalRight} } @@ -193,14 +234,66 @@ { ={3,} } { } \l_jwjournal_tmp_tl + + \regex_match:nVT { ❄️ \ *? -> } \l_jwjournal_tmp_tl + { + \regex_match:nVTF { ❄️ \ *? -> \ *? < [\+\-\ ]*(\d+|\d*\.\d+)\ * > } \l_jwjournal_tmp_tl + { + \exp_args:Nno \regex_extract_once:nnN + { ❄️ \ *? -> \ *? < ([\+\-\ ]*(?:\d+|\d*\.\d+)\ *) > } + { \l_jwjournal_tmp_tl } + \l_tmpa_seq + \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl + \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl + \tl_gput_right:Nn \g_jwjournal_content_tl { \JWJournalSkip } + \tl_gput_right:Nx \g_jwjournal_content_tl { < \l_tmpa_tl > } + \regex_replace_once:nnN + { ❄️ \ *? -> \ *? < (?:[\+\-\ ]*(?:\d+|\d*\.\d+)\ *) > (.*) } + { ❄️ \1 } + \l_jwjournal_tmp_tl + } + { + \tl_gput_right:Nn \g_jwjournal_content_tl { \JWJournalSkip } + \regex_replace_once:nnN + { ❄️ \ *? -> \ *? (.*) } + { ❄️ \1 } + \l_jwjournal_tmp_tl + } + } \regex_replace_all:nnN { -> } { \c{JWJournalSkip} } \l_jwjournal_tmp_tl + \regex_match:nVT { ❄️ \ *? <- } \l_jwjournal_tmp_tl + { + \regex_match:nVTF { ❄️ \ *? <- \ *? < [\+\-\ ]*(\d+|\d*\.\d+)\ * > } \l_jwjournal_tmp_tl + { + \exp_args:Nno \regex_extract_once:nnN + { ❄️ \ *? <- \ *? < ([\+\-\ ]*(?:\d+|\d*\.\d+)\ *) > } + { \l_jwjournal_tmp_tl } + \l_tmpa_seq + \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl + \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl + \tl_gput_right:Nn \g_jwjournal_content_tl { \JWJournalBack } + \tl_gput_right:Nx \g_jwjournal_content_tl { < \l_tmpa_tl > } + \regex_replace_once:nnN + { ❄️ \ *? <- \ *? < (?:[\+\-\ ]*(?:\d+|\d*\.\d+)\ *) > (.*) } + { ❄️ \1 } + \l_jwjournal_tmp_tl + } + { + \tl_gput_right:Nn \g_jwjournal_content_tl { \JWJournalBack } + \regex_replace_once:nnN + { ❄️ \ *? <- \ *? (.*) } + { ❄️ \1 } + \l_jwjournal_tmp_tl + } + } \regex_replace_all:nnN { <- } { \c{JWJournalBack} } \l_jwjournal_tmp_tl + \regex_replace_all:nnN { \|\| } { \c{JWJournalShowImageCenter} } @@ -213,6 +306,7 @@ { \)\) } { \c{JWJournalShowImageRight} } \l_jwjournal_tmp_tl + \regex_replace_once:nnN { \| } { \c{hfill} } @@ -228,8 +322,7 @@ % \l_jwjournal_tmp_tl \exp_args:Nno \regex_split:nnN { >> } { \l_jwjournal_tmp_tl } \l_tmpa_seq \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl - \tl_clear:N \l_jwjournal_tmp_tl - \tl_put_right:NV \l_jwjournal_tmp_tl \l_tmpa_tl + \tl_set_eq:NN \l_jwjournal_tmp_tl \l_tmpa_tl \seq_map_inline:Nn \l_tmpa_seq { \tl_put_right:Nn \l_jwjournal_tmp_tl diff --git a/macros/latex/contrib/mathastext/README.md b/macros/latex/contrib/mathastext/README.md index b008e82276..59ebf89913 100644 --- a/macros/latex/contrib/mathastext/README.md +++ b/macros/latex/contrib/mathastext/README.md @@ -10,11 +10,11 @@ This Work may be distributed and/or modified under the conditions of the [LPPL1.3c](http://www.latex-project.org/lppl/lppl-1-3c.txt) -The Author of this Work is Jean-Francois Burnol +The Author of this Work is Jean-Francois Burnol (`jfbu at free dot fr`) -Copyright (C) 2011-2019, 2022 Jean-Francois Burnol (`jfbu at free dot fr`) +Copyright (C) 2011-2016, 2018, 2019, 2022, 2023 Jean-Francois Burnol - Source: mathastext.dtx 1.3y 2022/11/04 + Source: mathastext.dtx 1.3z 2023/09/01 DESCRIPTION @@ -82,6 +82,12 @@ Main options: `italic`, `subdued`, `LGRgreek`. RECENT CHANGES ============== +1.3z \[2023/09/01\] +---- + +Fix 1.3y regression which broke `selfGreek` option due to internal +renamings. Thanks to Stephan Korell for report. + 1.3y \[2022/11/04\] ---- diff --git a/macros/latex/contrib/mathastext/mathastext.dtx b/macros/latex/contrib/mathastext/mathastext.dtx index c95ca043e5..0bc64214ab 100644 --- a/macros/latex/contrib/mathastext/mathastext.dtx +++ b/macros/latex/contrib/mathastext/mathastext.dtx @@ -1,9 +1,9 @@ -% -*- coding: iso-latin-1; time-stamp-format: "%02d-%02m-%:y at %02H:%02M:%02S %Z" -*- +% -*- coding: iso-latin-1; time-stamp-format: "%02d-%02m-%:y at %02H:%02M:%02S %Z"; time-stamp-active: nil -*- % N.B.: this dtx file does NOT use \DocInput, it only uses docstrip. % The LaTeX source of the documentation is NOT prefixed with %'s. %<*dtx> -\def\dtxtimestamp {Time-stamp: <04-11-2022 at 12:36:29 CET>} -\def\docdate{2022/11/04} +\def\dtxtimestamp {Time-stamp: <30-08-2023 at 21:41:24 CEST>} +\def\docdate{2023/09/01} % To extract run etex on this file, then to build documentation run % latexmk on mathastext.tex then dvipdfmx on the dvi. % For more information see http://jf.burnol.free.fr/v13/INSTALL.txt @@ -11,8 +11,8 @@ % due to usage of () as an active character. % %<*drv> -\def\MSTpkgdate {2022/11/04} -\def\MSTpkgversion {1.3y} +\def\MSTpkgdate {2023/09/01} +\def\MSTpkgversion {1.3z} % %<*dtx> \iffalse % meta-comment @@ -30,11 +30,11 @@ This Work may be distributed and/or modified under the conditions of the [LPPL1.3c](http://www.latex-project.org/lppl/lppl-1-3c.txt) -The Author of this Work is Jean-Francois Burnol +The Author of this Work is Jean-Francois Burnol (`jfbu at free dot fr`) -Copyright (C) 2011-2019, 2022 Jean-Francois Burnol (`jfbu at free dot fr`) +Copyright (C) 2011-2016, 2018, 2019, 2022, 2023 Jean-Francois Burnol - Source: mathastext.dtx 1.3y 2022/11/04 + Source: mathastext.dtx 1.3z 2023/09/01 % %<*dtx> @@ -44,9 +44,10 @@ Copyright (C) 2011-2019, 2022 Jean-Francois Burnol (`jfbu at free dot fr`) %%---------------------------------------------------------------- %% Package: mathastext %% Info: Use the text font in math mode (JFB) -%% Version: 1.3y 2022/11/04 +%% Version: 1.3z 2023/09/01 %% License: LPPL 1.3c (http://www.latex-project.org/lppl/lppl-1-3c.txt) -%% Copyright (C) 2011-2019, 2022 Jean-Francois Burnol +%% Copyright (C) 2011-2016, 2018, 2019, 2022, 2023 Jean-Francois Burnol +%% %% Examples of use of mathastext: %% http://jf.burnol.free.fr/mathastext.html %% http://jf.burnol.free.fr/showcase.html @@ -199,6 +200,12 @@ MATHASTEXT CHANGE LOG % %<*readme|changelog> +1.3z \[2023/09/01\] +---- + +Fix 1.3y regression which broke `selfGreek` option due to internal +renamings. Thanks to Stephan Korell for report. + 1.3y \[2022/11/04\] ---- @@ -1413,7 +1420,7 @@ $\mathnormal{ff}$, $\mathrm{ff}$, $\mathit{ff}$, $\mathbf{ff}$, $\mathtt{ff}$ %<*dtx> ^^Afi^^Aendgroup % end of big \iffalse block including generated files % customization should be done in mathastext.tex, not here. -\documentclass[abstract]{scrartcl} +\documentclass{scrartcl} \makeatletter %%% START OF CUSTOM doc.sty LOADING (May 21, 2022 in xint.dtx) %%% (October 29, 2022 here, comments trimmed) @@ -1533,8 +1540,10 @@ $\mathnormal{ff}$, $\mathrm{ff}$, $\mathit{ff}$, $\mathbf{ff}$, $\mathtt{ff}$ \SetSymbolFont{largesymbols}{bold}{OMX}{txex}{bx}{n} \DeclareFontSubstitution{OMX}{txex}{m}{n} -% in order to cancel the removal done by ltxdoc -% of comment characters inside verbatim blocks. +% in order to cancel the removal of comment characters +% inside verbatim blocks caused by doc.sty's redefinition +% of \@verbatim (a macro which is not used by tagging code, +% by the way) \makeatletter\let\check@percent\relax\makeatother \usepackage{color} @@ -1546,15 +1555,13 @@ $\mathnormal{ff}$, $\mathrm{ff}$, $\mathit{ff}$, $\mathbf{ff}$, $\mathtt{ff}$ \usepackage[hscale=0.66]{geometry} -\usepackage[pdfencoding=pdfdoc]{hyperref} +\usepackage{hyperref} \hypersetup{linktoc=all,% -%hidelinks,% colorlinks=true,% -breaklinks=true,% linkcolor={blue},% urlcolor={joli}, -pdfauthor={Jean-Fran\c cois Burnol},% +pdfauthor={Jean-Franois Burnol},% pdftitle={The mathastext package},% pdfsubject={LaTeX, math fonts},% pdfkeywords={LaTeX, Fonts},% @@ -1580,7 +1587,7 @@ pdfpagemode=UseOutlines,% % plus loin \@jfendshrtverb \catcode`\=13 \makeatletter -\def{\begingroup +\def{\leavevmode\begingroup \let\do\@makeother\dospecials \@jfendshrtverb } \def\@jfendshrtverb #1#2{\hyperref[#2]{\ttfamily\hyphenchar\font=127 #1#2}\endgroup} @@ -1591,13 +1598,14 @@ pdfpagemode=UseOutlines,% {mathastext}\xspace} \let\oldexists\exists\let\oldforall\forall - +\let\originalbullet\bullet \usepackage[subdued,% asterisk,% defaultmathsizes,% symbolmisc,symbolre,% LGRgreek]{mathastext} - +\let\symbolbullet\bullet +\let\bullet\originalbullet % This version will use the mlmodern font which is current % last loaded font package in preamble \Mathastext[upright] @@ -2335,7 +2343,7 @@ reasons of PDF file size.}% \subsection{Main options} - \subsubsection{The \blueit{italic} option} + \subsubsection[The italic option]{The \blueit{italic} option} In the initial version |1.0|, the Latin letters in mathematical mode assumed the exact same shape as in @@ -2363,7 +2371,7 @@ traditional French mathematical typography.\footnote{more precisely stated, the value of \cs{shapedefault} is used.} -\subsubsection{The \blueit{defaultmathsizes} option} +\subsubsection[The defaultmathsizes option]{The \blueit{defaultmathsizes} option} The default sizes give for subscripts of subscripts barely legible glyphs (author's opinion!). So \mst makes more reasonable choices. It also @@ -2371,7 +2379,7 @@ redefines \cs{Huge} and defines a \cs{HUGE} size, copied from the |moresize| package. To cancel all of this use option defaultmathsizes. -\subsubsection{The \blueit{subdued} option}\label{sec:subdued} +\subsubsection[The subdued option]{The \blueit{subdued} option}\label{sec:subdued} This option was introduced in |v1.15|.\RightNote{1.15} It provides a manner to switch on the \mst-\emph{ification} only for limited portions of @@ -2446,7 +2454,7 @@ the subdued \mst will pick them up in the same font as used for operator names, which for example in the case of the \emph{euler} package, is the main document font. -\subsubsection{The \blueit{LGRgreek} option} +\subsubsection[The LGRgreek option]{The \blueit{LGRgreek} option} There is the issue of Greek letters. Sometimes the text font has Greek glyphs, in |LGR| encoding% @@ -2531,7 +2539,7 @@ text. \begin{document} \end{verbatim} -\subsubsection{using \mst with \href{https://ctan.org/pkg/beamer}{beamer}}\label{ssec:beamer} +\subsubsection[using \mst with beamer]{using \mst with \href{https://ctan.org/pkg/beamer}{beamer}}\label{ssec:beamer} %\noindent\llap{\textcolor{green}{\bfseries 2015/02/26}\hspace{1em}} @@ -2590,7 +2598,7 @@ with release |3.34| of \href{https://ctan.org/pkg/beamer}{beamer}% |LY1|. \end{framed} -\subsubsection{using \mst with \href{https://ctan.org/pkg/frenchmath}{frenchmath}}\label{ssec:frenchmath} +\subsubsection[using \mst with frenchmath]{using \mst with \href{https://ctan.org/pkg/frenchmath}{frenchmath}}\label{ssec:frenchmath} To use \mst concurrently with the \href{https://ctan.org/pkg/frenchmath}{frenchmath} package% @@ -3254,11 +3262,12 @@ correction:\par \rlap{\texttt{text italic in math}}\break $abcdefghijklmnopqrstuvwxyz$\hfill \rlap{\texttt{math italic in math}}\break - {\usefont{OML}{cmm}{m}{it}abcdefghijklmnopqrstuvwxyz}\hfill + {\usefont{OML}{mlmm}{m}{it}abcdefghijklmnopqrstuvwxyz}\hfill \rlap{\texttt{math italic in text}}\par} Where are our italic corrections gone? the last line -was done with \cs{usefont\{OML\}\{lmm\}\{m\}\{it\}} and confirms that italic -corrections have been used for the math italic in math. +was done with \cs{usefont\{OML\}\{mlmm\}\{m\}\{it\}} and the +line before that using math mode is longer and confirms that italic +corrections have been used for the math italic in math mode. Turning to the \TeX book (and its Appendix G) we learn that in such circumstances, for the italic corrections to be put in from the font, one of its @@ -3416,18 +3425,15 @@ $\mathit{f_i^i}$\par $\mathrm{f_i^i}$ \emph{Comment out the} |fontspec| \emph{line and use pdf\LaTeX{}. All three outputs are different on my \TeX{} installation. \XeTeX{} does not have the italic corrections. \LuaLaTeX{} does, but only for the italic font. - pdf\LaTeX{} has them for both the italic and the upright font.% -\footnotemark} -%\tracingmacros1 % pour extraire le -0.5em du code de scrartcl... -\footnotetext {2016/11/04: the situation hasn't changed, + pdf\LaTeX{} has them for both the italic and the upright font.}% +\footnote{2016/11/04: the situation hasn't changed, at least on current TL2016. \noindent\kern-0.5em\relax2022/10/29: no change with current TL2022.} -%\tracingmacros0 % For more see % \url{http://tex.stackexchange.com/a/337076} which explores also the differences -% between the two Unicode engines regarding italic corrections in pure text mode.} +% between the two Unicode engines regarding italic corrections in pure text mode. \subsection{Extra glue after \texorpdfstring{\cs{exists}}{\textbackslash exists}, \texorpdfstring{\cs{forall}}{\textbackslash forall}, and before the prime glyph} @@ -4232,7 +4238,7 @@ all the glyphs of the Euler font, if option |eulergreek| (or \cs{neg}~$\neg$ \cs{clubsuit}~$\clubsuit$ \cs{diamondsuit}~$\diamondsuit$ \cs{heartsuit}~$\heartsuit$ \cs{spadesuit}~$\spadesuit$ \cs{smallint}~$\smallint$ \cs{wedge}~$\wedge$ \cs{vee}~$\vee$ \cs{cap}~$\cap$ - \cs{cup}~$\cup$ \cs{bullet}~$\bullet$ \cs{div}~$\div$ \cs{otimes}~$\otimes$ + \cs{cup}~$\cup$ \cs{bullet}~$\symbolbullet$ \cs{div}~$\div$ \cs{otimes}~$\otimes$ \cs{oplus}~$\oplus$ \cs{pm}~$\pm$ \cs{ast}~$\ast$ \cs{times}~$\times$ \cs{proptopsy}~$\proptopsy$ \cs{mid}~$\mid$ \cs{leq}~$\leq$ \cs{geq}~$\geq$ \cs{approx}~$\approx$ \cs{supset}~$\supset$ \cs{subset}~$\subset$ @@ -4479,8 +4485,8 @@ Formerly, it was set to |0mu|.} In the case of the option |italic|, the (without the quotes). See \autoref{sec:newgreek}. - This command can also be defined \emph{prior} to loading the package. - Indeed it is defined this way: + This command can also be defined \emph{prior} to loading the package, + as the package itself only does: \centeredline{|\providecommand*\MTgreekupdefault{n}|} \item \MTgreekitdefault:\RLNote{new:}{1.3x} a command with @@ -4492,8 +4498,8 @@ Formerly, it was set to |0mu|.} In the case of the option |italic|, the (without the quotes). See \autoref{sec:newgreek}. - This command can also be used \emph{prior} to loading the package. - Indeed it is defined this way: + This command can also be defined \emph{prior} to loading the package, + as the package itself only does: \centeredline{|\providecommand*\MTgreekitdefault{it}|} \end{enumerate} @@ -4976,16 +4982,10 @@ Numerous examples will be found there:\\ \parindent \z@ \parfillskip \@flushglue \parskip \tw@\p@ \let \do \@makeother \dospecials \catcode`\ =10 } -% et donc on ne fait pas \obeylines +% et donc on ne fait pas \obeylines, ni \@noligs \def\endverbatim{} \let\@vobeyspaces\relax -\begingroup \catcode `|=0 \catcode `[= 1 \catcode`]=2 -\catcode `\{=12 \catcode `\}=12 \catcode`\\=12 -|long|gdef|@xverbatim#1\end{verbatim}[#1|end[verbatim]] -|endgroup - -% \end{verbatim} Fix du font-locking de AUCTeX (11.89.6) % 2015/09/10 -- 2015/09/12 % Dornavant README.md (et possiblement un CHANGES.txt ou CHANGES.md) % sont auto-extraits du .dtx. @@ -5093,7 +5093,7 @@ Numerous examples will be found there:\\ % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage {mathastext} - [2022/11/04 v1.3y Use the text font in math mode (JFB)] + [2023/09/01 v1.3z Use the text font in math mode (JFB)] % \end{macrocode} % \LaTeX{} |2019-10-01| release has made robust math macros such as the math % accents and \cs{hbar}. @@ -6497,48 +6497,52 @@ defaultbf,defaultit,defaultsf,defaulttt}\mst@nonormalboldtrue} % package; to be examined next time --- which may be a long time in % future!). % +% Unfortunately the |1.3x/1.3y| did some internal renamings here (using +% |@lgr@| in macro names in place of |@greek@|) which were not everywhere +% followed up, and this broke the |selfGreek| option. Fixed at |1.3z|. +% % \begin{macrocode} \providecommand*\MTgreekupdefault{n} \providecommand*\MTgreekitdefault{it} -\newif\ifmst@lgr@lower@up -\newif\ifmst@lgr@upper@up +\newif\ifmst@greek@lower@up +\newif\ifmst@greek@upper@up \def\mst@update@greeksh{ - \def\mst@lgr@lsh{\mst@ltsh} - \def\mst@lgr@ush{\mst@opsh} - \mst@lgr@lower@uptrue + \def\mst@greek@lsh{\mst@ltsh} + \def\mst@greek@ush{\mst@opsh} + \mst@greek@lower@uptrue \expandafter\in@\expanded{{\mst@ltsh.}}{it.,sl.}% - \ifin@\mst@lgr@lower@upfalse\fi - \mst@lgr@upper@uptrue + \ifin@\mst@greek@lower@upfalse\fi + \mst@greek@upper@uptrue \expandafter\in@\expanded{{\mst@opsh.}}{it.,sl.}% - \ifin@\mst@lgr@upper@upfalse\fi + \ifin@\mst@greek@upper@upfalse\fi \ifmst@itgreek - \def\mst@lgr@lsh{\MTgreekitdefault} - \def\mst@lgr@ush{\MTgreekitdefault} - \mst@lgr@lower@upfalse - \mst@lgr@upper@upfalse + \def\mst@greek@lsh{\MTgreekitdefault} + \def\mst@greek@ush{\MTgreekitdefault} + \mst@greek@lower@upfalse + \mst@greek@upper@upfalse \fi \ifmst@upgreek - \def\mst@lgr@lsh{\MTgreekupdefault} - \def\mst@lgr@ush{\MTgreekupdefault} - \mst@lgr@lower@uptrue - \mst@lgr@upper@uptrue + \def\mst@greek@lsh{\MTgreekupdefault} + \def\mst@greek@ush{\MTgreekupdefault} + \mst@greek@lower@uptrue + \mst@greek@upper@uptrue \fi \ifmst@frenchmath \ifmst@itgreek\else \ifmst@upgreek\else - \def\mst@lgr@lsh{\mst@opsh} - \def\mst@lgr@ush{\mst@opsh} - \mst@lgr@lower@uptrue - \mst@lgr@upper@uptrue + \def\mst@greek@lsh{\mst@opsh} + \def\mst@greek@ush{\mst@opsh} + \mst@greek@lower@uptrue + \mst@greek@upper@uptrue \fi\fi \fi \ifcase\mst@greek@select \or - \def\mst@lgr@ush{\MTgreekitdefault} - \mst@lgr@upper@upfalse + \def\mst@greek@ush{\MTgreekitdefault} + \mst@greek@upper@upfalse \or - \def\mst@lgr@ush{\MTgreekupdefault} - \mst@lgr@upper@uptrue + \def\mst@greek@ush{\MTgreekupdefault} + \mst@greek@upper@uptrue \fi } \mst@update@greeksh @@ -7880,33 +7884,33 @@ defaultbf,defaultit,defaultsf,defaulttt}\mst@nonormalboldtrue} \DeclareMathSymbol{\Psiit}{\mathalpha}{mtgreekit}{89} \DeclareMathSymbol{\Omegait}{\mathalpha}{mtgreekit}{87} % - \def\mst@Alpha{\ifmst@lgr@upper@up\Alphaup\else\Alphait\fi}% - \def\mst@Beta{\ifmst@lgr@upper@up\Betaup\else\Betait\fi}% - \def\mst@Epsilon{\ifmst@lgr@upper@up\Epsilonup\else\Epsilonit\fi}% - \def\mst@Zeta{\ifmst@lgr@upper@up\Zetaup\else\Zetait\fi}% - \def\mst@Eta{\ifmst@lgr@upper@up\Etaup\else\Etait\fi}% - \def\mst@Iota{\ifmst@lgr@upper@up\Iotaup\else\Iotait\fi}% - \def\mst@Kappa{\ifmst@lgr@upper@up\Kappaup\else\Kappait\fi}% - \def\mst@Mu{\ifmst@lgr@upper@up\Muup\else\Muit\fi}% - \def\mst@Nu{\ifmst@lgr@upper@up\Nuup\else\Nuit\fi}% - \def\mst@Omicron{\ifmst@lgr@upper@up\Omicronup\else\Omicronit\fi}% - \def\mst@Rho{\ifmst@lgr@upper@up\Rhoup\else\Rhoit\fi}% - \def\mst@Tau{\ifmst@lgr@upper@up\Tauup\else\Tauit\fi}% - \def\mst@Chi{\ifmst@lgr@upper@up\Chiup\else\Chiit\fi}% + \def\mst@Alpha{\ifmst@greek@upper@up\Alphaup\else\Alphait\fi}% + \def\mst@Beta{\ifmst@greek@upper@up\Betaup\else\Betait\fi}% + \def\mst@Epsilon{\ifmst@greek@upper@up\Epsilonup\else\Epsilonit\fi}% + \def\mst@Zeta{\ifmst@greek@upper@up\Zetaup\else\Zetait\fi}% + \def\mst@Eta{\ifmst@greek@upper@up\Etaup\else\Etait\fi}% + \def\mst@Iota{\ifmst@greek@upper@up\Iotaup\else\Iotait\fi}% + \def\mst@Kappa{\ifmst@greek@upper@up\Kappaup\else\Kappait\fi}% + \def\mst@Mu{\ifmst@greek@upper@up\Muup\else\Muit\fi}% + \def\mst@Nu{\ifmst@greek@upper@up\Nuup\else\Nuit\fi}% + \def\mst@Omicron{\ifmst@greek@upper@up\Omicronup\else\Omicronit\fi}% + \def\mst@Rho{\ifmst@greek@upper@up\Rhoup\else\Rhoit\fi}% + \def\mst@Tau{\ifmst@greek@upper@up\Tauup\else\Tauit\fi}% + \def\mst@Chi{\ifmst@greek@upper@up\Chiup\else\Chiit\fi}% % - \def\mst@Digamma{\ifmst@lgr@upper@up\Digammaup\else\Digammait\fi}% + \def\mst@Digamma{\ifmst@greek@upper@up\Digammaup\else\Digammait\fi}% % - \def\mst@Gamma{\ifmst@lgr@upper@up\Gammaup\else\Gammait\fi}% - \def\mst@Delta{\ifmst@lgr@upper@up\Deltaup\else\Deltait\fi}% - \def\mst@Theta{\ifmst@lgr@upper@up\Thetaup\else\Thetait\fi}% - \def\mst@Lambda{\ifmst@lgr@upper@up\Lambdaup\else\Lambdait\fi}% - \def\mst@Xi{\ifmst@lgr@upper@up\Xiup\else\Xiit\fi}% - \def\mst@Pi{\ifmst@lgr@upper@up\Piup\else\Piit\fi}% - \def\mst@Sigma{\ifmst@lgr@upper@up\Sigmaup\else\Sigmait\fi}% - \def\mst@Upsilon{\ifmst@lgr@upper@up\Upsilonup\else\Upsilonit\fi}% - \def\mst@Phi{\ifmst@lgr@upper@up\Phiup\else\Phiit\fi}% - \def\mst@Psi{\ifmst@lgr@upper@up\Psiup\else\Psiit\fi}% - \def\mst@Omega{\ifmst@lgr@upper@up\Omegaup\else\Omegait\fi}% + \def\mst@Gamma{\ifmst@greek@upper@up\Gammaup\else\Gammait\fi}% + \def\mst@Delta{\ifmst@greek@upper@up\Deltaup\else\Deltait\fi}% + \def\mst@Theta{\ifmst@greek@upper@up\Thetaup\else\Thetait\fi}% + \def\mst@Lambda{\ifmst@greek@upper@up\Lambdaup\else\Lambdait\fi}% + \def\mst@Xi{\ifmst@greek@upper@up\Xiup\else\Xiit\fi}% + \def\mst@Pi{\ifmst@greek@upper@up\Piup\else\Piit\fi}% + \def\mst@Sigma{\ifmst@greek@upper@up\Sigmaup\else\Sigmait\fi}% + \def\mst@Upsilon{\ifmst@greek@upper@up\Upsilonup\else\Upsilonit\fi}% + \def\mst@Phi{\ifmst@greek@upper@up\Phiup\else\Phiit\fi}% + \def\mst@Psi{\ifmst@greek@upper@up\Psiup\else\Psiit\fi}% + \def\mst@Omega{\ifmst@greek@upper@up\Omegaup\else\Omegait\fi}% % \DeclareMathSymbol{\alphaup}{\mathalpha}{mtgreekup}{97} \DeclareMathSymbol{\betaup}{\mathalpha}{mtgreekup}{98} @@ -7965,33 +7969,33 @@ defaultbf,defaultit,defaultsf,defaulttt}\mst@nonormalboldtrue} \DeclareMathSymbol{\digammait}{\mathalpha}{mtgreekit}{147} \DeclareMathSymbol{\varsigmait}{\mathalpha}{mtgreekit}{99} % - \def\mst@alpha{\ifmst@lgr@lower@up\alphaup\else\alphait\fi}% - \def\mst@beta{\ifmst@lgr@lower@up\betaup\else\betait\fi}% - \def\mst@gamma{\ifmst@lgr@lower@up\gammaup\else\gammait\fi}% - \def\mst@delta{\ifmst@lgr@lower@up\deltaup\else\deltait\fi}% - \def\mst@epsilon{\ifmst@lgr@lower@up\epsilonup\else\epsilonit\fi}% - \def\mst@zeta{\ifmst@lgr@lower@up\zetaup\else\zetait\fi}% - \def\mst@eta{\ifmst@lgr@lower@up\etaup\else\etait\fi}% - \def\mst@theta{\ifmst@lgr@lower@up\thetaup\else\thetait\fi}% - \def\mst@iota{\ifmst@lgr@lower@up\iotaup\else\iotait\fi}% - \def\mst@kappa{\ifmst@lgr@lower@up\kappaup\else\kappait\fi}% - \def\mst@lambda{\ifmst@lgr@lower@up\lambdaup\else\lambdait\fi}% - \def\mst@mu{\ifmst@lgr@lower@up\muup\else\muit\fi}% - \def\mst@nu{\ifmst@lgr@lower@up\nuup\else\nuit\fi}% - \def\mst@xi{\ifmst@lgr@lower@up\xiup\else\xiit\fi}% - \def\mst@omicron{\ifmst@lgr@lower@up\omicronup\else\omicronit\fi}% - \def\mst@pi{\ifmst@lgr@lower@up\piup\else\piit\fi}% - \def\mst@rho{\ifmst@lgr@lower@up\rhoup\else\rhoit\fi}% - \def\mst@sigma{\ifmst@lgr@lower@up\sigmaup\else\sigmait\fi}% - \def\mst@tau{\ifmst@lgr@lower@up\tauup\else\tauit\fi}% - \def\mst@upsilon{\ifmst@lgr@lower@up\upsilonup\else\upsilonit\fi}% - \def\mst@phi{\ifmst@lgr@lower@up\phiup\else\phiit\fi}% - \def\mst@chi{\ifmst@lgr@lower@up\chiup\else\chiit\fi}% - \def\mst@psi{\ifmst@lgr@lower@up\psiup\else\psiit\fi}% - \def\mst@omega{\ifmst@lgr@lower@up\omegaup\else\omegait\fi}% + \def\mst@alpha{\ifmst@greek@lower@up\alphaup\else\alphait\fi}% + \def\mst@beta{\ifmst@greek@lower@up\betaup\else\betait\fi}% + \def\mst@gamma{\ifmst@greek@lower@up\gammaup\else\gammait\fi}% + \def\mst@delta{\ifmst@greek@lower@up\deltaup\else\deltait\fi}% + \def\mst@epsilon{\ifmst@greek@lower@up\epsilonup\else\epsilonit\fi}% + \def\mst@zeta{\ifmst@greek@lower@up\zetaup\else\zetait\fi}% + \def\mst@eta{\ifmst@greek@lower@up\etaup\else\etait\fi}% + \def\mst@theta{\ifmst@greek@lower@up\thetaup\else\thetait\fi}% + \def\mst@iota{\ifmst@greek@lower@up\iotaup\else\iotait\fi}% + \def\mst@kappa{\ifmst@greek@lower@up\kappaup\else\kappait\fi}% + \def\mst@lambda{\ifmst@greek@lower@up\lambdaup\else\lambdait\fi}% + \def\mst@mu{\ifmst@greek@lower@up\muup\else\muit\fi}% + \def\mst@nu{\ifmst@greek@lower@up\nuup\else\nuit\fi}% + \def\mst@xi{\ifmst@greek@lower@up\xiup\else\xiit\fi}% + \def\mst@omicron{\ifmst@greek@lower@up\omicronup\else\omicronit\fi}% + \def\mst@pi{\ifmst@greek@lower@up\piup\else\piit\fi}% + \def\mst@rho{\ifmst@greek@lower@up\rhoup\else\rhoit\fi}% + \def\mst@sigma{\ifmst@greek@lower@up\sigmaup\else\sigmait\fi}% + \def\mst@tau{\ifmst@greek@lower@up\tauup\else\tauit\fi}% + \def\mst@upsilon{\ifmst@greek@lower@up\upsilonup\else\upsilonit\fi}% + \def\mst@phi{\ifmst@greek@lower@up\phiup\else\phiit\fi}% + \def\mst@chi{\ifmst@greek@lower@up\chiup\else\chiit\fi}% + \def\mst@psi{\ifmst@greek@lower@up\psiup\else\psiit\fi}% + \def\mst@omega{\ifmst@greek@lower@up\omegaup\else\omegait\fi}% % - \def\mst@digamma{\ifmst@lgr@lower@up\digammaup\else\digammait\fi}% - \def\mst@varsigma{\ifmst@lgr@lower@up\varsigmaup\else\varsigmait\fi}% + \def\mst@digamma{\ifmst@greek@lower@up\digammaup\else\digammait\fi}% + \def\mst@varsigma{\ifmst@greek@lower@up\varsigmaup\else\varsigmait\fi}% \fi % \end{macrocode} % \end{macro} @@ -8681,40 +8685,40 @@ defaultbf,defaultit,defaultsf,defaulttt}\mst@nonormalboldtrue} % \begin{macrocode} \def\mst@greek@lsh@loc{\csname mst@ltshape@\mst@version\endcsname}% \def\mst@greek@ush@loc{\csname mst@shape@\mst@version\endcsname}% - \mst@lgr@lower@uptrue + \mst@greek@lower@uptrue \expandafter\in@\expanded{{\mst@greek@lsh@loc.}}{it.,sl.}% - \ifin@\mst@lgr@lower@upfalse\fi - \mst@lgr@upper@uptrue + \ifin@\mst@greek@lower@upfalse\fi + \mst@greek@upper@uptrue \expandafter\in@\expanded{{\mst@greek@ush@loc.}}{it.,sl.}% - \ifin@\mst@lgr@upper@upfalse\fi + \ifin@\mst@greek@upper@upfalse\fi \ifmst@itgreek \def\mst@greek@lsh@loc{\MTgreekitdefault}% \def\mst@greek@ush@loc{\MTgreekitdefault}% - \mst@lgr@lower@upfalse - \mst@lgr@upper@upfalse + \mst@greek@lower@upfalse + \mst@greek@upper@upfalse \fi \ifmst@upgreek \def\mst@greek@lsh@loc{\MTgreekupdefault}% \def\mst@greek@ush@loc{\MTgreekupdefault}% - \mst@lgr@lower@uptrue - \mst@lgr@upper@uptrue + \mst@greek@lower@uptrue + \mst@greek@upper@uptrue \fi \ifmst@frenchmath \ifmst@itgreek\else \ifmst@upgreek\else \def\mst@greek@lsh@loc{\csname mst@shape@\mst@version\endcsname}% \def\mst@greek@ush@loc{\csname mst@shape@\mst@version\endcsname}% - \mst@lgr@lower@uptrue - \mst@lgr@upper@uptrue + \mst@greek@lower@uptrue + \mst@greek@upper@uptrue \fi\fi \fi \ifcase\mst@greek@select \or \def\mst@greek@ush@loc{\MTgreekitdefault}% - \mst@lgr@upper@upfalse + \mst@greek@upper@upfalse \or \def\mst@greek@ush@loc{\MTgreekupdefault}% - \mst@lgr@upper@uptrue + \mst@greek@upper@uptrue \fi \ifmst@LGRgreeks \SetSymbolFont{mtgreekup}{#2}{LGR}{#4}{#5}{\MTgreekupdefault}% @@ -8725,14 +8729,14 @@ defaultbf,defaultit,defaultsf,defaulttt}\mst@nonormalboldtrue} % Also |1.3x| fixes some strange log messages which did not recall % the math version name and referred to `non subdued versions' (strange). % \begin{macrocode} - \expandafter\let\csname ifmst@lgr@\mst@version @upper@up\expandafter\endcsname - \csname ifmst@lgr@upper@up\endcsname - \expandafter\let\csname ifmst@lgr@\mst@version @lower@up\expandafter\endcsname - \csname ifmst@lgr@lower@up\endcsname + \expandafter\let\csname ifmst@greek@\mst@version @upper@up\expandafter\endcsname + \csname ifmst@greek@upper@up\endcsname + \expandafter\let\csname ifmst@greek@\mst@version @lower@up\expandafter\endcsname + \csname ifmst@greek@lower@up\endcsname \typeout{** Greek letters (upper: - `\ifmst@lgr@upper@up\MTgreekupdefault\else\MTgreekitdefault\fi\string', + `\ifmst@greek@upper@up\MTgreekupdefault\else\MTgreekitdefault\fi\string', lower: - `\ifmst@lgr@lower@up\MTgreekupdefault\else\MTgreekitdefault\fi\string') + `\ifmst@greek@lower@up\MTgreekupdefault\else\MTgreekitdefault\fi\string') will use font family `#4\string' (LGR)^^J** in mathastext math version `\mst@version\string'.}% @@ -8750,14 +8754,14 @@ defaultbf,defaultit,defaultsf,defaulttt}\mst@nonormalboldtrue} % This is where the shape of uppercase/lowercase Greek letters is recorded, % for \cs{MTversion}'s triggered \cs{MTcustomgreek} to do the right thing. % \begin{macrocode} - \expandafter\let\csname ifmst@lgr@\mst@version @upper@up\expandafter\endcsname - \csname ifmst@lgr@upper@up\endcsname - \expandafter\let\csname ifmst@lgr@\mst@version @lower@up\expandafter\endcsname - \csname ifmst@lgr@lower@up\endcsname + \expandafter\let\csname ifmst@greek@\mst@version @upper@up\expandafter\endcsname + \csname ifmst@greek@upper@up\endcsname + \expandafter\let\csname ifmst@greek@\mst@version @lower@up\expandafter\endcsname + \csname ifmst@greek@lower@up\endcsname \typeout{** Greek letters (upper: - `\ifmst@lgr@upper@up\MTgreekupdefault\else\MTgreekitdefault\fi\string', + `\ifmst@greek@upper@up\MTgreekupdefault\else\MTgreekitdefault\fi\string', lower: - `\ifmst@lgr@lower@up\MTgreekupdefault\else\MTgreekitdefault\fi\string') + `\ifmst@greek@lower@up\MTgreekupdefault\else\MTgreekitdefault\fi\string') will use font family `\mst@greekfont\string' (LGR)^^J** in mathastext math version `\mst@version\string'.}% \else @@ -8968,10 +8972,10 @@ defaultbf,defaultit,defaultsf,defaulttt}\mst@nonormalboldtrue} % \end{macrocode} % |1.3x| addition for \cs{MTcustomgreek} under |LGRgreeks| option. % \begin{macrocode} - \expandafter\let\csname ifmst@lgr@upper@up\expandafter\endcsname - \csname ifmst@lgr@\math@version @upper@up\endcsname - \expandafter\let\csname ifmst@lgr@lower@up\expandafter\endcsname - \csname ifmst@lgr@\math@version @lower@up\endcsname + \expandafter\let\csname ifmst@greek@upper@up\expandafter\endcsname + \csname ifmst@greek@\math@version @upper@up\endcsname + \expandafter\let\csname ifmst@greek@lower@up\expandafter\endcsname + \csname ifmst@greek@\math@version @lower@up\endcsname \MTcustomgreek \mst@nonsubduedhbar \mst@nonsubduedinodot @@ -8983,10 +8987,10 @@ defaultbf,defaultit,defaultsf,defaulttt}\mst@nonormalboldtrue} % \end{macrocode} % |1.3x| addition for \cs{MTcustomgreek} under |LGRgreek| option. % \begin{macrocode} - \expandafter\let\csname ifmst@lgr@upper@up\expandafter\endcsname - \csname ifmst@lgr@\math@version @upper@up\endcsname - \expandafter\let\csname ifmst@lgr@lower@up\expandafter\endcsname - \csname ifmst@lgr@\math@version @lower@up\endcsname + \expandafter\let\csname ifmst@greek@upper@up\expandafter\endcsname + \csname ifmst@greek@\math@version @upper@up\endcsname + \expandafter\let\csname ifmst@greek@lower@up\expandafter\endcsname + \csname ifmst@greek@\math@version @lower@up\endcsname \MTcustomgreek % new with 1.3d \mst@nonsubduedhbar \mst@nonsubduedinodot @@ -9257,9 +9261,9 @@ defaultbf,defaultit,defaultsf,defaulttt}\mst@nonormalboldtrue} \mst@encoding@normal/\mst@family@normal/\mst@series@normal% (\mst@boldvariant@normal)/\mst@ltshape@normal}% \ifmst@LGRgreek\typeout{** Greek letters (upper: - `\ifmst@lgr@upper@up\MTgreekupdefault\else\MTgreekitdefault\fi\string', + `\ifmst@greek@upper@up\MTgreekupdefault\else\MTgreekitdefault\fi\string', lower: - `\ifmst@lgr@lower@up\MTgreekupdefault\else\MTgreekitdefault\fi\string') + `\ifmst@greek@lower@up\MTgreekupdefault\else\MTgreekitdefault\fi\string') will use font family `\mst@greekfont\string' (LGR)}% \fi \ifmst@nodigits\else diff --git a/macros/latex/contrib/mathastext/mathastext.pdf b/macros/latex/contrib/mathastext/mathastext.pdf index df962ded91..461c8e6b4a 100644 Binary files a/macros/latex/contrib/mathastext/mathastext.pdf and b/macros/latex/contrib/mathastext/mathastext.pdf differ diff --git a/macros/latex/contrib/mitthesis/MIT-Thesis.pdf b/macros/latex/contrib/mitthesis/MIT-Thesis.pdf index 169e05b2e0..d21b696202 100644 Binary files a/macros/latex/contrib/mitthesis/MIT-Thesis.pdf and b/macros/latex/contrib/mitthesis/MIT-Thesis.pdf differ diff --git a/macros/latex/contrib/mitthesis/MIT-thesis-template/MIT-Thesis.tex b/macros/latex/contrib/mitthesis/MIT-thesis-template/MIT-Thesis.tex index 66deabb5d0..35865fc403 100644 --- a/macros/latex/contrib/mitthesis/MIT-thesis-template/MIT-Thesis.tex +++ b/macros/latex/contrib/mitthesis/MIT-thesis-template/MIT-Thesis.tex @@ -2,11 +2,13 @@ % !BIB TS-program = biber % !BIB program = biber -% This file is MIT-Thesis.tex, a template for producing MIT theses with the mitthesis class. -% Version: 1.05, 2023/07/21 +% This file is MIT-Thesis.tex, a LaTeX template for formatting an MIT thesis with the mitthesis class. +% +% Version: 1.06, 2023/08/29 +% % Author: John H. Lienhard (c) 2023. Reuse under the MIT license: https://ctan.org/license/mit -% Documentation: https://ctan.org/pkg/mitthesis +% Documentation is here: https://ctan.org/pkg/mitthesis %% Don't modify the \DocumentMetadata command unless you know what it does. %% If this command throws an "undefined" error, your latex system is out of date: try commenting this command out. @@ -14,32 +16,32 @@ pdfstandard = a-2b, pdfversion = 1.7, lang = en-US, -% debug = {xmp-export}, % output xmpi file to directly examine metadata +% debug = {xmp-export}, % uncomment to output a separate xmpi file showing the metadata } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \documentclass[twoside]{mitthesis} %,fontset=libertine ,fontset=newtx-sans-text, fontset=heros-stix2, fontset=stix2 % -% option [twoside] gives facing-page behavior for printing; omitting it will eliminate even-numbered blank pages. +% option [twoside] gives facing-page behavior for printing; omitting twoside will eliminate even-numbered blank pages. % option [lineno] provides line numbers, as for editing % option [mydesign] loads packages for color, title and list formats, margins, or captions: edit mydesign.tex to change defaults. % option [fontset] is a keyvalue which can be: % pdftex or unicode engines: defaultfonts, libertine, lucida % pdftex only: fira-newtxsf, newtx, newtx-sans-text % unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 -% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the latex font". +% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the LaTeX font". % You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. % If you are using multiple languages, load the babel package in your fontset file, before the fonts. %%%%%%%%% Packages used in sample chapters (not otherwise required) %%%%%%% %% Package for code listing in Appendix A. -\usepackage{listings} +\usepackage{listings}% documentation is here https://ctan.org/pkg/listings %% Set chemical formulas nicely -\usepackage[version=4]{mhchem} +\usepackage[version=4]{mhchem}% documentation is here https://ctan.org/pkg/mhchem -%% Latin filler used in Chapter 1, with a test for package version date +%% Latin filler used in Chapter 1, with a test for package version date. https://ctan.org/pkg/lipsum \usepackage{lipsum} \IfPackageAtLeastTF{lipsum}{2021/09/20}{\setlipsum{auto-lang=false}}{} @@ -55,14 +57,17 @@ %%%%%%%%% Representative set-up for biblatex %%%%%%%%%%%%%%%%%%%%%%%%%%%%% \usepackage[style=ieee,maxbibnames=10,sorting=none]{biblatex}% style=ext-numeric-comp,articlein=false,giveninits=true + \DefineBibliographyStrings{english}{url= \textsc{url} , }% replaces default "[Online]. Available" by "URL" + -\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= +\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= CHANGE %% These two commands enable line breaks in long URLs in the bibliography (delete if you don't want that) \setcounter{biburllcpenalty}{7000} \setcounter{biburlucpenalty}{8000} -% biblatex is very powerful, and you can customize most aspects the reference list and citations. +% biblatex is very powerful, and you can customize most aspects the reference list and citations to suit your needs. +% documentation is here: https://ctan.org/pkg/biblatex %%%%%%%%%% Option to use natbib %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -81,16 +86,16 @@ %%%%%%%%%% Table related packages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage{booktabs}% better quality tables -\usepackage{array}% additional options for table columns +\usepackage{booktabs}% better quality tables, https://ctan.org/pkg/booktabs +\usepackage{array}% additional options for table columns, https://ctan.org/pkg/array -%\usepackage{tabularx} +%\usepackage{tabularx}% https://ctan.org/pkg/tabularx -%\usepackage{dcolumn} % alignment on decimal places +%\usepackage{dcolumn}% alignment on decimal place, https://ctan.org/pkg/dcolumn %\newcolumntype{d}[1]{D{.}{.}{#1}} -%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Back in the typewriter era, double spaced lines were convenient for editing with a pencil. %% In typography, the separation between lines is called "leading", and it is usually set in @@ -98,73 +103,51 @@ %% to change the line separation, the most attractive results will be obtained by changing the %% leading in proportion to the the current font size, rather than just doubling the space. -%% The setspace package provides a tool for changing line separation (use these here) +%% The setspace package provides a tool for changing line separation (use thesetwo here) % -%\usepackage{setspace} -%\setstretch{1.1}% you can choose some other value for the stretch of space between lines +% \usepackage{setspace}% documentation at https://ctan.org/pkg/setspace +% \setstretch{1.1}% you can choose some other value for the stretch of space between lines % %% Use the these commands AFTER the frontmatter % -%\onehalfspacing -%\doublespacing -%\singlespacing % will turn these effects off (you can use these anywhere in the document) +% \onehalfspacing +% \doublespacing +% \singlespacing % will turn these effects off (you can use these anywhere in the document) %% The best result may be to stay with leading selected by the typographer who set up the font. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! -% - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, + pdfauthortitle={}, + % If you have a title, you can include it here. } -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. -} - -%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} - %%% edit the following commands to match your thesis %%%%%%%%%% \title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} @@ -176,6 +159,7 @@ \Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876][MBA, Ferengi School of Management, 2022] %\Author{Luisa Hernández}{Department of Research}[B.S. Mechanical Engineering, UCLA, 2018][M.S. Stellar Interiors, Vulcan Science Academy, 2020][MBA, Ferengi School of Management, 2022] +%\Author{Thurston Howell III}{Department of Economics} % Use once for each degree fulfilled by thesis % For two degrees from one department, leave the department argument blank for the second degree {}. @@ -190,7 +174,7 @@ % Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) % If more than one department, use more than once -% If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}. +% **If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}.** \Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} %\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} %\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} @@ -218,9 +202,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page - %%%%%%%%% Contents that you need to write follows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -229,19 +210,15 @@ %%% Frontmatter (write this material in the mentioned files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex \begin{abstract} \input{abstract.tex}% in this case, use \input rather than \include because you are inside an environment \end{abstract} - \cleardoublepage -\include{acknowledgments.tex}% - \cleardoublepage +\include{acknowledgments.tex} \include{biography.tex}% optional, see MIT Libraries https://libraries.mit.edu/distinctive-collections/thesis-specs/#format - \cleardoublepage %%% Table of contents and lists of stuff (delete lists you don't need, e.g., if no tables) %%%%%%%% @@ -253,7 +230,7 @@ %%% Chapters of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% If you feel a need for "double spacing", you can start here... +%% If you want to use "double spacing", you can start here... \include{chapter1.tex} %\include{chapter2.tex} @@ -269,7 +246,7 @@ %%% Bibliography %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -{\raggedright% to avoid stretched white space and split urls; DELETE if you prefer justified text +{ \raggedright% to avoid stretched white space and split urls; DELETE THIS if you prefer justified text % \printbibliography[title={References},heading=bibintoc] } diff --git a/macros/latex/contrib/mitthesis/MIT-thesis-template/chapter1.tex b/macros/latex/contrib/mitthesis/MIT-thesis-template/chapter1.tex index fda5b48ea2..f55a984123 100644 --- a/macros/latex/contrib/mitthesis/MIT-thesis-template/chapter1.tex +++ b/macros/latex/contrib/mitthesis/MIT-thesis-template/chapter1.tex @@ -1,5 +1,5 @@ % From mitthesis package -% Version: 1.02, 2023/07/21 +% Version: 1.03, 2023/08/10 % Documentation: https://ctan.org/pkg/mitthesis @@ -7,7 +7,7 @@ \lipsum[1-2] Postremo aliquos futuros suspicor, qui me ad alias litteras vocent, genus hoc scribendi, etsi sit elegans, personae tamen et dignitatis esse negent~\cite{DKE1969,ww1920,kirk2288a,churchill1948,gibbs1863}. -\section[A section discussing the first issue: \(\psi/\textrm{J}\)]{A section discussing the first issue: \ifpdftex\(\bm{\psi}/\bm{J}\)\else{\(\symbfup{\psi/J}\)}\fi} +\section[A section discussing the first issue: \(\textrm{J}/\psi\)]{A section discussing the first issue: \ifpdftex\(\bm{J}/\bm{\psi}\)\else{\(\symbfup{J/\psi}\)}\fi} We begin with some ideas from the literature \cite{Fong2015,sharpe1}. diff --git a/macros/latex/contrib/mitthesis/README.md b/macros/latex/contrib/mitthesis/README.md index 46bef90606..fb3b6bbc1e 100644 --- a/macros/latex/contrib/mitthesis/README.md +++ b/macros/latex/contrib/mitthesis/README.md @@ -1,10 +1,10 @@ - #mitthesis --- A LaTeX template for MIT theses# + #mitthesis --- A LaTeX template for an MIT thesis# - v1.05 dated 2023/07/21 + v1.06 dated 2023/08/29 ####Overview#### - This class provides a LaTeX template for MIT theses formatted according to + This class provides a LaTeX template to format an MIT thesis according to the requirements of the Massachusetts Institute of Technology Libraries (as posted in 2023): [https://libraries.mit.edu/distinctive-collections/thesis-specs/](https://libraries.mit.edu/distinctive-collections/thesis-specs/) @@ -53,6 +53,16 @@ --- ####Change log#### + + v1.06 (29 August 2023): + - Extensive revision of class file, with most code converted to expl3. Significant streamlining of remaining LaTeX2e code. Minor changes to user interface. No changes to format or design of thesis. + - Add user macros for \CopyrightAuthor, \DegreeMonth, \DegreeYear, and \Institution{..} + - Drop user macros \CCurl, \PDFRightsText, and \MIT{..} + - Reduce volume of pdf metadata required to be added by user + - Accommodate author names that end with a period or include a comma (e.g., Martin Luther King, Jr.) + - Reduce font size in fira-newtxsf fontset + - Update documentation + v1.05 (21 July 2023): - Fix bug in toc page number affecting some lists of figures or tables (note: for backward compatibility, remove code in .tex file around \tableofcontents, \listoffigures, and \listoftables so that your code will match the present version) - Include thesis submission date in abstract, remove previous degrees from abstract page, and allow May for degree month, per MIT Libraries diff --git a/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/No_cc_license.tex b/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/No_cc_license.tex index 90af70cb5d..337f31814b 100644 --- a/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/No_cc_license.tex +++ b/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/No_cc_license.tex @@ -17,73 +17,52 @@ } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\documentclass[]{mitthesis} +\documentclass[]{mitthesis} %,fontset=libertine ,fontset=newtx-sans-text, fontset=heros-stix2, fontset=stix2 % -% option [twoside] gives facing-page behavior for printing; omitting it will eliminate even-numbered blank pages. +% option [twoside] gives facing-page behavior for printing; omitting twoside will eliminate even-numbered blank pages. % option [lineno] provides line numbers, as for editing -% option [mydesign] loads titlesec, enumitem, caption, subcaption - you may edit the mydesign.tex file as you like it. +% option [mydesign] loads packages for color, title and list formats, margins, or captions: edit mydesign.tex to change defaults. % option [fontset] is a keyvalue which can be: % pdftex or unicode engines: defaultfonts, libertine, lucida % pdftex only: fira-newtxsf, newtx, newtx-sans-text % unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 -% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the latex font". +% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the LaTeX font". % You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. % If you are using multiple languages, load the babel package in your fontset file, before the fonts. +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! -% - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, + pdfauthortitle={}, + % If you have a title, you can include it here. } -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. -} - + %%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} - +\author{\YourName} %%% edit the following commands to match your thesis %%%%%%%%%% \title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} @@ -109,7 +88,7 @@ % Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) % If more than one department, use more than once -% If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}. +% **If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}.** \Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} %\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} %\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} @@ -137,8 +116,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex diff --git a/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_one_degree.tex b/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_one_degree.tex index 9b426eb0e3..c5e4db50b3 100644 --- a/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_one_degree.tex +++ b/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_one_degree.tex @@ -31,51 +31,32 @@ % If you are using multiple languages, load the babel package in your fontset file, before the fonts. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata -% - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, -} -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. + pdfauthortitle={}, + % If you have a title, you can include it here. } + %%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -137,8 +118,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex diff --git a/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees.tex b/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees.tex index b03232b383..6334a228ae 100644 --- a/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees.tex +++ b/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees.tex @@ -31,51 +31,32 @@ % If you are using multiple languages, load the babel package in your fontset file, before the fonts. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata -% - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, -} -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. + pdfauthortitle={}, + % If you have a title, you can include it here. } + %%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -139,8 +120,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex diff --git a/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees_from_one_department.tex b/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees_from_one_department.tex index 9589bc981f..9646d3d503 100644 --- a/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees_from_one_department.tex +++ b/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/One_author_two_degrees_from_one_department.tex @@ -31,52 +31,32 @@ % If you are using multiple languages, load the babel package in your fontset file, before the fonts. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata -% - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, + pdfauthortitle={}, + % If you have a title, you can include it here. } -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. -} - + %%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -137,8 +117,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex diff --git a/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_one_degree.tex b/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_one_degree.tex index 711264986e..e5e2618b69 100644 --- a/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_one_degree.tex +++ b/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_one_degree.tex @@ -31,51 +31,32 @@ % If you are using multiple languages, load the babel package in your fontset file, before the fonts. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata -% - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, -} -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. + pdfauthortitle={}, + % If you have a title, you can include it here. } + %%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -138,8 +119,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex diff --git a/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_two_degrees.tex b/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_two_degrees.tex index dc92f65998..930b218b1c 100644 --- a/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_two_degrees.tex +++ b/macros/latex/contrib/mitthesis/examples/cover_page_samples/latex_sources/Two_authors_two_degrees.tex @@ -31,51 +31,32 @@ % If you are using multiple languages, load the babel package in your fontset file, before the fonts. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata -% - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, -} -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. + pdfauthortitle={}, + % If you have a title, you can include it here. } + %%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -125,8 +106,6 @@ % Date that final thesis is submitted to department \ThesisDate{May 18, 1876} - - %%%%%% Choose whether to have a CREATIVE COMMONS License %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % If you are using a cc license, put details of your cc license here. @@ -138,8 +117,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/Defaultfonts.pdf b/macros/latex/contrib/mitthesis/examples/font_samples/Defaultfonts.pdf index 5c080c9afd..fab86f8556 100644 Binary files a/macros/latex/contrib/mitthesis/examples/font_samples/Defaultfonts.pdf and b/macros/latex/contrib/mitthesis/examples/font_samples/Defaultfonts.pdf differ diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/Fira_Newtxsf.pdf b/macros/latex/contrib/mitthesis/examples/font_samples/Fira_Newtxsf.pdf index 4b95649c1c..e862497f6c 100644 Binary files a/macros/latex/contrib/mitthesis/examples/font_samples/Fira_Newtxsf.pdf and b/macros/latex/contrib/mitthesis/examples/font_samples/Fira_Newtxsf.pdf differ diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/Heros-Stix2.pdf b/macros/latex/contrib/mitthesis/examples/font_samples/Heros-Stix2.pdf index 5eb395eb5f..6d0ff66249 100644 Binary files a/macros/latex/contrib/mitthesis/examples/font_samples/Heros-Stix2.pdf and b/macros/latex/contrib/mitthesis/examples/font_samples/Heros-Stix2.pdf differ diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/Libertine.pdf b/macros/latex/contrib/mitthesis/examples/font_samples/Libertine.pdf index 59314cd515..cc9163c2d4 100644 Binary files a/macros/latex/contrib/mitthesis/examples/font_samples/Libertine.pdf and b/macros/latex/contrib/mitthesis/examples/font_samples/Libertine.pdf differ diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/Lucida.pdf b/macros/latex/contrib/mitthesis/examples/font_samples/Lucida.pdf index 5455942967..2d57d358db 100644 Binary files a/macros/latex/contrib/mitthesis/examples/font_samples/Lucida.pdf and b/macros/latex/contrib/mitthesis/examples/font_samples/Lucida.pdf differ diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/Newtx-sans-text.pdf b/macros/latex/contrib/mitthesis/examples/font_samples/Newtx-sans-text.pdf index ae8977d4df..9e3f99af1f 100644 Binary files a/macros/latex/contrib/mitthesis/examples/font_samples/Newtx-sans-text.pdf and b/macros/latex/contrib/mitthesis/examples/font_samples/Newtx-sans-text.pdf differ diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/Newtx.pdf b/macros/latex/contrib/mitthesis/examples/font_samples/Newtx.pdf index 4df3847882..40da2bac86 100644 Binary files a/macros/latex/contrib/mitthesis/examples/font_samples/Newtx.pdf and b/macros/latex/contrib/mitthesis/examples/font_samples/Newtx.pdf differ diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/Stix2.pdf b/macros/latex/contrib/mitthesis/examples/font_samples/Stix2.pdf index 1fb37710cd..cb1c5cee2e 100644 Binary files a/macros/latex/contrib/mitthesis/examples/font_samples/Stix2.pdf and b/macros/latex/contrib/mitthesis/examples/font_samples/Stix2.pdf differ diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/Termes-Stix2.pdf b/macros/latex/contrib/mitthesis/examples/font_samples/Termes-Stix2.pdf deleted file mode 100644 index ca04ea5d18..0000000000 Binary files a/macros/latex/contrib/mitthesis/examples/font_samples/Termes-Stix2.pdf and /dev/null differ diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/Termes-stix2.pdf b/macros/latex/contrib/mitthesis/examples/font_samples/Termes-stix2.pdf new file mode 100644 index 0000000000..bab4183c99 Binary files /dev/null and b/macros/latex/contrib/mitthesis/examples/font_samples/Termes-stix2.pdf differ diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/Termes.pdf b/macros/latex/contrib/mitthesis/examples/font_samples/Termes.pdf index 792607b351..808306fb9f 100644 Binary files a/macros/latex/contrib/mitthesis/examples/font_samples/Termes.pdf and b/macros/latex/contrib/mitthesis/examples/font_samples/Termes.pdf differ diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Defaultfonts.tex b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Defaultfonts.tex index f700e4ba80..f924303a9f 100644 --- a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Defaultfonts.tex +++ b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Defaultfonts.tex @@ -2,45 +2,46 @@ % !BIB TS-program = biber % !BIB program = biber -% This file is MIT-Thesis.tex, a template for producing MIT theses with the mitthesis class. -% Version: 1.01, 2023/07/21 +% This file is MIT-Thesis.tex, a LaTeX template for formatting an MIT thesis with the mitthesis class. +% +% Version: 1.06, 2023/08/28 +% % Author: John H. Lienhard (c) 2023. Reuse under the MIT license: https://ctan.org/license/mit -% Documentation: https://ctan.org/pkg/mitthesis +% Documentation is here: https://ctan.org/pkg/mitthesis %% Don't modify the \DocumentMetadata command unless you know what it does. %% If this command throws an "undefined" error, your latex system is out of date: try commenting this command out. -\DocumentMetadata -{ +\DocumentMetadata{ pdfstandard = a-2b, pdfversion = 1.7, lang = en-US, -% debug = {xmp-export}, % output xmpi file to directly examine metadata +% debug = {xmp-export}, % uncomment to output a separate xmpi file showing the metadata } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\documentclass[fontset=defaultfonts]{mitthesis} +\documentclass[twoside]{mitthesis} %,fontset=libertine ,fontset=newtx-sans-text, fontset=heros-stix2, fontset=stix2 % -% option [twoside] gives facing-page behavior for printing; omitting it will eliminate even-numbered blank pages. +% option [twoside] gives facing-page behavior for printing; omitting twoside will eliminate even-numbered blank pages. % option [lineno] provides line numbers, as for editing -% option [mydesign] loads titlesec, enumitem, caption, subcaption - you may edit the mydesign.tex file as you like it. +% option [mydesign] loads packages for color, title and list formats, margins, or captions: edit mydesign.tex to change defaults. % option [fontset] is a keyvalue which can be: % pdftex or unicode engines: defaultfonts, libertine, lucida % pdftex only: fira-newtxsf, newtx, newtx-sans-text % unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 -% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the latex font". +% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the LaTeX font". % You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. % If you are using multiple languages, load the babel package in your fontset file, before the fonts. %%%%%%%%% Packages used in sample chapters (not otherwise required) %%%%%%% %% Package for code listing in Appendix A. -\usepackage{listings} +\usepackage{listings}% documentation is here https://ctan.org/pkg/listings %% Set chemical formulas nicely -\usepackage[version=4]{mhchem} +\usepackage[version=4]{mhchem}% documentation is here https://ctan.org/pkg/mhchem -%% Latin filler used in Chapter 1, with a test for package version date +%% Latin filler used in Chapter 1, with a test for package version date. https://ctan.org/pkg/lipsum \usepackage{lipsum} \IfPackageAtLeastTF{lipsum}{2021/09/20}{\setlipsum{auto-lang=false}}{} @@ -55,15 +56,18 @@ %%%%%%%%% Representative set-up for biblatex %%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage[style=ext-numeric-comp,giveninits=true,maxbibnames=10,sorting=none,articlein=false,]{biblatex} +\usepackage[style=ieee,maxbibnames=10,sorting=none]{biblatex}% style=ext-numeric-comp,articlein=false,giveninits=true + \DefineBibliographyStrings{english}{url= \textsc{url} , }% replaces default "[Online]. Available" by "URL" -\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= + +\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= CHANGE %% These two commands enable line breaks in long URLs in the bibliography (delete if you don't want that) \setcounter{biburllcpenalty}{7000} \setcounter{biburlucpenalty}{8000} -% biblatex is very powerful, and you can customize most aspects the reference list and citations. +% biblatex is very powerful, and you can customize most aspects the reference list and citations to suit your needs. +% documentation is here: https://ctan.org/pkg/biblatex %%%%%%%%%% Option to use natbib %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -82,16 +86,16 @@ %%%%%%%%%% Table related packages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage{booktabs}% better quality tables -\usepackage{array}% additional options for table columns +\usepackage{booktabs}% better quality tables, https://ctan.org/pkg/booktabs +\usepackage{array}% additional options for table columns, https://ctan.org/pkg/array -%\usepackage{tabularx} +%\usepackage{tabularx}% https://ctan.org/pkg/tabularx -%\usepackage{dcolumn} % alignment on decimal places +%\usepackage{dcolumn}% alignment on decimal place, https://ctan.org/pkg/dcolumn %\newcolumntype{d}[1]{D{.}{.}{#1}} -%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Back in the typewriter era, double spaced lines were convenient for editing with a pencil. %% In typography, the separation between lines is called "leading", and it is usually set in @@ -99,74 +103,51 @@ %% to change the line separation, the most attractive results will be obtained by changing the %% leading in proportion to the the current font size, rather than just doubling the space. -%% The setspace package provides a tool for changing line separation (use these here) +%% The setspace package provides a tool for changing line separation (use thesetwo here) % -%\usepackage{setspace} -%\setstretch{1.1}% you can choose some other value for the stretch of space between lines +% \usepackage{setspace}% documentation at https://ctan.org/pkg/setspace +% \setstretch{1.1}% you can choose some other value for the stretch of space between lines % %% Use the these commands AFTER the frontmatter % -%\onehalfspacing -%\doublespacing -%\singlespacing % will turn these effects off (you can use these anywhere in the document) +% \onehalfspacing +% \doublespacing +% \singlespacing % will turn these effects off (you can use these anywhere in the document) %% The best result may be to stay with leading selected by the typographer who set up the font. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! -% - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata -% - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, -} -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. + pdfauthortitle={}, + % If you have a title, you can include it here. } - -%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - \begin{document} - %%% edit the following commands to match your thesis %%%%%%%%%% \title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} @@ -176,25 +157,31 @@ % note on names: most of the following names are made up; Silas Holman was a professor at MIT in the 19th century. -\Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876] +\Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876][MBA, Ferengi School of Management, 2022] %\Author{Luisa Hernández}{Department of Research}[B.S. Mechanical Engineering, UCLA, 2018][M.S. Stellar Interiors, Vulcan Science Academy, 2020][MBA, Ferengi School of Management, 2022] +%\Author{Thurston Howell III}{Department of Economics} % Use once for each degree fulfilled by thesis +% For two degrees from one department, leave the department argument blank for the second degree {}. \Degree{Bachelor of Science in Physics}{Department of Physics} +%\Degree{Master of Science in Physics}{} %\Degree{Bachelor of Science in Mechanical Engineering}{Department of Mechanical Engineering} % If there is more than one supervisor, use the \Supervisor command for each. \Supervisor{Edward C. Pickering}{Professor of Physics} -%\Supervisor{Secunda Castor}{Department of Mechanical Engineering} +%\Supervisor{Secunda Castor}{Professor of Research} +%\Supervisor{Quintus Castor}{Professor of Log Dams} % Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) % If more than one department, use more than once +% **If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}.** \Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} -%\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Second Degree Department} +%\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} +%\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} % If your title page is overflowing (from too many names, degrees, etc.), you can scale % down the Signature block at the bottom with this command, or use another creative solution... -%\SignatureBlockSize{\small} +%\SignatureBlockSize{\small} %\SignatureBlockSize{\footnotesize} % Usage: \DegreeDate{Month}{year} % Valid degree months are September, February, or June. @@ -215,9 +202,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page - %%%%%%%%% Contents that you need to write follows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -226,22 +210,18 @@ %%% Frontmatter (write this material in the mentioned files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex \begin{abstract} \input{abstract.tex}% in this case, use \input rather than \include because you are inside an environment \end{abstract} - \cleardoublepage -\include{acknowledgments.tex}% - \cleardoublepage +\include{acknowledgments.tex} \include{biography.tex}% optional, see MIT Libraries https://libraries.mit.edu/distinctive-collections/thesis-specs/#format - \cleardoublepage -%%% Table of contents and lists of stuff (edit only if you want different lists) %%%%%%%%%%%%%%%% +%%% Table of contents and lists of stuff (delete lists you don't need, e.g., if no tables) %%%%%%%% \tableofcontents \listoffigures @@ -250,11 +230,12 @@ %%% Chapters of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% If you really feel the need to engage in "double spacing", you can start here... +%% If you want to use "double spacing", you can start here... \include{chapter1.tex} %\include{chapter2.tex} %\include{chapter3.tex} +%\include{chapter4.tex} %%% Appendicies of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -265,7 +246,7 @@ %%% Bibliography %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -{\raggedright% to avoid stretched white space and split urls; DELETE if you prefer justified text +{ \raggedright% to avoid stretched white space and split urls; DELETE THIS if you prefer justified text % \printbibliography[title={References},heading=bibintoc] } diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Fira_Newtxsf.tex b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Fira_Newtxsf.tex index 69d491ff84..d428bcadf1 100644 --- a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Fira_Newtxsf.tex +++ b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Fira_Newtxsf.tex @@ -2,45 +2,46 @@ % !BIB TS-program = biber % !BIB program = biber -% This file is MIT-Thesis.tex, a template for producing MIT theses with the mitthesis class. -% Version: 1.01, 2023/07/21 +% This file is MIT-Thesis.tex, a LaTeX template for formatting an MIT thesis with the mitthesis class. +% +% Version: 1.06, 2023/08/28 +% % Author: John H. Lienhard (c) 2023. Reuse under the MIT license: https://ctan.org/license/mit -% Documentation: https://ctan.org/pkg/mitthesis +% Documentation is here: https://ctan.org/pkg/mitthesis %% Don't modify the \DocumentMetadata command unless you know what it does. %% If this command throws an "undefined" error, your latex system is out of date: try commenting this command out. -\DocumentMetadata -{ +\DocumentMetadata{ pdfstandard = a-2b, pdfversion = 1.7, lang = en-US, -% debug = {xmp-export}, % output xmpi file to directly examine metadata +% debug = {xmp-export}, % uncomment to output a separate xmpi file showing the metadata } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\documentclass[fontset=fira-newtxsf]{mitthesis} +\documentclass[fontset=fira-newtxsf]{mitthesis} %,fontset=libertine ,fontset=newtx-sans-text, fontset=heros-stix2, fontset=stix2 % -% option [twoside] gives facing-page behavior for printing; omitting it will eliminate even-numbered blank pages. +% option [twoside] gives facing-page behavior for printing; omitting twoside will eliminate even-numbered blank pages. % option [lineno] provides line numbers, as for editing -% option [mydesign] loads titlesec, enumitem, caption, subcaption - you may edit the mydesign.tex file as you like it. +% option [mydesign] loads packages for color, title and list formats, margins, or captions: edit mydesign.tex to change defaults. % option [fontset] is a keyvalue which can be: % pdftex or unicode engines: defaultfonts, libertine, lucida % pdftex only: fira-newtxsf, newtx, newtx-sans-text % unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 -% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the latex font". +% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the LaTeX font". % You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. % If you are using multiple languages, load the babel package in your fontset file, before the fonts. %%%%%%%%% Packages used in sample chapters (not otherwise required) %%%%%%% %% Package for code listing in Appendix A. -\usepackage{listings} +\usepackage{listings}% documentation is here https://ctan.org/pkg/listings %% Set chemical formulas nicely -\usepackage[version=4]{mhchem} +\usepackage[version=4]{mhchem}% documentation is here https://ctan.org/pkg/mhchem -%% Latin filler used in Chapter 1, with a test for package version date +%% Latin filler used in Chapter 1, with a test for package version date. https://ctan.org/pkg/lipsum \usepackage{lipsum} \IfPackageAtLeastTF{lipsum}{2021/09/20}{\setlipsum{auto-lang=false}}{} @@ -55,15 +56,18 @@ %%%%%%%%% Representative set-up for biblatex %%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage[style=ext-numeric-comp,giveninits=true,maxbibnames=10,sorting=none,articlein=false,]{biblatex} +\usepackage[style=ieee,maxbibnames=10,sorting=none]{biblatex}% style=ext-numeric-comp,articlein=false,giveninits=true + \DefineBibliographyStrings{english}{url= \textsc{url} , }% replaces default "[Online]. Available" by "URL" -\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= + +\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= CHANGE %% These two commands enable line breaks in long URLs in the bibliography (delete if you don't want that) \setcounter{biburllcpenalty}{7000} \setcounter{biburlucpenalty}{8000} -% biblatex is very powerful, and you can customize most aspects the reference list and citations. +% biblatex is very powerful, and you can customize most aspects the reference list and citations to suit your needs. +% documentation is here: https://ctan.org/pkg/biblatex %%%%%%%%%% Option to use natbib %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -82,16 +86,16 @@ %%%%%%%%%% Table related packages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage{booktabs}% better quality tables -\usepackage{array}% additional options for table columns +\usepackage{booktabs}% better quality tables, https://ctan.org/pkg/booktabs +\usepackage{array}% additional options for table columns, https://ctan.org/pkg/array -%\usepackage{tabularx} +%\usepackage{tabularx}% https://ctan.org/pkg/tabularx -%\usepackage{dcolumn} % alignment on decimal places +%\usepackage{dcolumn}% alignment on decimal place, https://ctan.org/pkg/dcolumn %\newcolumntype{d}[1]{D{.}{.}{#1}} -%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Back in the typewriter era, double spaced lines were convenient for editing with a pencil. %% In typography, the separation between lines is called "leading", and it is usually set in @@ -99,74 +103,51 @@ %% to change the line separation, the most attractive results will be obtained by changing the %% leading in proportion to the the current font size, rather than just doubling the space. -%% The setspace package provides a tool for changing line separation (use these here) +%% The setspace package provides a tool for changing line separation (use thesetwo here) % -%\usepackage{setspace} -%\setstretch{1.1}% you can choose some other value for the stretch of space between lines +% \usepackage{setspace}% documentation at https://ctan.org/pkg/setspace +% \setstretch{1.1}% you can choose some other value for the stretch of space between lines % %% Use the these commands AFTER the frontmatter % -%\onehalfspacing -%\doublespacing -%\singlespacing % will turn these effects off (you can use these anywhere in the document) +% \onehalfspacing +% \doublespacing +% \singlespacing % will turn these effects off (you can use these anywhere in the document) %% The best result may be to stay with leading selected by the typographer who set up the font. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! -% - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata -% - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, -} -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. + pdfauthortitle={}, + % If you have a title, you can include it here. } - -%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - \begin{document} - %%% edit the following commands to match your thesis %%%%%%%%%% \title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} @@ -176,25 +157,31 @@ % note on names: most of the following names are made up; Silas Holman was a professor at MIT in the 19th century. -\Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876] +\Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876][MBA, Ferengi School of Management, 2022] %\Author{Luisa Hernández}{Department of Research}[B.S. Mechanical Engineering, UCLA, 2018][M.S. Stellar Interiors, Vulcan Science Academy, 2020][MBA, Ferengi School of Management, 2022] +%\Author{Thurston Howell III}{Department of Economics} % Use once for each degree fulfilled by thesis +% For two degrees from one department, leave the department argument blank for the second degree {}. \Degree{Bachelor of Science in Physics}{Department of Physics} +%\Degree{Master of Science in Physics}{} %\Degree{Bachelor of Science in Mechanical Engineering}{Department of Mechanical Engineering} % If there is more than one supervisor, use the \Supervisor command for each. \Supervisor{Edward C. Pickering}{Professor of Physics} -%\Supervisor{Secunda Castor}{Department of Mechanical Engineering} +%\Supervisor{Secunda Castor}{Professor of Research} +%\Supervisor{Quintus Castor}{Professor of Log Dams} % Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) % If more than one department, use more than once +% **If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}.** \Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} -%\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Second Degree Department} +%\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} +%\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} % If your title page is overflowing (from too many names, degrees, etc.), you can scale % down the Signature block at the bottom with this command, or use another creative solution... -%\SignatureBlockSize{\small} +%\SignatureBlockSize{\small} %\SignatureBlockSize{\footnotesize} % Usage: \DegreeDate{Month}{year} % Valid degree months are September, February, or June. @@ -215,9 +202,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page - %%%%%%%%% Contents that you need to write follows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -226,22 +210,18 @@ %%% Frontmatter (write this material in the mentioned files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex \begin{abstract} \input{abstract.tex}% in this case, use \input rather than \include because you are inside an environment \end{abstract} - \cleardoublepage -\include{acknowledgments.tex}% - \cleardoublepage +\include{acknowledgments.tex} \include{biography.tex}% optional, see MIT Libraries https://libraries.mit.edu/distinctive-collections/thesis-specs/#format - \cleardoublepage -%%% Table of contents and lists of stuff (edit only if you want different lists) %%%%%%%%%%%%%%%% +%%% Table of contents and lists of stuff (delete lists you don't need, e.g., if no tables) %%%%%%%% \tableofcontents \listoffigures @@ -250,11 +230,12 @@ %%% Chapters of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% If you really feel the need to engage in "double spacing", you can start here... +%% If you want to use "double spacing", you can start here... \include{chapter1.tex} %\include{chapter2.tex} %\include{chapter3.tex} +%\include{chapter4.tex} %%% Appendicies of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -265,7 +246,7 @@ %%% Bibliography %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -{\raggedright% to avoid stretched white space and split urls; DELETE if you prefer justified text +{ \raggedright% to avoid stretched white space and split urls; DELETE THIS if you prefer justified text % \printbibliography[title={References},heading=bibintoc] } diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Heros-Stix2.tex b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Heros-Stix2.tex index 3985d9f560..1ae057c0cd 100644 --- a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Heros-Stix2.tex +++ b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Heros-Stix2.tex @@ -2,45 +2,46 @@ % !BIB TS-program = biber % !BIB program = biber -% This file is MIT-Thesis.tex, a template for producing MIT theses with the mitthesis class. -% Version: 1.01, 2023/07/21 +% This file is MIT-Thesis.tex, a LaTeX template for formatting an MIT thesis with the mitthesis class. +% +% Version: 1.06, 2023/08/28 +% % Author: John H. Lienhard (c) 2023. Reuse under the MIT license: https://ctan.org/license/mit -% Documentation: https://ctan.org/pkg/mitthesis +% Documentation is here: https://ctan.org/pkg/mitthesis %% Don't modify the \DocumentMetadata command unless you know what it does. %% If this command throws an "undefined" error, your latex system is out of date: try commenting this command out. -\DocumentMetadata -{ +\DocumentMetadata{ pdfstandard = a-2b, pdfversion = 1.7, lang = en-US, -% debug = {xmp-export}, % output xmpi file to directly examine metadata +% debug = {xmp-export}, % uncomment to output a separate xmpi file showing the metadata } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\documentclass[fontset=heros-stix2]{mitthesis} +\documentclass[fontset=heros-stix2]{mitthesis} %,fontset=libertine ,fontset=newtx-sans-text, fontset=heros-stix2, fontset=stix2 % -% option [twoside] gives facing-page behavior for printing; omitting it will eliminate even-numbered blank pages. +% option [twoside] gives facing-page behavior for printing; omitting twoside will eliminate even-numbered blank pages. % option [lineno] provides line numbers, as for editing -% option [mydesign] loads titlesec, enumitem, caption, subcaption - you may edit the mydesign.tex file as you like it. +% option [mydesign] loads packages for color, title and list formats, margins, or captions: edit mydesign.tex to change defaults. % option [fontset] is a keyvalue which can be: % pdftex or unicode engines: defaultfonts, libertine, lucida % pdftex only: fira-newtxsf, newtx, newtx-sans-text % unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 -% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the latex font". +% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the LaTeX font". % You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. % If you are using multiple languages, load the babel package in your fontset file, before the fonts. %%%%%%%%% Packages used in sample chapters (not otherwise required) %%%%%%% %% Package for code listing in Appendix A. -\usepackage{listings} +\usepackage{listings}% documentation is here https://ctan.org/pkg/listings %% Set chemical formulas nicely -\usepackage[version=4]{mhchem} +\usepackage[version=4]{mhchem}% documentation is here https://ctan.org/pkg/mhchem -%% Latin filler used in Chapter 1, with a test for package version date +%% Latin filler used in Chapter 1, with a test for package version date. https://ctan.org/pkg/lipsum \usepackage{lipsum} \IfPackageAtLeastTF{lipsum}{2021/09/20}{\setlipsum{auto-lang=false}}{} @@ -55,15 +56,18 @@ %%%%%%%%% Representative set-up for biblatex %%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage[style=ext-numeric-comp,giveninits=true,maxbibnames=10,sorting=none,articlein=false,]{biblatex} +\usepackage[style=ieee,maxbibnames=10,sorting=none]{biblatex}% style=ext-numeric-comp,articlein=false,giveninits=true + \DefineBibliographyStrings{english}{url= \textsc{url} , }% replaces default "[Online]. Available" by "URL" + -\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= +\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= CHANGE %% These two commands enable line breaks in long URLs in the bibliography (delete if you don't want that) \setcounter{biburllcpenalty}{7000} \setcounter{biburlucpenalty}{8000} -% biblatex is very powerful, and you can customize most aspects the reference list and citations. +% biblatex is very powerful, and you can customize most aspects the reference list and citations to suit your needs. +% documentation is here: https://ctan.org/pkg/biblatex %%%%%%%%%% Option to use natbib %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -82,16 +86,16 @@ %%%%%%%%%% Table related packages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage{booktabs}% better quality tables -\usepackage{array}% additional options for table columns +\usepackage{booktabs}% better quality tables, https://ctan.org/pkg/booktabs +\usepackage{array}% additional options for table columns, https://ctan.org/pkg/array -%\usepackage{tabularx} +%\usepackage{tabularx}% https://ctan.org/pkg/tabularx -%\usepackage{dcolumn} % alignment on decimal places +%\usepackage{dcolumn}% alignment on decimal place, https://ctan.org/pkg/dcolumn %\newcolumntype{d}[1]{D{.}{.}{#1}} -%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Back in the typewriter era, double spaced lines were convenient for editing with a pencil. %% In typography, the separation between lines is called "leading", and it is usually set in @@ -99,73 +103,51 @@ %% to change the line separation, the most attractive results will be obtained by changing the %% leading in proportion to the the current font size, rather than just doubling the space. -%% The setspace package provides a tool for changing line separation (use these here) +%% The setspace package provides a tool for changing line separation (use thesetwo here) % -%\usepackage{setspace} -%\setstretch{1.1}% you can choose some other value for the stretch of space between lines +% \usepackage{setspace}% documentation at https://ctan.org/pkg/setspace +% \setstretch{1.1}% you can choose some other value for the stretch of space between lines % %% Use the these commands AFTER the frontmatter % -%\onehalfspacing -%\doublespacing -%\singlespacing % will turn these effects off (you can use these anywhere in the document) +% \onehalfspacing +% \doublespacing +% \singlespacing % will turn these effects off (you can use these anywhere in the document) %% The best result may be to stay with leading selected by the typographer who set up the font. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! -% - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, + pdfauthortitle={}, + % If you have a title, you can include it here. } -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. -} - -%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} - %%% edit the following commands to match your thesis %%%%%%%%%% \title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} @@ -177,6 +159,7 @@ \Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876][MBA, Ferengi School of Management, 2022] %\Author{Luisa Hernández}{Department of Research}[B.S. Mechanical Engineering, UCLA, 2018][M.S. Stellar Interiors, Vulcan Science Academy, 2020][MBA, Ferengi School of Management, 2022] +%\Author{Thurston Howell III}{Department of Economics} % Use once for each degree fulfilled by thesis % For two degrees from one department, leave the department argument blank for the second degree {}. @@ -191,7 +174,7 @@ % Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) % If more than one department, use more than once -% If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}. +% **If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}.** \Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} %\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} %\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} @@ -219,9 +202,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page - %%%%%%%%% Contents that you need to write follows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -230,19 +210,15 @@ %%% Frontmatter (write this material in the mentioned files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex \begin{abstract} \input{abstract.tex}% in this case, use \input rather than \include because you are inside an environment \end{abstract} - \cleardoublepage -\include{acknowledgments.tex}% - \cleardoublepage +\include{acknowledgments.tex} \include{biography.tex}% optional, see MIT Libraries https://libraries.mit.edu/distinctive-collections/thesis-specs/#format - \cleardoublepage %%% Table of contents and lists of stuff (delete lists you don't need, e.g., if no tables) %%%%%%%% @@ -254,11 +230,12 @@ %%% Chapters of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% If you really feel the need to engage in "double spacing", you can start here... +%% If you want to use "double spacing", you can start here... \include{chapter1.tex} %\include{chapter2.tex} %\include{chapter3.tex} +%\include{chapter4.tex} %%% Appendicies of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -269,7 +246,7 @@ %%% Bibliography %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -{\raggedright% to avoid stretched white space and split urls; DELETE if you prefer justified text +{ \raggedright% to avoid stretched white space and split urls; DELETE THIS if you prefer justified text % \printbibliography[title={References},heading=bibintoc] } diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Libertine.tex b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Libertine.tex index a4c37ddedb..8fa97df9b0 100644 --- a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Libertine.tex +++ b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Libertine.tex @@ -2,45 +2,46 @@ % !BIB TS-program = biber % !BIB program = biber -% This file is MIT-Thesis.tex, a template for producing MIT theses with the mitthesis class. -% Version: 1.01, 2023/07/21 +% This file is MIT-Thesis.tex, a LaTeX template for formatting an MIT thesis with the mitthesis class. +% +% Version: 1.06, 2023/08/28 +% % Author: John H. Lienhard (c) 2023. Reuse under the MIT license: https://ctan.org/license/mit -% Documentation: https://ctan.org/pkg/mitthesis +% Documentation is here: https://ctan.org/pkg/mitthesis %% Don't modify the \DocumentMetadata command unless you know what it does. %% If this command throws an "undefined" error, your latex system is out of date: try commenting this command out. -\DocumentMetadata -{ +\DocumentMetadata{ pdfstandard = a-2b, pdfversion = 1.7, lang = en-US, -% debug = {xmp-export}, % output xmpi file to directly examine metadata +% debug = {xmp-export}, % uncomment to output a separate xmpi file showing the metadata } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\documentclass[fontset=libertine]{mitthesis} +\documentclass[fontset=libertine]{mitthesis} %,fontset=libertine ,fontset=newtx-sans-text, fontset=heros-stix2, fontset=stix2 % -% option [twoside] gives facing-page behavior for printing; omitting it will eliminate even-numbered blank pages. +% option [twoside] gives facing-page behavior for printing; omitting twoside will eliminate even-numbered blank pages. % option [lineno] provides line numbers, as for editing -% option [mydesign] loads titlesec, enumitem, caption, subcaption - you may edit the mydesign.tex file as you like it. +% option [mydesign] loads packages for color, title and list formats, margins, or captions: edit mydesign.tex to change defaults. % option [fontset] is a keyvalue which can be: % pdftex or unicode engines: defaultfonts, libertine, lucida % pdftex only: fira-newtxsf, newtx, newtx-sans-text % unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 -% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the latex font". +% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the LaTeX font". % You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. % If you are using multiple languages, load the babel package in your fontset file, before the fonts. %%%%%%%%% Packages used in sample chapters (not otherwise required) %%%%%%% %% Package for code listing in Appendix A. -\usepackage{listings} +\usepackage{listings}% documentation is here https://ctan.org/pkg/listings %% Set chemical formulas nicely -\usepackage[version=4]{mhchem} +\usepackage[version=4]{mhchem}% documentation is here https://ctan.org/pkg/mhchem -%% Latin filler used in Chapter 1, with a test for package version date +%% Latin filler used in Chapter 1, with a test for package version date. https://ctan.org/pkg/lipsum \usepackage{lipsum} \IfPackageAtLeastTF{lipsum}{2021/09/20}{\setlipsum{auto-lang=false}}{} @@ -55,15 +56,18 @@ %%%%%%%%% Representative set-up for biblatex %%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage[style=ext-numeric-comp,giveninits=true,maxbibnames=10,sorting=none,articlein=false,]{biblatex} +\usepackage[style=ieee,maxbibnames=10,sorting=none]{biblatex}% style=ext-numeric-comp,articlein=false,giveninits=true + \DefineBibliographyStrings{english}{url= \textsc{url} , }% replaces default "[Online]. Available" by "URL" + -\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= +\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= CHANGE %% These two commands enable line breaks in long URLs in the bibliography (delete if you don't want that) \setcounter{biburllcpenalty}{7000} \setcounter{biburlucpenalty}{8000} -% biblatex is very powerful, and you can customize most aspects the reference list and citations. +% biblatex is very powerful, and you can customize most aspects the reference list and citations to suit your needs. +% documentation is here: https://ctan.org/pkg/biblatex %%%%%%%%%% Option to use natbib %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -82,16 +86,16 @@ %%%%%%%%%% Table related packages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage{booktabs}% better quality tables -\usepackage{array}% additional options for table columns +\usepackage{booktabs}% better quality tables, https://ctan.org/pkg/booktabs +\usepackage{array}% additional options for table columns, https://ctan.org/pkg/array -%\usepackage{tabularx} +%\usepackage{tabularx}% https://ctan.org/pkg/tabularx -%\usepackage{dcolumn} % alignment on decimal places +%\usepackage{dcolumn}% alignment on decimal place, https://ctan.org/pkg/dcolumn %\newcolumntype{d}[1]{D{.}{.}{#1}} -%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Back in the typewriter era, double spaced lines were convenient for editing with a pencil. %% In typography, the separation between lines is called "leading", and it is usually set in @@ -99,73 +103,51 @@ %% to change the line separation, the most attractive results will be obtained by changing the %% leading in proportion to the the current font size, rather than just doubling the space. -%% The setspace package provides a tool for changing line separation (use these here) +%% The setspace package provides a tool for changing line separation (use thesetwo here) % -%\usepackage{setspace} -%\setstretch{1.1}% you can choose some other value for the stretch of space between lines +% \usepackage{setspace}% documentation at https://ctan.org/pkg/setspace +% \setstretch{1.1}% you can choose some other value for the stretch of space between lines % %% Use the these commands AFTER the frontmatter % -%\onehalfspacing -%\doublespacing -%\singlespacing % will turn these effects off (you can use these anywhere in the document) +% \onehalfspacing +% \doublespacing +% \singlespacing % will turn these effects off (you can use these anywhere in the document) %% The best result may be to stay with leading selected by the typographer who set up the font. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! -% - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, + pdfauthortitle={}, + % If you have a title, you can include it here. } -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. -} - -%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} - %%% edit the following commands to match your thesis %%%%%%%%%% \title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} @@ -177,6 +159,7 @@ \Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876][MBA, Ferengi School of Management, 2022] %\Author{Luisa Hernández}{Department of Research}[B.S. Mechanical Engineering, UCLA, 2018][M.S. Stellar Interiors, Vulcan Science Academy, 2020][MBA, Ferengi School of Management, 2022] +%\Author{Thurston Howell III}{Department of Economics} % Use once for each degree fulfilled by thesis % For two degrees from one department, leave the department argument blank for the second degree {}. @@ -191,7 +174,7 @@ % Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) % If more than one department, use more than once -% If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}. +% **If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}.** \Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} %\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} %\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} @@ -219,9 +202,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page - %%%%%%%%% Contents that you need to write follows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -230,19 +210,15 @@ %%% Frontmatter (write this material in the mentioned files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex \begin{abstract} \input{abstract.tex}% in this case, use \input rather than \include because you are inside an environment \end{abstract} - \cleardoublepage -\include{acknowledgments.tex}% - \cleardoublepage +\include{acknowledgments.tex} \include{biography.tex}% optional, see MIT Libraries https://libraries.mit.edu/distinctive-collections/thesis-specs/#format - \cleardoublepage %%% Table of contents and lists of stuff (delete lists you don't need, e.g., if no tables) %%%%%%%% @@ -254,11 +230,12 @@ %%% Chapters of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% If you really feel the need to engage in "double spacing", you can start here... +%% If you want to use "double spacing", you can start here... \include{chapter1.tex} %\include{chapter2.tex} %\include{chapter3.tex} +%\include{chapter4.tex} %%% Appendicies of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -269,7 +246,7 @@ %%% Bibliography %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -{\raggedright% to avoid stretched white space and split urls; DELETE if you prefer justified text +{ \raggedright% to avoid stretched white space and split urls; DELETE THIS if you prefer justified text % \printbibliography[title={References},heading=bibintoc] } diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Lucida.tex b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Lucida.tex index 2c3a8e342c..1af3c90754 100644 --- a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Lucida.tex +++ b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Lucida.tex @@ -2,45 +2,46 @@ % !BIB TS-program = biber % !BIB program = biber -% This file is MIT-Thesis.tex, a template for producing MIT theses with the mitthesis class. -% Version: 1.01, 2023/07/21 +% This file is MIT-Thesis.tex, a LaTeX template for formatting an MIT thesis with the mitthesis class. +% +% Version: 1.06, 2023/08/28 +% % Author: John H. Lienhard (c) 2023. Reuse under the MIT license: https://ctan.org/license/mit -% Documentation: https://ctan.org/pkg/mitthesis +% Documentation is here: https://ctan.org/pkg/mitthesis %% Don't modify the \DocumentMetadata command unless you know what it does. %% If this command throws an "undefined" error, your latex system is out of date: try commenting this command out. -\DocumentMetadata -{ +\DocumentMetadata{ pdfstandard = a-2b, pdfversion = 1.7, lang = en-US, -% debug = {xmp-export}, % output xmpi file to directly examine metadata +% debug = {xmp-export}, % uncomment to output a separate xmpi file showing the metadata } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\documentclass[fontset=lucida]{mitthesis} +\documentclass[fontset=lucida]{mitthesis} %,fontset=libertine ,fontset=newtx-sans-text, fontset=heros-stix2, fontset=stix2 % -% option [twoside] gives facing-page behavior for printing; omitting it will eliminate even-numbered blank pages. +% option [twoside] gives facing-page behavior for printing; omitting twoside will eliminate even-numbered blank pages. % option [lineno] provides line numbers, as for editing -% option [mydesign] loads titlesec, enumitem, caption, subcaption - you may edit the mydesign.tex file as you like it. +% option [mydesign] loads packages for color, title and list formats, margins, or captions: edit mydesign.tex to change defaults. % option [fontset] is a keyvalue which can be: % pdftex or unicode engines: defaultfonts, libertine, lucida % pdftex only: fira-newtxsf, newtx, newtx-sans-text % unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 -% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the latex font". +% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the LaTeX font". % You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. % If you are using multiple languages, load the babel package in your fontset file, before the fonts. %%%%%%%%% Packages used in sample chapters (not otherwise required) %%%%%%% %% Package for code listing in Appendix A. -\usepackage{listings} +\usepackage{listings}% documentation is here https://ctan.org/pkg/listings %% Set chemical formulas nicely -\usepackage[version=4]{mhchem} +\usepackage[version=4]{mhchem}% documentation is here https://ctan.org/pkg/mhchem -%% Latin filler used in Chapter 1, with a test for package version date +%% Latin filler used in Chapter 1, with a test for package version date. https://ctan.org/pkg/lipsum \usepackage{lipsum} \IfPackageAtLeastTF{lipsum}{2021/09/20}{\setlipsum{auto-lang=false}}{} @@ -55,15 +56,18 @@ %%%%%%%%% Representative set-up for biblatex %%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage[style=ext-numeric-comp,giveninits=true,maxbibnames=10,sorting=none,articlein=false,]{biblatex} +\usepackage[style=ieee,maxbibnames=10,sorting=none]{biblatex}% style=ext-numeric-comp,articlein=false,giveninits=true + \DefineBibliographyStrings{english}{url= \textsc{url} , }% replaces default "[Online]. Available" by "URL" + -\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= +\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= CHANGE %% These two commands enable line breaks in long URLs in the bibliography (delete if you don't want that) \setcounter{biburllcpenalty}{7000} \setcounter{biburlucpenalty}{8000} -% biblatex is very powerful, and you can customize most aspects the reference list and citations. +% biblatex is very powerful, and you can customize most aspects the reference list and citations to suit your needs. +% documentation is here: https://ctan.org/pkg/biblatex %%%%%%%%%% Option to use natbib %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -82,16 +86,16 @@ %%%%%%%%%% Table related packages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage{booktabs}% better quality tables -\usepackage{array}% additional options for table columns +\usepackage{booktabs}% better quality tables, https://ctan.org/pkg/booktabs +\usepackage{array}% additional options for table columns, https://ctan.org/pkg/array -%\usepackage{tabularx} +%\usepackage{tabularx}% https://ctan.org/pkg/tabularx -%\usepackage{dcolumn} % alignment on decimal places +%\usepackage{dcolumn}% alignment on decimal place, https://ctan.org/pkg/dcolumn %\newcolumntype{d}[1]{D{.}{.}{#1}} -%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Back in the typewriter era, double spaced lines were convenient for editing with a pencil. %% In typography, the separation between lines is called "leading", and it is usually set in @@ -99,73 +103,51 @@ %% to change the line separation, the most attractive results will be obtained by changing the %% leading in proportion to the the current font size, rather than just doubling the space. -%% The setspace package provides a tool for changing line separation (use these here) +%% The setspace package provides a tool for changing line separation (use thesetwo here) % -%\usepackage{setspace} -%\setstretch{1.1}% you can choose some other value for the stretch of space between lines +% \usepackage{setspace}% documentation at https://ctan.org/pkg/setspace +% \setstretch{1.1}% you can choose some other value for the stretch of space between lines % %% Use the these commands AFTER the frontmatter % -%\onehalfspacing -%\doublespacing -%\singlespacing % will turn these effects off (you can use these anywhere in the document) +% \onehalfspacing +% \doublespacing +% \singlespacing % will turn these effects off (you can use these anywhere in the document) %% The best result may be to stay with leading selected by the typographer who set up the font. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! -% - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, + pdfauthortitle={}, + % If you have a title, you can include it here. } -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. -} - -%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} - %%% edit the following commands to match your thesis %%%%%%%%%% \title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} @@ -177,6 +159,7 @@ \Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876][MBA, Ferengi School of Management, 2022] %\Author{Luisa Hernández}{Department of Research}[B.S. Mechanical Engineering, UCLA, 2018][M.S. Stellar Interiors, Vulcan Science Academy, 2020][MBA, Ferengi School of Management, 2022] +%\Author{Thurston Howell III}{Department of Economics} % Use once for each degree fulfilled by thesis % For two degrees from one department, leave the department argument blank for the second degree {}. @@ -191,7 +174,7 @@ % Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) % If more than one department, use more than once -% If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}. +% **If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}.** \Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} %\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} %\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} @@ -219,9 +202,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page - %%%%%%%%% Contents that you need to write follows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -230,19 +210,15 @@ %%% Frontmatter (write this material in the mentioned files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex \begin{abstract} \input{abstract.tex}% in this case, use \input rather than \include because you are inside an environment \end{abstract} - \cleardoublepage -\include{acknowledgments.tex}% - \cleardoublepage +\include{acknowledgments.tex} \include{biography.tex}% optional, see MIT Libraries https://libraries.mit.edu/distinctive-collections/thesis-specs/#format - \cleardoublepage %%% Table of contents and lists of stuff (delete lists you don't need, e.g., if no tables) %%%%%%%% @@ -254,11 +230,12 @@ %%% Chapters of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% If you really feel the need to engage in "double spacing", you can start here... +%% If you want to use "double spacing", you can start here... \include{chapter1.tex} %\include{chapter2.tex} %\include{chapter3.tex} +%\include{chapter4.tex} %%% Appendicies of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -269,7 +246,7 @@ %%% Bibliography %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -{\raggedright% to avoid stretched white space and split urls; DELETE if you prefer justified text +{ \raggedright% to avoid stretched white space and split urls; DELETE THIS if you prefer justified text % \printbibliography[title={References},heading=bibintoc] } diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx-sans-text.tex b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx-sans-text.tex index 31832cc0ce..87ad88c57e 100644 --- a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx-sans-text.tex +++ b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx-sans-text.tex @@ -2,45 +2,46 @@ % !BIB TS-program = biber % !BIB program = biber -% This file is MIT-Thesis.tex, a template for producing MIT theses with the mitthesis class. -% Version: 1.01, 2023/07/21 +% This file is MIT-Thesis.tex, a LaTeX template for formatting an MIT thesis with the mitthesis class. +% +% Version: 1.06, 2023/08/28 +% % Author: John H. Lienhard (c) 2023. Reuse under the MIT license: https://ctan.org/license/mit -% Documentation: https://ctan.org/pkg/mitthesis +% Documentation is here: https://ctan.org/pkg/mitthesis %% Don't modify the \DocumentMetadata command unless you know what it does. %% If this command throws an "undefined" error, your latex system is out of date: try commenting this command out. -\DocumentMetadata -{ +\DocumentMetadata{ pdfstandard = a-2b, pdfversion = 1.7, lang = en-US, -% debug = {xmp-export}, % output xmpi file to directly examine metadata +% debug = {xmp-export}, % uncomment to output a separate xmpi file showing the metadata } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\documentclass[fontset=newtx-sans-text]{mitthesis} +\documentclass[fontset=newtx-sans-text]{mitthesis} %,fontset=libertine ,fontset=newtx-sans-text, fontset=heros-stix2, fontset=stix2 % -% option [twoside] gives facing-page behavior for printing; omitting it will eliminate even-numbered blank pages. +% option [twoside] gives facing-page behavior for printing; omitting twoside will eliminate even-numbered blank pages. % option [lineno] provides line numbers, as for editing -% option [mydesign] loads titlesec, enumitem, caption, subcaption - you may edit the mydesign.tex file as you like it. +% option [mydesign] loads packages for color, title and list formats, margins, or captions: edit mydesign.tex to change defaults. % option [fontset] is a keyvalue which can be: % pdftex or unicode engines: defaultfonts, libertine, lucida % pdftex only: fira-newtxsf, newtx, newtx-sans-text % unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 -% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the latex font". +% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the LaTeX font". % You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. % If you are using multiple languages, load the babel package in your fontset file, before the fonts. %%%%%%%%% Packages used in sample chapters (not otherwise required) %%%%%%% %% Package for code listing in Appendix A. -\usepackage{listings} +\usepackage{listings}% documentation is here https://ctan.org/pkg/listings %% Set chemical formulas nicely -\usepackage[version=4]{mhchem} +\usepackage[version=4]{mhchem}% documentation is here https://ctan.org/pkg/mhchem -%% Latin filler used in Chapter 1, with a test for package version date +%% Latin filler used in Chapter 1, with a test for package version date. https://ctan.org/pkg/lipsum \usepackage{lipsum} \IfPackageAtLeastTF{lipsum}{2021/09/20}{\setlipsum{auto-lang=false}}{} @@ -55,15 +56,18 @@ %%%%%%%%% Representative set-up for biblatex %%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage[style=ext-numeric-comp,giveninits=true,maxbibnames=10,sorting=none,articlein=false,]{biblatex} +\usepackage[style=ieee,maxbibnames=10,sorting=none]{biblatex}% style=ext-numeric-comp,articlein=false,giveninits=true + \DefineBibliographyStrings{english}{url= \textsc{url} , }% replaces default "[Online]. Available" by "URL" + -\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= +\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= CHANGE %% These two commands enable line breaks in long URLs in the bibliography (delete if you don't want that) \setcounter{biburllcpenalty}{7000} \setcounter{biburlucpenalty}{8000} -% biblatex is very powerful, and you can customize most aspects the reference list and citations. +% biblatex is very powerful, and you can customize most aspects the reference list and citations to suit your needs. +% documentation is here: https://ctan.org/pkg/biblatex %%%%%%%%%% Option to use natbib %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -82,16 +86,16 @@ %%%%%%%%%% Table related packages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage{booktabs}% better quality tables -\usepackage{array}% additional options for table columns +\usepackage{booktabs}% better quality tables, https://ctan.org/pkg/booktabs +\usepackage{array}% additional options for table columns, https://ctan.org/pkg/array -%\usepackage{tabularx} +%\usepackage{tabularx}% https://ctan.org/pkg/tabularx -%\usepackage{dcolumn} % alignment on decimal places +%\usepackage{dcolumn}% alignment on decimal place, https://ctan.org/pkg/dcolumn %\newcolumntype{d}[1]{D{.}{.}{#1}} -%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Back in the typewriter era, double spaced lines were convenient for editing with a pencil. %% In typography, the separation between lines is called "leading", and it is usually set in @@ -99,73 +103,51 @@ %% to change the line separation, the most attractive results will be obtained by changing the %% leading in proportion to the the current font size, rather than just doubling the space. -%% The setspace package provides a tool for changing line separation (use these here) +%% The setspace package provides a tool for changing line separation (use thesetwo here) % -%\usepackage{setspace} -%\setstretch{1.1}% you can choose some other value for the stretch of space between lines +% \usepackage{setspace}% documentation at https://ctan.org/pkg/setspace +% \setstretch{1.1}% you can choose some other value for the stretch of space between lines % %% Use the these commands AFTER the frontmatter % -%\onehalfspacing -%\doublespacing -%\singlespacing % will turn these effects off (you can use these anywhere in the document) +% \onehalfspacing +% \doublespacing +% \singlespacing % will turn these effects off (you can use these anywhere in the document) %% The best result may be to stay with leading selected by the typographer who set up the font. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! -% - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, + pdfauthortitle={}, + % If you have a title, you can include it here. } -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. -} - -%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} - %%% edit the following commands to match your thesis %%%%%%%%%% \title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} @@ -177,6 +159,7 @@ \Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876][MBA, Ferengi School of Management, 2022] %\Author{Luisa Hernández}{Department of Research}[B.S. Mechanical Engineering, UCLA, 2018][M.S. Stellar Interiors, Vulcan Science Academy, 2020][MBA, Ferengi School of Management, 2022] +%\Author{Thurston Howell III}{Department of Economics} % Use once for each degree fulfilled by thesis % For two degrees from one department, leave the department argument blank for the second degree {}. @@ -191,7 +174,7 @@ % Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) % If more than one department, use more than once -% If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}. +% **If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}.** \Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} %\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} %\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} @@ -219,9 +202,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page - %%%%%%%%% Contents that you need to write follows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -230,19 +210,15 @@ %%% Frontmatter (write this material in the mentioned files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex \begin{abstract} \input{abstract.tex}% in this case, use \input rather than \include because you are inside an environment \end{abstract} - \cleardoublepage -\include{acknowledgments.tex}% - \cleardoublepage +\include{acknowledgments.tex} \include{biography.tex}% optional, see MIT Libraries https://libraries.mit.edu/distinctive-collections/thesis-specs/#format - \cleardoublepage %%% Table of contents and lists of stuff (delete lists you don't need, e.g., if no tables) %%%%%%%% @@ -254,11 +230,12 @@ %%% Chapters of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% If you really feel the need to engage in "double spacing", you can start here... +%% If you want to use "double spacing", you can start here... \include{chapter1.tex} %\include{chapter2.tex} %\include{chapter3.tex} +%\include{chapter4.tex} %%% Appendicies of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -269,7 +246,7 @@ %%% Bibliography %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -{\raggedright% to avoid stretched white space and split urls; DELETE if you prefer justified text +{ \raggedright% to avoid stretched white space and split urls; DELETE THIS if you prefer justified text % \printbibliography[title={References},heading=bibintoc] } diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx.tex b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx.tex index fcc126e440..eb96cc7892 100644 --- a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx.tex +++ b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Newtx.tex @@ -2,45 +2,46 @@ % !BIB TS-program = biber % !BIB program = biber -% This file is MIT-Thesis.tex, a template for producing MIT theses with the mitthesis class. -% Version: 1.01, 2023/07/21 +% This file is MIT-Thesis.tex, a LaTeX template for formatting an MIT thesis with the mitthesis class. +% +% Version: 1.06, 2023/08/28 +% % Author: John H. Lienhard (c) 2023. Reuse under the MIT license: https://ctan.org/license/mit -% Documentation: https://ctan.org/pkg/mitthesis +% Documentation is here: https://ctan.org/pkg/mitthesis %% Don't modify the \DocumentMetadata command unless you know what it does. %% If this command throws an "undefined" error, your latex system is out of date: try commenting this command out. -\DocumentMetadata -{ +\DocumentMetadata{ pdfstandard = a-2b, pdfversion = 1.7, lang = en-US, -% debug = {xmp-export}, % output xmpi file to directly examine metadata +% debug = {xmp-export}, % uncomment to output a separate xmpi file showing the metadata } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\documentclass[fontset=newtx]{mitthesis} +\documentclass[fontset=newtx]{mitthesis} %,fontset=libertine ,fontset=newtx-sans-text, fontset=heros-stix2, fontset=stix2 % -% option [twoside] gives facing-page behavior for printing; omitting it will eliminate even-numbered blank pages. +% option [twoside] gives facing-page behavior for printing; omitting twoside will eliminate even-numbered blank pages. % option [lineno] provides line numbers, as for editing -% option [mydesign] loads titlesec, enumitem, caption, subcaption - you may edit the mydesign.tex file as you like it. +% option [mydesign] loads packages for color, title and list formats, margins, or captions: edit mydesign.tex to change defaults. % option [fontset] is a keyvalue which can be: % pdftex or unicode engines: defaultfonts, libertine, lucida % pdftex only: fira-newtxsf, newtx, newtx-sans-text % unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 -% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the latex font". +% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the LaTeX font". % You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. % If you are using multiple languages, load the babel package in your fontset file, before the fonts. %%%%%%%%% Packages used in sample chapters (not otherwise required) %%%%%%% %% Package for code listing in Appendix A. -\usepackage{listings} +\usepackage{listings}% documentation is here https://ctan.org/pkg/listings %% Set chemical formulas nicely -\usepackage[version=4]{mhchem} +\usepackage[version=4]{mhchem}% documentation is here https://ctan.org/pkg/mhchem -%% Latin filler used in Chapter 1, with a test for package version date +%% Latin filler used in Chapter 1, with a test for package version date. https://ctan.org/pkg/lipsum \usepackage{lipsum} \IfPackageAtLeastTF{lipsum}{2021/09/20}{\setlipsum{auto-lang=false}}{} @@ -55,15 +56,18 @@ %%%%%%%%% Representative set-up for biblatex %%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage[style=ext-numeric-comp,giveninits=true,maxbibnames=10,sorting=none,articlein=false,]{biblatex} +\usepackage[style=ieee,maxbibnames=10,sorting=none]{biblatex}% style=ext-numeric-comp,articlein=false,giveninits=true + \DefineBibliographyStrings{english}{url= \textsc{url} , }% replaces default "[Online]. Available" by "URL" + -\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= +\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= CHANGE %% These two commands enable line breaks in long URLs in the bibliography (delete if you don't want that) \setcounter{biburllcpenalty}{7000} \setcounter{biburlucpenalty}{8000} -% biblatex is very powerful, and you can customize most aspects the reference list and citations. +% biblatex is very powerful, and you can customize most aspects the reference list and citations to suit your needs. +% documentation is here: https://ctan.org/pkg/biblatex %%%%%%%%%% Option to use natbib %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -82,16 +86,16 @@ %%%%%%%%%% Table related packages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage{booktabs}% better quality tables -\usepackage{array}% additional options for table columns +\usepackage{booktabs}% better quality tables, https://ctan.org/pkg/booktabs +\usepackage{array}% additional options for table columns, https://ctan.org/pkg/array -%\usepackage{tabularx} +%\usepackage{tabularx}% https://ctan.org/pkg/tabularx -%\usepackage{dcolumn} % alignment on decimal places +%\usepackage{dcolumn}% alignment on decimal place, https://ctan.org/pkg/dcolumn %\newcolumntype{d}[1]{D{.}{.}{#1}} -%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Back in the typewriter era, double spaced lines were convenient for editing with a pencil. %% In typography, the separation between lines is called "leading", and it is usually set in @@ -99,73 +103,51 @@ %% to change the line separation, the most attractive results will be obtained by changing the %% leading in proportion to the the current font size, rather than just doubling the space. -%% The setspace package provides a tool for changing line separation (use these here) +%% The setspace package provides a tool for changing line separation (use thesetwo here) % -%\usepackage{setspace} -%\setstretch{1.1}% you can choose some other value for the stretch of space between lines +% \usepackage{setspace}% documentation at https://ctan.org/pkg/setspace +% \setstretch{1.1}% you can choose some other value for the stretch of space between lines % %% Use the these commands AFTER the frontmatter % -%\onehalfspacing -%\doublespacing -%\singlespacing % will turn these effects off (you can use these anywhere in the document) +% \onehalfspacing +% \doublespacing +% \singlespacing % will turn these effects off (you can use these anywhere in the document) %% The best result may be to stay with leading selected by the typographer who set up the font. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! -% - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, + pdfauthortitle={}, + % If you have a title, you can include it here. } -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. -} - -%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} - %%% edit the following commands to match your thesis %%%%%%%%%% \title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} @@ -177,6 +159,7 @@ \Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876][MBA, Ferengi School of Management, 2022] %\Author{Luisa Hernández}{Department of Research}[B.S. Mechanical Engineering, UCLA, 2018][M.S. Stellar Interiors, Vulcan Science Academy, 2020][MBA, Ferengi School of Management, 2022] +%\Author{Thurston Howell III}{Department of Economics} % Use once for each degree fulfilled by thesis % For two degrees from one department, leave the department argument blank for the second degree {}. @@ -191,7 +174,7 @@ % Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) % If more than one department, use more than once -% If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}. +% **If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}.** \Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} %\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} %\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} @@ -219,9 +202,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page - %%%%%%%%% Contents that you need to write follows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -230,19 +210,15 @@ %%% Frontmatter (write this material in the mentioned files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex \begin{abstract} \input{abstract.tex}% in this case, use \input rather than \include because you are inside an environment \end{abstract} - \cleardoublepage -\include{acknowledgments.tex}% - \cleardoublepage +\include{acknowledgments.tex} \include{biography.tex}% optional, see MIT Libraries https://libraries.mit.edu/distinctive-collections/thesis-specs/#format - \cleardoublepage %%% Table of contents and lists of stuff (delete lists you don't need, e.g., if no tables) %%%%%%%% @@ -254,11 +230,12 @@ %%% Chapters of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% If you really feel the need to engage in "double spacing", you can start here... +%% If you want to use "double spacing", you can start here... \include{chapter1.tex} %\include{chapter2.tex} %\include{chapter3.tex} +%\include{chapter4.tex} %%% Appendicies of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -269,7 +246,7 @@ %%% Bibliography %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -{\raggedright% to avoid stretched white space and split urls; DELETE if you prefer justified text +{ \raggedright% to avoid stretched white space and split urls; DELETE THIS if you prefer justified text % \printbibliography[title={References},heading=bibintoc] } diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Stix2.tex b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Stix2.tex index 7ac6317072..ffc9657186 100644 --- a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Stix2.tex +++ b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Stix2.tex @@ -2,45 +2,46 @@ % !BIB TS-program = biber % !BIB program = biber -% This file is MIT-Thesis.tex, a template for producing MIT theses with the mitthesis class. -% Version: 1.01, 2023/07/21 +% This file is MIT-Thesis.tex, a LaTeX template for formatting an MIT thesis with the mitthesis class. +% +% Version: 1.06, 2023/08/28 +% % Author: John H. Lienhard (c) 2023. Reuse under the MIT license: https://ctan.org/license/mit -% Documentation: https://ctan.org/pkg/mitthesis +% Documentation is here: https://ctan.org/pkg/mitthesis %% Don't modify the \DocumentMetadata command unless you know what it does. %% If this command throws an "undefined" error, your latex system is out of date: try commenting this command out. -\DocumentMetadata -{ +\DocumentMetadata{ pdfstandard = a-2b, pdfversion = 1.7, lang = en-US, -% debug = {xmp-export}, % output xmpi file to directly examine metadata +% debug = {xmp-export}, % uncomment to output a separate xmpi file showing the metadata } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\documentclass[fontset=stix2]{mitthesis} - -% option [twoside] gives facing-page behavior for printing; omitting it will eliminate even-numbered blank pages. +\documentclass[fontset=stix2]{mitthesis} %,fontset=libertine ,fontset=newtx-sans-text, fontset=heros-stix2, fontset=stix2 +% +% option [twoside] gives facing-page behavior for printing; omitting twoside will eliminate even-numbered blank pages. % option [lineno] provides line numbers, as for editing -% option [mydesign] loads titlesec, enumitem, caption, subcaption - you may edit the mydesign.tex file as you like it. +% option [mydesign] loads packages for color, title and list formats, margins, or captions: edit mydesign.tex to change defaults. % option [fontset] is a keyvalue which can be: % pdftex or unicode engines: defaultfonts, libertine, lucida % pdftex only: fira-newtxsf, newtx, newtx-sans-text % unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 -% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the latex font". +% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the LaTeX font". % You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. % If you are using multiple languages, load the babel package in your fontset file, before the fonts. %%%%%%%%% Packages used in sample chapters (not otherwise required) %%%%%%% %% Package for code listing in Appendix A. -\usepackage{listings} +\usepackage{listings}% documentation is here https://ctan.org/pkg/listings %% Set chemical formulas nicely -\usepackage[version=4]{mhchem} +\usepackage[version=4]{mhchem}% documentation is here https://ctan.org/pkg/mhchem -%% Latin filler used in Chapter 1, with a test for package version date +%% Latin filler used in Chapter 1, with a test for package version date. https://ctan.org/pkg/lipsum \usepackage{lipsum} \IfPackageAtLeastTF{lipsum}{2021/09/20}{\setlipsum{auto-lang=false}}{} @@ -55,15 +56,18 @@ %%%%%%%%% Representative set-up for biblatex %%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage[style=ext-numeric-comp,giveninits=true,maxbibnames=10,sorting=none,articlein=false,]{biblatex} +\usepackage[style=ieee,maxbibnames=10,sorting=none]{biblatex}% style=ext-numeric-comp,articlein=false,giveninits=true + \DefineBibliographyStrings{english}{url= \textsc{url} , }% replaces default "[Online]. Available" by "URL" -\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= + +\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= CHANGE %% These two commands enable line breaks in long URLs in the bibliography (delete if you don't want that) \setcounter{biburllcpenalty}{7000} \setcounter{biburlucpenalty}{8000} -% biblatex is very powerful, and you can customize most aspects the reference list and citations. +% biblatex is very powerful, and you can customize most aspects the reference list and citations to suit your needs. +% documentation is here: https://ctan.org/pkg/biblatex %%%%%%%%%% Option to use natbib %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -82,16 +86,16 @@ %%%%%%%%%% Table related packages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage{booktabs}% better quality tables -\usepackage{array}% additional options for table columns +\usepackage{booktabs}% better quality tables, https://ctan.org/pkg/booktabs +\usepackage{array}% additional options for table columns, https://ctan.org/pkg/array -%\usepackage{tabularx} +%\usepackage{tabularx}% https://ctan.org/pkg/tabularx -%\usepackage{dcolumn} % alignment on decimal places +%\usepackage{dcolumn}% alignment on decimal place, https://ctan.org/pkg/dcolumn %\newcolumntype{d}[1]{D{.}{.}{#1}} -%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Back in the typewriter era, double spaced lines were convenient for editing with a pencil. %% In typography, the separation between lines is called "leading", and it is usually set in @@ -99,73 +103,51 @@ %% to change the line separation, the most attractive results will be obtained by changing the %% leading in proportion to the the current font size, rather than just doubling the space. -%% The setspace package provides a tool for changing line separation (use these here) +%% The setspace package provides a tool for changing line separation (use thesetwo here) % -%\usepackage{setspace} -%\setstretch{1.1}% you can choose some other value for the stretch of space between lines +% \usepackage{setspace}% documentation at https://ctan.org/pkg/setspace +% \setstretch{1.1}% you can choose some other value for the stretch of space between lines % %% Use the these commands AFTER the frontmatter % -%\onehalfspacing -%\doublespacing -%\singlespacing % will turn these effects off (you can use these anywhere in the document) +% \onehalfspacing +% \doublespacing +% \singlespacing % will turn these effects off (you can use these anywhere in the document) %% The best result may be to stay with leading selected by the typographer who set up the font. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! -% - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata -% - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, -} -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. + pdfauthortitle={}, + % If you have a title, you can include it here. } - -%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} - %%% edit the following commands to match your thesis %%%%%%%%%% \title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} @@ -177,6 +159,7 @@ \Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876][MBA, Ferengi School of Management, 2022] %\Author{Luisa Hernández}{Department of Research}[B.S. Mechanical Engineering, UCLA, 2018][M.S. Stellar Interiors, Vulcan Science Academy, 2020][MBA, Ferengi School of Management, 2022] +%\Author{Thurston Howell III}{Department of Economics} % Use once for each degree fulfilled by thesis % For two degrees from one department, leave the department argument blank for the second degree {}. @@ -191,7 +174,7 @@ % Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) % If more than one department, use more than once -% If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}. +% **If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}.** \Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} %\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} %\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} @@ -219,9 +202,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page - %%%%%%%%% Contents that you need to write follows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -230,19 +210,15 @@ %%% Frontmatter (write this material in the mentioned files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex \begin{abstract} \input{abstract.tex}% in this case, use \input rather than \include because you are inside an environment \end{abstract} - \cleardoublepage -\include{acknowledgments.tex}% - \cleardoublepage +\include{acknowledgments.tex} \include{biography.tex}% optional, see MIT Libraries https://libraries.mit.edu/distinctive-collections/thesis-specs/#format - \cleardoublepage %%% Table of contents and lists of stuff (delete lists you don't need, e.g., if no tables) %%%%%%%% @@ -254,11 +230,12 @@ %%% Chapters of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% If you really feel the need to engage in "double spacing", you can start here... +%% If you want to use "double spacing", you can start here... \include{chapter1.tex} %\include{chapter2.tex} %\include{chapter3.tex} +%\include{chapter4.tex} %%% Appendicies of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -269,7 +246,7 @@ %%% Bibliography %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -{\raggedright% to avoid stretched white space and split urls; DELETE if you prefer justified text +{ \raggedright% to avoid stretched white space and split urls; DELETE THIS if you prefer justified text % \printbibliography[title={References},heading=bibintoc] } diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes-Stix2.tex b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes-Stix2.tex deleted file mode 100644 index 5da99c4c83..0000000000 --- a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes-Stix2.tex +++ /dev/null @@ -1,287 +0,0 @@ -% !TEX encoding = UTF-8 Unicode -% !BIB TS-program = biber -% !BIB program = biber - -% This file is MIT-Thesis.tex, a template for producing MIT theses with the mitthesis class. -% Version: 1.01, 2023/07/21 -% Author: John H. Lienhard (c) 2023. Reuse under the MIT license: https://ctan.org/license/mit - -% Documentation: https://ctan.org/pkg/mitthesis - -%% Don't modify the \DocumentMetadata command unless you know what it does. -%% If this command throws an "undefined" error, your latex system is out of date: try commenting this command out. -\DocumentMetadata -{ - pdfstandard = a-2b, - pdfversion = 1.7, - lang = en-US, -% debug = {xmp-export}, % output xmpi file to directly examine metadata -} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\documentclass[fontset=termes-stix2]{mitthesis} -% -% option [twoside] gives facing-page behavior for printing; omitting it will eliminate even-numbered blank pages. -% option [lineno] provides line numbers, as for editing -% option [mydesign] loads titlesec, enumitem, caption, subcaption - you may edit the mydesign.tex file as you like it. -% option [fontset] is a keyvalue which can be: -% pdftex or unicode engines: defaultfonts, libertine, lucida -% pdftex only: fira-newtxsf, newtx, newtx-sans-text -% unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 -% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the latex font". -% You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. -% If you are using multiple languages, load the babel package in your fontset file, before the fonts. - -%%%%%%%%% Packages used in sample chapters (not otherwise required) %%%%%%% - -%% Package for code listing in Appendix A. -\usepackage{listings} - -%% Set chemical formulas nicely -\usepackage[version=4]{mhchem} - -%% Latin filler used in Chapter 1, with a test for package version date -\usepackage{lipsum} -\IfPackageAtLeastTF{lipsum}{2021/09/20}{\setlipsum{auto-lang=false}}{} - - -%%%%%%%%% Graphics path (to figure files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%% Can set graphicspath to point to specific directories containing figures (the current directory is searched automatically) -%% For instance, to search a subdirectory of the current directory called "figures" and a parallel directory called "art", set: - -% \graphicspath{ {figures/} {../art/} }% For details see: https://latexref.xyz/dev/latex2e.html#g_t_005cgraphicspath - - -%%%%%%%%% Representative set-up for biblatex %%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\usepackage[style=ext-numeric-comp,giveninits=true,maxbibnames=10,sorting=none,articlein=false,]{biblatex} - -\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= - -%% These two commands enable line breaks in long URLs in the bibliography (delete if you don't want that) -\setcounter{biburllcpenalty}{7000} -\setcounter{biburlucpenalty}{8000} - -% biblatex is very powerful, and you can customize most aspects the reference list and citations. - - -%%%%%%%%%% Option to use natbib %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%\RequirePackage[numbers,sort&compress]{natbib} - -%%% add bibliography to table of contents -%\apptocmd{\bibliography}{\addcontentsline{toc}{chapter}{\protect\textbf{\bibname}}}{}{} - -%%% You can use this to rename the bibliography section -%\renewcommand{\bibname}{References} - -%%% Can adjust space between bibliography items (change 4pt to something else; don't drop last two lengths, they are stretchable "glue") -%\setlength\bibsep{4pt plus 1pt minus 1pt} - - -%%%%%%%%%% Table related packages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\usepackage{booktabs}% better quality tables -\usepackage{array}% additional options for table columns - -%\usepackage{tabularx} - -%\usepackage{dcolumn} % alignment on decimal places -%\newcolumntype{d}[1]{D{.}{.}{#1}} - - -%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%% Back in the typewriter era, double spaced lines were convenient for editing with a pencil. -%% In typography, the separation between lines is called "leading", and it is usually set in -%% proportion to the font size (i.e., when the font is loaded). If you really feel the need -%% to change the line separation, the most attractive results will be obtained by changing the -%% leading in proportion to the the current font size, rather than just doubling the space. - -%% The setspace package provides a tool for changing line separation (use these here) -% -%\usepackage{setspace} -%\setstretch{1.1}% you can choose some other value for the stretch of space between lines -% -%% Use the these commands AFTER the frontmatter -% -%\onehalfspacing -%\doublespacing -%\singlespacing % will turn these effects off (you can use these anywhere in the document) - -%% The best result may be to stay with leading selected by the typographer who set up the font. - - -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! - -\hypersetup{% -% -% Be sure to change the following to your own information! <======== !!! -% - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata -% - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, -} -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. -} - -%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\begin{document} - - -%%% edit the following commands to match your thesis %%%%%%%%%% - -\title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} - -% \Author{Author full name}{Author department}[Author's first PREVIOUS degree][Author's second PREVIOUS degree][... -% Note that third, fourth, fifth, and sixth arguments are optional [] and may be omitted - -% note on names: most of the following names are made up; Silas Holman was a professor at MIT in the 19th century. - -\Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876][MBA, Ferengi School of Management, 2022] -%\Author{Luisa Hernández}{Department of Research}[B.S. Mechanical Engineering, UCLA, 2018][M.S. Stellar Interiors, Vulcan Science Academy, 2020][MBA, Ferengi School of Management, 2022] - -% Use once for each degree fulfilled by thesis -% For two degrees from one department, leave the department argument blank for the second degree {}. -\Degree{Bachelor of Science in Physics}{Department of Physics} -%\Degree{Master of Science in Physics}{} -%\Degree{Bachelor of Science in Mechanical Engineering}{Department of Mechanical Engineering} - -% If there is more than one supervisor, use the \Supervisor command for each. -\Supervisor{Edward C. Pickering}{Professor of Physics} -%\Supervisor{Secunda Castor}{Professor of Research} -%\Supervisor{Quintus Castor}{Professor of Log Dams} - -% Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) -% If more than one department, use more than once -% If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}. -\Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} -%\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} -%\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} - -% If your title page is overflowing (from too many names, degrees, etc.), you can scale -% down the Signature block at the bottom with this command, or use another creative solution... -%\SignatureBlockSize{\small} %\SignatureBlockSize{\footnotesize} - -% Usage: \DegreeDate{Month}{year} -% Valid degree months are September, February, or June. -\DegreeDate{June}{1876} - -% Date that final thesis is submitted to department -\ThesisDate{May 18, 1876} - - -%%%%%% Choose whether to have a CREATIVE COMMONS License %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% If you are using a cc license, put details of your cc license here. -% Omit this command if you are not using a cc license. -% -\CClicense{CC BY-NC-ND 4.0}{https://creativecommons.org/licenses/by-nc-nd/4.0/} -% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%% Titlepage -\maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page - - -%%%%%%%%% Contents that you need to write follows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% \includeonly{acknowledgments,biography,chapter1,chapter2,...,appendixa,...} -% for usage, see https://latexref.xyz/dev/latex2e.html#g_t_005cinclude-_0026-_005cincludeonly - -%%% Frontmatter (write this material in the mentioned files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -% The abstract environment creates all the required headers and footnote. -% You only need to add the text of the abstract itself in the file abstract.tex -\begin{abstract} - \input{abstract.tex}% in this case, use \input rather than \include because you are inside an environment -\end{abstract} - \cleardoublepage - -\include{acknowledgments.tex}% - \cleardoublepage - -\include{biography.tex}% optional, see MIT Libraries https://libraries.mit.edu/distinctive-collections/thesis-specs/#format - \cleardoublepage - - -%%% Table of contents and lists of stuff (delete lists you don't need, e.g., if no tables) %%%%%%%% - -\tableofcontents -\listoffigures -\listoftables - - -%%% Chapters of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%% If you really feel the need to engage in "double spacing", you can start here... - -\include{chapter1.tex} -%\include{chapter2.tex} -%\include{chapter3.tex} - - -%%% Appendicies of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\appendix -\include{appendixa.tex} - - -%%% Bibliography %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -{\raggedright% to avoid stretched white space and split urls; DELETE if you prefer justified text -% -\printbibliography[title={References},heading=bibintoc] -} -% biblatex also supports chapter-by-chapter bibliography, https://tex.stackexchange.com/a/296502/119566 -% see the biblatex manual, section 3.14.3 - - -%%%% Option for natbib %%%%%%%%%%%%% -%% use an appropriate style (.bst) and your own .bib file[s] - -%\bibliographystyle{plainnat} -%\bibliography{mitthesis-sample.bib} - -\end{document} - \ No newline at end of file diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes-stix2.tex b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes-stix2.tex new file mode 100644 index 0000000000..29bb0e05cf --- /dev/null +++ b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes-stix2.tex @@ -0,0 +1,264 @@ +% !TEX encoding = UTF-8 Unicode +% !BIB TS-program = biber +% !BIB program = biber + +% This file is MIT-Thesis.tex, a LaTeX template for formatting an MIT thesis with the mitthesis class. +% +% Version: 1.06, 2023/08/28 +% +% Author: John H. Lienhard (c) 2023. Reuse under the MIT license: https://ctan.org/license/mit + +% Documentation is here: https://ctan.org/pkg/mitthesis + +%% Don't modify the \DocumentMetadata command unless you know what it does. +%% If this command throws an "undefined" error, your latex system is out of date: try commenting this command out. +\DocumentMetadata{ + pdfstandard = a-2b, + pdfversion = 1.7, + lang = en-US, +% debug = {xmp-export}, % uncomment to output a separate xmpi file showing the metadata +} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\documentclass[fontset=termes-stix2]{mitthesis} %,fontset=libertine ,fontset=newtx-sans-text, fontset=heros-stix2, fontset=stix2 +% +% option [twoside] gives facing-page behavior for printing; omitting twoside will eliminate even-numbered blank pages. +% option [lineno] provides line numbers, as for editing +% option [mydesign] loads packages for color, title and list formats, margins, or captions: edit mydesign.tex to change defaults. +% option [fontset] is a keyvalue which can be: +% pdftex or unicode engines: defaultfonts, libertine, lucida +% pdftex only: fira-newtxsf, newtx, newtx-sans-text +% unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 +% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the LaTeX font". +% You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. +% If you are using multiple languages, load the babel package in your fontset file, before the fonts. + +%%%%%%%%% Packages used in sample chapters (not otherwise required) %%%%%%% + +%% Package for code listing in Appendix A. +\usepackage{listings}% documentation is here https://ctan.org/pkg/listings + +%% Set chemical formulas nicely +\usepackage[version=4]{mhchem}% documentation is here https://ctan.org/pkg/mhchem + +%% Latin filler used in Chapter 1, with a test for package version date. https://ctan.org/pkg/lipsum +\usepackage{lipsum} +\IfPackageAtLeastTF{lipsum}{2021/09/20}{\setlipsum{auto-lang=false}}{} + + +%%%%%%%%% Graphics path (to figure files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Can set graphicspath to point to specific directories containing figures (the current directory is searched automatically) +%% For instance, to search a subdirectory of the current directory called "figures" and a parallel directory called "art", set: + +% \graphicspath{ {figures/} {../art/} }% For details see: https://latexref.xyz/dev/latex2e.html#g_t_005cgraphicspath + + +%%%%%%%%% Representative set-up for biblatex %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\usepackage[style=ieee,maxbibnames=10,sorting=none]{biblatex}% style=ext-numeric-comp,articlein=false,giveninits=true + \DefineBibliographyStrings{english}{url= \textsc{url} , }% replaces default "[Online]. Available" by "URL" + + +\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= CHANGE + +%% These two commands enable line breaks in long URLs in the bibliography (delete if you don't want that) +\setcounter{biburllcpenalty}{7000} +\setcounter{biburlucpenalty}{8000} + +% biblatex is very powerful, and you can customize most aspects the reference list and citations to suit your needs. +% documentation is here: https://ctan.org/pkg/biblatex + + +%%%%%%%%%% Option to use natbib %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%\RequirePackage[numbers,sort&compress]{natbib} + +%%% add bibliography to table of contents +%\apptocmd{\bibliography}{\addcontentsline{toc}{chapter}{\protect\textbf{\bibname}}}{}{} + +%%% You can use this to rename the bibliography section +%\renewcommand{\bibname}{References} + +%%% Can adjust space between bibliography items (change 4pt to something else; don't drop last two lengths, they are stretchable "glue") +%\setlength\bibsep{4pt plus 1pt minus 1pt} + + +%%%%%%%%%% Table related packages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\usepackage{booktabs}% better quality tables, https://ctan.org/pkg/booktabs +\usepackage{array}% additional options for table columns, https://ctan.org/pkg/array + +%\usepackage{tabularx}% https://ctan.org/pkg/tabularx + +%\usepackage{dcolumn}% alignment on decimal place, https://ctan.org/pkg/dcolumn +%\newcolumntype{d}[1]{D{.}{.}{#1}} + + +%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Back in the typewriter era, double spaced lines were convenient for editing with a pencil. +%% In typography, the separation between lines is called "leading", and it is usually set in +%% proportion to the font size (i.e., when the font is loaded). If you really feel the need +%% to change the line separation, the most attractive results will be obtained by changing the +%% leading in proportion to the the current font size, rather than just doubling the space. + +%% The setspace package provides a tool for changing line separation (use thesetwo here) +% +% \usepackage{setspace}% documentation at https://ctan.org/pkg/setspace +% \setstretch{1.1}% you can choose some other value for the stretch of space between lines +% +%% Use the these commands AFTER the frontmatter +% +% \onehalfspacing +% \doublespacing +% \singlespacing % will turn these effects off (you can use these anywhere in the document) + +%% The best result may be to stay with leading selected by the typographer who set up the font. + + +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! + +\hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) +% + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. +% + pdfauthortitle={}, + % If you have a title, you can include it here. +} + +%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{document} + +%%% edit the following commands to match your thesis %%%%%%%%%% + +\title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} + +% \Author{Author full name}{Author department}[Author's first PREVIOUS degree][Author's second PREVIOUS degree][... +% Note that third, fourth, fifth, and sixth arguments are optional [] and may be omitted + +% note on names: most of the following names are made up; Silas Holman was a professor at MIT in the 19th century. + +\Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876][MBA, Ferengi School of Management, 2022] +%\Author{Luisa Hernández}{Department of Research}[B.S. Mechanical Engineering, UCLA, 2018][M.S. Stellar Interiors, Vulcan Science Academy, 2020][MBA, Ferengi School of Management, 2022] +%\Author{Thurston Howell III}{Department of Economics} + +% Use once for each degree fulfilled by thesis +% For two degrees from one department, leave the department argument blank for the second degree {}. +\Degree{Bachelor of Science in Physics}{Department of Physics} +%\Degree{Master of Science in Physics}{} +%\Degree{Bachelor of Science in Mechanical Engineering}{Department of Mechanical Engineering} + +% If there is more than one supervisor, use the \Supervisor command for each. +\Supervisor{Edward C. Pickering}{Professor of Physics} +%\Supervisor{Secunda Castor}{Professor of Research} +%\Supervisor{Quintus Castor}{Professor of Log Dams} + +% Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) +% If more than one department, use more than once +% **If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}.** +\Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} +%\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} +%\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} + +% If your title page is overflowing (from too many names, degrees, etc.), you can scale +% down the Signature block at the bottom with this command, or use another creative solution... +%\SignatureBlockSize{\small} %\SignatureBlockSize{\footnotesize} + +% Usage: \DegreeDate{Month}{year} +% Valid degree months are September, February, or June. +\DegreeDate{June}{1876} + +% Date that final thesis is submitted to department +\ThesisDate{May 18, 1876} + + +%%%%%% Choose whether to have a CREATIVE COMMONS License %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% If you are using a cc license, put details of your cc license here. +% Omit this command if you are not using a cc license. +% +\CClicense{CC BY-NC-ND 4.0}{https://creativecommons.org/licenses/by-nc-nd/4.0/} +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%% Titlepage +\maketitle + +%%%%%%%%% Contents that you need to write follows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% \includeonly{acknowledgments,biography,chapter1,chapter2,...,appendixa,...} +% for usage, see https://latexref.xyz/dev/latex2e.html#g_t_005cinclude-_0026-_005cincludeonly + +%%% Frontmatter (write this material in the mentioned files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% The abstract environment creates all the required headers and footnote. +% You only need to add the text of the abstract itself in the file abstract.tex +\begin{abstract} + \input{abstract.tex}% in this case, use \input rather than \include because you are inside an environment +\end{abstract} + +\include{acknowledgments.tex} + +\include{biography.tex}% optional, see MIT Libraries https://libraries.mit.edu/distinctive-collections/thesis-specs/#format + + +%%% Table of contents and lists of stuff (delete lists you don't need, e.g., if no tables) %%%%%%%% + +\tableofcontents +\listoffigures +\listoftables + + +%%% Chapters of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% If you want to use "double spacing", you can start here... + +\include{chapter1.tex} +%\include{chapter2.tex} +%\include{chapter3.tex} +%\include{chapter4.tex} + + +%%% Appendicies of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\appendix +\include{appendixa.tex} + + +%%% Bibliography %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +{ \raggedright% to avoid stretched white space and split urls; DELETE THIS if you prefer justified text +% +\printbibliography[title={References},heading=bibintoc] +} +% biblatex also supports chapter-by-chapter bibliography, https://tex.stackexchange.com/a/296502/119566 +% see the biblatex manual, section 3.14.3 + + +%%%% Option for natbib %%%%%%%%%%%%% +%% use an appropriate style (.bst) and your own .bib file[s] + +%\bibliographystyle{plainnat} +%\bibliography{mitthesis-sample.bib} + +\end{document} + \ No newline at end of file diff --git a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes.tex b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes.tex index 586c7419a9..fb2f11a35d 100644 --- a/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes.tex +++ b/macros/latex/contrib/mitthesis/examples/font_samples/latex_sources/Termes.tex @@ -1,47 +1,47 @@ -% !TEX TS-program = LuaLaTeX % !TEX encoding = UTF-8 Unicode % !BIB TS-program = biber % !BIB program = biber -% This file is MIT-Thesis.tex, a template for producing MIT theses with the mitthesis class. -% Version: 1.01, 2023/07/21 +% This file is MIT-Thesis.tex, a LaTeX template for formatting an MIT thesis with the mitthesis class. +% +% Version: 1.06, 2023/08/28 +% % Author: John H. Lienhard (c) 2023. Reuse under the MIT license: https://ctan.org/license/mit -% Documentation: https://ctan.org/pkg/mitthesis +% Documentation is here: https://ctan.org/pkg/mitthesis %% Don't modify the \DocumentMetadata command unless you know what it does. %% If this command throws an "undefined" error, your latex system is out of date: try commenting this command out. -\DocumentMetadata -{ +\DocumentMetadata{ pdfstandard = a-2b, pdfversion = 1.7, lang = en-US, -% debug = {xmp-export}, % output xmpi file to directly examine metadata +% debug = {xmp-export}, % uncomment to output a separate xmpi file showing the metadata } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\documentclass[fontset=termes]{mitthesis} +\documentclass[fontset=termes]{mitthesis} %,fontset=libertine ,fontset=newtx-sans-text, fontset=heros-stix2, fontset=stix2 % -% option [twoside] gives facing-page behavior for printing; omitting it will eliminate even-numbered blank pages. +% option [twoside] gives facing-page behavior for printing; omitting twoside will eliminate even-numbered blank pages. % option [lineno] provides line numbers, as for editing -% option [mydesign] loads titlesec, enumitem, caption, subcaption - you may edit the mydesign.tex file as you like it. +% option [mydesign] loads packages for color, title and list formats, margins, or captions: edit mydesign.tex to change defaults. % option [fontset] is a keyvalue which can be: % pdftex or unicode engines: defaultfonts, libertine, lucida % pdftex only: fira-newtxsf, newtx, newtx-sans-text % unicode engines (luatex): heros-stix2, stix2, termes, termes-stix2 -% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the latex font". +% if no key value is given, fonts default to CMR (pdftex) or LMR (unicode), i.e., "the LaTeX font". % You can edit the fontset files or you can write your own, myfonts.tex, and do [fontset=myfonts]. % If you are using multiple languages, load the babel package in your fontset file, before the fonts. %%%%%%%%% Packages used in sample chapters (not otherwise required) %%%%%%% %% Package for code listing in Appendix A. -\usepackage{listings} +\usepackage{listings}% documentation is here https://ctan.org/pkg/listings %% Set chemical formulas nicely -\usepackage[version=4]{mhchem} +\usepackage[version=4]{mhchem}% documentation is here https://ctan.org/pkg/mhchem -%% Latin filler used in Chapter 1, with a test for package version date +%% Latin filler used in Chapter 1, with a test for package version date. https://ctan.org/pkg/lipsum \usepackage{lipsum} \IfPackageAtLeastTF{lipsum}{2021/09/20}{\setlipsum{auto-lang=false}}{} @@ -56,15 +56,18 @@ %%%%%%%%% Representative set-up for biblatex %%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage[style=ext-numeric-comp,giveninits=true,maxbibnames=10,sorting=none,articlein=false,]{biblatex} +\usepackage[style=ieee,maxbibnames=10,sorting=none]{biblatex}% style=ext-numeric-comp,articlein=false,giveninits=true + \DefineBibliographyStrings{english}{url= \textsc{url} , }% replaces default "[Online]. Available" by "URL" + -\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= +\addbibresource{mitthesis-sample.bib}%% <== change to YOUR bib file <================= CHANGE %% These two commands enable line breaks in long URLs in the bibliography (delete if you don't want that) \setcounter{biburllcpenalty}{7000} \setcounter{biburlucpenalty}{8000} -% biblatex is very powerful, and you can customize most aspects the reference list and citations. +% biblatex is very powerful, and you can customize most aspects the reference list and citations to suit your needs. +% documentation is here: https://ctan.org/pkg/biblatex %%%%%%%%%% Option to use natbib %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -83,16 +86,16 @@ %%%%%%%%%% Table related packages %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\usepackage{booktabs}% better quality tables -\usepackage{array}% additional options for table columns +\usepackage{booktabs}% better quality tables, https://ctan.org/pkg/booktabs +\usepackage{array}% additional options for table columns, https://ctan.org/pkg/array -%\usepackage{tabularx} +%\usepackage{tabularx}% https://ctan.org/pkg/tabularx -%\usepackage{dcolumn} % alignment on decimal places +%\usepackage{dcolumn}% alignment on decimal place, https://ctan.org/pkg/dcolumn %\newcolumntype{d}[1]{D{.}{.}{#1}} -%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% Option for "double spacing" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Back in the typewriter era, double spaced lines were convenient for editing with a pencil. %% In typography, the separation between lines is called "leading", and it is usually set in @@ -100,73 +103,51 @@ %% to change the line separation, the most attractive results will be obtained by changing the %% leading in proportion to the the current font size, rather than just doubling the space. -%% The setspace package provides a tool for changing line separation (use these here) +%% The setspace package provides a tool for changing line separation (use thesetwo here) % -%\usepackage{setspace} -%\setstretch{1.1}% you can choose some other value for the stretch of space between lines +% \usepackage{setspace}% documentation at https://ctan.org/pkg/setspace +% \setstretch{1.1}% you can choose some other value for the stretch of space between lines % %% Use the these commands AFTER the frontmatter % -%\onehalfspacing -%\doublespacing -%\singlespacing % will turn these effects off (you can use these anywhere in the document) +% \onehalfspacing +% \doublespacing +% \singlespacing % will turn these effects off (you can use these anywhere in the document) %% The best result may be to stay with leading selected by the typographer who set up the font. -%%%%%%%%%%% Hyperref setting and metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%% Metadata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\YourName{John H. Lienhard}% <====== CHANGE TO YOUR NAME !!! +% Most of the document metadata is created automatically. +% The following items should be adjusted to match your work. <================= !!!!!!!!!! \hypersetup{% + pdfsubject={Template for writing MIT theses with the mitthesis class}, + % Change this to briefly state topic of your thesis +% + pdfkeywords={Massachusetts Institute of Technology, MIT}, + % Add keywords that will help search engines and libraries to find your work. + % Includes the name[s] of the author[s] + % (If you have used \DocumentMetadata, at line 15, you can just put "\CopyrightAuthor," for the names.) % -% Be sure to change the following to your own information! <======== !!! -% - pdftitle={MIT thesis template}, - pdfkeywords={\YourName, Massachusetts Institute of Technology, MIT}, - pdfauthor={\YourName}, -% pdfauthor={{John H. Lienhard, V}},% if you have a comma in your name, surround by {..} - pdfauthortitle={Professor of Mechanical Engineering}, - pdfcaptionwriter={\YourName}, - pdfurl={https://lienhard.mit.edu}, - pdfcontactemail={lienhard@mit.edu}, - pdfcontactaddress={77 Massachusetts Avenue, Room 3-166}, - pdfcontactcity={Cambridge, MA}, - pdfcontactpostcode={02139}, - pdfcontactcountry={USA}, - pdfcontacturl={https://lienhard.mit.edu}, -% - pdfsubject={Template for writing MIT theses with the mitthesis class},% briefly state what this document is about -% - colorlinks=true, - linkcolor=Blue3,% from xcolor package - citecolor=Blue3,% from xcolor package - urlcolor=violet,% from xcolor package - filecolor=red, -% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does) -% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata + pdfurl={}, + % If you have a url for the thesis, put it here. Otherwise delete this. + % (MIT Libraries will put your thesis in DSPACE with a persistent url after you submit it.) +% + pdfcontactemail={}, + % You can put a [permanent] email address into the metadata, if you like. + % Otherwise delete this. % - pdfborder={0 0 0}, - bookmarksnumbered=true, - bookmarksopen=true, - bookmarksopenlevel=1, -% pdfpagemode=UseNone,% this option means don't open bookmarks panel - pdfpagelayout=SinglePage, - pdfdisplaydoctitle=true, - pdfstartview=Fit, - pdfnewwindow=true, + pdfauthortitle={}, + % If you have a title, you can include it here. } -\AtEndDocument{ - \hypersetup{pdfcopyright={Copyright © \DegreeYear\ by \YourName. \PDFRightsText},}% 1st and 3rd commands are defined by class file. -} - -%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%% End preamble %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} - %%% edit the following commands to match your thesis %%%%%%%%%% \title{The Atomic Theory as Applied To Gases, with Some Experiments on the Viscosity of Air} @@ -178,6 +159,7 @@ \Author{Silas W. Holman}{Department of Physics}%[B.S. Physics, MIT, 1876][MBA, Ferengi School of Management, 2022] %\Author{Luisa Hernández}{Department of Research}[B.S. Mechanical Engineering, UCLA, 2018][M.S. Stellar Interiors, Vulcan Science Academy, 2020][MBA, Ferengi School of Management, 2022] +%\Author{Thurston Howell III}{Department of Economics} % Use once for each degree fulfilled by thesis % For two degrees from one department, leave the department argument blank for the second degree {}. @@ -192,7 +174,7 @@ % Professor who formally accepts theses for your department (e.g., the Graduate Officer, Professor Sméagol,...) % If more than one department, use more than once -% If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}. +% **If you need to reduce vertical space, put the acceptor title in the second argument and leave the third blank {}.** \Acceptor{Primus Castor}{Professor of Wetlands Engineering}{Undergraduate Officer, Department of Physics} %\Acceptor{Tertius Castor}{Professor of Log Dams}{Graduate Officer, Department of Research} %\Acceptor{Quarta Castor}{Professor of Lodge Building}{Graduate Officer, Department of Mechanical Engineering} @@ -220,9 +202,6 @@ %%% Titlepage \maketitle - \cleardoublepage% for two-sided printing, this puts abstract on a right-hand (odd) page, possibly inserting a blank page - % if the the class option [twoside] is omitted, the command just begins a new page - %%%%%%%%% Contents that you need to write follows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -231,19 +210,15 @@ %%% Frontmatter (write this material in the mentioned files) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % The abstract environment creates all the required headers and footnote. % You only need to add the text of the abstract itself in the file abstract.tex \begin{abstract} \input{abstract.tex}% in this case, use \input rather than \include because you are inside an environment \end{abstract} - \cleardoublepage -\include{acknowledgments.tex}% - \cleardoublepage +\include{acknowledgments.tex} \include{biography.tex}% optional, see MIT Libraries https://libraries.mit.edu/distinctive-collections/thesis-specs/#format - \cleardoublepage %%% Table of contents and lists of stuff (delete lists you don't need, e.g., if no tables) %%%%%%%% @@ -255,11 +230,12 @@ %%% Chapters of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% If you really feel the need to engage in "double spacing", you can start here... +%% If you want to use "double spacing", you can start here... \include{chapter1.tex} %\include{chapter2.tex} %\include{chapter3.tex} +%\include{chapter4.tex} %%% Appendicies of thesis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -270,7 +246,7 @@ %%% Bibliography %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -{\raggedright% to avoid stretched white space and split urls; DELETE if you prefer justified text +{ \raggedright% to avoid stretched white space and split urls; DELETE THIS if you prefer justified text % \printbibliography[title={References},heading=bibintoc] } diff --git a/macros/latex/contrib/mitthesis/fontsets/mitthesis-fira-newtxsf.tex b/macros/latex/contrib/mitthesis/fontsets/mitthesis-fira-newtxsf.tex index 55e6a7de52..90ab699b18 100644 --- a/macros/latex/contrib/mitthesis/fontsets/mitthesis-fira-newtxsf.tex +++ b/macros/latex/contrib/mitthesis/fontsets/mitthesis-fira-newtxsf.tex @@ -1,5 +1,5 @@ % From mitthesis package -% Version: 1.02, 2023/07/03 +% Version: 1.03, 2023/08/29 % Documentation: https://ctan.org/pkg/mitthesis @@ -7,10 +7,10 @@ % \ifpdftex \typeout{^^JLoading Fira sans text font with newtx sans serif math font and Inconsolata typewriter^^J} - \RequirePackage[sfdefault]{FiraSans} % sans serif text package %,scaled=.85 + \RequirePackage[sfdefault,scaled=0.90]{FiraSans} % sans serif text package %,scaled=.85 \RequirePackage[T1]{fontenc} - \RequirePackage[varqu,varl,,scaled=1.12]{zi4} % inconsolata font for typewriter - \RequirePackage[cmintegrals,scaled=1.12]{newtxsf} % sans serif math + \RequirePackage[varqu,varl,scaled=1.05]{zi4} % inconsolata font for typewriter + \RequirePackage[scaled=1.05]{newtxsf} % sans serif math \RequirePackage{bm} \else \ClassWarning{mitnewthesis}{The newtx font set requires pdflatex. Defaulting to LMR fonts} diff --git a/macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.pdf b/macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.pdf index ddc3fcfafe..95c7b6c17b 100644 Binary files a/macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.pdf and b/macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.pdf differ diff --git a/macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.tex b/macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.tex index a896751c37..c9431036ea 100644 --- a/macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.tex +++ b/macros/latex/contrib/mitthesis/mitthesis-doc/mitthesis-doc.tex @@ -251,7 +251,7 @@ The new MIT thesis template consists of: \texttt{mitthesis.cls}; a root file \te \section*{Information you need to complete} Various fields and commands must be changed to your own information in the preamble of \texttt{MIT-Thesis.tex} and immediately after the \verb|\begin{document}| command. This information includes the title, author, degree and other essential information. With the comments in \texttt{MIT-Thesis.tex}, this step should be self-explanatory. Nevertheless some comments follow. -In the \verb|\hypersetup{..}| command, change the sample file to match your own information (name, title, keywords, etc.). These commands generate metadata that are incorporated into the pdf file. +In the \verb|\hypersetup{..}| command, change the sample file to match your own information (e.g., keywords, subject, etc.). These commands generate metadata that are incorporated into the pdf file. The commands that define the title page are as follow. \begin{itemize} @@ -262,7 +262,7 @@ Note that third, fourth, fifth, and sixth arguments are optional [..] and may be \item \verb|\Degree{name of degree}{department giving degree}|. Use once for each degree fulfilled by thesis. If the thesis satisfies two degrees from one department, leave the department argument blank for the \textit{second} degree: \verb|\Degree{2nd degree name}{}| -\item \verb|\Supervisor{supervisor name}{supervisor department}|. Use once for each supervisor. +\item \verb|\Supervisor{supervisor name}{supervisor title}|. Use once for each supervisor. \item \verb|\Acceptor{acceptor name}{acceptor title}{thesis related position}|. Professor who accepts theses for your department (e.g., the Graduate Officer). Use once for each department. @@ -280,11 +280,9 @@ If you wish to make your thesis available under a Creative Commons License, issu \vskip 5pt \noindent\quad\verb|\CClicense{CC BY-NC-ND 4.0}{https://creativecommons.org/licenses/by-nc-nd/4.0/}|. - \section*{Package options} Package options may be specified for \verb|\documentclass[..]{mitthesis}|. These options are described in Table~\ref{tab:1} and the subsections that follow. - \begin{table}[ht] \caption{Options to the document class\label{tab:1}} \smallskip\setlength\extrarowheight{3pt}% @@ -303,7 +301,7 @@ twoside & gives facing-page behavior for two-sided printing; omitting it will e \end{tabular}}% \end{table} -\subsection*{Font loading} +\subsection*{Font loading}\enlargethispage{\baselineskip}% By default, \texttt{mitthesis.cls} will load the traditional \LaTeX\ fonts, computer modern (\pdfTeX) or latin modern (unicode engines). By using the key value \texttt{fontset=$\cdots$} in the \verb|\documentclass| command, you can select a different set of fonts. Ten fontsets are predefined, including the default set (see Table~\ref{tab:2}). Three work only with \pdfTeX, four work only with unicode engines, and three work with either. These options include a mixture of serif or sans serif text and math fonts, as shown in the table. @@ -346,7 +344,11 @@ termes-stix2 & no & yes & serif & serif & \url{http://www.gust.org.pl/projects/ \subsection*{Design options} The thesis will follow the default styles of the \LaTeX\ report class for sections headings, captions, and lists. If you prefer different styles you can use the class option [mydesign] which loads the file \texttt{mydesign.tex}. -With \texttt{mydesign.tex}, you can set options for packages that manage color, e.g.\ \texttt{\hrefurl{https://ctan.org/pkg/xcolor}{xcolor}}, that change the margins, or that change the design of titles, captions, and lists: \texttt{\hrefurl{https://ctan.org/pkg/titlesec}{titlesec}}, \texttt{\hrefurl{https://ctan.org/pkg/caption}{caption}}, or \texttt{\hrefurl{https://ctan.org/pkg/enumitem}{enumitem}}. You can also load other packages. The \texttt{mitthesis} class will insert these commands at the appropriate point (prior to loading \texttt{\hrefurl{https://ctan.org/pkg/babel}{babel}}, fonts, or \texttt{\hrefurl{https://ctan.org/pkg/hyperref}{hyperref}}). You should not need to edit the class file.\footnote{If you are using different style files, say \texttt{styleA.tex} and \texttt{styleB.tex}, you can switch between them with the options [mydesign=styleA] and [mydesign=styleB].} +With \texttt{mydesign.tex}, you can set options for packages that manage color, e.g.\ \texttt{\hrefurl{https://ctan.org/pkg/xcolor}{xcolor}}, that change the margins, or that change the design of titles, captions, and lists: \texttt{\hrefurl{https://ctan.org/pkg/titlesec}{titlesec}}, \texttt{\hrefurl{https://ctan.org/pkg/caption}{caption}}, or \texttt{\hrefurl{https://ctan.org/pkg/enumitem}{enumitem}}. You can also load other packages. The \texttt{mitthesis} class will insert these commands at the appropriate point (prior to loading \texttt{\hrefurl{https://ctan.org/pkg/babel}{babel}}, fonts, or \texttt{\hrefurl{https://ctan.org/pkg/hyperref}{hyperref}}). You should not need to edit the class file. + +Hyperlink colors and pdf bookmark or viewing options from the \texttt{hyperref} package can be changed by using \verb|\hypersetup{ .. }| in the preamble or using \verb|\AtBeginDocument{ \hypersetup{ .. } }| in the \texttt{mydesign.tex} file. + +If you have two different style files, say \texttt{styleA.tex} and \texttt{styleB.tex}, you can switch between them with the options [mydesign=styleA] and [mydesign=styleB]. \subsection*{Single-sided vs.\ double-sided layout} The sample template uses the option \texttt{[twosided]}, which starts major sections (abstract, table of contents, chapters, etc.) on odd-numbered pages. This arrangement is suitable for two-sided printing, but can lead to empty even-numbered pages. If you do not wish to have this behavior, omit that option. By default, even and odd page margins are the same; this can be changed in the \texttt{mydesign.tex} file if necessary. @@ -366,7 +368,6 @@ bookmarks& is loaded automatically under the new pdf-management system & --- \\ doi & support for hyperlinking DOIs & hyperlink a doi number: \verb|\doi{..}| \\ etoolbox & extend or modify other macros & can use in preamble if needed \\ iftex & check which \LaTeX\ engine is running& macros to check engine \\ -ifthen & streamlined conditionals & can use in preamble if needed \\ geometry & set page size and margins & can use \verb|\newgeometry| in \texttt{mydesign.tex}\\ graphicsx& support for inserting images & use to include graphics\\ hyperref & support for hyperlinks and metadata & must complete setup in preamble\\ @@ -395,7 +396,7 @@ unicode-math & --- & load in a fontset file if using a unicode engine\\ \end{tabular*}}% \end{table} -\section*{PDF/A compatibility} +\section*{PDF/A compatibility}\enlargethispage{\baselineskip}% PDF/A-2b compliance will be automatic if the \verb|\DocumentMetadata{..}| command is issued before the \verb|\documentclass{..}| command and \textit{provided that your graphics are also compliant}. This command was added to \LaTeX\ in June 2022. For older versions of \LaTeX, the \texttt{mitthesis} class will fall back to loading \texttt{hyperxmp} to support pdf metadata, but PDF/A compliance will require post-processing (for example, by using the PreFlight function of Adobe Acrobat). An up-to-date \LaTeX\ installation is preferred. Current \LaTeX\ development (ca.~2023) is working toward fully accessible PDF/A out of the box (e.g., PDF/A-2a). Unicode compliance (e.g., PDF/A-2u) depends greatly on your fonts and figures. @@ -407,7 +408,7 @@ Specialized packages for many disciplines can be found in \hrefurl{https://ctan. When selecting a package to use, check that it is currently maintained (with relatively recent updates), and compare it to other packages that perform similar functions. Some packages are better than others, and some obsolete packages remain online. -\section*{Nomenclature} +\section*{Nomenclature}\enlargethispage{\baselineskip}% An optional nomenclature environment is provided by the class. This environment can support either chapter-by-chapter nomenclature (at the section level) or a single nomenclature for the entire thesis (at the chapter level). The environment has three optional arguments: [1] adjust space between symbol and definition; [2] name (heading) of the nomenclature list; and [3] level, which can be ``chapter'' or ``section'' depending on whether you have one nomenclature list for whole thesis or one for each chapter (default = section). @@ -446,14 +447,17 @@ produces the nomenclature list below \clearpage +\section*{Additional commands} +The class also provides \verb|\DegreeYear|, \verb|\DegreeMonth|, and \verb|\CopyrightAuthor|. The latter combines all author names into a single token list, e.g., ``Joseph O. Hirschfelder, Charles F. Curtiss and R. Byron Bird''; a period at the end of the final name (e.g., as in ``John F. Nash Jr.'') is removed. + \section*{Use outside MIT} If your want to adapt this template for use at a different institution, you can put the following commands in your preamble. \begin{itemize} -\item Use \verb|\def\MIT{YOUR INSTITUTION}| to change MIT to your own institution (use all capital letters). +\item Use \verb|\Institution{Your Institution}| to change MIT to your own institution on the title page. {\small\textit{New with v1.06.}} \item Use \verb|\maketitle*| (in place of \verb|\maketitle|) to drop the MIT copyright permission statement -\item Use \verb|\setcounter{acccnt}{-2}| to remove the ``Accepted by:'' field. +\item Omitting \verb|\Acceptor| commands will drop the ``Accepted by:'' field. To suppress the resultant error message, put \verb|\SuppressAcceptorError| before \verb|\maketitle*|. \newline{\small\textit{New with v1.06.}} \end{itemize} Please do not remove the license/copyright text from the sources files. diff --git a/macros/latex/contrib/mitthesis/mitthesis.cls b/macros/latex/contrib/mitthesis/mitthesis.cls index 8acd3e6358..b98528e532 100644 --- a/macros/latex/contrib/mitthesis/mitthesis.cls +++ b/macros/latex/contrib/mitthesis/mitthesis.cls @@ -7,8 +7,8 @@ %% MIT Libraries' requirements as of 2023. %% %% This file's version and date: - \def\versionno{1.05} - \def\versiondate{2023/07/21\space} + \def\versionno{1.06} + \def\versiondate{2023/08/29\space} %% %% Author: John H. Lienhard, V %% Department of Mechanical Engineering @@ -47,48 +47,26 @@ \NeedsTeXFormat{LaTeX2e} \ProvidesClass{mitthesis}[\versiondate MIT Thesis Template (JHL)] -\LoadClass[12pt]{report}% [twoside] option can be issued in the .tex file; point size must be set here. +\LoadClass[12pt,openright]{report}% [twoside] option can be issued in the .tex file; point size must be set here. -\RequirePackage{etoolbox}% provides \ifblank, \patchcmd, \apptocmd, etc. -\RequirePackage{ifthen} % provides \whiledo, etc. +\ExplSyntaxOn + \str_const:Nn \ClassName {mitthesis} +\ExplSyntaxOff -\def\ClassName{mitthesis} +\RequirePackage{iftex}[2019/11/07]% provides \ifpdftex, etc. %%%%%%%%%%%%% Some compatibility for older latex distributions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\providecommand\IfFormatAtLeastTF{\@ifl@t@r\fmtversion}% compare version to date -\providecommand\IfPackageAtLeastTF{\@ifpackagelater}% compare version to date - -\ifdefined\NewDocumentCommand\else - \RequirePackage{xparse}% enable pre-10/2020 formats to access essential macros later moved into LaTeX kernel -\fi +\providecommand\IfFormatAtLeastTF{\@ifl@t@r\fmtversion}% compare version to date; \If... added to latex 2020/10/01 +\providecommand\IfPackageAtLeastTF{\@ifpackagelater}% compare version to date; \If... added to latex 2020/10/01 \IfFormatAtLeastTF{2020/02/25}{% \typeout{^^JYour LaTeX format is dated \fmtversion. LaTeX distributions from 2022/11/01 or later are strongly recommended for best results^^J} }{% - \ClassError{\ClassName}{Your LaTeX format is dated \fmtversion. Formats dated 2022/11/01 or later are recommended for this class. Older formats may generate errors}{Please UPDATE your LaTeX distribution to obtain best results. TeX Live is available for download at no charge: \string https://www.tug.org/texlive/. You can try to click past the errors for now...}% + \ClassError{\ClassName}{Your LaTeX format is dated \fmtversion. Formats dated 2022/11/01 or later are strongly recommended for this class. Older formats may generate errors}{Please UPDATE your LaTeX distribution to obtain best results. TeX Live is available for download at no charge: \string https://www.tug.org/texlive/. You can try to click past the errors for now...}% } -\IfFileExists{iftex.sty}{% - \RequirePackage{iftex}% check whether pdftex or another engine is used - }{% - \ClassWarning{\ClassName}{This class requires the missing package iftex.sty---trying a work-around.} - % Code copied from iftex package written by the LaTeX3 Project (used under LPPL). - % \csname and \let construct useful for hiding \ifzzz tokens from outer level \if tests. - \def\IFTEX@let#1#2{% - \expandafter\let\csname if#1\expandafter\endcsname - \csname if#2\endcsname} - % pdftex (including in dvi mode) - \begingroup\expandafter\expandafter\expandafter\endgroup - \expandafter\ifx\csname pdftexversion\endcsname\relax - \IFTEX@let{pdftex}{false} - \else - \IFTEX@let{pdftex}{true} - \fi - \IFTEX@let{PDFTeX}{pdftex} - } - -% check whether pdfmanagement (\DocumentMetadata) has been loaded (to fallback on hyperxmp) +% check whether pdfmanagement (\DocumentMetadata) has been loaded (if not, fall back to hyperxmp) \newif\ifmit@pdfmanagement % As of 2021/07/23 we could instead do:\IfPDFManagementActiveTF{\mit@pdfmanagementtrue}{\mit@pdfmanagementfalse} \ExplSyntaxOn @@ -96,20 +74,21 @@ \bool_if:nTF { \bool_lazy_and_p:nn - {\cs_if_exist_p:N \pdfmanagement_if_active_p:} + { \cs_if_exist_p:N \pdfmanagement_if_active_p: } { \pdfmanagement_if_active_p: } } - { - \mit@pdfmanagementtrue - } - { - \mit@pdfmanagementfalse - } - }{\mit@pdfmanagementfalse} + { \mit@pdfmanagementtrue } + { \mit@pdfmanagementfalse } + }{ \mit@pdfmanagementfalse } \ExplSyntaxOff -%% Old installations may want textcomp load, but we only require copyright character: -\ifdefined\textcopyright\else %\def\textcopyright{©}\fi. % 2023/06/26 +% Enable pre-2020/10 formats to access essential macros later moved into LaTeX kernel +\ifdefined\NewDocumentCommand\else + \RequirePackage{xparse} +\fi + +%% Pre-2020/02 installations may need textcomp to be loaded, but we require only the copyright character: +\ifdefined\textcopyright\else \ifpdftex \DeclareTextSymbol{\textcopyright}{TS1}{'251} \DeclareTextSymbolDefault{\textcopyright}{TS1} @@ -133,7 +112,7 @@ \SetKeys[\ClassName]{fontset=defaultfonts}% \DeclareUnknownKeyHandler[\ClassName]{\relax}% suppress warning about unused keys \ProcessKeyOptions -}{% +}{% Compatibility code for distributions pre-2022/11 \RequirePackage{kvoptions} \SetupKeyvalOptions{ family=\ClassName, @@ -141,39 +120,33 @@ setkeys=\kvsetkeys, } % set key [fontset] for font selection - \DeclareStringOption[defaultfonts]{fontset}[]% fixed 2023/06/26 + \DeclareStringOption[defaultfonts]{fontset}[] + % + % set key [lineno] to load package lineno + \DeclareBoolOption{lineno} + % + % set key [mydesign] to input file mydesign.tex + \DeclareBoolOption{mydesign} % \ProcessKeyvalOptions{\ClassName} % %% Turn off these keys now that we're done with them - \def\@KeyFamily{\ClassName} \NewDocumentCommand\mit@DisableOption{m}{% \DisableKeyvalOption[% action=ignore,% class=\ClassName% - ]{#1}{\@KeyFamily}% + ]{#1}{\ClassName}% } - \NewDocumentCommand\@DisableKeys{>{\SplitList{;}}m}{\ProcessList{#1}{\mit@DisableOption}} + \NewDocumentCommand\mit@DisableKeys{>{\SplitList{;}}m}{\ProcessList{#1}{\mit@DisableOption}} + % + \mit@DisableKeys{fontset;lineno;mydesign}% % - \@DisableKeys{fontset;}% - - - %%%%%%%% more options %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - %%% option to obtain line numbers [lineno] - \newif\ifmit@lineno\mit@linenofalse - \DeclareOption{lineno}{\mit@linenotrue} - - %%% option for to load packages that customize the design [mydesign] (caption, subcaption, titlesec, itemenum) - \newif\ifmit@mydesign\mit@mydesignfalse - \DeclareOption{mydesign}{\mit@mydesigntrue} - %% Suppress warnings about unused global options - \DeclareOption*{} - + \DeclareOption*{} \ProcessOptions \relax } + %%%%%%%%%%%%% Line numbering (class option) %%%%%%%%%%%%%%%%%%%%%%%%% %%% Adjustments when lineno option is used @@ -187,21 +160,19 @@ \providecommand{\@LN@col}[1]{\relax} \providecommand{\@LN}[2]{\relax} + %%%%%%%%%%%%% Patch table of contents, list of figures, and list of tables %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% We'd like these to have pdf bookmarks and to have the lists appear in the table of contents +\RequirePackage{etoolbox}% provides \patchcmd + +% We'd like these sections to have pdf bookmarks and to have the two lists appear in the table of contents -\pretocmd{\tableofcontents}{\pdfbookmark[0]{Table of Contents}{toc}}{}{} -\apptocmd{\tableofcontents}{\cleardoublepage}{}{} -\pretocmd{\listoffigures}{\phantomsection}{}{} +\patchcmd{\tableofcontents}{\@starttoc{toc}}{\pdfbookmark[0]{Table of Contents}{toc}\@starttoc{toc}}{}{} \patchcmd{\listoffigures}{\chapter*{\listfigurename}}{\chapter*{\listfigurename}\addcontentsline{toc}{chapter}{\protect\textbf{\listfigurename}}}{}{} -\apptocmd{\listoffigures}{\cleardoublepage}{}{} -\pretocmd{\listoftables}{\phantomsection}{}{} \patchcmd{\listoftables}{\chapter*{\listtablename}}{\chapter*{\listtablename}\addcontentsline{toc}{chapter}{\protect\textbf{\listtablename}}}{}{} -\apptocmd{\listoftables}{\cleardoublepage}{}{} -%%%%%%%%%%%%% Geometry, mathtools, design, graphics, bibliography, hyperrefs, bookmarks %%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%% Geometry, mathtools, design, graphics, bibliography, hyperrefs, bookmarks, footnotes %%%%%%%%%%%% \RequirePackage[letterpaper,top=1in,bottom=1in,left=1in,right=1in,marginparwidth=50pt,headsep=12pt,footskip=0.5in]{geometry} @@ -243,7 +214,7 @@ % ==> NOT every font includes a bold math version, so you may need to use other math macros in the headings to get bold math <== \fi -%% Font loading +%% Font loading %%%%%%%%%% \typeout{^^JFontset key is \mit@fontset.^^J} \IfFileExists{fontsets/\ClassName-\mit@fontset.tex}{% 2023/07/03 \input{fontsets/\ClassName-\mit@fontset.tex} @@ -261,7 +232,7 @@ \fi } -\RequirePackage{graphicx} +\RequirePackage{graphicx} \ifmit@pdfmanagement \ClassInfo{\ClassName}{pdfmanagement is defined. Will not load hyperxmp}% @@ -275,16 +246,36 @@ % authors should use hypersetup to set details, in root .tex file \urlstyle{same} % this changes font for \url to the current text font -\providecommand\hrefurl[2]{\href{#1}{#2}}% in case new pdf management has not been loaded +\providecommand\hrefurl[2]{\href{#1}{#2}}% in case \DocumentMetadata has not been loaded \RequirePackage{doi} % create macro for hyperlinking doi numbers -% Directly add the xmp property that shows work is copyrighted. See l3pdfmeta.pdf. -% This is not automatic with \DocumentMetadata. "True" must be capitalized. -\ExplSyntaxOn - \cs_if_exist:NTF \pdfmeta_xmp_add:n {\pdfmeta_xmp_add:n{True}}{} -\ExplSyntaxOff - - +% the user can override all these design choices in the preamble, +% or by using \AtBeginDocument{ \hypersetup{..} } in mydesign.tex +\hypersetup{ + colorlinks=true, + linkcolor=Blue3,% from xcolor package + citecolor=Blue3,% from xcolor package + urlcolor=violet,% from xcolor package + filecolor=red, +% anchorcolor=yellow,% not all pdf viewers recognize this field (although Firefox does): hyperref issues a warning +% colorscheme=phelype,% overrides link, cite, url, file colors with a preset scheme, through \DocumentMetadata + pdfborder={0 0 0}, + bookmarksnumbered=true, + bookmarksopen=true, + bookmarksopenlevel=1, +% pdfpagemode=UseNone,% this option means don't open bookmarks panel + pdfpagelayout=SinglePage, + pdfdisplaydoctitle=true, + pdfstartview=Fit, + pdfnewwindow=true, +% + pdfcontactaddress={Massachusetts Institute of Technology, 77 Massachusetts Avenue}, + pdfcontactcity={Cambridge, MA}, + pdfcontactpostcode={02139-4307}, + pdfcontactcountry={USA}, + pdfcontacturl={https://dspace.mit.edu/handle/1721.1/7582},% DSPACE@MIT theses page +} + %%%%%%%%%%%%% Stuff related to PDF bookmarks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Since \bm may be useful in headings, this fix will reduce frequency with which @@ -292,435 +283,666 @@ \pdfstringdefDisableCommands{% \def\bm#1#{\relax}% } -% %%% Let's disable \( and \) in pdf bookmarks \pdfstringdefDisableCommands{% \def\({\relax}% \def\){\relax}% } -% %%% Let's also make sure \NoCaseChange in section headings won't break pdf bookmarks \pdfstringdefDisableCommands{% - \let\NoCaseChange\relax% + \let\NoCaseChange\relax% } -% %%% Let's just remove citations from pdf bookmarks \pdfstringdefDisableCommands{% \def\cite{\@gobble}% } -% %%% Let's fix \eqref in pdf bookmarks \pdfstringdefDisableCommands{% \def\eqref#1{(\ref{#1})}% -% -%%% Let's make sure footnotes in section headings don't break pdf bookmarks. -\robustify{\footnote} +} +%%% Let's make sure footnotes in section headings don't break pdf bookmarks. (Note: redefined \footnote below is protected) % \patchcmd{\section}{\sectionmark}{\let\footnote\@gobble\sectionmark}{}{}% <== not needed unless you implement running heads \pdfstringdefDisableCommands{% \def\footnote#1{}% } -} -%%% Let's have commas separate successive footnotes -\let\oldfootnote\footnote -\renewcommand\footnote[1]{% - \oldfootnote{#1}\futurelet\nextToken\isOtherfnote} - -\newcommand\isOtherfnote{% - \ifx\footnote\nextToken\textsuperscript{\mdseries,}% - \fi% -} + +\ExplSyntaxOn +%\debug_on:n {all} + +%%%%%%%%%% Put comma between successive footnotes %%%%%%%%%%%%%%%%%%%%%%%%%%% + +\cs_new:Npn \__mitthesis_NoteComma:n { \peek_meaning:NTF \footnote {\textsuperscript{\mdseries,}} { } } +\cs_new_eq:NN \__savefootnote \footnote +\cs_gset_protected:Npn \footnote #1 { \__savefootnote{#1}\__mitthesis_NoteComma:n } + +%%%%%%%%%% End Footnote comma %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%% MACROS FOR HANDLING TITLE AND ABSTRACT PAGES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%% Dates %%%%%%%%%%%%%%% - -\ExplSyntaxOn -\NewExpandableDocumentCommand\MonthCheck{mm}{% - \str_case_e:nnF {#1}{ {May}{} {June}{} {September}{} {February}{} - {\space May}{} {\space June}{} {\space September}{} {\space February}{} - {May\space}{} {June\space}{} {September\space}{} { February\space}{} - {\space May\space}{} {\space June\space}{} {\space September\space}{} {\space February\space}{} - }{#2} +%%%%%%%%%% Degree Date Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\tl_new:N \g__dd_month_tl +\tl_new:N \g__dd_year_tl +\cs_generate_variant:Nn \msg_error:nnn {nne} +\cs_generate_variant:Nn \str_casefold:n {e} +\cs_generate_variant:Nn \tl_gremove_all:Nn {No} +\cs_new_protected:Nn \__dd_setdates:nn { + \tl_gset:Nn \g__dd_month_tl {#1} + \tl_gset:Nn \g__dd_year_tl {#2} + \tl_gremove_all:No \g__dd_month_tl { \space } + \tl_gremove_all:No \g__dd_year_tl { \space } + \str_case_e:nnF + { \str_casefold:e { \tl_to_str:N \g__dd_month_tl } } + { {february}{} {may}{} {june}{} {september}{}} + { \msg_error:nne {\ClassName} {wrong_month} { \text_titlecase:n {\g__dd_month_tl} } } } -\ExplSyntaxOff +\msg_new:nnnn {\ClassName} {wrong_month} {The\ degree\ month\ must\ be\ one\ of\ February,\ May,\ June,\ or\ September.} {You\ cannot\ use\ #1\ as\ the\ degree\ month.} -\NewDocumentCommand\DegreeDate{mm}{% - \def\@DegreeMonth{\ignorespaces#1}% - \def\@@DegreeMonth{#1}% - \def\@DegreeYear{\ignorespaces#2}% - \def\DegreeYear{\ignorespaces#2}% +\cs_generate_variant:Nn \text_titlecase:n {o,V} +\NewDocumentCommand\DegreeDate{mm}{% {month}{year} + \__dd_setdates:nn {#1}{#2} + \cs_new:Npn \DegreeMonth { \text_titlecase:V { \g__dd_month_tl } } + \cs_new:Npn \DegreeYear { \text_titlecase:V { \g__dd_year_tl } } +} +\msg_new:nnnn {\ClassName} {no_degree_date} {Missing\ degree\ date!}{ + You\ MUST\ issue\ the\ \DegreeDate{month}{year}\ command\ between\ \string\begin{document}\ and\ \string\maketitle.} + +\NewDocumentCommand\ThesisDate{m}{ + \tl_if_exist:NTF \g_dd_thesisdate_tl { \g_dd_thesisdate_tl } { \__dd_thesisdate:n {#1} }% will use only value given first +} +\cs_new_protected:Nn \__dd_thesisdate:n { + \tl_new:N \g_dd_thesisdate_tl + \tl_gset:Nx \g_dd_thesisdate_tl { \tl_trim_spaces:n {#1} } } -\NewDocumentCommand\ThesisDate{m}{% - \def\@ThesisDate{\ignorespaces#1}% +%%%%%%%%%% End Degree Date Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%%% Author Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\seq_new:N \g_author_name_seq +\seq_new:N \g_author_department_seq +\seq_new:N \g_author_prevdegree_seq +\seq_new:N \g_author_secondprevdegree_seq +\seq_new:N \g_author_thirdprevdegree_seq +\seq_new:N \g_author_fourthprevdegree_seq +\int_gzero_new:N \g_author_authorcnt_int + +\NewDocumentCommand\Author{mm O{}O{}O{}O{} } + { + \tl_if_blank:nTF{#1}{ + \msg_error:nn {\ClassName} {blank_author} + }{ + \__author_data_add:nnnnnn { #1 } { #2 } { #3 } { #4 } { #5 } { #6 } + } + \tl_if_blank:nTF{#2}{\msg_error:nn {\ClassName} {blank_author_dep}}{} + } +\cs_new_protected:Nn \__author_data_add:nnnnnn + { + \int_gincr:N \g_author_authorcnt_int + \seq_gput_right:cx { g_author_name_seq } { \tl_trim_spaces:n {#1} } + \seq_gput_right:cx { g_author_department_seq } { \tl_trim_spaces:n {#2} } + \seq_gput_right:cx { g_author_prevdegree_seq } { \tl_trim_spaces:n {#3} } + \seq_gput_right:cx { g_author_secondprevdegree_seq } { \tl_trim_spaces:n {#4} } + \seq_gput_right:cx { g_author_thirdprevdegree_seq } { \tl_trim_spaces:n {#5} } + \seq_gput_right:cx { g_author_fourthprevdegree_seq } { \tl_trim_spaces:n {#6} } + } +\msg_new:nnnn {\ClassName} {blank_author} {Missing\ author\ name,\ check\ for\ blank\ in\ \Author\ command.}{% + You\ MUST\ provide\ an\ author\ name\ using\ the\ \Author{name}{department}\ command.} +\msg_new:nnnn {\ClassName} {blank_author_dep} {Missing\ author\ department,\ check\ for\ blank\ in\ \Author\ command.}{% + You\ MUST\ provide\ the\ author's\ department\ using\ the\ \Author{name}{department}\ command.} + +\NewExpandableDocumentCommand\CopyrightAuthor{}{ + \tl_if_exist:NTF \g__author_ca_tl + { \g__author_ca_tl } + { \__author_copyrightauthor: \g__author_ca_tl } } -%%%%%%%%%%%%%% Author, supervisor, acceptor, titles, and departments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newcounter{authorcnt} -\setcounter{authorcnt}{0}% this counter's final value is used repeatedly. - -\NewDocumentCommand\Author{m m oooo}{% - \ifblank{#1}{% - \ClassError{\ClassName}{Missing author name, check for blank in Author command}{% - You MUST provide an author name using the \Author{name}{department} command.}% - }{% - \addtocounter{authorcnt}{1}% - \expandafter\xdef\csname aut@\theauthorcnt\endcsname{\ignorespaces#1}% - \expandafter\xdef\csname autdep@\theauthorcnt\endcsname{\ignorespaces#2}% - \IfNoValueF{#3}{\expandafter\xdef\csname prevdegree@\theauthorcnt\endcsname{\ignorespaces#3}}% - \IfNoValueF{#4}{\expandafter\xdef\csname secondprevdegree@\theauthorcnt\endcsname{\ignorespaces#4}}% - \IfNoValueF{#5}{\expandafter\xdef\csname thirdprevdegree@\theauthorcnt\endcsname{\ignorespaces#5}}% - \IfNoValueF{#6}{\expandafter\xdef\csname fourthprevdegree@\theauthorcnt\endcsname{\ignorespaces#6}}% - }% - \ifblank{#2}{\ClassWarning{\ClassName}{Missing author department, check for blank in Author command}}{}% -}% defines \aut@authorcnt as Name #1 and \autdep@authorcnt as Name #1's department - -\newcounter{authorno} -\setcounter{authorno}{0} - -\NewDocumentCommand\@AuthorBlock{}{% Revised 2023/06/23 - \setcounter{authorno}{1}% - \ifnum\value{authorcnt}=0 - \ClassError{\ClassName}{Missing author! You must issue the \Author{name}{department} command}{% - You MUST issue the \Author{name}{department} command after \begin{document} and before \maketitle.}% - \fi - {by\par - \whiledo{\value{authorno}<\value{authorcnt}}{% - \ignorespaces\csname aut@\theauthorno\endcsname\par - \ifcsundef{prevdegree@\theauthorno}{\relax}{\normalsize\csname prevdegree@\theauthorno\endcsname}% - \ifcsundef{secondprevdegree@\theauthorno}{\relax}{\linebreak\normalsize\csname secondprevdegree@\theauthorno\endcsname}% - \ifcsundef{thirdprevdegree@\theauthorno}{\relax}{\linebreak\normalsize\csname thirdprevdegree@\theauthorno\endcsname}% - \ifcsundef{fourthprevdegree@\theauthorno}{\relax}{\linebreak\normalsize\csname fourthprevdegree@\theauthorno\endcsname}% - \par and\par - \addtocounter{authorno}{1}% - }% - \ignorespaces\csname aut@\theauthorno\endcsname - \ifcsundef{prevdegree@\theauthorno}{\relax}{\par\normalsize\csname prevdegree@\theauthorno\endcsname}% - \ifcsundef{secondprevdegree@\theauthorno}{\relax}{\linebreak \normalsize\csname secondprevdegree@\theauthorno\endcsname}% - \ifcsundef{thirdprevdegree@\theauthorno}{\relax}{\linebreak \normalsize\csname thirdprevdegree@\theauthorno\endcsname}% - \ifcsundef{fourthprevdegree@\theauthorno}{\relax}{\linebreak \normalsize\csname fourthprevdegree@\theauthorno\endcsname}% - \par\medskip - }% +\cs_new_protected:Nn \__author_copyrightauthor: { + \tl_new:N \g__author_ca_tl + \int_zero_new:N \l__author_autcrcnt_int + \int_incr:N \l__author_autcrcnt_int + \tl_gset:Nx \g__author_ca_tl { \seq_item:cn { g_author_name_seq } { \l__author_autcrcnt_int } } + \int_incr:N \l__author_autcrcnt_int + \int_while_do:nNnn { \l__author_autcrcnt_int } < { \g_author_authorcnt_int } + { + \tl_gput_right:Nx \g__author_ca_tl {,\ \seq_item:cn { g_author_name_seq } { \l__author_autcrcnt_int } } + \int_incr:N \l__author_autcrcnt_int + } + \int_compare:nNnT { \l__author_autcrcnt_int } = { \g_author_authorcnt_int } { + \tl_gput_right:Nx \g__author_ca_tl {\ and\ \seq_item:cn { g_author_name_seq } { \l__author_autcrcnt_int } } + } + \tl_set:Nn \l_tmpa_tl {\tl_item:Nn \g__author_ca_tl {-1} }% get last token + \str_case_e:nnT + { \l_tmpa_tl } + { {.}{} } + { \__copyright_remove_period:N { \g__author_ca_tl } }% remove last token if it is a period + \__author_pdfcopyrightauthor: +} +\cs_new:Nn \__copyright_remove_period:N + { + \tl_gset:Nx #1 { \tl_range:Nnn #1 { 1 } { \tl_count:N #1 - 1 } } + } +\cs_new_protected:Nn \__author_pdfcopyrightauthor: { + \tl_new:N \g__author_pdfca_tl + \int_set:Nn \l_tmpa_int {1} + \tl_gset:Nx \g__author_pdfca_tl { { \seq_item:cn { g_author_name_seq } { \l_tmpa_int } } } + \int_until_do:nNnn { \l_tmpa_int } = { \g_author_authorcnt_int } + { + \int_incr:N \l_tmpa_int + \tl_gput_right:Nx \g__author_pdfca_tl {,\ { \seq_item:cn { g_author_name_seq } { \l_tmpa_int } } } + } } -\NewDocumentCommand\@AbstractAuthorBlock{}{% Revised 2023/07/20 - \setcounter{authorno}{1}% + +\cs_new:Nn \__author_block: { + \int_zero_new:N \l__author_authorno_int + \int_incr:N \l__author_authorno_int + \int_compare:nNnTF { \g_author_authorcnt_int } = {0} { + \msg_error:nn {\ClassName} {no_author} + } {by\par - \whiledo{\value{authorno}<\value{authorcnt}}{% - \ignorespaces\csname aut@\theauthorno\endcsname + \int_until_do:nNnn { \l__author_authorno_int } = { \g_author_authorcnt_int } { + \seq_item:cn { g_author_name_seq } { \l__author_authorno_int } \par + \tl_set:Nx \l_tmpa_tl { \seq_item:cn { g_author_prevdegree_seq } { \l__author_authorno_int} } + \tl_if_empty:NF \l_tmpa_tl { \normalsize \l_tmpa_tl }% no linebreak or par for empty items + \tl_set:Nx \l_tmpa_tl { \seq_item:cn { g_author_secondprevdegree_seq } { \l__author_authorno_int} } + \tl_if_empty:NF \l_tmpa_tl { \linebreak\normalsize \l_tmpa_tl } + \tl_set:Nx \l_tmpa_tl { \seq_item:cn { g_author_thirdprevdegree_seq } { \l__author_authorno_int} } + \tl_if_empty:NF \l_tmpa_tl { \linebreak\normalsize \l_tmpa_tl } + \tl_set:Nx \l_tmpa_tl { \seq_item:cn { g_author_fourthprevdegree_seq } { \l__author_authorno_int} } + \tl_if_empty:NF \l_tmpa_tl { \linebreak\normalsize \l_tmpa_tl } \par and\par - \addtocounter{authorno}{1}% - }% - \ignorespaces\csname aut@\theauthorno\endcsname + \int_incr:N \l__author_authorno_int + } + \seq_item:cn { g_author_name_seq } { \l__author_authorno_int } \par + \tl_set:Nx \l_tmpa_tl { \seq_item:cn { g_author_prevdegree_seq } { \l__author_authorno_int} } + \tl_if_empty:NF \l_tmpa_tl { \normalsize \l_tmpa_tl }% no linebreak or par for empty items + \tl_set:Nx \l_tmpa_tl { \seq_item:cn { g_author_secondprevdegree_seq } { \l__author_authorno_int} } + \tl_if_empty:NF \l_tmpa_tl { \linebreak\normalsize \l_tmpa_tl } + \tl_set:Nx \l_tmpa_tl { \seq_item:cn { g_author_thirdprevdegree_seq } { \l__author_authorno_int} } + \tl_if_empty:NF \l_tmpa_tl { \linebreak\normalsize \l_tmpa_tl } + \tl_set:Nx \l_tmpa_tl { \seq_item:cn { g_author_fourthprevdegree_seq } {\l__author_authorno_int} } + \tl_if_empty:NF \l_tmpa_tl { \linebreak\normalsize \l_tmpa_tl } + \par\medskip + } +} +\msg_new:nnnn {\ClassName} {no_author} + { Missing\ author!\ You\ must\ issue\ the\ \Author{name}{department}\ command. }{ + You\ MUST\ issue\ the\ \Author{name}{department}\ command\ after\ \string\begin{document}\ and\ before\ \string\maketitle. } + +\cs_new:Nn \__author_abstractblock: { + \int_zero_new:N \l__author_authorno_int + \int_incr:N \l__author_authorno_int + \int_compare:nNnTF { \g_author_authorcnt_int } = {0} { + \msg_error:nn {\ClassName} {no_author} + } + {by\par + \int_until_do:nNnn { \l__author_authorno_int } = { \g_author_authorcnt_int } { + \seq_item:cn { g_author_name_seq } { \l__author_authorno_int } + \par and\par + \int_incr:N \l__author_authorno_int + }% + \seq_item:cn { g_author_name_seq } { \l__author_authorno_int } }% } -\newcounter{autcrcnt} -\setcounter{autcrcnt}{1} +%%%%%%%%%% End Author Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\NewDocumentCommand\@CopyrightAuthor{}{% - \csname aut@\theautcrcnt\endcsname - \addtocounter{autcrcnt}{1}% - \whiledo{\value{autcrcnt}<\value{authorcnt}}{% - , \ignorespaces\csname aut@\theautcrcnt\endcsname - \addtocounter{autcrcnt}{1}% - }% - \ifnum\value{autcrcnt}=\value{authorcnt}% - \space and\space\csname aut@\theauthorcnt\endcsname\ignorespaces - \fi - \setcounter{autcrcnt}{1}% reset so we can use this command more than once + +%%%%%%%%%% Supervisor Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\seq_new:N \g_supervisor_name_seq +\seq_new:N \g_supervisor_title_seq +\int_gzero_new:N \g_supervisor_supervisorcnt_int + +\NewDocumentCommand\Supervisor{mm}{ + \tl_if_blank:nTF{#1}{ + \msg_error:nn {\ClassName} {blank_supervisor} + }{ + \__supervisor_data_add:nn { #1 } { #2 } + } + \tl_if_blank:nTF{#2}{\msg_error:nn {\ClassName} {blank_supervisor_title}}{} } +\msg_new:nnnn {\ClassName} {blank_supervisor} + { Missing\ supervisor\ name, check\ for\ blank\ in\ \Supervisor{name}{title}\ command.}{ + You\ MUST\ provide\ the\ supervisor's\ name\ using\ the\ \Supervisor{name}{title}\ command.} +\msg_new:nnnn {\ClassName} {blank_supervisor_title} + { Missing\ supervisor\ title, check\ for\ blank\ in\ \Supervisor{name}{title}\ command. }{ + You\ MUST\ provide\ the\ supervisor's\ title\ using\ the\ \Supervisor{name}{title}\ command.} + +\cs_new_protected:Nn \__supervisor_data_add:nn + { + \int_gincr:N \g_supervisor_supervisorcnt_int + \seq_gput_right:cx { g_supervisor_name_seq } { \tl_trim_spaces:n {#1} } + \seq_gput_right:cx { g_supervisor_title_seq } { \tl_trim_spaces:n {#2} } + } + + +\cs_new:Nn \__supervisor_abstractblock: { + \int_zero_new:N \l__supervisor_supervisorno_int + \int_incr:N \l__supervisor_supervisorno_int + \setlength{\parindent}{0pt} + \par\bigskip + \int_compare:nNnTF { \g_supervisor_supervisorcnt_int } = {0} { + \msg_error:nn {\ClassName} {no_supervisor} + } + {\int_until_do:nNnn { \l__supervisor_supervisorno_int } = { \g_supervisor_supervisorcnt_int } { + Thesis\ supervisor:\space \seq_item:cn { g_supervisor_name_seq } { \l__supervisor_supervisorno_int }\par + Title:\space \seq_item:cn { g_supervisor_title_seq } { \l__supervisor_supervisorno_int }\par\medskip + \int_incr:N \l__supervisor_supervisorno_int + } + Thesis\ supervisor:\space \seq_item:cn { g_supervisor_name_seq } { \l__supervisor_supervisorno_int }\par + Title:\space \seq_item:cn { g_supervisor_title_seq } { \l__supervisor_supervisorno_int }\ignorespaces + } +} +\msg_new:nnnn {\ClassName} {no_supervisor} + { Missing\ supervisor!\ You\ must\ issue\ the\ \Supervisor{name}{title}\ command. }{ + You\ MUST\ issue\ the\ \Supervisor{name}{title}\ command\ after\ \string\begin{document}\ and\ before\ \string\maketitle. } -\newcounter{degcnt} -\setcounter{degcnt}{0} -\newcounter{depflag} -\setcounter{depflag}{0} -\NewDocumentCommand\Degree{mm}{% Revised 2023/06/23 - \ifblank{#1}{% - \ClassError{\ClassName}{Missing degree name, check for blank \Degree{name}{department} command}{% - Check for blank name \Degree{name}{department} command.}% - }{% - \addtocounter{degcnt}{1}% - \expandafter\xdef\csname deg@\thedegcnt\endcsname{\ignorespaces#1}% - \expandafter\xdef\csname degdep@\thedegcnt\endcsname{\ignorespaces#2}% - }% - \ifblank{#2}{% - \setcounter{depflag}{\value{degcnt}}% - \ClassWarning{\ClassName}{Missing degree department for Degree command number \thedegcnt. Assuming to be a duplicate of previous department}}{}% -}% defines \deg@degcnt as Name #1 and \degdep@degcnt as associated dept. - -\newcounter{degno} -\newcounter{depno} -\NewDocumentCommand\@DegreeBlock{}{% extensive revision 2023/06/23 - \ifnum\value{degcnt}=0 - \ClassError{\ClassName}{Missing degree! You must issue the \Degree{name}{department} command}{% - You MUST issue the \Degree{name}{department} command after \begin{document} and before \maketitle. You do want the degree, don't you?}% - \fi - \setcounter{degno}{1} - \setcounter{depno}{1} - \newcommand*\PrevDept{\csname degdep@\thedepno\endcsname} - \newcommand*\CurrDept{} - Submitted to the \mbox{\PrevDept}% - \whiledo{\value{depno}<\value{degcnt}}{% - \addtocounter{depno}{1}% - \renewcommand*\CurrDept{\csname degdep@\thedepno\endcsname}% - \ifnum\value{depflag}=\value{depno}\relax\else - \space and the\linebreak - \mbox{\CurrDept}% - \fi% - }% - \linebreak \mbox{in partial fulfillment of the requirements for the\space - \ifnum\value{degcnt}>1 degrees\else degree\fi\space of}% + +%%%%%%%%%% End Supervisor Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%%% Acceptor Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\seq_new:N \g_acceptor_name_seq +\seq_new:N \g_acceptor_department_seq +\seq_new:N \g_acceptor_title_seq +\int_gzero_new:N \g_acceptor_acceptorcnt_int + +\bool_new:N \g__acceptor_title_tf_bool +\bool_gset_false:N \g__acceptor_title_tf_bool + +\NewDocumentCommand\Acceptor{mmm}{ + \tl_if_blank:nTF{#1}{ + \msg_error:nn {\ClassName} {blank_acceptor} + }{ + \__acceptor_data_add:nnn {#1} {#2} {#3} + } + \tl_if_blank:nTF{#2}{\msg_error:nn {\ClassName} {blank_acceptor_dep}}{} + \tl_if_blank:nTF{#3}{ + \bool_gset_true:N \g__acceptor_title_tf_bool + \msg_warning:nn {\ClassName} {blank_acceptor_title}}{} +} +\msg_new:nnnn {\ClassName} {blank_acceptor} + { Missing\ acceptor\ name, check\ for\ blank\ in\ \Acceptor{name}{department}{title}\ command.}{ + You\ MUST\ provide\ the\ acceptor's\ name\ using\ the\ \Acceptor{name}{department}{title}\ command.} +\msg_new:nnnn {\ClassName} {blank_acceptor_dep} + { Missing\ acceptor\ department, check\ for\ blank\ in\ \Acceptor{name}{department}{title}\ command. }{ + You\ MUST\ provide\ the\ acceptor's\ department\ using\ the\ \Acceptor{name}{department}{title}\ command.} +\msg_new:nnn {\ClassName} {blank_acceptor_title} + { Missing\ acceptor\ title\ (blank\ in\ \Acceptor{name}{department}{title}\ command).\ Perhaps\ you\ are\ trying\ to\ save\ vertical\ space?\ You\ can\ put\ the\ acceptor\ title\ into\ department\ field\ instead.\ For\ consistency,\ I\ will\ omit\ titles\ of\ ALL\ acceptors.} + +\cs_new_protected:Nn \__acceptor_data_add:nnn + { + \int_gincr:N \g_acceptor_acceptorcnt_int + \seq_gput_right:cx { g_acceptor_name_seq } { \tl_trim_spaces:n {#1} } + \seq_gput_right:cx { g_acceptor_department_seq } { \tl_trim_spaces:n {#2} } + \seq_gput_right:cx { g_acceptor_title_seq } { \tl_trim_spaces:n {#3} } + } + +%%%%%%%%%% End Acceptor Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%%% Degree Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\seq_new:N \g_degree_name_seq +\seq_new:N \g_degree_department_seq +\int_gzero_new:N \g_degree_degreecnt_int +\int_gzero_new:N \g__degree_degreeflag_int + +\NewDocumentCommand\Degree{mm} + { + \tl_if_blank:nTF {#1} { + \msg_error:nn {\ClassName} {blank_degree} + }{ + \__degree_data_add:nn { #1 } { #2 } + } + \tl_if_blank:nT {#2} { + \int_gset_eq:NN \g__degree_degreeflag_int \g_degree_degreecnt_int + \msg_warning:nnx {\ClassName} {blank_degree_dep} { \int_to_arabic:n { \g__degree_degreeflag_int } } + \tl_if_blank:nT {#1} { \int_gincr:N \g__degree_degreeflag_int }% in case both are blank + } + } +\cs_new_protected:Nn \__degree_data_add:nn + { + \int_gincr:N \g_degree_degreecnt_int + \seq_gput_right:cx { g_degree_name_seq } { \tl_trim_spaces:n {#1} } + \seq_gput_right:cx { g_degree_department_seq } { \tl_trim_spaces:n {#2} } + } +\msg_new:nnnn {\ClassName} {blank_degree} {Missing\ degree\ name,\ check\ for\ blank\ in\ \Degree\ command.} + {You\ MUST\ provide\ a\ degree\ name\ using\ the\ \Degree{name}{department}\ command.} +\msg_new:nnnn {\ClassName} {blank_degree_dep} {Missing\ degree\ department\ for\ Degree\ command\ number\ + #1.\ Will\ treat\ as\ a\ duplicate\ of\ previous\ department.}{} + +\int_zero_new:N \l__degree_degreeno_int +\int_zero_new:N \l__degree_departmentno_int + +\cs_new:Nn \__degree_block: { + \int_compare:nNnTF { \g_degree_degreecnt_int } = {0} { + \msg_error:nn {\ClassName} {no_degree} + } + \int_zero_new:N \l__degree_degreeno_int + \int_incr:N \l__degree_degreeno_int + \int_zero_new:N \l__degree_departmentno_int + \int_incr:N \l__degree_departmentno_int + \cs_new:Nx \__degree_prevdept: {\seq_item:cn { g_degree_department_seq } { \l__degree_departmentno_int } } + \cs_new:Nn \__degree_currdept: {} + \mbox {Submitted\ to\ the\ } \mbox {\__degree_prevdept:} + \int_until_do:nNnn { \l__degree_departmentno_int } = { \g_degree_degreecnt_int } { + \int_incr:N \l__degree_departmentno_int + \cs_set:Nx \__degree_currdept: {\seq_item:cn { g_degree_department_seq } { \l__degree_departmentno_int } } + \int_compare:nNnTF { \l__degree_departmentno_int } = {\g__degree_degreeflag_int } { \scan_stop: } + { + \mbox {\ and\ the}\linebreak + \mbox {\__degree_currdept: } + } + } + \linebreak \mbox {in\ partial\ fulfillment\ of\ the\ requirements\ for\ the\ + \int_compare:nNnTF { \g_degree_degreecnt_int } > {1} {degrees} {degree} + \ of} \par\medskip - \whiledo{\value{degno}<\value{degcnt}}{% - \MakeUppercase{\ignorespaces\csname deg@\thedegno\endcsname}\par and\par - \addtocounter{degno}{1}% - }% - \MakeUppercase{\ignorespaces\csname deg@\thedegno\endcsname}\par\medskip + \int_until_do:nNnn { \l__degree_degreeno_int } = { \g_degree_degreecnt_int } { + \text_uppercase:n {\seq_item:cn { g_degree_name_seq } { \l__degree_degreeno_int }}\par and\par + \int_incr:N \l__degree_degreeno_int + } + \text_uppercase:n {\seq_item:cn { g_degree_name_seq } { \l__degree_degreeno_int }}\par\medskip } - -\NewDocumentCommand\@AbstractDegreeBlock{}{% 2023/07/19 - \setcounter{degno}{1} - \setcounter{depno}{1} - \newcommand*\PrevDept{\csname degdep@\thedepno\endcsname} - \newcommand*\CurrDept{} - Submitted to the \mbox{\PrevDept}% - \whiledo{\value{depno}<\value{degcnt}}{% - \addtocounter{depno}{1}% - \renewcommand*\CurrDept{\csname degdep@\thedepno\endcsname}% - \ifnum\value{depflag}=\value{depno}\relax\else - \space and the\linebreak - \mbox{\CurrDept}% - \fi% - }% - \linebreak on \@ThesisDate \space \mbox{in partial fulfillment of the requirements for the\space - \ifnum\value{degcnt}>1 degrees\else degree\fi\space of}% +\msg_new:nnnn {\ClassName} {no_degree} + { Missing\ degree!\ You\ must\ issue\ the\ \Degree{name}{department}\ command. }{ + You\ MUST\ issue\ the\ \Degree{name}{department}\ command\ after\ \string\begin{document}\ and\ before\ \string\maketitle.\ You\ do\ want\ the\ degree,\ don't\ you?} + + +\cs_new:Nn \__degree_abstractblock: { + \int_set:Nn \l__degree_degreeno_int {1} + \int_set:Nn \l__degree_departmentno_int {1} + \cs_set:Nx \__degree_prevdept: {\seq_item:cn { g_degree_department_seq } { \l__degree_departmentno_int } } + \cs_set:Nn \__degree_currdept: {} + \mbox {Submitted\ to\ the\ }\mbox{\__degree_prevdept:} + \int_until_do:nNnn { \l__degree_departmentno_int } = { \g_degree_degreecnt_int } { + \int_incr:N \l__degree_departmentno_int + \cs_set:Nx \__degree_currdept: {\seq_item:cn { g_degree_department_seq } { \l__degree_departmentno_int } } + \int_compare:nNnTF { \g__degree_degreeflag_int } = { \g_degree_degreecnt_int } { \scan_stop: } + { + \mbox {\ and\ the}\linebreak + \mbox { \__degree_currdept: } + } + } + \linebreak \mbox{on\ \g_dd_thesisdate_tl\ in\ partial\ fulfillment\ of\ the\ requirements\ for\ the\ + \int_compare:nNnTF { \g_degree_degreecnt_int } > {1} {degrees} {degree} + \ of} \par\medskip - \whiledo{\value{degno}<\value{degcnt}}{% - \MakeUppercase{\ignorespaces\csname deg@\thedegno\endcsname}\par and\par - \addtocounter{degno}{1}% - }% - \MakeUppercase{\ignorespaces\csname deg@\thedegno\endcsname}\par\medskip + \int_until_do:nNnn { \l__degree_degreeno_int } = { \g_degree_degreecnt_int } { + \text_uppercase:n {\seq_item:cn { g_degree_name_seq } { \l__degree_degreeno_int }}\par and\par + \int_incr:N \l__degree_degreeno_int + } + \text_uppercase:n {\seq_item:cn { g_degree_name_seq } { \l__degree_degreeno_int }}\par\medskip } +%%%%%%%%%% End Degree Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcounter{supcnt} -\setcounter{supcnt}{0} -\newcounter{supno} -\setcounter{supno}{0} -\NewDocumentCommand\Supervisor{mm}{% - \ifblank{#1}{% - \ClassError{\ClassName}{Missing supervisor name, check for blank in \Supervisor{name}{department} command}{ - Check for blank in \Supervisor{name}{department} command.}% - }{% - \addtocounter{supcnt}{1}% - \expandafter\xdef\csname sup@\thesupcnt\endcsname{#1}% - \expandafter\xdef\csname supdep@\thesupcnt\endcsname{#2}% - }% - \ifblank{#2}{\ClassError{\ClassName}{Missing supervisor department, check for blank in \Supervisor{name}{department} command}{% - check for blank in \Supervisor{name}{department} command.}}{}% -}% defines \sup@supcnt as Name #1 and \supdep@supcnt as associated dept. - -\newcounter{acccnt} -\setcounter{acccnt}{0} -\newcounter{accno} -\setcounter{accno}{0} -\newif\ifmit@noacctitle\mit@noacctitlefalse % Revised 2023/06/23 -\NewDocumentCommand\Acceptor{mmm}{% - \ifblank{#1}{% - \ClassWarning{\ClassName}{Missing acceptor name, check for blank in \Acceptor{name}{department}{title} command}% - }{% - \addtocounter{acccnt}{1}% - \expandafter\xdef\csname acc@\theacccnt\endcsname{#1}% - \expandafter\xdef\csname accdep@\theacccnt\endcsname{#2}% - \expandafter\xdef\csname acctitle@\theacccnt\endcsname{#3}% - }% - \ifblank{#2}{\ClassWarning{\ClassName}{Missing acceptor department, check for blank in \Acceptor{name}{department}{title} command.}}{}% - \ifblank{#3}{% - \mit@noacctitletrue - \ClassWarning{\ClassName}{Missing acceptor title (blank in \Acceptor{name}{department}{title} command). Perhaps you are trying to save vertical space? You can put the acceptor title into department field instead. For consistency, I will omit titles of ALL acceptors.}% - }{}% -}% defines \acc@acccnt as Name #1, \accdep@accccnt as associated dept, and \acctitle@acccnt as title of acceptor - -\newcommand*\@SigSize{\relax} -\NewDocumentCommand\SignatureBlockSize{m}{\renewcommand\@SigSize{\ignorespaces#1}}% revised 2023/06/23 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\NewDocumentCommand\@SetSignatureBlock{}{% Revised 2023/06/23 - \ifnum\value{supcnt}=0 - \ClassError{\ClassName}{Missing supervisor! You must issue the \Supervisor{name}{department} command}{% - You MUST issue the \Supervisor{name}{department} command after \begin{document} and before \maketitle.}% - \fi - \ifnum\value{acccnt}=0 - \ClassError{\ClassName}{Missing acceptor! You must issue the \Acceptor{name}{department} command}{% - You MUST issue the \Acceptor{name}{department} command after \begin{document} and before \maketitle.}% - \fi - \ifdefined\@ThesisDate\else\ClassError{\ClassName}{Missing thesis date!}{% - You must issue the \ThesisDate{Date thesis is submitted} command between \begin{document} and \maketitle.}% - \fi - \setcounter{authorno}{0}% - \setcounter{supno}{0}% - \setcounter{accno}{0}% - \@SigSize +%%%%%%%%%% Signature Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\NewDocumentCommand\SignatureBlockSize{m}{ + \__signature_sigsize:n {#1} +} +\tl_new:N \g__signature_sigsize_tl +\cs_new_protected:Nn \__signature_sigsize:n + { + \tl_gset:Nf \g__signature_sigsize_tl { \tl_trim_spaces:n {#1} } + \token_case_meaning:NnF \g__signature_sigsize_tl + { + \normalsize {} \small {} \footnotesize{} \scriptsize{} \tiny{} + } { + \msg_error:nn {\ClassName} {weird_sigsize} + } + } + +\cs_new:Nn \__signature_block: { + \int_compare:nNnT { \g_supervisor_supervisorcnt_int } = {0} { + \msg_error:nn {\ClassName} {no_supervisor}% this message is def'd in Abstract supervisor block + } + \int_compare:nNnT { \g_acceptor_acceptorcnt_int } = {0} { + \msg_error:nn {\ClassName} {no_acceptor} + } + \tl_if_exist:NF \g_dd_thesisdate_tl { + \msg_error:nn {\ClassName} {no_thesis_date} + } + \int_gzero_new:N \g__signature_autno_int + \int_gzero_new:N \g__signature_supno_int + \int_gzero_new:N \g__signature_accno_int + \g__signature_sigsize_tl \begin{tabbing} - \hspace{1.35in}\=\hspace{1in}\kill - \whiledo{\value{authorno}<\value{authorcnt}}{% starting with authorno = 0 ensures we reach authorcnt with +1 - \addtocounter{authorno}{1}% - Authored by: \> \csname aut@\theauthorno\endcsname\\% remove \ignorespaces x9, 2023/06/23 - \> \csname autdep@\theauthorno\endcsname\\ - \> \@ThesisDate \\[1em] - }% end whiledo - \whiledo{\value{supno}<\value{supcnt}}{% - \addtocounter{supno}{1}% - Certified by: \> \csname sup@\thesupno\endcsname\\ - \> \csname supdep@\thesupno\endcsname, Thesis Supervisor\\[1em] - }% end whiledo - \whiledo{\value{accno}<\value{acccnt}}{% - \addtocounter{accno}{1}% - Accepted by: \> \csname acc@\theaccno\endcsname\\ - \> \csname accdep@\theaccno\endcsname - \ifmit@noacctitle\else %<=== 2023/06/23 - \\ - \> \csname acctitle@\theaccno\endcsname - \fi - \\[1em] - }% end whiledo + \hspace{1.35in} \= \hspace{1in} \kill + \int_do_while:nNnn { \g__signature_autno_int } < { \g_author_authorcnt_int } { + \int_gincr:N \g__signature_autno_int + Authored\ by: \> \seq_item:cn { g_author_name_seq } { \g__signature_autno_int } \\ + \> \seq_item:cn { g_author_department_seq } { \g__signature_autno_int } \\ + \> \g_dd_thesisdate_tl \\[1em] + } + \int_do_while:nNnn { \g__signature_supno_int } < { \g_supervisor_supervisorcnt_int } { + \int_gincr:N \g__signature_supno_int + Certified\ by: \> \seq_item:cn { g_supervisor_name_seq } { \g__signature_supno_int } \\ + \> \seq_item:cn { g_supervisor_title_seq } { \g__signature_supno_int },\ Thesis\ Supervisor\\[1em] + } + \int_compare:nNnF { \g_acceptor_acceptorcnt_int } = {0} { + \int_do_while:nNnn { \g__signature_accno_int } < { \g_acceptor_acceptorcnt_int } { + \int_gincr:N \g__signature_accno_int + Accepted\ by: \> \seq_item:cn { g_acceptor_name_seq } { \g__signature_accno_int } \\ + \> \seq_item:cn { g_acceptor_department_seq } { \g__signature_accno_int } + \bool_if:NF \g__acceptor_title_tf_bool + { + \\ + \> \seq_item:cn { g_acceptor_title_seq } { \g__signature_accno_int } + } + \\[1em] + } + } \end{tabbing} } -\NewDocumentCommand\@SetAbstractSupervisorBlock{}{% revised 2023/06/23 - \setcounter{supno}{1} - \setlength{\parindent}{0pt} - \par\bigskip\noindent - \whiledo{\value{supno}<\value{supcnt}}{% - Thesis supervisor: \csname sup@\thesupno\endcsname\par - Title: \csname supdep@\thesupno\endcsname\par\medskip - \addtocounter{supno}{1}% - }% end whiledo - Thesis supervisor: \csname sup@\thesupno\endcsname\par - Title: \csname supdep@\thesupno\endcsname\ignorespaces -} +\msg_new:nnnn {\ClassName} {weird_sigsize} + { \SignatureBlockSize\ expects\ a\ font-sizing\ command,\ such\ as\ \small,\ \footnotesize,\ etc.}{You\ used\ a\ weird\ input\ value\ here.\ If\ you\ did\ so\ deliberately,\ try\ continuing.} +\msg_new:nnnn {\ClassName} {no_acceptor} + { Missing\ acceptor!\ You\ must\ issue\ the\ \Acceptor{name}{department}{title}\ command. }{ + You\ MUST\ issue\ the\ \Acceptor{name}{department}{title}\ command\ after\ \string\begin{document}\ and\ before\ \string\maketitle.} +\msg_new:nnnn {\ClassName} {no_thesis_date} + { Missing\ thesis\ date!\ You\ must\ issue\ the\ \ThesisDate{Date\ thesis\ is\ submitted}\ command.}{ + You\ MUST\ issue\ the\ \ThesisDate{Date thesis is submitted}\ command\ after\ \string\begin{document}\ and\ before\ \string\maketitle.} -%%%%%%%%%%%%%%%%%%% Copyright related %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% If for some reason you don't want a warning when you omit \Acceptor +\NewDocumentCommand\SuppressAcceptorError{} + { + \msg_redirect_name:nnn { \ClassName } { no_acceptor } { none } + } -\ExplSyntaxOn -\newif\ifmit@cclicense\mit@cclicensefalse -\NewDocumentCommand\CClicense{m m}{% - \def\CClicensetext{\hrefurl{#2}{\ignorespaces#1}}% #1 - text, #2 - url - \def\CCname{#1}% - \def\CCurl{#2}% only for backward compatibility - \mit@cclicensetrue - \cs_if_exist:NT \pdfmeta_xmp_add:n {% - \pdfmeta_xmp_add:n {#2} - } +%%%%%%%%%% End Signature Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%%% Copyright Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Directly add the xmp property that shows work is copyrighted. See l3pdfmeta.pdf. +% This is not automatic with \DocumentMetadata. "True" must be capitalized. +% +\cs_if_exist:NTF \pdfmeta_xmp_add:n {\pdfmeta_xmp_add:n{True}}{} + +\tl_new:N \g_copyright_ccname_tl +\tl_new:N \g_copyright_cclicensetext_tl +\tl_new:N \g_copyright_copyrightlicencse_tl +\tl_new:N \g_copyright_pdfrightstext_tl +\tl_new:N \g__copyright_crwords_tl_ +\tl_new:N \g__copyright_mitpermissionlast_tl + +\tl_new:N \g_copyright_mitpermission_tl +\tl_gset:Nn \g__copyright_mitpermissionlast_tl {to\ MIT\ a\ nonexclusive,\ worldwide,\ irrevocable,\ royalty-free\ license\ to\ exercise\ any\ and\ all\ rights\ under\ copyright,\ including\ to\ reproduce,\ preserve,\ distribute\ and\ publicly\ display\ copies\ of\ the\ thesis,\ or\ release\ the\ thesis\ under\ an\ open-access\ license.} + +\bool_new:N \g__cclicense_tf_bool +\bool_gset_false:N \g__cclicense_tf_bool + +\NewDocumentCommand\CClicense{mm}{ + \__copyright_licensedata:nn {#1}{#2} +% \def\CCurl{ \tl_trim_spaces:n {#2} }% for backward compatibility with v1.05, if necessary } -\ExplSyntaxOff +\cs_new_protected:Nn \__copyright_licensedata:nn + { + \tl_gset:Nf \g_copyright_cclicensetext_tl {\hrefurl{ \tl_trim_spaces:n {#2} }{ \tl_trim_spaces:n {#1} } }% #1 - text, #2 - url + \tl_gset:Nx \g_copyright_ccname_tl { \tl_trim_spaces:n {#1} } + \bool_gset_true:N \g__cclicense_tf_bool + \cs_if_exist:NT \pdfmeta_xmp_add:n { + \pdfmeta_xmp_add:n {#2} + } + \msg_note:nnx {\ClassName} {cclicense} { \text_expand:n {\g_copyright_ccname_tl} } + } +\msg_new:nnn {\ClassName} {cclicense} { Using\ Creative\ Commons\ License\ #1.} -%%%%%%%%%%%%%%%%%%% Create titlepage %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% End Copyright Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\def\MIT{MASSACHUSETTS INSTITUTE OF TECHNOLOGY} -\RenewDocumentCommand\maketitle{s}{% +%%%%%%%%%% Title page Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\RenewDocumentCommand{\title}{m} + { + \__mitthesis_title:n { #1 } + \hypersetup{ + pdftitle={\g_mitthesis_title_tl}, + } + } % - \ifdefined\@DegreeMonth\else\ClassError{\ClassName}{Missing degree date!}{% - You must issue the \DegreeDate{month}{year} command between \begin{document} and \maketitle}% - \fi +\tl_new:N \g_mitthesis_title_tl % - \ifmit@cclicense - \def\CopyrightLicense{This work is licensed under a \mbox{\CClicensetext} license.\par\MITpermission}% add mbox 2023/06/23 - \typeout{^^JUsing Creative Commons License \CCname^^J} - \def\PDFRightsText{This work is licensed under a \CCname\ license. \MITpermission}% for use in metadata - \else - \def\CopyrightLicense{All rights reserved.\par\MITpermission} - \def\PDFRightsText{All rights reserved. \MITpermission}% for use in metadata - \fi - \ifnum\value{authorcnt}>1 - \def\CRWords{The authors hereby grant}\else\def\CRWords{The author hereby grants} - \fi - \def\MITpermissionLast{to MIT a nonexclusive, worldwide, irrevocable, royalty-free license to exercise any and all rights under copyright, including to reproduce, preserve, distribute and publicly display copies of the thesis, or release the thesis under an open-access license.}% - \IfBooleanTF{#1}{\def\MITpermission{\relax}}{\def\MITpermission{\CRWords\space\MITpermissionLast}}% +\cs_new_protected:Nn \__mitthesis_title:n + { + \tl_gset:Nn \g_mitthesis_title_tl { \tl_trim_spaces:n {#1} } + } + +\tl_new:N \g_titlepage_institution_name_tl +\tl_gset:Nn \g_titlepage_institution_name_tl {Massachusetts\ Institute\ of\ Technology} +\cs_new:Npn \Institution #1 { \tl_gset:Nn \g_titlepage_institution_name_tl {\tl_trim_spaces:n #1} } + + +\RenewDocumentCommand\maketitle{s}{% + \cs_if_exist:NTF \DegreeMonth { \scan_stop: } { \msg_error:nn {\ClassName} {no_degree_date} }% msg defined in degree-date section +% + \bool_if:NTF \g__cclicense_tf_bool { + \tl_gset:Nn \g_copyright_copyrightlicencse_tl + {This\ work\ is\ licensed\ under\ a\ \mbox{\g_copyright_cclicensetext_tl}\ license.\par\g_copyright_mitpermission_tl} + \tl_gset:Nn \g_copyright_pdfrightstext_tl + {This\ work\ is\ licensed\ under\ a\ \g_copyright_ccname_tl\ license.\ \g_copyright_mitpermission_tl} + }{ + \tl_gset:Nn \g_copyright_copyrightlicencse_tl + {All\ rights\ reserved. \par\g_copyright_mitpermission_tl} + \tl_gset:Nn \g_copyright_pdfrightstext_tl + {All\ rights\ reserved.\ \g_copyright_mitpermission_tl} + } + \int_compare:nNnTF {\g_author_authorcnt_int} > {1} + { + \tl_gset:Nn \g__copyright_crwords_tl_ {The\ authors\ hereby\ grant} + } + { + \tl_gset:Nn \g__copyright_crwords_tl_ {The\ author\ hereby\ grants} + } + \IfBooleanTF{#1}{% + \tl_gset:Nn \g_copyright_mitpermission_tl {\scan_stop:} + }{ + \tl_gset:Nn \g_copyright_mitpermission_tl {\g__copyright_crwords_tl_\ \g__copyright_mitpermissionlast_tl} + } % \clearpage \thispagestyle{empty}% \phantomsection\addcontentsline{toc}{chapter}{\protect\textbf{Title page}}% - {\centering\vbox to \vsize{% vbox to prevent signature block from breaking across page. Remove if necessary. - \setlength{\parskip}{0.5\baselineskip plus 2pt minus 2pt}\setlength{\parindent}{0pt}% - {\Large\textbf{\@title}\par}% - \@AuthorBlock - \par - \@DegreeBlock - at the\par - \MIT\par - \@DegreeMonth\space\@DegreeYear - \MonthCheck{\@@DegreeMonth}{% - \ClassError{\ClassName}{Acceptable months for the degree date are February, May, June, and September}{Change % - the month of your degree date to one of February, May, June, or September.}% - }% - \par - \copyright\space\@DegreeYear\space\@CopyrightAuthor. \CopyrightLicense - \par - \vskip\baselineskip - % - \@SetSignatureBlock - \vfill - }}% - \newpage + {\centering \vbox_to_ht:nn { \vsize }% to prevent signature block from breaking across page + { + \setlength{\parskip}{0.5\baselineskip plus 2pt minus 2pt}\setlength{\parindent}{0pt}% + {\Large\textbf{\g_mitthesis_title_tl}\par} + \__author_block: + \par + \__degree_block: + at\ the\par + \text_uppercase:n { \g_titlepage_institution_name_tl }\par + \DegreeMonth\ \DegreeYear + \par + \copyright\space\DegreeYear\space\CopyrightAuthor\@.\c_space_token \g_copyright_copyrightlicencse_tl % In case name ends with III, IV, V,... + \par + \skip_vertical:n {\baselineskip} + % + \__signature_block: + \vfill % to avoid overstretched glue + } + }% + \hypersetup{ + pdfcopyright={Copyright\ ©\ \DegreeYear\ by\ \CopyrightAuthor.\ \g_copyright_pdfrightstext_tl}, + pdfauthor={\g__author_pdfca_tl}, + pdfcaptionwriter = {\g__author_pdfca_tl}, + } + \cleardoublepage } -%%%%%%%%%%%%%%%%%%% Create abstract page %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% End title page module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%%% Abstract page Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\RenewDocumentEnvironment{abstract}{+b}{% +% to change abstract name, follow either of these approaches in your preamble: +% \RenewExpandableDocumentCommand\abstractname{}{Summary} +% \renewcommand\abstractname{Summary} + +\RenewDocumentEnvironment{abstract}{+b}{ \newpage - \phantomsection\addcontentsline{toc}{chapter}{\protect\textbf{Abstract}}% + \phantomsection\addcontentsline{toc}{chapter}{\protect\textbf{\abstractname}} \begin{center} - {\large{\textbf{\@title}}\par} + {\large{\textbf{\g_mitthesis_title_tl}}\par} \setlength{\parskip}{0.5\baselineskip plus 2pt minus 2pt} - \@AbstractAuthorBlock + \__author_abstractblock: \par - \@AbstractDegreeBlock + \__degree_abstractblock: \end{center} - \vskip\baselineskip - \textbf{ABSTRACT}\par\vskip0.5em - \ignorespaces#1\ignorespaces - \ifblank{#1}{\typeout{Missing abstract!} MISSING ABSTRACT!}{\relax} -}{% - \@SetAbstractSupervisorBlock - \newpage - \ignorespacesafterend + \skip_vertical:n {\baselineskip} + \textbf{ \text_uppercase:n {\abstractname} }\par + \skip_vertical:n { 0.5em } + \tl_trim_spaces:n {#1} + \tl_if_blank:nT {#1} { MISSING\ ABSTRACT! \msg_error:nn { \ClassName } { missing_abstract } } +}{ + \__supervisor_abstractblock: + \cleardoublepage } +\msg_new:nnnn {\ClassName} { missing_abstract } {Missing\ Abstract!! } { No\ file\ was\ input\ for\ the\ abstract.\ You\ need\ to\ do\ \string\input{abstract.tex}.} -%%%%%%% A nomenclature environment, if needed %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% End abstract page Module %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%\debug_off:n {all} +\ExplSyntaxOff + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%% End title and abstract page codes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%%% A nomenclature environment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \providecommand{\nomname}{Nomenclature} \newlength\nomenwidth \newlength\savitemsep -\makeatletter +% nomenclature entries \NewDocumentCommand\entry{m m}{% - \ifblank{#2}{% - \ClassWarning{\ClassName}{The command \protect\entry requires two arguments. To obtain a subheading, use \protect\EntryHeading} - \itemsep3\p@ plus 1\p@ minus 1\p@% - \goodbreak\item[\itshape#1\hfill]\setlength\itemsep\savitemsep\@itempenalty=1000% - }{% - \item[#1\hfill]#2% - \@itempenalty=-\@lowpenalty% - }% + \item[#1\hfill]#2% + \@itempenalty=-\@lowpenalty } -% A separate command command for nomenclature subheadings +% nomenclature subheadings \NewDocumentCommand\EntryHeading{m}{% - \itemsep3\p@ plus 1\p@ minus 1\p@% - \goodbreak\item[\itshape#1\hfill]\setlength\itemsep\savitemsep\@itempenalty=1000% + \itemsep3\p@ plus 1\p@ minus 1\p@ + \goodbreak\item[\itshape#1\hfill]\setlength\itemsep\savitemsep\@itempenalty=1000 } -\makeatother % % Increase first optional argument to a dimension > 2em if wide entries cause undesired misalignment of columns. % Second optional argument can be used to rename the environment, e.g., to List of Symbols. +% Third optional argument selects section-level or chapter-level style for the nomenclature list. \NewDocumentEnvironment{nomenclature}{O{2em} O{\nomname} O{section}}{% \setlength\columnsep{2em} \setlength{\nomenwidth}{#1} @@ -738,7 +960,7 @@ }% }{\end{list}\ignorespacesafterend} - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endinput diff --git a/macros/xetex/latex/xepersian/README b/macros/xetex/latex/xepersian/README index 27b2191931..ea299d12fd 100644 --- a/macros/xetex/latex/xepersian/README +++ b/macros/xetex/latex/xepersian/README @@ -1,6 +1,6 @@ ____________________ The XePersian package -v24.9 +v25.0 The xepersian package provides a convenient interface for typesetting Persian and English texts in LaTeX, using XeTeX @@ -25,7 +25,7 @@ The announcements for the new releases of the package will also appear in the Discussions space under the Announcements category. -Current version release date: 2023/08/27 +Current version release date: 2023/08/30 ___________________________________________ Vafa Khalighi diff --git a/macros/xetex/latex/xepersian/xepersian-doc-intro.ltx b/macros/xetex/latex/xepersian/xepersian-doc-intro.ltx index 773e60af28..7ae150bda6 100644 --- a/macros/xetex/latex/xepersian/xepersian-doc-intro.ltx +++ b/macros/xetex/latex/xepersian/xepersian-doc-intro.ltx @@ -25,7 +25,7 @@ If you use \textsf{\XePersian} package to write any input \TeX\ document, and th * Copyright (c) 2008--2023 Vafa Khalighi * Copyright (c) 2018--2020 bidi-tex GitHub Organization * -* v24.9 (Release Women, Life, and Freedom), 2023/08/27 +* v25.0 (Release Women, Life, and Freedom), 2023/08/30 * * License: LaTeX Project Public License, version * 1.3c or higher (your choice) diff --git a/macros/xetex/latex/xepersian/xepersian-doc-title.ltx b/macros/xetex/latex/xepersian/xepersian-doc-title.ltx index 29a6ed51d9..36b5189db9 100644 --- a/macros/xetex/latex/xepersian/xepersian-doc-title.ltx +++ b/macros/xetex/latex/xepersian/xepersian-doc-title.ltx @@ -3,7 +3,7 @@ \begin{document} \title{\textcolor{blue!65!black}{\Huge The \textsf{\XePersian} \textit{Package}}\\ \LARGE Persian for \LaTeXe, using {\XeTeX} engine\\[5pt] -\large User documentation for \textcolor{blue!65!black}{version 24.9}} +\large User documentation for \textcolor{blue!65!black}{version 25.0}} \author{Vafa Khalighi\thanks{Thanks to the bidi-tex GitHub organization consisted of David Carlisle and other members of the {\LaTeX} team to maintain the package in the period 2018--2020.}} \setcounter{page}{0} \thispagestyle{empty} @@ -13,7 +13,7 @@ \textcolor{blue!65!black}{\Huge The \textsf{\XePersian} \textit{Package}} \Large -User documentation for \textcolor{blue!65!black}{version 24.9}} +User documentation for \textcolor{blue!65!black}{version 25.0}} \vskip 0pt plus 3fill \textit{\large to my Master, \textbf{Ferdowsi The Great}} diff --git a/macros/xetex/latex/xepersian/xepersian-doc.ltx b/macros/xetex/latex/xepersian/xepersian-doc.ltx index 1992bb189e..d959cfb800 100644 --- a/macros/xetex/latex/xepersian/xepersian-doc.ltx +++ b/macros/xetex/latex/xepersian/xepersian-doc.ltx @@ -1,7 +1,7 @@ \documentclass{ltxdoc} \input{xepersian-doc-preamble.ltx} \hypersetup{% - pdftitle={User documentation for version 24.9 of the XePersian + pdftitle={User documentation for version 25.0 of the XePersian package}% } \begin{document} diff --git a/macros/xetex/latex/xepersian/xepersian-doc.pdf b/macros/xetex/latex/xepersian/xepersian-doc.pdf index 710bff0bc8..afdd5e3184 100644 Binary files a/macros/xetex/latex/xepersian/xepersian-doc.pdf and b/macros/xetex/latex/xepersian/xepersian-doc.pdf differ diff --git a/macros/xetex/latex/xepersian/xepersian.dtx b/macros/xetex/latex/xepersian/xepersian.dtx index cf774721f0..a2887a1261 100644 --- a/macros/xetex/latex/xepersian/xepersian.dtx +++ b/macros/xetex/latex/xepersian/xepersian.dtx @@ -5,7 +5,7 @@ %<*readme> ____________________ The XePersian package -v24.9 +v25.0 The xepersian package provides a convenient interface for typesetting Persian and English texts in LaTeX, using XeTeX @@ -31,7 +31,7 @@ also appear in the Discussions space under the Announcements category. -Current version release date: 2023/08/27 +Current version release date: 2023/08/30 ___________________________________________ Vafa Khalighi @@ -168,7 +168,7 @@ by Vafa Khalighi. \documentclass{ltxdoc} \input{xepersian-doc-preamble.ltx} \hypersetup{% - pdftitle={Source documentation for version 24.9 of the XePersian + pdftitle={Source documentation for version 25.0 of the XePersian package}% } \EnableCrossrefs @@ -187,7 +187,7 @@ by Vafa Khalighi. % \GetFileInfo{\jobname.dtx} % \title{\textcolor{blue!65!black}{\Huge The \textsf{\XePersian} \textit{Package}}\\ %\LARGE Persian for \LaTeXe, using {\XeTeX} engine\\[5pt] -%\large Source documentation for \textcolor{blue!65!black}{version 24.9}} +%\large Source documentation for \textcolor{blue!65!black}{version 25.0}} % \author{Vafa Khalighi\thanks{Thanks to the bidi-tex GitHub organization consisted of David Carlisle and other members of the {\LaTeX} team to maintain the package in the period 2018--2020.}} %\setcounter{page}{0} %\thispagestyle{empty} @@ -197,7 +197,7 @@ by Vafa Khalighi. %\textcolor{blue!65!black}{\Huge The \textsf{\XePersian} \textit{Package}} % %\Large -%Source documentation for \textcolor{blue!65!black}{version 24.9}} +%Source documentation for \textcolor{blue!65!black}{version 25.0}} % %\vskip 0pt plus 3fill %\textit{\large to my Master, \textbf{Ferdowsi The Great}} @@ -245,7 +245,7 @@ by Vafa Khalighi. %\iffalse %<*table> %\fi -%% \CheckSum{11274} +%% \CheckSum{11192} %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z @@ -3592,8 +3592,8 @@ U+003E U+003E <> U+00BB ; >> -> RIGHT POINTING GUILLEMET % \section{File \texttt{xepersian.sty}} % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\def\xepersian@version{24.9} -\def\xepersiandate{2023/08/27} +\def\xepersian@version{25.0} +\def\xepersiandate{2023/08/30} \def\xepersian@releasename{Women, Life, and Freedom} \def\xepersian@persian@@releasename{زن، زندگی، و آزادی} \newcommand*{\xepersianreleasename}{\if@RTL\xepersian@persian@@releasename\else\xepersian@releasename\fi} @@ -4445,7 +4445,7 @@ Persian typesetting in XeLaTeX] \newcommand*{\@xepersian@pdfcustomproperties}{% This is the xepersian package, Version \xepersian@version\space (Release \xepersian@releasename), - Released August 27, 2023. + Released August 30, 2023. } \newcommand\twocolumnstableofcontents{% @@ -4997,126 +4997,6 @@ number is 999,999,999.}% \def\xepersian@@latin@baselineskip@scale{#1}% } -\newcommand*{\xepersian@setmainpersianfont}[1]{% - \settextfont[% - Path,% - UprightFont=*-Regular,% - BoldFont=*-Bold,% - BoldItalicFont=*-BoldItalic,% - ItalicFont= *-Italic,% - SlantedFont=*-Italic,% - BoldSlantedFont=*-BoldItalic,% - Numbers=Proportional% - ]{#1}% -} - -\define@choicekey{xepersian.sty}{mainpersianfont}[\xepersian@tempa\xepersian@tempb]{Default,Parsian,Naskh,Sans,Mono,Classic}[Default]{% - \ifcase\xepersian@tempb\relax - \xepersian@setmainpersianfont{ParsianTeX}% - \or - \xepersian@setmainpersianfont{Parsian}% - \or - \xepersian@setmainpersianfont{ParsianNaskh}% - \or - \xepersian@setmainpersianfont{ParsianSans}% - \or - \xepersian@setmainpersianfont{ParsianMono}% - \or - \xepersian@setmainpersianfont{ParsianTeXClassic}% - \fi} - -\define@choicekey{xepersian.sty}{persiansansfont}[\xepersian@tempa\xepersian@tempb]{on,off}[on]{% - \ifcase\xepersian@tempb\relax - \setpersiansansfont[% - Path,% - UprightFont=*-Regular,% - BoldFont=*-Bold,% - BoldItalicFont=*-BoldItalic,% - ItalicFont= *-Italic,% - SlantedFont=*-Italic,% - BoldSlantedFont=*-BoldItalic,% - Numbers=Proportional% - ]{ParsianSans}% - \or - \relax - \fi} - -\define@choicekey{xepersian.sty}{persianmonofont}[\xepersian@tempa\xepersian@tempb]{on,off}[on]{% - \ifcase\xepersian@tempb\relax - \setpersianmonofont[% - Path,% - UprightFont=*-Regular,% - BoldFont=*-Bold,% - BoldItalicFont=*-BoldItalic,% - ItalicFont= *-Italic,% - SlantedFont=*-Italic,% - BoldSlantedFont=*-BoldItalic,% - Numbers=Proportional% - ]{ParsianMono}% - \or - \relax - \fi} - -\newcommand*{\xepersian@setmathdigitfont}[1]{% - \setmathdigitfont[% - Path,% - UprightFont=*-Regular,% - BoldFont=*-Bold,% - BoldItalicFont=*-BoldItalic,% - ItalicFont= *-Italic,% - SlantedFont=*-Italic,% - BoldSlantedFont=*-BoldItalic,% - Numbers=Proportional% - ]{#1}% -} - -\define@choicekey{xepersian.sty}{mathdigitfont}[\xepersian@tempa\xepersian@tempb]{Default,Parsian,Naskh,Sans,Mono,Classic}[Default]{% - \ifcase\xepersian@tempb\relax - \xepersian@setmathdigitfont{ParsianTeX}% - \or - \xepersian@setmathdigitfont{Parsian}% - \or - \xepersian@setmathdigitfont{ParsianNaskh}% - \or - \xepersian@setmathdigitfont{ParsianSans}% - \or - \xepersian@setmathdigitfont{ParsianMono}% - \or - \xepersian@setmathdigitfont{ParsianTeXClassic}% - \fi} - -\define@choicekey{xepersian.sty}{mathsansdigitfont}[\xepersian@tempa\xepersian@tempb]{on,off}[on]{% - \ifcase\xepersian@tempb\relax - \setmathsfdigitfont[% - Path,% - UprightFont=*-Regular,% - BoldFont=*-Bold,% - BoldItalicFont=*-BoldItalic,% - ItalicFont= *-Italic,% - SlantedFont=*-Italic,% - BoldSlantedFont=*-BoldItalic,% - Numbers=Proportional% - ]{ParsianSans}% - \or - \relax - \fi} - -\define@choicekey{xepersian.sty}{mathmonodigitfont}[\xepersian@tempa\xepersian@tempb]{on,off}[on]{% - \ifcase\xepersian@tempb\relax - \setmathttdigitfont[% - Path,% - UprightFont=*-Regular,% - BoldFont=*-Bold,% - BoldItalicFont=*-BoldItalic,% - ItalicFont= *-Italic,% - SlantedFont=*-Italic,% - BoldSlantedFont=*-BoldItalic,% - Numbers=Proportional% - ]{ParsianMono}% - \or - \relax - \fi} - \define@choicekey{xepersian.sty}{logo}[\xepersian@tempa\xepersian@tempb]{on,off}[on]{% \ifcase\xepersian@tempb\relax \AtBeginDocument{\@bidi@inslogo@}% @@ -5182,9 +5062,7 @@ number is 999,999,999.}% latinfontsizescale=\@ne, mathfontsizescale=\@ne, baselineskipscale=\@ne, - latinbaselineskipscale=\@ne, - mainpersianfont=Default, - mathdigitfont=Default + latinbaselineskipscale=\@ne } \ProcessOptionsX diff --git a/macros/xetex/latex/xepersian/xepersian.pdf b/macros/xetex/latex/xepersian/xepersian.pdf index 6625ec7a77..52acb6ebc3 100644 Binary files a/macros/xetex/latex/xepersian/xepersian.pdf and b/macros/xetex/latex/xepersian/xepersian.pdf differ diff --git a/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl b/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl index 6c2054fcf7..4340b56766 100644 --- a/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl +++ b/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl @@ -48,6 +48,7 @@ $mirrors = { }, 'Korea' => { 'http://ftp.ktug.org/tex-archive/' => 1, + 'https://cran.asia/tex/' => 1, 'https://ftp.kaist.ac.kr/pub/tex-archive/' => 1, 'https://lab.uklee.pe.kr/tex-archive/' => 1, 'https://mirror.kakao.com/CTAN/' => 1, @@ -176,7 +177,6 @@ $mirrors = { 'https://ctan.mirror.globo.tech/' => 1, 'https://ctan.mirror.rafal.ca/' => 1, 'https://mirror.csclub.uwaterloo.ca/CTAN/' => 1, - 'https://mirror.its.dal.ca/ctan/' => 1, 'https://mirror.quantum5.ca/CTAN/' => 1, 'https://muug.ca/mirror/ctan/' => 1, }, diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb b/systems/texlive/tlnet/tlpkg/texlive.tlpdb index 7a94e67789..1360b182ca 100644 --- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb +++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb @@ -26,11 +26,11 @@ depend container_split_src_files/1 depend frozen/0 depend minrelease/2016 depend release/2023 -depend revision/68111 +depend revision/68118 name 00texlive.image category TLCore -revision 68099 +revision 68118 shortdesc TeX Live files only in the source repository longdesc The files here are not copied by the installer and containers longdesc are not built for them; they exist only in the source @@ -2912,6 +2912,7 @@ runfiles size=13070 tlpkg/tlpsrc/method.tlpsrc tlpkg/tlpsrc/metre.tlpsrc tlpkg/tlpsrc/metrix.tlpsrc + tlpkg/tlpsrc/metsymb.tlpsrc tlpkg/tlpsrc/mex.tlpsrc tlpkg/tlpsrc/mf2pt1.tlpsrc tlpkg/tlpsrc/mfirstuc.tlpsrc @@ -4785,7 +4786,7 @@ depend setting_available_architectures:aarch64-linux amd64-freebsd amd64-netbsd name 00texlive.installer category TLCore -revision 68102 +revision 68113 shortdesc TeX Live standalone installer package longdesc This package defines the files to go into the installer longdesc archives (install-tl-unx.tar.gz, install-tl.zip) built by the @@ -69265,7 +69266,7 @@ containerchecksum 41548fba89276395649f7c96f36d9f8ae2979a9bfe045cb3dedad24cb2f991 name collection-fontsextra category Collection -revision 67659 +revision 68118 shortdesc Additional fonts relocated 1 depend aboensis @@ -69503,6 +69504,7 @@ depend mathdesign depend mdputu depend mdsymbol depend merriweather +depend metsymb depend miama depend mintspirit depend missaali @@ -69620,7 +69622,7 @@ depend yfonts-t1 depend yinit-otf depend zlmtt containersize 2000 -containerchecksum 5ff156ec0592276a52b1485aa94918dfdc30817f59f1df8ae25c676dadc7b9605de5ef46a442079882888981519dffc3d9715020a445a4f8a461df1a60332090 +containerchecksum 74de615e8a28381bb15b8280ac3ef124678fbfa58c1cf865a2b565adac194538ead1eb9a4c9b0306c56b3d2941ee4c6fc8cd2823c0db0407ffc318af9eb59567 name collection-fontsrecommended category Collection @@ -165337,16 +165339,16 @@ catalogue-version 0.7 name jwjournal category Package -revision 68105 +revision 68116 shortdesc A personal class for writing journals relocated 1 longdesc This LaTeX document class enables the user to turn simple pure longdesc text entries into a colorful and nicely formatted journal. depend einfart -containersize 3164 -containerchecksum 25b21b1287f9dd18838ceb671f948bfa86864360d8fc80cac483c8779e26a33a3f03e9e2e62c066fd946acd9918e345a9d93e350c07b236ddce393acce3deb93 -doccontainersize 123856 -doccontainerchecksum f41baa98fdeaf20bd5301aebfd79334ee2aea4db2b31ddb17d097e7d2b630b247f85e07192da3db425b4eed04f93954c7e8d5e83b67451bde4eeb80670d16fbc +containersize 3380 +containerchecksum e83a9658ca640c9392197f335ab30acec0b387c2a2c44bc715822eabe4756b236b4a2fdf644ffece116a606f22231c62261ef604218203d53971f7a0c79259ce +doccontainersize 123904 +doccontainerchecksum 9f6ef6704ce323ac1c7bb6a2271a8706eb7bec239c577491bb57a4caacb8182ccc81aa1d44eda80fc0e7a210ddb49bd6510df8bd692c38aee06842174decfaed docfiles size=48 RELOC/doc/latex/jwjournal/DEPENDS.txt RELOC/doc/latex/jwjournal/LICENSE @@ -165357,7 +165359,7 @@ docfiles size=48 RELOC/doc/latex/jwjournal/jwjournal-demo-en.tex RELOC/doc/latex/jwjournal/jwjournal-demo-fr.pdf details="Example of use (French)" RELOC/doc/latex/jwjournal/jwjournal-demo-fr.tex -runfiles size=3 +runfiles size=4 RELOC/tex/latex/jwjournal/jwjournal.cls catalogue-contact-repository https://github.com/Jinwen-XU/jwjournal catalogue-ctan /macros/latex/contrib/jwjournal @@ -207868,6 +207870,62 @@ catalogue-license lppl1.3c catalogue-topics latin verse expl3 catalogue-version 1.5 +name metsymb +category Package +revision 68118 +shortdesc The package provides dedicated TeX commands to generate (vectorial) meteorological symbols +relocated 1 +longdesc The metsymb package introduces commands to generate official +longdesc meteorological symbols with vectorial quality. These include: +longdesc oktas (\zerookta, \oneokta, \twooktas, \ldots), cloud genera +longdesc (\cirrus, \cirrostratus, \nimbostratus, ...), and C_L / C_M / +longdesc C_H cloud codes (\clIII, \cmVI, \chIX, ...). Individual symbols +longdesc are designed using TikZ. They are then bundled into a dedicated +longdesc font with FontForge, and eventually tied to dedicted LaTeX +longdesc commands. The metsymb OpenType font is a side-product that can +longdesc be used on its own. This package essentially introduces a new +longdesc font in which each symbol is assigned to a glyph, which can +longdesc then be called individually from LaTeX documents via dedicated +longdesc commands. +containersize 16728 +containerchecksum 4577c5b1d2807e3a4d044b0c4a762071fad8435c7e31934f2208807ecc15ee6378e610bfaddad015edfcc849e533c6a20c37886b5b7da35337b02e5e6acb765c +doccontainersize 410132 +doccontainerchecksum 25571673430d1bfd037d09b3ed05540fdd2bab4a5e2dfa1d2967be3be5594d5a737c96bfaebfd81f9f71b8b6735f91a14fe89f9fed571d139f3418ea10271b5d +docfiles size=115 + RELOC/doc/fonts/metsymb/AUTHORS + RELOC/doc/fonts/metsymb/CHANGELOG + RELOC/doc/fonts/metsymb/CODE_OF_CONDUCT.md + RELOC/doc/fonts/metsymb/CONTRIBUTING.md + RELOC/doc/fonts/metsymb/LICENSE + RELOC/doc/fonts/metsymb/README.md details="Readme" + RELOC/doc/fonts/metsymb/metsymb.pdf details="Package documentation" + RELOC/doc/fonts/metsymb/metsymb_mwe.mplstyle + RELOC/doc/fonts/metsymb/metsymb_mwe.pdf + RELOC/doc/fonts/metsymb/metsymb_mwe.py + RELOC/doc/fonts/metsymb/testfont.pdf + RELOC/doc/fonts/metsymb/umetsymb.fd +srccontainersize 15712 +srccontainerchecksum 49bf097b10a9fac1840cb8e96f5110e5522c25ced249a806b0fb6108372fdadcce3e4642776b1559e851597b9be9e8d3110b0d50ad14322ffd95ab2b04c8c52b +srcfiles size=21 + RELOC/source/fonts/metsymb/metsymb.dtx + RELOC/source/fonts/metsymb/metsymb.ins + RELOC/source/fonts/metsymb/metsymb.sfd +runfiles size=12 + RELOC/fonts/afm/public/metsymb/metsymb.afm + RELOC/fonts/enc/dvips/metsymb/metsymb.enc + RELOC/fonts/map/dvips/metsymb/metsymb.map + RELOC/fonts/opentype/public/metsymb/metsymb.otf + RELOC/fonts/tfm/public/metsymb/metsymb.tfm + RELOC/fonts/type1/public/metsymb/metsymb.pfb + RELOC/tex/latex/metsymb/metsymb.sty +catalogue-contact-bugs https://github.com/MeteoSwiss/metsymb/issues +catalogue-contact-repository https://github.com/MeteoSwiss/metsymb +catalogue-contact-support https://github.com/MeteoSwiss/metsymb/discussions +catalogue-ctan /fonts/metsymb +catalogue-license bsd3 +catalogue-topics font font-symbol +catalogue-version 1.2.0 + name mex category Package revision 58661 @@ -314718,7 +314776,7 @@ docfiles size=376 name texlive-scripts category TLCore -revision 68102 +revision 68113 shortdesc TeX Live infrastructure programs longdesc Includes install-tl, tl-portable, rungs, etc.; not needed for longdesc tlmgr to run but still ours. Not included in tlcritical. @@ -314727,9 +314785,9 @@ depend texlive.infra execute addMap mathpple.map postaction shortcut type=menu name="TeX Live command-line" cmd=TEXDIR/tlpkg/installer/tl-cmd.bat containersize 114120 -containerchecksum 31d523960ec92a5b4c66fc1b1f04c36f25d0b373c651e6239fbcaedf39b30e04dada9078eef74883e4f7751a74b3e6eff92204cc35303178e37da4c0b5ed40a0 -doccontainersize 428804 -doccontainerchecksum a058864317a292d735f5fa26ffdeb08081cea57f92431d556374c0990b65259b0c34175276d8cbd6a1c87b106359e2d59301760b164e29c9738cbcb0ea4bfffc +containerchecksum 9706c9c0abc8092c4220368475447e3ca7cd68188383e0440eeda564e7cbfbcb0da79a2a5bc72deb16296ee37074c87696a862d6f33fb5763cd6b4108dcf6578 +doccontainersize 428848 +doccontainerchecksum 63001568d9c9fa287288c00efdec8eeb6bc5c500604aa5ea6792927da2e0bd5ef1213b58a703a3e8559977b6c392c9d0f9d23673cb287d238153a159e827dfa5 docfiles size=549 doc.html texmf-dist/doc/man/man1/fmtutil-sys.1 @@ -354682,16 +354740,16 @@ catalogue-version 2.0 name xepersian category Package -revision 68076 +revision 68117 shortdesc Persian for LaTeX, using XeTeX relocated 1 longdesc This package provides a convenient interface for typesetting longdesc Persian and English texts in LaTeX, using the XeTeX engine. -containersize 60620 -containerchecksum 588d7f13fcc89fe690c482f2dc6e5bb0ef7398cb19cd19c0758a466251118e9e6524241e484ce724db844b07653d27c7af1af218252f0915f43176955fd5c731 -doccontainersize 1020040 -doccontainerchecksum 979bf5792bd7dfece8a1ef0dca975e3e1c4a1bf7114b8beb283a56f2ec1a8ad1576b36277b0c5cc817f396c86476682a156423130b147552359dcbbff1ec7401 -docfiles size=324 +containersize 60332 +containerchecksum aba7b248b1ed6fc557e51c267d3da21a3f3473cb0b0d997ef7d899b3ec518a099a173a163c53aaa7ff29e13aa2f1dbebb65775af828c85fcb9e4e91476d6e1ca +doccontainersize 1004836 +doccontainerchecksum dc2f7a06a6122baf9f2284412edf4231eba88f6968f86eb06e47a3e3f3cac14f833ccdb8f69e95b17a05cdc9c3244c361e8d581b6ca65a715a82662ae722fd35 +docfiles size=320 RELOC/doc/xelatex/xepersian/README details="Readme" RELOC/doc/xelatex/xepersian/dkun-0.3.py RELOC/doc/xelatex/xepersian/dkun-0.4.py @@ -354710,9 +354768,9 @@ docfiles size=324 RELOC/doc/xelatex/xepersian/xepersian-doc.pdf details="Package user documentation" RELOC/doc/xelatex/xepersian/xepersian-logo.tex RELOC/doc/xelatex/xepersian/xepersian.pdf details="Package source documentation" -srccontainersize 75740 -srccontainerchecksum fec8fc17afeadfa0c69a44c517e39a4a5eacd7d2f7fce7ca375fcb1d8d4cab61d1ea5334a270cd380d598229aebea193bdac27fa042671f239c520acd11805b0 -srcfiles size=121 +srccontainersize 75492 +srccontainerchecksum 6cc50aa2d511d744499620b010066916913aedb63ed871f93ab8cdb45380da206dee76c4d8ceaf01be5df971e0437ffd8b469a3ae793810043515a966fdb40a7 +srcfiles size=120 RELOC/source/xelatex/xepersian/xepersian-doc-basics.ltx RELOC/source/xelatex/xepersian/xepersian-doc-boolean.ltx RELOC/source/xelatex/xepersian/xepersian-doc-captions.ltx @@ -354724,7 +354782,7 @@ srcfiles size=121 RELOC/source/xelatex/xepersian/xepersian-doc.ltx RELOC/source/xelatex/xepersian/xepersian.dtx RELOC/source/xelatex/xepersian/xepersian.ins -runfiles size=117 +runfiles size=116 RELOC/fonts/misc/xetex/fontmapping/xepersian/persian-tex-text-nonumbers.map RELOC/fonts/misc/xetex/fontmapping/xepersian/persian-tex-text-nonumbers.tec RELOC/fonts/misc/xetex/fontmapping/xepersian/persian-tex-text.map @@ -354800,7 +354858,7 @@ catalogue-contact-support https://github.com/kvafa/xepersian/discussions catalogue-ctan /macros/xetex/latex/xepersian catalogue-license lppl1.3c catalogue-topics persian xetex class -catalogue-version 24.9 +catalogue-version 25.0 name xepersian-hm category Package diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 index fdf927381d..0152f768d7 100644 --- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 +++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 @@ -1 +1 @@ -fab8de546ce9c7c3831d6b75d495f8f4 texlive.tlpdb +2e6fe359adbc3145e4e72b323ff90cac texlive.tlpdb diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 index 776d8d444f..594968ff28 100644 --- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 +++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 @@ -1 +1 @@ -2ac6d4113e2abf5b4349ddf136de5bf6c475edefc5afe30b7a1973046890233f1f495858054635d229cd0a6c0dc5363b26b4b5bed46bb146cf7b1814187c4d07 texlive.tlpdb +5468a937bce5a3230ac38bf775ec0202ec20c1b6ed7b6646cbc16dbc5d72f8fc566aa2e03554e8148d368f7ff089e97e55573d8bc0235b70f62655c50554425a texlive.tlpdb diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc index 378f043bfe..0afba9be1d 100644 --- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc +++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc @@ -1,11 +1,11 @@ -----BEGIN PGP SIGNATURE----- -iQEzBAEBCgAdFiEE2PL4YFeoV+QqiBBqTOGHfhlDjHAFAmTugxQACgkQTOGHfhlD -jHAcOwgAuAChTCWrC7fC9MnNV2MVoFNxkxpy1YYwuGXcTt7ntSIWX0yy0tysnfsy -5T9YMgMjYD1B8XApPiOE4yIVJEyCcLwPwGzixjFnH8FkP2HwmTX5nXmVp3aNEU/L -RntdmkvnfsSWGvfF592xU6TWY2J/vgtU32wHDfoYpdpZuY0VUDTyH3kf9QCqGluz -Bc3+jkLzuVTzh4R0Xk5FmvHCZHrLf0SMScYco3mTHQfaTRDgtidEv31poRJ5mCDc -eqAu9/XTqmhTQAHd+n80ZVhEl/sf1Thk4YsMsfCdx52tBal/R0c8zNgB3t+EyTyp -FINulRe8CTpKiyKelVtNa474FaEiGA== -=48G1 +iQEzBAEBCgAdFiEE2PL4YFeoV+QqiBBqTOGHfhlDjHAFAmTv1IUACgkQTOGHfhlD +jHCbIggAn41nM6JHEX2KqmY3I/iAJ6XXILU1n90Q3gn8IevHDcJqpbdPC6oxnQqr +KxwTvlqlf5SoGSlfCR5M1Lshk4rgkj/npli5dR2KhyZNMDywWedNhd+OBpc3r5+U +u+Up349JauYCxdEwbLq44drZewHMf4bo5ctY42RCD6AOxhtsJNNJb7sJiifp3edK +4ogGhGgCZx8frghchQA3BZCcruNOCILvxrgSIx8K79s6Ud9aX0jMP6r7G2+yJ5+a +A5xMGAhcDrhDBheistIV00jbgKrzETbEZwO+1HeqZA+UxQtvlRxNaQ+8CKFbaLby +rAWAuXfZswWkMyAxX/mOAF4QiHpBzg== +=SaRI -----END PGP SIGNATURE----- diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz index cd00d90b92..0f3fb1c6dc 100644 Binary files a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz and b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz differ diff --git a/timestamp b/timestamp index d3b4162e73..9a2c0b3402 100644 --- a/timestamp +++ b/timestamp @@ -2,4 +2,4 @@ # The source CTAN of this site's material: dante.ctan.org # The year-month-day-hour-minute of this site's material: -2023-08-30-02-02 +2023-08-31-02-02 -- cgit v1.2.3