summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-01-24 03:03:37 +0000
committerNorbert Preining <norbert@preining.info>2021-01-24 03:03:37 +0000
commit9456871cc89612c1f974af157f0ed08b9630c4c6 (patch)
tree776886b7d8b9cbf30f5c5a12f575a879829dd4fe
parentfcf66e0c8c8c0f5d590d5ac4411b13977aef8a30 (diff)
CTAN sync 202101240303
-rw-r--r--FILES.byname533
-rw-r--r--FILES.byname.gzbin2263587 -> 2263735 bytes
-rw-r--r--FILES.last07days887
-rw-r--r--fonts/newcomputermodern/NewCM10-Book.otfbin1187404 -> 1186096 bytes
-rw-r--r--fonts/newcomputermodern/README2
-rw-r--r--graphics/pgf/contrib/penrose/README (renamed from graphics/pgf/contrib/penrose/README.txt)0
-rw-r--r--graphics/pgf/contrib/penrose/penrose.pdfbin552561 -> 557513 bytes
-rw-r--r--graphics/pgf/contrib/penrose/penrose.tex151
-rw-r--r--graphics/pgf/contrib/penrose/penrose_code.dtx1588
-rw-r--r--graphics/pgf/contrib/penrose/penrose_code.pdfbin394873 -> 464179 bytes
-rw-r--r--graphics/pgf/contrib/spath3/README2
-rw-r--r--graphics/pgf/contrib/spath3/calligraphy.pdfbin0 -> 259679 bytes
-rw-r--r--graphics/pgf/contrib/spath3/calligraphy.tex (renamed from graphics/pgf/contrib/spath3/calligraphy_doc.tex)25
-rw-r--r--graphics/pgf/contrib/spath3/calligraphy_doc.pdfbin288184 -> 0 bytes
-rw-r--r--graphics/pgf/contrib/spath3/knots.pdfbin0 -> 333450 bytes
-rw-r--r--graphics/pgf/contrib/spath3/knots.tex (renamed from graphics/pgf/contrib/spath3/knots_doc.tex)44
-rw-r--r--graphics/pgf/contrib/spath3/knots_doc.pdfbin384979 -> 0 bytes
-rw-r--r--graphics/pgf/contrib/spath3/spath3.dtx4228
-rw-r--r--graphics/pgf/contrib/spath3/spath3.pdfbin0 -> 337099 bytes
-rw-r--r--graphics/pgf/contrib/spath3/spath3.tex650
-rw-r--r--graphics/pgf/contrib/spath3/spath3_code.dtx6719
-rw-r--r--graphics/pgf/contrib/spath3/spath3_code.pdfbin439282 -> 547140 bytes
-rw-r--r--macros/latex/contrib/eqexam/README.md5
-rw-r--r--macros/latex/contrib/eqexam/aebrandom.def201
-rw-r--r--macros/latex/contrib/eqexam/doc/eqexam.pdfbin806244 -> 745675 bytes
-rw-r--r--macros/latex/contrib/eqexam/doc/eqexamman.pdfbin624926 -> 671573 bytes
-rw-r--r--macros/latex/contrib/eqexam/doc/eqexamman.tex46
-rw-r--r--macros/latex/contrib/eqexam/eqexam.def428
-rw-r--r--macros/latex/contrib/eqexam/eqexam.dtx65
-rw-r--r--macros/latex/contrib/eqexam/examples/fig1.pdfbin12673 -> 11038 bytes
-rw-r--r--macros/latex/contrib/eqexam/examples/hw.cfg.txt12
-rw-r--r--macros/latex/contrib/eqexam/examples/quiz.cfg.txt7
-rw-r--r--macros/latex/contrib/eqexam/examples/test01.pdfbin0 -> 116251 bytes
-rw-r--r--macros/latex/contrib/eqexam/examples/test01.tex4
-rw-r--r--macros/latex/contrib/eqexam/examples/test02.pdfbin0 -> 216104 bytes
-rw-r--r--macros/latex/contrib/eqexam/examples/test03.pdfbin0 -> 161999 bytes
-rw-r--r--macros/latex/contrib/eqexam/examples/test_matching.pdfbin18253 -> 0 bytes
-rw-r--r--macros/latex/contrib/fnpct/README13
-rw-r--r--macros/latex/contrib/fnpct/fnpct-manual.cls331
-rw-r--r--macros/latex/contrib/fnpct/fnpct-manual.pdfbin0 -> 472808 bytes
-rw-r--r--macros/latex/contrib/fnpct/fnpct-manual.tex615
-rw-r--r--macros/latex/contrib/fnpct/fnpct.sty1883
-rw-r--r--macros/latex/contrib/fnpct/fnpct_en.pdfbin573765 -> 0 bytes
-rw-r--r--macros/latex/contrib/fnpct/fnpct_en.tex1044
-rwxr-xr-xsupport/xml2pmx/MacOS/xml2pmxbin134924 -> 139408 bytes
-rw-r--r--support/xml2pmx/README65
-rw-r--r--support/xml2pmx/doc/Readme.XML2PMX161
-rw-r--r--support/xml2pmx/doc/xml2pmx.116
-rw-r--r--support/xml2pmx/doc/xml2pmx.pdfbin16563 -> 17546 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb72
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.md52
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha5122
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc14
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.xzbin2275392 -> 2274796 bytes
-rw-r--r--systems/win32/miktex/tm/packages/next/pr.ini8
-rw-r--r--systems/win32/miktex/tm/packages/pr.ini8
-rw-r--r--systems/win32/w32tex/ChangeLog24
-rw-r--r--timestamp2
58 files changed, 11687 insertions, 8170 deletions
diff --git a/FILES.byname b/FILES.byname
index bce979ec6b..7ab713b076 100644
--- a/FILES.byname
+++ b/FILES.byname
@@ -5087,7 +5087,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
-2021/01/22 | 219964 | FILES.last07days
+2021/01/23 | 195166 | FILES.last07days
2020/08/14 | 104065 | fonts/academicons/academicons.pdf
2020/08/14 | 17247 | fonts/academicons/academicons.sty
2020/08/14 | 6546 | fonts/academicons/academicons.tex
@@ -81028,7 +81028,7 @@
2021/01/03 | 371584 | fonts/newcomputermodern/NewCM10-BoldItalic.otf
2021/01/03 | 431284 | fonts/newcomputermodern/NewCM10-Bold.otf
2021/01/03 | 1191600 | fonts/newcomputermodern/NewCM10-BookItalic.otf
-2021/01/03 | 1187404 | fonts/newcomputermodern/NewCM10-Book.otf
+2021/01/22 | 1186096 | fonts/newcomputermodern/NewCM10-Book.otf
2021/01/03 | 398744 | fonts/newcomputermodern/NewCM10-Italic.otf
2021/01/03 | 463144 | fonts/newcomputermodern/NewCM10-Regular.otf
2021/01/17 | 2079720 | fonts/newcomputermodern/NewCMMath-Book.otf
@@ -81055,8 +81055,8 @@
2020/06/24 | 244 | fonts/newcomputermodern/NewComputerModernSansBook.fontspec
2020/02/25 | 238 | fonts/newcomputermodern/NewComputerModernSans.fontspec
2020/12/18 | 341 | fonts/newcomputermodern/newcomputermodern.sty
-2021/01/18 | 9788 | fonts/newcomputermodern/README
-2021/01/18 | 8787673 | fonts/newcomputermodern.zip
+2021/01/22 | 9788 | fonts/newcomputermodern/README
+2021/01/23 | 8787669 | fonts/newcomputermodern.zip
2020/06/03 | 5405 | fonts/newpx/afm/NewPXBMI.afm
2019/09/10 | 4864 | fonts/newpx/afm/NewPXBMI_gnu.afm
2020/06/03 | 5651 | fonts/newpx/afm/NewPXMI.afm
@@ -142213,12 +142213,12 @@
2020/07/19 | 78122 | graphics/pgf/contrib/nimsticks/nimsticks.pdf
2020/07/19 | 1890 | graphics/pgf/contrib/nimsticks/README.md
2020/07/19 | 82263 | graphics/pgf/contrib/nimsticks.zip
-2018/07/10 | 88580 | graphics/pgf/contrib/penrose/penrose_code.dtx
-2018/07/10 | 394873 | graphics/pgf/contrib/penrose/penrose_code.pdf
-2018/07/10 | 552561 | graphics/pgf/contrib/penrose/penrose.pdf
-2018/07/10 | 24283 | graphics/pgf/contrib/penrose/penrose.tex
-2018/07/10 | 472 | graphics/pgf/contrib/penrose/README.txt
-2018/07/12 | 960121 | graphics/pgf/contrib/penrose.zip
+2021/01/22 | 98018 | graphics/pgf/contrib/penrose/penrose_code.dtx
+2021/01/22 | 464179 | graphics/pgf/contrib/penrose/penrose_code.pdf
+2021/01/22 | 557513 | graphics/pgf/contrib/penrose/penrose.pdf
+2021/01/22 | 26060 | graphics/pgf/contrib/penrose/penrose.tex
+2021/01/22 | 472 | graphics/pgf/contrib/penrose/README
+2021/01/23 | 1034990 | graphics/pgf/contrib/penrose.zip
2018/08/21 | 34321 | graphics/pgf/contrib/pgf-blur/pgf-blur.dtx
2018/08/21 | 250036 | graphics/pgf/contrib/pgf-blur/pgf-blur.pdf
2018/08/21 | 2254 | graphics/pgf/contrib/pgf-blur/README.md
@@ -142647,14 +142647,16 @@
2016/12/23 | 3599 | graphics/pgf/contrib/smartdiagram/smartdiagram.ins
2016/12/23 | 267814 | graphics/pgf/contrib/smartdiagram/smartdiagram.pdf
2016/12/23 | 276207 | graphics/pgf/contrib/smartdiagram.zip
-2018/08/02 | 288184 | graphics/pgf/contrib/spath3/calligraphy_doc.pdf
-2018/08/02 | 15886 | graphics/pgf/contrib/spath3/calligraphy_doc.tex
-2018/08/02 | 384979 | graphics/pgf/contrib/spath3/knots_doc.pdf
-2018/08/02 | 21659 | graphics/pgf/contrib/spath3/knots_doc.tex
-2019/02/12 | 519 | graphics/pgf/contrib/spath3/README
-2019/02/12 | 439282 | graphics/pgf/contrib/spath3/spath3_code.pdf
-2019/02/12 | 134242 | graphics/pgf/contrib/spath3/spath3.dtx
-2019/02/13 | 1134504 | graphics/pgf/contrib/spath3.zip
+2021/01/20 | 259679 | graphics/pgf/contrib/spath3/calligraphy.pdf
+2021/01/20 | 16415 | graphics/pgf/contrib/spath3/calligraphy.tex
+2021/01/20 | 333450 | graphics/pgf/contrib/spath3/knots.pdf
+2021/01/20 | 23129 | graphics/pgf/contrib/spath3/knots.tex
+2021/01/22 | 523 | graphics/pgf/contrib/spath3/README
+2021/01/22 | 197284 | graphics/pgf/contrib/spath3/spath3_code.dtx
+2021/01/22 | 547140 | graphics/pgf/contrib/spath3/spath3_code.pdf
+2021/01/22 | 337099 | graphics/pgf/contrib/spath3/spath3.pdf
+2021/01/22 | 21745 | graphics/pgf/contrib/spath3/spath3.tex
+2021/01/23 | 1509137 | graphics/pgf/contrib/spath3.zip
2019/02/18 | 107163 | graphics/pgf/contrib/spectralsequences/examples/ANSS-S_2.pdf
2019/02/18 | 4304 | graphics/pgf/contrib/spectralsequences/examples/ANSS-S_2.tex
2019/02/18 | 48774 | graphics/pgf/contrib/spectralsequences/examples/ANSS-S_3.pdf
@@ -171693,7 +171695,6 @@
2020/06/12 | 573255 | install/graphics/pgf/contrib/commutative-diagrams.tds.zip
2017/06/01 | 1005947 | install/graphics/pgf/contrib/hobby.tds.zip
2014/06/15 | 843875 | install/graphics/pgf/contrib/logicpuzzle.tds.zip
-2018/07/11 | 969430 | install/graphics/pgf/contrib/penrose.tds.zip
2020/03/01 | 17375854 | install/graphics/pgf/contrib/pgfplots.tds.zip
2013/12/11 | 491125 | install/graphics/pgf/contrib/rulercompass.tds.zip
2014/01/23 | 77120 | install/graphics/pgf/contrib/tikz-opm.tds.zip
@@ -184938,7 +184939,7 @@
2013/04/01 | 14776 | macros/context/contrib/context-visualcounter/tex/context/third/visualcounter/t-visualcounter.mkvi
2018/03/05 | 11 | macros/context/contrib/context-visualcounter/VERSION
2018/03/22 | 276789 | macros/context/contrib/context-visualcounter.zip
-2021/01/21 | 119657508 | macros/context/latest/cont-tmf.zip
+2021/01/22 | 119659630 | macros/context/latest/cont-tmf.zip
2016/04/21 | 32846 | macros/cstex/base/cmexb.tar.gz
2016/06/26 | 1728262 | macros/cstex/base/csfonts-t1.tar.gz
2007/03/01 | 187106 | macros/cstex/base/csfonts.tar.gz
@@ -196619,15 +196620,15 @@
2011/06/05 | 1965 | macros/latex/contrib/eqell/eqell.tex
2011/05/29 | 503 | macros/latex/contrib/eqell/README
2011/06/08 | 183039 | macros/latex/contrib/eqell.zip
-2020/04/10 | 6153 | macros/latex/contrib/eqexam/aebrandom.def
-2020/04/10 | 624926 | macros/latex/contrib/eqexam/doc/eqexamman.pdf
-2020/04/10 | 226080 | macros/latex/contrib/eqexam/doc/eqexamman.tex
-2020/04/10 | 806244 | macros/latex/contrib/eqexam/doc/eqexam.pdf
+2021/01/22 | 5931 | macros/latex/contrib/eqexam/aebrandom.def
+2021/01/23 | 671573 | macros/latex/contrib/eqexam/doc/eqexamman.pdf
+2021/01/23 | 227607 | macros/latex/contrib/eqexam/doc/eqexamman.tex
+2021/01/23 | 745675 | macros/latex/contrib/eqexam/doc/eqexam.pdf
2020/01/07 | 668610 | macros/latex/contrib/eqexam/doc/fortextbook/fortextbook.pdf
-2019/12/22 | 812490 | macros/latex/contrib/eqexam/doc/fortextbook.zip
+2016/01/19 | 718935 | macros/latex/contrib/eqexam/doc/fortextbook.zip
2010/06/18 | 334 | macros/latex/contrib/eqexam/eqecus.opt
-2020/04/10 | 66439 | macros/latex/contrib/eqexam/eqexam.def
-2020/04/04 | 411264 | macros/latex/contrib/eqexam/eqexam.dtx
+2021/01/22 | 65967 | macros/latex/contrib/eqexam/eqexam.def
+2021/01/23 | 413756 | macros/latex/contrib/eqexam/eqexam.dtx
2020/03/20 | 2139 | macros/latex/contrib/eqexam/eqexam.ins
2016/07/16 | 10197 | macros/latex/contrib/eqexam/examples/aeb-comment.sty
2011/04/08 | 252067 | macros/latex/contrib/eqexam/examples/coorplane.eps
@@ -196637,7 +196638,7 @@
2005/02/04 | 118 | macros/latex/contrib/eqexam/examples/fig1.bb
2000/05/02 | 831714 | macros/latex/contrib/eqexam/examples/fig1.eps
2005/02/04 | 33479 | macros/latex/contrib/eqexam/examples/fig1.jpg
-2005/02/04 | 12673 | macros/latex/contrib/eqexam/examples/fig1.pdf
+2021/01/23 | 11038 | macros/latex/contrib/eqexam/examples/fig1.pdf
2018/01/18 | 28355 | macros/latex/contrib/eqexam/examples/flextended-opt.pdf
2018/01/18 | 2966 | macros/latex/contrib/eqexam/examples/flextended-opt.tex
2011/04/08 | 212797 | macros/latex/contrib/eqexam/examples/graph.eps
@@ -196649,25 +196650,25 @@
2015/04/29 | 21745 | macros/latex/contrib/eqexam/examples/hw03.pdf
2018/01/18 | 1294 | macros/latex/contrib/eqexam/examples/hw03.tex
2005/02/05 | 396 | macros/latex/contrib/eqexam/examples/hw.cfg
-2005/02/05 | 396 | macros/latex/contrib/eqexam/examples/hw.cfg.txt
2015/04/29 | 22192 | macros/latex/contrib/eqexam/examples/markqs.pdf
2015/04/29 | 3544 | macros/latex/contrib/eqexam/examples/markqs.tex
2018/12/07 | 3548 | macros/latex/contrib/eqexam/examples/quiz01.tex
2015/04/30 | 34997 | macros/latex/contrib/eqexam/examples/quiz02.pdf
2015/04/29 | 3899 | macros/latex/contrib/eqexam/examples/quiz02.tex
2005/01/23 | 242 | macros/latex/contrib/eqexam/examples/quiz.cfg
-2005/01/23 | 242 | macros/latex/contrib/eqexam/examples/quiz.cfg.txt
2018/12/12 | 5457 | macros/latex/contrib/eqexam/examples/selectversion_tst.tex
-2020/03/22 | 12204 | macros/latex/contrib/eqexam/examples/test01.tex
+2021/01/23 | 116251 | macros/latex/contrib/eqexam/examples/test01.pdf
+2021/01/23 | 12202 | macros/latex/contrib/eqexam/examples/test01.tex
+2015/04/29 | 216104 | macros/latex/contrib/eqexam/examples/test02.pdf
2015/04/29 | 10273 | macros/latex/contrib/eqexam/examples/test02.tex
+2021/01/15 | 161999 | macros/latex/contrib/eqexam/examples/test03.pdf
2015/04/29 | 21131 | macros/latex/contrib/eqexam/examples/test03.tex
-2015/04/29 | 18253 | macros/latex/contrib/eqexam/examples/test_matching.pdf
-2015/04/29 | 1985 | macros/latex/contrib/eqexam/examples/test_matching.tex
+2021/01/23 | 1985 | macros/latex/contrib/eqexam/examples/test_matching.tex
2013/10/23 | 15984 | macros/latex/contrib/eqexam/examples/tex_survey_h.tex
2010/01/10 | 15205 | macros/latex/contrib/eqexam/examples/tex_survey.tex
-2020/04/10 | 4011 | macros/latex/contrib/eqexam/README.md
+2021/01/23 | 4160 | macros/latex/contrib/eqexam/README.md
2005/02/05 | 6195 | macros/latex/contrib/eqexam/script/eqAttach.asp
-2020/04/10 | 3338756 | macros/latex/contrib/eqexam.zip
+2021/01/23 | 3707422 | macros/latex/contrib/eqexam.zip
2019/07/01 | 106451 | macros/latex/contrib/eqexpl/eqexpl.pdf
2019/07/01 | 2142 | macros/latex/contrib/eqexpl/eqexpl.sty
2019/07/01 | 6393 | macros/latex/contrib/eqexpl/eqexpl.tex
@@ -198294,11 +198295,12 @@
2010/02/28 | 2715 | macros/latex/contrib/fnpara/fnpara-doc.tex
2012/03/11 | 6981 | macros/latex/contrib/fnpara/fnpara.sty
2012/03/11 | 177564 | macros/latex/contrib/fnpara.zip
-2019/10/05 | 573765 | macros/latex/contrib/fnpct/fnpct_en.pdf
-2019/10/05 | 40375 | macros/latex/contrib/fnpct/fnpct_en.tex
-2019/10/05 | 43618 | macros/latex/contrib/fnpct/fnpct.sty
-2019/10/05 | 1489 | macros/latex/contrib/fnpct/README
-2019/10/05 | 587449 | macros/latex/contrib/fnpct.zip
+2021/01/23 | 9063 | macros/latex/contrib/fnpct/fnpct-manual.cls
+2021/01/23 | 472808 | macros/latex/contrib/fnpct/fnpct-manual.pdf
+2021/01/23 | 26595 | macros/latex/contrib/fnpct/fnpct-manual.tex
+2021/01/23 | 46493 | macros/latex/contrib/fnpct/fnpct.sty
+2021/01/23 | 1488 | macros/latex/contrib/fnpct/README
+2021/01/23 | 492235 | macros/latex/contrib/fnpct.zip
2017/09/20 | 199982 | macros/latex/contrib/fnspe/fnspe.pdf
2017/09/20 | 5996 | macros/latex/contrib/fnspe/fnspe.sty
2017/09/20 | 14233 | macros/latex/contrib/fnspe/fnspe.tex
@@ -257101,10 +257103,10 @@
2018/01/26 | 4655 | support/wp2latex/html2latex.htm
2007/07/22 | 600 | support/wp2latex/readme.1st
2018/06/13 | 7401 | support/wp2latex/readme.txt
-2017/05/06 | 5656974 | support/wp2latex/wp2latex-3.75.zip
+2018/01/18 | 3785622 | support/wp2latex/wp2latex-3.76.zip
2018/01/26 | 45297 | support/wp2latex/wp2latex.doc.htm
2018/01/26 | 7259 | support/wp2latex/wp2latex.faq
-2017/05/06 | 888742 | support/wp2latex/WP2LaTeX_Installer-3.75.exe
+2018/01/16 | 888554 | support/wp2latex/WP2LaTeX_Installer-3.76.exe
2018/01/26 | 1241 | support/wp2latex/wp2latex.lsm
2018/01/26 | 35145 | support/wp2latex/wp2latex_pas-2.3.zip
2000/02/22 | 481 | support/wsuipa2tipa/README
@@ -257156,14 +257158,15 @@
2020/06/30 | 35148 | support/xml2pmx/doc/LICENSE
2020/05/21 | 4590 | support/xml2pmx/doc/musixtex.1
2020/05/21 | 23518 | support/xml2pmx/doc/musixtex.pdf
-2020/06/30 | 6264 | support/xml2pmx/doc/Readme.XML2PMX
-2020/06/30 | 1100 | support/xml2pmx/doc/xml2pmx.1
-2020/06/30 | 16563 | support/xml2pmx/doc/xml2pmx.pdf
-2020/08/12 | 134924 | support/xml2pmx/MacOS/xml2pmx
-2020/08/12 | 3318 | support/xml2pmx/README
+2021/01/23 | 8522 | support/xml2pmx/doc/Readme.XML2PMX
+2021/01/23 | 1367 | support/xml2pmx/doc/xml2pmx.1
+2021/01/23 | 17546 | support/xml2pmx/doc/xml2pmx.pdf
+2021/01/23 | 139408 | support/xml2pmx/MacOS/xml2pmx
+2021/01/23 | 3493 | support/xml2pmx/README
2020/08/12 | 287276 | support/xml2pmx/sources/xml2pmx-2020-08-12.tar.gz
-2020/08/12 | 261995 | support/xml2pmx/Windows/xml2pmx.exe
-2020/08/12 | 504119 | support/xml2pmx.zip
+2021/01/23 | 450898 | support/xml2pmx/sources/xml2pmx-2021-01-23.tar.gz
+2021/01/23 | 313412 | support/xml2pmx/Windows/xml2pmx.exe
+2021/01/23 | 964621 | support/xml2pmx.zip
2010/04/12 | 32230 | support/xpdfopen/aclocal.m4
2014/05/24 | 5053 | support/xpdfopen/ChangeLog
2010/04/12 | 179753 | support/xpdfopen/configure
@@ -266788,8 +266791,8 @@
2019/02/28 | 14064 | systems/texlive/tlnet/archive/mnsymbol.source.r18651.tar.xz
2019/02/28 | 260136 | systems/texlive/tlnet/archive/modeles-factures-belges-assocs.doc.r50010.tar.xz
2019/02/28 | 3096 | systems/texlive/tlnet/archive/modeles-factures-belges-assocs.r50010.tar.xz
-2019/11/07 | 839416 | systems/texlive/tlnet/archive/moderncv.doc.r52669.tar.xz
-2019/11/07 | 21988 | systems/texlive/tlnet/archive/moderncv.r52669.tar.xz
+2021/01/23 | 245668 | systems/texlive/tlnet/archive/moderncv.doc.r57496.tar.xz
+2021/01/23 | 30884 | systems/texlive/tlnet/archive/moderncv.r57496.tar.xz
2019/02/28 | 391208 | systems/texlive/tlnet/archive/modernposter.doc.r47269.tar.xz
2019/02/28 | 2552 | systems/texlive/tlnet/archive/modernposter.r47269.tar.xz
2020/06/12 | 186684 | systems/texlive/tlnet/archive/moderntimeline.doc.r55518.tar.xz
@@ -270228,8 +270231,8 @@
2020/03/24 | 280 | systems/texlive/tlnet/archive/texlive-cz.r54496.tar.xz
2020/12/26 | 1338744 | systems/texlive/tlnet/archive/texlive-de.doc.r57223.tar.xz
2020/12/26 | 272 | systems/texlive/tlnet/archive/texlive-de.r57223.tar.xz
-2021/01/22 | 171652 | systems/texlive/tlnet/archive/texlive-docindex.doc.r57481.tar.xz
-2021/01/22 | 388 | systems/texlive/tlnet/archive/texlive-docindex.r57481.tar.xz
+2021/01/23 | 172040 | systems/texlive/tlnet/archive/texlive-docindex.doc.r57494.tar.xz
+2021/01/23 | 388 | systems/texlive/tlnet/archive/texlive-docindex.r57494.tar.xz
2020/04/16 | 1891392 | systems/texlive/tlnet/archive/texlive-en.doc.r54755.tar.xz
2020/04/16 | 272 | systems/texlive/tlnet/archive/texlive-en.r54755.tar.xz
2020/03/22 | 3090144 | systems/texlive/tlnet/archive/texlive-es.doc.r54465.tar.xz
@@ -271977,16 +271980,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
2021/01/06 | 106039 | systems/texlive/tlnet/install-tl
-2021/01/22 | 5521100 | systems/texlive/tlnet/install-tl-unx.tar.gz
-2021/01/22 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
-2021/01/22 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
+2021/01/23 | 5521364 | systems/texlive/tlnet/install-tl-unx.tar.gz
+2021/01/23 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
+2021/01/23 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
2020/08/23 | 4889 | systems/texlive/tlnet/install-tl-windows.bat
-2021/01/22 | 19418739 | systems/texlive/tlnet/install-tl-windows.exe
-2021/01/22 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
-2021/01/22 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
-2021/01/22 | 24288833 | systems/texlive/tlnet/install-tl.zip
-2021/01/22 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
-2021/01/22 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
+2021/01/23 | 19418708 | systems/texlive/tlnet/install-tl-windows.exe
+2021/01/23 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
+2021/01/23 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
+2021/01/23 | 24288833 | systems/texlive/tlnet/install-tl.zip
+2021/01/23 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
+2021/01/23 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
2020/03/05 | 1215 | systems/texlive/tlnet/README.md
2020/04/06 | 5961 | systems/texlive/tlnet/tlpkg/gpg/pubring.gpg
2016/04/12 | 600 | systems/texlive/tlnet/tlpkg/gpg/random_seed
@@ -272042,12 +272045,12 @@
2020/05/17 | 20322 | systems/texlive/tlnet/tlpkg/TeXLive/TLCrypto.pm
2020/05/03 | 4786 | systems/texlive/tlnet/tlpkg/TeXLive/TLDownload.pm
2020/09/22 | 27563 | systems/texlive/tlnet/tlpkg/TeXLive/TLPaper.pm
-2021/01/22 | 17003360 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
-2021/01/22 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
+2021/01/23 | 17002697 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
+2021/01/23 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
2020/05/13 | 86417 | systems/texlive/tlnet/tlpkg/TeXLive/TLPDB.pm
-2021/01/22 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
-2021/01/22 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
-2021/01/22 | 2275392 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+2021/01/23 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
+2021/01/23 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
+2021/01/23 | 2274796 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
2020/04/15 | 58761 | systems/texlive/tlnet/tlpkg/TeXLive/TLPOBJ.pm
2020/03/20 | 41736 | systems/texlive/tlnet/tlpkg/TeXLive/TLPSRC.pm
2020/05/11 | 15010 | systems/texlive/tlnet/tlpkg/TeXLive/TLTREE.pm
@@ -276628,7 +276631,7 @@
2020/10/03 | 318630 | systems/win32/miktex/tm/packages/filehook.tar.lzma
2012/12/04 | 924573 | systems/win32/miktex/tm/packages/fileinfo.tar.lzma
2011/09/21 | 281409 | systems/win32/miktex/tm/packages/filemod.tar.lzma
-2021/01/22 | 563347 | systems/win32/miktex/tm/packages/files.csv.lzma
+2021/01/23 | 563347 | systems/win32/miktex/tm/packages/files.csv.lzma
2001/05/14 | 5617 | systems/win32/miktex/tm/packages/finbib.tar.lzma
2015/10/20 | 44379 | systems/win32/miktex/tm/packages/findhyph.tar.lzma
2011/10/21 | 89323 | systems/win32/miktex/tm/packages/fink.tar.lzma
@@ -277812,9 +277815,9 @@
2018/01/12 | 157226 | systems/win32/miktex/tm/packages/miktex-zip-bin-x64.tar.lzma
2021/01/16 | 39515 | systems/win32/miktex/tm/packages/miktex-zlib-bin-2.9.tar.lzma
2021/01/16 | 43377 | systems/win32/miktex/tm/packages/miktex-zlib-bin-x64-2.9.tar.lzma
-2021/01/22 | 206582 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
-2021/01/22 | 1248023 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
-2021/01/22 | 1164992 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
+2021/01/23 | 206528 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
+2021/01/23 | 1247391 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
+2021/01/23 | 1165022 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
2021/01/16 | 13454 | systems/win32/miktex/tm/packages/miktex-zzip-bin-2.9.tar.lzma
2021/01/16 | 14322 | systems/win32/miktex/tm/packages/miktex-zzip-bin-x64-2.9.tar.lzma
2016/07/15 | 35914 | systems/win32/miktex/tm/packages/mil3.tar.lzma
@@ -277972,187 +277975,187 @@
2018/04/09 | 400132 | systems/win32/miktex/tm/packages/newunicodechar.tar.lzma
2011/09/19 | 101312 | systems/win32/miktex/tm/packages/newvbtm.tar.lzma
2020/09/06 | 231669 | systems/win32/miktex/tm/packages/newverbs.tar.lzma
-2021/01/22 | 563841 | systems/win32/miktex/tm/packages/next/files.csv.lzma
-2021/01/22 | 50704 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma
-2021/01/22 | 56455 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
-2021/01/22 | 969230 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma
-2021/01/22 | 1078966 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
-2021/01/22 | 29024 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma
-2021/01/22 | 31346 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
-2021/01/22 | 29511 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma
-2021/01/22 | 34305 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
-2021/01/22 | 50030 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma
-2021/01/22 | 57610 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
-2021/01/22 | 85302 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma
-2021/01/22 | 94598 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
-2021/01/22 | 67495 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma
-2021/01/22 | 75340 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
-2021/01/22 | 27204 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma
-2021/01/22 | 30873 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
-2021/01/22 | 329920 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma
-2021/01/22 | 392682 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
-2021/01/22 | 32544 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma
-2021/01/22 | 36677 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
-2021/01/22 | 51409 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma
-2021/01/22 | 56598 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
-2021/01/22 | 231665 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma
-2021/01/22 | 254185 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
-2021/01/22 | 179468 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma
-2021/01/22 | 195675 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
-2021/01/22 | 52498 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma
-2021/01/22 | 59144 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
-2021/01/22 | 21130 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma
-2021/01/22 | 23313 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
-2021/01/22 | 461384 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
-2021/01/22 | 45636 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma
-2021/01/22 | 51184 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
-2021/01/22 | 281359 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma
-2021/01/22 | 320795 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
-2021/01/22 | 40962 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma
-2021/01/22 | 45270 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
-2021/01/22 | 116934 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma
-2021/01/22 | 131490 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
-2021/01/22 | 1281719 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma
-2021/01/22 | 1417674 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
-2021/01/22 | 87637 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma
-2021/01/22 | 99483 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
-2021/01/22 | 43072 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma
-2021/01/22 | 47902 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
-2021/01/22 | 25128 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma
-2021/01/22 | 28006 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
-2021/01/22 | 55851 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma
-2021/01/22 | 62740 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
-2021/01/22 | 135012 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma
-2021/01/22 | 152745 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
-2021/01/22 | 73323 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma
-2021/01/22 | 77839 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
-2021/01/22 | 71575 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma
-2021/01/22 | 80638 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
-2021/01/22 | 258631 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma
-2021/01/22 | 295621 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
-2021/01/22 | 22043 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma
-2021/01/22 | 25038 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
-2021/01/22 | 97403 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma
-2021/01/22 | 112280 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
-2021/01/22 | 63831 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma
-2021/01/22 | 72842 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
-2021/01/22 | 94788 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma
-2021/01/22 | 113935 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
-2021/01/22 | 38058 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma
-2021/01/22 | 42663 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
-2021/01/22 | 484329 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma
-2021/01/22 | 568174 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
-2021/01/22 | 147187 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma
-2021/01/22 | 159864 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
-2021/01/22 | 94803 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma
-2021/01/22 | 109149 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
-2021/01/22 | 16339 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma
-2021/01/22 | 17956 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
-2021/01/22 | 28230 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma
-2021/01/22 | 30030 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
-2021/01/22 | 624932 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma
-2021/01/22 | 680061 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
-2021/01/22 | 531716 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma
-2021/01/22 | 596722 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
-2021/01/22 | 475816 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma
-2021/01/22 | 514082 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
-2021/01/22 | 94377 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma
-2021/01/22 | 103331 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
-2021/01/22 | 1685633 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma
-2021/01/22 | 2002727 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
-2021/01/22 | 67685 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma
-2021/01/22 | 74156 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
-2021/01/22 | 27462 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma
-2021/01/22 | 31542 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
-2021/01/22 | 7747 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma
-2021/01/22 | 8774 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
-2021/01/22 | 195626 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma
-2021/01/22 | 213738 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
-2021/01/22 | 250205 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma
-2021/01/22 | 283982 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
-2021/01/22 | 97121 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma
-2021/01/22 | 101859 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
-2021/01/22 | 60606 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma
-2021/01/22 | 67915 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma
-2021/01/22 | 124938 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma
-2021/01/22 | 136345 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
-2021/01/22 | 147086 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma
-2021/01/22 | 163795 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
-2021/01/22 | 199584 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma
-2021/01/22 | 180158 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
-2021/01/22 | 67356 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma
-2021/01/22 | 77430 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
-2021/01/22 | 31227 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma
-2021/01/22 | 35065 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
-2021/01/22 | 38071 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma
-2021/01/22 | 42550 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
-2021/01/22 | 42871 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma
-2021/01/22 | 46959 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
-2021/01/22 | 45899 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma
-2021/01/22 | 52401 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
-2021/01/22 | 193759 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma
-2021/01/22 | 210931 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
-2021/01/22 | 35424 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma
-2021/01/22 | 40230 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
-2021/01/22 | 740140 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma
-2021/01/22 | 813997 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
-2021/01/22 | 198080 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma
-2021/01/22 | 202648 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
-2021/01/22 | 208087 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma
-2021/01/22 | 243510 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
-2021/01/22 | 78748 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma
-2021/01/22 | 87770 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
-2021/01/22 | 1171816 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma
-2021/01/22 | 1307385 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
-2021/01/22 | 20119 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma
-2021/01/22 | 23880 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
-2021/01/22 | 31549 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma
-2021/01/22 | 37251 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
-2021/01/22 | 63927 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma
-2021/01/22 | 71966 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
-2021/01/22 | 43563 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma
-2021/01/22 | 52056 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
-2021/01/22 | 1291598 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma
-2021/01/22 | 1421908 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
-2021/01/22 | 42398 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma
-2021/01/22 | 51861 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
-2021/01/22 | 56324 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma
-2021/01/22 | 59807 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
-2021/01/22 | 25330 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma
-2021/01/22 | 27441 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
-2021/01/22 | 16111 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma
-2021/01/22 | 18105 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
-2021/01/22 | 63762 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma
-2021/01/22 | 70202 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
-2021/01/22 | 153806 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma
-2021/01/22 | 167737 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
-2021/01/22 | 56977 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma
-2021/01/22 | 65322 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
-2021/01/22 | 99605 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma
-2021/01/22 | 104758 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
-2021/01/22 | 2495615 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma
-2021/01/22 | 2617419 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
-2021/01/22 | 55373 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma
-2021/01/22 | 62078 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
-2021/01/22 | 33533 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma
-2021/01/22 | 37310 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
-2021/01/22 | 27217 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma
-2021/01/22 | 33143 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
-2021/01/22 | 65816 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma
-2021/01/22 | 70424 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
-2021/01/22 | 310963 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma
-2021/01/22 | 345230 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
-2021/01/22 | 583738 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma
-2021/01/22 | 619142 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
-2021/01/22 | 39537 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma
-2021/01/22 | 43384 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
-2021/01/22 | 206591 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
-2021/01/22 | 1247592 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
-2021/01/22 | 1165147 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
-2021/01/22 | 13465 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma
-2021/01/22 | 14343 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
+2021/01/23 | 563841 | systems/win32/miktex/tm/packages/next/files.csv.lzma
+2021/01/23 | 50703 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma
+2021/01/23 | 56454 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
+2021/01/23 | 969229 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma
+2021/01/23 | 1078966 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
+2021/01/23 | 29023 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma
+2021/01/23 | 31345 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
+2021/01/23 | 29513 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma
+2021/01/23 | 34305 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
+2021/01/23 | 50032 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma
+2021/01/23 | 57610 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
+2021/01/23 | 85304 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma
+2021/01/23 | 94597 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
+2021/01/23 | 67496 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma
+2021/01/23 | 75341 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
+2021/01/23 | 27204 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma
+2021/01/23 | 30874 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
+2021/01/23 | 329919 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma
+2021/01/23 | 392681 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
+2021/01/23 | 32545 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma
+2021/01/23 | 36677 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
+2021/01/23 | 51410 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma
+2021/01/23 | 56599 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
+2021/01/23 | 231666 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma
+2021/01/23 | 254184 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
+2021/01/23 | 179467 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma
+2021/01/23 | 195674 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
+2021/01/23 | 52496 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma
+2021/01/23 | 59144 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
+2021/01/23 | 21129 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma
+2021/01/23 | 23312 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
+2021/01/23 | 461384 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
+2021/01/23 | 45636 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma
+2021/01/23 | 51184 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
+2021/01/23 | 281361 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma
+2021/01/23 | 320797 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
+2021/01/23 | 40964 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma
+2021/01/23 | 45270 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
+2021/01/23 | 116935 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma
+2021/01/23 | 131490 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
+2021/01/23 | 1281721 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma
+2021/01/23 | 1417675 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
+2021/01/23 | 87638 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma
+2021/01/23 | 99483 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
+2021/01/23 | 43071 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma
+2021/01/23 | 47904 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
+2021/01/23 | 25128 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma
+2021/01/23 | 28007 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
+2021/01/23 | 55852 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma
+2021/01/23 | 62741 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
+2021/01/23 | 135010 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma
+2021/01/23 | 152746 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
+2021/01/23 | 73321 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma
+2021/01/23 | 77839 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
+2021/01/23 | 71575 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma
+2021/01/23 | 80639 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
+2021/01/23 | 258630 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma
+2021/01/23 | 295623 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
+2021/01/23 | 22044 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma
+2021/01/23 | 25039 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
+2021/01/23 | 97403 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma
+2021/01/23 | 112281 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
+2021/01/23 | 63832 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma
+2021/01/23 | 72843 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
+2021/01/23 | 94787 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma
+2021/01/23 | 113936 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
+2021/01/23 | 38059 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma
+2021/01/23 | 42663 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
+2021/01/23 | 484326 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma
+2021/01/23 | 568172 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
+2021/01/23 | 147188 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma
+2021/01/23 | 159864 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
+2021/01/23 | 94802 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma
+2021/01/23 | 109149 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
+2021/01/23 | 16339 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma
+2021/01/23 | 17958 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
+2021/01/23 | 28229 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma
+2021/01/23 | 30031 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
+2021/01/23 | 624931 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma
+2021/01/23 | 680060 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
+2021/01/23 | 531715 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma
+2021/01/23 | 596721 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
+2021/01/23 | 475818 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma
+2021/01/23 | 514088 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
+2021/01/23 | 94376 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma
+2021/01/23 | 103331 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
+2021/01/23 | 1685633 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma
+2021/01/23 | 2002725 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
+2021/01/23 | 67684 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma
+2021/01/23 | 74157 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
+2021/01/23 | 27462 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma
+2021/01/23 | 31542 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
+2021/01/23 | 7747 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma
+2021/01/23 | 8773 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
+2021/01/23 | 195626 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma
+2021/01/23 | 213737 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
+2021/01/23 | 250203 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma
+2021/01/23 | 283982 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
+2021/01/23 | 97121 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma
+2021/01/23 | 101859 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
+2021/01/23 | 60606 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma
+2021/01/23 | 67914 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma
+2021/01/23 | 124938 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma
+2021/01/23 | 136346 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
+2021/01/23 | 147085 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma
+2021/01/23 | 163795 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
+2021/01/23 | 199584 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma
+2021/01/23 | 180158 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
+2021/01/23 | 67355 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma
+2021/01/23 | 77429 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
+2021/01/23 | 31227 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma
+2021/01/23 | 35065 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
+2021/01/23 | 38069 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma
+2021/01/23 | 42551 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
+2021/01/23 | 42872 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma
+2021/01/23 | 46958 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
+2021/01/23 | 45899 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma
+2021/01/23 | 52400 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
+2021/01/23 | 193758 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma
+2021/01/23 | 210931 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
+2021/01/23 | 35425 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma
+2021/01/23 | 40230 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
+2021/01/23 | 740141 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma
+2021/01/23 | 813998 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
+2021/01/23 | 198079 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma
+2021/01/23 | 202648 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
+2021/01/23 | 208089 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma
+2021/01/23 | 243510 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
+2021/01/23 | 78748 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma
+2021/01/23 | 87769 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
+2021/01/23 | 1171817 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma
+2021/01/23 | 1307387 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
+2021/01/23 | 20119 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma
+2021/01/23 | 23881 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
+2021/01/23 | 31550 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma
+2021/01/23 | 37250 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
+2021/01/23 | 63928 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma
+2021/01/23 | 71967 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
+2021/01/23 | 43563 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma
+2021/01/23 | 52057 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
+2021/01/23 | 1291601 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma
+2021/01/23 | 1421909 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
+2021/01/23 | 42399 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma
+2021/01/23 | 51863 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
+2021/01/23 | 56326 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma
+2021/01/23 | 59809 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
+2021/01/23 | 25333 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma
+2021/01/23 | 27440 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
+2021/01/23 | 16111 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma
+2021/01/23 | 18107 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
+2021/01/23 | 63764 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma
+2021/01/23 | 70203 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
+2021/01/23 | 153807 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma
+2021/01/23 | 167737 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
+2021/01/23 | 56978 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma
+2021/01/23 | 65322 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
+2021/01/23 | 99607 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma
+2021/01/23 | 104761 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
+2021/01/23 | 2495614 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma
+2021/01/23 | 2617421 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
+2021/01/23 | 55374 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma
+2021/01/23 | 62082 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
+2021/01/23 | 33532 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma
+2021/01/23 | 37310 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
+2021/01/23 | 27216 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma
+2021/01/23 | 33141 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
+2021/01/23 | 65815 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma
+2021/01/23 | 70425 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
+2021/01/23 | 310963 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma
+2021/01/23 | 345230 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
+2021/01/23 | 583740 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma
+2021/01/23 | 619144 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
+2021/01/23 | 39536 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma
+2021/01/23 | 43385 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
+2021/01/23 | 206572 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
+2021/01/23 | 1247153 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
+2021/01/23 | 1164868 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
+2021/01/23 | 13466 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma
+2021/01/23 | 14342 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
2019/03/12 | 1412 | systems/win32/miktex/tm/packages/nextpage.tar.lzma
-2021/01/22 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini
+2021/01/23 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini
2018/07/06 | 145915 | systems/win32/miktex/tm/packages/nexus-otf.tar.lzma
2017/03/30 | 191149 | systems/win32/miktex/tm/packages/nfssext-cfr.tar.lzma
2012/12/20 | 612251 | systems/win32/miktex/tm/packages/nicefilelist.tar.lzma
@@ -278482,7 +278485,7 @@
2020/10/20 | 342254 | systems/win32/miktex/tm/packages/preview.tar.lzma
2019/06/20 | 375963 | systems/win32/miktex/tm/packages/prftree.tar.lzma
2020/10/27 | 357822 | systems/win32/miktex/tm/packages/principia.tar.lzma
-2021/01/22 | 859 | systems/win32/miktex/tm/packages/pr.ini
+2021/01/23 | 859 | systems/win32/miktex/tm/packages/pr.ini
2010/09/27 | 248469 | systems/win32/miktex/tm/packages/printlen.tar.lzma
2008/06/17 | 77313 | systems/win32/miktex/tm/packages/proba.tar.lzma
2017/07/12 | 988486 | systems/win32/miktex/tm/packages/probsoln.tar.lzma
@@ -279657,7 +279660,7 @@
2021/01/13 | 5177516 | systems/win32/w32tex/aleph-w32.tar.xz
2021/01/20 | 66692556 | systems/win32/w32tex/biblatex-biber.tar.xz
2016/12/13 | 65971452 | systems/win32/w32tex/cbfonts.tar.xz
-2021/01/21 | 771169 | systems/win32/w32tex/ChangeLog
+2021/01/22 | 771857 | systems/win32/w32tex/ChangeLog
2009/08/03 | 141221 | systems/win32/w32tex/ChangeLog.0
2009/08/03 | 221890 | systems/win32/w32tex/ChangeLog.1
2009/08/03 | 116462 | systems/win32/w32tex/ChangeLog.2
@@ -279670,9 +279673,9 @@
2020/09/21 | 6434128 | systems/win32/w32tex/datetime2.tar.xz
2021/01/13 | 844644 | systems/win32/w32tex/dvi2ps-w32.tar.xz
2021/01/13 | 484204 | systems/win32/w32tex/dvi2tty-w32.tar.xz
-2021/01/17 | 4662768 | systems/win32/w32tex/dvipdfm-w32.tar.xz
+2021/01/22 | 4662260 | systems/win32/w32tex/dvipdfm-w32.tar.xz
2021/01/13 | 4550868 | systems/win32/w32tex/dvipsk-w32.tar.xz
-2021/01/13 | 2653592 | systems/win32/w32tex/dvitools-w32.tar.xz
+2021/01/22 | 2653880 | systems/win32/w32tex/dvitools-w32.tar.xz
2021/01/03 | 1179164 | systems/win32/w32tex/extractpdfmark-w32.tar.xz
2020/12/05 | 17348896 | systems/win32/w32tex/gregorio-w32.tar.xz
2009/08/03 | 1072620 | systems/win32/w32tex/gtftex.zip
@@ -279681,7 +279684,7 @@
2021/01/09 | 34772856 | systems/win32/w32tex/latex.tar.xz
2020/12/05 | 1008204 | systems/win32/w32tex/lcdf-typetools-w32.tar.xz
2020/12/18 | 403185380 | systems/win32/w32tex/ltxpkgdocs.tar.xz
-2021/01/21 | 33955984 | systems/win32/w32tex/ltxpkgs.tar.xz
+2021/01/22 | 33954220 | systems/win32/w32tex/ltxpkgs.tar.xz
2021/01/16 | 3866408 | systems/win32/w32tex/luajittex-dev-w32.tar.xz
2021/01/14 | 3865560 | systems/win32/w32tex/luajittex-exp-w32.tar.xz
2021/01/16 | 3869096 | systems/win32/w32tex/luajittex-w32.tar.xz
@@ -279700,19 +279703,19 @@
2021/01/13 | 1232056 | systems/win32/w32tex/omegaj-w32.tar.xz
2020/11/16 | 324540 | systems/win32/w32tex/otfbeta.tar.xz
2021/01/21 | 21154532 | systems/win32/w32tex/pdftex-w32.tar.xz
-2021/01/20 | 87939300 | systems/win32/w32tex/pgfcontrib.tar.xz
+2021/01/22 | 89179804 | systems/win32/w32tex/pgfcontrib.tar.xz
2015/01/26 | 189072 | systems/win32/w32tex/plain2-2.54-w32.tar.xz
2020/11/27 | 2807432 | systems/win32/w32tex/platex.tar.xz
2020/03/20 | 1598792 | systems/win32/w32tex/pmx.tar.xz
2020/12/05 | 1171272 | systems/win32/w32tex/pstoedit-w32.tar.xz
2020/10/25 | 274208000 | systems/win32/w32tex/pstricks.tar.xz
2021/01/13 | 517756 | systems/win32/w32tex/psutils-w32.tar.xz
-2021/01/17 | 6622444 | systems/win32/w32tex/ptex-ng-w32.tar.xz
+2021/01/22 | 6620976 | systems/win32/w32tex/ptex-ng-w32.tar.xz
2021/01/13 | 10633792 | systems/win32/w32tex/ptex-w32.tar.xz
2019/04/15 | 499188 | systems/win32/w32tex/sam2p-w32.tar.xz
2020/10/14 | 87958692 | systems/win32/w32tex/t1fonts.tar.xz
2020/10/31 | 142032 | systems/win32/w32tex/t1utils-w32.tar.xz
-2021/01/13 | 2604708 | systems/win32/w32tex/tex4htk-w32.tar.xz
+2021/01/22 | 2598408 | systems/win32/w32tex/tex4htk-w32.tar.xz
2018/06/20 | 15940044 | systems/win32/w32tex/tex-gyre.tar.xz
2021/01/18 | 4485396 | systems/win32/w32tex/texinfo-w32.tar.xz
2021/01/03 | 2050496 | systems/win32/w32tex/texinstwin.zip
@@ -279744,9 +279747,9 @@
2021/01/13 | 440824 | systems/win32/w32tex/win64/cweb-w64.tar.xz
2021/01/13 | 758912 | systems/win32/w32tex/win64/dvi2ps-w64.tar.xz
2021/01/13 | 448292 | systems/win32/w32tex/win64/dvi2tty-w64.tar.xz
-2021/01/17 | 807924 | systems/win32/w32tex/win64/dvipdfm-w64.tar.xz
+2021/01/22 | 808228 | systems/win32/w32tex/win64/dvipdfm-w64.tar.xz
2021/01/13 | 760100 | systems/win32/w32tex/win64/dvipsk-w64.tar.xz
-2021/01/13 | 2345592 | systems/win32/w32tex/win64/dvitools-w64.tar.xz
+2021/01/22 | 2372372 | systems/win32/w32tex/win64/dvitools-w64.tar.xz
2021/01/03 | 1090564 | systems/win32/w32tex/win64/extractpdfmark-w64.tar.xz
2020/12/05 | 305192 | systems/win32/w32tex/win64/gregorio-w64.tar.xz
2021/01/13 | 588044 | systems/win32/w32tex/win64/jtex-w64.tar.xz
@@ -279769,7 +279772,7 @@
2020/03/20 | 557532 | systems/win32/w32tex/win64/pmx-w64.tar.xz
2020/12/05 | 791172 | systems/win32/w32tex/win64/pstoedit-w64.tar.xz
2021/01/13 | 386240 | systems/win32/w32tex/win64/psutils-w64.tar.xz
-2021/01/17 | 1714200 | systems/win32/w32tex/win64/ptex-ng-w64.tar.xz
+2021/01/22 | 1713584 | systems/win32/w32tex/win64/ptex-ng-w64.tar.xz
2021/01/13 | 1871404 | systems/win32/w32tex/win64/ptex-w64.tar.xz
2021/01/03 | 329592 | systems/win32/w32tex/win64/sam2p-w64.tar.xz
2020/10/31 | 40588 | systems/win32/w32tex/win64/t1utils-w64.tar.xz
@@ -279780,8 +279783,8 @@
2020/01/18 | 42768 | systems/win32/w32tex/win64/txtutil-w64.tar.xz
2021/01/13 | 1805768 | systems/win32/w32tex/win64/uptex-w64.tar.xz
2021/01/13 | 3383744 | systems/win32/w32tex/win64/web2c-w64.tar.xz
-2021/01/17 | 11083796 | systems/win32/w32tex/win64/xetex-w64.tar.xz
-2021/01/17 | 49060520 | systems/win32/w32tex/xetex-w32.tar.xz
+2021/01/22 | 11077840 | systems/win32/w32tex/win64/xetex-w64.tar.xz
+2021/01/22 | 49057224 | systems/win32/w32tex/xetex-w32.tar.xz
2020/05/29 | 2936068 | systems/win32/w32tex/xindy-w32.tar.xz
2013/11/19 | 11356248 | systems/win32/w32tex/xymtex.tar.xz
2016/09/09 | 4334636 | systems/win32/w32tex/xypic.tar.xz
@@ -279878,7 +279881,7 @@
2004/06/04 | 404 | tds/tds.sed
2004/06/23 | 65418 | tds/tds.tex
2019/05/29 | 304264 | tds.zip
-2021/01/23 | 186 | timestamp
+2021/01/24 | 186 | timestamp
2002/08/26 | 61898 | usergrps/dante/antrag.pdf
2002/08/26 | 118217 | usergrps/dante/antrag.ps
2017/06/30 | 917 | usergrps/dante/dtk/doc/beispiel.bib
diff --git a/FILES.byname.gz b/FILES.byname.gz
index 59283e933d..e5c72ac491 100644
--- a/FILES.byname.gz
+++ b/FILES.byname.gz
Binary files differ
diff --git a/FILES.last07days b/FILES.last07days
index 40a8061749..0ff29e8fe1 100644
--- a/FILES.last07days
+++ b/FILES.last07days
@@ -1,298 +1,357 @@
-2021/01/22 | 99605 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma
-2021/01/22 | 99483 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
+2021/01/23 | 99607 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma
+2021/01/23 | 99483 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
+2021/01/23 | 97403 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma
+2021/01/23 | 97121 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma
+2021/01/23 | 969229 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma
+2021/01/23 | 964621 | support/xml2pmx.zip
+2021/01/23 | 94802 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma
+2021/01/23 | 94787 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma
+2021/01/23 | 94597 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
+2021/01/23 | 94376 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma
+2021/01/23 | 9063 | macros/latex/contrib/fnpct/fnpct-manual.cls
+2021/01/23 | 8787669 | fonts/newcomputermodern.zip
+2021/01/23 | 87769 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
+2021/01/23 | 8773 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
+2021/01/23 | 87638 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma
+2021/01/23 | 859 | systems/win32/miktex/tm/packages/pr.ini
+2021/01/23 | 85304 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma
+2021/01/23 | 8522 | support/xml2pmx/doc/Readme.XML2PMX
+2021/01/23 | 813998 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
+2021/01/23 | 80639 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
+2021/01/23 | 78748 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma
+2021/01/23 | 77839 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
+2021/01/23 | 7747 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma
+2021/01/23 | 77429 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
+2021/01/23 | 75341 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
+2021/01/23 | 745675 | macros/latex/contrib/eqexam/doc/eqexam.pdf
+2021/01/23 | 74157 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
+2021/01/23 | 740141 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma
+2021/01/23 | 73321 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma
+2021/01/23 | 72843 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
+2021/01/23 | 71967 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
+2021/01/23 | 71575 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma
+2021/01/23 | 70425 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
+2021/01/23 | 70203 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
+2021/01/23 | 680060 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
+2021/01/23 | 67914 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma
+2021/01/23 | 67684 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma
+2021/01/23 | 67496 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma
+2021/01/23 | 67355 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma
+2021/01/23 | 671573 | macros/latex/contrib/eqexam/doc/eqexamman.pdf
+2021/01/23 | 65815 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma
+2021/01/23 | 65322 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
+2021/01/23 | 63928 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma
+2021/01/23 | 63832 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma
+2021/01/23 | 63764 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma
+2021/01/23 | 62741 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
+2021/01/23 | 624931 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma
+2021/01/23 | 62082 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
+2021/01/23 | 619144 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
+2021/01/23 | 60606 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma
+2021/01/23 | 59809 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
+2021/01/23 | 596721 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
+2021/01/23 | 59144 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
+2021/01/23 | 583740 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma
+2021/01/23 | 57610 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
+2021/01/23 | 56978 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma
+2021/01/23 | 568172 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
+2021/01/23 | 56599 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
+2021/01/23 | 56454 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
+2021/01/23 | 563841 | systems/win32/miktex/tm/packages/next/files.csv.lzma
+2021/01/23 | 563347 | systems/win32/miktex/tm/packages/files.csv.lzma
+2021/01/23 | 56326 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma
+2021/01/23 | 55852 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma
+2021/01/23 | 55374 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma
+2021/01/23 | 5521364 | systems/texlive/tlnet/install-tl-unx.tar.gz
+2021/01/23 | 531715 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma
+2021/01/23 | 52496 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma
+2021/01/23 | 52400 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
+2021/01/23 | 52057 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
+2021/01/23 | 51863 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
+2021/01/23 | 51410 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma
+2021/01/23 | 514088 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
+2021/01/23 | 51184 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
+2021/01/23 | 50703 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma
+2021/01/23 | 50032 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma
+2021/01/23 | 492235 | macros/latex/contrib/fnpct.zip
+2021/01/23 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
+2021/01/23 | 484326 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma
+2021/01/23 | 47904 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
+2021/01/23 | 475818 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma
+2021/01/23 | 472808 | macros/latex/contrib/fnpct/fnpct-manual.pdf
+2021/01/23 | 46958 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
+2021/01/23 | 46493 | macros/latex/contrib/fnpct/fnpct.sty
+2021/01/23 | 461384 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
+2021/01/23 | 45899 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma
+2021/01/23 | 45636 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma
+2021/01/23 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
+2021/01/23 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
+2021/01/23 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
+2021/01/23 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
+2021/01/23 | 45270 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
+2021/01/23 | 450898 | support/xml2pmx/sources/xml2pmx-2021-01-23.tar.gz
+2021/01/23 | 43563 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma
+2021/01/23 | 43385 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
+2021/01/23 | 43071 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma
+2021/01/23 | 42872 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma
+2021/01/23 | 42663 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
+2021/01/23 | 42551 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
+2021/01/23 | 42399 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma
+2021/01/23 | 4160 | macros/latex/contrib/eqexam/README.md
+2021/01/23 | 413756 | macros/latex/contrib/eqexam/eqexam.dtx
+2021/01/23 | 40964 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma
+2021/01/23 | 40230 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
+2021/01/23 | 39536 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma
+2021/01/23 | 392681 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
+2021/01/23 | 388 | systems/texlive/tlnet/archive/texlive-docindex.r57494.tar.xz
+2021/01/23 | 38069 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma
+2021/01/23 | 38059 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma
+2021/01/23 | 37310 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
+2021/01/23 | 37250 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
+2021/01/23 | 3707422 | macros/latex/contrib/eqexam.zip
+2021/01/23 | 36677 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
+2021/01/23 | 35425 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma
+2021/01/23 | 35065 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
+2021/01/23 | 3493 | support/xml2pmx/README
+2021/01/23 | 345230 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
+2021/01/23 | 34305 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
+2021/01/23 | 33532 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma
+2021/01/23 | 33141 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
+2021/01/23 | 329919 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma
+2021/01/23 | 32545 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma
+2021/01/23 | 320797 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
+2021/01/23 | 31550 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma
+2021/01/23 | 31542 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
+2021/01/23 | 31345 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
+2021/01/23 | 313412 | support/xml2pmx/Windows/xml2pmx.exe
+2021/01/23 | 31227 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma
+2021/01/23 | 310963 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma
+2021/01/23 | 30884 | systems/texlive/tlnet/archive/moderncv.r57496.tar.xz
+2021/01/23 | 30874 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
+2021/01/23 | 30031 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
+2021/01/23 | 295623 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
+2021/01/23 | 29513 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma
+2021/01/23 | 29023 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma
+2021/01/23 | 283982 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
+2021/01/23 | 28229 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma
+2021/01/23 | 281361 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma
+2021/01/23 | 28007 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
+2021/01/23 | 27462 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma
+2021/01/23 | 27440 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
+2021/01/23 | 27216 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma
+2021/01/23 | 27204 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma
+2021/01/23 | 26595 | macros/latex/contrib/fnpct/fnpct-manual.tex
+2021/01/23 | 2617421 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
+2021/01/23 | 258630 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma
+2021/01/23 | 254184 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
+2021/01/23 | 25333 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma
+2021/01/23 | 25128 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma
+2021/01/23 | 25039 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
+2021/01/23 | 250203 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma
+2021/01/23 | 2495614 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma
+2021/01/23 | 245668 | systems/texlive/tlnet/archive/moderncv.doc.r57496.tar.xz
+2021/01/23 | 243510 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
+2021/01/23 | 24288833 | systems/texlive/tlnet/install-tl.zip
+2021/01/23 | 23881 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
+2021/01/23 | 23312 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
+2021/01/23 | 231666 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma
+2021/01/23 | 227607 | macros/latex/contrib/eqexam/doc/eqexamman.tex
+2021/01/23 | 2274796 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+2021/01/23 | 22044 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma
+2021/01/23 | 213737 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
+2021/01/23 | 21129 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma
+2021/01/23 | 210931 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
+2021/01/23 | 208089 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma
+2021/01/23 | 206572 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
+2021/01/23 | 206528 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
+2021/01/23 | 202648 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
+2021/01/23 | 20119 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma
+2021/01/23 | 2002725 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
+2021/01/23 | 199584 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma
+2021/01/23 | 1985 | macros/latex/contrib/eqexam/examples/test_matching.tex
+2021/01/23 | 198079 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma
+2021/01/23 | 195674 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
+2021/01/23 | 195626 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma
+2021/01/23 | 19418708 | systems/texlive/tlnet/install-tl-windows.exe
+2021/01/23 | 193758 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma
+2021/01/23 | 18107 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
+2021/01/23 | 180158 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
+2021/01/23 | 17958 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
+2021/01/23 | 179467 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma
+2021/01/23 | 17546 | support/xml2pmx/doc/xml2pmx.pdf
+2021/01/23 | 172040 | systems/texlive/tlnet/archive/texlive-docindex.doc.r57494.tar.xz
+2021/01/23 | 17002697 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
+2021/01/23 | 1685633 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma
+2021/01/23 | 167737 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
+2021/01/23 | 163795 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
+2021/01/23 | 16339 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma
+2021/01/23 | 16111 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma
+2021/01/23 | 159864 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
+2021/01/23 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
+2021/01/23 | 153807 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma
+2021/01/23 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
+2021/01/23 | 152746 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
+2021/01/23 | 1509137 | graphics/pgf/contrib/spath3.zip
+2021/01/23 | 1488 | macros/latex/contrib/fnpct/README
+2021/01/23 | 147188 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma
+2021/01/23 | 147085 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma
+2021/01/23 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
+2021/01/23 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
+2021/01/23 | 14342 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
+2021/01/23 | 1421909 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
+2021/01/23 | 1417675 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
+2021/01/23 | 139408 | support/xml2pmx/MacOS/xml2pmx
+2021/01/23 | 1367 | support/xml2pmx/doc/xml2pmx.1
+2021/01/23 | 136346 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
+2021/01/23 | 135010 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma
+2021/01/23 | 13466 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma
+2021/01/23 | 131490 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
+2021/01/23 | 1307387 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
+2021/01/23 | 1291601 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma
+2021/01/23 | 1281721 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma
+2021/01/23 | 124938 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma
+2021/01/23 | 1247391 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
+2021/01/23 | 1247153 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
+2021/01/23 | 12202 | macros/latex/contrib/eqexam/examples/test01.tex
+2021/01/23 | 1171817 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma
+2021/01/23 | 116935 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma
+2021/01/23 | 1165022 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
+2021/01/23 | 1164868 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
+2021/01/23 | 116251 | macros/latex/contrib/eqexam/examples/test01.pdf
+2021/01/23 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini
+2021/01/23 | 113936 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
+2021/01/23 | 112281 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
+2021/01/23 | 11038 | macros/latex/contrib/eqexam/examples/fig1.pdf
+2021/01/23 | 109149 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
+2021/01/23 | 1078966 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
+2021/01/23 | 104761 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
+2021/01/23 | 1034990 | graphics/pgf/contrib/penrose.zip
+2021/01/23 | 103331 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
+2021/01/23 | 101859 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
2021/01/22 | 987217 | macros/latex/contrib/acrotex/doc/eformman.pdf
2021/01/22 | 985 | macros/latex/contrib/moderncv/KNOWN_BUGS
-2021/01/22 | 97403 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma
-2021/01/22 | 97121 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma
-2021/01/22 | 969230 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma
+2021/01/22 | 98018 | graphics/pgf/contrib/penrose/penrose_code.dtx
+2021/01/22 | 9788 | fonts/newcomputermodern/README
2021/01/22 | 9637 | macros/latex/contrib/moderncv/moderncvheadii.sty
2021/01/22 | 9624 | systems/texlive/tlnet/archive/teubner.r57486.tar.xz
-2021/01/22 | 94803 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma
-2021/01/22 | 94788 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma
-2021/01/22 | 94598 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
2021/01/22 | 945692 | systems/win32/miktex/tm/packages/tkz-berge.tar.lzma
-2021/01/22 | 94377 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma
2021/01/22 | 9379 | macros/latex/contrib/moderncv/moderncvbodyv.sty
2021/01/22 | 926 | macros/latex/contrib/moderncv/README.md
2021/01/22 | 9266 | macros/latex/contrib/moderncv/moderncvheadiv.sty
2021/01/22 | 924656 | systems/texlive/tlnet/archive/tkz-berge.doc.r57485.tar.xz
2021/01/22 | 912973 | systems/win32/miktex/tm/packages/achemso.tar.lzma
2021/01/22 | 903444 | systems/texlive/tlnet/archive/tex4ht.r57492.tar.xz
+2021/01/22 | 89179804 | systems/win32/w32tex/pgfcontrib.tar.xz
2021/01/22 | 8854 | macros/latex/contrib/moderncv/moderncvheadi.sty
-2021/01/22 | 87770 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
-2021/01/22 | 8774 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
-2021/01/22 | 87637 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma
-2021/01/22 | 859 | systems/win32/miktex/tm/packages/pr.ini
-2021/01/22 | 85302 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma
2021/01/22 | 8444 | systems/texlive/tlnet/archive/tkz-berge.r57485.tar.xz
2021/01/22 | 8316 | systems/texlive/tlnet/archive/matapli.r57491.tar.xz
2021/01/22 | 823 | macros/latex/contrib/moderncv/publications.bib
2021/01/22 | 8224 | macros/latex/contrib/moderncv/moderncvheadvi.sty
-2021/01/22 | 813997 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
2021/01/22 | 810838 | systems/win32/miktex/tm/packages/chemnum.tar.lzma
-2021/01/22 | 80638 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
+2021/01/22 | 808228 | systems/win32/w32tex/win64/dvipdfm-w64.tar.xz
2021/01/22 | 794728 | systems/texlive/tlnet/archive/chemnum.doc.r57490.tar.xz
-2021/01/22 | 78748 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma
-2021/01/22 | 77839 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
-2021/01/22 | 7747 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma
2021/01/22 | 7746 | macros/latex/contrib/moderncv/moderncvheadv.sty
-2021/01/22 | 77430 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
+2021/01/22 | 771857 | systems/win32/w32tex/ChangeLog
2021/01/22 | 7650885 | systems/win32/miktex/tm/packages/mlmodern.tar.lzma
2021/01/22 | 7637 | macros/latex/contrib/moderncv/moderncvheadiii.sty
-2021/01/22 | 75340 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
2021/01/22 | 7507 | macros/latex/contrib/moderncv/moderncvbodyi.sty
-2021/01/22 | 74156 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
-2021/01/22 | 740140 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma
-2021/01/22 | 73323 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma
2021/01/22 | 729900 | systems/texlive/tlnet/archive/translation-biblatex-de.doc.r57483.tar.xz
-2021/01/22 | 72842 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
2021/01/22 | 7220 | macros/latex/contrib/moderncv/moderncvbodyiv.sty
-2021/01/22 | 71966 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
-2021/01/22 | 71575 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma
-2021/01/22 | 70424 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
-2021/01/22 | 70202 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
2021/01/22 | 6911 | macros/latex/contrib/moderncv/moderncvfooti.sty
2021/01/22 | 69080 | macros/latex/contrib/moderncv/moderncvskillmatrix.sty
-2021/01/22 | 680061 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
-2021/01/22 | 67915 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma
-2021/01/22 | 67685 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma
-2021/01/22 | 67495 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma
-2021/01/22 | 67356 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma
-2021/01/22 | 65816 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma
-2021/01/22 | 65322 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
-2021/01/22 | 63927 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma
-2021/01/22 | 63831 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma
-2021/01/22 | 63762 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma
+2021/01/22 | 6620976 | systems/win32/w32tex/ptex-ng-w32.tar.xz
+2021/01/22 | 65967 | macros/latex/contrib/eqexam/eqexam.def
2021/01/22 | 6367118 | systems/win32/miktex/tm/packages/newcomputermodern.tar.lzma
-2021/01/22 | 62740 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
-2021/01/22 | 624932 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma
2021/01/22 | 6216 | systems/texlive/tlnet/archive/tkz-graph.r57484.tar.xz
-2021/01/22 | 62078 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
-2021/01/22 | 619142 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
-2021/01/22 | 60606 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma
-2021/01/22 | 59807 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
2021/01/22 | 596 | systems/texlive/tlnet/archive/collection-langfrench.r57491.tar.xz
-2021/01/22 | 596722 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
2021/01/22 | 59416 | macros/latex/contrib/moderncv/picture.eps
-2021/01/22 | 59144 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
+2021/01/22 | 5931 | macros/latex/contrib/eqexam/aebrandom.def
2021/01/22 | 586743 | systems/win32/miktex/tm/packages/ms.tar.lzma
-2021/01/22 | 583738 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma
2021/01/22 | 578022 | macros/latex/contrib/acrotex/exerquiz.dtx
-2021/01/22 | 57610 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
-2021/01/22 | 56977 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma
-2021/01/22 | 568174 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
-2021/01/22 | 56598 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
-2021/01/22 | 56455 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
-2021/01/22 | 563841 | systems/win32/miktex/tm/packages/next/files.csv.lzma
-2021/01/22 | 563347 | systems/win32/miktex/tm/packages/files.csv.lzma
-2021/01/22 | 56324 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma
-2021/01/22 | 55851 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma
2021/01/22 | 5580 | systems/texlive/tlnet/archive/everysel.source.r57489.tar.xz
-2021/01/22 | 55373 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma
-2021/01/22 | 5521100 | systems/texlive/tlnet/install-tl-unx.tar.gz
+2021/01/22 | 557513 | graphics/pgf/contrib/penrose/penrose.pdf
2021/01/22 | 54768 | systems/texlive/tlnet/archive/reledmac.r57487.tar.xz
+2021/01/22 | 547140 | graphics/pgf/contrib/spath3/spath3_code.pdf
2021/01/22 | 542032 | systems/win32/miktex/tm/packages/easybook.tar.lzma
-2021/01/22 | 531716 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma
2021/01/22 | 52722 | systems/win32/miktex/tm/packages/chhaya.tar.lzma
2021/01/22 | 525403 | macros/latex/contrib/acrotex/doc/aeb_man.tex
-2021/01/22 | 52498 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma
-2021/01/22 | 52401 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
+2021/01/22 | 523 | graphics/pgf/contrib/spath3/README
2021/01/22 | 521097 | systems/win32/miktex/tm/packages/translations.tar.lzma
-2021/01/22 | 52056 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
-2021/01/22 | 51861 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
-2021/01/22 | 51409 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma
-2021/01/22 | 514082 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
-2021/01/22 | 51184 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
-2021/01/22 | 50704 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma
-2021/01/22 | 50030 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma
2021/01/22 | 494990 | macros/latex/contrib/acrotex/examples/webeqtst.pdf
-2021/01/22 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
-2021/01/22 | 484329 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma
-2021/01/22 | 47902 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
+2021/01/22 | 49057224 | systems/win32/w32tex/xetex-w32.tar.xz
2021/01/22 | 4778181 | systems/win32/miktex/tm/packages/matapli.tar.lzma
-2021/01/22 | 475816 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma
2021/01/22 | 4744452 | systems/texlive/tlnet/archive/matapli.doc.r57491.tar.xz
-2021/01/22 | 46959 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
-2021/01/22 | 461384 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
-2021/01/22 | 45899 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma
-2021/01/22 | 45636 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma
-2021/01/22 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
-2021/01/22 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
-2021/01/22 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
-2021/01/22 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
-2021/01/22 | 45270 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
+2021/01/22 | 472 | graphics/pgf/contrib/penrose/README
+2021/01/22 | 4662260 | systems/win32/w32tex/dvipdfm-w32.tar.xz
+2021/01/22 | 464179 | graphics/pgf/contrib/penrose/penrose_code.pdf
2021/01/22 | 451997 | systems/win32/miktex/tm/packages/everysel.tar.lzma
2021/01/22 | 4495 | macros/latex/contrib/acrotex/README.md
2021/01/22 | 4486 | macros/latex/contrib/moderncv/moderncvcompatibility.sty
2021/01/22 | 442272 | systems/texlive/tlnet/archive/everysel.doc.r57489.tar.xz
-2021/01/22 | 43563 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma
-2021/01/22 | 43384 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
-2021/01/22 | 43072 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma
-2021/01/22 | 42871 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma
-2021/01/22 | 42663 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
-2021/01/22 | 42550 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
-2021/01/22 | 42398 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma
-2021/01/22 | 40962 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma
2021/01/22 | 40432 | systems/texlive/tlnet/archive/teubner.source.r57486.tar.xz
-2021/01/22 | 40230 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
-2021/01/22 | 39537 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma
-2021/01/22 | 392682 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
-2021/01/22 | 388 | systems/texlive/tlnet/archive/texlive-docindex.r57481.tar.xz
2021/01/22 | 380 | systems/texlive/tlnet/archive/translation-biblatex-de.r57483.tar.xz
-2021/01/22 | 38071 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma
-2021/01/22 | 38058 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma
-2021/01/22 | 37310 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
-2021/01/22 | 37251 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
-2021/01/22 | 36677 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
-2021/01/22 | 35424 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma
-2021/01/22 | 35065 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
-2021/01/22 | 345230 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
2021/01/22 | 3444 | macros/latex/contrib/moderncv/moderncvcollection.sty
-2021/01/22 | 34305 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
2021/01/22 | 34085 | macros/latex/contrib/moderncv/moderncv.cls
-2021/01/22 | 33533 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma
+2021/01/22 | 33954220 | systems/win32/w32tex/ltxpkgs.tar.xz
+2021/01/22 | 337099 | graphics/pgf/contrib/spath3/spath3.pdf
2021/01/22 | 335074 | macros/latex/contrib/moderncv.zip
2021/01/22 | 3348384 | systems/win32/miktex/tm/packages/logix.tar.lzma
2021/01/22 | 332159 | systems/win32/miktex/tm/packages/tkz-graph.tar.lzma
-2021/01/22 | 33143 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
-2021/01/22 | 329920 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma
2021/01/22 | 3270783 | macros/latex/contrib/acrotex.zip
-2021/01/22 | 32544 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma
2021/01/22 | 325056 | systems/texlive/tlnet/archive/tkz-graph.doc.r57484.tar.xz
2021/01/22 | 3211 | macros/latex/contrib/moderncv/moderncviconsawesome.sty
-2021/01/22 | 320795 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
2021/01/22 | 320611 | macros/latex/contrib/moderncv/manual/moderncv_userguide.pdf
-2021/01/22 | 31549 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma
-2021/01/22 | 31542 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
2021/01/22 | 3146 | macros/latex/contrib/moderncv/moderncviconsletters.sty
-2021/01/22 | 31346 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
-2021/01/22 | 31227 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma
-2021/01/22 | 310963 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma
-2021/01/22 | 30873 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
2021/01/22 | 3064222 | systems/win32/miktex/tm/packages/stickstoo.tar.lzma
-2021/01/22 | 30030 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
2021/01/22 | 2989 | macros/latex/contrib/moderncv/moderncvstylebanking.sty
-2021/01/22 | 295621 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
-2021/01/22 | 29511 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma
-2021/01/22 | 29024 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma
2021/01/22 | 2892388 | systems/win32/miktex/tm/packages/erewhon.tar.lzma
-2021/01/22 | 283982 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
-2021/01/22 | 28230 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma
-2021/01/22 | 281359 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma
-2021/01/22 | 28006 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
-2021/01/22 | 27462 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma
-2021/01/22 | 27441 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
-2021/01/22 | 27217 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma
-2021/01/22 | 27204 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma
-2021/01/22 | 2617419 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
-2021/01/22 | 258631 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma
-2021/01/22 | 254185 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
-2021/01/22 | 25330 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma
-2021/01/22 | 25128 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma
-2021/01/22 | 25038 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
-2021/01/22 | 250205 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma
-2021/01/22 | 2495615 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma
-2021/01/22 | 243510 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
-2021/01/22 | 24288833 | systems/texlive/tlnet/install-tl.zip
+2021/01/22 | 2653880 | systems/win32/w32tex/dvitools-w32.tar.xz
+2021/01/22 | 26060 | graphics/pgf/contrib/penrose/penrose.tex
+2021/01/22 | 2598408 | systems/win32/w32tex/tex4htk-w32.tar.xz
2021/01/22 | 2401742 | systems/win32/miktex/tm/packages/profcollege.tar.lzma
-2021/01/22 | 23880 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
2021/01/22 | 2380 | systems/texlive/tlnet/archive/everysel.r57489.tar.xz
-2021/01/22 | 23313 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
-2021/01/22 | 231665 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma
+2021/01/22 | 2372372 | systems/win32/w32tex/win64/dvitools-w64.tar.xz
2021/01/22 | 22844 | systems/win32/miktex/tm/packages/miktex-misc.tar.lzma
-2021/01/22 | 2275392 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
-2021/01/22 | 22043 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma
2021/01/22 | 218820 | systems/texlive/tlnet/archive/texlive-scripts.doc.r57482.tar.xz
-2021/01/22 | 213738 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
+2021/01/22 | 21745 | graphics/pgf/contrib/spath3/spath3.tex
2021/01/22 | 2134 | macros/latex/contrib/moderncv/moderncvstyleoldstyle.sty
-2021/01/22 | 21130 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma
2021/01/22 | 2112 | macros/latex/contrib/moderncv/moderncvstylecasual.sty
-2021/01/22 | 210931 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
2021/01/22 | 2098 | macros/latex/contrib/moderncv/moderncvstyleclassic.sty
2021/01/22 | 208914 | systems/win32/miktex/tm/packages/aalok.tar.lzma
-2021/01/22 | 208087 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma
2021/01/22 | 2079 | macros/latex/contrib/moderncv/moderncvdebugtools.sty
2021/01/22 | 207660 | systems/texlive/tlnet/archive/reledmac.source.r57487.tar.xz
-2021/01/22 | 206591 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
-2021/01/22 | 206582 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
-2021/01/22 | 202648 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
2021/01/22 | 2019 | macros/latex/contrib/moderncv/tweaklist.sty
2021/01/22 | 20137 | macros/latex/contrib/moderncv/CHANGELOG
-2021/01/22 | 20119 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma
2021/01/22 | 2003044 | systems/win32/miktex/tm/packages/biblatex-oxref.tar.lzma
-2021/01/22 | 2002727 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
-2021/01/22 | 199584 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma
-2021/01/22 | 198080 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma
-2021/01/22 | 195675 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
-2021/01/22 | 195626 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma
+2021/01/22 | 197284 | graphics/pgf/contrib/spath3/spath3_code.dtx
2021/01/22 | 1942411 | systems/win32/miktex/tm/packages/cascadia-code.tar.lzma
-2021/01/22 | 19418739 | systems/texlive/tlnet/install-tl-windows.exe
-2021/01/22 | 193759 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma
2021/01/22 | 19039 | macros/latex/contrib/moderncv/LICENSE.txt
2021/01/22 | 187818 | macros/latex/contrib/acrotex/doc/eformman.tex
-2021/01/22 | 18105 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
-2021/01/22 | 180158 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
-2021/01/22 | 17956 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
-2021/01/22 | 179468 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma
2021/01/22 | 1784355 | systems/win32/miktex/tm/packages/asmeconf.tar.lzma
2021/01/22 | 1759 | macros/latex/contrib/moderncv/moderncvstylefancy.sty
-2021/01/22 | 171652 | systems/texlive/tlnet/archive/texlive-docindex.doc.r57481.tar.xz
-2021/01/22 | 17003360 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
-2021/01/22 | 1685633 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma
-2021/01/22 | 167737 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
+2021/01/22 | 1713584 | systems/win32/w32tex/win64/ptex-ng-w64.tar.xz
2021/01/22 | 1645 | macros/latex/contrib/moderncv/picture.jpg
-2021/01/22 | 163795 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
-2021/01/22 | 16339 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma
-2021/01/22 | 16111 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma
2021/01/22 | 1606946 | systems/win32/miktex/tm/packages/biblatex-gb7714-2015.tar.lzma
-2021/01/22 | 159864 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
2021/01/22 | 15831 | CTAN.sites
2021/01/22 | 15509 | macros/latex/contrib/moderncv/manual/moderncv_userguide.tex
-2021/01/22 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
-2021/01/22 | 153806 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma
-2021/01/22 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
-2021/01/22 | 152745 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
2021/01/22 | 15214 | macros/latex/contrib/moderncv/moderncviconsmarvosym.sty
2021/01/22 | 1499729 | macros/latex/contrib/acrotex/doc/aeb_man.pdf
-2021/01/22 | 147187 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma
2021/01/22 | 14716 | macros/latex/contrib/moderncv/template.tex
-2021/01/22 | 147086 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma
-2021/01/22 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
2021/01/22 | 145490 | systems/win32/miktex/tm/packages/luakeys.tar.lzma
2021/01/22 | 145040 | systems/win32/miktex/tm/packages/fancyvrb.tar.lzma
-2021/01/22 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
-2021/01/22 | 14343 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
-2021/01/22 | 1421908 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
2021/01/22 | 1419 | macros/latex/contrib/moderncv/moderncvstyleempty.sty
-2021/01/22 | 1417674 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
2021/01/22 | 1412 | systems/texlive/tlnet/archive/collection-pictures.r57485.tar.xz
-2021/01/22 | 136345 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
2021/01/22 | 136156 | systems/texlive/tlnet/archive/tex4ht.doc.r57492.tar.xz
2021/01/22 | 1357164 | systems/win32/miktex/tm/packages/circuitikz.tar.lzma
-2021/01/22 | 135012 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma
-2021/01/22 | 13465 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma
2021/01/22 | 132784 | systems/texlive/tlnet/archive/fancyvrb.doc.r57488.tar.xz
2021/01/22 | 132192 | systems/texlive/tlnet/archive/texlive-scripts.r57482.tar.xz
-2021/01/22 | 131490 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
-2021/01/22 | 1307385 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
-2021/01/22 | 1291598 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma
-2021/01/22 | 1281719 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma
-2021/01/22 | 124938 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma
-2021/01/22 | 1248023 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
-2021/01/22 | 1247592 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
+2021/01/22 | 119659630 | macros/context/latest/cont-tmf.zip
+2021/01/22 | 1186096 | fonts/newcomputermodern/NewCM10-Book.otf
2021/01/22 | 11720 | systems/texlive/tlnet/archive/fancyvrb.r57488.tar.xz
-2021/01/22 | 1171816 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma
-2021/01/22 | 116934 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma
-2021/01/22 | 1165147 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
-2021/01/22 | 1164992 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
-2021/01/22 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini
2021/01/22 | 11532 | systems/texlive/tlnet/archive/chemnum.r57490.tar.xz
-2021/01/22 | 113935 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
-2021/01/22 | 112280 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
2021/01/22 | 1117 | macros/latex/contrib/moderncv/moderncvcolorburgundy.sty
+2021/01/22 | 11077840 | systems/win32/w32tex/win64/xetex-w64.tar.xz
2021/01/22 | 1101323 | systems/win32/miktex/tm/packages/teubner.tar.lzma
-2021/01/22 | 109149 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
-2021/01/22 | 1078966 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
2021/01/22 | 1067 | macros/latex/contrib/moderncv/moderncvcolorpurple.sty
2021/01/22 | 1067 | macros/latex/contrib/moderncv/moderncvcolororange.sty
2021/01/22 | 1063 | macros/latex/contrib/moderncv/moderncvcolorblue.sty
@@ -301,12 +360,9 @@
2021/01/22 | 10536 | macros/latex/contrib/moderncv/moderncvbodyiii.sty
2021/01/22 | 1052 | macros/latex/contrib/moderncv/moderncvcolorred.sty
2021/01/22 | 1049744 | systems/texlive/tlnet/archive/teubner.doc.r57486.tar.xz
-2021/01/22 | 104758 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
2021/01/22 | 10473261 | systems/win32/miktex/tm/packages/reledmac.tar.lzma
2021/01/22 | 1040 | macros/latex/contrib/moderncv/moderncvcolorblack.sty
-2021/01/22 | 103331 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
2021/01/22 | 10210712 | systems/texlive/tlnet/archive/reledmac.doc.r57487.tar.xz
-2021/01/22 | 101859 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
2021/01/21 | 9989 | macros/latex/contrib/teubner/teubner.txt
2021/01/21 | 986567 | macros/latex/contrib/reledmac/reledpar.pdf
2021/01/21 | 90291 | macros/latex/contrib/teubner/teubner-doc.tex
@@ -315,7 +371,6 @@
2021/01/21 | 856653 | macros/latex/contrib/chemnum.zip
2021/01/21 | 775390 | macros/latex/contrib/matapli/doc/examples/couverture/CIMPA.png
2021/01/21 | 7716197 | macros/latex/contrib/matapli.zip
-2021/01/21 | 771169 | systems/win32/w32tex/ChangeLog
2021/01/21 | 750175 | info/translations/biblatex/de.zip
2021/01/21 | 74927 | macros/latex/contrib/chemnum/chemnum.sty
2021/01/21 | 69935 | macros/latex/contrib/matapli/doc/examples/couverture/couverture.jpg
@@ -341,7 +396,6 @@
2021/01/21 | 38176 | systems/mac/mactex/ExtrasFolder.pdf
2021/01/21 | 376372566 | systems/mac/mactex/MacTeXtras-20210121.zip
2021/01/21 | 357853 | macros/latex/contrib/reledmac/migration.pdf
-2021/01/21 | 33955984 | systems/win32/w32tex/ltxpkgs.tar.xz
2021/01/21 | 339431 | macros/latex/contrib/tkz/tkz-graph.zip
2021/01/21 | 33215 | macros/latex/contrib/matapli/tex/matapli.cls
2021/01/21 | 32053 | macros/latex/contrib/reledmac/examples/3-reledpar_pages_different_languages_lualatex.pdf
@@ -416,7 +470,6 @@
2021/01/21 | 1340 | macros/latex/contrib/chemnum/README
2021/01/21 | 13288024 | macros/latex/contrib/reledmac.zip
2021/01/21 | 1309 | macros/latex/contrib/matapli/doc/fond-doc.pdf
-2021/01/21 | 119657508 | macros/context/latest/cont-tmf.zip
2021/01/21 | 1173370 | macros/latex/contrib/matapli/doc/examples/couverture/couvertureModele.pdf
2021/01/21 | 1094424 | macros/latex/contrib/teubner.zip
2021/01/21 | 1065010 | macros/latex/contrib/tkz/tkz-berge.zip
@@ -428,7 +481,6 @@
2021/01/20 | 901 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-13-4-0.tex
2021/01/20 | 893802 | macros/latex/contrib/achemso.zip
2021/01/20 | 8902 | macros/latex/contrib/tkz/tkz-graph/doc/latex/TKZdoc-gr-vertex.tex
-2021/01/20 | 87939300 | systems/win32/w32tex/pgfcontrib.tar.xz
2021/01/20 | 810 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-13-2-0.tex
2021/01/20 | 802 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-3-3-0.tex
2021/01/20 | 797 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-2-4-0.tex
@@ -491,6 +543,7 @@
2021/01/20 | 339 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-25-8-0.tex
2021/01/20 | 339 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-25-7-0.tex
2021/01/20 | 336 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-26-10-0.tex
+2021/01/20 | 333450 | graphics/pgf/contrib/spath3/knots.pdf
2021/01/20 | 3327 | macros/latex/contrib/tkz/tkz-graph/doc/latex/TKZdoc-gr-edge.tex
2021/01/20 | 331 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-26-6-0.tex
2021/01/20 | 330 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-23-2-0.tex
@@ -532,6 +585,7 @@
2021/01/20 | 273 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-3-2-0.tex
2021/01/20 | 273 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-1-3-0.tex
2021/01/20 | 269 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-21-1-0.tex
+2021/01/20 | 259679 | graphics/pgf/contrib/spath3/calligraphy.pdf
2021/01/20 | 255 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-23-6-0.tex
2021/01/20 | 254 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-22-1-0.tex
2021/01/20 | 254 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-10-1-0.tex
@@ -546,6 +600,7 @@
2021/01/20 | 235 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-6-1-0.tex
2021/01/20 | 23512 | macros/latex/contrib/tkz/tkz-graph/doc/latex/TKZdoc-gr-style.tex
2021/01/20 | 231 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-11-1-0.tex
+2021/01/20 | 23129 | graphics/pgf/contrib/spath3/knots.tex
2021/01/20 | 230 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-17-2-0.tex
2021/01/20 | 229 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-26-5-0.tex
2021/01/20 | 229 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-15-1-0.tex
@@ -563,6 +618,7 @@
2021/01/20 | 1800 | macros/latex/contrib/tkz/tkz-graph/README.md
2021/01/20 | 1798 | macros/latex/contrib/fancyvrb/README
2021/01/20 | 1777 | macros/latex/contrib/tkz/tkz-berge/NamedGraphs/examples/latex/tkzNamed-27-2-0.tex
+2021/01/20 | 16415 | graphics/pgf/contrib/spath3/calligraphy.tex
2021/01/20 | 16202 | macros/latex/contrib/achemso/achemso-demo.tex
2021/01/20 | 16059 | macros/latex/contrib/everysel/everysel.dtx
2021/01/20 | 1565 | macros/latex/contrib/everysel/everysel.ins
@@ -804,7 +860,6 @@
2021/01/18 | 9884 | fonts/erewhon/tfm/Erewhon-RegularSlanted-tlf-t2b.tfm
2021/01/18 | 98491 | fonts/mlmodern/type1/mlmssqbo8.pfb
2021/01/18 | 98269 | fonts/mlmodern/type1/mlmssqo8.pfb
-2021/01/18 | 9788 | fonts/newcomputermodern/README
2021/01/18 | 97574 | fonts/mlmodern/type1/mlmvtlo10.pfb
2021/01/18 | 9720 | fonts/erewhon/tfm/Erewhon-Regular-osf-t2b.tfm
2021/01/18 | 9720 | fonts/erewhon/tfm/Erewhon-Regular-lf-t2b.tfm
@@ -884,7 +939,6 @@
2021/01/18 | 8796 | fonts/erewhon/tfm/Erewhon-BoldSlanted-osf-t1.tfm
2021/01/18 | 87967 | fonts/mlmodern/type1/mlmtti10.pfb
2021/01/18 | 8788 | fonts/erewhon/tfm/Erewhon-Italic-lf-t1.tfm
-2021/01/18 | 8787673 | fonts/newcomputermodern.zip
2021/01/18 | 87858 | fonts/mlmodern/type1/mlmssqbx8.pfb
2021/01/18 | 8784 | fonts/erewhon/tfm/Erewhon-Italic-osf-t1.tfm
2021/01/18 | 8780 | fonts/erewhon/tfm/Erewhon-BoldSlanted-lf-t1.tfm
@@ -1892,13 +1946,11 @@
2021/01/17 | 8229 | fonts/logix/README
2021/01/17 | 816 | macros/latex/contrib/reledmac/examples/makefile
2021/01/17 | 814968 | systems/win32/miktex/tm/packages/miktex-pdftex-bin-x64-2.9.tar.lzma
-2021/01/17 | 807924 | systems/win32/w32tex/win64/dvipdfm-w64.tar.xz
2021/01/17 | 7984943 | systems/texlive/tlnet/update-tlmgr-r57424.sh
2021/01/17 | 746079 | systems/win32/miktex/tm/packages/miktex-pdftex-bin-2.9.tar.lzma
2021/01/17 | 7292 | systems/texlive/tlnet/archive/luaotfload.source.r57443.tar.xz
2021/01/17 | 6806 | macros/latex/contrib/reledmac/examples/2-footnote_spacing.tex
2021/01/17 | 6804 | macros/latex/contrib/profcollege/metapost/PfC-Svgnames.mp
-2021/01/17 | 6622444 | systems/win32/w32tex/ptex-ng-w32.tar.xz
2021/01/17 | 6540 | macros/latex/contrib/reledmac/examples/4-reledpar_pages_notes_leftpage.tex
2021/01/17 | 627576 | systems/texlive/tlnet/archive/luaotfload.doc.r57443.tar.xz
2021/01/17 | 5998 | macros/latex/contrib/translations/dicts/translations-basic-dictionary-brazil.trsl
@@ -1916,11 +1968,9 @@
2021/01/17 | 5161 | macros/latex/contrib/reledmac/examples/2-one_series_per_pstart.tex
2021/01/17 | 49 | macros/latex/contrib/reledmac/examples/latexmkrc
2021/01/17 | 496826 | macros/latex/contrib/translations/translations_en.pdf
-2021/01/17 | 49060520 | systems/win32/w32tex/xetex-w32.tar.xz
2021/01/17 | 4893441 | fonts/logix/source/logix.vfc
2021/01/17 | 4842977 | systems/win32/miktex/tm/packages/nunito.tar.lzma
2021/01/17 | 4748 | fonts/logix/CHANGELOG
-2021/01/17 | 4662768 | systems/win32/w32tex/dvipdfm-w32.tar.xz
2021/01/17 | 4645 | macros/latex/contrib/reledmac/doc-more/page-typesetting-columns.tex
2021/01/17 | 455 | systems/texlive/tlnet/update-tlmgr-r57424.sh.sha512.asc
2021/01/17 | 455 | systems/texlive/tlnet/update-tlmgr-r57424.exe.sha512.asc
@@ -1992,7 +2042,6 @@
2021/01/17 | 18004 | macros/latex/contrib/profcollege/latex/PfC-EquationLaurent1.tex
2021/01/17 | 1776 | macros/latex/contrib/reledmac/examples/2-glossaries.tex
2021/01/17 | 1718299 | systems/win32/miktex/tm/packages/miktex-luatex-bin-2.9.tar.lzma
-2021/01/17 | 1714200 | systems/win32/w32tex/win64/ptex-ng-w64.tar.xz
2021/01/17 | 16 | macros/latex/contrib/reledmac/latexmkrc
2021/01/17 | 16 | macros/latex/contrib/reledmac/doc-more/latexmkrc
2021/01/17 | 1694 | macros/latex/contrib/translations/README
@@ -2027,418 +2076,4 @@
2021/01/17 | 1140 | macros/latex/contrib/reledmac/examples/2-lemma_disambigution.tex
2021/01/17 | 11391 | macros/latex/contrib/reledmac/examples/2-line_numbers_in_header.tex
2021/01/17 | 1115957 | systems/win32/miktex/tm/packages/luaotfload.tar.lzma
-2021/01/17 | 11083796 | systems/win32/w32tex/win64/xetex-w64.tar.xz
2021/01/17 | 10033 | macros/latex/contrib/reledmac/examples/4-reledpar_one_series_per_pstart.tex
-2021/01/16 | 99606 | systems/win32/miktex/tm/packages/miktex-epstopdf-bin-x64-2.9.tar.lzma
-2021/01/16 | 98948 | macros/luatex/generic/luaotfload/luaotfload-main.tex
-2021/01/16 | 9875 | macros/luatex/generic/luaotfload/fontloader-fonts-gbn.lua
-2021/01/16 | 98536 | systems/win32/miktex/tm/packages/miktex-texware-bin-2.9.tar.lzma
-2021/01/16 | 983 | macros/latex/contrib/acro/examples/acro.example.issue-119.tex
-2021/01/16 | 97287 | systems/win32/miktex/tm/packages/miktex-gd-bin-2.9.tar.lzma
-2021/01/16 | 97099 | systems/win32/miktex/tm/packages/miktex-mfware-bin-2.9.tar.lzma
-2021/01/16 | 967680 | systems/win32/miktex/tm/packages/miktex-asymptote-bin-2.9.tar.lzma
-2021/01/16 | 96509 | systems/texlive/tlnet/tlpkg/translations/vi.po
-2021/01/16 | 964175 | macros/luatex/generic/luaotfload/fontloader-reference.lua
-2021/01/16 | 95781 | systems/texlive/tlnet/tlpkg/translations/de.po
-2021/01/16 | 9516 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-t1.tfm
-2021/01/16 | 94887 | systems/win32/miktex/tm/packages/miktex-gregorio-bin-2.9.tar.lzma
-2021/01/16 | 94797 | systems/win32/miktex/tm/packages/miktex-jpeg-bin-2.9.tar.lzma
-2021/01/16 | 94539 | systems/win32/miktex/tm/packages/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
-2021/01/16 | 94470 | macros/luatex/generic/luaotfload/fontloader-font-otr.lua
-2021/01/16 | 94458 | systems/texlive/tlnet/tlpkg/translations/sk.po
-2021/01/16 | 94269 | systems/win32/miktex/tm/packages/miktex-lua53-bin-2.9.tar.lzma
-2021/01/16 | 941 | fonts/alfaslabone/latex/TS1AlphaSlabOne-TLF.fd
-2021/01/16 | 941 | fonts/alfaslabone/latex/OT1AlphaSlabOne-TLF.fd
-2021/01/16 | 941 | fonts/alfaslabone/latex/OT1AlphaSlabOne-Sup.fd
-2021/01/16 | 941 | fonts/alfaslabone/latex/LY1AlphaSlabOne-TLF.fd
-2021/01/16 | 941 | fonts/alfaslabone/latex/LY1AlphaSlabOne-Sup.fd
-2021/01/16 | 935 | fonts/alfaslabone/README
-2021/01/16 | 935 | fonts/alfaslabone/latex/T1AlphaSlabOne-TLF.fd
-2021/01/16 | 935 | fonts/alfaslabone/latex/T1AlphaSlabOne-Sup.fd
-2021/01/16 | 93381 | systems/texlive/tlnet/tlpkg/translations/it.po
-2021/01/16 | 912 | macros/luatex/generic/luaotfload/fontloader-fonts-mis.lua
-2021/01/16 | 90063 | macros/luatex/generic/luaotfload/fontloader-font-cff.lua
-2021/01/16 | 889312 | macros/latex/contrib/acro/acro-manual.pdf
-2021/01/16 | 88665 | systems/texlive/tlnet/tlpkg/translations/pt_BR.po
-2021/01/16 | 8840 | macros/luatex/generic/luaotfload/luaotfload-loaders.lua
-2021/01/16 | 8778 | systems/win32/miktex/tm/packages/miktex-md5-bin-x64-2.9.tar.lzma
-2021/01/16 | 87763 | systems/win32/miktex/tm/packages/miktex-png-bin-x64-2.9.tar.lzma
-2021/01/16 | 87627 | systems/win32/miktex/tm/packages/miktex-epstopdf-bin-2.9.tar.lzma
-2021/01/16 | 87323 | systems/texlive/tlnet/tlpkg/translations/uk.po
-2021/01/16 | 87256 | systems/texlive/tlnet/tlpkg/translations/cs.po
-2021/01/16 | 863258 | macros/luatex/generic/luaotfload/fontloader-2021-01-07.lua
-2021/01/16 | 86294 | systems/texlive/tlnet/tlpkg/translations/es.po
-2021/01/16 | 8597 | macros/luatex/generic/luaotfload/filegraph.tex
-2021/01/16 | 8559 | macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf
-2021/01/16 | 85445 | systems/win32/miktex/tm/packages/miktex-bibtex8bit-bin-2.9.tar.lzma
-2021/01/16 | 8479 | macros/luatex/generic/luaotfload/shaper-demo.pdf
-2021/01/16 | 8188 | macros/luatex/generic/luaotfload/luaotfload-fakesc.lua
-2021/01/16 | 8175 | macros/latex/contrib/acro/examples/acro.example.issue-119.pdf
-2021/01/16 | 8121 | macros/luatex/generic/luaotfload/luaotfload-case-el.lua
-2021/01/16 | 80840 | systems/win32/miktex/tm/packages/miktex-freeglut-bin-x64-2.9.tar.lzma
-2021/01/16 | 8040 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ly1.tfm
-2021/01/16 | 796 | graphics/pgf/contrib/tikz-bbox/README.txt
-2021/01/16 | 7904 | macros/luatex/generic/luaotfload/fontloader-font-oti.lua
-2021/01/16 | 78960 | macros/luatex/generic/luaotfload/luaotfload-tool.pdf
-2021/01/16 | 78748 | systems/win32/miktex/tm/packages/miktex-png-bin-2.9.tar.lzma
-2021/01/16 | 78522 | macros/luatex/generic/luaotfload/luaotfload-conf.pdf
-2021/01/16 | 779 | macros/latex/contrib/acro/examples/acro.example.possessive.tex
-2021/01/16 | 77943 | systems/texlive/tlnet/tlpkg/translations/ja.po
-2021/01/16 | 77854 | systems/win32/miktex/tm/packages/miktex-fonts-bin-x64-2.9.tar.lzma
-2021/01/16 | 77410 | systems/win32/miktex/tm/packages/miktex-mpmcli-bin-x64-2.9.tar.lzma
-2021/01/16 | 7726 | systems/win32/miktex/tm/packages/miktex-md5-bin-2.9.tar.lzma
-2021/01/16 | 766 | graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.tex
-2021/01/16 | 7589 | macros/luatex/generic/luaotfload/luaotfload-unicode.lua
-2021/01/16 | 757 | macros/latex/contrib/acro/examples/acro.example.texsx-542461.tex
-2021/01/16 | 75587 | systems/texlive/tlnet/tlpkg/translations/sl.po
-2021/01/16 | 75372 | systems/win32/miktex/tm/packages/miktex-bibtex-bin-x64-2.9.tar.lzma
-2021/01/16 | 7528 | macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
-2021/01/16 | 75009 | systems/texlive/tlnet/tlpkg/translations/nl.po
-2021/01/16 | 74138 | systems/win32/miktex/tm/packages/miktex-lzma-bin-x64-2.9.tar.lzma
-2021/01/16 | 735 | macros/luatex/generic/luaotfload/luaotfload.conf.example
-2021/01/16 | 73285 | systems/win32/miktex/tm/packages/miktex-fonts-bin-2.9.tar.lzma
-2021/01/16 | 73181 | systems/texlive/tlnet/tlpkg/translations/pl.po
-2021/01/16 | 72925 | systems/texlive/tlnet/tlpkg/translations/zh_CN.po
-2021/01/16 | 72849 | systems/win32/miktex/tm/packages/miktex-graphite2-bin-x64-2.9.tar.lzma
-2021/01/16 | 7260 | macros/luatex/generic/luaotfload/fontloader-fonts-ext.lua
-2021/01/16 | 72105 | systems/win32/miktex/tm/packages/miktex-ps2pk-bin-x64-2.9.tar.lzma
-2021/01/16 | 71731 | systems/win32/miktex/tm/packages/miktex-freeglut-bin-2.9.tar.lzma
-2021/01/16 | 7119 | graphics/pgf/contrib/tikz-bbox/pgfmanual-en-library-bbox.tex
-2021/01/16 | 706 | macros/latex/contrib/acro/examples/acro.example.issue-111.tex
-2021/01/16 | 70428 | systems/win32/miktex/tm/packages/miktex-web-bin-x64-2.9.tar.lzma
-2021/01/16 | 70096 | systems/win32/miktex/tm/packages/miktex-tex4ht-bin-x64-2.9.tar.lzma
-2021/01/16 | 699 | macros/luatex/generic/luaotfload/scripts-demo.tex
-2021/01/16 | 6866 | macros/luatex/generic/luaotfload/fontloader-font-afk.lua
-2021/01/16 | 6809 | macros/luatex/generic/luaotfload/luaotfload-case.lua
-2021/01/16 | 679622 | systems/win32/miktex/tm/packages/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
-2021/01/16 | 67921 | systems/win32/miktex/tm/packages/miktex-mkfntmap-bin-x64-2.9.tar.lzma
-2021/01/16 | 67672 | systems/win32/miktex/tm/packages/miktex-lzma-bin-2.9.tar.lzma
-2021/01/16 | 67591 | systems/win32/miktex/tm/packages/miktex-bibtex-bin-2.9.tar.lzma
-2021/01/16 | 67491 | systems/win32/miktex/tm/packages/miktex-mpmcli-bin-2.9.tar.lzma
-2021/01/16 | 6644 | macros/luatex/generic/luaotfload/fontloader-l-string.lua
-2021/01/16 | 65982 | systems/win32/miktex/tm/packages/miktex-web-bin-2.9.tar.lzma
-2021/01/16 | 65656 | macros/luatex/generic/luaotfload/fontloader-font-otj.lua
-2021/01/16 | 65263 | systems/win32/miktex/tm/packages/miktex-texify-bin-x64-2.9.tar.lzma
-2021/01/16 | 65067 | macros/latex/contrib/acro/examples/acro.example.units.pdf
-2021/01/16 | 6405 | macros/luatex/generic/luaotfload/fontloader-l-lua.lua
-2021/01/16 | 63952 | systems/win32/miktex/tm/packages/miktex-ps2pk-bin-2.9.tar.lzma
-2021/01/16 | 63836 | systems/win32/miktex/tm/packages/miktex-graphite2-bin-2.9.tar.lzma
-2021/01/16 | 63729 | systems/win32/miktex/tm/packages/miktex-tex4ht-bin-2.9.tar.lzma
-2021/01/16 | 63484 | systems/texlive/tlnet/tlpkg/translations/zh_TW.po
-2021/01/16 | 63211 | macros/luatex/generic/luaotfload/fontloader-font-con.lua
-2021/01/16 | 6317 | macros/luatex/generic/luaotfload/luaotfload-status.lua
-2021/01/16 | 62768 | systems/win32/miktex/tm/packages/miktex-fmt-bin-x64-2.9.tar.lzma
-2021/01/16 | 6259 | macros/luatex/generic/luaotfload/luaotfload-szss.lua
-2021/01/16 | 624840 | systems/win32/miktex/tm/packages/miktex-lcdf-typetools-bin-2.9.tar.lzma
-2021/01/16 | 62146 | systems/win32/miktex/tm/packages/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
-2021/01/16 | 619004 | systems/win32/miktex/tm/packages/miktex-yap-bin-x64-2.9.tar.lzma
-2021/01/16 | 60665 | systems/win32/miktex/tm/packages/miktex-mkfntmap-bin-2.9.tar.lzma
-2021/01/16 | 59890 | systems/win32/miktex/tm/packages/miktex-tdsutil-bin-x64.tar.lzma
-2021/01/16 | 596701 | systems/win32/miktex/tm/packages/miktex-libressl-bin-x64-2.9.tar.lzma
-2021/01/16 | 5952 | graphics/pgf/contrib/tikz-bbox/pgflibrarybbox.code.tex
-2021/01/16 | 59344 | macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
-2021/01/16 | 59131 | systems/win32/miktex/tm/packages/miktex-cweb-bin-x64-2.9.tar.lzma
-2021/01/16 | 5885 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.tex
-2021/01/16 | 58809 | systems/texlive/tlnet/tlpkg/translations/messages.pot
-2021/01/16 | 583949 | systems/win32/miktex/tm/packages/miktex-yap-bin-2.9.tar.lzma
-2021/01/16 | 5824 | systems/texlive/tlnet/archive/pslatex.r57434.tar.xz
-2021/01/16 | 57549 | systems/win32/miktex/tm/packages/miktex-bibarts-bin-x64-2.9.tar.lzma
-2021/01/16 | 57342 | macros/luatex/generic/luaotfload/fontloader-fonts-lig.lua
-2021/01/16 | 56929 | systems/win32/miktex/tm/packages/miktex-texify-bin-2.9.tar.lzma
-2021/01/16 | 567261 | systems/win32/miktex/tm/packages/miktex-harfbuzz-bin-x64-2.9.tar.lzma
-2021/01/16 | 56592 | systems/win32/miktex/tm/packages/miktex-cjkutils-bin-x64-2.9.tar.lzma
-2021/01/16 | 56410 | systems/win32/miktex/tm/packages/miktex-arctrl-bin-x64-2.9.tar.lzma
-2021/01/16 | 56234 | systems/win32/miktex/tm/packages/miktex-tdsutil-bin.tar.lzma
-2021/01/16 | 55802 | systems/win32/miktex/tm/packages/miktex-fmt-bin-2.9.tar.lzma
-2021/01/16 | 5502 | macros/luatex/generic/luaotfload/fontloader-font-cid.lua
-2021/01/16 | 54995 | systems/win32/miktex/tm/packages/miktex-ttf2pk2-bin-2.9.tar.lzma
-2021/01/16 | 548 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-tlf-ts1.vf
-2021/01/16 | 5388 | macros/luatex/generic/luaotfload/fontloader-data-con.lua
-2021/01/16 | 531607 | systems/win32/miktex/tm/packages/miktex-libressl-bin-2.9.tar.lzma
-2021/01/16 | 52 | macros/luatex/generic/luaotfload/luaotfload-blacklist.cnf
-2021/01/16 | 52446 | systems/win32/miktex/tm/packages/miktex-cweb-bin-2.9.tar.lzma
-2021/01/16 | 52418 | systems/win32/miktex/tm/packages/miktex-m-tx-bin-x64-2.9.tar.lzma
-2021/01/16 | 5240 | systems/texlive/tlnet/archive/marathi.r57432.tar.xz
-2021/01/16 | 52203 | macros/luatex/generic/luaotfload/luaotfload-tool.lua
-2021/01/16 | 51863 | systems/win32/miktex/tm/packages/miktex-psutils-bin-x64-2.9.tar.lzma
-2021/01/16 | 51837 | systems/win32/miktex/tm/packages/miktex-synctex-bin-x64-2.9.tar.lzma
-2021/01/16 | 5136 | macros/unicodetex/latex/aalok/aalok.ins
-2021/01/16 | 51341 | systems/win32/miktex/tm/packages/miktex-cjkutils-bin-2.9.tar.lzma
-2021/01/16 | 511552 | systems/win32/miktex/tm/packages/miktex-log4cxx-bin-x64-2.9.tar.lzma
-2021/01/16 | 51104 | systems/win32/miktex/tm/packages/miktex-dvicopy-bin-x64-2.9.tar.lzma
-2021/01/16 | 509722 | systems/win32/miktex/doc/miktex.pdf
-2021/01/16 | 50665 | systems/win32/miktex/tm/packages/miktex-arctrl-bin-2.9.tar.lzma
-2021/01/16 | 501958 | macros/luatex/generic/luaotfload/luaotfload-latex.pdf
-2021/01/16 | 50136 | systems/win32/miktex/tm/packages/miktex-bibarts-bin-2.9.tar.lzma
-2021/01/16 | 4956 | macros/luatex/generic/luaotfload/luaotfload-dvi.lua
-2021/01/16 | 483380 | systems/win32/miktex/tm/packages/miktex-harfbuzz-bin-2.9.tar.lzma
-2021/01/16 | 4823653 | fonts/stix2-type1.zip
-2021/01/16 | 47824 | systems/win32/miktex/tm/packages/miktex-expat-bin-x64-2.9.tar.lzma
-2021/01/16 | 475303 | systems/win32/miktex/tm/packages/miktex-log4cxx-bin-2.9.tar.lzma
-2021/01/16 | 46827 | systems/win32/miktex/tm/packages/miktex-mtprint-bin-x64-2.9.tar.lzma
-2021/01/16 | 4627580 | systems/texlive/tlnet/archive/nunito.r57429.tar.xz
-2021/01/16 | 461317 | systems/win32/miktex/tm/packages/miktex-doc.tar.lzma
-2021/01/16 | 46091 | macros/luatex/generic/luaotfload/fontloader-basics-chr.lua
-2021/01/16 | 45831 | systems/win32/miktex/tm/packages/miktex-m-tx-bin-2.9.tar.lzma
-2021/01/16 | 45647 | systems/win32/miktex/tm/packages/miktex-dvicopy-bin-2.9.tar.lzma
-2021/01/16 | 45547 | graphics/pxpic/pxpic.dtx
-2021/01/16 | 45242 | systems/win32/miktex/tm/packages/miktex-dvipng-bin-x64-2.9.tar.lzma
-2021/01/16 | 4430 | fonts/alfaslabone/doc/LICENSE.TXT
-2021/01/16 | 440 | systems/texlive/tlnet/archive/tlshell.doc.r57426.tar.xz
-2021/01/16 | 43947 | macros/luatex/generic/luaotfload/fontloader-util-str.lua
-2021/01/16 | 4376 | systems/texlive/tlnet/archive/fcolumn.r57428.tar.xz
-2021/01/16 | 43580 | systems/win32/miktex/tm/packages/miktex-psutils-bin-2.9.tar.lzma
-2021/01/16 | 43377 | systems/win32/miktex/tm/packages/miktex-zlib-bin-x64-2.9.tar.lzma
-2021/01/16 | 43067 | systems/win32/miktex/tm/packages/miktex-expat-bin-2.9.tar.lzma
-2021/01/16 | 42851 | systems/win32/miktex/tm/packages/miktex-mtprint-bin-2.9.tar.lzma
-2021/01/16 | 42630 | systems/win32/miktex/tm/packages/miktex-gsf2pk-bin-x64-2.9.tar.lzma
-2021/01/16 | 42530 | systems/win32/miktex/tm/packages/miktex-mthelp-bin-x64-2.9.tar.lzma
-2021/01/16 | 42400 | systems/win32/miktex/tm/packages/miktex-synctex-bin-2.9.tar.lzma
-2021/01/16 | 423 | fonts/alfaslabone/doc/alfaslabone-samples.tex
-2021/01/16 | 41758 | macros/luatex/generic/luaotfload/fontloader-l-table.lua
-2021/01/16 | 41599 | macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
-2021/01/16 | 41362 | macros/luatex/generic/luaotfload/filegraph.pdf
-2021/01/16 | 41303 | macros/luatex/generic/luaotfload/fontloader-l-unicode.lua
-2021/01/16 | 40952 | systems/win32/miktex/tm/packages/miktex-dvipng-bin-2.9.tar.lzma
-2021/01/16 | 4047 | macros/luatex/generic/luaotfload/luaotfload-fallback.lua
-2021/01/16 | 39651 | systems/win32/miktex/tm/packages/miktex-patgen-bin-x64.tar.lzma
-2021/01/16 | 39515 | systems/win32/miktex/tm/packages/miktex-zlib-bin-2.9.tar.lzma
-2021/01/16 | 392570 | systems/win32/miktex/tm/packages/miktex-cairo-bin-x64-2.9.tar.lzma
-2021/01/16 | 3896 | systems/texlive/tlnet/archive/readablecv.r57433.tar.xz
-2021/01/16 | 38703 | macros/luatex/generic/luaotfload/fontloader-l-lpeg.lua
-2021/01/16 | 3869096 | systems/win32/w32tex/luajittex-w32.tar.xz
-2021/01/16 | 3866408 | systems/win32/w32tex/luajittex-dev-w32.tar.xz
-2021/01/16 | 3821 | macros/luatex/generic/luaotfload/fontloader-fonts-def.lua
-2021/01/16 | 38041 | systems/win32/miktex/tm/packages/miktex-mthelp-bin-2.9.tar.lzma
-2021/01/16 | 38035 | systems/win32/miktex/tm/packages/miktex-gsf2pk-bin-2.9.tar.lzma
-2021/01/16 | 3784 | macros/luatex/generic/luaotfload/README.md
-2021/01/16 | 372 | macros/latex/contrib/acro/examples/acro.example.texsx-515295.tex
-2021/01/16 | 37272 | systems/win32/miktex/tm/packages/miktex-upmendex-bin-x64.tar.lzma
-2021/01/16 | 37227 | systems/win32/miktex/tm/packages/miktex-posix-bin-x64-2.9.tar.lzma
-2021/01/16 | 3693 | macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua
-2021/01/16 | 3674 | macros/luatex/generic/luaotfload/fontloader-fonts-syn.lua
-2021/01/16 | 36687 | systems/win32/miktex/tm/packages/miktex-chktex-bin-x64-2.9.tar.lzma
-2021/01/16 | 361 | macros/luatex/generic/luaotfload/fontloader-l-function.lua
-2021/01/16 | 3580 | macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua
-2021/01/16 | 35401 | systems/win32/miktex/tm/packages/miktex-patgen-bin.tar.lzma
-2021/01/16 | 353 | macros/latex/contrib/acro/examples/acro.example.texsx-513623.tex
-2021/01/16 | 35149 | macros/unicodetex/latex/aalok/COPYING
-2021/01/16 | 35046 | systems/win32/miktex/tm/packages/miktex-mspack-bin-x64-2.9.tar.lzma
-2021/01/16 | 34862 | macros/luatex/generic/luaotfload/fontloader-font-ott.lua
-2021/01/16 | 3451376 | systems/win32/w32tex/win64/luajittex-dev-w64.tar.xz
-2021/01/16 | 3450988 | systems/win32/w32tex/win64/luajittex-w64.tar.xz
-2021/01/16 | 345095 | systems/win32/miktex/tm/packages/miktex-xetex-bin-x64-2.9.tar.lzma
-2021/01/16 | 34312 | systems/win32/miktex/tm/packages/miktex-axohelp-bin-x64-2.9.tar.lzma
-2021/01/16 | 3406 | macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua
-2021/01/16 | 33721 | macros/latex/contrib/acro/examples/acro.example.texsx-507726.pdf
-2021/01/16 | 33490 | systems/win32/miktex/tm/packages/miktex-upmendex-bin.tar.lzma
-2021/01/16 | 33136 | systems/win32/miktex/tm/packages/miktex-uriparser-bin-x64-2.9.tar.lzma
-2021/01/16 | 33035 | macros/luatex/generic/luaotfload/fontloader-font-otl.lua
-2021/01/16 | 329 | macros/latex/contrib/acro/examples/acro.example.issue-109.tex
-2021/01/16 | 329919 | systems/win32/miktex/tm/packages/miktex-cairo-bin-2.9.tar.lzma
-2021/01/16 | 3287334 | macros/luatex/generic/luaotfload/luaotfload-characters.lua
-2021/01/16 | 32597 | macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
-2021/01/16 | 3252 | macros/latex/contrib/acro/acro-examples.sty
-2021/01/16 | 32509 | systems/win32/miktex/tm/packages/miktex-chktex-bin-2.9.tar.lzma
-2021/01/16 | 32432 | macros/latex/contrib/acro/examples/acro.example.texsx-505891.pdf
-2021/01/16 | 3214 | macros/latex/contrib/acro/examples/acro.example.basic.tex
-2021/01/16 | 319588 | systems/texlive/tlnet/archive/fcolumn.doc.r57428.tar.xz
-2021/01/16 | 31802 | macros/luatex/generic/luaotfload/fontloader-font-otc.lua
-2021/01/16 | 3179 | fonts/alfaslabone/enc/a_taosrr.enc
-2021/01/16 | 315 | macros/latex/contrib/acro/examples/acro.example.acflike.tex
-2021/01/16 | 315430 | graphics/pxpic.zip
-2021/01/16 | 31501 | systems/win32/miktex/tm/packages/miktex-posix-bin-2.9.tar.lzma
-2021/01/16 | 31451 | systems/win32/miktex/tm/packages/miktex-makeindex-bin-x64-2.9.tar.lzma
-2021/01/16 | 31298 | macros/luatex/generic/luaotfload/fontloader-font-one.lua
-2021/01/16 | 31285 | systems/win32/miktex/tm/packages/miktex-autosp-bin-x64-2.9.tar.lzma
-2021/01/16 | 3126816 | systems/win32/w32tex/win64/luatex-dev-w64.tar.xz
-2021/01/16 | 3123124 | systems/win32/w32tex/win64/luatex-w64.tar.xz
-2021/01/16 | 31180 | systems/win32/miktex/tm/packages/miktex-mspack-bin-2.9.tar.lzma
-2021/01/16 | 31151 | macros/luatex/generic/luaotfload/luaotfload-configuration.lua
-2021/01/16 | 310834 | systems/win32/miktex/tm/packages/miktex-xetex-bin-2.9.tar.lzma
-2021/01/16 | 30999 | macros/luatex/generic/luaotfload/luaotfload-parsers.lua
-2021/01/16 | 309853 | graphics/pxpic/pxpic.pdf
-2021/01/16 | 30841 | systems/win32/miktex/tm/packages/miktex-bzip2-bin-x64-2.9.tar.lzma
-2021/01/16 | 30275 | macros/latex/contrib/acro/examples/acro.example.issue-109.pdf
-2021/01/16 | 30036 | systems/win32/miktex/tm/packages/miktex-lacheck-bin-x64-2.9.tar.lzma
-2021/01/16 | 2999 | fonts/alfaslabone/enc/a_rymxky.enc
-2021/01/16 | 2958 | fonts/alfaslabone/enc/a_d2anrk.enc
-2021/01/16 | 295392 | systems/win32/miktex/tm/packages/miktex-freetype2-bin-x64-2.9.tar.lzma
-2021/01/16 | 29444 | systems/win32/miktex/tm/packages/miktex-axohelp-bin-2.9.tar.lzma
-2021/01/16 | 2943 | fonts/alfaslabone/enc/a_lzhlbi.enc
-2021/01/16 | 2902 | fonts/alfaslabone/enc/a_vqpkf5.enc
-2021/01/16 | 29029 | systems/win32/miktex/tm/packages/miktex-autosp-bin-2.9.tar.lzma
-2021/01/16 | 29002 | macros/luatex/generic/luaotfload/luaotfload-features.lua
-2021/01/16 | 2886 | fonts/alfaslabone/enc/a_adz5lu.enc
-2021/01/16 | 286 | macros/latex/contrib/acro/examples/acro.example.issue-154.tex
-2021/01/16 | 283886 | systems/win32/miktex/tm/packages/miktex-metapost-bin-x64-2.9.tar.lzma
-2021/01/16 | 2830 | fonts/alfaslabone/enc/a_5xld5w.enc
-2021/01/16 | 28088 | systems/win32/miktex/tm/packages/miktex-lacheck-bin-2.9.tar.lzma
-2021/01/16 | 27986 | systems/win32/miktex/tm/packages/miktex-findtexmf-bin-x64-2.9.tar.lzma
-2021/01/16 | 275 | macros/luatex/generic/luaotfload/luaotfload-main.lua
-2021/01/16 | 27458 | systems/win32/miktex/source/CHANGELOG.md
-2021/01/16 | 27391 | systems/win32/miktex/tm/packages/miktex-makeindex-bin-2.9.tar.lzma
-2021/01/16 | 27380 | systems/texlive/tlnet/archive/tlshell.r57426.tar.xz
-2021/01/16 | 27362 | systems/win32/miktex/tm/packages/miktex-teckit-bin-x64-2.9.tar.lzma
-2021/01/16 | 2732 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ot1.tfm
-2021/01/16 | 27195 | systems/win32/miktex/tm/packages/miktex-uriparser-bin-2.9.tar.lzma
-2021/01/16 | 27187 | systems/win32/miktex/tm/packages/miktex-bzip2-bin-2.9.tar.lzma
-2021/01/16 | 2667 | macros/luatex/generic/luaotfload/fontloader-font-vfc.lua
-2021/01/16 | 2615218 | systems/win32/miktex/tm/packages/miktex-texworks-bin-x64-2.9.tar.lzma
-2021/01/16 | 258611 | systems/win32/miktex/tm/packages/miktex-freetype2-bin-2.9.tar.lzma
-2021/01/16 | 2582 | macros/luatex/generic/luaotfload/luaotfload-suppress.lua
-2021/01/16 | 2555 | macros/luatex/generic/luaotfload/fontloader-l-math.lua
-2021/01/16 | 25404 | systems/win32/miktex/tm/packages/miktex-teckit-bin-2.9.tar.lzma
-2021/01/16 | 253989 | systems/win32/miktex/tm/packages/miktex-console-bin-x64-2.9.tar.lzma
-2021/01/16 | 25336 | macros/luatex/generic/luaotfload/luaotfload-filelist.lua
-2021/01/16 | 25187 | fonts/alfaslabone/doc/alfaslabone-samples.pdf
-2021/01/16 | 25134 | systems/win32/miktex/tm/packages/miktex-findtexmf-bin-2.9.tar.lzma
-2021/01/16 | 2506 | macros/luatex/generic/luaotfload/luaotfload-scripts.lua
-2021/01/16 | 25021 | systems/win32/miktex/tm/packages/miktex-fribidixetex-bin-x64-2.9.tar.lzma
-2021/01/16 | 250168 | systems/win32/miktex/tm/packages/miktex-metapost-bin-2.9.tar.lzma
-2021/01/16 | 2496339 | systems/win32/miktex/tm/packages/miktex-texworks-bin-2.9.tar.lzma
-2021/01/16 | 24566 | macros/luatex/generic/luaotfload/fontloader-font-ocl.lua
-2021/01/16 | 2441 | fonts/alfaslabone/latex/alfaslabone.sty
-2021/01/16 | 243495 | systems/win32/miktex/tm/packages/miktex-pmx-bin-x64-2.9.tar.lzma
-2021/01/16 | 24224 | macros/latex/contrib/acro/examples/acro.example.issue-154.pdf
-2021/01/16 | 241759 | fonts/alfaslabone.zip
-2021/01/16 | 23895404 | info/beginlatex.zip
-2021/01/16 | 23863 | systems/win32/miktex/tm/packages/miktex-popt-bin-x64-2.9.tar.lzma
-2021/01/16 | 238560 | graphics/pgf/contrib/tikz-bbox.zip
-2021/01/16 | 234562 | graphics/pgf/contrib/tikz-bbox/pgfmanual4bbox.pdf
-2021/01/16 | 23399 | macros/luatex/generic/luaotfload/fontloader-fonts-tfm.lua
-2021/01/16 | 23289 | systems/win32/miktex/tm/packages/miktex-devnag-bin-x64-2.9.tar.lzma
-2021/01/16 | 2315 | macros/luatex/generic/luaotfload/fontloader-fonts-enc.lua
-2021/01/16 | 22966 | macros/luatex/generic/luaotfload/fontloader-font-oto.lua
-2021/01/16 | 228792 | systems/win32/miktex/tm/packages/miktex-console-bin-2.9.tar.lzma
-2021/01/16 | 22752 | macros/latex/contrib/acro/examples/acro.example.texsx-513623.pdf
-2021/01/16 | 22175 | macros/luatex/generic/luaotfload/fontloader-l-file.lua
-2021/01/16 | 22023 | systems/win32/miktex/tm/packages/miktex-fribidixetex-bin-2.9.tar.lzma
-2021/01/16 | 21857 | macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
-2021/01/16 | 21837 | macros/luatex/generic/luaotfload/scripts-demo.pdf
-2021/01/16 | 214204 | systems/win32/miktex/tm/packages/miktex-metafont-bin-x64-2.9.tar.lzma
-2021/01/16 | 2125 | macros/latex/contrib/acro/README
-2021/01/16 | 21252 | systems/texlive/tlnet/archive/fcolumn.source.r57428.tar.xz
-2021/01/16 | 211107 | systems/win32/miktex/tm/packages/miktex-omegaware-bin-x64-2.9.tar.lzma
-2021/01/16 | 21097 | systems/win32/miktex/tm/packages/miktex-devnag-bin-2.9.tar.lzma
-2021/01/16 | 20922 | macros/latex/contrib/acro/examples/acro.example.acflike.pdf
-2021/01/16 | 207758 | systems/win32/miktex/tm/packages/miktex-pmx-bin-2.9.tar.lzma
-2021/01/16 | 207536 | systems/texlive/tlnet/archive/readablecv.doc.r57433.tar.xz
-2021/01/16 | 202652 | systems/win32/miktex/tm/packages/miktex-pixman-bin-x64-2.9.tar.lzma
-2021/01/16 | 20099 | systems/win32/miktex/tm/packages/miktex-popt-bin-2.9.tar.lzma
-2021/01/16 | 20031 | macros/luatex/generic/luaotfload/NEWS
-2021/01/16 | 199557 | systems/win32/miktex/tm/packages/miktex-mpfr-bin-2.9.tar.lzma
-2021/01/16 | 19944 | macros/luatex/generic/luaotfload/fontloader-font-def.lua
-2021/01/16 | 198013 | systems/win32/miktex/tm/packages/miktex-pixman-bin-2.9.tar.lzma
-2021/01/16 | 1978 | macros/latex/contrib/acro/examples/acro.example.units.tex
-2021/01/16 | 19570 | macros/luatex/generic/luaotfload/fontloader-font-map.lua
-2021/01/16 | 195688 | systems/win32/miktex/tm/packages/miktex-metafont-bin-2.9.tar.lzma
-2021/01/16 | 195525 | systems/win32/miktex/tm/packages/miktex-curl-bin-x64-2.9.tar.lzma
-2021/01/16 | 19547 | macros/luatex/generic/luaotfload/luaotfload-init.lua
-2021/01/16 | 1950415 | install/macros/luatex/generic/luaotfload.tds.zip
-2021/01/16 | 1946587 | macros/luatex/generic/luaotfload.zip
-2021/01/16 | 193635 | systems/win32/miktex/tm/packages/miktex-omegaware-bin-2.9.tar.lzma
-2021/01/16 | 191 | macros/luatex/generic/luaotfload/shaper-demo-graphite.tex
-2021/01/16 | 1888 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ly1--base.tfm
-2021/01/16 | 18717 | macros/luatex/generic/luaotfload/fontloader-font-onr.lua
-2021/01/16 | 18714 | macros/luatex/generic/luaotfload/COPYING
-2021/01/16 | 1864 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-ly1.tfm
-2021/01/16 | 18645 | macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
-2021/01/16 | 1860 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-ly1--base.tfm
-2021/01/16 | 1850 | macros/luatex/generic/luaotfload/fontloader-l-boolean.lua
-2021/01/16 | 18421 | macros/luatex/generic/luaotfload/fontloader-font-ota.lua
-2021/01/16 | 184044 | systems/texlive/tlnet/archive/marathi.doc.r57432.tar.xz
-2021/01/16 | 182 | macros/luatex/generic/luaotfload/shaper-demo.tex
-2021/01/16 | 182360 | systems/texlive/tlnet/archive/nunito.doc.r57429.tar.xz
-2021/01/16 | 182126 | macros/luatex/generic/luaotfload/fontloader-font-ots.lua
-2021/01/16 | 1812 | macros/luatex/generic/luaotfload/luaotfload.sty
-2021/01/16 | 18105 | systems/win32/miktex/tm/packages/miktex-tex2xindy-bin-x64-2.9.tar.lzma
-2021/01/16 | 1808 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-t1--base.tfm
-2021/01/16 | 18074 | macros/luatex/generic/luaotfload/luaotfload.conf.rst
-2021/01/16 | 1800 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-t1.tfm
-2021/01/16 | 179945 | systems/win32/miktex/tm/packages/miktex-mpfr-bin-x64-2.9.tar.lzma
-2021/01/16 | 17971 | systems/win32/miktex/tm/packages/miktex-kpathsea-bin-x64-2.9.tar.lzma
-2021/01/16 | 1794 | macros/luatex/generic/luaotfload/fontloader-font-ini.lua
-2021/01/16 | 179431 | systems/win32/miktex/tm/packages/miktex-curl-bin-2.9.tar.lzma
-2021/01/16 | 1792 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-t1--base.tfm
-2021/01/16 | 17536 | systems/texlive/tlnet/archive/marathi.source.r57432.tar.xz
-2021/01/16 | 1728 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-tlf-t1.vf
-2021/01/16 | 172864 | macros/latex/contrib/acro/acro.sty
-2021/01/16 | 1712 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-tlf-ly1.vf
-2021/01/16 | 1700 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-sup-t1.vf
-2021/01/16 | 1684 | fonts/alfaslabone/vf/AlphaSlabOne-Regular-sup-ly1.vf
-2021/01/16 | 167909 | systems/win32/miktex/tm/packages/miktex-tex-bin-x64-2.9.tar.lzma
-2021/01/16 | 16675 | macros/luatex/generic/luaotfload/luaotfload-latex.tex
-2021/01/16 | 16548 | macros/luatex/generic/luaotfload/luaotfload.conf.5
-2021/01/16 | 164413 | systems/win32/miktex/tm/packages/miktex-hunspell-bin-x64-2.9.tar.lzma
-2021/01/16 | 163858 | systems/win32/miktex/tm/packages/miktex-mo-bin-x64-2.9.tar.lzma
-2021/01/16 | 16313 | systems/win32/miktex/tm/packages/miktex-kpathsea-bin-2.9.tar.lzma
-2021/01/16 | 16101 | systems/win32/miktex/tm/packages/miktex-tex2xindy-bin-2.9.tar.lzma
-2021/01/16 | 15954 | macros/luatex/generic/luaotfload/luaotfload-colors.lua
-2021/01/16 | 15940 | macros/luatex/generic/luaotfload/luaotfload-tool.rst
-2021/01/16 | 15855 | macros/latex/contrib/acro/examples/acro.example.texsx-515295.pdf
-2021/01/16 | 15808 | macros/latex/contrib/acro/examples/acro.example.texsx-542461.pdf
-2021/01/16 | 15733 | macros/latex/contrib/acro/examples/acro.example.issue-111.pdf
-2021/01/16 | 154135 | macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
-2021/01/16 | 153828 | systems/win32/miktex/tm/packages/miktex-tex-bin-2.9.tar.lzma
-2021/01/16 | 152695 | systems/win32/miktex/tm/packages/miktex-fontconfig-bin-x64-2.9.tar.lzma
-2021/01/16 | 15196 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua
-2021/01/16 | 150917 | systems/win32/miktex/tm/packages/miktex-hunspell-bin-2.9.tar.lzma
-2021/01/16 | 15068 | macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
-2021/01/16 | 1476 | macros/latex/contrib/acro/examples/acro.example.texsx-507726.tex
-2021/01/16 | 146809 | systems/win32/miktex/tm/packages/miktex-mo-bin-2.9.tar.lzma
-2021/01/16 | 1449 | macros/luatex/generic/luaotfload/fontloader-font-lua.lua
-2021/01/16 | 144061 | macros/latex/contrib/acro/acro2.sty
-2021/01/16 | 14322 | systems/win32/miktex/tm/packages/miktex-zzip-bin-x64-2.9.tar.lzma
-2021/01/16 | 1428 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ts1.tfm
-2021/01/16 | 1420 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-tlf-ts1--base.tfm
-2021/01/16 | 1414570 | systems/win32/miktex/tm/packages/miktex-dvisvgm-bin-x64-2.9.tar.lzma
-2021/01/16 | 13977 | macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua
-2021/01/16 | 1383744 | systems/texlive/tlnet/archive/stix2-otf.r57427.tar.xz
-2021/01/16 | 1382570 | macros/latex/contrib/acro.zip
-2021/01/16 | 13788 | macros/luatex/generic/luaotfload/luaotfload.lua
-2021/01/16 | 13686 | macros/latex/contrib/acro/examples/acro.example.possessive.pdf
-2021/01/16 | 136437 | systems/win32/miktex/tm/packages/miktex-mktex-bin-x64-2.9.tar.lzma
-2021/01/16 | 13500 | macros/luatex/generic/luaotfload/fontloader-font-shp.lua
-2021/01/16 | 134863 | macros/luatex/generic/luaotfload/luaotfload-database.lua
-2021/01/16 | 134824 | systems/win32/miktex/tm/packages/miktex-fontconfig-bin-2.9.tar.lzma
-2021/01/16 | 13468 | macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
-2021/01/16 | 13454 | systems/win32/miktex/tm/packages/miktex-zzip-bin-2.9.tar.lzma
-2021/01/16 | 1332 | fonts/alfaslabone/tfm/AlphaSlabOne-Regular-sup-ot1.tfm
-2021/01/16 | 131466 | systems/win32/miktex/tm/packages/miktex-dvips-bin-x64-2.9.tar.lzma
-2021/01/16 | 1305255 | systems/win32/miktex/tm/packages/miktex-poppler-bin-x64-2.9.tar.lzma
-2021/01/16 | 1277725 | systems/win32/miktex/tm/packages/miktex-dvisvgm-bin-2.9.tar.lzma
-2021/01/16 | 12745 | macros/luatex/generic/luaotfload/fontloader-basics-gen.lua
-2021/01/16 | 12707 | macros/luatex/generic/luaotfload/luaotfload-tool.1
-2021/01/16 | 125351 | macros/latex/contrib/acro/examples/acro.example.basic.pdf
-2021/01/16 | 124829 | systems/win32/miktex/tm/packages/miktex-mktex-bin-2.9.tar.lzma
-2021/01/16 | 124025 | fonts/alfaslabone/type1/AlphaSlabOne-Regular.pfb
-2021/01/16 | 12224 | macros/luatex/generic/luaotfload/luaotfload-notdef.lua
-2021/01/16 | 1219820 | systems/texlive/tlnet/archive/stix2-otf.doc.r57427.tar.xz
-2021/01/16 | 1200 | systems/texlive/tlnet/archive/pslatex.source.r57434.tar.xz
-2021/01/16 | 11829 | macros/luatex/generic/luaotfload/fontloader-l-io.lua
-2021/01/16 | 117724 | macros/luatex/generic/luaotfload/fontloader-font-oup.lua
-2021/01/16 | 1171209 | systems/win32/miktex/tm/packages/miktex-poppler-bin-2.9.tar.lzma
-2021/01/16 | 116951 | systems/win32/miktex/tm/packages/miktex-dvips-bin-2.9.tar.lzma
-2021/01/16 | 11552 | macros/luatex/generic/luaotfload/fontloader-util-fil.lua
-2021/01/16 | 1145 | graphics/pxpic/README.md
-2021/01/16 | 113851 | systems/win32/miktex/tm/packages/miktex-gregorio-bin-x64-2.9.tar.lzma
-2021/01/16 | 11323 | macros/luatex/generic/luaotfload/luaotfload-log.lua
-2021/01/16 | 112818 | systems/texlive/tlnet/tlpkg/translations/ru.po
-2021/01/16 | 112264 | systems/win32/miktex/tm/packages/miktex-gd-bin-x64-2.9.tar.lzma
-2021/01/16 | 110206 | systems/texlive/tlnet/tlpkg/translations/sr.po
-2021/01/16 | 10984 | macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
-2021/01/16 | 109162 | systems/win32/miktex/tm/packages/miktex-jpeg-bin-x64-2.9.tar.lzma
-2021/01/16 | 109148 | fonts/alfaslabone/opentype/AlphaSlabOne-Regular.otf
-2021/01/16 | 1087 | fonts/alfaslabone/map/AlphaSlabOne.map
-2021/01/16 | 1077651 | systems/win32/miktex/tm/packages/miktex-asymptote-bin-x64-2.9.tar.lzma
-2021/01/16 | 107580 | macros/luatex/generic/luaotfload/fontloader-font-osd.lua
-2021/01/16 | 1068 | macros/latex/contrib/acro/examples/acro.example.texsx-505891.tex
-2021/01/16 | 106264 | systems/win32/miktex/tm/packages/miktex-texware-bin-x64-2.9.tar.lzma
-2021/01/16 | 104364 | macros/latex/contrib/acro/acro-manual.tex
-2021/01/16 | 103186 | systems/win32/miktex/tm/packages/miktex-lua53-bin-x64-2.9.tar.lzma
-2021/01/16 | 102502 | macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
-2021/01/16 | 101830 | systems/win32/miktex/tm/packages/miktex-mfware-bin-x64-2.9.tar.lzma
-2021/01/16 | 10064 | macros/luatex/generic/luaotfload/fontloader-basics-nod.lua
-2021/01/16 | 1004 | macros/luatex/generic/luaotfload/luaotfload-embolden.lua
-2021/01/16 | 100091 | systems/texlive/tlnet/tlpkg/translations/fr.po
diff --git a/fonts/newcomputermodern/NewCM10-Book.otf b/fonts/newcomputermodern/NewCM10-Book.otf
index 2c1754cf25..b014abe519 100644
--- a/fonts/newcomputermodern/NewCM10-Book.otf
+++ b/fonts/newcomputermodern/NewCM10-Book.otf
Binary files differ
diff --git a/fonts/newcomputermodern/README b/fonts/newcomputermodern/README
index 6493891cdb..aee8b7986d 100644
--- a/fonts/newcomputermodern/README
+++ b/fonts/newcomputermodern/README
@@ -1,7 +1,7 @@
New Computer Modern Fonts
- (Package version 3.00, GustFLv1 or later)
+ (Package version 3.01, GustFLv1 or later)
Antonis Tsolomitis
Samos, Greece, 2019--2021
diff --git a/graphics/pgf/contrib/penrose/README.txt b/graphics/pgf/contrib/penrose/README
index 43c2298f5f..43c2298f5f 100644
--- a/graphics/pgf/contrib/penrose/README.txt
+++ b/graphics/pgf/contrib/penrose/README
diff --git a/graphics/pgf/contrib/penrose/penrose.pdf b/graphics/pgf/contrib/penrose/penrose.pdf
index 089af30724..67ea7a9309 100644
--- a/graphics/pgf/contrib/penrose/penrose.pdf
+++ b/graphics/pgf/contrib/penrose/penrose.pdf
Binary files differ
diff --git a/graphics/pgf/contrib/penrose/penrose.tex b/graphics/pgf/contrib/penrose/penrose.tex
index b381149ee2..be44311844 100644
--- a/graphics/pgf/contrib/penrose/penrose.tex
+++ b/graphics/pgf/contrib/penrose/penrose.tex
@@ -1,4 +1,4 @@
-\immediate\write18{tex penrose_code.dtx}
+%\immediate\write18{tex penrose_code.dtx}
\documentclass{ltxdoc}
\usepackage[T1]{fontenc}
\usepackage{trace}
@@ -12,8 +12,15 @@
\usepackage{listings}
\lstloadlanguages{[LaTeX]TeX}
-\lstset{breakatwhitespace=true,breaklines=true,language=TeX}
-
+\lstset{
+ breakatwhitespace=true,
+ breaklines=true,
+ language=[LaTeX]TeX,
+ basicstyle=\small\ttfamily,
+ keepspaces=true,
+ columns=fullflexible
+}
+
\usepackage{fancyvrb}
\newenvironment{example}
@@ -23,7 +30,6 @@
\begin{center}
\setlength{\parindent}{0pt}
\fbox{\begin{minipage}{.9\linewidth}
- \lstset{breakatwhitespace=true,breaklines=true,language=TeX,basicstyle=\small}
\lstinputlisting[]{example.out}
\end{minipage}}
@@ -41,7 +47,6 @@
\begin{center}
\setlength{\parindent}{0pt}
\fbox{\begin{minipage}{.9\linewidth}
- \lstset{breakatwhitespace=true,breaklines=true,language=TeX,basicstyle=\small}
\lstinputlisting[]{example.out}
\end{minipage}}
\end{center}
@@ -73,18 +78,21 @@
\makeatother
\providecommand*{\url}{\texttt}
+\GetFileInfo{tikzlibrarypenrose.code.tex}
\title{The \textsf{Penrose} Package: Documentation}
\author{Andrew Stacey\texorpdfstring{\\ \url{loopspace@mathforge.org}}{}}
-\date{1.0~from 2018/07/10}
+ \date{\fileversion~from \filedate}
\begin{document}
\maketitle
+\tableofcontents
+
\section{Introduction}
The \textsf{Penrose} package is a TikZ library for drawing Penrose tiles.
-It currently supports the kite/dart, rhombus, and pentagon tile sets.
+It currently supports natively the kite/dart, rhombus, and pentagon tile sets, but has provision for defining new tiles.
There are two main methods for their placement: one that automatically generates a tiling, and one that allows for ``by hand'' placement.
Furthermore, the tiles themselves can be deformed and will still (hopefully!) fit together in the correct fashion.
@@ -148,7 +156,7 @@ If the shortcut keys are used to specify the tiles, this can be put in the \Verb
TikZ \Verb+pic+s can be named, using the \Verb+name=<name>+ key.
When a Penrose tile has been named then it can be used for positioning other tiles.
-Each edge is assigned a label from \Verb+a b c A B C+ and a new tile can be aligned with an old one along a matching edge (\Verb+a+ matches with \Verb+A+ and so on).
+Each edge is assigned a label from \Verb+a b c d e A B C D E+ and a new tile can be aligned with an old one along a matching edge (\Verb+a+ matches with \Verb+A+ and so on).
The edge labels are as follows.
For the \Verb+pentagon 5+, for example, the edges are all the same and the numbers are used to distinguish between them.
@@ -273,7 +281,7 @@ In practical terms, this means that if drawn then the line width is half that wh
There is a way to specify a Penrose tiling using \emph{Lindenmayer systems}.
In brief, this takes a golden triangle or gnomon (or one of the reverse ones) and repeatedly decomposes it into smaller triangles and gnomon.
Once a desired level has been reached, the resulting triangles and gnomon are glued together in pairs to create either darts and kites or rhombuses (of both types).
-This library contains an implementation of this both for each of the tilings.
+This library contains an implementation of this for each of the tilings.
The user command is:
%
@@ -351,41 +359,44 @@ Indeed, by using asymmetric paths, the matching rules can be enforced without th
Internally, the \Verb+penrose+ library uses the \Verb+spath3+ package for storing and manipulating the paths.
-To create a new edge path, use the key \Verb+save Penrose path=<edge>+ where \Verb+<edge>+ is one of \Verb+a+, \Verb+b+, \Verb+c+, or \Verb+d+.
+To create a new edge path, use the key \Verb+save Penrose path=<edge>+ where \Verb+<edge>+ is a symbol used in the edge description of a tile.
There are no constraints on the size of the path as all paths are scaled and transformed to fit the tiles.
Once the edge paths have been specified, they are welded together into the tiles using the following command:
%
\begin{verbatim}
-\MakePenroseTile{<name>}
+\BakePenroseTile{<name>}
\end{verbatim}
%
Here, \Verb+<name>+ is one of the names of the tiles.
This has global effect, as does the definition of the edge paths.
-Internally, the tile paths are stored as \Verb+spath+ objects (from the \Verb+spath3+ package) so the commands of that package can be used to, for example, make a copy of a tile.
-The internal name for a tile path is \Verb+Penrosepathtile<name>+ (no spaces) so can be cloned via:
+Paths, both sides and tiles, can be cloned via:
%
\begin{verbatim}
-\CloneSPath{Penrosepathtile<name>}{My Amazing Penrose Tile}
+\tikzset{clone Penrose side path={target}{source}
+\tikzset{clone Penrose tile path={target}{source}
\end{verbatim}
%
and restored with the same command (but names switched).
+The initial version of this package used \Verb!\MakePenroseTile! for this command.
+That command is still available for backwards compatibility.
+
\begin{example}
\begin{tikzpicture}
\pic[draw,dart,name=dart];
\pic[draw,kite,align with=dart along c];
\pic[draw,kite,align with=dart along C];
-\CloneSPath{Penrosepathtilekite}{Original kite}
-\CloneSPath{Penrosepathtiledart}{Original dart}
+\tikzset{clone Penrose tile path={original kite}{kite}}
+\tikzset{clone Penrose tile path={original dart}{dart}}
\path[save Penrose path=a] (0,0) to[out=-30,in=100] (1,0);
\path[save Penrose path=c] (0,0) to[out=-40,in=140] (1,0);
-\MakePenroseTile{kite}
-\MakePenroseTile{dart}
+\BakePenroseTile{kite}
+\BakePenroseTile{dart}
\pic[xshift=2cm,draw,dart,name=dart];
\pic[draw,kite,align with=dart along c];
\pic[draw,kite,align with=dart along C];
-\CloneSPath{Original kite}{Penrosepathtilekite}
-\CloneSPath{Original dart}{Penrosepathtiledart}
+\tikzset{clone Penrose tile path={kite}{original kite}}
+\tikzset{clone Penrose tile path={dart}{original dart}}
\pic[xshift=4cm,draw,dart,name=dart];
\pic[draw,kite,align with=dart along c];
\pic[draw,kite,align with=dart along C];
@@ -394,6 +405,58 @@ and restored with the same command (but names switched).
With deformed tiles, there is no guarantee that the inner arcs will match up perfectly.
+\section{Defining New Tiles}
+
+This package includes the capability to define new tiles.
+The command to do this is:
+%
+\begin{verbatim}
+\DefineTile{<name>}{<sides>}{<coordinates>}
+\end{verbatim}
+%
+For example,
+%
+\begin{verbatim}
+\DefineTile {square}{a A a A}
+{
+ {0,0}
+ {1,0}
+ {1,1}
+ {0,1}
+}
+\end{verbatim}
+%
+The \Verb!<sides>! is a list of sides for matching rules.
+Each letter used matches against its opposite case (so it is possible to create a side that matches against itself by using a symbol that \TeX\ regards as having the same upper as lower case; not all symbols work, I've used \Verb+!+ successfully).
+These are also used in path replacing, both a letter and its opposite case are replaced by the corresponding path (but in opposite directions) when the tile is ``baked''.
+The coordinates are passed to the \Verb!fp! module of \LaTeX3 so can involve complicated expressions.
+Note that the trigonometric functions for angles in degrees are \Verb!cosd!, \Verb!sind!, and \Verb!tand!.
+
+Note that the tile must be baked via the command \Verb!\BakePenroseTile! before it can be used.
+
+The new tile can be used with all the same features as the pre-defined Penrose tiles, except for the Lindenmayer systems.
+
+\begin{example}
+\DefineTile {square}{a A a A}
+{
+ {0,0}
+ {1,0}
+ {1,1}
+ {0,1}
+}
+
+\begin{tikzpicture}
+\path[save Penrose path=a] (0,0) to[out=45,in=135] (1,0);
+\BakePenroseTile{square}
+\pic[square,name=A,fill=green];
+\pic[square,align with=A along a1 using 2,name=B,fill=red];
+\pic[square,align with=A along A1 using 2,fill=red];
+\pic[square,align with=A along A2 using 1,fill=red];
+\pic[square,align with=B along a1 using 2,fill=green];
+\pic[square,align with=B along a2 using 1,fill=green];
+\end{tikzpicture}
+\end{example}
+
\section{More Examples}
Let's set some aesthetically pleasing shapes.
@@ -403,14 +466,14 @@ Let's set some aesthetically pleasing shapes.
\path[save Penrose path=a] (0,0) to[out=-30,in=100] (1,0);
\path[save Penrose path=b] (0,0) to[out=0,in=140] (1,0);
\path[save Penrose path=c] (0,0) to[out=-40,in=140] (1,0);
-\MakePenroseTile{thin rhombus}
-\MakePenroseTile{thick rhombus}
-\MakePenroseTile{golden triangle}
-\MakePenroseTile{reverse golden triangle}
-\MakePenroseTile{golden gnomon}
-\MakePenroseTile{reverse golden gnomon}
-\MakePenroseTile{kite}
-\MakePenroseTile{dart}
+\BakePenroseTile{thin rhombus}
+\BakePenroseTile{thick rhombus}
+\BakePenroseTile{golden triangle}
+\BakePenroseTile{reverse golden triangle}
+\BakePenroseTile{golden gnomon}
+\BakePenroseTile{reverse golden gnomon}
+\BakePenroseTile{kite}
+\BakePenroseTile{dart}
\end{tikzpicture}
\end{justexample}
@@ -418,14 +481,14 @@ Let's set some aesthetically pleasing shapes.
\path[save Penrose path=a] (0,0) to[out=-30,in=100] (1,0);
\path[save Penrose path=b] (0,0) to[out=0,in=140] (1,0);
\path[save Penrose path=c] (0,0) to[out=-40,in=140] (1,0);
-\MakePenroseTile{thin rhombus}
-\MakePenroseTile{thick rhombus}
-\MakePenroseTile{golden triangle}
-\MakePenroseTile{reverse golden triangle}
-\MakePenroseTile{golden gnomon}
-\MakePenroseTile{reverse golden gnomon}
-\MakePenroseTile{kite}
-\MakePenroseTile{dart}
+\BakePenroseTile{thin rhombus}
+\BakePenroseTile{thick rhombus}
+\BakePenroseTile{golden triangle}
+\BakePenroseTile{reverse golden triangle}
+\BakePenroseTile{golden gnomon}
+\BakePenroseTile{reverse golden gnomon}
+\BakePenroseTile{kite}
+\BakePenroseTile{dart}
\end{tikzpicture}
@@ -676,14 +739,14 @@ Lastly, here's an example that generates full page patterns.
\path[save Penrose path=a] (0,0) -- (1,0);
\path[save Penrose path=b] (0,0) -- (1,0);
\path[save Penrose path=c] (0,0) -- (1,0);
-\MakePenroseTile{thin rhombus}
-\MakePenroseTile{thick rhombus}
-\MakePenroseTile{golden triangle}
-\MakePenroseTile{reverse golden triangle}
-\MakePenroseTile{golden gnomon}
-\MakePenroseTile{reverse golden gnomon}
-\MakePenroseTile{kite}
-\MakePenroseTile{dart}
+\BakePenroseTile{thin rhombus}
+\BakePenroseTile{thick rhombus}
+\BakePenroseTile{golden triangle}
+\BakePenroseTile{reverse golden triangle}
+\BakePenroseTile{golden gnomon}
+\BakePenroseTile{reverse golden gnomon}
+\BakePenroseTile{kite}
+\BakePenroseTile{dart}
\end{tikzpicture}
\newpage
diff --git a/graphics/pgf/contrib/penrose/penrose_code.dtx b/graphics/pgf/contrib/penrose/penrose_code.dtx
index be7030312f..cdc6356965 100644
--- a/graphics/pgf/contrib/penrose/penrose_code.dtx
+++ b/graphics/pgf/contrib/penrose/penrose_code.dtx
@@ -34,7 +34,7 @@ See http://www.latex-project.org/lppl.txt
\endpreamble
\postamble
-Copyright (C) 2014-2018 by Andrew Stacey <loopspace@mathforge.org>
+Copyright (C) 2014-2019 by Andrew Stacey <loopspace@mathforge.org>
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License (LPPL), either
@@ -46,18 +46,18 @@ http://www.latex-project.org/lppl.txt
This work is "maintained" (as per LPPL maintenance status) by
Andrew Stacey.
-This work consists of the files penrose3.dtx
+This work consists of the files penrose_code.dtx
penrose.tex
and the derived files penrose.ins
- penrose3.pdf
+ penrose_code.pdf
penrose.pdf
tikzlibrarypenrose.code.tex
- README
+ README.txt
\endpostamble
\usedir{tex/latex/penrose}
\generate{
- \file{tikzlibrarypenrose.code.tex}{\from{\jobname.dtx}{library}}
+ \file{tikzlibrarypenrose.code.tex}{\from{\jobname.dtx}{package}}
}
%</install>
%<install>\endbatchfile
@@ -78,11 +78,11 @@ and the derived files penrose.ins
\fi
%</internal>
%<*driver>
-\documentclass[full]{l3doc}
+\documentclass{l3doc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{tikz}
-\usepackage{trace}
+%\usepackage{trace}
\usetikzlibrary{penrose}
%\traceoff
%\usepackage[numbered]{hypdoc}
@@ -139,6 +139,8 @@ and the derived files penrose.ins
%
%
% \changes{1.0}{2014/05/07}{Converted to DTX file}
+% \changes{1.2}{2019/02/23}{Added general tile creation code}
+% \changes{1.4}{2021/01/22}{Adapted to latest version of spath3}
%
% \DoNotIndex
% {
@@ -149,39 +151,50 @@ and the derived files penrose.ins
% \endcsname,
% }%
%
+%
% \providecommand*{\url}{\texttt}
+% \GetFileInfo{tikzlibrarypenrose.code.tex}
% \title{The \textsf{Penrose} package}
% \author{Andrew Stacey\texorpdfstring{\\ \url{loopspace@mathforge.org}}{}}
-% \date{1.0 from 2018/07/10}
+% \date{\fileversion~from \filedate}
%
%
% \maketitle
%
+% \tableofcontents
+%
+% \begin{documentation}
%
% \section{Introduction}
%
% This is a TikZ library for drawing Penrose tiles (kite/dart, rhombus, and pentagon versions).
% It provides two methods of drawing: one in which an automatic pattern is built, and one where the tiles can be placed ``by hand''.
% The tiles can be shaped and (hopefully!) still fit together.
-% For user documentation, see the \Verb+penrose.pdf+ file.
+% For full user documentation, see the \Verb+penrose.pdf+ file.
%
-% \StopEventually{}
%
-% \section{Implementation}
+% \end{documentation}
%
-% \iffalse
-%<*library>
-% \fi
-% \subsection{Initialisation}
+% \begin{implementation}
%
+% \section{Implementation}
%
% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+% \begin{macrocode}
%<@@=penrose>
% \end{macrocode}
+%
+% \subsection{Initialisation}
+%
+%
% We use the \Verb+spath3+ library for manipulating the paths that will make up the tiles.
%
% \begin{macrocode}
+\ProvidesExplFile {tikzlibrarypenrose.code.tex} {2021/01/22} {1.4} {TikZ pics for Penrose and other tiles}
\RequirePackage{spath3}
+\usetikzlibrary{spath3}
% \end{macrocode}
% Now we move in to the realm of \LaTeX3.
% \begin{macrocode}
@@ -189,50 +202,75 @@ and the derived files penrose.ins
% \end{macrocode}
%
% Start with some basic paths (lines) for the sides of the tiles so that we know that we have well-defined tiles at the outset.
-%
-% \begin{macrocode}
-\MakeSPath{Penrose path a}
- {
- \pgfsyssoftpath@movetotoken{0pt}{0pt}
- \pgfsyssoftpath@linetotoken{1pt}{0pt}
- }
-\SPathPrepare{Penrose path a}
-\CloneSPath {Penrose path a}{Penrose path b}
-\CloneSPath {Penrose path a}{Penrose path c}
-\CloneSPath {Penrose path a}{Penrose path d}
-\CloneSPath {Penrose path a}{Penrose path A}
-\CloneSPath {Penrose path a}{Penrose path B}
-\CloneSPath {Penrose path a}{Penrose path C}
-\CloneSPath {Penrose path a}{Penrose path D}
-% \end{macrocode}
-%
-% \begin{variable}{\l__penrose_tmpa_fp, \l__penrose_tmpb_fp, \l__penrose_tmpc_fp, \l__penrose_tmpa_tl, \l__penrose_tmpb_tl, \l__penrose_tmpc_tl}
+% These are globally defined as we will frequently want to define them in one tikzpicture and use them in another.
+%
+% \begin{macrocode}
+\tl_new:N \g_@@_side_a_tl
+\tl_new:N \g_@@_side_b_tl
+\tl_new:N \g_@@_side_c_tl
+\tl_new:N \g_@@_side_d_tl
+\tl_new:N \g_@@_side_e_tl
+\tl_new:N \g_@@_side_A_tl
+\tl_new:N \g_@@_side_B_tl
+\tl_new:N \g_@@_side_C_tl
+\tl_new:N \g_@@_side_D_tl
+\tl_new:N \g_@@_side_E_tl
+\tl_gset:Nn \g_@@_side_a_tl
+{
+ \pgfsyssoftpath@movetotoken{0pt}{0pt}
+ \pgfsyssoftpath@linetotoken{1pt}{0pt}
+}
+\tl_gset_eq:NN \g_@@_side_b_tl \g_@@_side_a_tl
+\tl_gset_eq:NN \g_@@_side_c_tl \g_@@_side_a_tl
+\tl_gset_eq:NN \g_@@_side_d_tl \g_@@_side_a_tl
+\tl_gset_eq:NN \g_@@_side_e_tl \g_@@_side_a_tl
+\tl_gset_eq:NN \g_@@_side_A_tl \g_@@_side_a_tl
+\tl_gset_eq:NN \g_@@_side_B_tl \g_@@_side_a_tl
+\tl_gset_eq:NN \g_@@_side_C_tl \g_@@_side_a_tl
+\tl_gset_eq:NN \g_@@_side_D_tl \g_@@_side_a_tl
+\tl_gset_eq:NN \g_@@_side_E_tl \g_@@_side_a_tl
+% \end{macrocode}
+%
+% \begin{variable}{\l_@@_tmpa_fp, \l_@@_tmpb_fp, \l_@@_tmpc_fp, \l_@@_tmpa_tl, \l_@@_tmpb_tl, \l_@@_tmpc_tl, \l_@@_tmpd_tl, \l_@@_tmpa_int, \l_@@_tmpb_int, \l_@@_xa_dim, \l_@@_ya_dim, \l_@@_xb_dim, \l_@@_yb_dim, \l_@@_tmpa_prop}
% We need a few temporary variables to hold intermediate calculations.
%
% \begin{macrocode}
-\fp_new:N \l__penrose_tmpa_fp
-\fp_new:N \l__penrose_tmpb_fp
-\fp_new:N \l__penrose_tmpc_fp
-\tl_new:N \l__penrose_tmpa_tl
-\tl_new:N \l__penrose_tmpb_tl
-\tl_new:N \l__penrose_tmpc_tl
+\fp_new:N \l_@@_tmpa_fp
+\fp_new:N \l_@@_tmpb_fp
+\fp_new:N \l_@@_tmpc_fp
+\str_new:N \l_@@_tmpa_str
+\str_new:N \l_@@_tmpb_str
+\tl_new:N \l_@@_tmpa_tl
+\tl_new:N \l_@@_tmpb_tl
+\tl_new:N \l_@@_tmpc_tl
+\tl_new:N \l_@@_tmpd_tl
+\tl_new:N \l_@@_tmp_tile_path_tl
+\tl_new:N \g_@@_smuggle_tl
+\int_new:N \l_@@_tmpa_int
+\int_new:N \l_@@_tmpb_int
+\dim_new:N \l_@@_xa_dim
+\dim_new:N \l_@@_ya_dim
+\dim_new:N \l_@@_xb_dim
+\dim_new:N \l_@@_yb_dim
+\prop_new:N \l_@@_tmpa_prop
% \end{macrocode}
% \end{variable}
%
% \subsection{Creating the Tiles}
%
-% \begin{macro}[internal]{\penrose_normalise_path:n}
+% \begin{macro}[internal]{\@@_normalise_path:Nn}
% When defining the path for a side, we normalise so that it starts at the origin and ends at \Verb+(1pt,0pt)+.
% \begin{macrocode}
-\cs_new_nopar:Npn \penrose_normalise_path:n #1
+\cs_new_nopar:Npn \@@_normalise_path:Nn #1#2
{
% \end{macrocode}
% Get the initial point of the path and convert to floating point.
% \begin{macrocode}
- \spath_get:nnN {#1} {initial point} \l__penrose_tmpa_tl
- \fp_set:Nn \l__penrose_tmpa_fp {\tl_head:N \l__penrose_tmpa_tl}
- \tl_set:Nx \l__penrose_tmpa_tl {\tl_tail:N \l__penrose_tmpa_tl}
- \fp_set:Nn \l__penrose_tmpb_fp {\tl_head:N \l__penrose_tmpa_tl}
+ \group_begin:
+ \spath_initialpoint:Nn \l_@@_tmpa_tl {#2}
+ \fp_set:Nn \l_@@_tmpa_fp {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \fp_set:Nn \l_@@_tmpb_fp {\tl_head:N \l_@@_tmpa_tl}
% \end{macrocode}
% Get the final point of the path, and compute the difference of the final and initial points.
%
@@ -245,71 +283,80 @@ and the derived files penrose.ins
% \]
%
% \begin{macrocode}
- \spath_get:nnN {#1} {final point} \l__penrose_tmpa_tl
- \fp_set:Nn \l__penrose_tmpa_fp
- {\tl_head:N \l__penrose_tmpa_tl - \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpa_tl {\tl_tail:N \l__penrose_tmpa_tl}
- \fp_set:Nn \l__penrose_tmpb_fp
- {\tl_head:N \l__penrose_tmpa_tl - \l__penrose_tmpb_fp}
+ \spath_finalpoint:Nn \l_@@_tmpa_tl {#2}
+ \fp_set:Nn \l_@@_tmpa_fp
+ {\tl_head:N \l_@@_tmpa_tl - \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \fp_set:Nn \l_@@_tmpb_fp
+ {\tl_head:N \l_@@_tmpa_tl - \l_@@_tmpb_fp}
% \end{macrocode}
% Now compute the square of the length of the path for scaling.
% \begin{macrocode}
- \fp_set:Nn \l__penrose_tmpc_fp
- {\l__penrose_tmpa_fp^2 + \l__penrose_tmpb_fp^2}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_tmpa_fp/\l__penrose_tmpc_fp}
- \fp_set:Nn \l__penrose_tmpb_fp {\l__penrose_tmpb_fp/\l__penrose_tmpc_fp}
- \fp_set:Nn \l__penrose_tmpc_fp {-\l__penrose_tmpb_fp}
+ \fp_set:Nn \l_@@_tmpc_fp
+ {\l_@@_tmpa_fp^2 + \l_@@_tmpb_fp^2}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_tmpa_fp/\l_@@_tmpc_fp}
+ \fp_set:Nn \l_@@_tmpb_fp {\l_@@_tmpb_fp/\l_@@_tmpc_fp}
+ \fp_set:Nn \l_@@_tmpc_fp {-\l_@@_tmpb_fp}
% \end{macrocode}
% Now construct the matrix.
% \begin{macrocode}
- \tl_set:Nx \l__penrose_tmpb_tl
+ \tl_set:Nx \l_@@_tmpb_tl
{
- {\fp_use:N \l__penrose_tmpa_fp}
- {\fp_use:N \l__penrose_tmpb_fp}
- {\fp_use:N \l__penrose_tmpc_fp}
- {\fp_use:N \l__penrose_tmpa_fp}
+ {\fp_use:N \l_@@_tmpa_fp}
+ {\fp_use:N \l_@@_tmpc_fp} % swapped
+ {\fp_use:N \l_@@_tmpb_fp} % swapped
+ {\fp_use:N \l_@@_tmpa_fp}
}
% \end{macrocode}
% Get the initial point back again for the translation part.
% \begin{macrocode}
- \spath_get:nnN {#1} {initial point} \l__penrose_tmpa_tl
+ \spath_initialpoint:Nn \l_@@_tmpa_tl {#2}
% \end{macrocode}
% But we need to premultiply by the matrix because of how the transformations are applied.
% \begin{macrocode}
- \fp_set:Nn \l__penrose_tmpa_fp
+ \fp_set:Nn \l_@@_tmpa_fp
{
- (-1) * \l__penrose_tmpa_fp * \tl_head:N \l__penrose_tmpa_tl
- + (-1) * \l__penrose_tmpb_fp * \tl_tail:N \l__penrose_tmpa_tl
+ (-1) * \l_@@_tmpa_fp * \tl_head:N \l_@@_tmpa_tl
+ + (-1) * \l_@@_tmpb_fp * \tl_tail:N \l_@@_tmpa_tl
}
- \fp_set:Nn \l__penrose_tmpb_fp
+ \fp_set:Nn \l_@@_tmpb_fp
{
- (-1) * \l__penrose_tmpa_fp * \tl_tail:N \l__penrose_tmpa_tl
- + \l__penrose_tmpb_fp * \tl_head:N \l__penrose_tmpa_tl
+ (-1) * \l_@@_tmpa_fp * \tl_tail:N \l_@@_tmpa_tl
+ + \l_@@_tmpb_fp * \tl_head:N \l_@@_tmpa_tl
}
% \end{macrocode}
% Finally, we apply the transformation to the path.
% \begin{macrocode}
- \tl_put_right:Nx \l__penrose_tmpb_tl {
- {\fp_to_dim:N \l__penrose_tmpa_fp}
- {\fp_to_dim:N \l__penrose_tmpb_fp}
+ \tl_put_right:Nx \l_@@_tmpb_tl {
+ {\fp_to_dim:N \l_@@_tmpa_fp}
+ {\fp_to_dim:N \l_@@_tmpb_fp}
}
- \spath_transform:nV {#1} \l__penrose_tmpb_tl
+ \spath_transform:NnV \l_@@_tmpa_tl {#2} \l_@@_tmpb_tl
+ \tl_gset_eq:NN \g_@@_smuggle_tl \l_@@_tmpa_tl
+ \group_end:
+ \tl_set_eq:NN #1 \g_@@_smuggle_tl
+ \tl_gclear:N \g_@@_smuggle_tl
}
+\cs_generate_variant:Nn \@@_normalise_path:Nn {NV, cn, cV}
+\cs_new_protected_nopar:Npn \@@_normalise_path:N #1
+{
+ \@@_normalise_path:NV #1#1
+}
+\cs_generate_variant:Nn \@@_normalise_path:N {c}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\SetPenrosePath}
+% \begin{function}{\SetPenrosePath}
% This sets the path corresponding to a particular side to the current path, and normalises it.
% \begin{macrocode}
\NewDocumentCommand \SetPenrosePath { m }
{
- \pgfsyssoftpath@getcurrentpath\l__penrose_tmpa_tl
- \spath_clear_new:n {Penrose path #1}
- \spath_put:nnV {Penrose path #1} {path} \l__penrose_tmpa_tl
- \penrose_normalise_path:n {Penrose path #1}
+ \pgfsyssoftpath@getcurrentpath\l_@@_tmpa_tl
+ \@@_normalise_path:N \l_@@_tmpa_tl
+ \tl_gset_eq:cN {g_@@_side_#1_tl} \l_@@_tmpa_tl
}
% \end{macrocode}
-% \end{macro}
+% \end{function}
%
% \begin{macro}[internal]{\tikz_scan_point:n}
% This is a wrapper around \Verb+\tikz@scan@one@point+ to make it easier to use with \LaTeX3 variables.
@@ -322,32 +369,32 @@ and the derived files penrose.ins
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\penrose_make_tile:nnn}
+% \begin{macro}[internal]{\@@_make_tile:nnn}
% This builds the tile path from its pieces.
% The arguments are the name of the tile, the descriptions of the sides, and a token list of the coordinates.
% \begin{macrocode}
-\cs_new_nopar:Npn \penrose_make_tile:nnn #1#2#3
+\cs_new_nopar:Npn \@@_make_tile:nnn #1#2#3
{
% \end{macrocode}
% Get the first coordinate and initialise the path with a move to this point.
% \begin{macrocode}
- \tl_set:Nn \l__penrose_tmpa_tl {#3}
- \tl_set:Nx \l__penrose_tmpb_tl {\tl_head:N \l__penrose_tmpa_tl}
- \tl_set:Nn \l__penrose_tmpa_tl {\pgfsyssoftpath@movetotoken}
- \tikz_scan_point:V \l__penrose_tmpb_tl
- \tl_put_right:Nx \l__penrose_tmpa_tl
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#3}
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nn \l_@@_tmpa_tl {\pgfsyssoftpath@movetotoken}
+ \tikz_scan_point:V \l_@@_tmpb_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl
{
{\dim_use:N \pgf@x}{\dim_use:N \pgf@y}
}
- \spath_clear_new:n {Penrose path tile #1}
- \spath_put:nnV {Penrose path tile #1} {path} \l__penrose_tmpa_tl
+ \tl_set_eq:NN \l_@@_tmp_tile_path_tl \l_@@_tmpa_tl
% \end{macrocode}
% Now we have our path initialised, we can start appending the side paths according to the specification in the second argument.
%
% We append the initial coordinate to the end of the list to make a closed cycle.
% \begin{macrocode}
- \tl_set:Nn \l__penrose_tmpa_tl {#3}
- \tl_put_right:Nx \l__penrose_tmpa_tl {{\tl_head:N \l__penrose_tmpa_tl}}
+ \tl_set:Nn \l_@@_tmpa_tl {#3}
+ \tl_put_right:Nx \l_@@_tmpa_tl {{\tl_head:N \l_@@_tmpa_tl}}
% \end{macrocode}
% Now we walk through the description of the sides, adding the specified paths to our tile path.
% \begin{macrocode}
@@ -355,66 +402,72 @@ and the derived files penrose.ins
% \end{macrocode}
% Clone the path for this side.
% \begin{macrocode}
- \spath_clone:nn {Penrose path ##1} {Penrose path tmpa}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_head:n {##1}}
+ \tl_set_eq:Nc \l_@@_tmpd_tl {g_@@_side_ \tl_use:N \l_@@_tmpc_tl _tl}
% \end{macrocode}
% Strip off the next coordinate, and convert it to a point.
% \begin{macrocode}
- \tl_set:Nx \l__penrose_tmpb_tl {\tl_head:N \l__penrose_tmpa_tl}
- \tl_set:Nx \l__penrose_tmpa_tl {\tl_tail:N \l__penrose_tmpa_tl}
- \tikz_scan_point:V \l__penrose_tmpb_tl
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \tikz_scan_point:V \l_@@_tmpb_tl
% \end{macrocode}
% Store the resulting coordinate.
% \begin{macrocode}
- \fp_set:Nn \l__penrose_tmpa_fp { \pgf@x }
- \fp_set:Nn \l__penrose_tmpb_fp { \pgf@y }
+ \fp_set:Nn \l_@@_tmpa_fp { \pgf@x }
+ \fp_set:Nn \l_@@_tmpb_fp { \pgf@y }
% \end{macrocode}
% Now get the next coordinate.
% \begin{macrocode}
- \tl_set:Nx \l__penrose_tmpb_tl {\tl_head:N \l__penrose_tmpa_tl}
- \tikz_scan_point:V \l__penrose_tmpb_tl
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tikz_scan_point:V \l_@@_tmpb_tl
% \end{macrocode}
% We want the difference between the two coordinates.
% \begin{macrocode}
- \fp_set:Nn \l__penrose_tmpa_fp {\pgf@x - \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpb_fp {\pgf@y - \l__penrose_tmpb_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\pgf@x - \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpb_fp {\pgf@y - \l_@@_tmpb_fp}
% \end{macrocode}
% This is converted into a transformation matrix.
% \begin{macrocode}
- \fp_set:Nn \l__penrose_tmpc_fp {-\l__penrose_tmpb_fp}
- \tl_set:Nx \l__penrose_tmpb_tl
+ \fp_set:Nn \l_@@_tmpc_fp {-\l_@@_tmpb_fp}
+ \tl_set:Nx \l_@@_tmpb_tl
{
- {\fp_use:N \l__penrose_tmpa_fp}
- {\fp_use:N \l__penrose_tmpc_fp}
- {\fp_use:N \l__penrose_tmpb_fp}
- {\fp_use:N \l__penrose_tmpa_fp}
+ {\fp_use:N \l_@@_tmpa_fp}
+ {\fp_use:N \l_@@_tmpb_fp} % not swapped
+ {\fp_use:N \l_@@_tmpc_fp} % not swapped
+ {\fp_use:N \l_@@_tmpa_fp}
{0}
{0}
}
% \end{macrocode}
% The transformation is applied to the cloned path.
% \begin{macrocode}
- \spath_transform:nV {Penrose path tmpa} \l__penrose_tmpb_tl
+ \spath_transform:NV \l_@@_tmpd_tl \l_@@_tmpb_tl
% \end{macrocode}
% And this is welded to the tile path.
% \begin{macrocode}
- \spath_weld:nn {Penrose path tile #1} {Penrose path tmpa}
+ \spath_weld:NV \l_@@_tmp_tile_path_tl \l_@@_tmpd_tl
}
% \end{macrocode}
% At the end we close the path.
% \begin{macrocode}
- \spath_close_path:n {Penrose path tile #1}
+ \spath_close:N \l_@@_tmp_tile_path_tl
+ \tl_gset_eq:NN \g_@@_smuggle_tl \l_@@_tmp_tile_path_tl
+ \group_end:
+ \tl_gclear_new:c {g_@@_tile_#1_tl}
+ \tl_gset_eq:cN {g_@@_tile_#1_tl} \g_@@_smuggle_tl
+ \tl_gclear:N \g_@@_smuggle_tl
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\penrose_make_tile:nn}
+% \begin{macro}[internal]{\@@_make_tile:nn}
% A wrapper around the above which allows us to specify the second two arguments as two items in a token list.
% \begin{macrocode}
-\cs_new_nopar:Npn \penrose_make_tile:nn #1#2
+\cs_new_nopar:Npn \@@_make_tile:nn #1#2
{
- \penrose_make_tile:nnn {#1} #2
+ \@@_make_tile:nnn {#1} #2
}
-\cs_generate_variant:Nn \penrose_make_tile:nn {nV}
+\cs_generate_variant:Nn \@@_make_tile:nn {nV}
% \end{macrocode}
% \end{macro}
%
@@ -422,21 +475,28 @@ and the derived files penrose.ins
%
% The tile specifications are contained in a \Verb+prop+.
% \begin{macrocode}
-\prop_new:N \g__penrose_tiles_prop
+\prop_new:N \g_@@_tiles_prop
% \end{macrocode}
%
-% \begin{macro}[internal]{\tl_add_coordinate:Nnn}
+% \begin{macro}[internal]{\@@_add_coordinate:Nnn, \@@_add_coordinate:w}
% Process a coordinate through \Verb+fp+ and adds it to a token list.
% \begin{macrocode}
-\cs_new_nopar:Npn \tl_add_coordinate:Nnn #1#2#3 {
- \fp_set:Nn \l__penrose_tmpa_fp{#2}
- \fp_set:Nn \l__penrose_tmpb_fp{#3}
+\cs_new_nopar:Npn \@@_add_coordinate:Nnn #1#2#3 {
+ \fp_set:Nn \l_@@_tmpa_fp{#2}
+ \fp_set:Nn \l_@@_tmpb_fp{#3}
\tl_put_right:Nx #1
{
- {(\fp_use:N \l__penrose_tmpa_fp, \fp_use:N \l__penrose_tmpb_fp)}
+ {(\fp_use:N \l_@@_tmpa_fp, \fp_use:N \l_@@_tmpb_fp)}
}
}
% \end{macrocode}
+% Wrapper around the add coordinate command to split at a comma.
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_add_coordinate:w #1#2,#3 \q_stop
+{
+ \@@_add_coordinate:Nnn \l_@@_tmpa_tl {#2}{#3}
+}
+% \end{macrocode}
% \end{macro}
%
% Now we specify the tiles.
@@ -446,182 +506,186 @@ and the derived files penrose.ins
% \begin{itemize}
% \item Thin Rhombus.
% \begin{macrocode}
-\tl_clear:N \l__penrose_tmpa_tl
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{sind(18)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(18)}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{-sind(18)}
+\tl_clear:N \l_@@_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{sind(18)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(18)}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{-sind(18)}
-\prop_gput:Nnx \g__penrose_tiles_prop {thin~ rhombus}
-{{a A B b} {\tl_use:N \l__penrose_tmpa_tl}}
+\prop_gput:Nnx \g_@@_tiles_prop {thin~ rhombus}
+{{a A B b} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Thick Rhombus.
% \begin{macrocode}
-\tl_clear:N \l__penrose_tmpa_tl
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(36)}{sind(36)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(36)}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(36)}{-sind(36)}
+\tl_clear:N \l_@@_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(36)}{sind(36)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(36)}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(36)}{-sind(36)}
-\prop_gput:Nnx \g__penrose_tiles_prop {thick~ rhombus}
-{{B a A b} {\tl_use:N \l__penrose_tmpa_tl}}
+\prop_gput:Nnx \g_@@_tiles_prop {thick~ rhombus}
+{{B a A b} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Dart.
% \begin{macrocode}
-\tl_clear:N \l__penrose_tmpa_tl
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl
+\tl_clear:N \l_@@_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{2*sind(18)*cosd(108)}{2*sind(18)*sind(108)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*sind(18)}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*sind(18)}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{2*sind(18)*cosd(108)}{-2*sind(18)*sind(108)}
-\prop_gput:Nnx \g__penrose_tiles_prop {dart}
-{{c a A C} {\tl_use:N \l__penrose_tmpa_tl}}
+\prop_gput:Nnx \g_@@_tiles_prop {dart}
+{{c a A C} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Kite.
% \begin{macrocode}
-\tl_clear:N \l__penrose_tmpa_tl
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(36)}{sind(36)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(36)}{-sind(36)}
+\tl_clear:N \l_@@_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(36)}{sind(36)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(36)}{-sind(36)}
-\prop_gput:Nnx \g__penrose_tiles_prop {kite}
-{{a c C A} {\tl_use:N \l__penrose_tmpa_tl}}
+\prop_gput:Nnx \g_@@_tiles_prop {kite}
+{{a c C A} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Golden Triangle.
% \begin{macrocode}
-\tl_clear:N \l__penrose_tmpa_tl
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{sind(18)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{-sind(18)}
+\tl_clear:N \l_@@_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{sind(18)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{-sind(18)}
-\prop_gput:Nnx \g__penrose_tiles_prop {golden~ triangle}
-{{a c b} {\tl_use:N \l__penrose_tmpa_tl}}
+\prop_gput:Nnx \g_@@_tiles_prop {golden~ triangle}
+{{a c b} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Reverse Golden Triangle.
% \begin{macrocode}
-\tl_clear:N \l__penrose_tmpa_tl
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{sind(18)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{-sind(18)}
+\tl_clear:N \l_@@_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{sind(18)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{-sind(18)}
-\prop_gput:Nnx \g__penrose_tiles_prop {reverse~ golden~ triangle}
-{{B C A} {\tl_use:N \l__penrose_tmpa_tl}}
+\prop_gput:Nnx \g_@@_tiles_prop {reverse~ golden~ triangle}
+{{B C A} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Golden Gnomon
% \begin{macrocode}
-\tl_clear:N \l__penrose_tmpa_tl
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(36)}{sind(36)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(36)}{0}
+\tl_clear:N \l_@@_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(36)}{sind(36)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(36)}{0}
-\prop_gput:Nnx \g__penrose_tiles_prop {golden~ gnomon}
-{{C b A} {\tl_use:N \l__penrose_tmpa_tl}}
+\prop_gput:Nnx \g_@@_tiles_prop {golden~ gnomon}
+{{C b A} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Reverse Golden Gnomon
% \begin{macrocode}
-\tl_clear:N \l__penrose_tmpa_tl
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(36)}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(36)}{-sind(36)}
-\prop_gput:Nnx \g__penrose_tiles_prop {reverse~ golden~ gnomon}
-{{a B c} {\tl_use:N \l__penrose_tmpa_tl}}
+\tl_clear:N \l_@@_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(36)}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(36)}{-sind(36)}
+\prop_gput:Nnx \g_@@_tiles_prop {reverse~ golden~ gnomon}
+{{a B c} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Primary Pentagon (pentagon 5)
% \begin{macrocode}
-\tl_clear:N \l__penrose_tmpa_tl
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(108)}{sind(108)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl
+\tl_clear:N \l_@@_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(108)}{sind(108)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{1+cosd(72)+cosd(144)}{sind(72)+sind(144)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1+cosd(72)}{sind(72)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1}{0}
-\prop_gput:Nnx \g__penrose_tiles_prop {pentagon~ 5}
-{{a a a a a} {\tl_use:N \l__penrose_tmpa_tl}}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1+cosd(72)}{sind(72)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1}{0}
+\prop_gput:Nnx \g_@@_tiles_prop {pentagon~ 5}
+{{a a a a a} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Secondary Pentagon (pentagon 3)
% \begin{macrocode}
-\prop_gput:Nnx \g__penrose_tiles_prop {pentagon~ 3}
-{{A b a a b} {\tl_use:N \l__penrose_tmpa_tl}}
+\prop_gput:Nnx \g_@@_tiles_prop {pentagon~ 3}
+{{A b a a b} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Tertiary Pentagon (pentagon 2)
% \begin{macrocode}
-\prop_gput:Nnx \g__penrose_tiles_prop {pentagon~ 2}
-{{d A c c A} {\tl_use:N \l__penrose_tmpa_tl}}
+\prop_gput:Nnx \g_@@_tiles_prop {pentagon~ 2}
+{{d A e c A} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Pentagram
% \begin{macrocode}
-\tl_clear:N \l__penrose_tmpa_tl
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1-cosd(36)}{-sind(36)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl
+\tl_clear:N \l_@@_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1-cosd(36)}{-sind(36)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{1-cosd(36)-cosd(108)}{-sind(36)-sind(108)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(108)}{-sind(108)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(108)}{-sind(108)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{-1+3*cosd(108)+cosd(36)}{-sind(36)-sind(108)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{-1+2*cosd(108)+cosd(36)}{-sind(36)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {-1+2*cosd(108)}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(108)}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(108)}{sind(108)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0}
-\prop_gput:Nnx \g__penrose_tiles_prop {pentagram}
-{{C C C C C C C C C C} {\tl_use:N \l__penrose_tmpa_tl}}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {-1+2*cosd(108)}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(108)}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(108)}{sind(108)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
+\prop_gput:Nnx \g_@@_tiles_prop {pentagram}
+{{C E C E C E C E C E} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Boat
% \begin{macrocode}
-\tl_clear:N \l__penrose_tmpa_tl
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {-1+2*cosd(108)}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(108)}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(108)}{sind(108)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1-cosd(36)}{-sind(36)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl
+\tl_clear:N \l_@@_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {-1+2*cosd(108)}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(108)}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(108)}{sind(108)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1-cosd(36)}{-sind(36)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{-1+2*cosd(108)+cosd(36)}{-sind(36)}
-\prop_gput:Nnx \g__penrose_tiles_prop {boat}
-{{C C C C B D B} {\tl_use:N \l__penrose_tmpa_tl}}
+\prop_gput:Nnx \g_@@_tiles_prop {boat}
+{{C E C E B D B} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \item Diamond.
% \begin{macrocode}
-\tl_clear:N \l__penrose_tmpa_tl
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{sind(18)}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(18)}{0}
-\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{-sind(18)}
-\prop_gput:Nnx \g__penrose_tiles_prop {diamond}
-{{D B B D} {\tl_use:N \l__penrose_tmpa_tl}}
+\tl_clear:N \l_@@_tmpa_tl
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{sind(18)}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(18)}{0}
+\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{-sind(18)}
+\prop_gput:Nnx \g_@@_tiles_prop {diamond}
+{{D B B D} {\tl_use:N \l_@@_tmpa_tl}}
% \end{macrocode}
%
% \end{itemize}
%
-% \begin{macro}[internal]{\MakePenroseTile}
+% \begin{function}{\BakePenroseTile}
% This is the user wrapper around the tile creation macros.
% \begin{macrocode}
-\NewDocumentCommand \MakePenroseTile {m}
+\NewDocumentCommand \BakePenroseTile {m}
{
- \prop_get:NnN \g__penrose_tiles_prop {#1} \l__penrose_tmpa_tl
- \penrose_make_tile:nV {#1} \l__penrose_tmpa_tl
+ \prop_get:NnN \g_@@_tiles_prop {#1} \l_@@_tmpa_tl
+ \@@_make_tile:nV {#1} \l_@@_tmpa_tl
}
% \end{macrocode}
-% \end{macro}
+% For backwards compatibility.
+% \begin{macrocode}
+\cs_set_eq:NN \MakePenroseTile \BakePenroseTile
+% \end{macrocode}
+% \end{function}
%
-% \begin{macro}[internal]{\UsePenroseTile}
+% \begin{function}{\UsePenroseTile}
% This is the command that actually places a tile on the page.
% The first argument is optional and is for styling.
% \begin{macrocode}
@@ -631,36 +695,36 @@ and the derived files penrose.ins
% We need to transform the tile to correspond to the current transformation matrix.
% To ensure that we only transform the current tile, we clone it first.
% \begin{macrocode}
- \spath_clone:nn {Penrose path tile #2} {Penrose path tmpa}
+ \tl_set_eq:Nc \l_@@_tmp_tile_path_tl {g_@@_tile_#2_tl}
% \end{macrocode}
% The transformation matrix returned by PGF appears to be transposed from what it should be.
% (This needs a little more investigation, it might be that I've implemented the multiplication incorrectly here.)
% \begin{macrocode}
- \pgfgettransform \l__penrose_tmpa_tl
- \tl_clear:N \l__penrose_tmpb_tl
- \tl_set:Nx \l__penrose_tmpb_tl {{\tl_head:N \l__penrose_tmpa_tl}}
- \tl_set:Nx \l__penrose_tmpa_tl {\tl_tail:N \l__penrose_tmpa_tl}
- \tl_put_right:Nx \l__penrose_tmpb_tl
- {
- {\tl_item:Nn \l__penrose_tmpa_tl {2}}
- }
- \tl_put_right:Nx \l__penrose_tmpb_tl
- {
- {\tl_item:Nn \l__penrose_tmpa_tl {1}}
- }
- \tl_set:Nx \l__penrose_tmpa_tl {\tl_tail:N \l__penrose_tmpa_tl}
- \tl_set:Nx \l__penrose_tmpa_tl {\tl_tail:N \l__penrose_tmpa_tl}
- \tl_put_right:NV \l__penrose_tmpb_tl \l__penrose_tmpa_tl
+ \pgfgettransform \l_@@_tmpa_tl
+% \tl_clear:N \l_@@_tmpb_tl
+% \tl_set:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+% \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+% \tl_put_right:Nx \l_@@_tmpb_tl
+% {
+% {\tl_item:Nn \l_@@_tmpa_tl {1}}
+% }
+% \tl_put_right:Nx \l_@@_tmpb_tl
+% {
+% {\tl_item:Nn \l_@@_tmpa_tl {2}}
+% }
+% \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+% \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+% \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpa_tl
% \end{macrocode}
% Apply the transformation, protocol the path, and render it.
% \begin{macrocode}
- \spath_transform:nV {Penrose path tmpa} \l__penrose_tmpb_tl
- \spath_protocol_path:n {Penrose path tmpa}
- \spath_tikz_path:nn {#1}{Penrose path tmpa}
+ \spath_transform:NV \l_@@_tmp_tile_path_tl \l_@@_tmpa_tl
+ \spath_tikz_path:nV {#1} \l_@@_tmp_tile_path_tl
}
% \end{macrocode}
-% \end{macro}
+% \end{function}
%
+% \begin{macro}{save Penrose path}
% This is a style for a user to take a path and make it into the path for one of the sides.
% It needs to store both that side and the reverse.
% \begin{macrocode}
@@ -670,60 +734,395 @@ and the derived files penrose.ins
% \end{macrocode}
% Get the current path.
% \begin{macrocode}
- \pgfsyssoftpath@getcurrentpath\l__penrose_tmpa_tl
-% \end{macrocode}
-% Clear the receiving path, and store the current path in it.
-% \begin{macrocode}
- \spath_clear_new:n {Penrose path #1}
- \spath_put:nnV {Penrose path #1} {path} \l__penrose_tmpa_tl
+ \pgfsyssoftpath@getcurrentpath\l_@@_tmpa_tl
% \end{macrocode}
-% Normalise the path.
+% Normalise the path and save.
% \begin{macrocode}
- \penrose_normalise_path:n {Penrose path #1}
+ \@@_normalise_path:N \l_@@_tmpa_tl
+ \tl_gclear_new:c {g_@@_side_#1_tl}
+ \tl_gset_eq:cN {g_@@_side_#1_tl} \l_@@_tmpa_tl
% \end{macrocode}
% Now create the reverse path.
% The name is the upper case version.
% \begin{macrocode}
- \tex_uppercase:D {\tl_set:Nx \l__penrose_tmpa_tl {#1}}
+ \tl_set:Nx \l_@@_tmpb_tl {\str_uppercase:n {#1}}
% \end{macrocode}
-% Clone the path.
+% Reverse the path, and relocate to the interval \([0,1]\).
% \begin{macrocode}
- \spath_clone:nn {Penrose path #1}
- {Penrose path \tl_use:N \l__penrose_tmpa_tl }
-% \end{macrocode}
-% Reverse it.
-% \begin{macrocode}
- \spath_reverse:n {Penrose path \tl_use:N \l__penrose_tmpa_tl}
-% \end{macrocode}
-% Swap the start and end.
-% \begin{macrocode}
- \spath_transform:nnnnnnn {Penrose path \tl_use:N \l__penrose_tmpa_tl}
- {-1} {0} {0} {-1} {1} {0}
+ \spath_reverse:N \l_@@_tmpa_tl
+ \spath_transform:Nnnnnnn \l_@@_tmpa_tl {-1} {0} {0} {-1} {1} {0}
+ \tl_gclear_new:c {g_@@_side_ \tl_use:N \l_@@_tmpb_tl _tl}
+ \tl_gset_eq:cN {g_@@_side_ \tl_use:N \l_@@_tmpb_tl _tl} \l_@@_tmpa_tl
}
},
+ clone~ Penrose~ side~ path/.style~ 2~ args={
+ spath/set~ name=Penrose~side,
+ spath/clone~ global={#1}{#2}
+ },
+ spath/prefix/Penrose~side/.style={
+ spath/set~ prefix=g_@@_side_,
+ },
+ spath/suffix/Penrose~side/.style={
+ spath/set~ suffix=_tl,
+ },
+ clone~ Penrose~ tile~ path/.style~ 2~ args={
+ spath/set~ name=Penrose~tile,
+ spath/clone~ global={#1}{#2}
+ },
+ spath/prefix/Penrose~tile/.style={
+ spath/set~ prefix=g_@@_tile_,
+ },
+ spath/suffix/Penrose~tile/.style={
+ spath/set~ suffix=_tl,
+ },
expand~ key/.code={
\exp_args:NV \pgfkeysalso #1
}
}
% \end{macrocode}
+% \end{macro}
%
% Create the basic tile shapes.
% \begin{macrocode}
-\MakePenroseTile {thin~ rhombus}
-\MakePenroseTile {thick~ rhombus}
-\MakePenroseTile {dart}
-\MakePenroseTile {kite}
-\MakePenroseTile {golden~ triangle}
-\MakePenroseTile {reverse~ golden~ triangle}
-\MakePenroseTile {golden~ gnomon}
-\MakePenroseTile {reverse~ golden~ gnomon}
-\MakePenroseTile {pentagon~ 5}
-\MakePenroseTile {pentagon~ 3}
-\MakePenroseTile {pentagon~ 2}
-\MakePenroseTile {pentagram}
-\MakePenroseTile {boat}
-\MakePenroseTile {diamond}
+\BakePenroseTile {thin~ rhombus}
+\BakePenroseTile {thick~ rhombus}
+\BakePenroseTile {dart}
+\BakePenroseTile {kite}
+\BakePenroseTile {golden~ triangle}
+\BakePenroseTile {reverse~ golden~ triangle}
+\BakePenroseTile {golden~ gnomon}
+\BakePenroseTile {reverse~ golden~ gnomon}
+\BakePenroseTile {pentagon~ 5}
+\BakePenroseTile {pentagon~ 3}
+\BakePenroseTile {pentagon~ 2}
+\BakePenroseTile {pentagram}
+\BakePenroseTile {boat}
+\BakePenroseTile {diamond}
+% \end{macrocode}
+%
+%
+% \subsection{User-Definable Tiles}
+%
+% The commands in this section are for enabling a user to define their own tile.
+%
+%
+% \begin{macro}[internal]{\@@_transform_side:nn}
+% Apply a transformation to make a given side lie on the x-axis.
+% First argument is the tile, second is the side.
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_transform_side:nn #1#2
+{
+% \end{macrocode}
+% Get our tile data.
+% \begin{macrocode}
+ \prop_get:NnN \g_@@_tiles_prop {#1} \l_@@_tmpa_tl
+% \end{macrocode}
+% Start with the edge list.
+%
+% Initialise the counter.
+% \begin{macrocode}
+ \int_zero:N \l_@@_tmpb_int
+ \int_incr:N \l_@@_tmpb_int
+% \end{macrocode}
+% Get the path type list.
+%
+% \begin{macrocode}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_tmpa_tl}
+% \end{macrocode}
+%
+% Iterate through the path type list, looking for the requested path.
+% \begin{macrocode}
+ \tl_map_inline:Nn \l_@@_tmpc_tl {
+ \str_if_eq:nnT {##1} {#2} {
+ \tl_map_break:
+ }
+ \int_incr:N \l_@@_tmpb_int
+ }
+% \end{macrocode}
+% Get the coordinate list.
+% \begin{macrocode}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpa_tl}
+% \end{macrocode}
+% Strip off the outer braces.
+% \begin{macrocode}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_item:Nn \l_@@_tmpc_tl {1}}
+% \end{macrocode}
+% Add the first coordinate at the end.
+% \begin{macrocode}
+ \tl_put_right:Nx \l_@@_tmpc_tl
+ {{\tl_item:Nn \l_@@_tmpc_tl {1}}}
+% \end{macrocode}
+% Get the coordinates for this edge.
+% \begin{macrocode}
+ \tl_set:Nx \l_@@_tmpa_tl
+ {\tl_item:Nn \l_@@_tmpc_tl {\int_use:N \l_@@_tmpb_int}}
+ \tl_set:Nx \l_@@_tmpb_tl
+ {\tl_item:Nn \l_@@_tmpc_tl {\int_use:N \l_@@_tmpb_int + 1}}
+% \end{macrocode}
+% Translate second to origin.
+% \begin{macrocode}
+ \tikz_scan_point:V \l_@@_tmpb_tl
+ \dim_set_eq:Nc \l_@@_xa_dim {pgf@x}
+ \dim_set_eq:Nc \l_@@_ya_dim {pgf@y}
+% \end{macrocode}
+% Rotate and scale first to unit x-vector.
+% \begin{macrocode}
+ \tikz_scan_point:V \l_@@_tmpa_tl
+ \dim_set_eq:Nc \l_@@_xb_dim {pgf@x}
+ \dim_set_eq:Nc \l_@@_yb_dim {pgf@y}
+
+ \dim_sub:Nn \l_@@_xb_dim {\l_@@_xa_dim }
+ \dim_sub:Nn \l_@@_yb_dim {\l_@@_ya_dim }
+% \end{macrocode}
+% And normalise the vector along it.
+% \begin{macrocode}
+ \pgfpointnormalised{\pgfpoint{\l_@@_xb_dim}{\l_@@_yb_dim}}
+ \dim_set_eq:Nc \l_@@_xb_dim {pgf@x}
+ \dim_set_eq:Nc \l_@@_yb_dim {pgf@y}
+% \end{macrocode}
+% Now rotate so that the \(x\)--axis lies along the edge.
+% \begin{macrocode}
+ \pgftransformtriangle%
+ {\pgfpoint{0pt}{0pt}}%
+ {\pgfpoint{\l_@@_xb_dim}{-\l_@@_yb_dim}}
+ {\pgfpoint{\l_@@_yb_dim}{\l_@@_xb_dim}}
+
+ \pgftransformshift{\pgfpoint{-\l_@@_xa_dim}{-\l_@@_ya_dim}}
+
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \tl_if_eq:nnT {nVT}
+\cs_generate_variant:Nn \@@_transform_side:nn {nx,nV}
+% \end{macrocode}
+%
+% \begin{macro}[internal]{\TransformAlongSide}
+% Make this available outside the \LaTeX3 environment.
+% \begin{macrocode}
+\DeclareDocumentCommand \TransformAlongSide {m m}
+{
+ \@@_transform_side:nx {#1}{#2}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_coordinates_at_vertices:n}
+% This places TikZ coordinates at the vertices of the tile.
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_coordinates_at_vertices:n #1
+{
+% \end{macrocode}
+% Get our tile data
+% \begin{macrocode}
+ \prop_get:NnN \g_@@_tiles_prop {#1} \l_@@_tmpa_tl
+% \end{macrocode}
+% Start with the edge list
+% \begin{macrocode}
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
+% \end{macrocode}
+% Get the coordinate list
+% \begin{macrocode}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpa_tl}
+% \end{macrocode}
+% Strip off the outer braces
+% \begin{macrocode}
+ \tl_set:Nx \l_@@_tmpc_tl
+ {\tl_item:Nn \l_@@_tmpc_tl {1}}
+% \end{macrocode}
+% Add the first coordinate at the end
+% \begin{macrocode}
+ \tl_put_right:Nx \l_@@_tmpc_tl
+ {{\tl_item:Nn \l_@@_tmpc_tl {1}}}
+% \end{macrocode}
+% Get the first coordinate
+% \begin{macrocode}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_head:N \l_@@_tmpc_tl}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+% \end{macrocode}
+% Iterate through the path type list, looking for the requested path
+% \begin{macrocode}
+ \tl_map_inline:Nn \l_@@_tmpb_tl {
+ \tl_set:Nx \l_@@_tmpd_tl {
+ \exp_not:N \coordinate
+ (-edge~ ##1~ start)~ at \tl_use:N \l_@@_tmpa_tl;
+ }
+ \tl_use:N \l_@@_tmpd_tl
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_head:N \l_@@_tmpc_tl}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_set:Nx \l_@@_tmpd_tl {
+ \exp_not:N \coordinate
+ (-edge~ ##1~ end)~ at \tl_use:N \l_@@_tmpa_tl;
+ }
+ \tl_use:N \l_@@_tmpd_tl
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\CoordinatesAtVertices}
+% User-accessible wrapper around the above.
+% \begin{macrocode}
+\DeclareDocumentCommand \CoordinatesAtVertices {m}
+{
+ \@@_coordinates_at_vertices:n {#1}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{function}{\DefineTile}
+% This is the user function for defining a tile.
+% \begin{macrocode}
+\DeclareDocumentCommand \DefineTile { m m m }
+{
+% \end{macrocode}
+% Clear the temporary variable.
+% \begin{macrocode}
+ \tl_clear:N \l_@@_tmpa_tl
+% \end{macrocode}
+% The 3rd parameter is a list of coordinates at vertices, iterate through them and add them to the list.
+% \begin{macrocode}
+ \tl_map_inline:nn {#3} {
+ \@@_add_coordinate:w \l_@@_tmpa_tl ##1 \q_stop
+ }
+% \end{macrocode}
+% Now we make a list of the edge types (from the 2nd parameter), using a prop to keep track of whether an edge is repeated.
+% \begin{macrocode}
+ \prop_clear:N \l_@@_tmpa_prop
+ \tl_map_inline:nn {#2} {
+ \prop_if_in:NnTF \l_@@_tmpa_prop {##1}
+ {
+ \prop_put:Nnn \l_@@_tmpa_prop {##1} {1}
+ }
+ {
+ \prop_put:Nnn \l_@@_tmpa_prop {##1} {0}
+ }
+ }
+% \end{macrocode}
+% Having established their multiplicity, we now create the edges with their names, appending numbers to their names if used more than once.
+% \begin{macrocode}
+ \tl_clear:N \l_@@_tmpb_tl
+ \tl_map_inline:nn {#2}
+ {
+ \tl_clear:N \l_@@_tmpc_tl
+ \tl_put_right:Nn \l_@@_tmpc_tl {##1}
+ \int_compare:nF {\prop_item:Nn \l_@@_tmpa_prop {##1} == 0} {
+ \tl_put_right:Nx \l_@@_tmpc_tl
+ {\prop_item:Nn \l_@@_tmpa_prop {##1}}
+ \prop_put:Nnx \l_@@_tmpa_prop {##1}
+ {\int_eval:n {\prop_item:Nn \l_@@_tmpa_prop {##1} + 1}}
+ }
+ \tl_put_right:Nx \l_@@_tmpb_tl {{ \l_@@_tmpc_tl }}
+ }
+% \end{macrocode}
+% Finally, we can create our tile and add it to the global tile prop.
+% \begin{macrocode}
+ \prop_gput:Nnx \g_@@_tiles_prop {#1}
+ {{\tl_use:N \l_@@_tmpb_tl} {\tl_use:N \l_@@_tmpa_tl}}
+% \end{macrocode}
+% Having created the tile, we make a TikZ pic to place it on the page.
+% \begin{macrocode}
+ \tikzset{
+ #1/.pic={
+ \begin{scope}
+% \end{macrocode}
+% Were we given a tile to align ourselves against?
+% \begin{macrocode}
+ \pgfkeysgetvalue{/tikz/Penrose/alignment~ location}{\prloc}
+ \ifx\prloc\pgfutil@empty
+ \else
+% \end{macrocode}
+% Yes, we were.
+% So we adjust our position accordingly.
+% The first job is to transform so that we're along the edge of the receiving tile.
+% \begin{macrocode}
+ \begingroup
+% \end{macrocode}
+% We get the locations of the start and end of the receiving tile.
+% As \Verb+pic+ sets the node prefix, we have to temporarily suspend that (hence working in a group).
+% \begin{macrocode}
+ \tikzset{name~ prefix~ ..}%
+ \tikz@scan@one@point\pgfutil@firstofone%
+ (\prloc-edge~ \pgfkeysvalueof{/tikz/Penrose/alignment~ edge}~ start)%
+ \global\pgf@xa=\pgf@x
+ \global\pgf@ya=\pgf@y
+ \tikz@scan@one@point\pgfutil@firstofone%
+ (\prloc-edge~ \pgfkeysvalueof{/tikz/Penrose/alignment~ edge}~ end)%
+ \global\pgf@xb=\pgf@x
+ \global\pgf@yb=\pgf@y
+ \endgroup
+% \end{macrocode}
+% We store the initial points in \Verb+\pgf@xa+ and \Verb+\pgf@ya+ but we want \Verb+\pgf@xb+ and \Verb+\pgf@yb+ to be a vector along the edge.
+% \begin{macrocode}
+ \advance\pgf@xb by -\pgf@xa
+ \advance\pgf@yb by -\pgf@ya
+% \end{macrocode}
+% We shift to the start of the edge.
+% \begin{macrocode}
+ \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
+% \end{macrocode}
+% And normalise the vector along it.
+% \begin{macrocode}
+ \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
+ \pgf@xb=\pgf@x
+ \pgf@yb=\pgf@y
+% \end{macrocode}
+% Now rotate so that the \(x\)--axis lies along the edge.
+% \begin{macrocode}
+ \pgftransformtriangle%
+ {\pgfpoint{0pt}{0pt}}%
+ {\pgfpoint{\pgf@xb}{\pgf@yb}}%
+ {\pgfpoint{-\pgf@yb}{\pgf@xb}}
+% \end{macrocode}
+% The next job is to shift and rotate the current tile so that the correct edge ends up against the receiving tile.
+% \begin{macrocode}
+ \str_set:Nx \l_@@_tmpa_str
+ {\pgfkeysvalueof{/tikz/Penrose/alignment~ edge}}
+ \str_set:Nx \l_@@_tmpa_str {\str_head:N \l_@@_tmpa_str}
+ \str_put_right:Nx \l_@@_tmpa_str
+ {\pgfkeysvalueof{/tikz/Penrose/alignment~ new~ edge}}
+ \str_set:Nx \l_@@_tmpb_str {\str_lowercase:f { \l_@@_tmpa_str}}
+ \str_if_eq:NNT \l_@@_tmpa_str \l_@@_tmpb_str
+ {
+ \str_set:Nx \l_@@_tmpb_str
+ {\str_uppercase:f { \l_@@_tmpa_str}}
+ }
+
+ \@@_transform_side:nV {#1} \l_@@_tmpb_str
+ \fi
% \end{macrocode}
+% Now that the transformation is finalised, we can render the tile.
+% We clip against the tile path so that the tiles don't ``bleed''.
+% If we didn't do this, drawing the tile would result in overlaps which can look a bit ugly.
+% On the other hand, tight clipping can lead to ``gaps'' between the tiles so we make this optional by enclosing it in a style.
+% \begin{macrocode}
+ \UsePenroseTile[
+ every~ Penrose~ tile~ clip/.try,
+ every~ #1~ clip/.try
+ ]{#1}
+ \UsePenroseTile[
+ every~ Penrose~ tile/.try,
+ every~ #1/.try,
+ pic~ actions
+ ]{#1}
+% Lastly, we put coordinates at each vertex, labelled by which edge they are.
+% \begin{macrocode}
+ \@@_coordinates_at_vertices:n {#1}
+ \end{scope}
+ },
+% \end{macrocode}
+% This is a shortcut for installing the \Verb+pic+ type.
+% \begin{macrocode}
+ #1/.style={
+ every~ Penrose~ pic/.try,
+ pic~ type=#1,
+ },
+ }
+}
+% \end{macrocode}
+% \end{function}
+%
%
% \subsection{Lindenmayer System}
%
@@ -735,32 +1134,32 @@ and the derived files penrose.ins
%
% These are the rules for generating rhombus tilings.
% \begin{macrocode}
-\prop_new:N \g__penrose_rhombus_lms_rule_prop
-\prop_put:Nnn \g__penrose_rhombus_lms_rule_prop {T} {[f*sT][f>g]}
-\prop_put:Nnn \g__penrose_rhombus_lms_rule_prop {t} {[f_st][f>G]}
-\prop_put:Nnn \g__penrose_rhombus_lms_rule_prop {G} {[f+sG][sf>g][sf*sT]}
-\prop_put:Nnn \g__penrose_rhombus_lms_rule_prop {g} {[f-sg][sf>G][sf_st]}
+\prop_new:N \g_@@_rhombus_lms_rule_prop
+\prop_gput:Nnn \g_@@_rhombus_lms_rule_prop {T} {[f*sT][f>g]}
+\prop_gput:Nnn \g_@@_rhombus_lms_rule_prop {t} {[f_st][f>G]}
+\prop_gput:Nnn \g_@@_rhombus_lms_rule_prop {G} {[f+sG][sf>g][sf*sT]}
+\prop_gput:Nnn \g_@@_rhombus_lms_rule_prop {g} {[f-sg][sf>G][sf_st]}
% \end{macrocode}
%
% These are the rules for generating kite and dart tilings.
% \begin{macrocode}
-\prop_new:N \g__penrose_kite_lms_rule_prop
-\prop_put:Nnn \g__penrose_kite_lms_rule_prop {T} {[f*sT][f>st][+sg]}
-\prop_put:Nnn \g__penrose_kite_lms_rule_prop {t} {[f_st][f>sT][-sG]}
-\prop_put:Nnn \g__penrose_kite_lms_rule_prop {G} {[f*+sG][sT]}
-\prop_put:Nnn \g__penrose_kite_lms_rule_prop {g} {[f-_sg][st]}
+\prop_new:N \g_@@_kite_lms_rule_prop
+\prop_gput:Nnn \g_@@_kite_lms_rule_prop {T} {[f*sT][f>st][+sg]}
+\prop_gput:Nnn \g_@@_kite_lms_rule_prop {t} {[f_st][f>sT][-sG]}
+\prop_gput:Nnn \g_@@_kite_lms_rule_prop {G} {[f*+sG][sT]}
+\prop_gput:Nnn \g_@@_kite_lms_rule_prop {g} {[f-_sg][st]}
% \end{macrocode}
%
% These are the rules for generating pentagon tilings.
% \begin{macrocode}
-\prop_new:N \g__penrose_pentagon_lms_rule_prop
-\prop_put:Nnn \g__penrose_pentagon_lms_rule_prop {P}
+\prop_new:N \g_@@_pentagon_lms_rule_prop
+\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {P}
{[s>P][1sF+Q][1+sF+Q][1*sF+Q][1-sF+Q][1_sF+Q]} % pentagon 5
-\prop_put:Nnn \g__penrose_pentagon_lms_rule_prop {Q}
+\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {Q}
{[s>P][1+sFR][1*sF*R][1-sF+Q][1_sF+Q][1sF+Q][->fsD]} % pentagon 3
-\prop_put:Nnn \g__penrose_pentagon_lms_rule_prop {R}
+\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {R}
{[s>P][1-sF+Q][1+sF*R][1*sFR][1_sF*R][1sFR][_>fsD][>fsD]} % pentagon 2
-\prop_put:Nnn \g__penrose_pentagon_lms_rule_prop {G}
+\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {G}
{
[s>G]
[se[>d+R][e1B]]
@@ -769,103 +1168,103 @@ and the derived files penrose.ins
[*se[>d+R][e1B]]
[_se[>d+R][e1B]]
} % pentagram
-\prop_put:Nnn \g__penrose_pentagon_lms_rule_prop {B}
+\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {B}
{
[s>G]
[se[>d+R][e1B]]
[+se[>d+R][e1B]]
[-se[>d+R][e1B]]
} % boat
-\prop_put:Nnn \g__penrose_pentagon_lms_rule_prop {D}
+\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {D}
{[s>d+R][s>eG][se1B]} % diamond
% \end{macrocode}
%
% Each of the standard tilings can also be drawn using triangles using the same rules.
% \begin{macrocode}
-\prop_set_eq:NN \g__penrose_rtriangle_lms_rule_prop
-\g__penrose_rhombus_lms_rule_prop
-\prop_set_eq:NN \g__penrose_ktriangle_lms_rule_prop
-\g__penrose_kite_lms_rule_prop
+\prop_gset_eq:NN \g_@@_rtriangle_lms_rule_prop
+\g_@@_rhombus_lms_rule_prop
+\prop_gset_eq:NN \g_@@_ktriangle_lms_rule_prop
+\g_@@_kite_lms_rule_prop
% \end{macrocode}
%
% These hold the various actions.
% \begin{macrocode}
-\prop_new:N \g__penrose_default_lms_action_prop
-\prop_new:N \g__penrose_rhombus_lms_action_prop
-\prop_new:N \g__penrose_kite_lms_action_prop
-\prop_new:N \g__penrose_rtriangle_lms_action_prop
-\prop_new:N \g__penrose_ktriangle_lms_action_prop
-\prop_new:N \g__penrose_pentagon_lms_action_prop
+\prop_new:N \g_@@_default_lms_action_prop
+\prop_new:N \g_@@_rhombus_lms_action_prop
+\prop_new:N \g_@@_kite_lms_action_prop
+\prop_new:N \g_@@_rtriangle_lms_action_prop
+\prop_new:N \g_@@_ktriangle_lms_action_prop
+\prop_new:N \g_@@_pentagon_lms_action_prop
% \end{macrocode}
%
% We need some parameters.
% \begin{macrocode}
-\dim_new:N \l__penrose_step_dim
-\dim_set:Nn \l__penrose_step_dim {1cm}
+\dim_new:N \l_@@_step_dim
+\dim_set:Nn \l_@@_step_dim {1cm}
% \end{macrocode}
%
% These are the defaults, which will be used in all the rule sets.
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_default_lms_action_prop {[} {\group_begin:}
-\prop_put:Nnn \g__penrose_default_lms_action_prop {]} {\group_end:}
-\prop_put:Nnn \g__penrose_default_lms_action_prop {f}
-{\pgftransformxshift{\l__penrose_step_dim}}
-\prop_put:Nnn \g__penrose_default_lms_action_prop {s} {
- \fp_set:Nn \l__penrose_tmpa_fp { 2 * sind(18) * \l__penrose_step_dim }
- \dim_set:Nn \l__penrose_step_dim {\fp_to_dim:N \l__penrose_tmpa_fp}
+\prop_gput:Nnn \g_@@_default_lms_action_prop {[} {\group_begin:}
+\prop_gput:Nnn \g_@@_default_lms_action_prop {]} {\group_end:}
+\prop_gput:Nnn \g_@@_default_lms_action_prop {f}
+{\pgftransformxshift{\l_@@_step_dim}}
+\prop_gput:Nnn \g_@@_default_lms_action_prop {s} {
+ \fp_set:Nn \l_@@_tmpa_fp { 2 * sind(18) * \l_@@_step_dim }
+ \dim_set:Nn \l_@@_step_dim {\fp_to_dim:N \l_@@_tmpa_fp}
}
% \end{macrocode}
%
% The rhombus rules need a variety of turns.
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {+}
+\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {+}
{\pgftransformrotate{144}}
-\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {*}
+\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {*}
{\pgftransformrotate{108}}
-\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {-}
+\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {-}
{\pgftransformrotate{216}}
-\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {_}
+\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {_}
{\pgftransformrotate{252}}
-\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {>}
+\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {>}
{\pgftransformrotate{180}}
% \end{macrocode}
%
% Up to now, the actions for the rhombus and its triangle replacement are the same.
% \begin{macrocode}
-\prop_set_eq:NN \g__penrose_rtriangle_lms_action_prop
-\g__penrose_rhombus_lms_action_prop
+\prop_gset_eq:NN \g_@@_rtriangle_lms_action_prop
+\g_@@_rhombus_lms_action_prop
% \end{macrocode}
%
% Now we do the actions that actually draw something.
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {T} {
+\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {T} {
\group_begin:
% \end{macrocode}
% As we go through, we keep track of how many tiles we've drawn.
% \begin{macrocode}
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
% \end{macrocode}
% Set up the position, size, and angle correctly.
% \begin{macrocode}
\pgftransformrotate{198}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*2*cosd(18)}
- \pgftransformxshift{-\fp_to_dim:N \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*2*cosd(18)}
+ \pgftransformxshift{-\fp_to_dim:N \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
% \end{macrocode}
% Now we draw the thin rhombus, applying every style we can possibly imagine.
% The \Verb+Penrose tile+ style gets the current tile and total tile numbers passed to it.
% \begin{macrocode}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ thin~ rhombus/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{thin~rhombus}
\group_end:
}
@@ -873,21 +1272,21 @@ and the derived files penrose.ins
%
% Same for the thick rhombus.
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {G} {
+\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {G} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)/(2*cosd(36))}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \int_gincr:N \g_@@_tile_int
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)/(2*cosd(36))}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ thick~ rhombus/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{thick~rhombus}
\group_end:
}
@@ -895,59 +1294,59 @@ and the derived files penrose.ins
%
% Now we do the same for the kite and dart tiling.
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_kite_lms_action_prop {+} {\pgftransformrotate{36}}
-\prop_put:Nnn \g__penrose_kite_lms_action_prop {*} {\pgftransformrotate{108}}
-\prop_put:Nnn \g__penrose_kite_lms_action_prop {-} {\pgftransformrotate{-36}}
-\prop_put:Nnn \g__penrose_kite_lms_action_prop {_}
+\prop_gput:Nnn \g_@@_kite_lms_action_prop {+} {\pgftransformrotate{36}}
+\prop_gput:Nnn \g_@@_kite_lms_action_prop {*} {\pgftransformrotate{108}}
+\prop_gput:Nnn \g_@@_kite_lms_action_prop {-} {\pgftransformrotate{-36}}
+\prop_gput:Nnn \g_@@_kite_lms_action_prop {_}
{\pgftransformrotate{-108}}
-\prop_put:Nnn \g__penrose_kite_lms_action_prop {>} {\pgftransformrotate{180}}
+\prop_gput:Nnn \g_@@_kite_lms_action_prop {>} {\pgftransformrotate{180}}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_set_eq:NN \g__penrose_ktriangle_lms_action_prop
-\g__penrose_kite_lms_action_prop
+\prop_gset_eq:NN \g_@@_ktriangle_lms_action_prop
+\g_@@_kite_lms_action_prop
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_kite_lms_action_prop {T} {
+\prop_gput:Nnn \g_@@_kite_lms_action_prop {T} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
\pgftransformrotate{36}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ kite/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{kite}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_kite_lms_action_prop {g} {
+\prop_gput:Nnn \g_@@_kite_lms_action_prop {g} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
\pgftransformrotate{144}
- \pgftransformxshift{-\l__penrose_step_dim * 2 * sin(18)}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \pgftransformxshift{-\l_@@_step_dim * 2 * sin(18)}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ dart/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{dart}
\group_end:
}
@@ -955,185 +1354,185 @@ and the derived files penrose.ins
%
% Now we set up the actions for the triangle variations.
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_rtriangle_lms_action_prop {T} {
+\prop_gput:Nnn \g_@@_rtriangle_lms_action_prop {T} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
\pgftransformrotate{18}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ reverse~ golden~ triangle/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{reverse~ golden~ triangle}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_rtriangle_lms_action_prop {t} {
+\prop_gput:Nnn \g_@@_rtriangle_lms_action_prop {t} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
\pgftransformrotate{-18}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ golden~ triangle/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{golden~ triangle}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_rtriangle_lms_action_prop {G} {
+\prop_gput:Nnn \g_@@_rtriangle_lms_action_prop {G} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
\pgftransformrotate{180}
- \pgftransformxshift{-\l__penrose_step_dim}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)/(2*cosd(36))}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \pgftransformxshift{-\l_@@_step_dim}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)/(2*cosd(36))}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ reverse~ golden~ gnomon/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{reverse~ golden~ gnomon}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_rtriangle_lms_action_prop {g} {
+\prop_gput:Nnn \g_@@_rtriangle_lms_action_prop {g} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
\pgftransformrotate{180}
- \pgftransformxshift{-\l__penrose_step_dim}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)/(2*cosd(36))}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \pgftransformxshift{-\l_@@_step_dim}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)/(2*cosd(36))}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ golden~ gnomon/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{golden~ gnomon}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_ktriangle_lms_action_prop {T} {
+\prop_gput:Nnn \g_@@_ktriangle_lms_action_prop {T} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
\pgftransformrotate{18}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ reverse~ golden~ triangle/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{reverse~ golden~ triangle}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_ktriangle_lms_action_prop {t} {
+\prop_gput:Nnn \g_@@_ktriangle_lms_action_prop {t} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
\pgftransformrotate{-18}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ golden~ triangle/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{golden~ triangle}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_ktriangle_lms_action_prop {G} {
+\prop_gput:Nnn \g_@@_ktriangle_lms_action_prop {G} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
\pgftransformrotate{180}
- \pgftransformxshift{-\l__penrose_step_dim}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)/(2*cosd(36))}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \pgftransformxshift{-\l_@@_step_dim}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)/(2*cosd(36))}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ reverse~ golden~ gnomon/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{reverse~ golden~ gnomon}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_ktriangle_lms_action_prop {g} {
+\prop_gput:Nnn \g_@@_ktriangle_lms_action_prop {g} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
\pgftransformrotate{180}
- \pgftransformxshift{-\l__penrose_step_dim}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)/(2*cosd(36))}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \pgftransformxshift{-\l_@@_step_dim}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)/(2*cosd(36))}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ golden~ gnomon/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{golden~ gnomon}
\group_end:
}
@@ -1143,239 +1542,239 @@ and the derived files penrose.ins
%
% The rules need a variety of turns.
% \begin{macrocode}
-\int_new:N \l__penrose_pentagon_parity_int
-\seq_new:N \l__penrose_pentagon_parity_seq
-\seq_set_from_clist:Nn \l__penrose_pentagon_parity_seq {odd,even}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {1} {
- \int_set:Nn \l__penrose_pentagon_parity_int
- {3 - \l__penrose_pentagon_parity_int}
+\int_new:N \l_@@_pentagon_parity_int
+\seq_new:N \l_@@_pentagon_parity_seq
+\seq_set_from_clist:Nn \l_@@_pentagon_parity_seq {odd,even}
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {1} {
+ \int_set:Nn \l_@@_pentagon_parity_int
+ {3 - \l_@@_pentagon_parity_int}
}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {+}
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {+}
{\pgftransformrotate{72}}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {*}
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {*}
{\pgftransformrotate{144}}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {-}
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {-}
{\pgftransformrotate{288}}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {_}
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {_}
{\pgftransformrotate{216}}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {>}
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {>}
{\pgftransformrotate{180}}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {|}
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {|}
{\pgftransformxscale{-1}}
% \end{macrocode}
% The scale factor is different.
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {s} {
- \fp_set:Nn \l__penrose_tmpa_fp
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {s} {
+ \fp_set:Nn \l_@@_tmpa_fp
{
- 1/(2 + 2 * cosd(72) ) * \l__penrose_step_dim
+ 1/(2 + 2 * cosd(72) ) * \l_@@_step_dim
}
- \dim_set:Nn \l__penrose_step_dim {\fp_to_dim:N \l__penrose_tmpa_fp}
+ \dim_set:Nn \l_@@_step_dim {\fp_to_dim:N \l_@@_tmpa_fp}
}
% \end{macrocode}
% And we tend to work better vertically.
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {f} {
- \fp_set:Nn \l__penrose_tmpa_fp { tand(54)/2 * \l__penrose_step_dim }
- \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp}
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {f} {
+ \fp_set:Nn \l_@@_tmpa_fp { tand(54)/2 * \l_@@_step_dim }
+ \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp}
}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {F} {
- \fp_set:Nn \l__penrose_tmpa_fp { tand(54) * \l__penrose_step_dim }
- \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp}
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {F} {
+ \fp_set:Nn \l_@@_tmpa_fp { tand(54) * \l_@@_step_dim }
+ \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp}
}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {d} {
- \fp_set:Nn \l__penrose_tmpa_fp
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {d} {
+ \fp_set:Nn \l_@@_tmpa_fp
{
- (tand(54)/2 - tand(72)/2 + sind(36) ) * \l__penrose_step_dim
+ (tand(54)/2 - tand(72)/2 + sind(36) ) * \l_@@_step_dim
}
- \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp}
+ \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp}
}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {e} {
- \fp_set:Nn \l__penrose_tmpa_fp
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {e} {
+ \fp_set:Nn \l_@@_tmpa_fp
{
- tand(54) * cosd(36) * \l__penrose_step_dim
+ tand(54) * cosd(36) * \l_@@_step_dim
}
- \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp}
+ \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp}
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {P} {
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {P} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/2}
- \pgftransformxshift{-\fp_to_dim:N \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*tand(54)/2}
- \pgftransformyshift{-\fp_to_dim:N \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \int_gincr:N \g_@@_tile_int
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/2}
+ \pgftransformxshift{-\fp_to_dim:N \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*tand(54)/2}
+ \pgftransformyshift{-\fp_to_dim:N \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ pentagon/.try,
every~
- \seq_item:Nn \l__penrose_pentagon_parity_seq
- {\l__penrose_pentagon_parity_int}
+ \seq_item:Nn \l_@@_pentagon_parity_seq
+ {\l_@@_pentagon_parity_int}
\space pentagon/.try,
every~ pentagon~ 5/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{pentagon~5}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {Q} {
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {Q} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/2}
- \pgftransformxshift{-\fp_to_dim:N \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*tand(54)/2}
- \pgftransformyshift{-\fp_to_dim:N \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \int_gincr:N \g_@@_tile_int
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/2}
+ \pgftransformxshift{-\fp_to_dim:N \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*tand(54)/2}
+ \pgftransformyshift{-\fp_to_dim:N \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ pentagon/.try,
every~
- \seq_item:Nn \l__penrose_pentagon_parity_seq
- {\l__penrose_pentagon_parity_int}
+ \seq_item:Nn \l_@@_pentagon_parity_seq
+ {\l_@@_pentagon_parity_int}
\space pentagon/.try,
every~ pentagon~ 3/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{pentagon~3}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {R} {
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {R} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/2}
- \pgftransformxshift{-\fp_to_dim:N \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*tand(54)/2}
- \pgftransformyshift{-\fp_to_dim:N \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \int_gincr:N \g_@@_tile_int
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/2}
+ \pgftransformxshift{-\fp_to_dim:N \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*tand(54)/2}
+ \pgftransformyshift{-\fp_to_dim:N \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ pentagon/.try,
every~
- \seq_item:Nn \l__penrose_pentagon_parity_seq
- {\l__penrose_pentagon_parity_int}
+ \seq_item:Nn \l_@@_pentagon_parity_seq
+ {\l_@@_pentagon_parity_int}
\space pentagon/.try,
every~ pentagon~ 2/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{pentagon~2}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {G} {
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {G} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
% \pgftransformrotate{198}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*cosd(72)}
- \pgftransformxshift{\fp_to_dim:N \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*tand(54)*cosd(72)}
- \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*cosd(72)}
+ \pgftransformxshift{\fp_to_dim:N \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*tand(54)*cosd(72)}
+ \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ pentagram/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{pentagram}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {B} {
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {B} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
% \pgftransformrotate{198}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*cosd(72)}
- \pgftransformxshift{\fp_to_dim:N \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*tand(54)*cosd(72)}
- \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*cosd(72)}
+ \pgftransformxshift{\fp_to_dim:N \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*tand(54)*cosd(72)}
+ \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ boat/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{boat}
\group_end:
}
% \end{macrocode}
%
% \begin{macrocode}
-\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {D} {
+\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {D} {
\group_begin:
- \int_gincr:N \l__penrose_tile_int
+ \int_gincr:N \g_@@_tile_int
\pgftransformrotate{90}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*cosd(18)}
- \pgftransformxshift{-\fp_to_dim:N \l__penrose_tmpa_fp}
- \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)}
- \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp}
- \tl_set:Nx \l__penrose_tmpc_tl
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*cosd(18)}
+ \pgftransformxshift{-\fp_to_dim:N \l_@@_tmpa_fp}
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
+ \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
+ \tl_set:Nx \l_@@_tmpc_tl
{
- {\int_use:N \l__penrose_tile_int}
- {\int_use:N \l__penrose_tiles_int}
+ {\int_use:N \g_@@_tile_int}
+ {\int_use:N \g_@@_tiles_int}
}
\UsePenroseTile[
every~ Penrose~ tile/.try,
every~ diamond/.try,
- Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try,
- Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl
+ Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
+ Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
]{diamond}
\group_end:
}
% \end{macrocode}
%
-% \begin{macro}[internal]{\penrose_make_lms:Nnnn}
+% \begin{macro}[internal]{\@@_make_lms:Nnnn}
% This creates the token list of actions, starting with the seed.
% The arguments are: a token list to store the result in, the name of the system, the number of iterations, and the initial state.
% \begin{macrocode}
-\cs_new_nopar:Npn \penrose_make_lms:Nnnn #1#2#3#4
+\cs_new_nopar:Npn \@@_make_lms:Nnnn #1#2#3#4
{
\group_begin:
% \end{macrocode}
% On the first time round, we start with the given seed.
% \begin{macrocode}
- \tl_set:Nn \l__penrose_tmpb_tl {#4}
+ \tl_set:Nn \l_@@_tmpb_tl {#4}
% \end{macrocode}
% We repeat the specified number of times.
% \begin{macrocode}
@@ -1383,50 +1782,50 @@ and the derived files penrose.ins
% \end{macrocode}
% Duplicate the current state.
% \begin{macrocode}
- \tl_set_eq:NN \l__penrose_tmpa_tl \l__penrose_tmpb_tl
+ \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_tmpb_tl
% \end{macrocode}
% Clear the receiving token list.
% \begin{macrocode}
- \tl_clear:N \l__penrose_tmpb_tl
+ \tl_clear:N \l_@@_tmpb_tl
% \end{macrocode}
% Walk through the current list, appending to the receiving list according to the rules.
% \begin{macrocode}
- \tl_map_inline:Nn \l__penrose_tmpa_tl
+ \tl_map_inline:Nn \l_@@_tmpa_tl
{
% \end{macrocode}
% If a rule exists, copy that.
% \begin{macrocode}
- \prop_if_in:cnTF {g__penrose_#2_lms_rule_prop} {##1}
+ \prop_if_in:cnTF {g_@@_#2_lms_rule_prop} {##1}
{
- \tl_put_right:Nx \l__penrose_tmpb_tl
- {\prop_item:cn {g__penrose_#2_lms_rule_prop} {##1} }
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {\prop_item:cn {g_@@_#2_lms_rule_prop} {##1} }
}
{
% \end{macrocode}
% Otherwise, just copy the token.
% \begin{macrocode}
- \tl_put_right:Nn \l__penrose_tmpb_tl {##1}
+ \tl_put_right:Nn \l_@@_tmpb_tl {##1}
}
}
}
% \end{macrocode}
% We've done all this inside a group, now pass the result outside.
% \begin{macrocode}
- \tl_set:Nn \l__penrose_tmpa_tl {
+ \tl_set:Nn \l_@@_tmpa_tl {
\group_end:
\tl_set:Nn #1
}
- \tl_put_right:Nx \l__penrose_tmpa_tl {{\tl_use:N \l__penrose_tmpb_tl}}
- \tl_use:N \l__penrose_tmpa_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl {{\tl_use:N \l_@@_tmpb_tl}}
+ \tl_use:N \l_@@_tmpa_tl
}
-\cs_generate_variant:Nn \penrose_make_lms:Nnnn {Nnnx}
+\cs_generate_variant:Nn \@@_make_lms:Nnnn {Nnnx}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\penrose_invoke_lms:Nn}
+% \begin{macro}[internal]{\@@_invoke_lms:Nn}
% This carries out the actions specified by the resulting rules.
% \begin{macrocode}
-\cs_new_nopar:Npn \penrose_invoke_lms:Nn #1#2
+\cs_new_nopar:Npn \@@_invoke_lms:Nn #1#2
{
\group_begin:
% \end{macrocode}
@@ -1435,14 +1834,14 @@ and the derived files penrose.ins
% Otherwise, just do nothing.
% \begin{macrocode}
\tl_map_inline:Nn #1 {
- \prop_if_in:cnTF {g__penrose_#2_lms_action_prop} {##1}
+ \prop_if_in:cnTF {g_@@_#2_lms_action_prop} {##1}
{
- \prop_item:cn {g__penrose_#2_lms_action_prop} {##1}
+ \prop_item:cn {g_@@_#2_lms_action_prop} {##1}
}
{
- \prop_if_in:cnT {g__penrose_default_lms_action_prop} {##1}
+ \prop_if_in:cnT {g_@@_default_lms_action_prop} {##1}
{
- \prop_item:cn {g__penrose_default_lms_action_prop} {##1}
+ \prop_item:cn {g_@@_default_lms_action_prop} {##1}
}
}
}
@@ -1453,11 +1852,11 @@ and the derived files penrose.ins
%
% We keep track of the number of tiles.
% \begin{macrocode}
-\int_new:N \l__penrose_tile_int
-\int_new:N \l__penrose_tiles_int
+\int_new:N \g_@@_tile_int
+\int_new:N \g_@@_tiles_int
% \end{macrocode}
%
-% \begin{macro}[internal]{\PenroseDecomposition}
+% \begin{function}{\PenroseDecomposition}
% This is the user macro to invoke the decomposition.
% The arguments are: optional styles, the name, number of iterations, and starting seed.
% \begin{macrocode}
@@ -1465,39 +1864,39 @@ and the derived files penrose.ins
{
\group_begin:
\tikzset{#1}
- \penrose_make_lms:Nnnx \l__penrose_tmpa_tl {#2} {#3} {#4}
- \penrose_count_lms:N \l__penrose_tmpa_tl
- \int_gzero:N \l__penrose_tile_int
- \int_gset:Nn \l__penrose_pentagon_parity_int {2}
- \penrose_invoke_lms:Nn \l__penrose_tmpa_tl {#2}
+ \@@_make_lms:Nnnx \l_@@_tmpa_tl {#2} {#3} {#4}
+ \@@_count_lms:N \l_@@_tmpa_tl
+ \int_gzero:N \g_@@_tile_int
+ \int_set:Nn \l_@@_pentagon_parity_int {2}
+ \@@_invoke_lms:Nn \l_@@_tmpa_tl {#2}
\group_end:
}
% \end{macrocode}
-% \end{macro}
+% \end{function}
%
-% \begin{macro}[internal]{\penrose_count_lms:N}
+% \begin{macro}[internal]{\@@_count_lms:N}
% This counts the number of tiles in the string.
% \begin{macrocode}
-\cs_new_nopar:Npn \penrose_count_lms:N #1
+\cs_new_nopar:Npn \@@_count_lms:N #1
{
- \int_gzero:N \l__penrose_tiles_int
+ \int_gzero:N \g_@@_tiles_int
\tl_map_inline:Nn #1
{
\tl_if_eq:nnT {##1} {T}
{
- \int_incr:N \l__penrose_tiles_int
+ \int_gincr:N \g_@@_tiles_int
}
\tl_if_eq:nnT {##1} {t}
{
- \int_incr:N \l__penrose_tiles_int
+ \int_gincr:N \g_@@_tiles_int
}
\tl_if_eq:nnT {##1} {G}
{
- \int_incr:N \l__penrose_tiles_int
+ \int_gincr:N \g_@@_tiles_int
}
\tl_if_eq:nnT {##1} {g}
{
- \int_incr:N \l__penrose_tiles_int
+ \int_gincr:N \g_@@_tiles_int
}
}
}
@@ -1508,7 +1907,7 @@ and the derived files penrose.ins
% \begin{macrocode}
\tikzset{
Penrose~ step/.code={
- \dim_set:Nn \l__penrose_step_dim {#1}
+ \dim_set:Nn \l_@@_step_dim {#1}
}
}
% \end{macrocode}
@@ -2717,8 +3116,11 @@ and the derived files penrose.ins
}
% \end{macrocode}
%
-% \iffalse
-%</library>
-% \fi
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
%\Finale
\endinput
diff --git a/graphics/pgf/contrib/penrose/penrose_code.pdf b/graphics/pgf/contrib/penrose/penrose_code.pdf
index b30a2d3442..59579b2524 100644
--- a/graphics/pgf/contrib/penrose/penrose_code.pdf
+++ b/graphics/pgf/contrib/penrose/penrose_code.pdf
Binary files differ
diff --git a/graphics/pgf/contrib/spath3/README b/graphics/pgf/contrib/spath3/README
index a9d1fe6210..dad3e28a92 100644
--- a/graphics/pgf/contrib/spath3/README
+++ b/graphics/pgf/contrib/spath3/README
@@ -1,6 +1,6 @@
----------------------------------------------------------------
spath3 --- LaTeX3 functions for manipulating PGF soft paths
-E-mail: stacey@math.ntnu.no
+E-mail: loopspace@mathforge.org
Released under the LaTeX Project Public License v1.3c or later
See http://www.latex-project.org/lppl.txt
----------------------------------------------------------------
diff --git a/graphics/pgf/contrib/spath3/calligraphy.pdf b/graphics/pgf/contrib/spath3/calligraphy.pdf
new file mode 100644
index 0000000000..f2852f4d1b
--- /dev/null
+++ b/graphics/pgf/contrib/spath3/calligraphy.pdf
Binary files differ
diff --git a/graphics/pgf/contrib/spath3/calligraphy_doc.tex b/graphics/pgf/contrib/spath3/calligraphy.tex
index c1b88c9e8e..7690e5c5b7 100644
--- a/graphics/pgf/contrib/spath3/calligraphy_doc.tex
+++ b/graphics/pgf/contrib/spath3/calligraphy.tex
@@ -1,4 +1,4 @@
-\immediate\write18{tex spath3.dtx}
+\immediate\write18{tex spath3_doc.dtx}
\documentclass{ltxdoc}
\usepackage[T1]{fontenc}
\usepackage{trace}
@@ -11,7 +11,14 @@
\usepackage{listings}
\lstloadlanguages{[LaTeX]TeX}
-\lstset{breakatwhitespace=true,breaklines=true,language=TeX}
+\lstset{
+ breakatwhitespace=true,
+ breaklines=true,
+ language=[LaTeX]TeX,
+ basicstyle=\small\ttfamily,
+ keepspaces=true,
+ columns=fullflexible
+}
\usepackage{fancyvrb}
@@ -22,7 +29,6 @@
\begin{center}
\setlength{\parindent}{0pt}
\fbox{\begin{minipage}{.9\linewidth}
- \lstset{breakatwhitespace=true,breaklines=true,language=TeX,basicstyle=\small}
\lstinputlisting[]{example.out}
\end{minipage}}
@@ -36,13 +42,20 @@
\GetFileInfo{spath3.sty}
\title{The \textsf{calligraphy} Package: Documentation}
-\author{Andrew Stacey \\ \url{stacey@math.ntnu.no}}
+\author{Andrew Stacey \\ \url{loopspace@mathforge.org}}
\date{\fileversion~from \filedate}
\begin{document}
\maketitle
-% \section{Introduction}
+
+ \section{Pre-Introduction}
+ This library is built on top of a package for manipulating PGF's \emph{soft paths} called \texttt{spath3}.
+ Version 2.0 of \texttt{spath3} involved considerable reorganisation of the code.
+ I tried to ensure that this didn't affect this library but it is extremely likely that I wasn't fully successful.
+ If something that used to work no longer does, please do let me know either by opening an issue on github (\url{https://github.com/loopspace/spath3}) or at the above email.
+
+ \section{Introduction}
The \Verb+calligraphy+ TikZ library is designed to enable calligraphic style drawings in TikZ.
The idea is to be able to ``stroke'' a line with a ``pen''.
As a simple example, compare the two lines in the following picture.
@@ -255,4 +268,4 @@ The following pens are predefined:
\end{example}
\end{itemize}
-\end{document} \ No newline at end of file
+\end{document}
diff --git a/graphics/pgf/contrib/spath3/calligraphy_doc.pdf b/graphics/pgf/contrib/spath3/calligraphy_doc.pdf
deleted file mode 100644
index 12a0313d8a..0000000000
--- a/graphics/pgf/contrib/spath3/calligraphy_doc.pdf
+++ /dev/null
Binary files differ
diff --git a/graphics/pgf/contrib/spath3/knots.pdf b/graphics/pgf/contrib/spath3/knots.pdf
new file mode 100644
index 0000000000..b1962a3c4c
--- /dev/null
+++ b/graphics/pgf/contrib/spath3/knots.pdf
Binary files differ
diff --git a/graphics/pgf/contrib/spath3/knots_doc.tex b/graphics/pgf/contrib/spath3/knots.tex
index 67c23ca128..20859a1d4e 100644
--- a/graphics/pgf/contrib/spath3/knots_doc.tex
+++ b/graphics/pgf/contrib/spath3/knots.tex
@@ -1,17 +1,24 @@
-\immediate\write18{tex spath3.dtx}
+\immediate\write18{tex spath3_code.dtx}
\documentclass{ltxdoc}
\usepackage[T1]{fontenc}
\usepackage{trace}
\usepackage{lmodern}
\usepackage{morefloats}
\usepackage{tikz}
-\usetikzlibrary{knots}
+\usetikzlibrary{knots,spath3,hobby}
\usepackage[numbered]{hypdoc}
\definecolor{lstbgcolor}{rgb}{0.9,0.9,0.9}
\usepackage{listings}
\lstloadlanguages{[LaTeX]TeX}
-\lstset{breakatwhitespace=true,breaklines=true,language=TeX}
+\lstset{
+ breakatwhitespace=true,
+ breaklines=true,
+ language=[LaTeX]TeX,
+ basicstyle=\small\ttfamily,
+ keepspaces=true,
+ columns=fullflexible
+}
\usepackage{fancyvrb}
@@ -22,7 +29,6 @@
\begin{center}
\setlength{\parindent}{0pt}
\fbox{\begin{minipage}{.9\linewidth}
- \lstset{breakatwhitespace=true,breaklines=true,language=TeX,basicstyle=\small}
\lstinputlisting[]{example.out}
\end{minipage}}
@@ -37,15 +43,41 @@
\GetFileInfo{spath3.sty}
\title{The \textsf{knots} Package: Documentation}
-\author{Andrew Stacey \\ \url{stacey@math.ntnu.no}}
+\author{Andrew Stacey \\ \url{loopspace@mathforge.org}}
\date{\fileversion~from \filedate}
\begin{document}
\maketitle
-\section{Introduction}
+\section{Pre-Introduction}
+
+This library is built on top of a package for manipulating PGF's \emph{soft paths} called \texttt{spath3}.
+ Version 2.0 of \texttt{spath3} involved considerable reorganisation of the code.
+ I tried to ensure that this didn't affect this library but it is extremely likely that I wasn't fully successful.
+ If something that used to work no longer does, please do let me know either by opening an issue on github (\url{https://github.com/loopspace/spath3}) or at the above email.
+
+ That version of \texttt{spath3} also introduced an alternative way of drawing knots which involves breaking the paths at their crossing points and introducing actual gaps.
+ This makes it easier to do things like have the knots on non-uniform backgrounds, and to style different parts of the knot differently such as illustrating a \(3\)--colouring.
+ To see how that works, look at the documentation of the \texttt{spath3} TikZ library.
+ Here's an example of how to draw a knot with that library.
+
+ \begin{example}
+\begin{tikzpicture}[
+ use Hobby shortcut,
+ every trefoil component/.style={ultra thick, draw},
+ trefoil component 1/.style={red},
+ trefoil component 2/.style={blue},
+ trefoil component 3/.style={green},
+]
+\path[spath/save=trefoil] ([closed]90:2) foreach \k in {1,...,3} { .. (-30+\k*240:.5) .. (90+\k*240:2) } (90:2);
+\tikzset{spath/knot={trefoil}{8pt}{1,3,5}}
+\end{tikzpicture}
+\end{example}
+
+\section{Introduction}
+
The \Verb+knots+ package is a TikZ library for drawing knot (and similar) diagrams.
It provides a few useful styles and node shapes but its main contribution is the \Verb+knot+ environment.
The \Verb+knot+ environment allows you to draw some strands of a knot (or braid or tangle or whatever -- we shall use the imprecise term ``knot'' to refer to any similar diagram) and then to modify the crossings via a simple interface.
diff --git a/graphics/pgf/contrib/spath3/knots_doc.pdf b/graphics/pgf/contrib/spath3/knots_doc.pdf
deleted file mode 100644
index d818161e21..0000000000
--- a/graphics/pgf/contrib/spath3/knots_doc.pdf
+++ /dev/null
Binary files differ
diff --git a/graphics/pgf/contrib/spath3/spath3.dtx b/graphics/pgf/contrib/spath3/spath3.dtx
deleted file mode 100644
index 9d6ae2825d..0000000000
--- a/graphics/pgf/contrib/spath3/spath3.dtx
+++ /dev/null
@@ -1,4228 +0,0 @@
-% \iffalse meta-comment
-%<*internal>
-\iffalse
-%</internal>
-%<*readme>
-----------------------------------------------------------------
-spath3 --- LaTeX3 functions for manipulating PGF soft paths
-E-mail: stacey@math.ntnu.no
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
-----------------------------------------------------------------
-
-This package defines some functions used to manipulate PGFs soft paths.
-As applications of its use, included are a package for drawing calligraphic paths and a package for drawing knot diagrams.
-%</readme>
-%<*internal>
-\fi
-\def\nameofplainTeX{plain}
-\ifx\fmtname\nameofplainTeX\else
- \expandafter\begingroup
-\fi
-%</internal>
-%<*install>
-\input docstrip.tex
-\keepsilent
-\askforoverwritefalse
-\preamble
-----------------------------------------------------------------
-spath3 --- Functions for manipulating PGF soft paths
-E-mail: stacey@math.ntnu.no
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
-----------------------------------------------------------------
-
-\endpreamble
-\postamble
-
-Copyright (C) 2011-2019 by Andrew Stacey <stacey@math.ntnu.no>
-
-This work may be distributed and/or modified under the
-conditions of the LaTeX Project Public License (LPPL), either
-version 1.3c of this license or (at your option) any later
-version. The latest version of this license is in the file:
-
-http://www.latex-project.org/lppl.txt
-
-This work is "maintained" (as per LPPL maintenance status) by
-Andrew Stacey.
-
-This work consists of the files spath3.dtx
- calligraphy_doc.tex
- knots_doc.tex
-and the derived files spath3.ins,
- spath3_code.pdf,
- spath3.sty,
- tikzlibrarycalligraphy.code.tex
- tikzlibraryknots.code.tex
- calligraphy.pdf
- knots.pdf
- README
-
-\endpostamble
-\usedir{tex/latex/spath3}
-\generate{
- \file{\jobname.sty}{\from{\jobname.dtx}{spath3}}
-}
-\generate{
- \file{tikzlibrarycalligraphy.code.tex}{\from{\jobname.dtx}{calligraphy}}
-}
-\generate{
- \file{tikzlibraryknots.code.tex}{\from{\jobname.dtx}{knots}}
-}
-%</install>
-%<install>\endbatchfile
-%<*internal>
-\usedir{source/latex/spath3}
-\generate{
- \file{\jobname.ins}{\from{\jobname.dtx}{install}}
-}
-\nopreamble\nopostamble
-\usedir{doc/latex/demopkg}
-\generate{
- \file{README.txt}{\from{\jobname.dtx}{readme}}
-}
-\ifx\fmtname\nameofplainTeX
- \expandafter\endbatchfile
-\else
- \expandafter\endgroup
-\fi
-%</internal>
-%<*driver>
-\documentclass[full]{l3doc}
-\usepackage[T1]{fontenc}
-\usepackage{lmodern}
-%\usepackage{morefloats}
-\usepackage{tikz}
-\usepackage{trace}
-\usepackage{spath3}
-%\traceoff
-%\usepackage[numbered]{hypdoc}
-\definecolor{lstbgcolor}{rgb}{0.9,0.9,0.9}
-
-\usepackage{listings}
-\lstloadlanguages{[LaTeX]TeX}
-\lstset{breakatwhitespace=true,breaklines=true,language=TeX}
-
-\usepackage{fancyvrb}
-
-\newenvironment{example}
- {\VerbatimEnvironment
- \begin{VerbatimOut}[gobble=2]{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}
- \input{example.out}
- \end{minipage}}
-\end{center}
-}
-\EnableCrossrefs
-\CodelineIndex
-\RecordChanges
-\begin{document}
- \DocInput{\jobname.dtx}
-\end{document}
-%</driver>
-% \fi
-%
-% \CheckSum{4488}
-%
-% \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{1.0}{2011/05/03}{Converted to DTX file}
-% \changes{1.1}{2016/02/19}{Fixes due to changes in LaTeX3}
-% \changes{1.2}{2019/02/12}{More fixes due to changes in LaTeX3}
-%
-% \DoNotIndex{\newcommand,\newenvironment}
-%
-% \providecommand*{\url}{\texttt}
-% \GetFileInfo{spath3.sty}
-% \title{The \textsf{spath3} package}
-% \author{Andrew Stacey \\ \url{stacey@math.ntnu.no}}
-% \date{\fileversion~from \filedate}
-%
-%
-% \maketitle
-%
-%
-% \section{Introduction}
-%
-% The \Verb+spath3+ package is intended as a library for manipulating PGF's \emph{soft paths}.
-% In between defining a path and using it, PGF stores a path as a \emph{soft path} where all the defining structure has been resolved into the basic operations but these have not yet been written to the output file.
-% They can therefore still be manipulated by \TeX, and as they have a very rigid form (and limited vocabulary), they are relatively easy to modify.
-% This package provides some methods for working with these paths.
-% It is not really intended for use by end users but as a foundation on which other packages can be built.
-% As examples, the \Verb+calligraphy+ package and the \Verb+knot+ package are included.
-% The first of these simulates a calligraphic pen stroking a path.
-% The second can be used to draw knot (and similar) diagrams.
-%
-% The format of a soft path is a sequence of triples of the form \Verb+\macro {dimension}{dimension}+.
-% The macro is one of a short list, the dimensions are coordinates in points.
-% There are certain further restrictions, particularly that every path must begin with a \Verb+move to+, and B\'ezier curves consist of three triples.
-%
-% \StopEventually{}
-%
-% \section{Implementation}
-%
-% \iffalse
-%<*spath3>
-% \fi
-% \subsection{Initialisation}
-%
-% Load the \LaTeX3 foundation and register us as a \LaTeX3\ package.
-% \begin{macrocode}
-\NeedsTeXFormat{LaTeX2e}
-\RequirePackage{expl3}
-\RequirePackage{pgf}
-\ProvidesExplPackage {spath3} {2019/02/12} {1.2} {Functions for
-manipulating PGF soft paths}
-\RequirePackage{xparse}
-% \end{macrocode}
-%
-% We need a slew of temporary variables.
-% \begin{macrocode}
-\tl_new:N \l__spath_tmpa_tl
-\tl_new:N \l__spath_tmpb_tl
-\tl_new:N \l__spath_tmpc_tl
-\tl_new:N \l__spath_tmpd_tl
-\tl_new:N \l__spath_smuggle_tl
-\dim_new:N \l__spath_tmpa_dim
-\dim_new:N \l__spath_tmpb_dim
-\fp_new:N \l__spath_tmpa_fp
-\fp_new:N \l__spath_tmpb_fp
-\int_new:N \l__spath_tmpa_int
-\int_new:N \g__spath_map_int
-% \end{macrocode}
-%
-% We need to be able to compare against the macros that can occur in a soft path so these token lists contain them.
-% \begin{macrocode}
-\tl_new:N \g__spath_moveto_tl
-\tl_new:N \g__spath_lineto_tl
-\tl_new:N \g__spath_curveto_tl
-\tl_new:N \g__spath_curvetoa_tl
-\tl_new:N \g__spath_curvetob_tl
-\tl_new:N \g__spath_closepath_tl
-\tl_set:Nn \g__spath_moveto_tl {\pgfsyssoftpath@movetotoken}
-\tl_set:Nn \g__spath_lineto_tl {\pgfsyssoftpath@linetotoken}
-\tl_set:Nn \g__spath_curveto_tl {\pgfsyssoftpath@curvetotoken}
-\tl_set:Nn \g__spath_curvetoa_tl {\pgfsyssoftpath@curvetosupportatoken}
-\tl_set:Nn \g__spath_curvetob_tl {\pgfsyssoftpath@curvetosupportbtoken}
-\tl_set:Nn \g__spath_closepath_tl {\pgfsyssoftpath@closepathtoken}
-% \end{macrocode}
-%
-% \subsection{Basic Structure and Methods}
-%
-% A soft path is a \Verb+prop+.
-% These are lists of the attributes that we define.
-% The first consists of all attributes, the second of those that are ``moveable'' in the sense that they change if we transform the path, the third are the ones that contain actual paths.
-%
-% Note that if using these attributes outside an \Verb+expl3+ context, the spaces should be omitted.
-% \begin{macrocode}
-\tl_new:N \g__spath_attributes
-\tl_new:N \g__spath_moveable_attributes
-\tl_new:N \g__spath_path_attributes
-\tl_set:Nn \g__spath_attributes {
- {path}
- {reverse path}
- {length}
- {real length}
- {number of components}
- {initial point}
- {final point}
- {initial action}
- {final action}
- {min bb}
- {max bb}
-}
-\tl_set:Nn \g__spath_moveable_attributes {
- {initial point}
- {final point}
- {min bb}
- {max bb}
-}
-\tl_set:Nn \g__spath_path_attributes {
- {path}
- {reverse path}
-}
-% \end{macrocode}
-%
-% An \Verb+spath+ object is actually a \Verb+prop+.
-% The following functions are wrappers around the underlying \Verb+prop+ functions.
-% We prefix the names to avoid clashing with other \Verb+prop+s that might be lying around, this is why all the \Verb+spath+ methods take argument \Verb+:n+ and not \Verb+:N+.
-% Given that \Verb+spath+ objects might be created inside a group but used outside it, we work globally throughout.
-% \begin{macro}{\spath_new:n}
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_new:n #1
-{
- \prop_new:c {l__spath_#1}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_clear:n}
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_clear:n #1
-{
- \prop_gclear:c {l__spath_#1}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_clear_new:n}
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_clear_new:n #1
-{
- \prop_gclear_new:c {l__spath_#1}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_show:n}
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_show:n #1
-{
- \prop_show:c {l__spath_#1}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_put:nnn}
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_put:nnn #1#2#3
-{
- \prop_gput:cnn {l__spath_#1} {#2} {#3}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_remove:nn}
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_remove:nn #1#2
-{
- \prop_gremove:cn {l__spath_#1} {#2}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\__spath_get:nn}
-% This function is an internal one since the real \Verb+get+ function will generate its data if it does not already exist.
-% \begin{macrocode}
-\cs_new_nopar:Npn \__spath_get:nn #1#2
-{
- \prop_item:cn {l__spath_#1} {#2}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\__spath_get:nnN}
-% \begin{macrocode}
-\cs_new_nopar:Npn \__spath_get:nnN #1#2#3
-{
- \prop_get:cnN {l__spath_#1} {#2} #3
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_if_in:nn}
-% \begin{macrocode}
-\prg_new_conditional:Npnn \spath_if_in:nn #1#2 {p, T, F, TF}
-{
- \prop_if_in:cnTF {l__spath_#1} {#2}
- { \prg_return_true: }
- { \prg_return_false: }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\__spath_get:nnN}
-% \begin{macrocode}
-\cs_generate_variant:Nn \__prop_split:NnTF {cnTF}
-\prg_new_protected_conditional:Npnn \__spath_get:nnN #1#2#3 {T, F, TF}
-{
- \__prop_split:cnTF {l__spath_#1} {#2}
- {
- \tl_set:Nn #3 {##2}
- \prg_return_true:
- }
- { \prg_return_false: }
-}
-\cs_generate_variant:Nn \spath_put:nnn {nnV, nnx, nno}
-\cs_generate_variant:Nn \__spath_get:nn {Vn}
-\cs_generate_variant:Nn \__spath_get:nnN {VnN}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_if_exist:n}
-% \begin{macrocode}
-\prg_new_conditional:Npnn \spath_if_exist:n #1 {p,T,F,TF}
-{
- \prop_if_exist:cTF {l__spath_#1}
- {
- \prg_return_true:
- }
- {
- \prg_return_false:
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_clone:nn}
-% Clones an \Verb+spath+.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_clone:nn #1 #2
-{
- \spath_clear_new:n {#2}
- \tl_map_inline:Nn \g__spath_attributes
- {
- \spath_if_in:nnT {#1} {##1}
- {
- \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl
- \spath_put:nnV {#2} {##1} \l__spath_tmpa_tl
- }
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_get_current_path:n}
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \spath_get_current_path:n #1
-{
- \pgfsyssoftpath@getcurrentpath\l__spath_tmpa_tl
- \spath_clear_new:n {#1}
- \spath_put:nnV {#1} {path} \l__spath_tmpa_tl
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_set_current_path:n}
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \spath_set_current_path:n #1
-{
- \spath_get:nnN {#1} {min bb} \l__spath_tmpa_tl
- \exp_last_unbraced:NV \pgf@protocolsizes\l__spath_tmpa_tl
-
- \spath_get:nnN {#1} {max bb} \l__spath_tmpa_tl
- \exp_last_unbraced:NV \pgf@protocolsizes\l__spath_tmpa_tl
-
- \spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \pgfsyssoftpath@setcurrentpath\l__spath_tmpa_tl
- \pgfsyssoftpath@flushcurrentpath
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_use_path:nn}
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \spath_use_path:nn #1#2
-{
- \spath_set_current_path:n {#1}
- \pgfusepath{#2}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_protocol_path:n}
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \spath_protocol_path:n #1
-{
- \spath_get:nnN {#1} {min bb} \l__spath_tmpa_tl
- \exp_last_unbraced:NV \pgf@protocolsizes\l__spath_tmpa_tl
-
- \spath_get:nnN {#1} {max bb} \l__spath_tmpa_tl
- \exp_last_unbraced:NV \pgf@protocolsizes\l__spath_tmpa_tl
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_tikz_path:nn}
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \spath_tikz_path:nn #1#2
-{
- \path[#1] \pgfextra{
- \spath_get:nnN {#2} {path} \l__spath_tmpa_tl
- \pgfsyssoftpath@setcurrentpath \l__spath_tmpa_tl
- };
-}
-\cs_generate_variant:Nn \spath_tikz_path:nn {Vn}
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Computing Information}
-%
-% \begin{macro}{\spath_get:nn}
-% The information that we store along with a soft path can be computed from it, but computing it every time is wasteful.
-% So this is the real \Verb+\spath_get:nn+ function which checks to see if we have already computed it and then either retrieves it or computes it.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_get:nn #1#2
-{
- \spath_if_in:nnF {#1} {#2}
- {
- \cs_if_exist_use:cT {spath_generate_#2:n} {{#1}}
- }
- \__spath_get:nn {#1} {#2}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_get:nnN}
-% As above but leaves the result in a token list rather than in the stream.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_get:nnN #1#2#3
-{
- \spath_if_in:nnF {#1} {#2}
- {
- \cs_if_exist_use:cT {spath_generate_#2:n} {{#1}}
- }
- \__spath_get:nnN {#1} {#2} #3
-}
-\cs_generate_variant:Nn \spath_get:nnN {VnN}
-% \end{macrocode}
-% \end{macro}
-%
-% The next slew of functions generate data from the original path, storing it in the \Verb+prop+ for further retrieval.
-% \begin{macro}{\spath_generate_length:n}
-% Counts the number of triples in the path.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_generate_length:n #1
-{
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \spath_put:nnx {#1} {length} {\int_eval:n {\tl_count:N \l__spath_tmpa_tl /3 }}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_generate_reallength:n}
-% The real length of a path is the number of triples that actually draw something (that is, the number of lines and curves).
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_generate_reallength:n #1
-{
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \int_set:Nn \l__spath_tmpa_int {0}
- \tl_map_inline:Nn \l__spath_tmpa_tl {
- \tl_if_eq:nnT {##1} {\pgfsyssoftpath@linetotoken}
- {
- \int_incr:N \l__spath_tmpa_int
- }
- \tl_if_eq:nnT {##1} {\pgfsyssoftpath@curvetotoken}
- {
- \int_incr:N \l__spath_tmpa_int
- }
- }
- \spath_put:nnx {#1} {real length} {\int_use:N \l__spath_tmpa_int}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_generate_numberofcomponents:n}
-% A component is a continuous segment of the path, separated by moves.
-% Successive moves are not collapsed, and zero length moves count.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_generate_numberofcomponents:n #1
-{
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \int_set:Nn \l__spath_tmpa_int {0}
- \tl_map_inline:Nn \l__spath_tmpa_tl {
- \tl_if_eq:nnT {##1} {\pgfsyssoftpath@movetotoken}
- {
- \int_incr:N \l__spath_tmpa_int
- }
- }
- \spath_put:nnx {#1} {number of components} {\int_use:N \l__spath_tmpa_int}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_generate_initialpoint:n}
-% The starting point of the path.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_generate_initialpoint:n #1
-{
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \tl_clear:N \l__spath_tmpb_tl
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \spath_put:nnV {#1} {initial point} \l__spath_tmpb_tl
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_generate_finalpoint:n}
-% The final point of the path.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_generate_finalpoint:n #1
-{
- \tl_clear:N \l__spath_tmpb_tl
- \spath_if_in:nnTF {#1} {reverse path}
- {
- \__spath_get:nnN {#1} {reverse path} \l__spath_tmpa_tl
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- }
- {
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \tl_reverse:N \l__spath_tmpa_tl
- \tl_put_left:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_put_left:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- }
- \spath_put:nnV {#1} {final point} \l__spath_tmpb_tl
-}
-\cs_generate_variant:Nn \spath_generate_finalpoint:n {V}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_generate_reversepath:n}
-% This computes the reverse of the path.
-% TODO: handle closed paths, possibly rectangles.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_generate_reversepath:n #1
-{
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \tl_clear:N \l__spath_tmpb_tl
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_put_left:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- \bool_until_do:nn {
- \tl_if_empty_p:N \l__spath_tmpa_tl
- }
- {
- \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nn \l__spath_tmpd_tl {}
- \tl_case:NnF \l__spath_tmpc_tl
- {
- \g__spath_moveto_tl {\tl_set_eq:NN \l__spath_tmpd_tl \g__spath_moveto_tl }
- \g__spath_lineto_tl {\tl_set_eq:NN \l__spath_tmpd_tl \g__spath_lineto_tl }
- \g__spath_curveto_tl {\tl_set_eq:NN \l__spath_tmpd_tl \g__spath_curvetoa_tl }
- \g__spath_curvetoa_tl {\tl_set_eq:NN \l__spath_tmpd_tl \g__spath_curveto_tl }
- \g__spath_curvetob_tl {\tl_set_eq:NN \l__spath_tmpd_tl \g__spath_curvetob_tl }
- }
- {
- \tl_show:N \l__spath_tmpc_tl
- }
- \tl_put_left:NV \l__spath_tmpb_tl \l__spath_tmpd_tl
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_put_left:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- }
- \tl_put_left:NV \l__spath_tmpb_tl \g__spath_moveto_tl
- \spath_put:nnV {#1} {reverse path} \l__spath_tmpb_tl
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_generate_initialaction:n}
-% This is the first thing that the path does (after the initial move).
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_generate_initialaction:n #1
-{
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \tl_clear:N \l__spath_tmpb_tl
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_if_empty:NF \l__spath_tmpa_tl {
- \tl_set:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl}
- }
- \spath_put:nnV {#1} {initial action} \l__spath_tmpb_tl
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_generate_final action:n}
-% This is the last thing that the path does.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_generate_finalaction:n #1
-{
- \tl_clear:N \l__spath_tmpb_tl
- \spath_if_in:nnTF {#1} {reverse path}
- {
- \__spath_get:nnN {#1} {reverse path} \l__spath_tmpa_tl
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- }
- {
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \tl_reverse:N \l__spath_tmpa_tl
- }
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_if_empty:NF \l__spath_tmpa_tl {
- \tl_set:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl}
- }
- \tl_if_eq:NNT \l__spath_tmpa_tl \g__spath_curvetoa_tl
- {
- \tl_set_eq:NN \l__spath_tmpa_tl \g__spath_curveto_tl
- }
- \spath_put:nnV {#1} {final action} \l__spath_tmpb_tl
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_generate_minbb:n}
-% This computes the minimum (bottom left) of the bounding box of the path.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_generate_minbb:n #1
-{
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \bool_until_do:nn {
- \tl_if_empty_p:N \l__spath_tmpa_tl
- }
- {
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpa_dim}}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpb_dim}}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- }
- \tl_clear:N \l__spath_tmpb_tl
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- \spath_put:nnV {#1} {min bb} \l__spath_tmpb_tl
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_generate_max bb:n}
-% This computes the maximum (top right) of the bounding box of the path.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_generate_maxbb:n #1
-{
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \bool_until_do:nn {
- \tl_if_empty_p:N \l__spath_tmpa_tl
- }
- {
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpa_dim {\dim_max:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpa_dim}}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\dim_max:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpb_dim}}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- }
- \tl_clear:N \l__spath_tmpb_tl
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- \spath_put:nnV {#1} {max bb} \l__spath_tmpb_tl
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_generate_all:n}
-% This function generates all of the data in one fell swoop.
-% By traversing the path just once it is quicker than doing each one individually.
-% However, it does need to store a lot of data as it goes.
-% \begin{itemize}
-% \item \Verb+\l__spath_rp_tl+ will hold the reversed path
-% \item \Verb+\l__spath_l_int+ will hold the length
-% \item \Verb+\l__spath_rl_int+ will hold the real length
-% \item \Verb+\l__spath_nc_int+ will hold the number of components
-% \item \Verb+\l__spath_ip_tl+ will hold the initial point
-% \item \Verb+\l__spath_fp_tl+ will hold the final point
-% \item \Verb+\l__spath_ia_tl+ will hold the initial action
-% \item \Verb+\l__spath_fa_tl+ will hold the final action
-% \item \Verb+\l__spath_minx_dim+ will hold the min x bb
-% \item \Verb+\l__spath_miny_dim+ will hold the min y bb
-% \item \Verb+\l__spath_maxx_dim+ will hold the max x bb
-% \item \Verb+\l__spath_maxy_dim+ will hold the max y bb
-% \end{itemize}
-% \begin{macrocode}
-\tl_new:N \l__spath_rp_tl
-\int_new:N \l__spath_l_int
-\int_new:N \l__spath_rl_int
-\int_new:N \l__spath_nc_int
-\tl_new:N \l__spath_ip_tl
-\tl_new:N \l__spath_fp_tl
-\tl_new:N \l__spath_ia_tl
-\tl_new:N \l__spath_fa_tl
-\dim_new:N \l__spath_minx_dim
-\dim_new:N \l__spath_miny_dim
-\dim_new:N \l__spath_maxx_dim
-\dim_new:N \l__spath_maxy_dim
-
-\cs_new_nopar:Npn \spath_generate_all:n #1
-{
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
-
- \tl_clear:N \l__spath_rp_tl
- \int_set:Nn \l__spath_l_int {1}
- \int_zero:N \l__spath_rl_int
- \int_set:Nn \l__spath_nc_int {1}
- \tl_clear:N \l__spath_ip_tl
- \tl_clear:N \l__spath_fp_tl
- \tl_clear:N \l__spath_ia_tl
- \tl_clear:N \l__spath_fa_tl
- \dim_zero:N \l__spath_minx_dim
- \dim_zero:N \l__spath_miny_dim
- \dim_zero:N \l__spath_maxx_dim
- \dim_zero:N \l__spath_maxy_dim
-
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \tl_clear:N \l__spath_ip_tl
- \tl_put_right:Nx \l__spath_ip_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
-
- \dim_set_eq:NN \l__spath_minx_dim \l__spath_tmpa_dim
- \dim_set_eq:NN \l__spath_miny_dim \l__spath_tmpb_dim
- \dim_set_eq:NN \l__spath_maxx_dim \l__spath_tmpa_dim
- \dim_set_eq:NN \l__spath_maxy_dim \l__spath_tmpb_dim
-
- \tl_put_left:Nx \l__spath_rp_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
-
- \tl_set:Nx \l__spath_ia_tl {\tl_head:N \l__spath_tmpa_tl}
-
- \bool_until_do:nn {
- \tl_if_empty_p:N \l__spath_tmpa_tl
- }
- {
- \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nn \l__spath_tmpd_tl {}
- \tl_set_eq:NN \l__spath_fa_tl \l__spath_tmpc_tl
- \int_incr:N \l__spath_l_int
-
- \tl_case:NnF \l__spath_tmpc_tl
- {
- \g__spath_moveto_tl {
- \tl_set_eq:NN \l__spath_tmpd_tl \g__spath_moveto_tl
- \int_incr:N \l__spath_nc_int
- }
- \g__spath_lineto_tl {
- \tl_set_eq:NN \l__spath_tmpd_tl \g__spath_lineto_tl
- \int_incr:N \l__spath_rl_int
- }
- \g__spath_curveto_tl {
- \tl_set_eq:NN \l__spath_tmpd_tl \g__spath_curvetoa_tl
- \int_incr:N \l__spath_rl_int
- }
- \g__spath_curvetoa_tl {
- \tl_set_eq:NN \l__spath_tmpd_tl \g__spath_curveto_tl
- }
- \g__spath_curvetob_tl {
- \tl_set_eq:NN \l__spath_tmpd_tl \g__spath_curvetob_tl
- }
- }
- {
- \tl_show:N \l__spath_tmpc_tl
- }
- \tl_put_left:NV \l__spath_rp_tl \l__spath_tmpd_tl
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \dim_set:Nn \l__spath_minx_dim {\dim_min:nn { \l__spath_minx_dim} {\l__spath_tmpa_dim}}
- \dim_set:Nn \l__spath_miny_dim {\dim_min:nn { \l__spath_miny_dim} {\l__spath_tmpb_dim}}
- \dim_set:Nn \l__spath_maxx_dim {\dim_max:nn { \l__spath_maxx_dim} {\l__spath_tmpa_dim}}
- \dim_set:Nn \l__spath_maxy_dim {\dim_max:nn { \l__spath_maxy_dim} {\l__spath_tmpb_dim}}
-
- \tl_put_left:Nx \l__spath_rp_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
-
- \tl_set:Nx \l__spath_fp_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
-
- }
-
- \tl_put_left:NV \l__spath_rp_tl \g__spath_moveto_tl
-
- \spath_put:nnV {#1} {reverse path} \l__spath_rp_tl
- \spath_put:nnV {#1} {length} \l__spath_l_int
- \spath_put:nnV {#1} {real length} \l__spath_rl_int
- \spath_put:nnV {#1} {number of components} \l__spath_nc_int
- \spath_put:nnV {#1} {initial point} \l__spath_ip_tl
- \spath_put:nnV {#1} {final point} \l__spath_fp_tl
- \spath_put:nnV {#1} {initial action} \l__spath_ia_tl
- \spath_put:nnV {#1} {final action} \l__spath_fa_tl
-
- \tl_clear:N \l__spath_tmpb_tl
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_minx_dim}
- {\dim_use:N \l__spath_miny_dim}
- }
- \spath_put:nnV {#1} {min bb} \l__spath_tmpb_tl
-
- \tl_clear:N \l__spath_tmpb_tl
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_maxx_dim}
- {\dim_use:N \l__spath_maxy_dim}
- }
- \spath_put:nnV {#1} {max bb} \l__spath_tmpb_tl
-
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Path Manipulation}
-%
-% \begin{macro}{\spath_translate:nnn}
-% Translates a path.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_translate:nnn #1#2#3
-{
- \tl_map_inline:Nn \g__spath_moveable_attributes
- {
- \spath_if_in:nnT {#1} {##1}
- {
- \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl
-
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl + #2}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl + #3}
- \tl_clear:N \l__spath_tmpb_tl
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- \spath_put:nnV {#1} {##1} \l__spath_tmpb_tl
- }
- }
- \tl_map_inline:Nn \g__spath_path_attributes
- {
- \spath_if_in:nnT {#1} {##1}
- {
- \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl
- \tl_clear:N \l__spath_tmpb_tl
- \bool_until_do:nn {
- \tl_if_empty_p:N \l__spath_tmpa_tl
- }
- {
- \tl_put_right:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl + #2}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl + #3}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- }
- \spath_put:nnV {#1} {##1} \l__spath_tmpb_tl
- }
- }
-}
-
-\cs_generate_variant:Nn \spath_translate:nnn {nxx}
-% \end{macrocode}
-%
-% This variant allows for passing the coordinates as a single braced group as it strips off the outer braces of the second argument.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_translate:nn #1#2
-{
- \spath_translate:nnn {#1} #2
-}
-
-\cs_generate_variant:Nn \spath_translate:nn {nV}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_scale:nnn}
-% Scale a path.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_scale:nnn #1#2#3
-{
- \tl_map_inline:Nn \g__spath_moveable_attributes
- {
- \spath_if_in:nnT {#1} {##1}
- {
- \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl
-
- \fp_set:Nn \l__spath_tmpa_fp {\tl_head:N \l__spath_tmpa_tl * #2}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \fp_set:Nn \l__spath_tmpb_fp {\tl_head:N \l__spath_tmpa_tl * #3}
- \tl_clear:N \l__spath_tmpb_tl
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\fp_to_dim:N \l__spath_tmpa_fp}
- {\fp_to_dim:N \l__spath_tmpb_fp}
- }
- \spath_put:nnV {#1} {##1} \l__spath_tmpb_tl
- }
- }
- \tl_map_inline:Nn \g__spath_path_attributes
- {
- \spath_if_in:nnT {#1} {##1}
- {
- \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl
- \tl_clear:N \l__spath_tmpb_tl
- \bool_until_do:nn {
- \tl_if_empty_p:N \l__spath_tmpa_tl
- }
- {
- \tl_put_right:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \fp_set:Nn \l__spath_tmpa_fp {\tl_head:N \l__spath_tmpa_tl * #2}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \fp_set:Nn \l__spath_tmpb_fp {\tl_head:N \l__spath_tmpa_tl * #3}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\fp_to_dim:N \l__spath_tmpa_fp}
- {\fp_to_dim:N \l__spath_tmpb_fp}
- }
- }
- \spath_put:nnV {#1} {##1} \l__spath_tmpb_tl
- }
- }
-}
-\cs_generate_variant:Nn \spath_scale:nnn {nxx}
-% \end{macrocode}
-%
-% This variant allows for passing the coordinates as a single braced group as it strips off the outer braces of the second argument.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_scale:nn #1#2
-{
- \spath_scale:nnn {#1} #2
-}
-
-\cs_generate_variant:Nn \spath_scale:nn {nV}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_transform:nnnnnnn}
-% Applies an affine (matrix and vector) transformation to path.
-% The matrix is specified in rows first.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_transform:nnnnnnn #1#2#3#4#5#6#7
-{
- \tl_map_inline:Nn \g__spath_moveable_attributes
- {
- \spath_if_in:nnT {#1} {##1}
- {
- \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_head:N \l__spath_tmpa_tl}
- \fp_set:Nn \l__spath_tmpa_fp {\l__spath_tmpa_tl * #2 + \l__spath_tmpb_tl * #3 + #6}
- \fp_set:Nn \l__spath_tmpb_fp {\l__spath_tmpa_tl * #4 + \l__spath_tmpb_tl * #5 + #7}
- \tl_clear:N \l__spath_tmpb_tl
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\fp_to_dim:N \l__spath_tmpa_fp}
- {\fp_to_dim:N \l__spath_tmpb_fp}
- }
- \spath_put:nnV {#1} {##1} \l__spath_tmpb_tl
- }
- }
- \tl_map_inline:Nn \g__spath_path_attributes
- {
- \spath_if_in:nnT {#1} {##1}
- {
- \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl
- \tl_clear:N \l__spath_tmpb_tl
- \bool_until_do:nn {
- \tl_if_empty_p:N \l__spath_tmpa_tl
- }
- {
- \tl_put_right:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_set:Nx \l_tmpb_tl {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \fp_set:Nn \l__spath_tmpa_fp {\l_tmpa_tl * #2 + \l_tmpb_tl * #3 + #6}
- \fp_set:Nn \l__spath_tmpb_fp {\l_tmpa_tl * #4 + \l_tmpb_tl * #5 + #7}
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\fp_to_dim:N \l__spath_tmpa_fp}
- {\fp_to_dim:N \l__spath_tmpb_fp}
- }
- }
- \spath_put:nnV {#1} {##1} \l__spath_tmpb_tl
- }
- }
-}
-
-\cs_generate_variant:Nn \spath_transform:nnnnnnn {nxxxxxx}
-% \end{macrocode}
-%
-% This variant allows for passing the coordinates as a single braced group as it strips off the outer braces of the second argument.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_transform:nn #1#2
-{
- \spath_transform:nnnnnnn {#1} #2
-}
-
-\cs_generate_variant:Nn \spath_transform:nn {nV}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_reverse:n}
-% This reverses a path.
-% As a lot of the data is invariant under reversing, there isn't a lot to do.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_reverse:n #1
-{
- \spath_if_in:nnF {#1} {reverse path} {
- \use:c {spath_generate_reverse path:n} {#1}
- }
- \spath_swap:nnn {#1} {path} {reverse path}
- \spath_swap:nnn {#1} {initial point} {final point}
- \spath_swap:nnn {#1} {initial action} {final action}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_swap:nnn}
-% Swaps two entries, being careful to ensure that their existence (or otherwise) is preserved.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_swap:nnn #1#2#3
-{
- \__spath_get:nnNF {#1} {#2} \l__spath_tmpa_tl {\tl_clear:N \l__spath_tmpa_tl}
- \__spath_get:nnNF {#1} {#3} \l__spath_tmpb_tl {\tl_clear:N \l__spath_tmpb_tl}
- \tl_if_empty:NTF \l__spath_tmpb_tl
- {\spath_remove:nn {#1} {#2}}
- {\spath_put:nnV {#1} {#2} \l__spath_tmpb_tl}
- \tl_if_empty:NTF \l__spath_tmpa_tl
- {\spath_remove:nn {#1} {#3}}
- {\spath_put:nnV {#1} {#3} \l__spath_tmpa_tl}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_weld:nn}
-% This welds one path to another, moving the second so that it's initial point coincides with the first's final point.
-% It is called a \emph{weld} because the initial move of the second path is removed.
-% The first path is updated, the second is not modified.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_weld:nn #1#2
-{
- \spath_clone:nn {#2} {tmp_path}
- \spath_get:nnN {#1} {final point} \l__spath_tmpa_tl
-
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
-
- \spath_get:nnN {#2} {initial point} \l__spath_tmpa_tl
-
- \dim_sub:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_sub:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
-
- \spath_translate:nxx {tmp_path} {\dim_use:N \l__spath_tmpa_dim} {\dim_use:N \l__spath_tmpb_dim}
-
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \__spath_get:nnN {tmp_path} {path} \l__spath_tmpb_tl
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl
-
- \spath_put:nnV {#1} {path} \l__spath_tmpa_tl
-
- \__spath_get:nnNTF {tmp_path} {final point} \l__spath_tmpa_tl
- {
- \spath_put:nnV {#1} {final point} \l__spath_tmpa_tl
- }
- {
- \spath_remove:nn {#1} {final point}
- }
-
- \__spath_get:nnNTF {tmp_path} {final action} \l__spath_tmpa_tl
- {
- \spath_put:nnV {#1} {final action} \l__spath_tmpa_tl
- }
- {
- \spath_remove:nn {#1} {final action}
- }
-
- \__spath_get:nnNT {tmp_path} {min bb} \l__spath_tmpa_tl
- {
- \__spath_get:nnNT {#1} {min bb} \l__spath_tmpb_tl
- {
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
-
- \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\l__spath_tmpa_dim} {\tl_head:N \l__spath_tmpb_tl}}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\l__spath_tmpb_dim} {\tl_head:N \l__spath_tmpb_tl}}
-
- \tl_clear:N \l__spath_tmpb_tl
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- \spath_put:nnV {#1} {min bb} \l__spath_tmpb_tl
- }
- }
-
- \__spath_get:nnNT {tmp_path} {max bb} \l__spath_tmpa_tl
- {
- \__spath_get:nnNT {#1} {max bb} \l__spath_tmpb_tl
- {
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
-
- \dim_set:Nn \l__spath_tmpa_dim {\dim_max:nn {\l__spath_tmpa_dim} {\tl_head:N \l__spath_tmpb_tl}}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \dim_set:Nn \l__spath_tmpb_dim {\dim_max:nn {\l__spath_tmpb_dim} {\tl_head:N \l__spath_tmpb_tl}}
-
- \tl_clear:N \l__spath_tmpb_tl
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- \spath_put:nnV {#1} {max bb} \l__spath_tmpb_tl
- }
- }
-
- \__spath_get:nnNT {tmp_path} {reverse path} \l__spath_tmpa_tl
- {
- \__spath_get:nnNT {#1} {reverse path} \l__spath_tmpb_tl
- {
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl
-
- \spath_put:nnV {#1} {reverse path} \l__spath_tmpa_tl
- }
- }
-
- \__spath_get:nnNT {tmp_path} {length} \l__spath_tmpa_tl
- {
- \__spath_get:nnNT {#1} {length} \l__spath_tmpb_tl
- {
- \int_set:Nn \l__spath_tmpa_int {\l__spath_tmpa_tl + \l__spath_tmpb_tl - 1}
- \spath_put:nnV {#1} {length} \l__spath_tmpa_int
- }
- }
-
- \__spath_get:nnNT {tmp_path} {real length} \l__spath_tmpa_tl
- {
- \__spath_get:nnNT {#1} {real length} \l__spath_tmpb_tl
- {
- \int_set:Nn \l__spath_tmpa_int {\l__spath_tmpa_tl + \l__spath_tmpb_tl}
- \spath_put:nnV {#1} {real length} \l__spath_tmpa_int
- }
- }
-
- \__spath_get:nnNT {tmp_path} {number of components} \l__spath_tmpa_tl
- {
- \__spath_get:nnNT {#1} {number of components} \l__spath_tmpb_tl
- {
- \int_set:Nn \l__spath_tmpa_int {\l__spath_tmpa_tl + \l__spath_tmpb_tl - 1}
- \spath_put:nnV {#1} {number of components} \l__spath_tmpa_int
- }
- }
-
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_prepend_no_move:nn}
-% Prepend the path from the second \Verb+spath+ to the first, removing
-% the adjoining move.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_prepend_no_move:nn #1#2
-{
- \spath_if_exist:nT {#2}
- {
- \__spath_get:nnN {#2} {path} \l__spath_tmpa_tl
- \__spath_get:nnN {#1} {path} \l__spath_tmpb_tl
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl
- \spath_put:nnV {#1} {path} \l__spath_tmpa_tl
-
- \spath_if_in:nnTF {#2} {initial point}
- {
- \__spath_get:nnN {#2} {initial point} \l__spath_tmpa_tl
- \spath_put:nnV {#1} {initial point} \l__spath_tmpa_tl
- }
- {
- \spath_remove:nn {#1} {initial point}
- }
-
- \spath_if_in:nnTF {#2} {initial action}
- {
- \__spath_get:nnN {#2} {initial action} \l__spath_tmpa_tl
- \spath_put:nnV {#1} {initial action} \l__spath_tmpa_tl
- }
- {
- \spath_remove:nn {#1} {initial action}
- }
-
- \bool_if:nTF
- {
- \spath_if_in_p:nn {#1} {length}
- &&
- \spath_if_in_p:nn {#2} {length}
- }
- {
- \__spath_get:nnN {#1} {length} \l__spath_tmpa_tl
- \__spath_get:nnN {#2} {length} \l__spath_tmpb_tl
- \spath_put:nnx {#1} {length} {\int_eval:n {\l__spath_tmpa_tl +
- \l__spath_tmpb_tl - 1}}
- }
- {
- \spath_remove:nn {#1} {length}
- }
- \bool_if:nTF
- {
- \spath_if_in_p:nn {#1} {real length}
- &&
- \spath_if_in_p:nn {#2} {real length}
- }
- {
- \__spath_get:nnN {#1} {real length} \l__spath_tmpa_tl
- \__spath_get:nnN {#2} {real length} \l__spath_tmpb_tl
- \spath_put:nnx {#1} {real length} {\int_eval:n {\l__spath_tmpa_tl +
- \l__spath_tmpb_tl }}
- }
- {
- \spath_remove:nn {#1} {real length}
- }
- \bool_if:nTF
- {
- \spath_if_in_p:nn {#1} {number of components}
- &&
- \spath_if_in_p:nn {#2} {number of components}
- }
- {
- \__spath_get:nnN {#1} {number of components} \l__spath_tmpa_tl
- \__spath_get:nnN {#2} {number of components} \l__spath_tmpb_tl
- \spath_put:nnx {#1} {number of components} {\int_eval:n {\l__spath_tmpa_tl +
- \l__spath_tmpb_tl - 1}}
- }
- {
- \spath_remove:nn {#1} {number of components}
- }
- \bool_if:nTF
- {
- \spath_if_in_p:nn {#1} {min bb}
- &&
- \spath_if_in_p:nn {#2} {min bb}
- }
- {
- \__spath_get:nnN {#1} {min bb} \l__spath_tmpa_tl
- \__spath_get:nnN {#2} {min bb} \l__spath_tmpb_tl
- \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\tl_item:Nn
- \l__spath_tmpa_tl {1}} {\tl_item:Nn
- \l__spath_tmpb_tl {1}}}
- \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\tl_item:Nn
- \l__spath_tmpa_tl {2}} {\tl_item:Nn
- \l__spath_tmpb_tl {2}}}
- \spath_put:nnx {#1} {min bb} {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- }
- {
- \spath_remove:nn {#1} {min bb}
- }
- \bool_if:nTF
- {
- \spath_if_in_p:nn {#1} {max bb}
- &&
- \spath_if_in_p:nn {#2} {max bb}
- }
- {
- \__spath_get:nnN {#1} {max bb} \l__spath_tmpa_tl
- \__spath_get:nnN {#2} {max bb} \l__spath_tmpb_tl
- \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\tl_item:Nn
- \l__spath_tmpa_tl {1}} {\tl_item:Nn
- \l__spath_tmpb_tl {1}}}
- \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\tl_item:Nn
- \l__spath_tmpa_tl {2}} {\tl_item:Nn
- \l__spath_tmpb_tl {2}}}
- \spath_put:nnx {#1} {max bb} {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- }
- {
- \spath_remove:nn {#1} {max bb}
- }
- \bool_if:nTF
- {
- \spath_if_in_p:nn {#1} {reverse path}
- &&
- \spath_if_in_p:nn {#2} {reverse path}
- }
- {
- \__spath_get:nnN {#1} {reverse path} \l__spath_tmpa_tl
- \__spath_get:nnN {#2} {reverse path} \l__spath_tmpb_tl
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl
- \spath_put:nnV {#1} {reverse path} \l__spath_tmpb_tl
- }
- {
- \spath_remove:nn {#1} {reverse path}
- }
-
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_append_no_move:nn}
-% Append the path from the second \Verb+spath+ to the first, removing
-% the adjoining move.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_append_no_move:nn #1#2
-{
- \spath_if_exist:nT {#2}
- {
- \spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \spath_get:nnN {#2} {path} \l__spath_tmpb_tl
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl
- \spath_put:nnV {#1} {path} \l__spath_tmpa_tl
- \spath_if_in:nnTF {#2} {final point}
- {
- \__spath_get:nnN {#2} {final point} \l__spath_tmpa_tl
- \spath_put:nnV {#1} {final point} \l__spath_tmpa_tl
- }
- {
- \spath_remove:nn {#1} {final point}
- }
- \spath_if_in:nnTF {#2} {final action}
- {
- \__spath_get:nnN {#2} {final action} \l__spath_tmpa_tl
- \spath_put:nnV {#1} {final action} \l__spath_tmpa_tl
- }
- {
- \spath_remove:nn {#1} {final action}
- }
- \bool_if:nTF
- {
- \spath_if_in_p:nn {#1} {length}
- &&
- \spath_if_in_p:nn {#2} {length}
- }
- {
- \__spath_get:nnN {#1} {length} \l__spath_tmpa_tl
- \__spath_get:nnN {#2} {length} \l__spath_tmpb_tl
- \spath_put:nnx {#1} {length} {\int_eval:n {\l__spath_tmpa_tl +
- \l__spath_tmpb_tl - 1}}
- }
- {
- \spath_remove:nn {#1} {length}
- }
- \bool_if:nTF
- {
- \spath_if_in_p:nn {#1} {real length}
- &&
- \spath_if_in_p:nn {#2} {real length}
- }
- {
- \__spath_get:nnN {#1} {real length} \l__spath_tmpa_tl
- \__spath_get:nnN {#2} {real length} \l__spath_tmpb_tl
- \spath_put:nnx {#1} {real length} {\int_eval:n {\l__spath_tmpa_tl +
- \l__spath_tmpb_tl }}
- }
- {
- \spath_remove:nn {#1} {real length}
- }
- \bool_if:nTF
- {
- \spath_if_in_p:nn {#1} {number of components}
- &&
- \spath_if_in_p:nn {#2} {number of components}
- }
- {
- \__spath_get:nnN {#1} {number of components} \l__spath_tmpa_tl
- \__spath_get:nnN {#2} {number of components} \l__spath_tmpb_tl
- \spath_put:nnx {#1} {number of components} {\int_eval:n {\l__spath_tmpa_tl +
- \l__spath_tmpb_tl - 1}}
- }
- {
- \spath_remove:nn {#1} {number of components}
- }
- \bool_if:nTF
- {
- \spath_if_in_p:nn {#1} {min bb}
- &&
- \spath_if_in_p:nn {#2} {min bb}
- }
- {
- \__spath_get:nnN {#1} {min bb} \l__spath_tmpa_tl
- \__spath_get:nnN {#2} {min bb} \l__spath_tmpb_tl
- \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\tl_item:Nn
- \l__spath_tmpa_tl {1}} {\tl_item:Nn
- \l__spath_tmpb_tl {1}}}
- \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\tl_item:Nn
- \l__spath_tmpa_tl {2}} {\tl_item:Nn
- \l__spath_tmpb_tl {2}}}
- \spath_put:nnx {#1} {min bb} {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- }
- {
- \spath_remove:nn {#1} {min bb}
- }
- \bool_if:nTF
- {
- \spath_if_in_p:nn {#1} {max bb}
- &&
- \spath_if_in_p:nn {#2} {max bb}
- }
- {
- \__spath_get:nnN {#1} {max bb} \l__spath_tmpa_tl
- \__spath_get:nnN {#2} {max bb} \l__spath_tmpb_tl
- \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\tl_item:Nn
- \l__spath_tmpa_tl {1}} {\tl_item:Nn
- \l__spath_tmpb_tl {1}}}
- \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\tl_item:Nn
- \l__spath_tmpa_tl {2}} {\tl_item:Nn
- \l__spath_tmpb_tl {2}}}
- \spath_put:nnx {#1} {max bb} {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- }
- {
- \spath_remove:nn {#1} {max bb}
- }
- \bool_if:nTF
- {
- \spath_if_in_p:nn {#1} {reverse path}
- &&
- \spath_if_in_p:nn {#2} {reverse path}
- }
- {
- \__spath_get:nnN {#2} {reverse path} \l__spath_tmpa_tl
- \__spath_get:nnN {#1} {reverse path} \l__spath_tmpb_tl
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl}
- \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl
- \spath_put:nnV {#1} {reverse path} \l__spath_tmpb_tl
- }
- {
- \spath_remove:nn {#1} {reverse path}
- }
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_bake_round:n}
-% Ought to clear the reverse path, if set.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_bake_round:n #1
-{
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \pgf@@processround\l__spath_tmpa_tl\l__spath_tmpb_tl
- \spath_put:nnV {#1} {path} \l__spath_tmpb_tl
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_close_path:n}
-% Appends a close path to the end of the path, and to the end of the reverse path.
-% For now, the point is the initial or final point (respectively).
-% To be future proof, it ought to be the point of the adjacent move to.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_close_path:n #1
-{
- \spath_get:nnN {#1} {initial point} \l__spath_tmpb_tl
- \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl
- \tl_put_right:NV \l__spath_tmpa_tl \g__spath_closepath_tl
- \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl
- \spath_put:nnV {#1} {path} \l__spath_tmpa_tl
- \spath_if_in:nnT {#1} {reverse path}
- {
- \spath_get:nnN {#1} {final point} \l__spath_tmpb_tl
- \__spath_get:nnN {#1} {reverse path} \l__spath_tmpa_tl
- \tl_put_right:NV \l__spath_tmpa_tl \g__spath_closepath_tl
- \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl
- \spath_put:nnV {#1} {reverse path} \l__spath_tmpa_tl
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Iteration Functions}
-%
-% \begin{macro}{\spath_map_component:Nn}
-% This iterates through the components of a path, applying the inline function to each.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_map_component:Nn #1#2
-{
- \int_gincr:N \g__spath_map_int
- \cs_gset:cpn { __spath_map_ \int_use:N \g__spath_map_int :w } ##1 {#2}
- \tl_set:NV \l__spath_tmpa_tl #1
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_put_right:NV \l__spath_tmpa_tl \g__spath_moveto_tl
- \tl_set_eq:NN \l__spath_tmpb_tl \g__spath_moveto_tl
- \bool_until_do:nn {
- \tl_if_empty_p:N \l__spath_tmpa_tl
- }
- {
- \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl}
- \tl_if_eq:NNT \l__spath_tmpc_tl \g__spath_moveto_tl
- {
- \exp_args:NnV \use:c { __spath_map_ \int_use:N \g__spath_map_int :w } \l__spath_tmpb_tl
-\tl_clear:N \l__spath_tmpb_tl
- }
- \tl_if_single:NTF \l__spath_tmpc_tl
- {
- \tl_put_right:NV \l__spath_tmpb_tl \l__spath_tmpc_tl
- }
- {
- \tl_put_right:Nx \l__spath_tmpb_tl {{\l__spath_tmpc_tl}}
- }
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_map_segment_inline:Nn}
-% This iterates through the segments of the path, applying the inline function to each.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_map_segment_inline:Nn #1#2
-{
- \int_gincr:N \g__spath_map_int
- \cs_gset:cpn { __spath_map_ \int_use:N \g__spath_map_int :w } ##1 ##2 {#2}
- \spath_map_segment_function:Nc #1 { __spath_map_ \int_use:N \g__spath_map_int :w }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_map_segment_inline:nn}
-% This iterates through the segments of the path of the \Verb+spath+ object, applying the inline function to each.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_map_segment_inline:nn #1#2
-{
- \int_gincr:N \g__spath_map_int
- \cs_gset:cpn { __spath_map_ \int_use:N \g__spath_map_int :w } ##1 ##2 {#2}
- \spath_get:nnN {#1} {path} \l__spath_tmpd_tl
- \spath_map_segment_function:Nc \l__spath_tmpd_tl { __spath_map_ \int_use:N \g__spath_map_int :w }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\spath_map_segment_function:nN}
-% This iterates through the segments of the path of the \Verb+spath+ object, applying the specified function to each.
-% The specified function should take two \Verb+N+ type arguments.
-% The first is a token representing the type of path segment, the second is the path segment itself.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_map_segment_function:nN #1#2
-{
- \spath_get:nnN {#1} {path} \l__spath_tmpd_tl
- \spath_map_segment_function:NN \l__spath_tmpd_tl #2
-}
-% \end{macrocode}
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_map_segment_function:NN #1#2
-{
- \tl_set_eq:NN \l__spath_tmpa_tl #1
- \tl_clear:N \l__spath_tmpb_tl
- \dim_zero:N \l__spath_tmpa_dim
- \dim_zero:N \l__spath_tmpb_dim
-
- \bool_until_do:nn {
- \tl_if_empty_p:N \l__spath_tmpa_tl
- }
- {
- \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_case:NnF \l__spath_tmpc_tl
- {
- \g__spath_lineto_tl
- {
- \tl_set_eq:NN \l__spath_tmpb_tl \g__spath_moveto_tl
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- \tl_put_right:NV \l__spath_tmpb_tl \g__spath_lineto_tl
-
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- }
-
- \g__spath_curvetoa_tl
- {
- \tl_set_eq:NN \l__spath_tmpb_tl \g__spath_moveto_tl
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- \tl_put_right:NV \l__spath_tmpb_tl \g__spath_curvetoa_tl
-
- \prg_replicate:nn {2} {
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- \tl_put_right:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
- }
-
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- }
-
- \g__spath_closepath_tl
- {
- \tl_set_eq:NN \l__spath_tmpb_tl \g__spath_moveto_tl
- \tl_put_right:Nx \l__spath_tmpb_tl
- {
- {\dim_use:N \l__spath_tmpa_dim}
- {\dim_use:N \l__spath_tmpb_dim}
- }
- \tl_put_right:NV \l__spath_tmpb_tl \g__spath_lineto_tl
-
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- }
-
- }
- {
-
- \tl_set_eq:NN \l__spath_tmpb_tl \l__spath_tmpc_tl
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}}
- \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl}
- \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl}
-
- }
-
- #2 \l__spath_tmpc_tl \l__spath_tmpb_tl
- \tl_clear:N \l__spath_tmpb_tl
-
- }
-}
-\cs_generate_variant:Nn \spath_map_segment_function:NN {Nc}
-% \end{macrocode}
-% \end{macro}
-%
-% \subsection{Public Commands}
-%
-% The next functions are more ``public'' than the previous lot.
-% That said, they aren't intended for direct use in a normal document.
-%
-% Most are just wrappers around internal functions.
-%
-% \begin{macro}{\MakeSPath}
-% Constructs an \Verb+spath+ object out of the given name and path.
-% \begin{macrocode}
-\NewDocumentCommand \MakeSPath { m m }
-{
- \spath_clear_new:n {#1}
- \spath_put:nno {#1} {path} {#2}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\MakeSPathList}
-% This constructs a list of \Verb+spath+ objects from a single path by splitting it into components.
-% \begin{macrocode}
-\NewDocumentCommand \MakeSPathList { m m }
-{
- \tl_gclear_new:c {l__spath_list_#1}
- \int_zero:N \l__spath_tmpa_int
- \spath_map_component:Nn #2 {
- \spath_clear_new:n {#1 _ \int_use:N \l__spath_tmpa_int}
- \spath_put:nnn {#1 _ \int_use:N \l__spath_tmpa_int} {path} {##1}
- \tl_gput_right:cx {l__spath_list_#1} {{#1 _ \int_use:N \l__spath_tmpa_int}}
- \int_incr:N \l__spath_tmpa_int
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\CloneSPath}
-% \begin{macrocode}
-\NewDocumentCommand \CloneSPath { m m }
-{
- \spath_clone:nn {#1} {#2}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\SPathInfo}
-% \begin{macrocode}
-\NewDocumentCommand \SPathInfo { m m }
-{
- \spath_get:nn {#1} {#2}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\SPathPrepare}
-% \begin{macrocode}
-\NewDocumentCommand \SPathPrepare { m }
-{
- \spath_generate_all:n {#1}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\SPathListPrepare}
-% \begin{macrocode}
-\NewDocumentCommand \SPathListPrepare { m }
-{
- \tl_map_inline:cn {l__spath_list_#1}
- {
- \spath_generate_all:n {##1}
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\SPathInfoInto}
-% \begin{macrocode}
-\NewDocumentCommand \SPathInfoInto { m m m }
-{
- \tl_clear_new:N #3
- \spath_get:nnN {#1} {#2} #3
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\SPathShow}
-% \begin{macrocode}
-\NewDocumentCommand \SPathShow { m }
-{
- \spath_show:n {#1}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\SPathTranslate}
-% \begin{macrocode}
-\NewDocumentCommand \SPathTranslate { m m m }
-{
- \spath_translate:nnn {#1} {#2} {#3}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\SPathTranslateInto}
-% Clones the path before translating it.
-% \begin{macrocode}
-\NewDocumentCommand \SPathTranslateInto { m m m m }
-{
- \spath_clone:nn {#1} {#2}
- \spath_translate:nnn {#2} {#3} {#4}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\SPathScale}
-% \begin{macrocode}
-\NewDocumentCommand \SPathScale { m m m }
-{
- \spath_scale:nnn {#1} {#2} {#3}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\SPathScaleInto}
-% Clones the path first.
-% \begin{macrocode}
-\NewDocumentCommand \SPathScaleInto { m m m m }
-{
- \spath_clone:nn {#1} {#2}
- \spath_scale:nnn {#2} {#3} {#4}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\SPathWeld}
-% \begin{macrocode}
-\NewDocumentCommand \SPathWeld { m m }
-{
- \spath_weld:nn {#1} {#2}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\SPathWeldInto}
-% \begin{macrocode}
-\NewDocumentCommand \SPathWeldInto { m m m }
-{
- \spath_clone:nn {#1} {#2}
- \spath_weld:nn {#2} {#3}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% Interfaces via TikZ keys.
-% \begin{macrocode}
-\tikzset{
- save~spath/.code={
- \tikz@addmode{
- \spath_get_current_path:n {#1}
- }
- },
- restore~spath/.code={
- \spath_set_current_path:n {#1}
- }
-}
-% \end{macrocode}
-% \subsection{Miscellaneous Commands}
-%
-% \begin{macro}{\spath_split_curve:nnNN}
-% Splits a Bezier cubic into pieces.
-% \begin{macrocode}
-\cs_new_nopar:Npn \spath_split_curve:nnNN #1#2#3#4
-{
- \group_begin:
- \tl_gclear:N \l__spath_smuggle_tl
- \tl_set_eq:NN \l__spath_tmpa_tl \g__spath_moveto_tl
- \tl_put_right:Nx \l__spath_tmpa_tl {
- {\tl_item:nn {#2} {2}}
- {\tl_item:nn {#2} {3}}
- }
- \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curvetoa_tl
- \tl_put_right:Nx \l__spath_tmpa_tl
- {
- {\fp_to_dim:n
- {
- (1 - #1) * \tl_item:nn {#2} {2} + (#1) * \tl_item:nn {#2} {5}
- }}
- {\fp_to_dim:n
- {
- (1 - #1) * \tl_item:nn {#2} {3} + (#1) * \tl_item:nn {#2} {6}
- }}
- }
- \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curvetob_tl
- \tl_put_right:Nx \l__spath_tmpa_tl
- {
- {\fp_to_dim:n
- {
- (1 - #1)^2 * \tl_item:nn {#2} {2} + 2 * (1 - #1) * (#1) * \tl_item:nn {#2} {5} + (#1)^2 * \tl_item:nn {#2} {8}
- }}
- {\fp_to_dim:n
- {
- (1 - #1)^2 * \tl_item:nn {#2} {3} + 2 * (1 - #1) * (#1) * \tl_item:nn {#2} {6} + (#1)^2 * \tl_item:nn {#2} {9}
- }}
- }
- \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curveto_tl
- \tl_put_right:Nx \l__spath_tmpa_tl
- {
- {\fp_to_dim:n
- {
- (1 - #1)^3 * \tl_item:nn {#2} {2} + 3 * (1 - #1)^2 * (#1) * \tl_item:nn {#2} {5} + 3 * (1 - #1) * (#1)^2 * \tl_item:nn {#2} {8} + (#1)^3 * \tl_item:nn {#2} {11}
- }}
- {\fp_to_dim:n
- {
- (1 - #1)^3 * \tl_item:nn {#2} {3} + 3 * (1 - #1)^2 * (#1) * \tl_item:nn {#2} {6} + 3 * (1 - #1) * (#1)^2 * \tl_item:nn {#2} {9} + (#1)^3 * \tl_item:nn {#2} {12}
- }}
- }
- \tl_gset_eq:NN \l__spath_smuggle_tl \l__spath_tmpa_tl
- \group_end:
- \tl_set_eq:NN #3 \l__spath_smuggle_tl
- \group_begin:
- \tl_set_eq:NN \l__spath_tmpa_tl \g__spath_moveto_tl
- \tl_put_right:Nx \l__spath_tmpa_tl
- {
- {\fp_to_dim:n
- {
- (1 - #1)^3 * \tl_item:nn {#2} {2} + 3 * (1 - #1)^2 * (#1) * \tl_item:nn {#2} {5} + 3 * (1 - #1) * (#1)^2 * \tl_item:nn {#2} {8} + (#1)^3 * \tl_item:nn {#2} {11}
- }}
- {\fp_to_dim:n
- {
- (1 - #1)^3 * \tl_item:nn {#2} {3} + 3 * (1 - #1)^2 * (#1) * \tl_item:nn {#2} {6} + 3 * (1 - #1) * (#1)^2 * \tl_item:nn {#2} {9} + (#1)^3 * \tl_item:nn {#2} {12}
- }}
- }
- \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curvetoa_tl
- \tl_put_right:Nx \l__spath_tmpa_tl
- {
- {\fp_to_dim:n
- {
- (1 - #1)^2 * \tl_item:nn {#2} {5} + 2 * (1 - #1) * (#1) * \tl_item:nn {#2} {8} + (#1)^2 * \tl_item:nn {#2} {11}
- }}
- {\fp_to_dim:n
- {
- (1 - #1)^2 * \tl_item:nn {#2} {6} + 2 * (1 - #1) * (#1) * \tl_item:nn {#2} {9} + (#1)^2 * \tl_item:nn {#2} {12}
- }}
- }
- \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curvetob_tl
- \tl_put_right:Nx \l__spath_tmpa_tl
- {
- {\fp_to_dim:n
- {
- (1 - #1) * \tl_item:nn {#2} {8} + (#1) * \tl_item:nn {#2} {11}
- }}
- {\fp_to_dim:n
- {
- (1 - #1) * \tl_item:nn {#2} {9} + (#1) * \tl_item:nn {#2} {12}
- }}
- }
- \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curveto_tl
- \tl_put_right:Nx \l__spath_tmpa_tl {
- {\tl_item:nn {#2} {11}}
- {\tl_item:nn {#2} {12}}
- }
- \tl_gset_eq:NN \l__spath_smuggle_tl \l__spath_tmpa_tl
- \group_end:
- \tl_set_eq:NN #4 \l__spath_smuggle_tl
-}
-
-\cs_generate_variant:Nn \spath_split_curve:nnNN {nVNN, VVNN}
-% \end{macrocode}
-% \end{macro}
-% \iffalse
-%</spath3>
-% \fi
-%
-% \iffalse
-%<*calligraphy>
-% \fi
-%
-% \section{The Calligraphy Package}
-%
-% \subsection{Initialisation}
-% \begin{macrocode}
-\RequirePackage{spath3}
-\ExplSyntaxOn
-
-\tl_new:N \l__cal_tmpa_tl
-\tl_new:N \l__cal_tmpb_tl
-\int_new:N \l__cal_tmpa_int
-\int_new:N \l__cal_tmpb_int
-\int_new:N \l__cal_path_component_int
-\int_new:N \l__cal_label_int
-\dim_new:N \l__cal_tmpa_dim
-\dim_new:N \l__cal_tmpb_dim
-\dim_new:N \l__cal_tmpc_dim
-\dim_new:N \l__cal_tmpd_dim
-\dim_new:N \l__cal_tmpe_dim
-\dim_new:N \l__cal_tmpf_dim
-\dim_new:N \l__cal_tmpg_dim
-\dim_new:N \l__cal_tmph_dim
-\bool_new:N \l__cal_annotate_bool
-\bool_new:N \l__cal_taper_start_bool
-\bool_new:N \l__cal_taper_end_bool
-\bool_new:N \l__cal_taperable_bool
-\dim_new:N \l__cal_taper_width_dim
-\dim_new:N \l__cal_line_width_dim
-
-\bool_set_true:N \l__cal_taper_start_bool
-\bool_set_true:N \l__cal_taper_end_bool
-
-\cs_generate_variant:Nn \tl_put_right:Nn {Nv}
-% \end{macrocode}
-%
-% \subsection{TikZ Keys}
-%
-% The public interface to this package is through TikZ keys and styles.
-% \begin{macrocode}
-\tikzset{
- define~pen/.code={
- \tikzset{pen~name=#1}
- \pgf@relevantforpicturesizefalse
- \tikz@addmode{
- \pgfsyssoftpath@getcurrentpath\l__cal_tmpa_tl
- \MakeSPathList{calligraphy pen \pgfkeysvalueof{/tikz/pen~name}}{\l__cal_tmpa_tl}
- \SPathListPrepare{calligraphy pen \pgfkeysvalueof{/tikz/pen~name}}
- \pgfusepath{discard}%
- }
- },
- define~pen/.default={default},
- use~pen/.code={
- \tikzset{pen~name=#1}
- \int_gzero:N \l__cal_path_component_int
- \cs_set_eq:NN \pgfpathmoveto \cal_moveto:n
- \tikz@addmode{
- \pgfsyssoftpath@getcurrentpath\l__cal_tmpa_tl
- \MakeSPathList{calligraphy path}{\l__cal_tmpa_tl}
- \SPathListPrepare{calligraphy path}
- \CalligraphyPathCreate{calligraphy path}{\pgfkeysvalueof{/tikz/pen~name}}
- }
- },
- use~pen/.default={default},
- pen~name/.initial={default},
- copperplate/.style={pen~name=copperplate},
- pen~colour/.initial={black},
- weight/.is~choice,
- weight/heavy/.style={
- line~width=\pgfkeysvalueof{/tikz/heavy~line~width},
- taper~width=\pgfkeysvalueof{/tikz/light~line~width},
- },
- weight/light/.style={
- line~width=\pgfkeysvalueof{/tikz/light~line~width},
- taper~width=0pt,
- },
- heavy/.style={
- weight=heavy
- },
- light/.style={
- weight=light
- },
- heavy~line~width/.initial=2pt,
- light~line~width/.initial=1pt,
- taper/.is~choice,
- taper/.default=both,
- taper/none/.style={
- taper~start=false,
- taper~end=false,
- },
- taper/both/.style={
- taper~start=true,
- taper~end=true,
- },
- taper/start/.style={
- taper~start=true,
- taper~end=false,
- },
- taper/end/.style={
- taper~start=false,
- taper~end=true,
- },
- taper~start/.code={
- \tl_if_eq:nnTF {#1} {true}
- {
- \bool_set_true:N \l__cal_taper_start_bool
- }
- {
- \bool_set_false:N \l__cal_taper_start_bool
- }
- },
- taper~start/.default={true},
- taper~end/.code={
- \tl_if_eq:nnTF {#1} {true}
- {
- \bool_set_true:N \l__cal_taper_end_bool
- }
- {
- \bool_set_false:N \l__cal_taper_end_bool
- }
- },
- taper~end/.default={true},
- taper~width/.code={\dim_set:Nn \l__cal_taper_width_dim {#1}},
- nib~style/.code~2~args={
- \tl_clear_new:c {l__cal_nib_style_#1}
- \tl_set:cn {l__cal_nib_style_#1} {#2}
- },
- stroke~style/.code~2~args={
- \tl_clear_new:c {l__cal_stroke_style_#1}
- \tl_set:cn {l__cal_stroke_style_#1} {#2}
- },
- this~stroke~style/.code={
- \tl_clear_new:c {l__cal_stroke_inline_style_ \int_use:N \l__cal_path_component_int}
- \tl_set:cn {l__cal_stroke_inline_style_ \int_use:N \l__cal_path_component_int} {#1}
- },
- annotate/.style={
- annotate~if,
- annotate~reset,
- annotation~style/.update~value={#1},
- },
- annotate~if/.default={true},
- annotate~if/.code={
- \tl_if_eq:nnTF {#1} {true}
- {
- \bool_set_true:N \l__cal_annotate_bool
- }
- {
- \bool_set_false:N \l__cal_annotate_bool
- }
- },
- annotate~reset/.code={
- \int_gzero:N \l__cal_label_int
- },
- annotation~style/.initial={draw,->},
- annotation~shift/.initial={(0,1ex)},
- every~annotation~node/.initial={anchor=south~west},
- annotation~node~style/.code~2~args={
- \tl_set:cn {l__cal_annotation_style_ #1 _tl}{#2}
- },
- tl~use:N/.code={
- \exp_args:NV \pgfkeysalso #1
- },
- tl~use:c/.code={
- \tl_if_exist:cT {#1}
- {
- \exp_args:Nv \pgfkeysalso {#1}
- }
- },
- /handlers/.update~style/.code={
- \tl_if_eq:nnF {#1} {\pgfkeysnovalue}
- {
- \pgfkeys{\pgfkeyscurrentpath/.code=\pgfkeysalso{#1}}
- }
- },
- /handlers/.update~value/.code={
- \tl_if_eq:nnF {#1} {\pgfkeysnovalue}
- {
- \pgfkeyssetvalue{\pgfkeyscurrentpath}{#1}
- }
- }
-}
-% \end{macrocode}
-%
-% Some wrappers around the TikZ keys.
-% \begin{macrocode}
-\NewDocumentCommand \pen { O{} }
-{
- \path[define~ pen,every~ calligraphy~ pen/.try,#1]
-}
-
-\NewDocumentCommand \definepen { O{} }
-{
- \tikz \path[define~ pen,every~ calligraphy~ pen/.try,#1]
-}
-
-\NewDocumentCommand \calligraphy { O{} }
-{
- \path[use~ pen,every~ calligraphy/.try,#1]
-}
-% \end{macrocode}
-%
-% \subsection{The Path Creation}
-%
-% \begin{macro}{\CalligraphyPathCreate}
-% This is the main command for creating the calligraphic paths.
-% \begin{macrocode}
-\NewDocumentCommand \CalligraphyPathCreate { m m }
-{
- \int_zero:N \l__cal_tmpa_int
- \tl_map_inline:cn {l__spath_list_#1}
- {
- \int_incr:N \l__cal_tmpa_int
- \int_zero:N \l__cal_tmpb_int
- \tl_map_inline:cn {l__spath_list_calligraphy pen #2}
- {
- \int_incr:N \l__cal_tmpb_int
- \group_begin:
- \pgfsys@beginscope
-
- \cal_apply_style:c {l__cal_stroke_style_ \int_use:N \l__cal_tmpa_int}
- \cal_apply_style:c {l__cal_stroke_inline_style_ \int_use:N \l__cal_tmpa_int}
- \cal_apply_style:c {l__cal_nib_style_ \int_use:N \l__cal_tmpb_int}
-
- \spath_clone:nn {##1} {calligraphy temp path}
-
- \__spath_get:nnN {####1} {initial point} \l__cal_tmpa_tl
- \spath_translate:nV {calligraphy temp path} \l__cal_tmpa_tl
-
- \__spath_get:nnN {####1} {length} \l__cal_tmpa_tl
-
- \int_compare:nTF {\l__cal_tmpa_tl = 1}
- {
- \cal_at_least_three:n {calligraphy temp path}
-
- \spath_protocol_path:n {calligraphy temp path}
-
- \__spath_get:nnN {calligraphy temp path} {path} \l__cal_tmpa_tl
-
- \tikz@options
- \dim_set:Nn \l__cal_line_width_dim {\pgflinewidth}
- \cal_maybe_taper:N \l__cal_tmpa_tl
- }
- {
-
- \spath_weld:nn {calligraphy temp path} {####1}
- \spath_reverse:n {##1}
- \spath_reverse:n {####1}
- \spath_weld:nn {calligraphy temp path} {##1}
- \spath_weld:nn {calligraphy temp path} {####1}
- \spath_reverse:n {##1}
- \spath_reverse:n {####1}
-
- \tl_clear:N \l__cal_tmpa_tl
- \tl_set:Nn \l__cal_tmpa_tl {fill=\pgfkeysvalueof{/tikz/pen~colour},draw=none}
- \tl_if_exist:cT {l__cal_stroke_style_ \int_use:N \l__cal_tmpa_int}
- {
- \tl_put_right:Nv \l__cal_tmpa_tl {l__cal_stroke_style_ \int_use:N \l__cal_tmpa_int}
- }
- \tl_if_exist:cT {l__cal_stroke_inline_style_ \int_use:N \l__cal_tmpa_int}
- {
- \tl_put_right:Nn \l__cal_tmpa_tl {,}
- \tl_put_right:Nv \l__cal_tmpa_tl {l__cal_stroke_inline_style_ \int_use:N \l__cal_tmpa_int}
- }
- \tl_if_exist:cT {l__cal_nib_style_ \int_use:N \l__cal_tmpb_int}
- {
- \tl_put_right:Nn \l__cal_tmpa_tl {,}
- \tl_put_right:Nv \l__cal_tmpa_tl {l__cal_nib_style_ \int_use:N \l__cal_tmpb_int}
- }
- \spath_tikz_path:Vn \l__cal_tmpa_tl {calligraphy temp path}
-
- }
- \pgfsys@endscope
- \group_end:
- }
- \bool_if:NT \l__cal_annotate_bool
- {
- \spath_clone:nn {##1} {calligraphy temp path}
- \tl_set_eq:Nc \l_tmpa_tl {l__spath_list_calligraphy pen #2}
- \tl_reverse:N \l_tmpa_tl
- \tl_set:Nx \l_tmpa_tl {\tl_head:N \l_tmpa_tl}
- \spath_generate_finalpoint:V \l_tmpa_tl
- \spath_get:VnN \l_tmpa_tl {final point} \l_tmpa_tl
- \spath_translate:nV {calligraphy temp path} \l_tmpa_tl
- \tikz@scan@one@point\pgfutil@firstofone\pgfkeysvalueof{/tikz/annotation~shift}
- \spath_translate:nnn {calligraphy temp path} {\pgf@x} {\pgf@y}
-
- \pgfkeysgetvalue{/tikz/annotation~style}{\l_tmpa_tl}
- \spath_tikz_path:Vn \l_tmpa_tl {calligraphy temp path}
- \spath_get:nnN {calligraphy temp path} {final point} \l_tmpa_tl
- \exp_last_unbraced:NV \pgfqpoint \l_tmpa_tl
- \begin{scope}[reset~ cm]
- \node[every~annotation~node/.try,tl~use:c = {l__cal_annotation_style_ \int_use:N \l__cal_tmpa_int _tl}] at (\pgf@x,\pgf@y) {\int_use:N \l__cal_tmpa_int};
- \end{scope}
- }
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\cal_moveto:n}
-% When creating the path, we need to keep track of the number of components so that we can apply styles accordingly.
-% \begin{macrocode}
-\cs_new_eq:NN \cal_orig_moveto:n \pgfpathmoveto
-\cs_new_nopar:Npn \cal_moveto:n #1
-{
- \int_gincr:N \l__cal_path_component_int
- \cal_orig_moveto:n {#1}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\cal_apply_style:N}
-% Interface for applying \Verb+\tikzset+ to a token list.
-% \begin{macrocode}
-\cs_new_nopar:Npn \cal_apply_style:N #1
-{
- \tl_if_exist:NT #1 {
- \exp_args:NV \tikzset #1
- }
-}
-\cs_generate_variant:Nn \cal_apply_style:N {c}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\cal_at_least_three:n}
-% A tapered path has to have at least three components.
-% This figures out if it is necessary and sets up the splitting.
-% \begin{macrocode}
-\cs_new_nopar:Npn \cal_at_least_three:n #1
-{
- \spath_get:nnN {#1} {real length} \l__cal_tmpa_tl
- \tl_clear:N \l__cal_tmpb_tl
- \int_compare:nTF {\l__cal_tmpa_tl = 1}
- {
- \spath_get:nnN {#1} {path} \l__cal_tmpa_tl
- \spath_map_segment_inline:Nn \l__cal_tmpa_tl
- {
- \tl_case:NnF ##1 {
- \g__spath_lineto_tl {
- \cal_split_line_in_three:NN \l__cal_tmpb_tl ##2
- }
- \g__spath_curvetoa_tl {
- \cal_split_curve_in_three:NN \l__cal_tmpb_tl ##2
- }
- }
- {
- \tl_put_right:NV \l__cal_tmpb_tl ##2
- }
- }
- \spath_put:nnV {#1} {path} \l__cal_tmpb_tl
- }
- {
- \int_compare:nT {\l__cal_tmpa_tl = 2}
- {
- \spath_get:nnN {#1} {path} \l__cal_tmpa_tl
- \spath_map_segment_inline:Nn \l__cal_tmpa_tl
- {
- \tl_case:NnF ##1 {
- \g__spath_lineto_tl {
- \cal_split_line_in_two:NN \l__cal_tmpb_tl ##2
- }
- \g__spath_curvetoa_tl {
- \cal_split_curve_in_two:NN \l__cal_tmpb_tl ##2
- }
- }
- {
- \tl_put_right:NV \l__cal_tmpb_tl ##2
- }
- }
- \spath_put:nnV {#1} {path} \l__cal_tmpb_tl
- }
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\cal_split_line_in_two:NN}
-% Splits a line in two, adding the splits to the first token list.
-% \begin{macrocode}
-\cs_new_nopar:Npn \cal_split_line_in_two:NN #1#2
-{
- \tl_set_eq:NN \l__cal_tmpc_tl #2
-
- \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl}
-
- \dim_set:Nn \l__cal_tmpa_dim {\tl_head:N \l__cal_tmpc_tl}
- \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl}
-
- \dim_set:Nn \l__cal_tmpb_dim {\tl_head:N \l__cal_tmpc_tl}
- \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl}
-
- \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl}
-
- \dim_set:Nn \l__cal_tmpc_dim {\tl_head:N \l__cal_tmpc_tl}
- \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl}
- \dim_set:Nn \l__cal_tmpd_dim {\tl_head:N \l__cal_tmpc_tl}
- \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl}
-
- \tl_put_right:NV #1 \g__spath_lineto_tl
-
- \tl_put_right:Nx #1 {
- {\dim_eval:n {(\l__cal_tmpa_dim + \l__cal_tmpc_dim)/2}}
- {\dim_eval:n {(\l__cal_tmpb_dim + \l__cal_tmpd_dim)/2}}
- }
-
- \tl_put_right:NV #1 \g__spath_lineto_tl
- \tl_put_right:Nx #1 {
- {\dim_use:N \l__cal_tmpc_dim}
- {\dim_use:N \l__cal_tmpd_dim}
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\cal_split_line_in_three:NN}
-% Splits a line in three, adding the splits to the first token list.
-% \begin{macrocode}
-\cs_new_nopar:Npn \cal_split_line_in_three:NN #1#2
-{
- \tl_set_eq:NN \l__cal_tmpc_tl #2
-
- \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl}
-
- \dim_set:Nn \l__cal_tmpa_dim {\tl_head:N \l__cal_tmpc_tl}
- \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl}
-
- \dim_set:Nn \l__cal_tmpb_dim {\tl_head:N \l__cal_tmpc_tl}
- \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl}
-
- \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl}
-
- \dim_set:Nn \l__cal_tmpc_dim {\tl_head:N \l__cal_tmpc_tl}
- \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl}
- \dim_set:Nn \l__cal_tmpd_dim {\tl_head:N \l__cal_tmpc_tl}
- \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl}
-
- \tl_put_right:NV #1 \g__spath_lineto_tl
-
- \tl_put_right:Nx #1 {
- {\dim_eval:n {(2\l__cal_tmpa_dim + \l__cal_tmpc_dim)/3}}
- {\dim_eval:n {(2\l__cal_tmpb_dim + \l__cal_tmpd_dim)/3}}
- }
-
- \tl_put_right:NV #1 \g__spath_lineto_tl
-
- \tl_put_right:Nx #1 {
- {\dim_eval:n {(\l__cal_tmpa_dim + 2\l__cal_tmpc_dim)/3}}
- {\dim_eval:n {(\l__cal_tmpb_dim + 2\l__cal_tmpd_dim)/3}}
- }
-
- \tl_put_right:NV #1 \g__spath_lineto_tl
- \tl_put_right:Nx #1 {
- {\dim_use:N \l__cal_tmpc_dim}
- {\dim_use:N \l__cal_tmpd_dim}
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\cal_split_curve_in_two:NN}
-% Splits a curve in two, adding the splits to the first token list.
-% \begin{macrocode}
-\cs_new_nopar:Npn \cal_split_curve_in_two:NN #1#2
-{
- \spath_split_curve:nVNN {.5} #2 \l_tmpa_tl \l_tmpb_tl
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl}
- \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl}
- \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl}
- \tl_put_right:NV #1 \l_tmpa_tl
- \tl_put_right:NV #1 \l_tmpb_tl
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\cal_split_curve_in_three:NN}
-% Splits a curve in three, adding the splits to the first token list.
-% \begin{macrocode}
-\cs_new_nopar:Npn \cal_split_curve_in_three:NN #1#2
-{
- \spath_split_curve:nVNN {1/3} #2 \l_tmpa_tl \l_tmpb_tl
-
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_put_right:NV #1 \l_tmpa_tl
-
- \spath_split_curve:nVNN {.5} \l_tmpb_tl \l_tmpa_tl \l_tmpb_tl
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl}
- \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl}
- \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl}
- \tl_put_right:NV #1 \l_tmpa_tl
- \tl_put_right:NV #1 \l_tmpb_tl
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\cal_maybe_taper:N}
-% Possibly tapers the path, depending on the booleans.
-% \begin{macrocode}
-\cs_new_nopar:Npn \cal_maybe_taper:N #1
-{
- \tl_set_eq:NN \l__cal_tmpa_tl #1
-
- \bool_if:NT \l__cal_taper_start_bool
- {
-
- \dim_set:Nn \l__cal_tmpa_dim {\tl_item:Nn \l__cal_tmpa_tl {2}}
- \dim_set:Nn \l__cal_tmpb_dim {\tl_item:Nn \l__cal_tmpa_tl {3}}
- \tl_set:Nx \l__cal_tmpb_tl {\tl_item:Nn \l__cal_tmpa_tl {4}}
-
- \tl_case:NnF \l__cal_tmpb_tl
- {
- \g__spath_lineto_tl
- {
-
- \bool_set_true:N \l__cal_taperable_bool
- \dim_set:Nn \l__cal_tmpg_dim {\tl_item:Nn \l__cal_tmpa_tl {5}}
- \dim_set:Nn \l__cal_tmph_dim {\tl_item:Nn \l__cal_tmpa_tl {6}}
- \dim_set:Nn \l__cal_tmpc_dim {(2\l__cal_tmpa_dim + \l__cal_tmpg_dim)/3}
- \dim_set:Nn \l__cal_tmpd_dim {(2\l__cal_tmpb_dim + \l__cal_tmph_dim)/3}
- \dim_set:Nn \l__cal_tmpe_dim {(\l__cal_tmpa_dim + 2\l__cal_tmpg_dim)/3}
- \dim_set:Nn \l__cal_tmpf_dim {(\l__cal_tmpb_dim + 2\l__cal_tmph_dim)/3}
- \prg_replicate:nn {4}
- {
- \tl_set:Nx \l__cal_tmpa_tl {\tl_tail:N \l__cal_tmpa_tl}
- }
- \tl_put_left:NV \l__cal_tmpa_tl \g__spath_moveto_tl
- }
- \g__spath_curvetoa_tl
- {
- \bool_set_true:N \l__cal_taperable_bool
- \dim_set:Nn \l__cal_tmpc_dim {\tl_item:Nn \l__cal_tmpa_tl {5}}
- \dim_set:Nn \l__cal_tmpd_dim {\tl_item:Nn \l__cal_tmpa_tl {6}}
- \dim_set:Nn \l__cal_tmpe_dim {\tl_item:Nn \l__cal_tmpa_tl {8}}
- \dim_set:Nn \l__cal_tmpf_dim {\tl_item:Nn \l__cal_tmpa_tl {9}}
- \dim_set:Nn \l__cal_tmpg_dim {\tl_item:Nn \l__cal_tmpa_tl {11}}
- \dim_set:Nn \l__cal_tmph_dim {\tl_item:Nn \l__cal_tmpa_tl {12}}
- \prg_replicate:nn {10}
- {
- \tl_set:Nx \l__cal_tmpa_tl {\tl_tail:N \l__cal_tmpa_tl}
- }
- \tl_put_left:NV \l__cal_tmpa_tl \g__spath_moveto_tl
- }
- }
- {
- \bool_set_false:N \l__cal_taperable_bool
- }
-
- \bool_if:NT \l__cal_taperable_bool
- {
- \__cal_taper_aux:
- }
-
- }
-
- \bool_if:NT \l__cal_taper_end_bool
- {
-
- \dim_set:Nn \l__cal_tmpa_dim {\tl_item:Nn \l__cal_tmpa_tl {-2}}
- \dim_set:Nn \l__cal_tmpb_dim {\tl_item:Nn \l__cal_tmpa_tl {-1}}
- \tl_set:Nx \l__cal_tmpb_tl {\tl_item:Nn \l__cal_tmpa_tl {-3}}
-
- \tl_case:NnF \l__cal_tmpb_tl
- {
- \g__spath_lineto_tl
- {
-
- \bool_set_true:N \l__cal_taperable_bool
- \dim_set:Nn \l__cal_tmpg_dim {\tl_item:Nn \l__cal_tmpa_tl {-5}}
- \dim_set:Nn \l__cal_tmph_dim {\tl_item:Nn \l__cal_tmpa_tl {-4}}
- \dim_set:Nn \l__cal_tmpc_dim {(2\l__cal_tmpa_dim + \l__cal_tmpg_dim)/3}
- \dim_set:Nn \l__cal_tmpd_dim {(2\l__cal_tmpb_dim + \l__cal_tmph_dim)/3}
- \dim_set:Nn \l__cal_tmpe_dim {(\l__cal_tmpa_dim + 2\l__cal_tmpg_dim)/3}
- \dim_set:Nn \l__cal_tmpf_dim {(\l__cal_tmpb_dim + 2\l__cal_tmph_dim)/3}
- \tl_reverse:N \l__cal_tmpa_tl
- \prg_replicate:nn {3}
- {
- \tl_set:Nx \l__cal_tmpa_tl {\tl_tail:N \l__cal_tmpa_tl}
- }
- \tl_reverse:N \l__cal_tmpa_tl
- }
- \g__spath_curveto_tl
- {
- \bool_set_true:N \l__cal_taperable_bool
- \dim_set:Nn \l__cal_tmpc_dim {\tl_item:Nn \l__cal_tmpa_tl {-5}}
- \dim_set:Nn \l__cal_tmpd_dim {\tl_item:Nn \l__cal_tmpa_tl {-4}}
- \dim_set:Nn \l__cal_tmpe_dim {\tl_item:Nn \l__cal_tmpa_tl {-8}}
- \dim_set:Nn \l__cal_tmpf_dim {\tl_item:Nn \l__cal_tmpa_tl {-7}}
- \dim_set:Nn \l__cal_tmpg_dim {\tl_item:Nn \l__cal_tmpa_tl {-11}}
- \dim_set:Nn \l__cal_tmph_dim {\tl_item:Nn \l__cal_tmpa_tl {-10}}
- \tl_reverse:N \l__cal_tmpa_tl
- \prg_replicate:nn {9}
- {
- \tl_set:Nx \l__cal_tmpa_tl {\tl_tail:N \l__cal_tmpa_tl}
- }
- \tl_reverse:N \l__cal_tmpa_tl
- }
- }
- {
- \bool_set_false:N \l__cal_taperable_bool
- }
-
- \bool_if:NT \l__cal_taperable_bool
- {
- \__cal_taper_aux:
- }
-
- }
-
- \pgfsyssoftpath@setcurrentpath\l__cal_tmpa_tl
- \pgfsetstrokecolor{\pgfkeysvalueof{/tikz/pen~colour}}
- \pgfusepath{stroke}
-
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\__cal_taper_aux:}
-% Auxiliary macro to avoid unnecessary code duplication.
-% \begin{macrocode}
-\cs_new_nopar:Npn \__cal_taper_aux:
-{
- \tl_clear:N \l__cal_tmpb_tl
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_moveto_tl
-
- \fp_set:Nn \l__cal_tmpa_fp
- {
- \l__cal_tmpd_dim - \l__cal_tmpb_dim
- }
- \fp_set:Nn \l__cal_tmpb_fp
- {
- \l__cal_tmpa_dim - \l__cal_tmpc_dim
- }
- \fp_set:Nn \l__cal_tmpe_fp
- {
- (\l__cal_tmpa_fp^2 + \l__cal_tmpb_fp^2)^.5
- }
-
- \fp_set:Nn \l__cal_tmpa_fp {.5*\l__cal_taper_width_dim * \l__cal_tmpa_fp / \l__cal_tmpe_fp}
- \fp_set:Nn \l__cal_tmpb_fp {.5*\l__cal_taper_width_dim * \l__cal_tmpb_fp / \l__cal_tmpe_fp}
-
- \fp_set:Nn \l__cal_tmpc_fp
- {
- \l__cal_tmph_dim - \l__cal_tmpf_dim
- }
- \fp_set:Nn \l__cal_tmpd_fp
- {
- \l__cal_tmpe_dim - \l__cal_tmpg_dim
- }
- \fp_set:Nn \l__cal_tmpe_fp
- {
- (\l__cal_tmpc_fp^2 + \l__cal_tmpd_fp^2)^.5
- }
-
- \fp_set:Nn \l__cal_tmpc_fp {.5*\l__cal_line_width_dim * \l__cal_tmpc_fp / \l__cal_tmpe_fp}
- \fp_set:Nn \l__cal_tmpd_fp {.5*\l__cal_line_width_dim * \l__cal_tmpd_fp / \l__cal_tmpe_fp}
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpa_dim}}
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpb_dim}}
- }
-
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetoa_tl
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpc_dim}}
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpd_dim}}
- }
-
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetob_tl
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpc_fp + \l__cal_tmpe_dim}}
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpd_fp + \l__cal_tmpf_dim}}
- }
-
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curveto_tl
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpc_fp + \l__cal_tmpg_dim}}
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpd_fp + \l__cal_tmph_dim}}
- }
-
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetoa_tl
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpc_fp + \l__cal_tmpg_dim - \fp_to_dim:n{ 1.32 * \l__cal_tmpd_fp}}}
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpd_fp + \l__cal_tmph_dim + \fp_to_dim:n {1.32* \l__cal_tmpc_fp}}}
- }
-
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetob_tl
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpc_fp + \l__cal_tmpg_dim - \fp_to_dim:n {1.32 * \l__cal_tmpd_fp}}}
- {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpd_fp + \l__cal_tmph_dim + \fp_to_dim:n {1.32 * \l__cal_tmpc_fp}}}
- }
-
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curveto_tl
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpc_fp + \l__cal_tmpg_dim}}
- {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpd_fp + \l__cal_tmph_dim}}
- }
-
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetoa_tl
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpc_fp + \l__cal_tmpe_dim}}
- {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpd_fp + \l__cal_tmpf_dim}}
- }
-
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetob_tl
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpc_dim}}
- {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpd_dim}}
- }
-
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curveto_tl
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpa_dim}}
- {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpb_dim}}
- }
-
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetoa_tl
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpa_dim + \fp_to_dim:n{ 1.32 * \l__cal_tmpb_fp}}}
- {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpb_dim - \fp_to_dim:n {1.32* \l__cal_tmpa_fp}}}
- }
-
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetob_tl
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpa_dim + \fp_to_dim:n {1.32 * \l__cal_tmpb_fp}}}
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpb_dim - \fp_to_dim:n {1.32 * \l__cal_tmpa_fp}}}
- }
-
- \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curveto_tl
-
- \tl_put_right:Nx \l__cal_tmpb_tl
- {
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpa_dim}}
- {\dim_eval:n { \fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpb_dim}}
- }
-
- \pgfsyssoftpath@setcurrentpath\l__cal_tmpb_tl
- \pgfsetfillcolor{\pgfkeysvalueof{/tikz/pen~colour}}
- \pgfusepath{fill}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% Defines a copperplate pen.
-% \begin{macrocode}
-\tl_set:Nn \l__cal_tmpa_tl {\pgfsyssoftpath@movetotoken{0pt}{0pt}}
-\MakeSPathList{calligraphy pen copperplate}{\l__cal_tmpa_tl}
-\SPathListPrepare{calligraphy pen copperplate}
-% \end{macrocode}
-%
-% \begin{macrocode}
-\ExplSyntaxOff
-% \end{macrocode}
-%
-% \subsection{Decorations}
-%
-% If a decoration library is loaded we define some decorations that use the calligraphy library, specifically the copperplate pen with its tapering.
-%
-% First, a brace decoration.
-% \begin{macrocode}
-\expandafter\ifx\csname pgfdeclaredecoration\endcsname\relax
-\else
-\pgfdeclaredecoration{calligraphic brace}{brace}
-{
- \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final]
- {
- \pgfsyssoftpath@setcurrentpath{\pgfutil@empty}
- \pgfpathmoveto{\pgfpointorigin}
- \pgfpathcurveto
- {\pgfqpoint{.15\pgfdecorationsegmentamplitude}{.3\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
- {
- \pgftransformxshift{+\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance}
- \pgfpathlineto{\pgfqpoint{-\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
- \pgfpathcurveto
- {\pgfqpoint{-.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{-.15\pgfdecorationsegmentamplitude}{.7\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{0\pgfdecorationsegmentamplitude}{1\pgfdecorationsegmentamplitude}}
- \pgfpathmoveto{\pgfqpoint{0\pgfdecorationsegmentamplitude}{1\pgfdecorationsegmentamplitude}}
- \pgfpathcurveto
- {\pgfqpoint{.15\pgfdecorationsegmentamplitude}{.7\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
- }
- {
- \pgftransformxshift{+\pgfdecoratedremainingdistance}
- \pgfpathlineto{\pgfqpoint{-\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
- \pgfpathcurveto
- {\pgfqpoint{-.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{-.15\pgfdecorationsegmentamplitude}{.3\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{0pt}{0pt}}
- }
- \tikzset{
- taper width=.5\pgflinewidth,
- taper
- }%
- \pgfsyssoftpath@getcurrentpath\cal@tmp@path
- \MakeSPathList{calligraphy path}{\cal@tmp@path}%
- \SPathListPrepare{calligraphy path}%
- \CalligraphyPathCreate{calligraphy path}{copperplate}%
- }
- \state{final}{}
-}
-% \end{macrocode}
-%
-% The second is a straightened parenthesis (so that when very large it doesn't bow out too far).
-% \begin{macrocode}
-\pgfdeclaredecoration{calligraphic straight parenthesis}{brace}
-{
- \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final]
- {
- \pgfsyssoftpath@setcurrentpath{\pgfutil@empty}
- \pgfpathmoveto{\pgfpointorigin}
- \pgfpathcurveto
- {\pgfqpoint{.76604\pgfdecorationsegmentamplitude}{.64279\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{2.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{3.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}}
- {
- \pgftransformxshift{+\pgfdecoratedremainingdistance}
- \pgfpathlineto{\pgfqpoint{-3.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}}
- \pgfpathcurveto
- {\pgfqpoint{-2.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{-.76604\pgfdecorationsegmentamplitude}{.64279\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{0pt}{0pt}}
- }
- \tikzset{
- taper width=.5\pgflinewidth,
- taper
- }%
- \pgfsyssoftpath@getcurrentpath\cal@tmp@path
- \MakeSPathList{calligraphy path}{\cal@tmp@path}%
- \SPathListPrepare{calligraphy path}%
- \CalligraphyPathCreate{calligraphy path}{copperplate}%
- }
- \state{final}{}%
-}
-% \end{macrocode}
-%
-% The third is a curved parenthesis.
-% \begin{macrocode}
-\pgfdeclaredecoration{calligraphic curved parenthesis}{brace}
-{
- \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final]
- {
- \pgfsyssoftpath@setcurrentpath{\pgfutil@empty}
- \pgfpathmoveto{\pgfpointorigin}
- \pgf@xa=\pgfdecoratedremainingdistance\relax
- \advance\pgf@xa by -1.5890\pgfdecorationsegmentamplitude\relax
- \edef\cgrphy@xa{\the\pgf@xa}
- \pgfpathcurveto
- {\pgfqpoint{1.5890\pgfdecorationsegmentamplitude}{1.3333\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{\cgrphy@xa}{1.3333\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{\pgfdecoratedremainingdistance}{0pt}}
- \tikzset{
- taper width=.5\pgflinewidth,
- taper
- }%
- \pgfsyssoftpath@getcurrentpath\cal@tmp@path
- \MakeSPathList{calligraphy path}{\cal@tmp@path}%
- \SPathListPrepare{calligraphy path}%
- \CalligraphyPathCreate{calligraphy path}{copperplate}%
- }
- \state{final}{}%
-}
-% \end{macrocode}
-% End the conditional for if pgfdecoration module is loaded
-% \begin{macrocode}
-\fi
-% \end{macrocode}
-% \iffalse
-%</calligraphy>
-% \fi
-%
-%
-% \iffalse
-%<*knots>
-% \fi
-%%
-% \section{Drawing Knots}
-%
-%
-% \subsection{Initialisation}
-%
-% We load the \Verb+spath3+ library and the \Verb+intersections+ TikZ library.
-% Then we get going.
-% \begin{macrocode}
-\RequirePackage{spath3}
-\usetikzlibrary{intersections}
-
-\ExplSyntaxOn
-
-\tl_new:N \l__knot_tmpa_tl
-\tl_new:N \l__knot_tmpb_tl
-\tl_new:N \l__knot_tmpc_tl
-\tl_new:N \l__knot_tmpd_tl
-\tl_new:N \l__knot_tmpe_tl
-\tl_new:N \l__knot_tmpf_tl
-\tl_new:N \l__knot_tmpg_tl
-\tl_new:N \l__knot_redraws_tl
-\tl_new:N \l__knot_clip_width_tl
-\tl_new:N \l__knot_name_tl
-\tl_new:N \l__knot_node_tl
-\tl_new:N \l__knot_aux_tl
-\tl_new:N \l__knot_auxa_tl
-
-\int_new:N \l__knot_tmpa_int
-\int_new:N \l__knot_strands_int
-\int_new:N \l__knot_intersections_int
-\int_new:N \l__knot_filaments_int
-\int_new:N \l__knot_component_start_int
-
-\dim_new:N \l__knot_tmpa_dim
-\dim_new:N \l__knot_tmpb_dim
-\dim_new:N \l__knot_tmpc_dim
-\dim_new:N \l__knot_tolerance_dim
-\dim_new:N \l__knot_clip_bg_radius_dim
-\dim_new:N \l__knot_clip_draw_radius_dim
-
-\bool_new:N \l__knot_draft_bool
-\bool_new:N \l__knot_ignore_ends_bool
-\bool_new:N \l__knot_self_intersections_bool
-\bool_new:N \l__knot_splits_bool
-\bool_new:N \l__knot_super_draft_bool
-
-\bool_new:N \l__knot_prepend_prev_bool
-\bool_new:N \l__knot_append_next_bool
-\bool_new:N \l__knot_skip_bool
-\bool_new:N \l__knot_save_bool
-
-\seq_new:N \l__knot_nodes_seq
-
-\bool_set_true:N \l__knot_ignore_ends_bool
-% \end{macrocode}
-%
-% Configuration is via TikZ keys and styles.
-% \begin{macrocode}
-\tikzset{
- knot/.code={
- \tl_if_eq:nnTF {#1} {none}
- {
- \tikz@addmode{\tikz@mode@doublefalse}
- }
- {
- \tikz@addmode{\tikz@mode@doubletrue}
- \tl_if_eq:nnTF {\pgfkeysnovalue} {#1}
- {
- \tikz@addoption{\pgfsetinnerstrokecolor{.}}
- }
- {
- \pgfsetinnerstrokecolor{#1}
- }
- \tikz@addoption{
- \pgfsetstrokecolor{knotbg}
- }
- \tl_set:Nn \tikz@double@setup{
- \pgfsetinnerlinewidth{\pgflinewidth}
- \pgfsetlinewidth{\dim_eval:n {\tl_use:N \l__knot_gap_tl \pgflinewidth}}
- }
- }
- },
- knot~ gap/.store~ in=\l__knot_gap_tl,
- knot~ gap=3,
- knot~ diagram/.is~family,
- knot~ diagram/.unknown/.code={
- \tl_set_eq:NN \l__knot_tmpa_tl \pgfkeyscurrentname
- \pgfkeysalso{
- /tikz/\l__knot_tmpa_tl=#1
- }
- },
- background~ colour/.code={%
- \colorlet{knotbg}{#1}%
- },
- background~ color/.code={%
- \colorlet{knotbg}{#1}%
- },
- background~ colour=white,
- knot~ diagram,
- name/.store~ in=\l__knot_name_tl,
- name={knot},
- save~ intersections/.is~ choice,
- save~ intersections/.default=true,
- save~ intersections/true/.code={
- \bool_set_true:N \l__knot_save_bool
- },
- save~ intersections/false/.code={
- \bool_set_false:N \l__knot_save_bool
- },
- every~ strand/.style={draw},
- ignore~ endpoint~ intersections/.code={
- \tl_if_eq:nnTF {#1} {true}
- {
- \bool_set_true:N \l__knot_ignore_ends_bool
- }
- {
- \bool_set_false:N \l__knot_ignore_ends_bool
- }
- },
- ignore~ endpoint~ intersections/.default=true,
- consider~ self~ intersections/.is~choice,
- consider~ self~ intersections/true/.code={
- \bool_set_true:N \l__knot_self_intersections_bool
- \bool_set_true:N \l__knot_splits_bool
- },
- consider~ self~ intersections/false/.code={
- \bool_set_false:N \l__knot_self_intersections_bool
- \bool_set_false:N \l__knot_splits_bool
- },
- consider~ self~ intersections/no~ splits/.code={
- \bool_set_true:N \l__knot_self_intersections_bool
- \bool_set_false:N \l__knot_splits_bool
- },
- consider~ self~ intersections/.default={true},
- clip~ radius/.code={
- \dim_set:Nn \l__knot_clip_bg_radius_dim {#1}
- \dim_set:Nn \l__knot_clip_draw_radius_dim {#1+2pt}
- },
- clip~ draw~ radius/.code={
- \dim_set:Nn \l__knot_clip_draw_radius_dim {#1}
- },
- clip~ background~ radius/.code={
- \dim_set:Nn \l__knot_clip_bg_radius_dim {#1}
- },
- clip~ radius=10pt,
- end~ tolerance/.code={
- \dim_set:Nn \l__knot_tolerance_dim {#1}
- },
- end~ tolerance=14pt,
- clip/.style={
- clip
- },
- background~ clip/.style={
- clip
- },
- clip~ width/.code={
- \tl_set:Nn \l__knot_clip_width_tl {#1}
- },
- clip~ width=3,
- flip~ crossing/.code={%
- \tl_clear_new:c {l__knot_crossing_#1}
- \tl_set:cn {l__knot_crossing_#1} {x}
- },
- ignore~ crossing/.code={%
- \tl_clear_new:c {l__knot_ignore_crossing_#1}
- \tl_set:cn {l__knot_ignore_crossing_#1} {x}
- },
- draft~ mode/.is~ choice,
- draft~ mode/off/.code={%
- \bool_set_false:N \l__knot_draft_bool
- \bool_set_false:N \l__knot_super_draft_bool
- },
- draft~ mode/crossings/.code={%
- \bool_set_true:N \l__knot_draft_bool
- \bool_set_false:N \l__knot_super_draft_bool
- },
- draft~ mode/strands/.code={%
- \bool_set_true:N \l__knot_draft_bool
- \bool_set_true:N \l__knot_super_draft_bool
- },
- draft/.is~ family,
- draft,
- crossing~ label/.style={
- overlay,
- fill=white,
- fill~ opacity=.5,
- text~ opacity=1,
- text=blue,
- pin~ edge={blue,<-}
- },
- strand~ label/.style={
- overlay,
- circle,
- draw=purple,
- fill=white,
- fill~ opacity=.5,
- text~ opacity=1,
- text=purple,
- inner~ sep=0pt
- },
-}
-% \end{macrocode}
-%
-% Wrapper around \Verb+\tikzset+ for applying keys from a token list, checking for if the given token list exists.
-% \begin{macrocode}
-\cs_new_nopar:Npn \knot_apply_style:N #1
-{
- \tl_if_exist:NT #1 {
- \exp_args:NV \tikzset #1
- }
-}
-\cs_generate_variant:Nn \knot_apply_style:N {c}
-% \end{macrocode}
-%
-%\begin{macro}{\flipcrossings}
-% The user can specify a comma separated list of crossings to flip.
-% \begin{macrocode}
-\NewDocumentCommand \flipcrossings {m}
-{
- \tikzset{knot~ diagram/flip~ crossing/.list={#1}}%
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\strand}
-% This is how the user specifies a strand of the knot.
-% \begin{macrocode}
-\NewDocumentCommand \strand { O{} }
-{
- \int_incr:N \l__knot_strands_int
- \tl_clear_new:c {l__knot_options_strand \int_use:N \l__knot_strands_int}
- \tl_set:cn {l__knot_options_strand \int_use:N \l__knot_strands_int} {#1}
- \path[#1,save~ spath=knot strand \int_use:N \l__knot_strands_int]
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{knot}
-% This is the wrapper environment that calls the knot generation code.
-% \begin{macrocode}
-\NewDocumentEnvironment{knot} { O{} }
-{
- \knot_initialise:n {#1}
-}
-{
- \knot_render:
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_initialise:n}
-% Set up some stuff before loading in the strands.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \knot_initialise:n #1
-{
- \tikzset{knot~ diagram/.cd,every~ knot~ diagram/.try,#1}
- \int_zero:N \l__knot_strands_int
- \tl_clear:N \l__knot_redraws_tl
- \seq_gclear:N \l__knot_nodes_seq
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_render:}
-% This is the code that starts the work of rendering the knot.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \knot_render:
-{
-% \end{macrocode}
-% Start a scope and reset the transformation (since all transformations have already been taken into account when defining the strands).
-% \begin{macrocode}
- \pgfscope
- \pgftransformreset
-% \end{macrocode}
-% Loop through the strands drawing each one for the first time.
-% \begin{macrocode}
- \int_step_function:nnnN {1} {1} {\l__knot_strands_int} \knot_draw_strand:n
-% \end{macrocode}
-% In super draft mode we don't do anything else.
-% \begin{macrocode}
- \bool_if:NF \l__knot_super_draft_bool
- {
-% \end{macrocode}
-% In draft mode we draw labels at the ends of the strands; this also handles splitting curves to avoid self-intersections of Bezier curves if that's requested.
-% \begin{macrocode}
- \int_step_function:nnnN {1} {1} {\l__knot_strands_int} \knot_draw_labels:n
-% \end{macrocode}
-% If we're considering self intersections we need to split the strands into filaments.
-% \begin{macrocode}
- \bool_if:NTF \l__knot_self_intersections_bool
- {
- \knot_split_strands:
- \int_set_eq:NN \l__knot_tmpa_int \l__knot_filaments_int
- \tl_set:Nn \l__knot_prefix_tl {filament}
- }
- {
- \int_set_eq:NN \l__knot_tmpa_int \l__knot_strands_int
- \tl_set:Nn \l__knot_prefix_tl {strand}
- }
-% \end{macrocode}
-% Initialise the intersection count.
-% \begin{macrocode}
- \int_gzero:N \l__knot_intersections_int
-% \end{macrocode}
-% If in draft mode we label the intersections, otherwise we just stick a coordinate at each one.
-% \begin{macrocode}
- \bool_if:NTF \l__knot_draft_bool
- {
- \tl_set:Nn \l__knot_node_tl {
- \exp_not:N \node[coordinate,
- pin={[node~ contents={\int_use:N \l__knot_intersections_int},knot~ diagram/draft/crossing~ label, knot~ diagram/draft/crossing~ \int_use:N \l__knot_intersections_int \c_space_tl label/.try]
- }]
- }
- }
- {
- \tl_set:Nn \l__knot_node_tl {\exp_not:N \node[coordinate]}
- }
-% \end{macrocode}
-% This double loop steps through the pieces (strands or filaments) and computes the intersections and does stuff with those.
-% \begin{macrocode}
- \int_step_variable:nnnNn {1} {1} {\l__knot_tmpa_int - 1} \l__knot_tmpa_tl
- {
- \int_step_variable:nnnNn {\tl_use:N \l__knot_tmpa_tl + 1} {1} {\l__knot_tmpa_int} \l__knot_tmpb_tl
- {
- \knot_intersections:VV \l__knot_tmpa_tl \l__knot_tmpb_tl
- }
- }
-% \end{macrocode}
-% If any redraws were requested, do them here.
-% \begin{macrocode}
- \tl_use:N \l__knot_redraws_tl
-% \end{macrocode}
-% Draw the crossing nodes
-% \begin{macrocode}
- \seq_use:Nn \l__knot_nodes_seq {}
- }
-% \end{macrocode}
-% Close the scope
-% \begin{macrocode}
- \endpgfscope
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_draw_strand:n}
-% This renders a strand using the options originally specified.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \knot_draw_strand:n #1
-{
- \pgfscope
- \group_begin:
- \tl_set:Nn \l_tmpa_tl {knot~ diagram/every~ strand/.try,}
- \tl_put_right:Nv \l_tmpa_tl {l__knot_options_strand #1}
- \tl_put_right:Nn \l_tmpa_tl {,knot~ diagram/only~ when~ rendering/.try,only~ when~ rendering/.try}
- \spath_bake_round:n {knot strand #1}
- \spath_tikz_path:Vn \l_tmpa_tl {knot strand #1}
- \group_end:
- \endpgfscope
-}
-\cs_generate_variant:Nn \tl_put_right:Nn {Nv}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_draw_labels:n}
-% Draw a label at each end of each strand, if in draft mode.
-% Also, if requested, split potentially self intersecting Bezier curves.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \knot_draw_labels:n #1
-{
- \bool_if:NT \l__knot_draft_bool
- {
- \spath_get:nnN {knot strand #1} {final point} \l__knot_tmpb_tl
- \dim_set:Nn \l__knot_tmpa_dim {\tl_item:Nn \l__knot_tmpb_tl {1}}
- \dim_set:Nn \l__knot_tmpb_dim {\tl_item:Nn \l__knot_tmpb_tl {2}}
- \node[knot~ diagram/draft/strand~label] at (\l__knot_tmpa_dim,\l__knot_tmpb_dim) {#1};
- \spath_get:nnN {knot strand #1} {initial point} \l__knot_tmpb_tl
- \dim_set:Nn \l__knot_tmpa_dim {\tl_item:Nn \l__knot_tmpb_tl {1}}
- \dim_set:Nn \l__knot_tmpb_dim {\tl_item:Nn \l__knot_tmpb_tl {2}}
- \node[knot~ diagram/draft/strand~label] at (\l__knot_tmpa_dim,\l__knot_tmpb_dim) {#1};
- }
- \bool_if:nT {
- \l__knot_self_intersections_bool
- &&
- \l__knot_splits_bool
- }
- {
- \tl_clear:N \l__knot_tmpa_tl
- \spath_map_segment_function:nN {knot strand #1} \knot_split_self_intersects:NN
- \spath_put:nnV {knot strand #1} {path} \l__knot_tmpa_tl
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_split_self_intersects:NN}
-% This is the macro that does the split.
-% Figuring out whether a Bezier cubic self intersects is apparently a difficult problem so we don't bother.
-% We compute a point such that if there is an intersection then it lies on either side of the point.
-% I don't recall where the formula came from!
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \knot_split_self_intersects:NN #1#2
-{
- \tl_case:NnF #1
- {
- \g__spath_curvetoa_tl
- {
- \fp_set:Nn \l_tmpa_fp
- {
- (\tl_item:Nn #2 {3} - 3 * \tl_item:Nn #2 {6} + 3 * \tl_item:Nn #2 {9} - \tl_item:Nn #2 {12})
- *
- (3 * \tl_item:Nn #2 {8} - 3 * \tl_item:Nn #2 {11})
- -
- (\tl_item:Nn #2 {2} - 3 * \tl_item:Nn #2 {5} + 3 * \tl_item:Nn #2 {8} - \tl_item:Nn #2 {11})
- *
- (3 * \tl_item:Nn #2 {9} - 3 * \tl_item:Nn #2 {12})
- }
- \fp_set:Nn \l_tmpb_fp
- {
- (\tl_item:Nn #2 {2} - 3 * \tl_item:Nn #2 {5} + 3 * \tl_item:Nn #2 {8} - \tl_item:Nn #2 {11})
- *
- (3 * \tl_item:Nn #2 {6} - 6 * \tl_item:Nn #2 {9} + 3 * \tl_item:Nn #2 {12})
- -
- (\tl_item:Nn #2 {3} - 3 * \tl_item:Nn #2 {6} + 3 * \tl_item:Nn #2 {9} - \tl_item:Nn #2 {12})
- *
- (3 * \tl_item:Nn #2 {5} - 6 * \tl_item:Nn #2 {8} + 3 * \tl_item:Nn #2 {11})
- }
- \fp_compare:nTF
- {
- \l_tmpb_fp != 0
- }
- {
- \fp_set:Nn \l_tmpa_fp {.5 * \l_tmpa_fp / \l_tmpb_fp}
- \fp_compare:nTF
- {
- 0 < \l_tmpa_fp && \l_tmpa_fp < 1
- }
- {
- \spath_split_curve:VVNN \l_tmpa_fp #2 \l_tmpa_tl \l_tmpb_tl
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl}
- \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl}
- \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl}
- \tl_put_right:NV \l__knot_tmpa_tl \l_tmpa_tl
- \tl_put_right:NV \l__knot_tmpa_tl \l_tmpb_tl
- }
- {
- \tl_set_eq:NN \l_tmpa_tl #2
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_put_right:NV \l__knot_tmpa_tl \l_tmpa_tl
- }
- }
- {
- \tl_set_eq:NN \l_tmpa_tl #2
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_put_right:NV \l__knot_tmpa_tl \l_tmpa_tl
- }
- }
- \g__spath_lineto_tl
- {
- \tl_set_eq:NN \l_tmpa_tl #2
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
- \tl_put_right:NV \l__knot_tmpa_tl \l_tmpa_tl
- }
- }
- {
- \tl_put_right:NV \l__knot_tmpa_tl #2
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_intersections:nn}
-% This computes the intersections of two pieces and steps through them.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \knot_intersections:nn #1#2
-{
- \group_begin:
- \tl_set_eq:NN \l__knot_tmpa_tl \l__knot_prefix_tl
- \tl_put_right:Nn \l__knot_tmpa_tl {#1}
- \tl_set_eq:NN \l__knot_tmpb_tl \l__knot_prefix_tl
- \tl_put_right:Nn \l__knot_tmpb_tl {#2}
- \spath_get:nnN {knot \tl_use:N \l__knot_tmpa_tl} {path} \l__knot_tmpc_tl
- \spath_get:nnN {knot \tl_use:N \l__knot_tmpb_tl} {path} \l__knot_tmpd_tl
-
- \bool_if:nTF {
- \l__knot_save_bool
- &&
- \tl_if_exist_p:c {knot~ intersections~ \tl_use:N \l__knot_name_tl - \tl_use:N \l__knot_tmpa_tl - \tl_use:N \l__knot_tmpb_tl}
- }
- {
- \tl_use:c {knot~ intersections~ \tl_use:N \l__knot_name_tl - \tl_use:N \l__knot_tmpa_tl - \tl_use:N \l__knot_tmpb_tl}
- }
- {
-\pgfintersectionofpaths{\pgfsetpath\l__knot_tmpc_tl}{\pgfsetpath\l__knot_tmpd_tl}
-
- }
- \int_compare:nT {\pgfintersectionsolutions > 0}
- {
- \int_step_function:nnnN {1} {1} {\pgfintersectionsolutions} \knot_do_intersection:n
- }
- \knot_save_intersections:VV \l__knot_tmpa_tl \l__knot_tmpb_tl
- \group_end:
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_save_intersections:nn}
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \knot_save_intersections:nn #1#2
-{
- \bool_if:NT \l__knot_save_bool
- {
- \tl_clear:N \l__knot_aux_tl
- \tl_put_right:Nn \l__knot_aux_tl
- {
- \def\pgfintersectionsolutions
- }
- \tl_put_right:Nx \l__knot_aux_tl
- {
- {\int_eval:n {\pgfintersectionsolutions}}
- }
- \int_compare:nT {\pgfintersectionsolutions > 0}
- {
- \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions}
- {
- \pgfpointintersectionsolution{##1}
- \dim_set:Nn \l__knot_tmpa_dim {\pgf@x}
- \dim_set:Nn \l__knot_tmpb_dim {\pgf@y}
- \tl_put_right:Nn \l__knot_aux_tl
- {
- \expandafter\def\csname pgfpoint@intersect@solution@##1\endcsname
- }
- \tl_put_right:Nx \l__knot_aux_tl
- {
- {\exp_not:N \pgf@x=\dim_use:N \l__knot_tmpa_dim\exp_not:N\relax\exp_not:N \pgf@y =\dim_use:N \l__knot_tmpb_dim\relax}
- }
- }
- \tl_set:Nn \l__knot_auxa_tl {\expandafter \gdef \csname knot~ intersections~}
- \tl_put_right:Nx \l__knot_auxa_tl {\tl_use:N \l__knot_name_tl - #1 - #2}
- \tl_put_right:Nn \l__knot_auxa_tl {\endcsname}
- \tl_put_right:Nx \l__knot_auxa_tl {{\tl_to_str:N \l__knot_aux_tl}}
- \protected@write\@auxout{}{\tl_to_str:N \l__knot_auxa_tl}
- }
- }
-}
-\cs_generate_variant:Nn \knot_save_intersections:nn {VV}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_do_intersection:n}
-% This handles a specific intersection.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \knot_do_intersection:n #1
-{
-% \end{macrocode}
-% Get the intersection coordinates.
-% \begin{macrocode}
- \pgfpointintersectionsolution{#1}
- \dim_set:Nn \l__knot_tmpa_dim {\pgf@x}
- \dim_set:Nn \l__knot_tmpb_dim {\pgf@y}
-% \end{macrocode}
-% If we're dealing with filaments, we can get false positives from the end points.
-% \begin{macrocode}
- \bool_set_false:N \l__knot_skip_bool
- \bool_if:NT \l__knot_self_intersections_bool
- {
-% \end{macrocode}
-% If one filament preceded the other, test for the intersection being at the relevant end point.
-% \begin{macrocode}
- \tl_set:Nn \l_tmpa_tl {knot previous}
- \tl_put_right:NV \l_tmpa_tl \l__knot_tmpa_tl
- \tl_set:Nv \l_tmpa_tl \l_tmpa_tl
- \tl_if_eq:NNT \l_tmpa_tl \l__knot_tmpb_tl
- {
- \knot_test_endpoint:VnT \l__knot_tmpb_tl {final point}
- {
- \bool_set_true:N \l__knot_skip_bool
- }
- }
-
- \tl_set:Nn \l_tmpa_tl {knot previous}
- \tl_put_right:NV \l_tmpa_tl \l__knot_tmpb_tl
- \tl_set:Nv \l_tmpa_tl \l_tmpa_tl
- \tl_if_eq:NNT \l_tmpa_tl \l__knot_tmpa_tl
- {
- \knot_test_endpoint:VnT \l__knot_tmpa_tl {final point}
- {
- \bool_set_true:N \l__knot_skip_bool
- }
- }
- }
-% \end{macrocode}
-% The user can also say that end points of filaments (or strands) should simply be ignored anyway.
-% \begin{macrocode}
- \bool_if:NT \l__knot_ignore_ends_bool
- {
- \knot_test_endpoint:VnT \l__knot_tmpa_tl {initial point}
- {
- \bool_set_true:N \l__knot_skip_bool
- }
- \knot_test_endpoint:VnT \l__knot_tmpa_tl {final point}
- {
- \bool_set_true:N \l__knot_skip_bool
- }
- \knot_test_endpoint:VnT \l__knot_tmpb_tl {initial point}
- {
- \bool_set_true:N \l__knot_skip_bool
- }
- \knot_test_endpoint:VnT \l__knot_tmpb_tl {final point}
- {
- \bool_set_true:N \l__knot_skip_bool
- }
- }
-% \end{macrocode}
-% Assuming that we passed all the above tests, we render the crossing.
-% \begin{macrocode}
- \bool_if:NF \l__knot_skip_bool
- {
-
- \int_gincr:N \l__knot_intersections_int
-% \end{macrocode}
-% This is the intersection test.
-% If the intersection finder finds too many, it might be useful to ignore some.
-% \begin{macrocode}
- \bool_if:nF
- {
- \tl_if_exist_p:c {l__knot_ignore_crossing_ \int_use:N
- \l__knot_intersections_int}
- &&
- ! \tl_if_empty_p:c {l__knot_ignore_crossing_ \int_use:N
- \l__knot_intersections_int}
- }
- {
-% \end{macrocode}
-% This is the flip test.
-% We only render one of the paths.
-% The ``flip'' swaps which one we render.
-% \begin{macrocode}
- \bool_if:nTF
- {
- \tl_if_exist_p:c {l__knot_crossing_ \int_use:N
- \l__knot_intersections_int}
- &&
- ! \tl_if_empty_p:c {l__knot_crossing_ \int_use:N
- \l__knot_intersections_int}
- }
- {
- \tl_set_eq:NN \l__knot_tmpg_tl \l__knot_tmpb_tl
- }
- {
- \tl_set_eq:NN \l__knot_tmpg_tl \l__knot_tmpa_tl
- }
-% \end{macrocode}
-% Now we know which one we're rendering, we test to see if we should also render its predecessor or successor to ensure that we render a path through the entire crossing region.
-% \begin{macrocode}
- \bool_if:NT \l__knot_self_intersections_bool
- {
- \knot_test_endpoint:VnT \l__knot_tmpg_tl {initial point}
- {
- \bool_set_true:N \l__knot_prepend_prev_bool
- }
- {
- \bool_set_false:N \l__knot_prepend_prev_bool
- }
- \knot_test_endpoint:VnT \l__knot_tmpg_tl {final point}
- {
- \bool_set_true:N \l__knot_append_next_bool
- }
- {
- \bool_set_false:N \l__knot_append_next_bool
- }
-% \end{macrocode}
-% If either of those tests succeeded, do the appending or prepending.
-% \begin{macrocode}
- \bool_if:nT
- {
- \l__knot_prepend_prev_bool || \l__knot_append_next_bool
- }
- {
- \spath_clone:nn {knot \tl_use:N \l__knot_tmpg_tl}
- {knot \tl_use:N \l__knot_prefix_tl -1}
-
- \tl_set_eq:cc {l__knot_options_ \tl_use:N \l__knot_prefix_tl -1} {l__knot_options_ \tl_use:N \l__knot_tmpg_tl}
-
- \bool_if:nT
- {
- \l__knot_prepend_prev_bool
- &&
- \tl_if_exist_p:c {knot previous \tl_use:N \l__knot_tmpg_tl}
- &&
- !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl}
- }
- {
- \spath_prepend_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}}
-% \end{macrocode}
-% If we split potentially self intersecting curves, we test to see if we should prepend yet another segment.
-% \begin{macrocode}
- \bool_if:nT
- {
- \l__knot_splits_bool
- &&
- \tl_if_exist_p:c {knot previous \tl_use:N \l__knot_tmpg_tl}
- &&
- !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl}
- }
- {
- \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {initial point}
- {
- \spath_get:nnN {knot \tl_use:N \l__knot_prefix_tl -1} {path} \l_tmpa_tl
- \spath_prepend_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}}}
- \spath_get:nnN {knot \tl_use:N \l__knot_prefix_tl -1} {path} \l_tmpa_tl
-
- }
- }
- }
-% \end{macrocode}
-% Now the same for appending.
-% \begin{macrocode}
- \bool_if:nT
- {
- \l__knot_append_next_bool
- &&
- \tl_if_exist_p:c {knot next \tl_use:N \l__knot_tmpg_tl}
- &&
- !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl}
- }
- {
- \spath_append_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}}
- \bool_if:nT
- {
- \l__knot_splits_bool
- &&
- \tl_if_exist_p:c {knot previous \tl_use:N
- \l__knot_tmpg_tl}
- &&
- !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl}
- }
- {
- \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {final point}
- {
- \spath_append_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}}}
-
- }
- }
- }
-
- \tl_set:Nn \l__knot_tmpg_tl {\tl_use:N \l__knot_prefix_tl -1}
- }
- }
-% \end{macrocode}
-% Now we render the crossing.
-% \begin{macrocode}
- \pgfscope
- \group_begin:
- \tikzset{knot~ diagram/every~ intersection/.try, every~ intersection/.try, knot~ diagram/intersection~ \int_use:N \l__knot_intersections_int/.try}
- \knot_draw_crossing:nVV {\tl_use:N \l__knot_tmpg_tl} \l__knot_tmpa_dim \l__knot_tmpb_dim
- \group_end:
- \endpgfscope
-% \end{macrocode}
-% This ends the boolean as to whether to consider the intersection at all
-% \begin{macrocode}
- }
-% \end{macrocode}
-% And stick a coordinate possibly with a label at the crossing.
-% \begin{macrocode}
- \seq_gpush:Nx \l__knot_nodes_seq { \l__knot_node_tl (\l__knot_name_tl \c_space_tl \int_use:N \l__knot_intersections_int) at (\dim_use:N \l__knot_tmpa_dim, \dim_use:N \l__knot_tmpb_dim) {};}
-
- }
-}
-
-\cs_generate_variant:Nn \knot_intersections:nn {VV}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_test_endpoint:N}
-% Test whether the point is near the intersection point.
-% \begin{macrocode}
-\prg_new_conditional:Npnn \knot_test_endpoint:N #1 {p,T,F,TF}
-{
- \dim_compare:nTF
- {
- \dim_abs:n { \l__knot_tmpa_dim - \tl_item:Nn #1 {1}}
- +
- \dim_abs:n { \l__knot_tmpb_dim - \tl_item:Nn #1 {2}}
- <
- \l__knot_tolerance_dim
- }
- {
- \prg_return_true:
- }
- {
- \prg_return_false:
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_test_endpoint:nn}
-% Wrapper around the above.
-% \begin{macrocode}
-\prg_new_protected_conditional:Npnn \knot_test_endpoint:nn #1#2 {T,F,TF}
-{
- \spath_get:nnN {knot #1} {#2} \l__knot_tmpd_tl
- \knot_test_endpoint:NTF \l__knot_tmpd_tl
- {
- \prg_return_true:
- }
- {
- \prg_return_false:
- }
-}
-
-\cs_generate_variant:Nn \knot_test_endpoint:nnT {VnT,vnT}
-\cs_generate_variant:Nn \knot_test_endpoint:nnF {VnF,vnF}
-\cs_generate_variant:Nn \knot_test_endpoint:nnTF {VnTF,vnTF}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_draw_crossing:nnn}
-% This is the code that actually renders a crossing.
-% \begin{macrocode}
-\cs_new_nopar:Npn \knot_draw_crossing:nnn #1#2#3
-{
- \group_begin:
- \pgfscope
- \path[knot~ diagram/background~ clip] (#2, #3) circle[radius=\l__knot_clip_bg_radius_dim];
-
- \tl_set:Nn \l_tmpa_tl {knot~ diagram/every~ strand/.try,}
- \tl_if_exist:cT {l__knot_options_ #1}
- {
- \tl_put_right:Nv \l_tmpa_tl {l__knot_options_ #1}
- }
- \tl_put_right:Nn \l_tmpa_tl {,knotbg,line~ width= \tl_use:N \l__knot_clip_width_tl * \pgflinewidth}
- \spath_tikz_path:Vn \l_tmpa_tl {knot #1}
-
- \endpgfscope
-
- \pgfscope
- \path[knot~ diagram/clip] (#2, #3) circle[radius=\l__knot_clip_draw_radius_dim];
-
- \tl_set:Nn \l_tmpa_tl {knot~ diagram/every~ strand/.try,}
- \tl_if_exist:cT {l__knot_options_ #1}
- {
- \tl_put_right:Nv \l_tmpa_tl {l__knot_options_ #1}
- }
- \tl_put_right:Nn \l_tmpa_tl {,knot~ diagram/only~ when~ rendering/.try,only~ when~ rendering/.try}
- \spath_tikz_path:Vn \l_tmpa_tl {knot #1}
-
- \endpgfscope
- \group_end:
-}
-
-\cs_generate_variant:Nn \knot_draw_crossing:nnn {nVV}
-
-\cs_new_nopar:Npn \knot_draw_crossing:nn #1#2
-{
- \tikz@scan@one@point\pgfutil@firstofone #2 \relax
- \knot_draw_crossing:nVV {#1} \pgf@x \pgf@y
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_split_strands:}
-% This, and the following macros, are for splitting strands into filaments.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \knot_split_strands:
-{
- \int_gzero:N \l__knot_filaments_int
- \int_step_function:nnnN {1} {1} {\l__knot_strands_int} \knot_split_strand:n
- \int_step_function:nnnN {1} {1} {\l__knot_filaments_int} \knot_compute_nexts:n
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_compute_nexts:n}
-% Each filament needs to know its predecessor and successor.
-% We work out the predecessors as we go along, this fills in the successors.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \knot_compute_nexts:n #1
-{
- \tl_clear_new:c {knot next \tl_use:c {knot previous filament #1}}
- \tl_set:cn {knot next \tl_use:c {knot previous filament #1}} {filament #1}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_split_strand:n}
-% Sets up the split for a single strand.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \knot_split_strand:n #1
-{
- \int_set_eq:NN \l__knot_component_start_int \l__knot_filaments_int
- \int_incr:N \l__knot_component_start_int
- \tl_set_eq:Nc \l__knot_tmpa_tl {l__knot_options_strand #1}
- \spath_map_segment_function:nN {knot strand #1} \knot_save_filament:NN
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\knot_save_filament:NN}
-% Saves a filament as a new \Verb+spath+ object.
-% \begin{macrocode}
-\cs_new_protected_nopar:Npn \knot_save_filament:NN #1#2
-{
- \tl_case:NnF #1
- {
- \g__spath_moveto_tl
- {
- \int_compare:nT {\l__knot_component_start_int < \l__knot_filaments_int}
- {
- \int_set_eq:NN \l__knot_component_start_int \l__knot_filaments_int
- }
- }
- \g__spath_lineto_tl
- {
- \int_gincr:N \l__knot_filaments_int
- \spath_clear_new:n {knot filament \int_use:N \l__knot_filaments_int}
- \spath_put:nnV {knot filament \int_use:N \l__knot_filaments_int} {path} #2
- \tl_set_eq:cN {l__knot_options_filament \int_use:N \l__knot_filaments_int} \l__knot_tmpa_tl
-
- \tl_clear_new:c {knot previous filament \int_use:N \l__knot_filaments_int}
- \int_compare:nF {\l__knot_component_start_int == \l__knot_filaments_int}
- {
- \tl_set:cx {knot previous filament \int_use:N \l__knot_filaments_int} {filament \int_eval:n {\l__knot_filaments_int - 1}}
- }
- }
- \g__spath_curvetoa_tl
- {
- \int_gincr:N \l__knot_filaments_int
- \spath_clear_new:n {knot filament \int_use:N \l__knot_filaments_int}
- \spath_put:nnV {knot filament \int_use:N \l__knot_filaments_int} {path} #2
- \tl_set_eq:cN {l__knot_options_filament \int_use:N \l__knot_filaments_int} \l__knot_tmpa_tl
-
- \tl_clear_new:c {knot previous filament \int_use:N \l__knot_filaments_int}
- \int_compare:nF {\l__knot_component_start_int == \l__knot_filaments_int}
- {
- \tl_set:cx {knot previous filament \int_use:N \l__knot_filaments_int} {filament \int_eval:n {\l__knot_filaments_int - 1}}
- }
- }
- \g__spath_closepath_tl
- {
- \tl_show:N #2
- \int_gincr:N \l__knot_filaments_int
- \spath_clear_new:n {knot filament \int_use:N \l__knot_filaments_int}
- \tl_clear:N \l_tmpa_tl
- \tl_put_right:Nx {\tl_item:Nn #2 {1}\tl_item:Nn #2 {2}\tl_item:Nn #2 {3}}
- \tl_put_right:NV \l_tmpa_tl \g__spath_lineto_tl
- \tl_put_right:Nx {\tl_item:Nn #2 {5}\tl_item:Nn #2 {6}}
- \tl_show:N \l_tmpa_tl
- \spath_put:nnV {knot filament \int_use:N \l__knot_filaments_int} {path} \l_tmpa_tl
- \tl_set_eq:cN {l__knot_options_filament \int_use:N \l__knot_filaments_int} \l__knot_tmpa_tl
- \tl_clear_new:c {knot previous filament \int_use:N \l__knot_filaments_int}
- \int_compare:nF {\l__knot_component_start_int == \l__knot_filaments_int}
- {
- \tl_set:cx {knot previous filament \int_use:N \l__knot_filaments_int} {filament \int_eval:n {\l__knot_filaments_int - 1}}
- }
- \tl_set:cx {knot previous filament \int_use:N \l__knot_component_start_int} {filament \int_use:N \l__knot_filaments_int}
- }
- }
- {
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\redraw}
-% The user can redraw segments of the strands at specific locations.
-% \begin{macrocode}
-\NewDocumentCommand \redraw { m m }
-{
-% \tikz@scan@one@point\pgfutil@firstofone #2 \relax
- \tl_put_right:Nn \l__knot_redraws_tl {\knot_draw_crossing:nn}
- \tl_put_right:Nx \l__knot_redraws_tl {
- {strand #1} {#2}% {\dim_use:N \pgf@x} {\dim_use:N \pgf@y}
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macrocode}
-\ExplSyntaxOff
-% \end{macrocode}
-%
-% \begin{macro}{\pgf@sh@@knotanchor}
-% Add the extra anchors for the knot crossing nodes.
-% \begin{macrocode}
-\def\pgf@sh@@knotanchor#1#2{%
- \anchor{#2 north west}{%
- \csname pgf@anchor@knot #1@north west\endcsname%
- \pgf@x=#2\pgf@x%
- \pgf@y=#2\pgf@y%
- }%
- \anchor{#2 north east}{%
- \csname pgf@anchor@knot #1@north east\endcsname%
- \pgf@x=#2\pgf@x%
- \pgf@y=#2\pgf@y%
- }%
- \anchor{#2 south west}{%
- \csname pgf@anchor@knot #1@south west\endcsname%
- \pgf@x=#2\pgf@x%
- \pgf@y=#2\pgf@y%
- }%
- \anchor{#2 south east}{%
- \csname pgf@anchor@knot #1@south east\endcsname%
- \pgf@x=#2\pgf@x%
- \pgf@y=#2\pgf@y%
- }%
- \anchor{#2 north}{%
- \csname pgf@anchor@knot #1@north\endcsname%
- \pgf@x=#2\pgf@x%
- \pgf@y=#2\pgf@y%
- }%
- \anchor{#2 east}{%
- \csname pgf@anchor@knot #1@east\endcsname%
- \pgf@x=#2\pgf@x%
- \pgf@y=#2\pgf@y%
- }%
- \anchor{#2 west}{%
- \csname pgf@anchor@knot #1@west\endcsname%
- \pgf@x=#2\pgf@x%
- \pgf@y=#2\pgf@y%
- }%
- \anchor{#2 south}{%
- \csname pgf@anchor@knot #1@south\endcsname%
- \pgf@x=#2\pgf@x%
- \pgf@y=#2\pgf@y%
- }%
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{knot crossing}
-% \begin{macrocode}
-\pgfdeclareshape{knot crossing}
-{
- \inheritsavedanchors[from=circle] % this is nearly a circle
- \inheritanchorborder[from=circle]
- \inheritanchor[from=circle]{north}
- \inheritanchor[from=circle]{north west}
- \inheritanchor[from=circle]{north east}
- \inheritanchor[from=circle]{center}
- \inheritanchor[from=circle]{west}
- \inheritanchor[from=circle]{east}
- \inheritanchor[from=circle]{mid}
- \inheritanchor[from=circle]{mid west}
- \inheritanchor[from=circle]{mid east}
- \inheritanchor[from=circle]{base}
- \inheritanchor[from=circle]{base west}
- \inheritanchor[from=circle]{base east}
- \inheritanchor[from=circle]{south}
- \inheritanchor[from=circle]{south west}
- \inheritanchor[from=circle]{south east}
- \inheritanchorborder[from=circle]
- \pgf@sh@@knotanchor{crossing}{2}
- \pgf@sh@@knotanchor{crossing}{3}
- \pgf@sh@@knotanchor{crossing}{4}
- \pgf@sh@@knotanchor{crossing}{8}
- \pgf@sh@@knotanchor{crossing}{16}
- \pgf@sh@@knotanchor{crossing}{32}
- \backgroundpath{
- \pgfutil@tempdima=\radius%
- \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
- \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
- \ifdim\pgf@xb<\pgf@yb%
- \advance\pgfutil@tempdima by-\pgf@yb%
- \else%
- \advance\pgfutil@tempdima by-\pgf@xb%
- \fi%
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{knot over cross}
-% \begin{macrocode}
-\pgfdeclareshape{knot over cross}
-{
- \inheritsavedanchors[from=rectangle] % this is nearly a circle
- \inheritanchorborder[from=rectangle]
- \inheritanchor[from=rectangle]{north}
- \inheritanchor[from=rectangle]{north west}
- \inheritanchor[from=rectangle]{north east}
- \inheritanchor[from=rectangle]{center}
- \inheritanchor[from=rectangle]{west}
- \inheritanchor[from=rectangle]{east}
- \inheritanchor[from=rectangle]{mid}
- \inheritanchor[from=rectangle]{mid west}
- \inheritanchor[from=rectangle]{mid east}
- \inheritanchor[from=rectangle]{base}
- \inheritanchor[from=rectangle]{base west}
- \inheritanchor[from=rectangle]{base east}
- \inheritanchor[from=rectangle]{south}
- \inheritanchor[from=rectangle]{south west}
- \inheritanchor[from=rectangle]{south east}
- \inheritanchorborder[from=rectangle]
- \backgroundpath{
- \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
- \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
- \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
- \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
- }
- \foregroundpath{
-% store lower right in xa/ya and upper right in xb/yb
- \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
- \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
- \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
- \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{knot under cross}
-% \begin{macrocode}
-\pgfdeclareshape{knot under cross}
-{
- \inheritsavedanchors[from=rectangle] % this is nearly a circle
- \inheritanchorborder[from=rectangle]
- \inheritanchor[from=rectangle]{north}
- \inheritanchor[from=rectangle]{north west}
- \inheritanchor[from=rectangle]{north east}
- \inheritanchor[from=rectangle]{center}
- \inheritanchor[from=rectangle]{west}
- \inheritanchor[from=rectangle]{east}
- \inheritanchor[from=rectangle]{mid}
- \inheritanchor[from=rectangle]{mid west}
- \inheritanchor[from=rectangle]{mid east}
- \inheritanchor[from=rectangle]{base}
- \inheritanchor[from=rectangle]{base west}
- \inheritanchor[from=rectangle]{base east}
- \inheritanchor[from=rectangle]{south}
- \inheritanchor[from=rectangle]{south west}
- \inheritanchor[from=rectangle]{south east}
- \inheritanchorborder[from=rectangle]
- \backgroundpath{
- \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
- \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
- \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
- \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
- }
- \foregroundpath{
-% store lower right in xa/ya and upper right in xb/yb
- \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
- \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
- \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
- \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{knot vert}
-% \begin{macrocode}
-\pgfdeclareshape{knot vert}
-{
- \inheritsavedanchors[from=rectangle] % this is nearly a circle
- \inheritanchorborder[from=rectangle]
- \inheritanchor[from=rectangle]{north}
- \inheritanchor[from=rectangle]{north west}
- \inheritanchor[from=rectangle]{north east}
- \inheritanchor[from=rectangle]{center}
- \inheritanchor[from=rectangle]{west}
- \inheritanchor[from=rectangle]{east}
- \inheritanchor[from=rectangle]{mid}
- \inheritanchor[from=rectangle]{mid west}
- \inheritanchor[from=rectangle]{mid east}
- \inheritanchor[from=rectangle]{base}
- \inheritanchor[from=rectangle]{base west}
- \inheritanchor[from=rectangle]{base east}
- \inheritanchor[from=rectangle]{south}
- \inheritanchor[from=rectangle]{south west}
- \inheritanchor[from=rectangle]{south east}
- \inheritanchorborder[from=rectangle]
- \backgroundpath{
-% store lower right in xa/ya and upper right in xb/yb
- \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
- \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
- \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
- \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
- \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
- \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{knot horiz}
-% \begin{macrocode}
-\pgfdeclareshape{knot horiz}
-{
- \inheritsavedanchors[from=rectangle] % this is nearly a circle
- \inheritanchorborder[from=rectangle]
- \inheritanchor[from=rectangle]{north}
- \inheritanchor[from=rectangle]{north west}
- \inheritanchor[from=rectangle]{north east}
- \inheritanchor[from=rectangle]{center}
- \inheritanchor[from=rectangle]{west}
- \inheritanchor[from=rectangle]{east}
- \inheritanchor[from=rectangle]{mid}
- \inheritanchor[from=rectangle]{mid west}
- \inheritanchor[from=rectangle]{mid east}
- \inheritanchor[from=rectangle]{base}
- \inheritanchor[from=rectangle]{base west}
- \inheritanchor[from=rectangle]{base east}
- \inheritanchor[from=rectangle]{south}
- \inheritanchor[from=rectangle]{south west}
- \inheritanchor[from=rectangle]{south east}
- \inheritanchorborder[from=rectangle]
- \foregroundpath{
-% store lower right in xa/ya and upper right in xb/yb
- \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
- \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
- \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
- \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
- \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
- \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \iffalse
-%</knots>
-% \fi
-%\Finale
-\endinput
diff --git a/graphics/pgf/contrib/spath3/spath3.pdf b/graphics/pgf/contrib/spath3/spath3.pdf
new file mode 100644
index 0000000000..bbc90be42e
--- /dev/null
+++ b/graphics/pgf/contrib/spath3/spath3.pdf
Binary files differ
diff --git a/graphics/pgf/contrib/spath3/spath3.tex b/graphics/pgf/contrib/spath3/spath3.tex
new file mode 100644
index 0000000000..86f925ba9e
--- /dev/null
+++ b/graphics/pgf/contrib/spath3/spath3.tex
@@ -0,0 +1,650 @@
+\RequirePackage{shellesc}
+\immediate\write18{tex spath3_code.dtx}
+\documentclass{l3doc}
+\usepackage{tikz}
+\usetikzlibrary{
+ spath3,
+ hobby,
+ patterns,
+ intersections,
+ arrows.meta,
+}
+
+\usepackage{listings}
+\lstloadlanguages{[LaTeX]TeX}
+\lstset{
+ breakatwhitespace=true,
+ breaklines=true,
+ language=[LaTeX]TeX,
+ basicstyle=\small\ttfamily,
+ keepspaces=true,
+ columns=fullflexible
+}
+
+\usepackage{fancyvrb}
+
+\newenvironment{example}
+{\VerbatimEnvironment
+\begin{VerbatimOut}[gobble=0]{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}
+}
+
+\providecommand*{\url}{\texttt}
+\GetFileInfo{spath3.sty}
+
+\title{The \textsf{spath3} Package: Documentation}
+\author{Andrew Stacey \\ \url{loopspace@mathforge.org}}
+ \date{\fileversion~from \filedate}
+
+ \begin{document}
+
+ \maketitle
+
+ \section{Introduction}
+
+ The \texttt{spath3} package was originally designed as a low-level package for manipulating the \emph{soft paths} defined by PGF/TikZ.
+ Soft paths form one stage of the stack of translations between what the author writes in the \texttt{tikzpicture} environments in their \LaTeX\ document and what is eventually written to the output file.
+ Most of the complicated processing has been done by the time a soft path is constructed, but it is still very definitely a \TeX\ object and there has not, for example, been any consideration as to what the eventual output file format is (such as PDF, DVI, or SVG).
+ So it is very amenable to being modified at this stage and this package provides a set of routines for doing so.
+
+ The original purpose was to provide a common core on which other packages would be built.
+ Indeed, the packages \texttt{calligraphy}, \texttt{knots}, and \texttt{penrose} all use this package.
+ However, over time I've found myself wanting to use the routines of this package at a higher level and so have designed some user-level interfaces.
+ This document documents those.
+
+ To clarify some terminology, paths are composed of \emph{segment} and \emph{components}.
+A \emph{segment} is a minimal drawing piece.
+Thus it might be a straight line or a B\'ezier curve.
+A \emph{component} is a minimal connected section of the path.
+So every component starts with a move command and continues until the next move command.
+For ease of implementation (and to enable a copperplate pen in the calligraphy package!), an isolated move is considered as a component.
+
+
+ \section{TikZ Keys}
+
+\begin{lstlisting}
+\usetikzlibrary{spath3}
+\end{lstlisting}
+
+The \texttt{spath3} TikZ library defines a set of keys that can be issued to muck about with soft paths.
+These are all defined in the \texttt{spath} family, so all the following keys should be prefixed by \texttt{spath/}, or the key \texttt{spath/.cd} needs to be used beforehand.
+
+\subsection{Saving and Using Soft Paths}
+
+\begin{function}{save}
+\begin{syntax}
+|save=|\meta{name}
+\end{syntax}
+
+Saves the current path with name \texttt{<name>}.
+This delays until the path is fully constructed so can be issued in the options to the main command.
+
+Soft paths constructed this way are local to the group in which the path command is issued.
+
+The soft path is actually stored in a macro constructed from the name.
+There are a couple of reasons for using a \emph{name} rather than a macro directly.
+One is so that it is compatible with the \texttt{intersections} library -- by default both this package and that save their paths in the same underlying macro.
+The other is to provide a way to link a soft path with a set of TikZ styles (this is particularly useful when splitting the path into components).
+\end{function}
+
+\begin{function}{save global}
+\begin{syntax}
+|save global=|\meta{name}
+\end{syntax}
+
+Saves the current soft path globally.
+\end{function}
+
+\begin{function}{clone}
+\begin{syntax}
+|clone=|\marg{target}\marg{source}
+\end{syntax}
+
+Clones one soft path into another.
+\end{function}
+
+\begin{function}{restore}
+\begin{syntax}
+|restore=|\meta{name}
+\end{syntax}
+
+Restores a previously saved soft path to the current path.
+This happens immediately so can be issued in the options to the main command and then the path can be extended with normal drawing commands.
+Any keys that affect the soft path directly should be applied \emph{before} this one.
+
+One thing should be noted about transformations.
+By the time a soft path is built, all available transformations have been applied.
+This means that when re-inserting a soft path back into a high level command (such as |\draw|), the effect of existing transformations might produce some confusing effects.
+When restoring a path then the library tries to set the last point correctly, but depending on how this is used it can result in transformations being applied twice.
+\end{function}
+
+\begin{function}{append}
+\begin{syntax}
+|append=|\meta{name}
+\end{syntax}
+
+This inserts a soft path into the path at the current point, it is therefore more suited to being used part way through a path construction.
+In a sense, it is a little like a \texttt{pic} in that it enables the user to construct a path segment early to be reused at various places.
+
+The path is \emph{welded} on to the current path, meaning that it starts from the current point and there is no \texttt{move}.
+This is particularly useful for creating filled regions.
+\end{function}
+
+\begin{function}{reverse}
+\begin{syntax}
+|reverse=|\meta{name}
+\end{syntax}
+
+Reverses the path in the named spath object.
+This doesn't do any actually drawing.
+The effect is local, but if you want to work with both the original path and its reversal in the same path then use the \texttt{clone} key to copy it first.
+\end{function}
+
+\begin{function}{append reverse}
+\begin{syntax}
+|append reverse=|\meta{name}
+\end{syntax}
+
+Like \texttt{append} except that the inserted path is reversed first.
+\end{function}
+
+\begin{function}{insert}
+\begin{syntax}
+|insert=|\meta{name}
+\end{syntax}
+
+Like \texttt{append} except that it doesn't move the inserted path and there is a move between the current path and the inserted path.
+\end{function}
+
+\begin{function}{
+ shorten at end,
+shorten at start,
+shorten at both ends
+}
+\begin{syntax}
+|shorten at end=|\marg{name}\marg{dimen}
+\end{syntax}
+
+Shortens the soft path by the dimension from one or both ends.
+This shortens the soft path along its length so that it is guaranteed that the shorter path traces a subset of the original path.
+For B\'ezier curves, however, the amount of shortening is approximate and is better for shorter distances.
+If wanting to shorten by a large amount it is better to shorten by a small amount a number of times.
+\end{function}
+
+\begin{function}{translate}
+\begin{syntax}
+|translate=|\marg{name}\marg{x-dimen}\marg{y-dimen}
+\end{syntax}
+
+Translates the soft path by the given dimensions.
+\end{function}
+
+\begin{function}{transform}
+\begin{syntax}
+|transform=|\marg{name}\marg{transformations}
+\end{syntax}
+
+This applies the transformation to the soft path.
+The transformation is processed by TikZ so should consist of TikZ-level transformations such as |shift={(2,2)}|.
+\end{function}
+
+\subsection{Intersection Routines}
+
+To use these features you need to use the \texttt{intersections} library.
+
+\begin{function}{split at self intersections}
+\begin{syntax}
+|split at self intersections=|\meta{path}
+\end{syntax}
+
+This inserts breaks into the named soft path at the points where it intersects itself.
+\end{function}
+
+\begin{function}{split at intersections}
+\begin{syntax}
+|split at intersections=|\marg{first}\marg{second}
+\end{syntax}
+
+This inserts breaks into a pair of paths at their mutual intersections.
+\end{function}
+
+\subsection{Working with Components}
+
+\begin{function}{get components of}
+\begin{syntax}
+|get components of=|\marg{macro}\marg{path}
+\end{syntax}
+
+This splits the path into a list of its components, which are stored in the macro.
+The macro can be used in a |\foreach|.
+\end{function}
+
+\begin{function}{render components}
+\begin{syntax}
+|render components=|\meta{path}
+\end{syntax}
+
+This renders the components of a given path as separate TikZ commands, so that each can be separately styled.
+It applies the following styles (in this order):
+
+\begin{enumerate}
+\item \texttt{every spath component}
+\item \texttt{spath component <number>}
+\item \texttt{spath component=<number>}
+\item \texttt{every <path> component}
+\item \texttt{<path> component <number>}
+\item \texttt{<path> component=<number>}
+\end{enumerate}
+\end{function}
+
+\begin{function}{insert gaps after components}
+\begin{syntax}
+|insert gaps after components=|\marg{path}\marg{gap}\marg{components}
+\end{syntax}
+
+This inserts a gap between components of a path by shortening the end of the specified component and start of the next one.
+The list of components is passed through a |\foreach| loop so that syntax like |2,4,...,16|.
+\end{function}
+
+\begin{function}{join components}
+\begin{syntax}
+|join components=|\marg{path}\marg{components}
+\end{syntax}
+
+This removes the \texttt{move} between the given component and the previous one.
+If the component is the first one then it is joined to the last component.
+\end{function}
+
+\begin{function}{spot weld}
+\begin{syntax}
+|spot weld=|\meta{path}
+\end{syntax}
+
+This removes the \texttt{move} between any two components of the path where the end point of one component is the same as the initial point of the next (the tolerance on error here is \(0.01\)pt).
+\end{function}
+
+\begin{function}{remove empty components}
+\begin{syntax}
+|remove empty components=|\meta{path}
+\end{syntax}
+
+This removes empty components of the path (which consist of simply a move).
+\end{function}
+
+\subsection{Shortening Paths}
+
+\begin{function}{
+shorten path at end,
+shorten path at start,
+shorten path at both ends
+}
+\begin{syntax}
+|shorten path at end=|\marg{path}\marg{length}
+\end{syntax}
+
+This shortens a path by the given amount from the specified end.
+The shortening is done so that it guarantees that it lies along the original path, but therefore the length is not completely guaranteed to be accurate.
+This is particularly true for B\'ezier paths and if there is a very short segment at the end.
+
+It uses the derivative at the end to work out how much to shorten by.
+\end{function}
+
+\subsection{Exporting Paths}
+
+There are two keys to export a path.
+
+\begin{function}{save to aux}
+\begin{syntax}
+|save to aux=|\meta{path}
+\end{syntax}
+
+This will save the path to the auxfile so that it is available again on the next run through.
+\end{function}
+
+\begin{function}{export to svg}
+\begin{syntax}
+|export to svg=|\meta{path}
+\end{syntax}
+
+Saves the path to the file \texttt{path.svg} as an SVG document.
+\end{function}
+
+\subsection{Knots}
+
+\begin{function}{knot}
+\begin{syntax}
+|knot=|\meta{path}\meta{gap}\meta{components}
+\end{syntax}
+
+This style combines various of the above to make it simpler to draw knots and links.
+It expands to:
+
+\begin{lstlisting}
+knot/.style n args={3}{
+ spath/.cd,
+ split at self intersections=#1,
+ insert gaps after components={#1}{#2}{#3},
+ maybe spot weld=#1,
+ render components=#1
+}
+\end{lstlisting}
+
+This splits a path at the points where it self-intersects and then inserts gaps between specified components.
+The key |maybe spot weld| does a |spot weld| depending on whether or not the key |draft mode| is set to |true| or |false|.
+The point here is that when designing the knot it is useful to not weld together components since that changes the component count.
+But once the gaps are inserted in the desired places, welding the remaining components produces a nicer diagram.
+
+The components can be styled using the keys as described in |render components|.
+\end{function}
+
+\subsection{Coordinates}
+
+Soft paths are not natural TikZ objects and so when replaced back into a TikZ path construction then they don't fully interact with other TikZ things, like placing nodes at points on the path.
+To make things a little easier there is defined a coordinate system which identifies a point at a certain location along a soft path and keys which apply a transformation.
+
+\begin{function}{spath cs}
+\begin{syntax}
+|(spath cs:|\marg{name} \marg{parameter}|)|
+\end{syntax}
+
+The location specification is a little technical.
+It is specified as a number from \(0\) to \(1\), but the parameter works as follows.
+Let \(n\) be the number of \emph{segments} on the path (these are the individual drawing elements that make up the path).
+The interval from \(\frac{k-1}{n}\) to \(\frac{k}{n}\) is assigned to the \(k\)th segment of the path.
+Then for a parameter in that interval, the location uses the natural parametrisation of that segment.
+For a straight line, it is simply the proportional position along but for a B\'ezier curve then it uses the B\'ezier parametrisation.
+
+The space is vital, so if the \texttt{name} is contained in a macro then a space has to be inserted somehow.
+One option is to wrap the macro in braces, as seen in the examples in the next section.
+\end{function}
+
+\begin{function}{transform to, upright transform to}
+\begin{syntax}
+|transform to=|\marg{path}\marg{parameter}
+|upright transform to=|\marg{path}\marg{parameter}
+\end{syntax}
+
+These keys (which are in the |spath| family) set the transformation so that the origin is at the specified point of the curve (as described above) and the \(x\)--axis is tangential to the curve.
+The transformation is \emph{orthogonal} in that it is achieved by a rotation and a translation.
+
+The first key aligns the axes so that the \(x\)--axis is in the forward direction of the path as that path was constructed.
+The second key aligns the axes so that the \(y\)--axis points up the page.
+The intention with the second key is that it is similar to what happens with the |sloped| key when a node is placed on a curve.
+\end{function}
+
+\section{Examples}
+
+\begin{enumerate}
+\item Saving, restoring, inserting, and appending.
+
+\begin{example}
+\begin{tikzpicture}
+\path[spath/save=rpath] (0,0) to[out=30,in=150] (1,1);
+\foreach \k in {1,...,9} {
+ \fill[green] (spath cs:rpath 0.\k) circle[radius=3pt];
+ \node[above left] at (spath cs:rpath 0.\k) {\(0.\k\)};
+}
+\fill[green] (2,2) circle[radius=3pt];
+\draw[blue, spath/transform={rpath}{shift={(2,2)}}, spath/restore=rpath] node[right] {transform};
+\draw[orange] (3,0) [spath/insert=rpath] node[right] {insert};
+\draw[red] (3,-1) -- +(0,2) [spath/append=rpath] node[above] {append};
+\draw[spath/restore=rpath] node[right] {restore};
+\end{tikzpicture}
+\end{example}
+
+\item Reversing.
+
+\begin{example}
+\begin{tikzpicture}
+\path[spath/save=apath] (0,0) to[out=0,in=180] (2,1) to[out=0,in=180] (4,0);
+\filldraw[
+ green,
+ draw=black,
+ ultra thick,
+ spath/restore=apath
+] -- ++(0,-4) [spath/append reverse=apath] -- cycle;
+\end{tikzpicture}
+\end{example}
+
+\item Transformations.
+
+\begin{example}
+\begin{tikzpicture}
+\draw[spath/save=tpath] (0,0) rectangle +(1,1);
+\draw[rotate=45, xscale=2, yscale=3, ultra thick, red] (0,0) rectangle +(1,1);
+\draw[
+ spath/transform={tpath}{rotate=45, xscale=2, yscale=3},
+ spath/restore={tpath}];
+\end{tikzpicture}
+\end{example}
+
+\begin{example}
+\begin{tikzpicture}
+\draw[spath/save=oval] (0,0) to[out=0,in=0] (0,2) to[out=180,in=180] (0,0);
+\foreach \k in {0,...,9} {
+ \node[transform shape, spath/transform to={oval}{0.\k}] {k};
+}
+\begin{scope}[xshift = 3cm]
+\draw[spath/save=soval] (0,0) to[out=0,in=0] (0,2) to[out=180,in=180] (0,0);
+\foreach \k in {0,...,9} {
+ \node[transform shape, spath/upright transform to={soval}{0.\k}] {k};
+}
+\end{scope}
+\end{tikzpicture}
+\end{example}
+
+\item Shortening.
+
+\begin{example}
+\begin{tikzpicture}
+\path[spath/save=apath] (0,0) foreach \k in {1,...,4} { -- ++(1,0) +(0,0)};
+\draw[
+ ultra thick,
+ red,
+ spath/.cd,
+ shorten at end={apath}{7pt},
+ shorten at start={apath}{9pt},
+ translate={apath}{0pt}{1pt},
+ restore=apath,
+];
+\draw (0,0) circle[radius=9pt] [spath/insert=apath] circle[radius=7pt];
+\end{tikzpicture}
+\end{example}
+
+
+\begin{example}
+\begin{tikzpicture}
+\path[spath/save=apath] (0,0) foreach \k in {1,...,4} { to[out=0,in=180] ++(1,0) +(0,0)};
+\draw[
+ ultra thick,
+ red,
+ spath/.cd,
+ shorten at end={apath}{7pt},
+ shorten at start={apath}{9pt},
+ translate={apath}{0pt}{1pt},
+ restore=apath,
+];
+\draw (0,0) circle[radius=9pt] [spath/insert=apath] circle[radius=7pt];
+\end{tikzpicture}
+\end{example}
+
+\begin{example}
+\begin{tikzpicture}
+\draw[spath/save=npath] (0,0) foreach \k in {1,...,4} { -- ++(1,0) +(0,0)};
+\draw[green] (0,0) -- +(0,-3pt) foreach \k in {1,...,4} { -- +(0,-3pt) ++(1,0)} -- +(0,-3pt);
+
+\tikzset{
+ spath/.cd,
+ insert gaps after components={npath}{10pt}{1,3},
+ get components of={npath}\components,
+}
+
+\tikzset{
+ path 1/.style={
+ red,
+ },
+}
+
+\foreach[count=\k] \cpt in \components {
+ \path[
+ draw,
+ path \k/.try,
+ spath/.cd,
+ translate=\cpt{0pt}{\k pt},
+ restore=\cpt,
+ ] +(0,3pt) -- +(0,-3pt);
+ \node[text=red] at (spath cs:{\cpt} .5) {\(\k\)};
+}
+\end{tikzpicture}
+\end{example}
+
+\item Intersections.
+
+One of the main motivations for implementing the intersection routines was to provide a different way of drawing knots and links and similar diagrams.
+
+\begin{enumerate}
+
+\item Define the two paths for the braid (usually these will be defined with |\path|).
+\begin{example}
+\begin{tikzpicture}[
+ use Hobby shortcut,
+]
+\draw[spath/save global=pathA] (0,0) to[out=0,in=180] ++(2,1) to[out=0,in=180] ++(2,-1) to[out=0,in=180] ++(2,1) to[out=0,in=180] ++(2,-1);
+\draw[spath/save global=pathB] (0,1) to[out=0,in=180] ++(2,-1) to[out=0,in=180] ++(2,1) to[out=0,in=180] ++(2,-1) to[out=0,in=180] ++(2,1);
+\end{tikzpicture}
+\end{example}
+
+\item Split the paths at their mutual intersections and render them with a count of the components.
+
+\begin{example}
+\begin{tikzpicture}
+\tikzset{
+ spath/.cd,
+ split at intersections={pathA}{pathB},
+ get components of={pathA}\pathAcomponents,
+ get components of={pathB}\pathBcomponents,
+}
+
+\foreach[count=\k] \cpt in \pathAcomponents {
+ \draw[spath/restore=\cpt,-Circle];
+ \node[fill=white, fill opacity=.5, circle, text opacity=1] at (spath cs:{\cpt} .5) {\(\k\)};
+}
+
+\foreach[count=\k] \cpt in \pathBcomponents {
+ \draw[spath/restore=\cpt,-Circle];
+ \node[fill=white, fill opacity=.5, circle, text opacity=1] at (spath cs:{\cpt} .5) {\(\k\)};
+}
+\end{tikzpicture}
+\end{example}
+
+\item Now we insert gaps after certain components in each path and then render the components.
+To show that the gaps are genuine, we use a patterned background.
+Although the paths were defined globally, the splitting in the previous example was local so we need to repeat it in this one.
+
+\begin{example}
+\begin{tikzpicture}
+\tikzset{
+ spath/.cd,
+ split at intersections={pathA}{pathB},
+ insert gaps after components={pathA}{5pt}{1,3},
+ join components={pathA}{3,5},
+ get components of={pathA}\pathAcomponents,
+ insert gaps after components={pathB}{5pt}{2,4},
+ join components={pathB}{2,4},
+ get components of={pathB}\pathBcomponents,
+}
+
+\fill[red!50!white] (-.5,-.5) rectangle (8.5,1.5);
+\fill[pattern=bricks, pattern color=white] (-.5,-.5) rectangle (8.5,1.5);
+
+\foreach[count=\k] \cpt in \pathAcomponents {
+ \draw[blue, line width=2pt,spath/restore=\cpt];
+ \node[fill=cyan, fill opacity=.5, circle, text opacity=1] at (spath cs:{\cpt} .3) {\(\k\)};
+}
+
+\foreach[count=\k] \cpt in \pathBcomponents {
+ \draw[green, line width=2pt,spath/restore=\cpt];
+ \node[fill=green!50, fill opacity=.5, circle, text opacity=1] at (spath cs:{\cpt} .3) {\(\k\)};
+}
+\end{tikzpicture}
+\end{example}
+\end{enumerate}
+
+\item This example is notable because many of the intersection points are where segments of the path end, showing that the algorithm works well even in this circumstance.
+
+\begin{enumerate}
+\item Here's the original path.
+\begin{example}
+\begin{tikzpicture}
+\draw[spath/save global=spiral] (5,0) -- (2.5,0) -- ++(0,-.25) -- ++(-2.5,0)
+arc[radius=2.25cm,start angle=180,end angle=90]
+arc[radius=2cm,start angle=90, delta angle=-180]
+arc[radius=1.75cm,start angle=-90, delta angle=-180]
+arc[radius=1.5cm,start angle=90, delta angle=-180]
+arc[radius=1.25cm,start angle=-90, delta angle=-180]
+arc[radius=1cm,start angle=90, delta angle=-180]
+arc[radius=.75cm,start angle=-90, delta angle=-180]
+arc[radius=.5cm,start angle=90, delta angle=-180]
+;
+\end{tikzpicture}
+\end{example}
+
+\item This renders labels on each component after splitting.
+\begin{example}
+\begin{tikzpicture}
+\tikzset{
+ spath/.cd,
+ split at self intersections=spiral,
+ get components of={spiral}\pathcomponents,
+}
+
+\foreach[count=\k] \cpt in \pathcomponents {
+ \draw[spath/restore=\cpt,-|];
+ \node[fill=white, fill opacity=.5, circle, text opacity=1] at (spath cs:{\cpt} .5) {\(\k\)};
+}
+\end{tikzpicture}
+\end{example}
+
+\item Finally, we put the gaps in where we want them.
+
+\begin{example}
+\begin{tikzpicture}
+\tikzset{
+ spath/.cd,
+ split at self intersections=spiral,
+ insert gaps after components={spiral}{10pt}{1,3,5,7,10,11,14},
+ spot weld=spiral,
+ get components of={spiral}\pathcomponents,
+}
+
+\foreach[count=\k] \cpt in \pathcomponents {
+ \draw[blue, line width=2pt,spath/restore=\cpt];
+}
+\end{tikzpicture}
+\end{example}
+\end{enumerate}
+
+\item Here's a trefoil knot, demonstrating the \texttt{knot} style that simplifies creating knots.
+\begin{example}
+\begin{tikzpicture}[
+ use Hobby shortcut,
+ every trefoil component/.style={ultra thick, draw, red},
+ trefoil component 1/.style={blue},
+]
+\path[spath/save=trefoil] ([closed]90:2) foreach \k in {1,...,3} { .. (-30+\k*240:.5) .. (90+\k*240:2) } (90:2);
+\tikzset{spath/knot={trefoil}{8pt}{1,3,5}}
+\end{tikzpicture}
+\end{example}
+\end{enumerate}
+ \end{document}
diff --git a/graphics/pgf/contrib/spath3/spath3_code.dtx b/graphics/pgf/contrib/spath3/spath3_code.dtx
new file mode 100644
index 0000000000..c5c584c4f8
--- /dev/null
+++ b/graphics/pgf/contrib/spath3/spath3_code.dtx
@@ -0,0 +1,6719 @@
+% \iffalse meta-comment
+%<*internal>
+\iffalse
+%</internal>
+%<*readme>
+----------------------------------------------------------------
+spath3 --- LaTeX3 functions for manipulating PGF soft paths
+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 some functions used to manipulate PGFs soft paths.
+As applications of its use, included are a package for drawing calligraphic paths and a package for drawing knot diagrams.
+%</readme>
+%<*internal>
+\fi
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+%</internal>
+%<*install>
+\input l3docstrip.tex
+\keepsilent
+\askforoverwritefalse
+\preamble
+----------------------------------------------------------------
+spath3 --- Functions for manipulating PGF soft paths
+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) 2011-2019 by Andrew Stacey <loopspace@mathforge.org>
+
+This work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License (LPPL), either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in the file:
+
+http://www.latex-project.org/lppl.txt
+
+This work is "maintained" (as per LPPL maintenance status) by
+Andrew Stacey.
+
+This work consists of the files spath3.dtx
+ calligraphy_doc.tex
+ knots_doc.tex
+ spath3.tex
+and the derived files spath3.ins,
+ spath3_code.pdf,
+ spath3.sty,
+ tikzlibrarycalligraphy.code.tex
+ tikzlibraryknots.code.tex
+ tikzlibraryspath3.code.tex
+ calligraphy.pdf
+ knots.pdf
+ spath3.pdf
+ README
+
+\endpostamble
+\usedir{tex/latex/spath3}
+\generate{
+ \file{spath3.sty}{\from{\jobname.dtx}{spath3}}
+}
+\generate{
+ \file{tikzlibrarycalligraphy.code.tex}{\from{\jobname.dtx}{calligraphy}}
+}
+\generate{
+ \file{tikzlibraryknots.code.tex}{\from{\jobname.dtx}{knots}}
+}
+\generate{
+ \file{tikzlibraryspath3.code.tex}{\from{\jobname.dtx}{tikzspath3}}
+}
+%</install>
+%<install>\endbatchfile
+%<*internal>
+\usedir{source/latex/spath3}
+\generate{
+ \file{\jobname.ins}{\from{\jobname.dtx}{install}}
+}
+\nopreamble\nopostamble
+\usedir{doc/latex/demopkg}
+\generate{
+ \file{README.txt}{\from{\jobname.dtx}{readme}}
+}
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+%</internal>
+%<*driver>
+\documentclass[full]{l3doc}
+\usepackage[T1]{fontenc}
+\usepackage{lmodern}
+%\usepackage{morefloats}
+\usepackage{tikz}
+\usepackage{trace}
+\usepackage{spath3}
+%\traceoff
+%\usepackage[numbered]{hypdoc}
+\definecolor{lstbgcolor}{rgb}{0.9,0.9,0.9}
+
+\usepackage{listings}
+\lstloadlanguages{[LaTeX]TeX}
+\lstset{
+ breakatwhitespace=true,
+ breaklines=true,
+ language=[LaTeX]TeX,
+ basicstyle=\small\ttfamily,
+ keepspaces=true,
+ columns=fullflexible
+}
+
+\usepackage{fancyvrb}
+
+\newenvironment{example}
+ {\VerbatimEnvironment
+ \begin{VerbatimOut}[gobble=2]{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}
+}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{6848}
+%
+% \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{1.0}{2011/05/03}{Converted to DTX file}
+% \changes{1.1}{2016/02/19}{Fixes due to changes in LaTeX3}
+% \changes{1.2}{2019/02/12}{More fixes due to changes in LaTeX3}
+% \changes{1.4}{2020/12/18}{A fair amount of code reimplementation and reorganisation, together with defining TikZ keys to make functions available for use.}
+% \changes{2.0}{2021/01/19}{Refactored the code to remove the OO approach and make it functional, introduced the spath3 TikZ library to provide a user interface.}
+%
+% \DoNotIndex{\newcommand,\newenvironment}
+%
+% \providecommand*{\url}{\texttt}
+% \GetFileInfo{spath3.sty}
+% \title{The \textsf{spath3} package: code}
+% \author{Andrew Stacey \\ \url{loopspace@mathforge.org}}
+% \date{\fileversion~from \filedate}
+%
+%
+% \maketitle
+%
+%
+% \section{Introduction}
+%
+% The \Verb+spath3+ package is intended as a library for manipulating PGF's \emph{soft paths}.
+% In between defining a path and using it, PGF stores a path as a \emph{soft path} where all the defining structure has been resolved into the basic operations but these have not yet been written to the output file.
+% They can therefore still be manipulated by \TeX, and as they have a very rigid form (and limited vocabulary), they are relatively easy to modify.
+% This package provides some methods for working with these paths.
+% It was originally not really intended for use by end users but as a foundation on which other packages can be built.
+% However, over the years I've found myself using it at ever higher levels and so a set of interfaces has been designed using TikZ keys.
+%
+% It also provides the engine that drives a few other packages, such as the \Verb+calligraphy+, \Verb+knot+, and \Verb+penrose+ packages.
+% The first two of these are subpackages of this one.
+% The \Verb+calligraphy+ package simulates a calligraphic pen stroking a path.
+% The \Verb+knots+ package can be used to draw knot (and similar) diagrams.
+%
+% For usage, see the documentation of the following packages (\Verb+texdoc <package>+):
+%
+% \begin{itemize}
+% \item \Verb+calligraphy+
+% \item \Verb+knots+
+% \item \Verb+penrose+
+% \item \Verb+spath3+ (\emph{this} document is the code, there's another which focusses on usage)
+% \end{itemize}
+%
+% \section{Technical Details}
+%
+% The format of a soft path is a sequence of triples of the form \Verb+\macro {dimension}{dimension}+.
+% The macro is one of a short list, the dimensions are coordinates in points.
+% There are certain further restrictions, particularly that every path must begin with a \Verb+move to+, and B\'ezier curves consist of three triples.
+%
+% In the original implementation, I wrapped this token list in a \Verb+prop+ to store useful information along with the path.
+% Over time, this additional structure has proved a little unwieldy and I've pared it back to working primarily with the original soft path as a token list.
+%
+% A frequent use of this package is to break a path into pieces and do something with each of those pieces.
+% To that end, there are various words that I use to describe the levels of the structure of a path.
+%
+% At the top level is the path itself.
+% At the bottom level are the triples of the form \Verb+\macro{dim}{dim}+, as described above.
+% In between these are the \emph{segments} and \emph{components}.
+%
+% A \emph{segment} is a minimal drawing piece.
+% Thus it might be a straight line or a B\'ezier curve.
+% When a path is broken into segments then each segment is a complete path so it isn't simply a selection of triples from the original path.
+%
+% A \emph{component} is a minimal connected section of the path.
+% So every component starts with a move command and continues until the next move command.
+% For ease of implementation (and to enable a copperplate pen in the calligraphy package!), an isolated move is considered as a component.
+% Thus the following path consists of three components:
+%
+% \begin{Verbatim}
+% \path (0,0) -- (1,0) (2,0) (3,0) to[out=0,in=90] (4,0);
+% \end{Verbatim}
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \iffalse
+%<*spath3>
+% \fi
+% \subsection{Initialisation}
+%
+% \begin{macrocode}
+%<@@=spath>
+% \end{macrocode}
+%
+% Load the \LaTeX3 foundation and register us as a \LaTeX3\ package.
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+\RequirePackage{expl3}
+\RequirePackage{pgf}
+\ProvidesExplPackage {spath3} {2021/01/19} {2.0} {Functions for
+manipulating PGF soft paths}
+\RequirePackage{xparse}
+% \end{macrocode}
+%
+% Utilities copied from \url{https://github.com/loopspace/LaTeX3-Utilities} for adding something in braces to a token list.
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_tl_put_right_braced:Nn
+{
+ \tl_put_right:Nn #1 { { #2 } }
+}
+\cs_generate_variant:Nn \@@_tl_put_right_braced:Nn { NV, cV, cv, Nx, cx }
+
+\cs_new_protected:Nn \@@_tl_gput_right_braced:Nn
+{
+ \tl_gput_right:Nn #1 { { #2 } }
+}
+\cs_generate_variant:Nn \@@_tl_gput_right_braced:Nn { NV, cV, cv, Nx, cx }
+\cs_new_protected:Nn \@@_tl_put_left_braced:Nn
+{
+ \tl_put_left:Nn #1 { { #2 } }
+}
+\cs_generate_variant:Nn \@@_tl_put_left_braced:Nn { NV, cV, cv, Nx, cx }
+
+\cs_new_protected:Nn \@@_tl_gput_left_braced:Nn
+{
+ \tl_gput_left:Nn #1 { { #2 } }
+}
+\cs_generate_variant:Nn \@@_tl_gput_left_braced:Nn { NV, cV, cv, Nx, cx }
+% \end{macrocode}
+%
+% We need a slew of temporary variables.
+% \begin{macrocode}
+\tl_new:N \l_@@_tmpa_tl
+\tl_new:N \l_@@_tmpb_tl
+\tl_new:N \l_@@_tmpc_tl
+\tl_new:N \l_@@_tmpd_tl
+\tl_new:N \l_@@_tmpe_tl
+
+\seq_new:N \l_@@_tmpa_seq
+\seq_new:N \l_@@_tmpb_seq
+
+\tl_new:N \g_@@_output_tl
+\int_new:N \g_@@_output_int
+\seq_new:N \g_@@_output_seq
+
+\dim_new:N \l_@@_tmpa_dim
+\dim_new:N \l_@@_tmpb_dim
+\dim_new:N \l_@@_move_x_dim
+\dim_new:N \l_@@_move_y_dim
+\fp_new:N \l_@@_tmpa_fp
+\fp_new:N \l_@@_tmpb_fp
+\int_new:N \l_@@_tmpa_int
+
+\bool_new:N \g_@@_output_bool
+\bool_new:N \l_@@_closed_bool
+% \end{macrocode}
+%
+% We need to be able to compare against the macros that can occur in a soft path so these token lists contain them.
+% These are global constants so that they can be used in other packages.
+% \begin{macrocode}
+\tl_const:Nn \c_spath_moveto_tl {\pgfsyssoftpath@movetotoken}
+\tl_const:Nn \c_spath_lineto_tl {\pgfsyssoftpath@linetotoken}
+\tl_const:Nn \c_spath_curveto_tl {\pgfsyssoftpath@curvetotoken}
+\tl_const:Nn \c_spath_curvetoa_tl {\pgfsyssoftpath@curvetosupportatoken}
+\tl_const:Nn \c_spath_curvetob_tl {\pgfsyssoftpath@curvetosupportbtoken}
+\tl_const:Nn \c_spath_closepath_tl {\pgfsyssoftpath@closepathtoken}
+% \end{macrocode}
+%
+%
+% We will want to be able to use anonymous spaths internally, so we create a global counter that we can use to refer to them.
+% \begin{macrocode}
+\int_new:N \g_@@_anon_int
+\int_gzero:N \g_@@_anon_int
+% \end{macrocode}
+%
+% Groups and iterations don't mix well and I haven't got a good scheme for protecting local calculations when iterating, so we do our best with iteration-specific variables.
+% \begin{macrocode}
+\tl_new:N \l_@@_itera_tl
+\tl_new:N \l_@@_iterb_tl
+\tl_new:N \l_@@_iterc_tl
+\tl_new:N \l_@@_iterd_tl
+\tl_new:N \l_@@_iterp_tl
+\dim_new:N \l_@@_itera_dim
+\dim_new:N \l_@@_iterb_dim
+\seq_new:N \l_@@_iter_seq
+% \end{macrocode}
+%
+% And some error messages
+% \begin{macrocode}
+\msg_new:nnn { spath3 } { unknown path construction } { The~ path~ construction~ element~ #1~ is~ not~ currently~ supported.}
+% \end{macrocode}
+%
+%
+% \subsection{Functional Implementation}
+%
+% In the functional approach, we start with a token list containing a soft path and do something to it (either calculate some information or manipulate it in some fashion).
+% We then store that information, or the manipulated path, in an appropriate macro.
+% The macro to store it in is the first argument.
+% These functions occur in two versions, the one with the \texttt{g} makes the assignment global.
+%
+% \begin{macro}{
+% \spath_segments_to_seq:Nn,
+% \spath_segments_gto_seq:Nn
+%}
+% Splits a soft path into \emph{segments}, storing the result in a sequence.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_segments_to_seq:n #1
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_itera_tl {#1}
+ \tl_clear:N \l_@@_iterb_tl
+ \seq_clear:N \l_@@_iter_seq
+ \dim_zero:N \l_@@_itera_dim
+ \dim_zero:N \l_@@_iterb_dim
+
+ \bool_until_do:nn {
+ \tl_if_empty_p:N \l_@@_itera_tl
+ }
+ {
+ \tl_set:Nx \l_@@_iterc_tl {\tl_head:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_case:NnF \l_@@_iterc_tl
+ {
+ \c_spath_moveto_tl
+ {
+ \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
+ \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+
+ \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
+ \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+
+ \tl_set:Nx \l_@@_iterd_tl {\tl_head:N \l_@@_itera_tl}
+ \tl_if_eq:NNF \l_@@_iterd_tl \c_spath_moveto_tl
+ {
+ \tl_clear:N \l_@@_iterb_tl
+ }
+
+ }
+
+ \c_spath_lineto_tl
+ {
+ \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_iterb_tl
+ {
+ {\dim_use:N \l_@@_itera_dim}
+ {\dim_use:N \l_@@_iterb_dim}
+ }
+ \tl_put_right:NV \l_@@_iterb_tl \c_spath_lineto_tl
+
+ \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
+ \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+
+ \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
+ \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+
+ }
+
+ \c_spath_curvetoa_tl
+ {
+ \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_iterb_tl
+ {
+ {\dim_use:N \l_@@_itera_dim}
+ {\dim_use:N \l_@@_iterb_dim}
+ }
+ \tl_put_right:NV \l_@@_iterb_tl \c_spath_curvetoa_tl
+
+ \prg_replicate:nn {2} {
+ \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_put_right:Nx \l_@@_iterb_tl {\tl_head:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ }
+
+ \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
+ \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+
+ \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
+ \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+
+ }
+
+ \c_spath_closepath_tl
+ {
+ \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_iterb_tl
+ {
+ {\dim_use:N \l_@@_itera_dim}
+ {\dim_use:N \l_@@_iterb_dim}
+ }
+ \tl_put_right:NV \l_@@_iterb_tl \c_spath_lineto_tl
+
+ \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
+ \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+
+ \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
+ \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+
+ }
+
+ }
+ {
+
+ \tl_set_eq:NN \l_@@_iterb_tl \l_@@_iterc_tl
+ \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
+ \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+
+ \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
+ \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+
+ }
+
+ \tl_if_empty:NF \l_@@_iterb_tl
+ {
+ \seq_put_right:NV \l_@@_iter_seq \l_@@_iterb_tl
+ }
+ \tl_clear:N \l_@@_iterb_tl
+ }
+
+ \seq_gclear:N \g_@@_output_seq
+ \seq_gset_eq:NN \g_@@_output_seq \l_@@_iter_seq
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_segments_to_seq:Nn #1#2
+{
+ \@@_segments_to_seq:n {#2}
+ \seq_clear_new:N #1
+ \seq_set_eq:NN #1 \g_@@_output_seq
+ \seq_gclear:N \g_@@_output_seq
+}
+\cs_generate_variant:Nn \spath_segments_to_seq:Nn {NV, cn, cV, Nv, cv}
+\cs_new_protected_nopar:Npn \spath_segments_gto_seq:Nn #1#2
+{
+ \@@_segments_to_seq:n {#2}
+ \seq_clear_new:N #1
+ \seq_gset_eq:NN #1 \g_@@_output_seq
+ \seq_gclear:N \g_@@_output_seq
+}
+\cs_generate_variant:Nn \spath_segments_gto_seq:Nn {NV, cn, cV, Nv, cv}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_components_to_seq:Nn,
+% \spath_components_gto_seq:Nn,
+% \spath_components_to_clist:Nn,
+% \spath_components_gto_clist:Nn,
+% }
+% Splits a soft path into \emph{components}, storing the result in a sequence or a clist.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_components_to_seq:n #1
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_itera_tl {#1}
+ \seq_clear:N \l_@@_iter_seq
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_put_right:NV \l_@@_itera_tl \c_spath_moveto_tl
+ \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl
+ \bool_do_until:nn {
+ \tl_if_empty_p:N \l_@@_itera_tl
+ }
+ {
+ \tl_set:Nx \l_@@_iterc_tl {\tl_head:N \l_@@_itera_tl}
+ \tl_if_eq:NNT \l_@@_iterc_tl \c_spath_moveto_tl
+ {
+ \seq_put_right:NV \l_@@_iter_seq \l_@@_iterb_tl
+ \tl_clear:N \l_@@_iterb_tl
+ }
+ \tl_if_single:NTF \l_@@_iterc_tl
+ {
+ \tl_put_right:NV \l_@@_iterb_tl \l_@@_iterc_tl
+ }
+ {
+ \tl_put_right:Nx \l_@@_iterb_tl {{\l_@@_iterc_tl}}
+ }
+ \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ }
+
+ \seq_gclear:N \g_@@_output_seq
+ \seq_gset_eq:NN \g_@@_output_seq \l_@@_iter_seq
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_components_to_seq:Nn #1#2
+{
+ \@@_components_to_seq:n {#2}
+ \seq_clear_new:N #1
+ \seq_set_eq:NN #1 \g_@@_output_seq
+ \seq_gclear:N \g_@@_output_seq
+}
+\cs_generate_variant:Nn \spath_components_to_seq:Nn {NV, cn, cV, cv, Nv}
+\cs_new_protected_nopar:Npn \spath_components_gto_seq:Nn #1#2
+{
+ \@@_components_to_seq:n {#2}
+ \seq_clear_new:N #1
+ \seq_gset_eq:NN #1 \g_@@_output_seq
+ \seq_gclear:N \g_@@_output_seq
+}
+\cs_generate_variant:Nn \spath_components_gto_seq:Nn {NV, cn, cV, cv, Nv}
+\cs_new_protected_nopar:Npn \spath_components_to_clist:Nn #1#2
+{
+ \@@_components_to_seq:n {#2}
+ \clist_clear_new:N #1
+ \clist_set_from_seq:NN #1 \g_@@_output_seq
+ \seq_gclear:N \g_@@_output_seq
+}
+\cs_generate_variant:Nn \spath_components_to_clist:Nn {NV, cn, cV, cv, Nv}
+\cs_new_protected_nopar:Npn \spath_components_gto_clist:Nn #1#2
+{
+ \@@_components_to_seq:n {#2}
+ \clist_clear_new:N #1
+ \clist_gset_from_seq:NN #1 \g_@@_output_seq
+ \seq_gclear:N \g_@@_output_seq
+}
+\cs_generate_variant:Nn \spath_components_gto_clist:Nn {NV, cn, cV, cv, Nv}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\spath_length:n}
+% Counts the number of triples in the path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_length:n #1
+{
+ \int_eval:n {\tl_count:n {#1} / 3}
+}
+\cs_generate_variant:Nn \spath_length:n {V}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_reallength:Nn,
+% \spath_greallength:Nn
+% }
+% The real length of a path is the number of triples that actually draw something (that is, the number of lines, curves, and closepaths).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_reallength:n #1
+{
+ \group_begin:
+ \int_set:Nn \l_@@_tmpa_int {0}
+ \tl_map_inline:nn {#1} {
+ \tl_set:Nn \l_@@_tmpc_tl {##1}
+ \tl_case:NnT \l_@@_tmpc_tl
+ {
+ \c_spath_lineto_tl {}
+ \c_spath_curveto_tl {}
+ \c_spath_closepath_tl {}
+ }
+ {
+ \int_incr:N \l_@@_tmpa_int
+ }
+ }
+ \int_gzero:N \g_@@_output_int
+ \int_gset_eq:NN \g_@@_output_int \l_@@_tmpa_int
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_reallength:Nn #1#2
+{
+ \@@_reallength:n {#2}
+ \int_set_eq:NN #1 \g_@@_output_int
+ \int_gzero:N \g_@@_output_int
+}
+\cs_generate_variant:Nn \spath_reallength:Nn {NV, cn, cV, Nv, cv}
+\cs_new_protected_nopar:Npn \spath_greallength:Nn #1#2
+{
+ \@@_reallength:n {#2}
+ \int_gset_eq:NN #1 \g_@@_output_int
+ \int_gzero:N \g_@@_output_int
+}
+\cs_generate_variant:Nn \spath_greallength:Nn {NV, cn, cV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_numberofcomponents:Nn,
+% \spath_gnumberofcomponents:Nn
+% }
+% A component is a continuous segment of the path, separated by moves.
+% Successive moves are not collapsed, and zero length moves count.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_numberofcomponents:n #1
+{
+ \group_begin:
+ \int_set:Nn \l_@@_tmpa_int {0}
+ \tl_map_inline:nn {#1} {
+ \tl_set:Nn \l_@@_tmpa_tl {##1}
+ \tl_case:Nn \l_@@_tmpa_tl
+ {
+ \c_spath_moveto_tl
+ {
+ \int_incr:N \l_@@_tmpa_int
+ }
+ }
+ }
+ \int_gzero:N \g_@@_output_int
+ \int_gset_eq:NN \g_@@_output_int \l_@@_tmpa_int
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_numberofcomponents:Nn #1#2
+{
+ \@@_numberofcomponents:n {#2}
+ \int_set_eq:NN #1 \g_@@_output_int
+ \int_gzero:N \g_@@_output_int
+}
+\cs_generate_variant:Nn \spath_numberofcomponents:Nn {NV, cn, cV}
+\cs_new_protected_nopar:Npn \spath_gnumberofcomponents:Nn #1#2
+{
+ \@@_numberofcomponents:n {#2}
+ \int_gset_eq:NN #1 \g_@@_output_int
+ \int_gzero:N \g_@@_output_int
+}
+\cs_generate_variant:Nn \spath_gnumberofcomponents:Nn {NV, cn, cV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_initialpoint:Nn,
+% \spath_ginitialpoint:Nn
+% }
+% The starting point of the path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_initialpoint:n #1
+{
+ \group_begin:
+ \tl_clear:N \l_@@_tmpb_tl
+ \tl_set:Nx \l_@@_tmpb_tl
+ {
+ { \tl_item:nn {#1} {2} }
+ { \tl_item:nn {#1} {3} }
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_initialpoint:Nn #1#2
+{
+ \@@_initialpoint:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_initialpoint:Nn {NV, cn, cV, Nv}
+\cs_new_protected_nopar:Npn \spath_ginitialpoint:Nn #1#2
+{
+ \@@_initialpoint:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_ginitialpoint:Nn {NV, cn, cV, Nv}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_finalpoint:Nn,
+% \spath_gfinalpoint:Nn,
+% }
+% The final point of the path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_finalpoint:n #1
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_reverse:N \l_@@_tmpa_tl
+ \tl_clear:N \l_@@_tmpb_tl
+ \tl_set:Nx \l_@@_tmpb_tl
+ {
+ { \tl_item:Nn \l_@@_tmpa_tl {2} }
+ { \tl_item:Nn \l_@@_tmpa_tl {1} }
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_finalpoint:Nn #1#2
+{
+ \@@_finalpoint:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_finalpoint:Nn {NV, cn, cV, Nv}
+\cs_new_protected_nopar:Npn \spath_gfinalpoint:Nn #1#2
+{
+ \@@_finalpoint:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gfinalpoint:Nn {NV, cn, cV, Nv}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_reverse:Nn,
+% \spath_greverse:Nn
+% }
+% This computes the reverse of the path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_reverse:n #1
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+
+ \tl_clear:N \l_@@_tmpb_tl
+ \tl_clear:N \l_@@_tmpd_tl
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \tl_put_left:Nx \l_@@_tmpd_tl
+ {
+ {\dim_use:N \l_@@_tmpa_dim}
+ {\dim_use:N \l_@@_tmpb_dim}
+ }
+
+ \bool_set_false:N \l_@@_closed_bool
+
+ \bool_until_do:nn {
+ \tl_if_empty_p:N \l_@@_tmpa_tl
+ }
+ {
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_tmpa_tl}
+
+ \tl_case:NnTF \l_@@_tmpc_tl
+ {
+ \c_spath_moveto_tl {
+
+ \bool_if:NT \l_@@_closed_bool
+ {
+ \tl_put_right:NV \l_@@_tmpd_tl \c_spath_closepath_tl
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpd_tl}
+ \tl_put_right:Nx \l_@@_tmpd_tl
+ {
+ { \tl_head:N \l_@@_tmpd_tl }
+ { \tl_head:N \l_@@_tmpe_tl }
+ }
+ }
+ \bool_set_false:N \l_@@_closed_bool
+ \tl_put_left:NV \l_@@_tmpd_tl \c_spath_moveto_tl
+ \tl_put_left:NV \l_@@_tmpb_tl \l_@@_tmpd_tl
+ \tl_clear:N \l_@@_tmpd_tl
+ }
+ \c_spath_lineto_tl {
+ \tl_put_left:NV \l_@@_tmpd_tl \c_spath_lineto_tl
+ }
+ \c_spath_curveto_tl {
+ \tl_put_left:NV \l_@@_tmpd_tl \c_spath_curvetoa_tl
+ }
+ \c_spath_curvetoa_tl {
+ \tl_put_left:NV \l_@@_tmpd_tl \c_spath_curveto_tl
+ }
+ \c_spath_curvetob_tl {
+ \tl_put_left:NV \l_@@_tmpd_tl \c_spath_curvetob_tl
+ }
+ }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \tl_put_left:Nx \l_@@_tmpd_tl
+ {
+ {\dim_use:N \l_@@_tmpa_dim}
+ {\dim_use:N \l_@@_tmpb_dim}
+ }
+
+ }
+ {
+ \tl_if_eq:NNTF \l_@@_tmpc_tl \c_spath_closepath_tl
+ {
+ \bool_set_true:N \l_@@_closed_bool
+ }
+ {
+ \msg_warning:nnx { spath3 } { unknown path construction } {\l_@@_tmpc_tl }
+ }
+
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ }
+ }
+
+ \bool_if:NT \l_@@_closed_bool
+ {
+ \tl_put_right:NV \l_@@_tmpd_tl \c_spath_closepath_tl
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpd_tl}
+ \tl_put_right:Nx \l_@@_tmpd_tl
+ {
+ { \tl_head:N \l_@@_tmpd_tl }
+ { \tl_head:N \l_@@_tmpe_tl }
+ }
+ }
+
+ \bool_set_false:N \l_@@_closed_bool
+ \tl_put_left:NV \l_@@_tmpd_tl \c_spath_moveto_tl
+ \tl_put_left:NV \l_@@_tmpb_tl \l_@@_tmpd_tl
+
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_reverse:Nn #1#2
+{
+ \@@_reverse:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_reverse:Nn {NV, cn, cV, Nv}
+\cs_new_protected_nopar:Npn \spath_reverse:N #1
+{
+ \spath_reverse:NV #1#1
+}
+\cs_generate_variant:Nn \spath_reverse:N {c}
+\cs_new_protected_nopar:Npn \spath_greverse:Nn #1#2
+{
+ \@@_reverse:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_greverse:Nn {NV, cn, cV, Nv}
+\cs_new_protected_nopar:Npn \spath_greverse:N #1
+{
+ \spath_greverse:NV #1#1
+}
+\cs_generate_variant:Nn \spath_greverse:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_initialaction:Nn,
+% \spath_ginitialaction:Nn,
+% }
+% This is the first thing that the path does (after the initial move).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_initialaction:n #1
+{
+ \group_begin:
+ \tl_clear:N \l_@@_tmpa_tl
+ \int_compare:nT
+ {
+ \tl_count:n {#1} > 3
+ }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \tl_item:Nn {#1} {4}
+ }
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_initialaction:Nn #1#2
+{
+ \@@_initialaction:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_initialaction:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_ginitialaction:Nn #1#2
+{
+ \@@_initialaction:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_ginitialaction:Nn {NV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_finalaction:Nn,
+% \spath_gfinalaction:Nn
+% }
+% This is the last thing that the path does.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_finalaction:n #1
+{
+ \group_begin:
+ \tl_clear:N \l_@@_tmpb_tl
+ \int_compare:nT
+ {
+ \tl_count:n {#1} > 3
+ }
+ {
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_reverse:N \l_@@_tmpa_tl
+ \tl_set:Nx \l_@@_tmpb_tl
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {3}
+ }
+ \tl_if_eq:NNT \l_@@_tmpb_tl \c_spath_curvetoa_tl
+ {
+ \tl_set_eq:NN \l_@@_tmpb_tl \c_spath_curveto_tl
+ }
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_finalaction:Nn #1#2
+{
+ \@@_finalaction:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_finalaction:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_gfinalaction:Nn #1#2
+{
+ \@@_finalaction:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gfinalaction:Nn {NV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_minbb:Nn,
+% \spath_gminbb:Nn
+% }
+% This computes the minimum (bottom left) of the bounding box of the path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_minbb:n #1
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \bool_until_do:nn {
+ \tl_if_empty_p:N \l_@@_tmpa_tl
+ }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpa_dim {\dim_min:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpa_dim}}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpb_dim {\dim_min:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpb_dim}}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+ \tl_clear:N \l_@@_tmpb_tl
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_use:N \l_@@_tmpa_dim}
+ {\dim_use:N \l_@@_tmpb_dim}
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_minbb:Nn #1#2
+{
+ \@@_minbb:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_minbb:Nn {NV, cn, cV}
+\cs_new_protected_nopar:Npn \spath_gminbb:Nn #1#2
+{
+ \@@_minbb:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gminbb:Nn {NV, cn, cV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_maxbb:Nn,
+% \spath_gmaxbb:Nn,
+% }
+% This computes the maximum (top right) of the bounding box of the path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_maxbb:n #1
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \bool_until_do:nn {
+ \tl_if_empty_p:N \l_@@_tmpa_tl
+ }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpa_dim {\dim_max:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpa_dim}}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpb_dim {\dim_max:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpb_dim}}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+ \tl_clear:N \l_@@_tmpb_tl
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_use:N \l_@@_tmpa_dim}
+ {\dim_use:N \l_@@_tmpb_dim}
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_maxbb:Nn #1#2
+{
+ \@@_maxbb:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_maxbb:Nn {NV, cn, cV}
+\cs_new_protected_nopar:Npn \spath_gmaxbb:Nn #1#2
+{
+ \@@_maxbb:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gmaxbb:Nn {NV, cn, cV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_save_to_aux:Nn,
+% \spath_save_to_aux:N
+% }
+% This saves a soft path to the auxfile.
+% The first argument is the macro that will be assigned to the soft path when the aux file is read back in.
+% \begin{macrocode}
+\int_set:Nn \l_@@_tmpa_int {\char_value_catcode:n {`@}}
+\char_set_catcode_letter:N @
+\cs_new_protected_nopar:Npn \spath_save_to_aux:Nn #1#2 {
+ \tl_if_empty:nF {#2}
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_put_right:Nn \l_@@_tmpa_tl {
+ \ExplSyntaxOn
+ \tl_clear:N #1
+ \tl_set:Nn #1 {#2}
+ \ExplSyntaxOff
+ }
+ \protected@write\@auxout{}{
+ \tl_to_str:N \l_@@_tmpa_tl
+ }
+ }
+}
+\char_set_catcode:nn {`@} {\l_@@_tmpa_int}
+\cs_generate_variant:Nn \spath_save_to_aux:Nn {cn, cV, NV}
+\cs_new_protected_nopar:Npn \spath_save_to_aux:N #1
+{
+ \tl_if_exist:NT #1
+ {
+ \spath_save_to_aux:NV #1#1
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Path Manipulation}
+%
+% These functions all manipulate a soft path.
+% They come with a variety of different argument specifications.
+% As a general rule, the first argument is the macro in which to store the modified path, the second is the path to manipulate, and the rest are the information about what to do.
+% There is always a variant in which the path is specified by a macro and restored back in that same macro.
+%
+%
+% \begin{macro}{
+% \spath_translate:Nnnn,
+% \spath_translate:Nnn,
+% \spath_gtranslate:Nnnn,
+% \spath_gtranslate:Nnn
+% }
+% Translates a path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_translate:nnn #1#2#3
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_clear:N \l_@@_tmpb_tl
+ \bool_until_do:nn {
+ \tl_if_empty_p:N \l_@@_tmpa_tl
+ }
+ {
+ \tl_put_right:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl + #2}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl + #3}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_use:N \l_@@_tmpa_dim}
+ {\dim_use:N \l_@@_tmpb_dim}
+ }
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_translate:Nnnn #1#2#3#4
+{
+ \@@_translate:nnn {#2}{#3}{#4}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_translate:Nnnn {NVxx, NVVV, NVnn}
+\cs_new_protected_nopar:Npn \spath_translate:Nnn #1#2#3
+{
+ \spath_translate:NVnn #1#1{#2}{#3}
+}
+\cs_generate_variant:Nn \spath_translate:Nnn {NVV, cnn, cVV}
+\cs_new_protected_nopar:Npn \spath_gtranslate:Nnnn #1#2#3#4
+{
+ \@@_translate:nnn {#2}{#3}{#4}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gtranslate:Nnnn {NVxx, NVVV, NVnn}
+\cs_new_protected_nopar:Npn \spath_gtranslate:Nnn #1#2#3
+{
+ \spath_gtranslate:NVnn #1#1{#2}{#3}
+}
+\cs_generate_variant:Nn \spath_gtranslate:Nnn {NVV, cnn, cVV}
+% \end{macrocode}
+%
+% This variant allows for passing the coordinates as a single braced group as it strips off the outer braces of the second argument.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_translate:Nn #1#2
+{
+ \spath_translate:Nnn #1 #2
+}
+\cs_generate_variant:Nn \spath_translate:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_gtranslate:Nn #1#2
+{
+ \spath_gtranslate:Nnn #1 #2
+}
+\cs_generate_variant:Nn \spath_gtranslate:Nn {NV}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{
+% \spath_scale:Nnnn,
+% \spath_scale:Nnn,
+% \spath_gscale:Nnnn,
+% \spath_gscale:Nnn
+% }
+% Scale a path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_scale:nnn #1#2#3
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_clear:N \l_@@_tmpb_tl
+ \bool_until_do:nn {
+ \tl_if_empty_p:N \l_@@_tmpa_tl
+ }
+ {
+ \tl_put_right:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \fp_set:Nn \l_@@_tmpa_fp {\tl_head:N \l_@@_tmpa_tl * #2}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \fp_set:Nn \l_@@_tmpb_fp {\tl_head:N \l_@@_tmpa_tl * #3}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\fp_to_dim:N \l_@@_tmpa_fp}
+ {\fp_to_dim:N \l_@@_tmpb_fp}
+ }
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_scale:Nnnn #1#2#3#4
+{
+ \@@_scale:nnn {#2}{#3}{#4}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_scale:Nnnn {NVnn, Nnxx}
+\cs_new_protected_nopar:Npn \spath_scale:Nnn #1#2#3
+{
+ \spath_scale:NVnn #1#1{#2}{#3}
+}
+\cs_generate_variant:Nn \spath_scale:Nnn {cnn, cVV, NVV}
+\cs_new_protected_nopar:Npn \spath_gscale:Nnnn #1#2#3#4
+{
+ \@@_scale:nnn {#2}{#3}{#4}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gscale:Nnnn {NVnn, Nnxx}
+\cs_new_protected_nopar:Npn \spath_gscale:Nnn #1#2#3
+{
+ \spath_gscale:NVnn #1#1{#2}{#3}
+}
+\cs_generate_variant:Nn \spath_gscale:Nnn {cnn, cVV, NVV}
+% \end{macrocode}
+%
+% This variant allows for passing the coordinates as a single braced group as it strips off the outer braces of the second argument.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_scale:Nn #1#2
+{
+ \spath_scale:Nnn #1 #2
+}
+
+\cs_generate_variant:Nn \spath_scale:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_gscale:Nn #1#2
+{
+ \spath_gscale:Nnn #1 #2
+}
+
+\cs_generate_variant:Nn \spath_gscale:Nn {NV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_transform:Nnnnnnnn,
+% \spath_transform:Nnnnnnn,
+% \spath_gtransform:Nnnnnnnn,
+% \spath_gtransform:Nnnnnnn,
+% }
+% Applies an affine (matrix and vector) transformation to path.
+% The matrix is specified in rows first.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_transform:nnnnnnn #1#2#3#4#5#6#7
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_clear:N \l_@@_tmpb_tl
+ \bool_until_do:nn {
+ \tl_if_empty_p:N \l_@@_tmpa_tl
+ }
+ {
+ \tl_put_right:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpd_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \fp_set:Nn \l_@@_tmpa_fp {\l_@@_tmpc_tl * #2 + \l_@@_tmpd_tl * #4 + #6}
+ \fp_set:Nn \l_@@_tmpb_fp {\l_@@_tmpc_tl * #3 + \l_@@_tmpd_tl * #5 + #7}
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\fp_to_dim:N \l_@@_tmpa_fp}
+ {\fp_to_dim:N \l_@@_tmpb_fp}
+ }
+ }
+
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_transform:Nnnnnnnn #1#2#3#4#5#6#7#8
+{
+ \@@_transform:nnnnnnn {#2}{#3}{#4}{#5}{#6}{#7}{#8}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_transform:Nnnnnnnn {NVnnnnnn, Nnxxxxxx, cnnnnnnn}
+\cs_new_protected_nopar:Npn \spath_transform:Nnnnnnn #1#2#3#4#5#6#7
+{
+ \spath_transform:NVnnnnnn #1#1{#2}{#3}{#4}{#5}{#6}{#7}
+}
+\cs_generate_variant:Nn \spath_transform:Nnnnnnn {cnnnnnn}
+\cs_new_protected_nopar:Npn \spath_transform:Nnn #1#2#3
+{
+ \spath_transform:Nnnnnnnn #1{#2}#3
+}
+\cs_generate_variant:Nn \spath_transform:Nnn {cnn, cVn, NVn, NnV}
+\cs_new_protected_nopar:Npn \spath_transform:Nn #1#2
+{
+ \spath_transform:NVnnnnnn #1#1#2
+}
+\cs_generate_variant:Nn \spath_transform:Nn {cn, cV, NV}
+
+\cs_new_protected_nopar:Npn \spath_gtransform:Nnnnnnnn #1#2#3#4#5#6#7#8
+{
+ \@@_transform:nnnnnnn {#2}{#3}{#4}{#5}{#6}{#7}{#8}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gtransform:Nnnnnnnn {NVnnnnnn, Nnxxxxxx, cnnnnnnn}
+\cs_new_protected_nopar:Npn \spath_gtransform:Nnnnnnn #1#2#3#4#5#6#7
+{
+ \spath_gtransform:NVnnnnnn #1#1{#2}{#3}{#4}{#5}{#6}{#7}
+}
+\cs_generate_variant:Nn \spath_gtransform:Nnnnnnn {cnnnnnn}
+\cs_new_protected_nopar:Npn \spath_gtransform:Nnn #1#2#3
+{
+ \spath_gtransform:Nnnnnnnn #1{#2}#3
+}
+\cs_generate_variant:Nn \spath_gtransform:Nnn {cnn, cVn, NVn, NnV}
+\cs_new_protected_nopar:Npn \spath_gtransform:Nn #1#2
+{
+ \spath_gtransform:NVnnnnnn #1#1#2
+}
+\cs_generate_variant:Nn \spath_gtransform:Nn {cn, cV, NV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_weld:Nnn,
+% \spath_weld:Nn,
+% \spath_gweld:Nnn,
+% \spath_gweld:Nn
+% }
+% This welds one path to another, moving the second so that its initial point coincides with the first's final point.
+% It is called a \emph{weld} because the initial move of the second path is removed.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_weld:nn #1#2
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_set:Nn \l_@@_tmpb_tl {#2}
+
+ \spath_finalpoint:NV \l_@@_tmpc_tl \l_@@_tmpa_tl
+ \spath_initialpoint:NV \l_@@_tmpd_tl \l_@@_tmpb_tl
+
+ \dim_set:Nn \l_@@_tmpa_dim
+ {
+ \tl_item:Nn \l_@@_tmpc_tl {1}
+ -
+ \tl_item:Nn \l_@@_tmpd_tl {1}
+ }
+ \dim_set:Nn \l_@@_tmpb_dim
+ {
+ \tl_item:Nn \l_@@_tmpc_tl {2}
+ -
+ \tl_item:Nn \l_@@_tmpd_tl {2}
+ }
+
+ \spath_translate:NVV \l_@@_tmpb_tl \l_@@_tmpa_dim \l_@@_tmpb_dim
+
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_tail:N \l_@@_tmpb_tl}
+ }
+
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_weld:Nnn #1#2#3
+{
+ \@@_weld:nn {#2}{#3}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_weld:Nnn {NVV,NVn}
+\cs_new_protected_nopar:Npn \spath_weld:Nn #1#2
+{
+ \spath_weld:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_weld:Nn {NV, Nv, cV, cv}
+\cs_new_protected_nopar:Npn \spath_gweld:Nnn #1#2#3
+{
+ \@@_weld:nn {#2}{#3}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gweld:Nnn {NVV, NVn}
+\cs_new_protected_nopar:Npn \spath_gweld:Nn #1#2
+{
+ \spath_gweld:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_gweld:Nn {NV, Nv, cV, cv}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{
+% \spath_append_no_move:Nnn,
+% \spath_append_no_move:Nn,
+% \spath_gappend_no_move:Nnn,
+% \spath_gappend_no_move:Nn,
+% }
+% Append the path from the second \Verb+spath+ to the first, removing
+% the adjoining move.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_append_no_move:nn #1#2
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_set:Nn \l_@@_tmpb_tl {#2}
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_tail:N \l_@@_tmpb_tl}
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_tail:N \l_@@_tmpb_tl}
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_tail:N \l_@@_tmpb_tl}
+
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_append_no_move:Nnn #1#2#3
+{
+ \@@_append_no_move:nn {#2}{#3}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_append_no_move:Nnn {NVV, NVn}
+\cs_new_protected_nopar:Npn \spath_append_no_move:Nn #1#2
+{
+ \spath_append_no_move:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_append_no_move:Nn {NV, cv}
+\cs_new_protected_nopar:Npn \spath_gappend_no_move:Nnn #1#2#3
+{
+ \@@_append_no_move:nn {#2}{#3}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gappend_no_move:Nnn {NVV, NVn}
+\cs_new_protected_nopar:Npn \spath_gappend_no_move:Nn #1#2
+{
+ \spath_gappend_no_move:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_gappend_no_move:Nn {NV, cv}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_append:Nnn,
+% \spath_append:Nn,
+% \spath_gappend:Nnn,
+% \spath_gappend:Nn,
+% }
+% Prepend the path from the second \Verb+spath+ to the first.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_append:Nnn #1#2#3
+{
+ \tl_set:Nn #1 {#2}
+ \tl_put_right:Nn #1 {#3}
+}
+\cs_generate_variant:Nn \spath_append:Nnn {NVV, NVn}
+\cs_new_protected_nopar:Npn \spath_append:Nn #1#2
+{
+ \spath_append:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_append:Nn {NV, Nv}
+\cs_new_protected_nopar:Npn \spath_gappend:Nnn #1#2#3
+{
+ \tl_gset:Nn #1 {#2}
+ \tl_gput_right:Nn #1 {#3}
+}
+\cs_generate_variant:Nn \spath_gappend:Nnn {NVV, NVn}
+\cs_new_protected_nopar:Npn \spath_gappend:Nn #1#2
+{
+ \spath_gappend:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_gappend:Nn {NV, Nv}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{
+% \spath_prepend_no_move:Nnn,
+% \spath_prepend_no_move:Nn,
+% \spath_gprepend_no_move:Nnn,
+% \spath_gprepend_no_move:Nn,
+% }
+% Prepend the path from the second \Verb+spath+ to the first, removing
+% the adjoining move.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_prepend_no_move:Nnn #1#2#3
+{
+ \spath_append_no_move:Nnn #1{#3}{#2}
+}
+\cs_generate_variant:Nn \spath_prepend_no_move:Nnn {NVV, NVn}
+\cs_new_protected_nopar:Npn \spath_prepend_no_move:Nn #1#2
+{
+ \spath_prepend_no_move:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_prepend_no_move:Nn {NV, cv}
+\cs_new_protected_nopar:Npn \spath_gprepend_no_move:Nnn #1#2#3
+{
+ \spath_gappend_no_move:Nnn #1{#3}{#2}
+}
+\cs_generate_variant:Nn \spath_gprepend_no_move:Nnn {NVV, NVn}
+\cs_new_protected_nopar:Npn \spath_gprepend_no_move:Nn #1#2
+{
+ \spath_gprepend_no_move:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_gprepend_no_move:Nn {NV, cv}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_prepend:Nnn,
+% \spath_prepend:Nn,
+% \spath_gprepend:Nnn,
+% \spath_gprepend:Nn
+% }
+% Prepend the path from the second \Verb+spath+ to the first.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_prepend:Nnn #1#2#3
+{
+ \spath_append:Nnn #1{#3}{#2}
+}
+\cs_generate_variant:Nn \spath_prepend:Nnn {NVV, NVn}
+\cs_new_protected_nopar:Npn \spath_prepend:Nn #1#2
+{
+ \spath_prepend:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_prepend:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_gprepend:Nnn #1#2#3
+{
+ \spath_gappend:Nnn #1{#3}{#2}
+}
+\cs_generate_variant:Nn \spath_gprepend:Nnn {NVV, NVn}
+\cs_new_protected_nopar:Npn \spath_gprepend:Nn #1#2
+{
+ \spath_gprepend:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_gprepend:Nn {NV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_bake_round:Nn,
+% \spath_bake_round:N,
+% \spath_gbake_round:Nn,
+% \spath_gbake_round:N
+% }
+%
+% The corner rounding routine is applied quite late in the process of building a soft path so this ensures that it is done.
+%
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_bake_round:n #1
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \pgf@@@@processround \l_@@_tmpa_tl\l_@@_tmpb_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_bake_round:Nn #1#2
+{
+ \@@_bake_round:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_bake_round:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_bake_round:N #1
+{
+ \spath_bake_round:NV #1#1
+}
+\cs_generate_variant:Nn \spath_bake_round:N {c}
+\cs_new_protected_nopar:Npn \spath_gbake_round:Nn #1#2
+{
+ \@@_bake_round:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gbake_round:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_gbake_round:N #1
+{
+ \spath_gbake_round:NV #1#1
+}
+\cs_generate_variant:Nn \spath_gbake_round:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_close:Nn,
+% \spath_close:N,
+% \spath_gclose:Nn,
+% \spath_gclose:N
+% }
+% Appends a close path to the end of the path.
+% For now, the point is the initial or final point (respectively).
+% To be future proof, it ought to be the point of the adjacent move to.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_close:n #1
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \spath_initialpoint:NV \l_@@_tmpb_tl \l_@@_tmpa_tl
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_closepath_tl
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_close:Nn #1#2
+{
+ \@@_close:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_close:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_close:N #1
+{
+ \spath_close:NV #1#1
+}
+\cs_generate_variant:Nn \spath_close:N {c}
+\cs_new_protected_nopar:Npn \spath_gclose:Nn #1#2
+{
+ \@@_close:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gclose:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_gclose:N #1
+{
+ \spath_gclose:NV #1#1
+}
+\cs_generate_variant:Nn \spath_gclose:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{
+% \spath_open:Nn,
+% \spath_open:N,
+% \spath_gopen:Nn,
+% \spath_gopen:N
+% }
+% Removes all close paths from the path, replacing them by \Verb+lineto+ if they move any distance.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_open:n #1
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_clear:N \l_@@_tmpb_tl
+ \bool_until_do:nn {
+ \tl_if_empty_p:N \l_@@_tmpa_tl
+ }
+ {
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \tl_case:NnF \l_@@_tmpc_tl
+ {
+ \c_spath_closepath_tl {
+
+ \bool_if:nF
+ {
+ \dim_compare_p:n
+ {
+ \l_@@_move_x_dim == \l_@@_tmpa_dim
+ }
+ &&
+ \dim_compare_p:n
+ {
+ \l_@@_move_y_dim == \l_@@_tmpb_dim
+ }
+ }
+ {
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_lineto_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl {
+ { \dim_use:N \l_@@_move_x_dim }
+ { \dim_use:N \l_@@_move_y_dim }
+ }
+ }
+
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+
+ \c_spath_moveto_tl {
+ \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpc_tl
+
+ \dim_set:Nn \l_@@_move_x_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_move_y_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \tl_put_right:Nx \l_@@_tmpb_tl {
+ { \dim_use:N \l_@@_move_x_dim }
+ { \dim_use:N \l_@@_move_y_dim }
+ }
+
+ \dim_set_eq:NN \l_@@_tmpa_dim \l_@@_move_x_dim
+ \dim_set_eq:NN \l_@@_tmpb_dim \l_@@_move_y_dim
+ }
+ }
+ {
+ \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpc_tl
+
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+
+ \tl_put_right:Nx \l_@@_tmpb_tl {
+ { \dim_use:N \l_@@_tmpa_dim }
+ { \dim_use:N \l_@@_tmpb_dim }
+ }
+ }
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_open:Nn #1#2
+{
+ \@@_open:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_open:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_open:N #1
+{
+ \spath_open:NV #1#1
+}
+\cs_new_protected_nopar:Npn \spath_gopen:Nn #1#2
+{
+ \@@_open:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gopen:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_gopen:N #1
+{
+ \spath_gopen:NV #1#1
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_remove_empty_components:Nn,
+% \spath_remove_empty_components:N,
+% \spath_gremove_empty_components:Nn,
+% \spath_gremove_empty_components:N
+% }
+% Remove any component that is simply a moveto.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_remove_empty_components:n #1
+{
+ \group_begin:
+ \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1}
+ \tl_clear:N \l_@@_tmpa_tl
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \int_compare:nF
+ {
+ \tl_count:n {##1} == 3
+ }
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {##1}
+ }
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_remove_empty_components:Nn #1#2
+{
+ \@@_remove_empty_components:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_remove_empty_components:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_remove_empty_components:N #1
+{
+ \spath_remove_empty_components:NV #1#1
+}
+\cs_generate_variant:Nn \spath_remove_empty_components:N {c}
+\cs_new_protected_nopar:Npn \spath_gremove_empty_components:Nn #1#2
+{
+ \@@_remove_empty_components:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gremove_empty_components:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_gremove_empty_components:N #1
+{
+ \spath_gremove_empty_components:NV #1#1
+}
+\cs_generate_variant:Nn \spath_gremove_empty_components:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\spath_if_eq:nn}
+% Test if two soft paths are equal, we allow a little tolerance on the calculations.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \spath_if_eq:nn #1#2 { T, F, TF }
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_set:Nn \l_@@_tmpb_tl {#2}
+ \bool_gset_true:N \g_@@_tmpa_bool
+ \int_compare:nNnTF {\tl_count:N \l_@@_tmpa_tl} = {\tl_count:N \l_@@_tmpb_tl}
+ {
+ \int_step_inline:nnnn {1} {3} {\tl_count:N \l_@@_tmpa_tl}
+ {
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_item:Nn \l_@@_tmpa_tl {##1}}
+ \tl_set:Nx \l_@@_tmpd_tl {\tl_item:Nn \l_@@_tmpb_tl {##1}}
+ \tl_if_eq:NNF \l_@@_tmpc_tl \l_@@_tmpd_tl
+ {
+ \bool_gset_false:N \g_@@_tmpa_bool
+ }
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpa_tl {##1+1}}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpb_tl {##1+1}}
+ \dim_compare:nF { \dim_abs:n { \l_@@_tmpa_dim - \l_@@_tmpb_dim} < 0.001pt }
+ {
+ \bool_gset_false:N \g_@@_tmpa_bool
+ }
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpa_tl {##1+2}}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpb_tl {##1+2}}
+ \dim_compare:nF { \dim_abs:n { \l_@@_tmpa_dim - \l_@@_tmpb_dim} < 0.001pt }
+ {
+ \bool_gset_false:N \g_@@_tmpa_bool
+ }
+ }
+ }
+ {
+ \bool_gset_false:N \g_@@_tmpa_bool
+ }
+ \group_end:
+ \bool_if:NTF \g_@@_tmpa_bool
+ {
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+}
+\prg_generate_conditional_variant:Nnn \spath_if_eq:nn {VV, Vn, nV, vv} {TF, T, F}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Splitting Commands}
+%
+% \begin{macro}{
+% \spath_split_curve:NNnn,
+% \spath_gsplit_curve:NNnn
+% }
+% Splits a Bezier cubic into pieces, storing the pieces in the first two arguments.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_split_curve:nn #1#2
+{
+ \group_begin:
+ \tl_set_eq:NN \l_@@_tmpa_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl {
+ {\tl_item:nn {#1} {2}}
+ {\tl_item:nn {#1} {3}}
+ }
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_curvetoa_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl
+ {
+ {\fp_to_dim:n
+ {
+ (1 - #2) * \tl_item:nn {#1} {2} + (#2) * \tl_item:nn {#1} {5}
+ }}
+ {\fp_to_dim:n
+ {
+ (1 - #2) * \tl_item:nn {#1} {3} + (#2) * \tl_item:nn {#1} {6}
+ }}
+ }
+
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_curvetob_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl
+ {
+ {\fp_to_dim:n
+ {
+ (1 - #2)^2 * \tl_item:nn {#1} {2} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {5} + (#2)^2 * \tl_item:nn {#1} {8}
+ }}
+ {\fp_to_dim:n
+ {
+ (1 - #2)^2 * \tl_item:nn {#1} {3} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {6} + (#2)^2 * \tl_item:nn {#1} {9}
+ }}
+ }
+
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_curveto_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl
+ {
+ {\fp_to_dim:n
+ {
+ (1 - #2)^3 * \tl_item:nn {#1} {2} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8} + (#2)^3 * \tl_item:nn {#1} {11}
+ }}
+ {\fp_to_dim:n
+ {
+ (1 - #2)^3 * \tl_item:nn {#1} {3} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9} + (#2)^3 * \tl_item:nn {#1} {12}
+ }}
+ }
+
+ \tl_gclear:N \g_@@_output_tl
+ \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_tmpa_tl
+
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_set_eq:NN \l_@@_tmpa_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl
+ {
+ {\fp_to_dim:n
+ {
+ (1 - #2)^3 * \tl_item:nn {#1} {2} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8} + (#2)^3 * \tl_item:nn {#1} {11}
+ }}
+ {\fp_to_dim:n
+ {
+ (1 - #2)^3 * \tl_item:nn {#1} {3} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9} + (#2)^3 * \tl_item:nn {#1} {12}
+ }}
+ }
+
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_curvetoa_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl
+ {
+ {\fp_to_dim:n
+ {
+ (1 - #2)^2 * \tl_item:nn {#1} {5} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {8} + (#2)^2 * \tl_item:nn {#1} {11}
+ }}
+ {\fp_to_dim:n
+ {
+ (1 - #2)^2 * \tl_item:nn {#1} {6} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {9} + (#2)^2 * \tl_item:nn {#1} {12}
+ }}
+ }
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_curvetob_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl
+ {
+ {\fp_to_dim:n
+ {
+ (1 - #2) * \tl_item:nn {#1} {8} + (#2) * \tl_item:nn {#1} {11}
+ }}
+ {\fp_to_dim:n
+ {
+ (1 - #2) * \tl_item:nn {#1} {9} + (#2) * \tl_item:nn {#1} {12}
+ }}
+ }
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_curveto_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl {
+ {\tl_item:nn {#1} {11}}
+ {\tl_item:nn {#1} {12}}
+ }
+
+ \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_tmpa_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_split_curve:NNnn #1#2#3#4
+{
+ \@@_split_curve:nn {#3}{#4}
+ \tl_set:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}}
+ \tl_set:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_split_curve:NNnn {NNnV, NNVn, NNVV}
+\cs_new_protected_nopar:Npn \spath_gsplit_curve:NNnn #1#2#3#4
+{
+ \@@_split_curve:nn {#3}{#4}
+ \tl_gset:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}}
+ \tl_gset:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gsplit_curve:NNnn {NNnV, NNVn, NNVV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_split_line:NNnn,
+% \spath_gsplit_line:NNnn
+% }
+% Splits a line segment.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_split_line:nn #1#2
+{
+ \group_begin:
+ \tl_set_eq:NN \l_@@_tmpa_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl {
+ {\tl_item:nn {#1} {2}}
+ {\tl_item:nn {#1} {3}}
+ }
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_lineto_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl
+ {
+ {\fp_to_dim:n
+ {
+ (1 - #2) * \tl_item:nn {#1} {2} + (#2) * \tl_item:nn {#1} {5}
+ }}
+ {\fp_to_dim:n
+ {
+ (1 - #2) * \tl_item:nn {#1} {3} + (#2) * \tl_item:nn {#1} {6}
+ }}
+ }
+ \tl_gclear:N \g_@@_output_tl
+ \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_tmpa_tl
+
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_set_eq:NN \l_@@_tmpa_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl
+ {
+ {\fp_to_dim:n
+ {
+ (1 - #2) * \tl_item:nn {#1} {2} + (#2) * \tl_item:nn {#1} {5}
+ }}
+ {\fp_to_dim:n
+ {
+ (1 - #2) * \tl_item:nn {#1} {3} + (#2) * \tl_item:nn {#1} {6}
+ }}
+ }
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_lineto_tl
+ \tl_put_right:Nx \l_@@_tmpa_tl {
+ {\tl_item:nn {#1} {5}}
+ {\tl_item:nn {#1} {6}}
+ }
+
+ \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_tmpa_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_split_line:NNnn #1#2#3#4
+{
+ \@@_split_line:nn {#3}{#4}
+ \tl_set:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}}
+ \tl_set:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_split_line:NNnn {NNnV, NNVn, NNVV}
+\cs_new_protected_nopar:Npn \spath_gsplit_line:NNnn #1#2#3#4
+{
+ \@@_split_line:nn {#3}{#4}
+ \tl_gset:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}}
+ \tl_gset:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gsplit_line:NNnn {NNnV, NNVn, NNVV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\int_new:N \l_@@_split_int
+\int_new:N \l_@@_splitat_int
+\fp_new:N \l_@@_split_fp
+\bool_new:N \l_@@_split_bool
+\tl_new:N \l_@@_split_path_tl
+\tl_new:N \l_@@_split_patha_tl
+\tl_new:N \l_@@_split_pathb_tl
+\tl_new:N \l_@@_split_intoa_tl
+\tl_new:N \l_@@_split_intob_tl
+\dim_new:N \l_@@_splitx_dim
+\dim_new:N \l_@@_splity_dim
+% \end{macrocode}
+%
+% \begin{macro}{
+% \spath_split_at:NNnn,
+% \spath_split_at:Nnn,
+% \spath_split_at:Nn,
+% \spath_gsplit_at:NNnn
+% \spath_gsplit_at:Nnn,
+% \spath_gsplit_at:Nn
+% }
+% Split a path according to the parameter generated by the intersection routine.
+% The versions with two \texttt{N} arguments stores the two parts in two macros, the version with a single \texttt{N} joins them back into a single path (as separate components).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_split_at:nn #1#2
+{
+ \group_begin:
+ \int_set:Nn \l_@@_splitat_int {\fp_to_int:n {floor(#2) + 1}}
+ \fp_set:Nn \l_@@_split_fp {#2 - floor(#2)}
+
+ % Is split point near one end or other of a component?
+ \fp_compare:nT
+ {
+ \l_@@_split_fp < 0.01
+ }
+ {
+ % Near the start, so we'll place it at the start
+ \fp_set:Nn \l_@@_split_fp {0}
+ }
+ \fp_compare:nT
+ {
+ \l_@@_split_fp > 0.99
+ }
+ {
+ % Near the end, so we'll place it at the end
+ \fp_set:Nn \l_@@_split_fp {0}
+ \int_incr:N \l_@@_splitat_int
+ }
+
+ \int_zero:N \l_@@_split_int
+ \bool_set_true:N \l_@@_split_bool
+
+ \tl_set:Nn \l_@@_split_path_tl {#1}
+ \tl_clear:N \l_@@_split_patha_tl
+
+ \dim_zero:N \l_@@_splitx_dim
+ \dim_zero:N \l_@@_splity_dim
+
+ \bool_until_do:nn {
+ \tl_if_empty_p:N \l_@@_split_path_tl
+ ||
+ \int_compare_p:n { \l_@@_splitat_int == \l_@@_split_int }
+ }
+ {
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_split_path_tl}
+ \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+ \tl_case:Nn \l_@@_tmpc_tl
+ {
+ \c_spath_lineto_tl
+ {
+ \int_incr:N \l_@@_split_int
+ }
+ \c_spath_curvetoa_tl
+ {
+ \int_incr:N \l_@@_split_int
+ }
+ }
+ \int_compare:nT { \l_@@_split_int < \l_@@_splitat_int }
+ {
+ \tl_put_right:NV \l_@@_split_patha_tl \l_@@_tmpc_tl
+
+ \tl_put_right:Nx \l_@@_split_patha_tl
+ {{ \tl_head:N \l_@@_split_path_tl }}
+ \dim_set:Nn \l_@@_splitx_dim {\tl_head:N \l_@@_split_path_tl}
+ \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+
+ \tl_put_right:Nx \l_@@_split_patha_tl
+ {{ \tl_head:N \l_@@_split_path_tl }}
+ \dim_set:Nn \l_@@_splity_dim {\tl_head:N \l_@@_split_path_tl}
+ \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+
+ }
+ }
+
+ \tl_clear:N \l_@@_split_pathb_tl
+ \tl_put_right:NV \l_@@_split_pathb_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_split_pathb_tl
+ {
+ {\dim_use:N \l_@@_splitx_dim}
+ {\dim_use:N \l_@@_splity_dim}
+ }
+
+ \fp_compare:nTF
+ {
+ \l_@@_split_fp == 0
+ }
+ {
+ \tl_set_eq:NN \l_@@_split_intob_tl \l_@@_split_pathb_tl
+ \tl_if_empty:NF \l_@@_split_path_tl
+ {
+ \tl_put_right:NV \l_@@_split_intob_tl \l_@@_tmpc_tl
+ \tl_put_right:NV \l_@@_split_intob_tl \l_@@_split_path_tl
+ }
+ }
+ {
+
+ \tl_case:Nn \l_@@_tmpc_tl
+ {
+ \c_spath_lineto_tl
+ {
+ \tl_put_right:NV \l_@@_split_pathb_tl \l_@@_tmpc_tl
+ \tl_put_right:Nx \l_@@_split_pathb_tl
+ {{ \tl_head:N \l_@@_split_path_tl }}
+ \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+
+ \tl_put_right:Nx \l_@@_split_pathb_tl
+ {{ \tl_head:N \l_@@_split_path_tl }}
+ \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+
+ \spath_split_line:NNVV
+ \l_@@_split_intoa_tl
+ \l_@@_split_intob_tl
+ \l_@@_split_pathb_tl
+ \l_@@_split_fp
+
+ \prg_replicate:nn {3} {
+ \tl_set:Nx \l_@@_split_intoa_tl {\tl_tail:N \l_@@_split_intoa_tl}
+ }
+
+ \tl_put_right:NV \l_@@_split_patha_tl \l_@@_split_intoa_tl
+ \tl_put_right:NV \l_@@_split_intob_tl \l_@@_split_path_tl
+ }
+ \c_spath_curvetoa_tl
+ {
+ \tl_put_right:NV \l_@@_split_pathb_tl \l_@@_tmpc_tl
+ \tl_put_right:Nx \l_@@_split_pathb_tl
+ {{ \tl_head:N \l_@@_split_path_tl }}
+ \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+
+ \tl_put_right:Nx \l_@@_split_pathb_tl
+ {{ \tl_head:N \l_@@_split_path_tl }}
+ \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+
+ \prg_replicate:nn {2} {
+
+ \tl_put_right:Nx \l_@@_split_pathb_tl
+ { \tl_head:N \l_@@_split_path_tl }
+ \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+
+ \tl_put_right:Nx \l_@@_split_pathb_tl
+ {{ \tl_head:N \l_@@_split_path_tl }}
+ \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+
+ \tl_put_right:Nx \l_@@_split_pathb_tl
+ {{ \tl_head:N \l_@@_split_path_tl }}
+ \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+ }
+
+ \spath_split_curve:NNVV
+ \l_@@_split_intoa_tl
+ \l_@@_split_intob_tl
+ \l_@@_split_pathb_tl \l_@@_split_fp
+
+ \prg_replicate:nn {3} {
+ \tl_set:Nx \l_@@_split_intoa_tl {\tl_tail:N \l_@@_split_intoa_tl}
+ }
+
+ \tl_put_right:NV \l_@@_split_patha_tl \l_@@_split_intoa_tl
+ \tl_put_right:NV \l_@@_split_intob_tl \l_@@_split_path_tl
+ }
+ }
+ }
+
+ \tl_gclear:N \g_@@_output_tl
+ \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_split_patha_tl
+ \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_split_intob_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_split_at:NNnn #1#2#3#4
+{
+ \@@_split_at:nn {#3}{#4}
+ \tl_set:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}}
+ \tl_set:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_split_at:NNnn {NNVn, NNVV, NNnV}
+\cs_new_protected_nopar:Npn \spath_gsplit_at:NNnn #1#2#3#4
+{
+ \@@_split_at:nn {#3}{#4}
+ \tl_gset:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}}
+ \tl_gset:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gsplit_at:NNnn {NNVn, NNVV, NNnV}
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_split_at:Nnn #1#2#3
+{
+ \@@_split_at:nn {#2}{#3}
+ \tl_set:Nx #1 {\tl_item:Nn \g_@@_output_tl {1} \tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_split_at:Nnn {NVn, NVV}
+\cs_new_protected_nopar:Npn \spath_split_at:Nn #1#2
+{
+ \spath_split_at:NVn #1#1{#2}
+}
+\cs_new_protected_nopar:Npn \spath_gsplit_at:Nnn #1#2#3
+{
+ \@@_split_at:nn {#2}{#3}
+ \tl_gset:Nx #1 {\tl_item:Nn \g_@@_output_tl {1} \tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gsplit_at:Nnn {NVn, NVV}
+\cs_new_protected_nopar:Npn \spath_gsplit_at:Nn #1#2
+{
+ \spath_gsplit_at:NVn #1#1{#2}
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Shortening Paths}
+%
+% This code relates to shortening paths.
+% For curved paths, the routine uses the derivative at the end to figure out how far back to shorten.
+% This means that the actual length that it shortens by is approximate, but it is guaranteed to be along its length.
+%
+% As in the previous section, there are various versions.
+% In particular, there are versions where the path can be specified by a macro and is saved back into that macro.
+%
+% \begin{macrocode}
+\tl_new:N \l_@@_shorten_fa_tl
+\tl_new:N \l_@@_shorten_path_tl
+\tl_new:N \l_@@_shorten_last_tl
+\tl_new:N \l_@@_shorten_lasta_tl
+\tl_new:N \l_@@_shorten_lastb_tl
+\int_new:N \l_@@_shorten_int
+\fp_new:N \l_@@_shorten_x_fp
+\fp_new:N \l_@@_shorten_y_fp
+\fp_new:N \l_@@_shorten_len_fp
+% \end{macrocode}
+%
+% \begin{macro}{
+% \spath_shorten_at_end:Nnn
+% }
+% This macro shortens a path from the end by a dimension.
+%
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_shorten_at_end:nn #1#2
+{
+ \int_compare:nTF
+ {
+ \tl_count:n {#1} > 3
+ }
+ {
+ \group_begin:
+ \tl_set:Nn \l_@@_shorten_path_tl {#1}
+ \tl_reverse:N \l_@@_shorten_path_tl
+
+ \tl_set:Nx \l_@@_shorten_fa_tl {\tl_item:Nn \l_@@_shorten_path_tl {3}}
+
+ \tl_clear:N \l_@@_shorten_last_tl
+ \tl_if_eq:NNTF \l_@@_shorten_fa_tl \c_spath_curveto_tl
+ {
+ \int_set:Nn \l_@@_shorten_int {3}
+ }
+ {
+ \int_set:Nn \l_@@_shorten_int {1}
+ }
+
+ \prg_replicate:nn { \l_@@_shorten_int }
+ {
+ \tl_put_right:Nx \l_@@_shorten_last_tl
+ {
+ {\tl_head:N \l_@@_shorten_path_tl}
+ }
+ \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl}
+ \tl_put_right:Nx \l_@@_shorten_last_tl
+ {
+ {\tl_head:N \l_@@_shorten_path_tl}
+ }
+ \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl}
+ \tl_put_right:Nx \l_@@_shorten_last_tl
+ {
+ \tl_head:N \l_@@_shorten_path_tl
+ }
+ \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl}
+ }
+
+ \tl_put_right:Nx \l_@@_shorten_last_tl
+ {
+ {\tl_item:Nn \l_@@_shorten_path_tl {1}}
+ {\tl_item:Nn \l_@@_shorten_path_tl {2}}
+ }
+ \tl_put_right:NV \l_@@_shorten_last_tl \c_spath_moveto_tl
+
+ \tl_reverse:N \l_@@_shorten_path_tl
+
+ \fp_set:Nn \l_@@_shorten_x_fp
+ {
+ \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {4}}
+ -
+ \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {1}}
+ }
+
+ \fp_set:Nn \l_@@_shorten_y_fp
+ {
+ \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {5}}
+ -
+ \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {2}}
+ }
+
+ \fp_set:Nn \l_@@_shorten_len_fp
+ {
+ sqrt( \l_@@_shorten_x_fp * \l_@@_shorten_x_fp + \l_@@_shorten_y_fp * \l_@@_shorten_y_fp )
+ }
+
+ \fp_compare:nTF
+ {
+ \l_@@_shorten_len_fp > #2
+ }
+ {
+
+ \fp_set:Nn \l_@@_shorten_len_fp
+ {
+ (\l_@@_shorten_len_fp - #2)/ \l_@@_shorten_len_fp
+ }
+
+ \tl_reverse:N \l_@@_shorten_last_tl
+
+ \tl_if_eq:NNTF \l_@@_shorten_fa_tl \c_spath_curveto_tl
+ {
+ \fp_set:Nn \l_@@_shorten_len_fp
+ {
+ 1 - (1 -\l_@@_shorten_len_fp)/3
+ }
+ \spath_split_curve:NNVV
+ \l_@@_shorten_lasta_tl
+ \l_@@_shorten_lastb_tl
+ \l_@@_shorten_last_tl
+ \l_@@_shorten_len_fp
+ }
+ {
+ \spath_split_line:NNVV
+ \l_@@_shorten_lasta_tl
+ \l_@@_shorten_lastb_tl
+ \l_@@_shorten_last_tl
+ \l_@@_shorten_len_fp
+ }
+
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_shorten_lasta_tl {\tl_tail:N \l_@@_shorten_lasta_tl}
+ }
+
+ \tl_put_right:NV \l_@@_shorten_path_tl \l_@@_shorten_lasta_tl
+
+ }
+ {
+
+ \int_compare:nT
+ {
+ \tl_count:N \l_@@_shorten_path_tl > 3
+ }
+ {
+ \dim_set:Nn \l_@@_tmpa_dim {\fp_to_dim:n {#2 - \l_@@_shorten_len_fp } }
+ \spath_shorten_at_end:NV \l_@@_shorten_path_tl \l_@@_tmpa_dim
+ }
+ }
+
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_shorten_path_tl
+ \group_end:
+ }
+ {
+ \tl_gset:Nn \g_@@_output_tl {#1}
+ }
+}
+\cs_new_protected_nopar:Npn \spath_shorten_at_end:Nnn #1#2#3
+{
+ \@@_shorten_at_end:nn {#2}{#3}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_shorten_at_end:Nnn {NVV, cnn, cVV, NVn}
+\cs_new_protected_nopar:Npn \spath_shorten_at_end:Nn #1#2
+{
+ \spath_shorten_at_end:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_shorten_at_end:Nn {cn, cV, NV}
+\cs_new_protected_nopar:Npn \spath_gshorten_at_end:Nnn #1#2#3
+{
+ \@@_shorten_at_end:nn {#2}{#3}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gshorten_at_end:Nnn {NVV, cnn, cVV, NVn}
+\cs_new_protected_nopar:Npn \spath_gshorten_at_end:Nn #1#2
+{
+ \spath_gshorten_at_end:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_gshorten_at_end:Nn {cn, cV, NV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_shorten_at_start:Nnn,
+% \spath_shorten_at_start:Nn,
+% \spath_gshorten_at_start:Nnn,
+% \spath_gshorten_at_start:Nn
+% }
+%
+% This macro shortens a path from the start by a dimension.
+%
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_shorten_at_start:nn #1#2
+{
+ \int_compare:nTF
+ {
+ \tl_count:n {#1} > 3
+ }
+ {
+ \group_begin:
+ \tl_set:Nn \l_@@_shorten_path_tl {#1}
+
+ \tl_set:Nx \l_@@_shorten_fa_tl {\tl_item:Nn \l_@@_shorten_path_tl {4}}
+
+ \tl_clear:N \l_@@_shorten_last_tl
+
+ \tl_if_eq:NNTF \l_@@_shorten_fa_tl \c_spath_curvetoa_tl
+ {
+ \int_set:Nn \l_@@_shorten_int {3}
+ }
+ {
+ \int_set:Nn \l_@@_shorten_int {1}
+ }
+
+ \tl_set_eq:NN \l_@@_shorten_last_tl \c_spath_moveto_tl
+ \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl }
+
+ \prg_replicate:nn { \l_@@_shorten_int }
+ {
+ \@@_tl_put_right_braced:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {1}}
+ \@@_tl_put_right_braced:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {2}}
+ \tl_put_right:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {3}}
+
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl }
+ }
+ }
+ \@@_tl_put_right_braced:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {1}}
+ \@@_tl_put_right_braced:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {2}}
+
+ \fp_set:Nn \l_@@_shorten_x_fp
+ {
+ \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {5}}
+ -
+ \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {2}}
+ }
+
+ \fp_set:Nn \l_@@_shorten_y_fp
+ {
+ \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {6}}
+ -
+ \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {3}}
+ }
+
+ \fp_set:Nn \l_@@_shorten_len_fp
+ {
+ sqrt( \l_@@_shorten_x_fp * \l_@@_shorten_x_fp + \l_@@_shorten_y_fp * \l_@@_shorten_y_fp )
+ }
+
+ \fp_compare:nTF
+ {
+ \l_@@_shorten_len_fp > #2
+ }
+ {
+
+ \fp_set:Nn \l_@@_shorten_len_fp
+ {
+ #2/ \l_@@_shorten_len_fp
+ }
+
+ \tl_if_eq:NNTF \l_@@_shorten_fa_tl \c_spath_curvetoa_tl
+ {
+ \fp_set:Nn \l_@@_shorten_len_fp
+ {
+ \l_@@_shorten_len_fp/3
+ }
+ \spath_split_curve:NNVV
+ \l_@@_shorten_lasta_tl
+ \l_@@_shorten_lastb_tl
+ \l_@@_shorten_last_tl
+ \l_@@_shorten_len_fp
+ }
+ {
+ \spath_split_line:NNVV
+ \l_@@_shorten_lasta_tl
+ \l_@@_shorten_lastb_tl
+ \l_@@_shorten_last_tl
+ \l_@@_shorten_len_fp
+ }
+
+ \prg_replicate:nn {2}
+ {
+ \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl}
+ }
+
+ \tl_put_left:NV \l_@@_shorten_path_tl \l_@@_shorten_lastb_tl
+
+ }
+ {
+
+ \tl_put_left:NV \l_@@_shorten_path_tl \c_spath_moveto_tl
+
+ \int_compare:nT
+ {
+ \tl_count:N \l_@@_shorten_path_tl > 3
+ }
+ {
+ \dim_set:Nn \l_@@_tmpa_dim {\fp_to_dim:n {#2 - \l_@@_shorten_len_fp } }
+ \spath_shorten_at_start:NV \l_@@_shorten_path_tl \l_@@_tmpa_dim
+ }
+ }
+
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_shorten_path_tl
+ \group_end:
+ }
+ {
+ \tl_gset:Nn \g_@@_output_tl {#1}
+ }
+}
+\cs_new_protected_nopar:Npn \spath_shorten_at_start:Nnn #1#2#3
+{
+ \@@_shorten_at_start:nn {#2}{#3}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_shorten_at_start:Nnn {NVV, cnn, cVV, NVn}
+\cs_new_protected_nopar:Npn \spath_shorten_at_start:Nn #1#2
+{
+ \spath_shorten_at_start:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_shorten_at_start:Nn {cn, cV, NV}
+\cs_new_protected_nopar:Npn \spath_gshorten_at_start:Nnn #1#2#3
+{
+ \@@_shorten_at_start:nn {#2}{#3}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gshorten_at_start:Nnn {NVV, cnn, cVV, NVn}
+\cs_new_protected_nopar:Npn \spath_gshorten_at_start:Nn #1#2
+{
+ \spath_gshorten_at_start:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_gshorten_at_start:Nn {cn, cV, NV}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Points on a Path}
+%
+% \begin{macro}{
+% \spath_point_at:Nnn,
+% \spath_gpoint_at:Nnn,
+% }
+%
+% Get the location of a point on a path, using the same location specification as the intersection library.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_point_at:nn #1#2
+{
+ \group_begin:
+ \int_set:Nn \l_@@_tmpa_int {\fp_to_int:n {floor(#2) + 1}}
+ \fp_set:Nn \l_@@_tmpa_fp {#2 - floor(#2)}
+
+ \spath_segments_to_seq:Nn \l_@@_tmpa_seq {#1}
+
+ \int_compare:nTF
+ {
+ \l_@@_tmpa_int < 1
+ }
+ {
+ \spath_initialpoint:Nn \l_@@_tmpc_tl {#1}
+ }
+ {
+ \int_compare:nTF
+ {
+ \l_@@_tmpa_int > \seq_count:N \l_@@_tmpa_seq
+ }
+ {
+ \spath_finalpoint:Nn \l_@@_tmpc_tl {#1}
+ }
+ {
+
+ \tl_set:Nx \l_@@_tmpa_tl {\seq_item:Nn \l_@@_tmpa_seq { \l_@@_tmpa_int} }
+
+ \int_compare:nTF
+ {
+ \tl_count:N \l_@@_tmpa_tl > 3
+ }
+ {
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_item:Nn \l_@@_tmpa_tl {4}}
+ }
+ {
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_item:Nn \l_@@_tmpa_tl {1}}
+ }
+
+ \tl_clear:N \l_@@_tmpc_tl
+
+ \tl_case:Nn \l_@@_tmpb_tl
+ {
+ \c_spath_moveto_tl
+ {
+ \tl_set:Nx \l_@@_tmpc_tl
+ {
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {2}
+ }
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {3}
+ }
+ }
+ }
+
+ \c_spath_lineto_tl
+ {
+ \tl_set:Nx \l_@@_tmpc_tl
+ {
+ {\fp_to_dim:n
+ {
+ (1 - \l_@@_tmpa_fp) * ( \tl_item:Nn \l_@@_tmpa_tl {2} )
+ +
+ \l_@@_tmpa_fp * ( \tl_item:Nn \l_@@_tmpa_tl {5} )
+ }
+ }
+ {\fp_to_dim:n
+ {
+ (1 - \l_@@_tmpa_fp) * ( \tl_item:Nn \l_@@_tmpa_tl {3} )
+ +
+ \l_@@_tmpa_fp * ( \tl_item:Nn \l_@@_tmpa_tl {6} )
+ }
+ }
+ }
+ }
+
+ \c_spath_closepath_tl
+ {
+ \tl_set:Nx \l_@@_tmpc_tl
+ {
+ {\fp_to_dim:n
+ {
+ (1 - \l_@@_tmpa_fp) * ( \tl_item:Nn \l_@@_tmpa_tl {2} )
+ +
+ \l_@@_tmpa_fp * ( \tl_item:Nn \l_@@_tmpa_tl {5} )
+ }
+ }
+ {\fp_to_dim:n
+ {
+ (1 - \l_@@_tmpa_fp) * ( \tl_item:Nn \l_@@_tmpa_tl {3} )
+ +
+ \l_@@_tmpa_fp * ( \tl_item:Nn \l_@@_tmpa_tl {6} )
+ }
+ }
+ }
+ }
+
+ \c_spath_curvetoa_tl
+ {
+ \tl_set:Nx \l_@@_tmpc_tl
+ {
+ {\fp_to_dim:n
+ {
+ (1 - \l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {2} + 3 * (1 - \l_@@_tmpa_fp)^2 * (\l_@@_tmpa_fp) * \tl_item:Nn \l_@@_tmpa_tl {5} + 3 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp)^2 * \tl_item:Nn \l_@@_tmpa_tl {8} + (\l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {11}
+ }}
+ {\fp_to_dim:n
+ {
+ (1 - \l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {3} + 3 * (1 - \l_@@_tmpa_fp)^2 * (\l_@@_tmpa_fp) * \tl_item:Nn \l_@@_tmpa_tl {6} + 3 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp)^2 * \tl_item:Nn \l_@@_tmpa_tl {9} + (\l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {12}
+ }}
+ }
+ }
+ }
+ }
+ }
+
+ \tl_gclear:N \g_@@_output_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpc_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_point_at:Nnn #1#2#3
+{
+ \@@_point_at:nn {#2}{#3}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_point_at:Nnn {NVn, NVV, NnV}
+\cs_new_protected_nopar:Npn \spath_gpoint_at:Nnn #1#2#3
+{
+ \@@_point_at:nn {#2}{#3}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gpoint_at:Nnn {NVn, NVV, NnV}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{
+% \spath_tangent_at:Nnn,
+% \spath_gtangent_at:Nnn,
+% }
+%
+% Get the tangent at a point on a path, using the same location specification as the intersection library.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_tangent_at:nn #1#2
+{
+ \group_begin:
+ \int_set:Nn \l_@@_tmpa_int {\fp_to_int:n {floor(#2) + 1}}
+ \fp_set:Nn \l_@@_tmpa_fp {#2 - floor(#2)}
+
+ \spath_segments_to_seq:Nn \l_@@_tmpa_seq {#1}
+
+ \int_compare:nTF
+ {
+ \l_@@_tmpa_int < 1
+ }
+ {
+ \spath_initialpoint:Nn \l_@@_tmpc_tl {#1}
+ }
+ {
+ \int_compare:nTF
+ {
+ \l_@@_tmpa_int > \seq_count:N \l_@@_tmpa_seq
+ }
+ {
+ \spath_finalpoint:Nn \l_@@_tmpc_tl {#1}
+ }
+ {
+
+ \tl_set:Nx \l_@@_tmpa_tl {\seq_item:Nn \l_@@_tmpa_seq { \l_@@_tmpa_int} }
+
+ \int_compare:nTF
+ {
+ \tl_count:N \l_@@_tmpa_tl > 3
+ }
+ {
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_item:Nn \l_@@_tmpa_tl {4}}
+ }
+ {
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_item:Nn \l_@@_tmpa_tl {1}}
+ }
+
+ \tl_clear:N \l_@@_tmpc_tl
+
+ \tl_case:Nn \l_@@_tmpb_tl
+ {
+ \c_spath_moveto_tl
+ {
+ \tl_set:Nx \l_@@_tmpc_tl
+ {
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {2}
+ }
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {3}
+ }
+ }
+ }
+
+ \c_spath_lineto_tl
+ {
+ \tl_set:Nx \l_@@_tmpc_tl
+ {
+ {\fp_to_dim:n
+ {
+ ( \tl_item:Nn \l_@@_tmpa_tl {5} )
+ -
+ ( \tl_item:Nn \l_@@_tmpa_tl {2} )
+ }
+ }
+ {\fp_to_dim:n
+ {
+ ( \tl_item:Nn \l_@@_tmpa_tl {6} )
+ -
+ ( \tl_item:Nn \l_@@_tmpa_tl {3} )
+ }
+ }
+ }
+ }
+
+ \c_spath_closepath_tl
+ {
+ \tl_set:Nx \l_@@_tmpc_tl
+ {
+ {\fp_to_dim:n
+ {
+ ( \tl_item:Nn \l_@@_tmpa_tl {5} )
+ -
+ ( \tl_item:Nn \l_@@_tmpa_tl {2} )
+ }
+ }
+ {\fp_to_dim:n
+ {
+ ( \tl_item:Nn \l_@@_tmpa_tl {6} )
+ -
+ ( \tl_item:Nn \l_@@_tmpa_tl {3} )
+ }
+ }
+ }
+ }
+
+ \c_spath_curvetoa_tl
+ {
+ \tl_set:Nx \l_@@_tmpc_tl
+ {
+ {\fp_to_dim:n
+ {
+ 3*(1 - \l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {5} - \tl_item:Nn \l_@@_tmpa_tl {2})
+ + 6 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp) * (\tl_item:Nn \l_@@_tmpa_tl {8} - \tl_item:Nn \l_@@_tmpa_tl {5})
+ + 3*(\l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {11} - \tl_item:Nn \l_@@_tmpa_tl {8})
+ }
+ }
+ {\fp_to_dim:n
+ {
+ 3*(1 - \l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {6} - \tl_item:Nn \l_@@_tmpa_tl {3})
+ + 6 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp) * (\tl_item:Nn \l_@@_tmpa_tl {9} - \tl_item:Nn \l_@@_tmpa_tl {6})
+ + 3*(\l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {12} - \tl_item:Nn \l_@@_tmpa_tl {9})
+ }}
+ }
+ }
+ }
+ }
+ }
+
+ \tl_gclear:N \g_@@_output_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpc_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_tangent_at:Nnn #1#2#3
+{
+ \@@_tangent_at:nn {#2}{#3}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_tangent_at:Nnn {NVn, NVV, NnV}
+\cs_new_protected_nopar:Npn \spath_gtangent_at:Nnn #1#2#3
+{
+ \@@_tangent_at:nn {#2}{#3}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gtangent_at:Nnn {NVn, NVV, NnV}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{
+% \spath_transformation_at:Nnn,
+% \spath_gtransformation_at:Nnn
+% }
+% Gets a transformation that will align to a point on the path with the x-axis along the path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_transformation_at:nn #1#2
+{
+ \group_begin:
+ \tl_clear:N \l_@@_tmpa_tl
+ \@@_tangent_at:nn {#1}{#2}
+ \tl_set_eq:NN \l_@@_tmpb_tl \g_@@_output_tl
+ \fp_set:Nn \l_@@_tmpa_fp { sqrt( (\tl_item:Nn \l_@@_tmpb_tl {1})^2 + (\tl_item:Nn \l_@@_tmpb_tl {2})^2 ) }
+ \fp_compare:nTF {\l_@@_tmpa_fp = 0}
+ {
+ \fp_set:Nn \l_@@_tmpa_fp {1}
+ \fp_set:Nn \l_@@_tmpb_fp {0}
+ }
+ {
+ \fp_set:Nn \l_@@_tmpb_fp { (\tl_item:Nn \l_@@_tmpb_tl {2}) / \l_@@_tmpa_fp }
+ \fp_set:Nn \l_@@_tmpa_fp { (\tl_item:Nn \l_@@_tmpb_tl {1}) / \l_@@_tmpa_fp }
+ }
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ { \fp_to_decimal:n { \l_@@_tmpa_fp } }
+ { \fp_to_decimal:n { \l_@@_tmpb_fp } }
+ { \fp_to_decimal:n {- \l_@@_tmpb_fp } }
+ { \fp_to_decimal:n { \l_@@_tmpa_fp } }
+ }
+ \@@_point_at:nn {#1}{#2}
+ \tl_put_right:NV \l_@@_tmpa_tl \g_@@_output_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_transformation_at:Nnn #1#2#3
+{
+ \@@_transformation_at:nn {#2}{#3}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_transformation_at:Nnn {NVn, NVV, NnV, NvV}
+\cs_new_protected_nopar:Npn \spath_gtransformation_at:Nnn #1#2#3
+{
+ \@@_transformation_at:nn {#2}{#3}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gtransformation_at:Nnn {NVn, NVV, NnV}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Intersection Routines}
+%
+% Note: I'm not consistent with number schemes.
+% The intersection library is 0-based, but the user interface is 1-based (since if we ``count'' in a \Verb+\foreach+ then it starts at 1).
+% This should be more consistent.
+%
+% \begin{macrocode}
+\tl_new:N \l_@@_split_path_a_tl
+\tl_new:N \l_@@_split_path_b_tl
+\tl_new:N \l_@@_split_path_a_start_tl
+\tl_new:N \l_@@_split_path_b_start_tl
+\tl_new:N \l_@@_split_path_a_end_tl
+\tl_new:N \l_@@_split_path_b_end_tl
+\tl_new:N \l_@@_split_path_a_final_tl
+\tl_new:N \l_@@_split_path_b_final_tl
+
+\tl_new:N \l_@@_split_prev_first_tl
+\tl_new:N \l_@@_split_prev_second_tl
+
+\seq_new:N \l_@@_split_first_seq
+\seq_new:N \l_@@_split_second_seq
+
+\int_new:N \l_@@_split_segment_int
+% \end{macrocode}
+%
+% \begin{macro}{
+% \spath_intersect:NN,
+% \spath_intersect:nn,
+% }
+% Pass two spaths to pgf's intersection routine.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_intersect:NN #1#2
+{
+ \pgfintersectionofpaths%
+ {%
+ \pgfsetpath #1
+ }{%
+ \pgfsetpath #2
+ }
+}
+\tl_new:N \l_@@_intersecta_tl
+\tl_new:N \l_@@_intersectb_tl
+\cs_new_protected_nopar:Npn \spath_intersect:nn #1#2
+{
+ \tl_set:Nn \l_@@_intersecta_tl {#1}
+ \tl_set:Nn \l_@@_intersectb_tl {#2}
+ \spath_intersect:NN \l_@@_intersecta_tl \l_@@_intersectb_tl
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_split_at_intersections:NNnn,
+% \spath_split_at_intersections:NN,
+% \spath_gsplit_at_intersections:NNnn,
+% \spath_gsplit_at_intersections:NN
+% }
+% Given two paths, split them at points where they intersect and store them in the macros.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_split_at_intersections:nn #1#2
+{
+ \group_begin:
+
+ % Clear some token lists and sequences
+ \tl_clear:N \l_@@_split_path_a_final_tl
+ \tl_clear:N \l_@@_split_path_b_final_tl
+ \seq_clear:N \l_@@_split_first_seq
+ \seq_clear:N \l_@@_split_second_seq
+
+ \pgfintersectionsortbyfirstpath
+ % Find the intersections of these segments
+ \tl_set:Nn \l_@@_split_path_a_tl {#1}
+ \tl_set:Nn \l_@@_split_path_b_tl {#2}
+ % Remove empty components
+% \spath_path_remove_empty_components:N \l_@@_split_path_a_tl
+% \spath_path_remove_empty_components:N \l_@@_split_path_b_tl
+
+ \spath_intersect:NN \l_@@_split_path_a_tl \l_@@_split_path_b_tl
+
+ % If we get intersections
+ \int_compare:nT {\pgfintersectionsolutions > 0}
+ {
+ % Find the times of the intersections on each path
+ \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions}
+ {
+ \pgfintersectiongetsolutiontimes{##1}{\l_@@_split_first_tl}{\l_@@_split_second_tl}
+ \seq_put_left:NV \l_@@_split_first_seq \l_@@_split_first_tl
+ }
+ }
+
+ \spath_intersect:NN \l_@@_split_path_b_tl \l_@@_split_path_a_tl
+
+ % If we get intersections
+ \int_compare:nT {\pgfintersectionsolutions > 0}
+ {
+ % Find the times of the intersections on each path
+ \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions}
+ {
+ \pgfintersectiongetsolutiontimes{##1}{\l_@@_split_first_tl}{\l_@@_split_second_tl}
+ \seq_put_left:NV \l_@@_split_second_seq \l_@@_split_first_tl
+ }
+ }
+
+ \tl_set:Nn \l_@@_split_prev_first_tl {-1}
+
+ \seq_map_inline:Nn \l_@@_split_first_seq
+ {
+ \tl_set:Nn \l_@@_split_first_tl {##1}
+
+ \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_split_first_tl
+ \int_compare:nT
+ {
+ \fp_to_int:n {floor( \l_@@_split_first_tl) }
+ =
+ \fp_to_int:n {floor( \l_@@_split_prev_first_tl) }
+ }
+ {
+ \tl_set:Nx \l_@@_split_first_tl
+ {
+ \fp_eval:n {
+ floor( \l_@@_split_first_tl )
+ +
+ ( \l_@@_split_first_tl - floor( \l_@@_split_first_tl) )
+ /
+ ( \l_@@_split_prev_first_tl - floor( \l_@@_split_prev_first_tl) )
+ }
+ }
+ }
+ \tl_set_eq:NN \l_@@_split_prev_first_tl \l_@@_tmpa_tl
+
+ \spath_split_at:NNVV \l_@@_split_path_a_start_tl \l_@@_split_path_a_end_tl \l_@@_split_path_a_tl \l_@@_split_first_tl
+
+ \tl_put_left:NV \l_@@_split_path_a_final_tl \l_@@_split_path_a_end_tl
+ \tl_set_eq:NN \l_@@_split_path_a_tl \l_@@_split_path_a_start_tl
+
+ }
+
+ \tl_set:Nn \l_@@_split_prev_second_tl {-1}
+
+ \seq_map_inline:Nn \l_@@_split_second_seq
+ {
+ \tl_set:Nn \l_@@_split_second_tl {##1}
+
+ \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_split_second_tl
+ \int_compare:nT
+ {
+ \fp_to_int:n {floor( \l_@@_split_second_tl) }
+ =
+ \fp_to_int:n {floor( \l_@@_split_prev_second_tl) }
+ }
+ {
+ \tl_set:Nx \l_@@_split_second_tl
+ {
+ \fp_eval:n {
+ floor( \l_@@_split_second_tl )
+ +
+ ( \l_@@_split_second_tl - floor( \l_@@_split_second_tl) )
+ /
+ ( \l_@@_split_prev_second_tl - floor( \l_@@_split_prev_second_tl) )
+ }
+ }
+ }
+ \tl_set_eq:NN \l_@@_split_prev_second_tl \l_@@_tmpa_tl
+
+ \spath_split_at:NNVV \l_@@_split_path_b_start_tl \l_@@_split_path_b_end_tl \l_@@_split_path_b_tl\l_@@_split_second_tl
+
+ \tl_put_left:NV \l_@@_split_path_b_final_tl \l_@@_split_path_b_end_tl
+ \tl_set_eq:NN \l_@@_split_path_b_tl \l_@@_split_path_b_start_tl
+
+ }
+
+ \tl_put_left:NV \l_@@_split_path_a_final_tl \l_@@_split_path_a_tl
+ \tl_put_left:NV \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl
+
+ \tl_if_empty:NT \l_@@_split_path_a_final_tl
+ {
+ \tl_set_eq:NN \l_@@_split_path_a_final_tl \l_@@_split_path_a_tl
+ }
+ \tl_if_empty:NT \l_@@_split_path_b_final_tl
+ {
+ \tl_set_eq:NN \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl
+ }
+
+ \spath_remove_empty_components:N \l_@@_split_path_a_final_tl
+ \spath_remove_empty_components:N \l_@@_split_path_b_final_tl
+
+ \tl_gclear:N \g_@@_output_tl
+ \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_split_path_a_final_tl
+ \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_split_path_b_final_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_split_at_intersections:NNnn #1#2#3#4
+{
+ \@@_split_at_intersections:nn {#3}{#4}
+ \tl_set:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}}
+ \tl_set:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_split_at_intersections:NNnn {NNVV, ccVV, ccvv}
+\cs_new_protected_nopar:Npn \spath_split_at_intersections:NN #1#2
+{
+ \spath_split_at_intersections:NNVV #1#2#1#2
+}
+\cs_generate_variant:Nn \spath_split_at_intersections:NN {cc}
+\cs_new_protected_nopar:Npn \spath_gsplit_at_intersections:NNnn #1#2#3#4
+{
+ \@@_split_at_intersections:nn {#3}{#4}
+ \tl_gset:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}}
+ \tl_gset:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gsplit_at_intersections:NNnn {NNVV, ccVV, ccvv}
+\cs_new_protected_nopar:Npn \spath_gsplit_at_intersections:NN #1#2
+{
+ \spath_gsplit_at_intersections:NNVV #1#2#1#2
+}
+\cs_generate_variant:Nn \spath_gsplit_at_intersections:NN {cc}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_split_at_self_intersections:Nn,
+% \spath_split_at_self_intersections:N,
+% \spath_gsplit_at_self_intersections:Nn,
+% \spath_gsplit_at_self_intersections:N,
+% }
+% Given a path, split it at points where it self-intersects and store in the given macro.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_split_at_self_intersections:n #1
+{
+ \group_begin:
+
+ % Copy the path
+ \tl_set:Nn \l_@@_split_path_b_tl {#1}
+
+ % Open the path
+ \spath_open:N \l_@@_split_path_b_tl
+ % Remove empty components
+ \spath_remove_empty_components:N \l_@@_split_path_b_tl
+ % Make a copy for later
+ \tl_set_eq:NN \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl
+
+ % Clear some token lists and sequences
+ \tl_clear:N \l_@@_split_path_a_tl
+ \seq_clear:N \l_@@_split_first_seq
+ \int_zero:N \l_@@_split_segment_int
+
+ \pgfintersectionsortbyfirstpath
+
+ \bool_do_until:nn
+ {
+ \int_compare_p:n
+ {
+ \tl_count:N \l_@@_split_path_b_tl < 4
+ }
+ }
+ {
+ \tl_clear:N \l_@@_split_path_a_tl
+ \tl_put_right:Nx \l_@@_split_path_a_tl
+ {
+ \tl_item:Nn \l_@@_split_path_b_tl {1}
+ {\tl_item:Nn \l_@@_split_path_b_tl {2}}
+ {\tl_item:Nn \l_@@_split_path_b_tl {3}}
+ }
+
+ \tl_set:Nx \l_@@_tmpa_tl { \tl_item:Nn \l_@@_split_path_b_tl {4} }
+
+ \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
+
+ \int_zero:N \l_@@_tmpa_int
+
+ \tl_case:Nn \l_@@_tmpa_tl
+ {
+ \c_spath_moveto_tl
+ {
+ \tl_clear:N \l_@@_split_path_a_tl
+ \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
+ \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
+ \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
+ }
+ \c_spath_lineto_tl
+ {
+ \int_set:Nn \l_@@_tmpa_int {1}
+ }
+ \c_spath_curvetoa_tl
+ {
+ \int_set:Nn \l_@@_tmpa_int {3}
+ }
+ }
+
+ \prg_replicate:nn { \l_@@_tmpa_int }
+ {
+ \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
+ \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
+
+ \tl_put_right:Nx \l_@@_split_path_a_tl
+ {
+ \tl_item:Nn \l_@@_split_path_b_tl {1}
+ {\tl_item:Nn \l_@@_split_path_b_tl {2}}
+ {\tl_item:Nn \l_@@_split_path_b_tl {3}}
+ }
+
+ \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
+ }
+
+ \tl_put_left:NV \l_@@_split_path_b_tl \c_spath_moveto_tl
+
+ \tl_if_empty:NF \l_@@_split_path_a_tl
+ {
+ % Intersect the current segment with the rest of the path
+ \spath_intersect:NN \l_@@_split_path_a_tl \l_@@_split_path_b_tl
+
+
+ % If we get intersections
+ \int_compare:nT {\pgfintersectionsolutions > 0}
+ {
+ % Find the times of the intersections on each path
+ \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions}
+ {
+ \pgfintersectiongetsolutiontimes{##1}{\l_@@_split_first_tl}{\l_@@_split_second_tl}
+ \fp_compare:nT
+ {
+ \l_@@_split_first_tl < .99
+ }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\fp_to_decimal:n {\l_@@_split_first_tl + \l_@@_split_segment_int}}
+ \seq_put_right:NV \l_@@_split_first_seq \l_@@_tmpa_tl
+ }
+ }
+ }
+
+ \spath_intersect:NN \l_@@_split_path_b_tl \l_@@_split_path_a_tl
+
+ % If we get intersections
+ \int_compare:nT {\pgfintersectionsolutions > 0}
+ {
+ % Find the times of the intersections on each path
+ \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions}
+ {
+ \pgfintersectiongetsolutiontimes{##1}{\l_@@_split_first_tl}{\l_@@_split_second_tl}
+ \fp_compare:nT
+ {
+ \l_@@_split_first_tl > .01
+ }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\fp_to_decimal:n {\l_@@_split_first_tl + \l_@@_split_segment_int + 1}}
+ \seq_put_right:NV \l_@@_split_first_seq \l_@@_tmpa_tl
+ }
+ }
+ }
+
+ }
+ % Increment the segment counter
+ \int_incr:N \l_@@_split_segment_int
+ }
+
+ % Sort the sequence by reverse order along the path
+ \seq_sort:Nn \l_@@_split_first_seq
+ {
+ \fp_compare:nNnTF { ##1 } < { ##2 }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+
+ % Restore the original copy of the path
+ \tl_set_eq:NN \l_@@_split_path_b_tl \l_@@_split_path_b_final_tl
+
+ % Clear the token lists
+ \tl_clear:N \l_@@_split_path_b_start_tl
+ \tl_clear:N \l_@@_split_path_b_end_tl
+ \tl_clear:N \l_@@_split_path_b_final_tl
+
+ \tl_set:Nn \l_@@_split_prev_first_tl {-1}
+
+ \seq_map_inline:Nn \l_@@_split_first_seq
+ {
+ \tl_set:Nn \l_@@_split_first_tl {##1}
+ \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_split_first_tl
+ \int_compare:nT
+ {
+ \fp_to_int:n {floor( \l_@@_split_first_tl ) }
+ =
+ \fp_to_int:n {floor( \l_@@_split_prev_first_tl) }
+ }
+ {
+ \tl_set:Nx \l_@@_split_first_tl
+ {
+ \fp_eval:n {
+ floor( \l_@@_split_first_tl )
+ +
+ ( \l_@@_split_first_tl - floor( \l_@@_split_first_tl) )
+ /
+ ( \l_@@_split_prev_first_tl - floor( \l_@@_split_prev_first_tl) )
+ }
+ }
+ }
+ \tl_set_eq:NN \l_@@_split_prev_first_tl \l_@@_tmpa_tl
+
+ \spath_split_at:NNVV \l_@@_split_path_b_start_tl \l_@@_split_path_b_end_tl \l_@@_split_path_b_tl \l_@@_split_first_tl
+
+ \tl_put_left:NV \l_@@_split_path_b_final_tl \l_@@_split_path_b_end_tl
+ \tl_set_eq:NN \l_@@_split_path_b_tl \l_@@_split_path_b_start_tl
+
+ }
+
+ \tl_put_left:NV \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl
+
+ \tl_if_empty:NT \l_@@_split_path_b_final_tl
+ {
+ \tl_set_eq:NN \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl
+ }
+
+ \spath_remove_empty_components:N \l_@@_split_path_b_final_tl
+
+ \tl_gclear:N \g_@@_output_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_split_path_b_final_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_split_at_self_intersections:Nn #1#2
+{
+ \@@_split_at_self_intersections:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_split_at_self_intersections:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_split_at_self_intersections:N #1
+{
+ \spath_split_at_self_intersections:NV #1#1
+}
+\cs_generate_variant:Nn \spath_split_at_self_intersections:N {c}
+\cs_new_protected_nopar:Npn \spath_gsplit_at_self_intersections:Nn #1#2
+{
+ \@@_split_at_self_intersections:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gsplit_at_self_intersections:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_gsplit_at_self_intersections:N #1
+{
+ \spath_gsplit_at_self_intersections:NV #1#1
+}
+\cs_generate_variant:Nn \spath_gsplit_at_self_intersections:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{
+% \spath_join_component:Nnn,
+% \spath_join_component:Nn,
+% \spath_gjoin_component:Nnn,
+% \spath_gjoin_component:Nn,
+% }
+% Join the specified component of the spath to its predecessor.
+% \begin{macrocode}
+\tl_new:N \l_@@_tmpj_tl
+\cs_new_protected_nopar:Npn \@@_join_component:nn #1#2
+{
+ \group_begin:
+ \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1}
+ \int_compare:nT
+ {
+ #2 == 1
+ }
+ {
+ \tl_clear:N \l_@@_tmpj_tl
+ \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpj_tl
+
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_tmpj_tl {\tl_tail:N \l_@@_tmpj_tl}
+ }
+
+ \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpj_tl
+ }
+ \bool_if:nT
+ {
+ \int_compare_p:n
+ {
+ #2 > 1
+ }
+ &&
+ \int_compare_p:n
+ {
+ #2 <= \seq_count:N \l_@@_tmpa_seq
+ }
+ }
+ {
+
+ \seq_clear:N \l_@@_tmpb_seq
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
+ {
+ \tl_set:Nn \l_@@_tmpj_tl {##2}
+ \int_compare:nT {##1 = #2}
+ {
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_tmpj_tl {\tl_tail:N \l_@@_tmpj_tl}
+ }
+ }
+ \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpj_tl
+ }
+
+ \seq_set_eq:NN \l_@@_tmpa_seq \l_@@_tmpb_seq
+ }
+
+ \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpa_seq {} }
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_join_component:Nnn #1#2#3
+{
+ \@@_join_component:nn {#2}{#3}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_join_component:Nnn {NVn, NVV}
+\cs_new_protected_nopar:Npn \spath_join_component:Nn #1#2
+{
+ \spath_join_component:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_join_component:Nn {cn, NV, cV}
+\cs_new_protected_nopar:Npn \spath_gjoin_component:Nnn #1#2#3
+{
+ \@@_join_component:nn {#2}{#3}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gjoin_component:Nnn {NVn, NVV}
+\cs_new_protected_nopar:Npn \spath_gjoin_component:Nn #1#2
+{
+ \spath_gjoin_component:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_gjoin_component:Nn {cn, NV, cV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_spot_weld_components:Nn,
+% \spath_spot_weld_components:N,
+% \spath_spot_gweld_components:Nn,
+% \spath_spot_gweld_components:N,
+% }
+% Weld together any components where the last point of one is at the start point of the next (within a tolerance).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_spot_weld_components:n #1
+{
+ \group_begin:
+ \dim_zero:N \l_@@_move_x_dim
+ \dim_zero:N \l_@@_move_y_dim
+
+ \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1}
+ \seq_clear:N \l_@@_tmpb_seq
+ \dim_set:Nn \l_@@_move_x_dim {\tl_item:nn {#1} {2} + 10 pt}
+ \dim_set:Nn \l_@@_move_y_dim {\tl_item:nn {#1} {3} + 10 pt}
+
+ \int_set:Nn \l_@@_tmpa_int {\seq_count:N \l_@@_tmpa_seq}
+
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \tl_set:Nn \l_@@_tmpa_tl {##1}
+ \bool_if:nT
+ {
+ \dim_compare_p:n
+ {
+ \dim_abs:n {\l_@@_move_x_dim - \tl_item:Nn \l_@@_tmpa_tl {2} } < 0.01pt
+ }
+ &&
+ \dim_compare_p:n
+ {
+ \dim_abs:n {\l_@@_move_y_dim - \tl_item:Nn \l_@@_tmpa_tl {3} } < 0.01pt
+ }
+ }
+ {
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+ \int_decr:N \l_@@_tmpa_int
+ }
+ \tl_reverse:N \l_@@_tmpa_tl
+ \dim_set:Nn \l_@@_move_x_dim {\tl_item:Nn \l_@@_tmpa_tl {2}}
+ \dim_set:Nn \l_@@_move_y_dim {\tl_item:Nn \l_@@_tmpa_tl {1}}
+ \tl_reverse:N \l_@@_tmpa_tl
+ \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl
+ }
+
+ \tl_set:Nx \l_@@_tmpa_tl {\seq_use:Nn \l_@@_tmpb_seq {} }
+ \spath_components_to_seq:NV \l_@@_tmpb_seq \l_@@_tmpa_tl
+
+
+ \spath_initialpoint:Nn \l_@@_tmpa_tl {#1}
+ \spath_finalpoint:Nn \l_@@_tmpb_tl {#1}
+
+ \bool_if:nT
+ {
+ \dim_compare_p:n
+ {
+ \dim_abs:n {\tl_item:Nn \l_@@_tmpa_tl {1} - \tl_item:Nn \l_@@_tmpb_tl {1} } < 0.01pt
+ }
+ &&
+ \dim_compare_p:n
+ {
+ \dim_abs:n {\tl_item:Nn \l_@@_tmpa_tl {2} - \tl_item:Nn \l_@@_tmpb_tl {2} } < 0.01pt
+ }
+ }
+ {
+ \int_compare:nTF
+ {
+ \seq_count:N \l_@@_tmpb_seq > 1
+ }
+ {
+ \seq_pop_left:NN \l_@@_tmpb_seq \l_@@_tmpb_tl
+
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_tail:N \l_@@_tmpb_tl}
+ }
+ \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpb_tl
+ }
+ {
+ \tl_set:NV \l_@@_tmpb_tl \c_spath_closepath_tl
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ { \tl_item:Nn \l_@@_tmpa_tl {1} }
+ { \tl_item:Nn \l_@@_tmpa_tl {2} }
+ }
+ \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpb_tl
+ }
+ }
+
+ \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpb_seq {}}
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_spot_weld_components:Nn #1#2
+{
+ \@@_spot_weld_components:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_spot_weld_components:Nn {NV, cV, cn}
+\cs_new_protected_nopar:Npn \spath_spot_weld_components:N #1
+{
+ \spath_spot_weld_components:NV #1#1
+}
+\cs_generate_variant:Nn \spath_spot_weld_components:N {c}
+\cs_new_protected_nopar:Npn \spath_spot_gweld_components:Nn #1#2
+{
+ \@@_spot_weld_components:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_spot_gweld_components:Nn {NV, cV, cn}
+\cs_new_protected_nopar:Npn \spath_spot_gweld_components:N #1
+{
+ \spath_spot_gweld_components:NV #1#1
+}
+\cs_generate_variant:Nn \spath_spot_gweld_components:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Exporting Commands}
+%
+% \begin{macro}{
+% \spath_convert_to_svg:Nn,
+% \spath_gconvert_to_svg:Nn,
+% }
+% Convert the soft path to an SVG document.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_convert_to_svg:n #1
+{
+ \group_begin:
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_put_right:Nn \l_@@_tmpa_tl
+ {
+ <?xml~ version="1.0"~ standalone="no"?>
+ \iow_newline:
+ <!DOCTYPE~ svg~ PUBLIC~ "-//W3C//DTD SVG 1.1//EN"~
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+ \iow_newline:
+ <svg~ xmlns="http://www.w3.org/2000/svg"~ version="1.1"~viewBox="
+ }
+
+ \spath_minbb:Nn \l_@@_tmpb_tl {#1}
+ \spath_maxbb:Nn \l_@@_tmpc_tl {#1}
+ \tl_put_right:Nx \l_@@_tmpa_tl
+ {
+ \dim_to_decimal:n
+ {
+ \tl_item:Nn \l_@@_tmpb_tl {1} - 10pt
+ }
+ \exp_not:n {~}
+ \dim_to_decimal:n
+ {
+ \tl_item:Nn \l_@@_tmpb_tl {2} - 10pt
+ }
+ \exp_not:n {~}
+ \dim_to_decimal:n
+ {
+ \tl_item:Nn \l_@@_tmpc_tl {1}
+ -
+ \tl_item:Nn \l_@@_tmpb_tl {1}
+ + 20pt
+ }
+ \exp_not:n {~}
+ \dim_to_decimal:n
+ {
+ \tl_item:Nn \l_@@_tmpc_tl {2}
+ -
+ \tl_item:Nn \l_@@_tmpb_tl {2}
+ + 20pt
+ }
+ }
+
+ \tl_put_right:Nn \l_@@_tmpa_tl
+ {
+ ">
+ \iow_newline:
+ <path~ d="
+ }
+ \tl_set:Nn \l_@@_tmpc_tl {use:n}
+ \tl_map_inline:Nn #1
+ {
+ \tl_set:Nn \l_@@_tmpb_tl {##1}
+ \tl_case:NnF \l_@@_tmpb_tl
+ {
+ \c_spath_moveto_tl
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {M~}
+ \tl_set:Nn \l_@@_tmpc_tl {use:n}
+ }
+ \c_spath_lineto_tl
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {L~}
+ \tl_set:Nn \l_@@_tmpc_tl {use:n}
+ }
+ \c_spath_closepath_tl
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {Z~}
+ \tl_set:Nn \l_@@_tmpc_tl {use_none:n}
+ }
+ \c_spath_curvetoa_tl
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {C~}
+ \tl_set:Nn \l_@@_tmpc_tl {use:n}
+ }
+ \c_spath_curvetob_tl {
+ \tl_set:Nn \l_@@_tmpc_tl {use:n}
+ }
+ \c_spath_curveto_tl {
+ \tl_set:Nn \l_@@_tmpc_tl {use:n}
+ }
+ }
+ {
+ \tl_put_right:Nx \l_@@_tmpa_tl {\use:c { \l_@@_tmpc_tl } {\dim_to_decimal:n {##1}} ~}
+ }
+ }
+ \tl_put_right:Nn \l_@@_tmpa_tl
+ {
+ "~ fill="none"~ stroke="black"~ />
+ \iow_newline:
+ </svg>
+ \iow_newline:
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_convert_to_svg:Nn #1#2
+{
+ \@@_convert_to_svg:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_new_protected_nopar:Npn \spath_gconvert_to_svg:Nn #1#2
+{
+ \@@_convert_to_svg:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_export_to_svg:nn
+% }
+% Save a soft path to an SVG file.
+% \begin{macrocode}
+\iow_new:N \g_@@_stream
+\cs_new_protected_nopar:Npn \spath_export_to_svg:nn #1#2
+{
+ \spath_convert_path_to_svg:Nn \l_@@_iterp_tl {#2}
+ \iow_open:Nn \g_@@_stream {#1 .svg}
+ \iow_now:Nx \g_@@_stream
+ {
+ \tl_use:N \l_@@_iterp_tl
+ }
+ \iow_close:N \g_@@_stream
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\spath_show:n}
+% Displays the soft path on the terminal.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_show:n #1
+{
+ \int_step_inline:nnnn {1} {3} {\tl_count:n {#1}}
+ {
+ \iow_term:x {
+ \tl_item:Nn \l_@@_tmpa_tl {##1}
+ {\tl_item:Nn \l_@@_tmpa_tl {##1+1}}
+ {\tl_item:Nn \l_@@_tmpa_tl {##1+2}}
+ }
+ }
+}
+\cs_generate_variant:Nn \spath_show:n {V, v}
+% \end{macrocode}
+% \end{macro}
+
+% \subsubsection{PGF and TikZ Interface Functions}
+%
+% Spaths come from PGF so we need some functions that get and set spaths from the pgf system.
+%
+% \begin{macro}{
+% \spath_get_current_path:N,
+% \spath_gget_current_path:N
+% }
+% Grab the current soft path from PGF.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_get_current_path:N #1
+{
+ \pgfsyssoftpath@getcurrentpath #1
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_gget_current_path:N #1
+{
+ \pgfsyssoftpath@getcurrentpath #1
+ \tl_gset_eq:NN #1 #1
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\spath_protocol_path:n}
+% This feeds the bounding box of the soft path to PGF to ensure that its current bounding box contains the soft path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_protocol_path:n #1
+{
+ \spath_minbb:Nn \l_@@_tmpa_tl {#1}
+ \exp_last_unbraced:NV \pgf@protocolsizes\l_@@_tmpa_tl
+
+ \spath_maxbb:Nn \l_@@_tmpa_tl {#1}
+ \exp_last_unbraced:NV \pgf@protocolsizes\l_@@_tmpa_tl
+}
+\cs_generate_variant:Nn \spath_protocol_path:n {V}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_set_current_path:n,
+% \spath_set_current_path:N
+% }
+% Sets the current path to the specified soft path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_set_current_path:n #1
+{
+ \spath_protocol_path:n {#1}
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \pgfsyssoftpath@setcurrentpath\l_@@_tmpa_tl
+}
+\cs_new_protected_nopar:Npn \spath_set_current_path:N #1
+{
+ \spath_protocol_path:V #1
+ \pgfsyssoftpath@setcurrentpath #1
+}
+\cs_generate_variant:Nn \spath_set_current_path:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \spath_use_path:nn
+% }
+% Uses the given soft path at the PGF level.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_use_path:nn #1#2
+{
+ \spath_set_current_path:n {#1}
+ \pgfusepath{#2}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\spath_tikz_path:nn}
+% Uses the given soft path at the TikZ level.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_tikz_path:nn #1#2
+{
+ \path[#1] \pgfextra{
+ \spath_set_current_path:n {#2}
+ \tl_put_right:Nn \tikz@preactions {\def\tikz@actions@path{#2}}
+ };
+}
+\cs_generate_variant:Nn \spath_tikz_path:nn {Vn, VV, nv, Vv, nV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\spath_set_tikz_coords:n}
+% Sets the \Verb+\tikz@lastx+ and other coordinates from the soft path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \spath_set_tikz_coords:n #1
+{
+ \spath_finalpoint:Nn \l_@@_tmpa_tl {#1}
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \exp_not:c {tikz@lastx}=\tl_item:Nn \l_@@_tmpa_tl {1}
+ \exp_not:c {tikz@lasty}=\tl_item:Nn \l_@@_tmpa_tl {2}
+ \exp_not:c {tikz@lastxsaved}=\tl_item:Nn \l_@@_tmpa_tl {1}
+ \exp_not:c {tikz@lastysaved}=\tl_item:Nn \l_@@_tmpa_tl {2}
+ }
+ \tl_use:N \l_@@_tmpa_tl
+}
+\cs_generate_variant:Nn \spath_set_tikz_coords:n {V, v}
+% \end{macrocode}
+% \end{macro}
+%
+% \iffalse
+%</spath3>
+% \fi
+%
+% \section{The TikZ interface}
+%
+% \iffalse
+%<*tikzspath3>
+% \fi
+%
+% This provides an interface to the soft path manipulation routines via a series of TikZ keys.
+% They all live in the \texttt{spath} family.
+%
+%
+% \begin{macrocode}
+\RequirePackage{spath3}
+\RequirePackage{expl3}
+\ExplSyntaxOn
+
+\tl_new:N \l_@@_current_tl
+\tl_new:N \l_@@_reverse_tl
+\tl_new:N \l_@@_prefix_tl
+\tl_new:N \l_@@_suffix_tl
+\tl_new:N \g_@@_smuggle_tl
+\seq_new:N \g_@@_tmpa_seq
+\seq_new:N \g_@@_tmpb_seq
+\bool_new:N \l_@@_draft_bool
+% \end{macrocode}
+%
+% When saving a soft path, by default we use a naming convention that is compatible with the intersections library so that paths saved here and paths saved by the \texttt{name path} facility of the intersections library are mutually exchangeable.
+%
+% \begin{macrocode}
+\tl_set:Nn \l_@@_prefix_tl {tikz@intersect@path@name@}
+\tl_set:Nn \l_@@_suffix_tl {}
+% \end{macrocode}
+%
+% When a soft path is grabbed from TikZ we're usually deep in a group so I've adapted the code from the intersections library to dig the definition out of the group without making everything global.
+%
+% \begin{macrocode}
+\tl_new:N \g_@@_tikzfinish_tl
+\cs_new_protected_nopar:Npn \spath_at_end_of_path:
+{
+ \tl_use:N \g_@@_tikzfinish_tl
+ \tl_gclear:N \g_@@_tikzfinish_tl
+}
+\tl_put_right:Nn \tikz@finish {\spath_at_end_of_path:}
+
+\cs_new_protected_nopar:Npn \spath_save_path:Nn #1#2
+{
+ \tl_gput_right:Nn \g_@@_tikzfinish_tl
+ {
+ \tl_clear_new:N #1
+ \tl_set:Nn #1 {#2}
+ }
+}
+\cs_generate_variant:Nn \spath_save_path:Nn {cn, NV, cV}
+
+\cs_new_protected_nopar:Npn \spath_gsave_path:Nn #1#2
+{
+ \tl_gput_right:Nn \g_@@_tikzfinish_tl
+ {
+ \tl_gclear_new:N #1
+ \tl_gset:Nn #1 {#2}
+ }
+}
+\cs_generate_variant:Nn \spath_gsave_path:Nn {cn, NV, cV}
+% \end{macrocode}
+%
+% Now we define all of our keys.
+%
+% \begin{macrocode}
+\tikzset{
+% \end{macrocode}
+%
+% We're in the \texttt{spath} key family.
+%
+% \begin{macrocode}
+ spath/.is~family,
+ spath/.cd,
+% \end{macrocode}
+%
+% We provide for saving soft paths with a specific prefix and suffix in the name.
+% The default is to make it compatible with the intersections library.
+%
+% \begin{macrocode}
+ set~ prefix/.store~ in=\l_@@_prefix_tl,
+ prefix/.is~choice,
+ prefix/default/.style={
+ /tikz/spath/set~ prefix=tikz@intersect@path@name@
+ },
+ set~ suffix/.store~ in=\l_@@_suffix_tl,
+ suffix/.is~choice,
+ suffix/default/.style={
+ /tikz/spath/set~ suffix={}
+ },
+ set~ name/.style={
+ /tikz/spath/prefix=#1,
+ /tikz/spath/suffix=#1
+ },
+% \end{macrocode}
+%
+% Keys for saving and cloning a soft path.
+%
+% \begin{macrocode}
+ save/.code={
+ \tikz@addmode{
+ \spath_get_current_path:N \l_@@_tmpa_tl
+ \spath_bake_round:NV \l_@@_tmpa_tl \l_@@_tmpa_tl
+ \spath_save_path:cV {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} \l_@@_tmpa_tl
+ }
+ },
+ clone/.code~ 2~ args={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_clear_new:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_set_eq:cc
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ },
+ clone~ global/.code~ 2~ args={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_gclear_new:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_gset_eq:cc
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ },
+ save~ global/.code={
+ \tikz@addmode{
+ \spath_get_current_path:N \l_@@_tmpa_tl
+ \spath_bake_round:NV \l_@@_tmpa_tl \l_@@_tmpa_tl
+ \spath_gsave_path:cV
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \l_@@_tmpa_tl
+ }
+ },
+% \end{macrocode}
+%
+% Saves a soft path to the aux file.
+%
+% \begin{macrocode}
+ save~ to~ aux/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_save_to_aux:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ },
+% \end{macrocode}
+%
+% Restores a soft path to the current path.
+%
+% \begin{macrocode}
+ restore/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_set_current_path:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \spath_set_tikz_coords:v
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ },
+% \end{macrocode}
+%
+% Diagnostic, show the current path in the terminal and log.
+%
+% \begin{macrocode}
+ show~current~path/.code={
+ \tikz@addmode{
+ \pgfsyssoftpath@getcurrentpath\l_@@_tmpa_tl
+ \iow_term:n {---~ current~ soft~ path~ ---}
+ \spath_show:V \l_@@_tmpa_tl
+ }
+ },
+% \end{macrocode}
+%
+% Diagnostic, show the named soft path in the terminal and log.
+%
+% \begin{macrocode}
+ show/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \iow_term:n {---~ soft~ path~ #1~ ---}
+ \spath_show:v {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ },
+% \end{macrocode}
+%
+% Appends the named path to the current path with a weld.
+%
+% \begin{macrocode}
+ append/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_get_current_path:N \l_@@_current_tl
+ \spath_weld:Nv
+ \l_@@_current_tl
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \spath_set_current_path:N \l_@@_current_tl
+ \spath_set_tikz_coords:V \l_@@_current_tl
+ }
+ },
+% \end{macrocode}
+%
+% Joins the second named path to the first.
+%
+% \begin{macrocode}
+ join~ with/.code~ 2~ args={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_append:cv
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ }
+ },
+% \end{macrocode}
+%
+% Does a ``spot weld'' on a soft path, which means that any components that start where the previous component ends are welded together.
+%
+% \begin{macrocode}
+ spot~ weld/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_spot_weld_components:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ },
+% \end{macrocode}
+%
+% Reverses the named path.
+%
+% \begin{macrocode}
+ reverse/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_reverse:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ },
+% \end{macrocode}
+%
+% Appends the reversal of the path to the current path.
+%
+% \begin{macrocode}
+ append~ reverse/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_reverse:Nv
+ \l_@@_reverse_tl
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \spath_get_current_path:N \l_@@_current_tl
+ \spath_weld:NV \l_@@_current_tl \l_@@_reverse_tl
+ \spath_set_current_path:N \l_@@_current_tl
+ \spath_set_tikz_coords:V \l_@@_current_tl
+ }
+ },
+% \end{macrocode}
+%
+% Inserts the named path into the current path as-is, meaning without transforming or welding it.
+%
+% \begin{macrocode}
+ insert/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_get_current_path:N \l_@@_current_tl
+ \spath_append:Nv
+ \l_@@_current_tl
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \spath_set_current_path:N \l_@@_current_tl
+ \spath_set_tikz_coords:V \l_@@_current_tl
+ }
+ },
+% \end{macrocode}
+%
+% Inserts the reverse of the named path.
+%
+% \begin{macrocode}
+ insert~ reverse/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_reverse:Nv
+ \l_@@_reverse_tl
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \spath_get_current_path:N \l_@@_current_tl
+ \spath_append:NV \l_@@_current_tl \l_@@_reverse_tl
+ \spath_set_current_path:N \l_@@_current_tl
+ \spath_set_tikz_coords:V \l_@@_current_tl
+ }
+ },
+% \end{macrocode}
+%
+% These keys shorten the path.
+%
+% \begin{macrocode}
+ shorten~ at~ end/.code~ 2~ args={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_shorten_at_end:cn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2}
+ }
+ },
+ shorten~ at~ start/.code~ 2~ args ={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_shorten_at_start:cn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2}
+ }
+ },
+ shorten~ at~ both~ ends/.code~ 2~ args={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_shorten_at_end:cn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2}
+ \spath_shorten_at_start:cn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2}
+ }
+ },
+% \end{macrocode}
+%
+% This translates the named path.
+%
+% \begin{macrocode}
+ translate/.code~ n~ args={3}{
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_translate:cnn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}{#2}{#3}
+ }
+ },
+% \end{macrocode}
+%
+% Exports the path as an SVG file.
+%
+% \begin{macrocode}
+ export~ to~ svg/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_export_to_svg:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ },
+% \end{macrocode}
+%
+% Transforms the named path using TikZ transformation specifications.
+%
+% \begin{macrocode}
+ transform/.code~ 2~ args={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \group_begin:
+ \pgftransformreset
+ \tikzset{#2}
+ \pgfgettransform \l_@@_tmpa_tl
+ \tl_gset:Nn \g_@@_smuggle_tl
+ {
+ \spath_transform:cnnnnnn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ \tl_gput_right:NV \g_@@_smuggle_tl \l_@@_tmpa_tl
+ \group_end:
+ \tl_use:N \g_@@_smuggle_tl
+ }
+ },
+ transform~global/.code~ 2~ args={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \group_begin:
+ \pgftransformreset
+ \tikzset{#2}
+ \pgfgettransform \l_@@_tmpa_tl
+ \tl_gset:Nn \g_@@_smuggle_tl
+ {
+ \spath_gtransform:cnnnnnn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ \tl_gput_right:NV \g_@@_smuggle_tl \l_@@_tmpa_tl
+ \group_end:
+ \tl_use:N \g_@@_smuggle_tl
+ }
+ },
+% \end{macrocode}
+%
+% Splits two paths at their mutual intersections.
+%
+% \begin{macrocode}
+ split~ at~ intersections/.code~ n~ args={2}{
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_split_at_intersections:cc
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ }
+ },
+% \end{macrocode}
+%
+% Splits a path at its self-intersections.
+%
+% \begin{macrocode}
+ split~ at~ self~ intersections/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_split_at_self_intersections:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ },
+% \end{macrocode}
+%
+% Extract the components of a path into a comma separated list (suitable for using in a \Verb+\foreach+ loop).
+%
+% \begin{macrocode}
+ get~ components~ of/.code~ 2~ args={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \clist_clear_new:N #2
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \tl_new:c
+ {\tl_use:N \l_@@_prefix_tl anonymous_\int_use:N \g_@@_anon_int \tl_use:N \l_@@_suffix_tl}
+ \tl_set:cn
+ {\tl_use:N \l_@@_prefix_tl anonymous_\int_use:N \g_@@_anon_int \tl_use:N \l_@@_suffix_tl} {##1}
+ \clist_put_right:Nx #2 {anonymous_\int_use:N \g_@@_anon_int}
+ \int_gincr:N \g_@@_anon_int
+ }
+ }
+ },
+% \end{macrocode}
+%
+% Loop through the components of a soft path and render each as a separate TikZ path so that they can be individually styled.
+%
+% \begin{macrocode}
+ render~ components/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \group_begin:
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
+ {
+ \spath_tikz_path:nn
+ {
+ every~ spath~ component/.try,
+ spath ~component~ ##1/.try,
+ spath ~component/.try={##1},
+ every~ #1~ component/.try,
+ #1 ~component~ ##1/.try,
+ #1 ~component/.try={##1},
+ }
+ {
+ ##2
+ }
+ }
+ \group_end:
+ }
+ },
+% \end{macrocode}
+%
+% This puts gaps between components of a soft path.
+% The list of components is passed through a \Verb+\foreach+ loop so can use the shortcut syntax from those loops.
+%
+% \begin{macrocode}
+ insert~ gaps~ after~ components/.code~ n~ args={3}{
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \group_begin:
+ \seq_gclear:N \g_@@_tmpa_seq
+ \seq_gclear:N \g_@@_tmpb_seq
+ \foreach \l_@@_tmpa_tl in {#3}
+ {
+ \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
+ \seq_gput_right:Nx \g_@@_tmpb_seq {\int_eval:n { \l_@@_tmpa_tl + 1 }}
+ }
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \seq_clear:N \l_@@_tmpb_seq
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
+ {
+ \tl_set:Nn \l_@@_tmpa_tl {##2}
+ \seq_if_in:NnT \g_@@_tmpa_seq {##1}
+ {
+ \spath_shorten_at_end:Nn \l_@@_tmpa_tl {#2/2}
+ }
+ \seq_if_in:NnT \g_@@_tmpb_seq {##1}
+ {
+ \spath_shorten_at_start:Nn \l_@@_tmpa_tl {#2/2}
+ }
+ \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl
+ }
+ \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpb_seq {} }
+ \group_end:
+ \tl_set_eq:cN
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+ }
+ },
+% \end{macrocode}
+%
+% Join the specified components together, joining each to its previous one.
+%
+% \begin{macrocode}
+ join~ components/.code~ 2~ args={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \seq_gclear:N \g_@@_tmpa_seq
+ \foreach \l_@@_tmpa_tl in {#2}
+ {
+ \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
+ }
+ \seq_gsort:Nn \g_@@_tmpa_seq
+ {
+ \int_compare:nNnTF {##1} > {##2}
+ { \sort_return_same: }
+ { \sort_return_swapped: }
+ }
+ \seq_map_inline:Nn \g_@@_tmpa_seq
+ {
+ \spath_join_component:cn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}{##1}
+ }
+ }
+ },
+% \end{macrocode}
+%
+% Remove all components of the path that don't actually draw anything.
+%
+% \begin{macrocode}
+ remove~ empty~ components/.code={
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_remove_empty_components:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ },
+% \end{macrocode}
+%
+% This puts a conditional around the \texttt{spot weld} key because when figuring out a knot drawing then we will initially want to render it without the spot weld to keep the number of components constant.
+%
+% \begin{macrocode}
+ draft~ mode/.is~ choice,
+ draft~ mode/true/.code={
+ \bool_set_true:N \l_@@_draft_bool
+ },
+ draft~ mode/false/.code={
+ \bool_set_false:N \l_@@_draft_bool
+ },
+ maybe~ spot~ weld/.code={
+ \bool_if:NF \l_@@_draft_bool
+ {
+ \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_spot_weld_components:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ }
+ },
+% \end{macrocode}
+%
+% Set the transformation to lie along a path.
+%
+% \begin{macrocode}
+ transform~ to/.code~ 2~ args={
+ \group_begin:
+ \tl_if_exist:cTF
+ {
+ \tl_use:N \l_@@_prefix_tl
+ #1
+ \tl_use:N \l_@@_suffix_tl
+ }
+ {
+ \spath_reallength:Nv
+ \l_@@_tmpa_int
+ {
+ \tl_use:N \l_@@_prefix_tl
+ #1
+ \tl_use:N \l_@@_suffix_tl
+ }
+
+ \tl_set:Nx \l_@@_tmpb_tl
+ {\fp_to_decimal:n {(#2) * (\l_@@_tmpa_int)}}
+ \spath_transformation_at:NvV \l_@@_tmpc_tl
+ {
+ \tl_use:N \l_@@_prefix_tl
+ #1
+ \tl_use:N \l_@@_suffix_tl
+ }
+ \l_@@_tmpb_tl
+ \tl_gset_eq:NN \g_@@_smuggle_tl \l_@@_tmpc_tl
+ }
+ {
+ \tl_gset_eq:NN \g_@@_smuggle_tl { {1}{0}{0}{1}{0pt}{0pt} }
+ }
+ \group_end:
+ \exp_last_unbraced:NV \pgfsettransformentries \g_@@_smuggle_tl
+ \tl_gclear:N \g_@@_smuggle_tl
+ },
+% \end{macrocode}
+%
+% As above, but with a possible extra \(180^\circ\) rotation if needed to ensure that the new \(y\)--axis points vaguely upwards.
+%
+% \begin{macrocode}
+ upright~ transform~ to/.code~ 2~ args={
+ \group_begin:
+ \tl_if_exist:cTF
+ {
+ \tl_use:N \l_@@_prefix_tl
+ #1
+ \tl_use:N \l_@@_suffix_tl
+ }
+ {
+ \spath_reallength:Nv
+ \l_@@_tmpa_int
+ {
+ \tl_use:N \l_@@_prefix_tl
+ #1
+ \tl_use:N \l_@@_suffix_tl
+ }
+
+ \tl_set:Nx \l_@@_tmpb_tl
+ {\fp_to_decimal:n {(#2) * (\l_@@_tmpa_int)}}
+ \spath_transformation_at:NvV \l_@@_tmpc_tl
+ {
+ \tl_use:N \l_@@_prefix_tl
+ #1
+ \tl_use:N \l_@@_suffix_tl
+ }
+ \l_@@_tmpb_tl
+ \tl_gset_eq:NN \g_@@_smuggle_tl \l_@@_tmpc_tl
+ }
+ {
+ \tl_gset_eq:NN \g_@@_smuggle_tl { {1}{0}{0}{1}{0pt}{0pt} }
+ }
+ \fp_compare:nT { \tl_item:Nn \g_@@_smuggle_tl {4} < 0}
+ {
+ \tl_gset:Nx \g_@@_smuggle_tl
+ {
+ { \fp_eval:n { - (\tl_item:Nn \g_@@_smuggle_tl {1})} }
+ { \fp_eval:n { - (\tl_item:Nn \g_@@_smuggle_tl {2})} }
+ { \fp_eval:n { - (\tl_item:Nn \g_@@_smuggle_tl {3})} }
+ { \fp_eval:n { - (\tl_item:Nn \g_@@_smuggle_tl {4})} }
+ { \tl_item:Nn \g_@@_smuggle_tl {5} }
+ { \tl_item:Nn \g_@@_smuggle_tl {6} }
+ }
+ }
+ \group_end:
+ \exp_last_unbraced:NV \pgfsettransformentries \g_@@_smuggle_tl
+ \tl_gclear:N \g_@@_smuggle_tl
+ },
+% \end{macrocode}
+%
+% This is a useful set of styles for drawing a knot diagram.
+%
+% \begin{macrocode}
+ knot/.style~ n~ args={3}{
+ spath/.cd,
+ split~ at~ self~ intersections=#1,
+ insert~ gaps~ after~ components={#1}{#2}{#3},
+ maybe~ spot~ weld=#1,
+ render~ components=#1
+ },
+}
+% \end{macrocode}
+%
+% This defines a coordinate system that finds a position on a soft path.
+%
+% \begin{macrocode}
+\tikzdeclarecoordinatesystem{spath}{%
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_trim_spaces:N \l_@@_tmpa_tl
+
+ \seq_set_split:NnV \l_@@_tmpa_seq {~} \l_@@_tmpa_tl
+ \seq_pop_right:NN \l_@@_tmpa_seq \l_@@_tmpb_tl
+
+ \tl_set:Nx \l_@@_tmpa_tl { \seq_use:Nn \l_@@_tmpa_seq {~} }
+ \tl_if_exist:cTF
+ {
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_tmpa_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+ {
+
+ \tl_set_eq:Nc
+ \l_@@_tmpa_tl
+ {
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_tmpa_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+
+ \tl_if_empty:NTF \l_@@_tmpa_tl
+ {
+ \tl_gset_eq:NN \g_@@_smuggle_tl \pgfpointorigin
+ }
+ {
+ \spath_reallength:NV \l_@@_tmpa_int \l_@@_tmpa_tl
+ \tl_set:Nx \l_@@_tmpb_tl
+ {\fp_to_decimal:n {(\l_@@_tmpb_tl) * (\l_@@_tmpa_int)}}
+ \spath_point_at:NVV \l_@@_tmpc_tl \l_@@_tmpa_tl \l_@@_tmpb_tl
+
+ \tl_clear:N \l_@@_tmpd_tl
+ \tl_put_right:Nn \l_@@_tmpd_tl {\pgf@x=}
+ \tl_put_right:Nx \l_@@_tmpd_tl {\tl_item:Nn \l_@@_tmpc_tl {1}}
+ \tl_put_right:Nn \l_@@_tmpd_tl {\relax}
+ \tl_put_right:Nn \l_@@_tmpd_tl {\pgf@y=}
+ \tl_put_right:Nx \l_@@_tmpd_tl {\tl_item:Nn \l_@@_tmpc_tl {2}}
+ \tl_put_right:Nn \l_@@_tmpd_tl {\relax}
+ \tl_gset_eq:NN \g_@@_smuggle_tl \l_@@_tmpd_tl
+ }
+ }
+ {
+ \tl_gset_eq:NN \g_@@_smuggle_tl \pgfpointorigin
+ }
+ \group_end:
+ \tl_use:N \g_@@_smuggle_tl
+}
+
+\ExplSyntaxOff
+% \end{macrocode}
+% \iffalse
+%</tikzspath3>
+% \fi
+%
+% \iffalse
+%<*calligraphy>
+% \fi
+%
+% \section{The Calligraphy Package}
+%
+% \begin{macrocode}
+%<@@=cal>
+% \end{macrocode}
+%
+% \subsection{Initialisation}
+% \begin{macrocode}
+\RequirePackage{spath3}
+\ExplSyntaxOn
+
+\tl_new:N \l_@@_tmpa_tl
+\tl_new:N \l_@@_tmpb_tl
+\tl_new:N \l_@@_tmp_path_tl
+\tl_new:N \l_@@_tmp_rpath_tl
+\tl_new:N \l_@@_tmp_rpathb_tl
+\tl_new:N \l_@@_tmp_patha_tl
+
+\seq_new:N \l_@@_tmpa_seq
+
+\int_new:N \l_@@_tmpa_int
+\int_new:N \l_@@_tmpb_int
+\int_new:N \g_@@_path_component_int
+\int_new:N \g_@@_label_int
+
+\fp_new:N \l_@@_tmpa_fp
+\fp_new:N \l_@@_tmpb_fp
+\fp_new:N \l_@@_tmpc_fp
+\fp_new:N \l_@@_tmpd_fp
+\fp_new:N \l_@@_tmpe_fp
+
+\dim_new:N \l_@@_tmpa_dim
+\dim_new:N \l_@@_tmpb_dim
+\dim_new:N \l_@@_tmpc_dim
+\dim_new:N \l_@@_tmpd_dim
+\dim_new:N \l_@@_tmpe_dim
+\dim_new:N \l_@@_tmpf_dim
+\dim_new:N \l_@@_tmpg_dim
+\dim_new:N \l_@@_tmph_dim
+
+\bool_new:N \l_@@_annotate_bool
+\bool_new:N \l_@@_taper_start_bool
+\bool_new:N \l_@@_taper_end_bool
+\bool_new:N \l_@@_taperable_bool
+
+\dim_new:N \l_@@_taper_width_dim
+\dim_new:N \l_@@_line_width_dim
+
+\bool_set_true:N \l_@@_taper_start_bool
+\bool_set_true:N \l_@@_taper_end_bool
+
+\cs_generate_variant:Nn \tl_put_right:Nn {Nv}
+
+\msg_new:nnn { calligraphy } { undefined pen } { The~ pen~ "#1"~ is~ not~ defined. }
+% \end{macrocode}
+%
+% \subsection{TikZ Keys}
+%
+% The public interface to this package is through TikZ keys and styles.
+% \begin{macrocode}
+\tikzset{
+ define~pen/.code={
+ \tikzset{pen~name=#1}
+ \pgf@relevantforpicturesizefalse
+ \tikz@addmode{
+ \pgfsyssoftpath@getcurrentpath\l_@@_tmpa_tl
+ \spath_components_to_seq:NV \l_@@_tmpa_seq \l_@@_tmpa_tl
+ \seq_gclear_new:c {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq}
+ \seq_gset_eq:cN {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq} \l_@@_tmpa_seq
+ \pgfusepath{discard}%
+ }
+ },
+ define~pen/.default={default},
+ use~pen/.code={
+ \tikzset{pen~name=#1}
+ \int_gzero:N \g_@@_path_component_int
+ \cs_set_eq:NN \pgfpathmoveto \cal_moveto:n
+ \tikz@addmode{
+ \pgfsyssoftpath@getcurrentpath\l_@@_tmpa_tl
+ \spath_components_to_seq:NV \l_@@_tmpa_seq \l_@@_tmpa_tl
+ \tl_if_exist:cTF {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq}
+ {
+ \cal_path_create:Nc \l_@@_tmpa_seq {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq}
+ }
+ {
+ \msg_warning:nnx { calligraphy } { undefined pen } { \pgfkeysvalueof{/tikz/pen~name} }
+ }
+ }
+ },
+ use~pen/.default={default},
+ pen~name/.initial={default},
+ copperplate/.style={pen~name=copperplate},
+ pen~colour/.initial={black},
+ weight/.is~choice,
+ weight/heavy/.style={
+ line~width=\pgfkeysvalueof{/tikz/heavy~line~width},
+ taper~width=\pgfkeysvalueof{/tikz/light~line~width},
+ },
+ weight/light/.style={
+ line~width=\pgfkeysvalueof{/tikz/light~line~width},
+ taper~width=0pt,
+ },
+ heavy/.style={
+ weight=heavy
+ },
+ light/.style={
+ weight=light
+ },
+ heavy~line~width/.initial=2pt,
+ light~line~width/.initial=1pt,
+ taper/.is~choice,
+ taper/.default=both,
+ taper/none/.style={
+ taper~start=false,
+ taper~end=false,
+ },
+ taper/both/.style={
+ taper~start=true,
+ taper~end=true,
+ },
+ taper/start/.style={
+ taper~start=true,
+ taper~end=false,
+ },
+ taper/end/.style={
+ taper~start=false,
+ taper~end=true,
+ },
+ taper~start/.code={
+ \tl_if_eq:nnTF {#1} {true}
+ {
+ \bool_set_true:N \l_@@_taper_start_bool
+ }
+ {
+ \bool_set_false:N \l_@@_taper_start_bool
+ }
+ },
+ taper~start/.default={true},
+ taper~end/.code={
+ \tl_if_eq:nnTF {#1} {true}
+ {
+ \bool_set_true:N \l_@@_taper_end_bool
+ }
+ {
+ \bool_set_false:N \l_@@_taper_end_bool
+ }
+ },
+ taper~end/.default={true},
+ taper~width/.code={\dim_set:Nn \l_@@_taper_width_dim {#1}},
+ nib~style/.code~2~args={
+ \tl_clear_new:c {l_@@_nib_style_#1}
+ \tl_set:cn {l_@@_nib_style_#1} {#2}
+ },
+ stroke~style/.code~2~args={
+ \tl_clear_new:c {l_@@_stroke_style_#1}
+ \tl_set:cn {l_@@_stroke_style_#1} {#2}
+ },
+ this~stroke~style/.code={
+ \tl_clear_new:c {l_@@_stroke_inline_style_ \int_use:N \g_@@_path_component_int}
+ \tl_set:cn {l_@@_stroke_inline_style_ \int_use:N \g_@@_path_component_int} {#1}
+ },
+ annotate/.style={
+ annotate~if,
+ annotate~reset,
+ annotation~style/.update~value={#1},
+ },
+ annotate~if/.default={true},
+ annotate~if/.code={
+ \tl_if_eq:nnTF {#1} {true}
+ {
+ \bool_set_true:N \l_@@_annotate_bool
+ }
+ {
+ \bool_set_false:N \l_@@_annotate_bool
+ }
+ },
+ annotate~reset/.code={
+ \int_gzero:N \g_@@_label_int
+ },
+ annotation~style/.initial={draw,->},
+ annotation~shift/.initial={(0,1ex)},
+ every~annotation~node/.initial={anchor=south~west},
+ annotation~node~style/.code~2~args={
+ \tl_clear_new:c {l_@@_annotation_style_ #1 _tl}
+ \tl_set:cn {l_@@_annotation_style_ #1 _tl}{#2}
+ },
+ tl~use:N/.code={
+ \exp_args:NV \pgfkeysalso #1
+ },
+ tl~use:c/.code={
+ \tl_if_exist:cT {#1}
+ {
+ \exp_args:Nv \pgfkeysalso {#1}
+ }
+ },
+ /handlers/.update~style/.code={
+ \tl_if_eq:nnF {#1} {\pgfkeysnovalue}
+ {
+ \pgfkeys{\pgfkeyscurrentpath/.code=\pgfkeysalso{#1}}
+ }
+ },
+ /handlers/.update~value/.code={
+ \tl_if_eq:nnF {#1} {\pgfkeysnovalue}
+ {
+ \pgfkeyssetvalue{\pgfkeyscurrentpath}{#1}
+ }
+ },
+}
+% \end{macrocode}
+%
+% Some wrappers around the TikZ keys.
+% \begin{macrocode}
+\NewDocumentCommand \pen { O{} }
+{
+ \path[define~ pen,every~ calligraphy~ pen/.try,#1]
+}
+
+\NewDocumentCommand \definepen { O{} }
+{
+ \tikz \path[define~ pen,every~ calligraphy~ pen/.try,#1]
+}
+
+\NewDocumentCommand \calligraphy { O{} }
+{
+ \path[use~ pen,every~ calligraphy/.try,#1]
+}
+% \end{macrocode}
+%
+% \subsection{The Path Creation}
+%
+% \begin{macro}[internal]{\cal_path_create:NN}
+% This is the main command for creating the calligraphic paths.
+% First argument is the given path
+% Second argument is the pen path
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \cal_path_create:NN #1#2
+{
+ \int_zero:N \l_@@_tmpa_int
+ \seq_map_inline:Nn #1
+ {
+ \int_compare:nT {\tl_count:n {##1} > 3}
+ {
+
+ \int_incr:N \l_@@_tmpa_int
+ \int_zero:N \l_@@_tmpb_int
+
+ \tl_set:Nn \l_@@_tmp_path_tl {##1}
+ \spath_open:N \l_@@_tmp_path_tl
+ \spath_reverse:NV \l_@@_tmp_rpath_tl \l_@@_tmp_path_tl
+
+ \seq_map_inline:Nn #2
+ {
+ \int_incr:N \l_@@_tmpb_int
+ \group_begin:
+ \pgfsys@beginscope
+ \cal_apply_style:c {l_@@_stroke_style_ \int_use:N \l_@@_tmpa_int}
+ \cal_apply_style:c {l_@@_stroke_inline_style_ \int_use:N \l_@@_tmpa_int}
+ \cal_apply_style:c {l_@@_nib_style_ \int_use:N \l_@@_tmpb_int}
+
+ \spath_initialpoint:Nn \l_@@_tmpa_tl {####1}
+ \tl_set_eq:NN \l_@@_tmp_patha_tl \l_@@_tmp_path_tl
+ \spath_translate:NV \l_@@_tmp_patha_tl \l_@@_tmpa_tl
+
+ \int_compare:nTF {\tl_count:n {####1} == 3}
+ {
+ \cal_at_least_three:N \l_@@_tmp_patha_tl
+ \spath_protocol_path:V \l_@@_tmp_patha_tl
+
+ \tikz@options
+ \dim_set:Nn \l_@@_line_width_dim {\pgflinewidth}
+ \cal_maybe_taper:N \l_@@_tmp_patha_tl
+ }
+ {
+ \spath_weld:Nn \l_@@_tmp_patha_tl {####1}
+ \spath_weld:NV \l_@@_tmp_patha_tl \l_@@_tmp_rpath_tl
+ \spath_reverse:Nn \l_@@_tmp_rpathb_tl {####1}
+ \spath_weld:NV \l_@@_tmp_patha_tl \l_@@_tmp_rpathb_tl
+
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_set:Nn \l_@@_tmpa_tl {fill=\pgfkeysvalueof{/tikz/pen~colour},draw=none}
+ \tl_if_exist:cT {l_@@_stroke_style_ \int_use:N \l_@@_tmpa_int}
+ {
+ \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_stroke_style_ \int_use:N \l_@@_tmpa_int}
+ }
+ \tl_if_exist:cT {l_@@_stroke_inline_style_ \int_use:N \l_@@_tmpa_int}
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {,}
+ \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_stroke_inline_style_ \int_use:N \l_@@_tmpa_int}
+ }
+ \tl_if_exist:cT {l_@@_nib_style_ \int_use:N \l_@@_tmpb_int}
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {,}
+ \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_nib_style_ \int_use:N \l_@@_tmpb_int}
+ }
+ \spath_tikz_path:VV \l_@@_tmpa_tl \l_@@_tmp_patha_tl
+
+ }
+ \pgfsys@endscope
+ \group_end:
+ }
+
+ \bool_if:NT \l_@@_annotate_bool
+ {
+ \seq_get_right:NN #2 \l_@@_tmpa_tl
+ \spath_finalpoint:NV \l_@@_tmpa_tl \l_@@_tmpa_tl
+ \spath_translate:NV \l_@@_tmp_path_tl \l_@@_tmpa_tl
+ \tikz@scan@one@point\pgfutil@firstofone\pgfkeysvalueof{/tikz/annotation~shift}
+
+ \spath_translate:Nnn \l_@@_tmp_path_tl {\pgf@x} {\pgf@y}
+
+ \pgfkeysgetvalue{/tikz/annotation~style}{\l_@@_tmpa_tl}
+ \spath_tikz_path:VV \l_@@_tmpa_tl \l_@@_tmp_path_tl
+
+ \spath_finalpoint:NV \l_@@_tmpa_tl \l_@@_tmp_path_tl
+
+ \exp_last_unbraced:NV \pgfqpoint \l_@@_tmpa_tl
+ \begin{scope}[reset~ cm]
+ \node[every~annotation~node/.try,tl~use:c = {l_@@_annotation_style_ \int_use:N \l_@@_tmpa_int _tl}] at (\pgf@x,\pgf@y) {\int_use:N \l_@@_tmpa_int};
+ \end{scope}
+ }
+ }
+ }
+}
+\cs_generate_variant:Nn \cal_path_create:NN {Nc}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\cal_moveto:n}
+% When creating the path, we need to keep track of the number of components so that we can apply styles accordingly.
+% \begin{macrocode}
+\cs_new_eq:NN \cal_orig_moveto:n \pgfpathmoveto
+\cs_new_nopar:Npn \cal_moveto:n #1
+{
+ \int_gincr:N \g_@@_path_component_int
+ \cal_orig_moveto:n {#1}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\cal_apply_style:N}
+% Interface for applying \Verb+\tikzset+ to a token list.
+% \begin{macrocode}
+\cs_new_nopar:Npn \cal_apply_style:N #1
+{
+ \tl_if_exist:NT #1 {
+ \exp_args:NV \tikzset #1
+ }
+}
+\cs_generate_variant:Nn \cal_apply_style:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\cal_at_least_three:Nn}
+% A tapered path has to have at least three components.
+% This figures out if it is necessary and sets up the splitting.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \cal_at_least_three:Nn #1#2
+{
+ \spath_reallength:Nn \l_@@_tmpa_int {#2}
+ \tl_clear:N \l_@@_tmpb_tl
+ \tl_set:Nn \l_@@_tmpb_tl {#2}
+ \int_compare:nTF {\l_@@_tmpa_int = 1}
+ {
+ \spath_split_at:Nn \l_@@_tmpb_tl {2/3}
+ \spath_split_at:Nn \l_@@_tmpb_tl {1/2}
+ }
+ {
+ \int_compare:nT {\l_@@_tmpa_int = 2}
+ {
+ \spath_split_at:Nn \l_@@_tmpb_tl {1.5}
+ \spath_split_at:Nn \l_@@_tmpb_tl {.5}
+ }
+ }
+ \tl_set_eq:NN #1 \l_@@_tmpb_tl
+}
+\cs_generate_variant:Nn \cal_at_least_three:Nn {NV}
+\cs_new_protected_nopar:Npn \cal_at_least_three:N #1
+{
+ \cal_at_least_three:NV #1#1
+}
+\cs_generate_variant:Nn \cal_at_least_three:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\cal_maybe_taper:N}
+% Possibly tapers the path, depending on the booleans.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \cal_maybe_taper:N #1
+{
+ \tl_set_eq:NN \l_@@_tmpa_tl #1
+
+ \bool_if:NT \l_@@_taper_start_bool
+ {
+
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpa_tl {2}}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpa_tl {3}}
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_item:Nn \l_@@_tmpa_tl {4}}
+
+ \tl_case:NnF \l_@@_tmpb_tl
+ {
+ \c_spath_lineto_tl
+ {
+
+ \bool_set_true:N \l_@@_taperable_bool
+ \dim_set:Nn \l_@@_tmpg_dim {\tl_item:Nn \l_@@_tmpa_tl {5}}
+ \dim_set:Nn \l_@@_tmph_dim {\tl_item:Nn \l_@@_tmpa_tl {6}}
+ \dim_set:Nn \l_@@_tmpc_dim {(2\l_@@_tmpa_dim + \l_@@_tmpg_dim)/3}
+ \dim_set:Nn \l_@@_tmpd_dim {(2\l_@@_tmpb_dim + \l_@@_tmph_dim)/3}
+ \dim_set:Nn \l_@@_tmpe_dim {(\l_@@_tmpa_dim + 2\l_@@_tmpg_dim)/3}
+ \dim_set:Nn \l_@@_tmpf_dim {(\l_@@_tmpb_dim + 2\l_@@_tmph_dim)/3}
+ \prg_replicate:nn {4}
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+ \tl_put_left:NV \l_@@_tmpa_tl \c_spath_moveto_tl
+ }
+ \c_spath_curvetoa_tl
+ {
+ \bool_set_true:N \l_@@_taperable_bool
+ \dim_set:Nn \l_@@_tmpc_dim {\tl_item:Nn \l_@@_tmpa_tl {5}}
+ \dim_set:Nn \l_@@_tmpd_dim {\tl_item:Nn \l_@@_tmpa_tl {6}}
+ \dim_set:Nn \l_@@_tmpe_dim {\tl_item:Nn \l_@@_tmpa_tl {8}}
+ \dim_set:Nn \l_@@_tmpf_dim {\tl_item:Nn \l_@@_tmpa_tl {9}}
+ \dim_set:Nn \l_@@_tmpg_dim {\tl_item:Nn \l_@@_tmpa_tl {11}}
+ \dim_set:Nn \l_@@_tmph_dim {\tl_item:Nn \l_@@_tmpa_tl {12}}
+ \prg_replicate:nn {10}
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+ \tl_put_left:NV \l_@@_tmpa_tl \c_spath_moveto_tl
+ }
+ }
+ {
+ \bool_set_false:N \l_@@_taperable_bool
+ }
+
+ \bool_if:NT \l_@@_taperable_bool
+ {
+ \@@_taper_aux:
+ }
+
+ }
+
+ \bool_if:NT \l_@@_taper_end_bool
+ {
+
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpa_tl {-2}}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpa_tl {-1}}
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_item:Nn \l_@@_tmpa_tl {-3}}
+
+ \tl_case:NnF \l_@@_tmpb_tl
+ {
+ \c_spath_lineto_tl
+ {
+
+ \bool_set_true:N \l_@@_taperable_bool
+ \dim_set:Nn \l_@@_tmpg_dim {\tl_item:Nn \l_@@_tmpa_tl {-5}}
+ \dim_set:Nn \l_@@_tmph_dim {\tl_item:Nn \l_@@_tmpa_tl {-4}}
+ \dim_set:Nn \l_@@_tmpc_dim {(2\l_@@_tmpa_dim + \l_@@_tmpg_dim)/3}
+ \dim_set:Nn \l_@@_tmpd_dim {(2\l_@@_tmpb_dim + \l_@@_tmph_dim)/3}
+ \dim_set:Nn \l_@@_tmpe_dim {(\l_@@_tmpa_dim + 2\l_@@_tmpg_dim)/3}
+ \dim_set:Nn \l_@@_tmpf_dim {(\l_@@_tmpb_dim + 2\l_@@_tmph_dim)/3}
+ \tl_reverse:N \l_@@_tmpa_tl
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+ \tl_reverse:N \l_@@_tmpa_tl
+ }
+ \c_spath_curveto_tl
+ {
+ \bool_set_true:N \l_@@_taperable_bool
+ \dim_set:Nn \l_@@_tmpc_dim {\tl_item:Nn \l_@@_tmpa_tl {-5}}
+ \dim_set:Nn \l_@@_tmpd_dim {\tl_item:Nn \l_@@_tmpa_tl {-4}}
+ \dim_set:Nn \l_@@_tmpe_dim {\tl_item:Nn \l_@@_tmpa_tl {-8}}
+ \dim_set:Nn \l_@@_tmpf_dim {\tl_item:Nn \l_@@_tmpa_tl {-7}}
+ \dim_set:Nn \l_@@_tmpg_dim {\tl_item:Nn \l_@@_tmpa_tl {-11}}
+ \dim_set:Nn \l_@@_tmph_dim {\tl_item:Nn \l_@@_tmpa_tl {-10}}
+ \tl_reverse:N \l_@@_tmpa_tl
+ \prg_replicate:nn {9}
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+ \tl_reverse:N \l_@@_tmpa_tl
+ }
+ }
+ {
+ \bool_set_false:N \l_@@_taperable_bool
+ }
+
+ \bool_if:NT \l_@@_taperable_bool
+ {
+ \@@_taper_aux:
+ }
+
+ }
+
+ \pgfsyssoftpath@setcurrentpath\l_@@_tmpa_tl
+ \pgfsetstrokecolor{\pgfkeysvalueof{/tikz/pen~colour}}
+ \pgfusepath{stroke}
+
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_taper_aux:}
+% Auxiliary macro to avoid unnecessary code duplication.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_taper_aux:
+{
+ \tl_clear:N \l_@@_tmpb_tl
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_moveto_tl
+
+ \fp_set:Nn \l_@@_tmpa_fp
+ {
+ \l_@@_tmpd_dim - \l_@@_tmpb_dim
+ }
+ \fp_set:Nn \l_@@_tmpb_fp
+ {
+ \l_@@_tmpa_dim - \l_@@_tmpc_dim
+ }
+ \fp_set:Nn \l_@@_tmpe_fp
+ {
+ (\l_@@_tmpa_fp^2 + \l_@@_tmpb_fp^2)^.5
+ }
+
+ \fp_set:Nn \l_@@_tmpa_fp {.5*\l_@@_taper_width_dim * \l_@@_tmpa_fp / \l_@@_tmpe_fp}
+ \fp_set:Nn \l_@@_tmpb_fp {.5*\l_@@_taper_width_dim * \l_@@_tmpb_fp / \l_@@_tmpe_fp}
+
+ \fp_set:Nn \l_@@_tmpc_fp
+ {
+ \l_@@_tmph_dim - \l_@@_tmpf_dim
+ }
+ \fp_set:Nn \l_@@_tmpd_fp
+ {
+ \l_@@_tmpe_dim - \l_@@_tmpg_dim
+ }
+ \fp_set:Nn \l_@@_tmpe_fp
+ {
+ (\l_@@_tmpc_fp^2 + \l_@@_tmpd_fp^2)^.5
+ }
+
+ \fp_set:Nn \l_@@_tmpc_fp {.5*\l_@@_line_width_dim * \l_@@_tmpc_fp / \l_@@_tmpe_fp}
+ \fp_set:Nn \l_@@_tmpd_fp {.5*\l_@@_line_width_dim * \l_@@_tmpd_fp / \l_@@_tmpe_fp}
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim}}
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim}}
+ }
+
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetoa_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpc_dim}}
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpd_dim}}
+ }
+
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetob_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpe_dim}}
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmpf_dim}}
+ }
+
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curveto_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpg_dim}}
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmph_dim}}
+ }
+
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetoa_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpg_dim - \fp_to_dim:n{ 1.32 * \l_@@_tmpd_fp}}}
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmph_dim + \fp_to_dim:n {1.32* \l_@@_tmpc_fp}}}
+ }
+
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetob_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpg_dim - \fp_to_dim:n {1.32 * \l_@@_tmpd_fp}}}
+ {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmph_dim + \fp_to_dim:n {1.32 * \l_@@_tmpc_fp}}}
+ }
+
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curveto_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpg_dim}}
+ {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmph_dim}}
+ }
+
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetoa_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpe_dim}}
+ {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmpf_dim}}
+ }
+
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetob_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpc_dim}}
+ {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpd_dim}}
+ }
+
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curveto_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim}}
+ {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim}}
+ }
+
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetoa_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim + \fp_to_dim:n{ 1.32 * \l_@@_tmpb_fp}}}
+ {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim - \fp_to_dim:n {1.32* \l_@@_tmpa_fp}}}
+ }
+
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetob_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim + \fp_to_dim:n {1.32 * \l_@@_tmpb_fp}}}
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim - \fp_to_dim:n {1.32 * \l_@@_tmpa_fp}}}
+ }
+
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curveto_tl
+
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim}}
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim}}
+ }
+
+ \pgfsyssoftpath@setcurrentpath\l_@@_tmpb_tl
+ \pgfsetfillcolor{\pgfkeysvalueof{/tikz/pen~colour}}
+ \pgfusepath{fill}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% Defines a copperplate pen.
+% \begin{macrocode}
+\tl_set:Nn \l_@@_tmpa_tl {\pgfsyssoftpath@movetotoken{0pt}{0pt}}
+\spath_components_to_seq:NV \l_@@_tmpa_seq \l_@@_tmpa_tl
+\seq_gclear_new:N \g_@@_pen_copperplate_seq
+\seq_gset_eq:NN \g_@@_pen_copperplate_seq \l_@@_tmpa_seq
+% \end{macrocode}
+%
+% \begin{macro}{\CopperplatePath}
+% This is used in the decorations section to convert a path to a copperplate path.
+% \begin{macrocode}
+\DeclareDocumentCommand \CopperplatePath { m }
+{
+ \spath_components_to_seq:NV \l_@@_tmpa_seq #1
+ \cal_path_create:NN \l_@@_tmpa_seq \g_@@_pen_copperplate_seq
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\ExplSyntaxOff
+% \end{macrocode}
+%
+% \subsection{Decorations}
+%
+% If a decoration library is loaded we define some decorations that use the calligraphy library, specifically the copperplate pen with its tapering.
+%
+% First, a brace decoration.
+% \begin{macrocode}
+\expandafter\ifx\csname pgfdeclaredecoration\endcsname\relax
+\else
+\pgfdeclaredecoration{calligraphic brace}{brace}
+{
+ \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final]
+ {
+ \pgfsyssoftpath@setcurrentpath{\pgfutil@empty}
+ \pgfpathmoveto{\pgfpointorigin}
+ \pgfpathcurveto
+ {\pgfqpoint{.15\pgfdecorationsegmentamplitude}{.3\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
+ {
+ \pgftransformxshift{+\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance}
+ \pgfpathlineto{\pgfqpoint{-\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
+ \pgfpathcurveto
+ {\pgfqpoint{-.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{-.15\pgfdecorationsegmentamplitude}{.7\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{0\pgfdecorationsegmentamplitude}{1\pgfdecorationsegmentamplitude}}
+ \pgfpathmoveto{\pgfqpoint{0\pgfdecorationsegmentamplitude}{1\pgfdecorationsegmentamplitude}}
+ \pgfpathcurveto
+ {\pgfqpoint{.15\pgfdecorationsegmentamplitude}{.7\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
+ }
+ {
+ \pgftransformxshift{+\pgfdecoratedremainingdistance}
+ \pgfpathlineto{\pgfqpoint{-\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
+ \pgfpathcurveto
+ {\pgfqpoint{-.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{-.15\pgfdecorationsegmentamplitude}{.3\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{0pt}{0pt}}
+ }
+ \tikzset{
+ taper width=.5\pgflinewidth,
+ taper
+ }%
+ \pgfsyssoftpath@getcurrentpath\cal@tmp@path
+ \CopperplatePath{\cal@tmp@path}
+ }
+ \state{final}{}
+}
+% \end{macrocode}
+%
+% The second is a straightened parenthesis (so that when very large it doesn't bow out too far).
+% \begin{macrocode}
+\pgfdeclaredecoration{calligraphic straight parenthesis}{brace}
+{
+ \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final]
+ {
+ \pgfsyssoftpath@setcurrentpath{\pgfutil@empty}
+ \pgfpathmoveto{\pgfpointorigin}
+ \pgfpathcurveto
+ {\pgfqpoint{.76604\pgfdecorationsegmentamplitude}{.64279\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{2.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{3.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}}
+ {
+ \pgftransformxshift{+\pgfdecoratedremainingdistance}
+ \pgfpathlineto{\pgfqpoint{-3.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}}
+ \pgfpathcurveto
+ {\pgfqpoint{-2.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{-.76604\pgfdecorationsegmentamplitude}{.64279\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{0pt}{0pt}}
+ }
+ \tikzset{
+ taper width=.5\pgflinewidth,
+ taper
+ }%
+ \pgfsyssoftpath@getcurrentpath\cal@tmp@path
+ \CopperplatePath{\cal@tmp@path}
+ }
+ \state{final}{}%
+}
+% \end{macrocode}
+%
+% The third is a curved parenthesis.
+% \begin{macrocode}
+\pgfdeclaredecoration{calligraphic curved parenthesis}{brace}
+{
+ \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final]
+ {
+ \pgfsyssoftpath@setcurrentpath{\pgfutil@empty}
+ \pgfpathmoveto{\pgfpointorigin}
+ \pgf@xa=\pgfdecoratedremainingdistance\relax
+ \advance\pgf@xa by -1.5890\pgfdecorationsegmentamplitude\relax
+ \edef\cgrphy@xa{\the\pgf@xa}
+ \pgfpathcurveto
+ {\pgfqpoint{1.5890\pgfdecorationsegmentamplitude}{1.3333\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{\cgrphy@xa}{1.3333\pgfdecorationsegmentamplitude}}
+ {\pgfqpoint{\pgfdecoratedremainingdistance}{0pt}}
+ \tikzset{
+ taper width=.5\pgflinewidth,
+ taper
+ }%
+ \pgfsyssoftpath@getcurrentpath\cal@tmp@path
+ \CopperplatePath{\cal@tmp@path}
+ }
+ \state{final}{}%
+}
+% \end{macrocode}
+% End the conditional for if pgfdecoration module is loaded
+% \begin{macrocode}
+\fi
+% \end{macrocode}
+% \iffalse
+%</calligraphy>
+% \fi
+%
+%
+% \iffalse
+%<*knots>
+% \fi
+%%
+% \section{Drawing Knots}
+%
+% \begin{macrocode}
+%<@@=knot>
+% \end{macrocode}
+%
+% \subsection{Initialisation}
+%
+% We load the \Verb+spath3+ library and the \Verb+intersections+ TikZ library.
+% Then we get going.
+% \begin{macrocode}
+\RequirePackage{spath3}
+\usetikzlibrary{intersections,spath3}
+
+\ExplSyntaxOn
+
+\tl_new:N \l_@@_tmpa_tl
+\tl_new:N \l_@@_tmpb_tl
+\tl_new:N \l_@@_tmpc_tl
+\tl_new:N \l_@@_tmpd_tl
+\tl_new:N \l_@@_tmpg_tl
+\tl_new:N \l_@@_redraws_tl
+\tl_new:N \l_@@_clip_width_tl
+\tl_new:N \l_@@_name_tl
+\tl_new:N \l_@@_node_tl
+\tl_new:N \l_@@_aux_tl
+\tl_new:N \l_@@_auxa_tl
+\tl_new:N \l_@@_prefix_tl
+
+\seq_new:N \l_@@_segments_seq
+
+\int_new:N \l_@@_tmpa_int
+\int_new:N \l_@@_strands_int
+\int_new:N \g_@@_intersections_int
+\int_new:N \g_@@_filaments_int
+\int_new:N \l_@@_component_start_int
+
+\fp_new:N \l_@@_tmpa_fp
+\fp_new:N \l_@@_tmpb_fp
+
+\dim_new:N \l_@@_tmpa_dim
+\dim_new:N \l_@@_tmpb_dim
+\dim_new:N \l_@@_tolerance_dim
+\dim_new:N \l_@@_clip_bg_radius_dim
+\dim_new:N \l_@@_clip_draw_radius_dim
+
+\bool_new:N \l_@@_draft_bool
+\bool_new:N \l_@@_ignore_ends_bool
+\bool_new:N \l_@@_self_intersections_bool
+\bool_new:N \l_@@_splits_bool
+\bool_new:N \l_@@_super_draft_bool
+
+\bool_new:N \l_@@_prepend_prev_bool
+\bool_new:N \l_@@_append_next_bool
+\bool_new:N \l_@@_skip_bool
+\bool_new:N \l_@@_save_bool
+
+\seq_new:N \g_@@_nodes_seq
+
+\bool_set_true:N \l_@@_ignore_ends_bool
+% \end{macrocode}
+%
+% Configuration is via TikZ keys and styles.
+% \begin{macrocode}
+\tikzset{
+ spath/prefix/knot/.style={
+ spath/set~ prefix=knot strand,
+ },
+ spath/suffix/knot/.style={
+ spath/set~ suffix={},
+ },
+ knot/.code={
+ \tl_if_eq:nnTF {#1} {none}
+ {
+ \tikz@addmode{\tikz@mode@doublefalse}
+ }
+ {
+ \tikz@addmode{\tikz@mode@doubletrue}
+ \tl_if_eq:nnTF {\pgfkeysnovalue} {#1}
+ {
+ \tikz@addoption{\pgfsetinnerstrokecolor{.}}
+ }
+ {
+ \pgfsetinnerstrokecolor{#1}
+ }
+ \tikz@addoption{
+ \pgfsetstrokecolor{knotbg}
+ }
+ \tl_set:Nn \tikz@double@setup{
+ \pgfsetinnerlinewidth{\pgflinewidth}
+ \pgfsetlinewidth{\dim_eval:n {\tl_use:N \l_@@_gap_tl \pgflinewidth}}
+ }
+ }
+ },
+ knot~ gap/.store~ in=\l_@@_gap_tl,
+ knot~ gap=3,
+ knot~ diagram/.is~family,
+ knot~ diagram/.unknown/.code={
+ \tl_set_eq:NN \l_@@_tmpa_tl \pgfkeyscurrentname
+ \pgfkeysalso{
+ /tikz/\l_@@_tmpa_tl=#1
+ }
+ },
+ background~ colour/.code={%
+ \colorlet{knotbg}{#1}%
+ },
+ background~ color/.code={%
+ \colorlet{knotbg}{#1}%
+ },
+ background~ colour=white,
+ knot~ diagram,
+ name/.store~ in=\l_@@_name_tl,
+ name={knot},
+ save~ intersections/.is~ choice,
+ save~ intersections/.default=true,
+ save~ intersections/true/.code={
+ \bool_set_true:N \l_@@_save_bool
+ },
+ save~ intersections/false/.code={
+ \bool_set_false:N \l_@@_save_bool
+ },
+ every~ strand/.style={draw},
+ ignore~ endpoint~ intersections/.code={
+ \tl_if_eq:nnTF {#1} {true}
+ {
+ \bool_set_true:N \l_@@_ignore_ends_bool
+ }
+ {
+ \bool_set_false:N \l_@@_ignore_ends_bool
+ }
+ },
+ ignore~ endpoint~ intersections/.default=true,
+ consider~ self~ intersections/.is~choice,
+ consider~ self~ intersections/true/.code={
+ \bool_set_true:N \l_@@_self_intersections_bool
+ \bool_set_true:N \l_@@_splits_bool
+ },
+ consider~ self~ intersections/false/.code={
+ \bool_set_false:N \l_@@_self_intersections_bool
+ \bool_set_false:N \l_@@_splits_bool
+ },
+ consider~ self~ intersections/no~ splits/.code={
+ \bool_set_true:N \l_@@_self_intersections_bool
+ \bool_set_false:N \l_@@_splits_bool
+ },
+ consider~ self~ intersections/.default={true},
+ clip~ radius/.code={
+ \dim_set:Nn \l_@@_clip_bg_radius_dim {#1}
+ \dim_set:Nn \l_@@_clip_draw_radius_dim {#1+2pt}
+ },
+ clip~ draw~ radius/.code={
+ \dim_set:Nn \l_@@_clip_draw_radius_dim {#1}
+ },
+ clip~ background~ radius/.code={
+ \dim_set:Nn \l_@@_clip_bg_radius_dim {#1}
+ },
+ clip~ radius=10pt,
+ end~ tolerance/.code={
+ \dim_set:Nn \l_@@_tolerance_dim {#1}
+ },
+ end~ tolerance=14pt,
+ clip/.style={
+ clip
+ },
+ background~ clip/.style={
+ clip
+ },
+ clip~ width/.code={
+ \tl_set:Nn \l_@@_clip_width_tl {#1}
+ },
+ clip~ width=3,
+ flip~ crossing/.code={%
+ \tl_clear_new:c {l_@@_crossing_#1}
+ \tl_set:cn {l_@@_crossing_#1} {x}
+ },
+ ignore~ crossing/.code={%
+ \tl_clear_new:c {l_@@_ignore_crossing_#1}
+ \tl_set:cn {l_@@_ignore_crossing_#1} {x}
+ },
+ draft~ mode/.is~ choice,
+ draft~ mode/off/.code={%
+ \bool_set_false:N \l_@@_draft_bool
+ \bool_set_false:N \l_@@_super_draft_bool
+ },
+ draft~ mode/crossings/.code={%
+ \bool_set_true:N \l_@@_draft_bool
+ \bool_set_false:N \l_@@_super_draft_bool
+ },
+ draft~ mode/strands/.code={%
+ \bool_set_true:N \l_@@_draft_bool
+ \bool_set_true:N \l_@@_super_draft_bool
+ },
+ draft/.is~ family,
+ draft,
+ crossing~ label/.style={
+ overlay,
+ fill=white,
+ fill~ opacity=.5,
+ text~ opacity=1,
+ text=blue,
+ pin~ edge={blue,<-}
+ },
+ strand~ label/.style={
+ overlay,
+ circle,
+ draw=purple,
+ fill=white,
+ fill~ opacity=.5,
+ text~ opacity=1,
+ text=purple,
+ inner~ sep=0pt
+ },
+}
+% \end{macrocode}
+%
+% Wrapper around \Verb+\tikzset+ for applying keys from a token list, checking for if the given token list exists.
+% \begin{macrocode}
+\cs_new_nopar:Npn \knot_apply_style:N #1
+{
+ \tl_if_exist:NT #1 {
+ \exp_args:NV \tikzset #1
+ }
+}
+\cs_generate_variant:Nn \knot_apply_style:N {c}
+% \end{macrocode}
+%
+%\begin{macro}[internal]{\flipcrossings}
+% The user can specify a comma separated list of crossings to flip.
+% \begin{macrocode}
+\NewDocumentCommand \flipcrossings {m}
+{
+ \tikzset{knot~ diagram/flip~ crossing/.list={#1}}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\strand}
+% This is how the user specifies a strand of the knot.
+% \begin{macrocode}
+\NewDocumentCommand \strand { O{} }
+{
+ \int_incr:N \l_@@_strands_int
+ \tl_clear_new:c {l_@@_options_strand \int_use:N \l_@@_strands_int}
+ \tl_set:cn {l_@@_options_strand \int_use:N \l_@@_strands_int} {#1}
+ \path[#1,spath/set~ name=knot,spath/save=\int_use:N \l_@@_strands_int]
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{knot}
+% This is the wrapper environment that calls the knot generation code.
+% \begin{macrocode}
+\NewDocumentEnvironment{knot} { O{} }
+{
+ \knot_initialise:n {#1}
+}
+{
+ \knot_render:
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_initialise:n}
+% Set up some stuff before loading in the strands.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_initialise:n #1
+{
+ \tikzset{knot~ diagram/.cd,every~ knot~ diagram/.try,#1}
+ \int_zero:N \l_@@_strands_int
+ \tl_clear:N \l_@@_redraws_tl
+ \seq_gclear:N \g_@@_nodes_seq
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_render:}
+% This is the code that starts the work of rendering the knot.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_render:
+{
+% \end{macrocode}
+% Start a scope and reset the transformation (since all transformations have already been taken into account when defining the strands).
+% \begin{macrocode}
+ \pgfscope
+ \pgftransformreset
+% \end{macrocode}
+% Loop through the strands drawing each one for the first time.
+% \begin{macrocode}
+ \int_step_function:nnnN {1} {1} {\l_@@_strands_int} \knot_draw_strand:n
+% \end{macrocode}
+% In super draft mode we don't do anything else.
+% \begin{macrocode}
+ \bool_if:NF \l_@@_super_draft_bool
+ {
+% \end{macrocode}
+% In draft mode we draw labels at the ends of the strands; this also handles splitting curves to avoid self-intersections of Bezier curves if that's requested.
+% \begin{macrocode}
+ \int_step_function:nnnN {1} {1} {\l_@@_strands_int} \knot_draw_labels:n
+% \end{macrocode}
+% If we're considering self intersections we need to split the strands into filaments.
+% \begin{macrocode}
+ \bool_if:NTF \l_@@_self_intersections_bool
+ {
+ \knot_split_strands:
+ \int_set_eq:NN \l_@@_tmpa_int \g_@@_filaments_int
+ \tl_set:Nn \l_@@_prefix_tl {filament}
+ }
+ {
+ \int_set_eq:NN \l_@@_tmpa_int \l_@@_strands_int
+ \tl_set:Nn \l_@@_prefix_tl {strand}
+ }
+% \end{macrocode}
+% Initialise the intersection count.
+% \begin{macrocode}
+ \int_gzero:N \g_@@_intersections_int
+% \end{macrocode}
+% If in draft mode we label the intersections, otherwise we just stick a coordinate at each one.
+% \begin{macrocode}
+ \tl_clear:N \l_@@_node_tl
+ \bool_if:NT \l_@@_draft_bool
+ {
+ \tl_set:Nn \l_@@_node_tl {
+ \exp_not:N \node[coordinate,
+ pin={[node~ contents={\int_use:N \g_@@_intersections_int},knot~ diagram/draft/crossing~ label, knot~ diagram/draft/crossing~ \int_use:N \g_@@_intersections_int \c_space_tl label/.try]
+ }]
+ }
+ }
+% \end{macrocode}
+% This double loop steps through the pieces (strands or filaments) and computes the intersections and does stuff with those.
+% \begin{macrocode}
+ \int_step_variable:nnnNn {1} {1} {\l_@@_tmpa_int - 1} \l_@@_tmpa_tl
+ {
+ \int_step_variable:nnnNn {\tl_use:N \l_@@_tmpa_tl + 1} {1} {\l_@@_tmpa_int} \l_@@_tmpb_tl
+ {
+ \knot_intersections:VV \l_@@_tmpa_tl \l_@@_tmpb_tl
+ }
+ }
+% \end{macrocode}
+% If any redraws were requested, do them here.
+% \begin{macrocode}
+ \tl_use:N \l_@@_redraws_tl
+% \end{macrocode}
+% Draw the crossing nodes
+% \begin{macrocode}
+ \seq_use:Nn \g_@@_nodes_seq {}
+ }
+% \end{macrocode}
+% Close the scope
+% \begin{macrocode}
+ \endpgfscope
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_draw_strand:n}
+% This renders a strand using the options originally specified.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_draw_strand:n #1
+{
+ \pgfscope
+ \group_begin:
+ \spath_bake_round:c {knot strand #1}
+ \tl_set:Nn \l_@@_tmpa_tl {knot~ diagram/every~ strand/.try,}
+ \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_options_strand #1}
+ \tl_put_right:Nn \l_@@_tmpa_tl {,knot~ diagram/only~ when~ rendering/.try,only~ when~ rendering/.try}
+ \spath_tikz_path:Vv \l_@@_tmpa_tl {knot strand #1}
+ \group_end:
+ \endpgfscope
+}
+\cs_generate_variant:Nn \tl_put_right:Nn {Nv}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_draw_labels:n}
+% Draw a label at each end of each strand, if in draft mode.
+% Also, if requested, split potentially self intersecting Bezier curves.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_draw_labels:n #1
+{
+ \bool_if:NT \l_@@_draft_bool
+ {
+ \spath_finalpoint:Nv \l_@@_tmpb_tl {knot strand #1}
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpb_tl {1}}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpb_tl {2}}
+ \node[knot~ diagram/draft/strand~label] at (\l_@@_tmpa_dim,\l_@@_tmpb_dim) {#1};
+ \spath_initialpoint:Nv \l_@@_tmpb_tl {knot strand #1}
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpb_tl {1}}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpb_tl {2}}
+ \node[knot~ diagram/draft/strand~label] at (\l_@@_tmpa_dim,\l_@@_tmpb_dim) {#1};
+ }
+ \bool_if:nT {
+ \l_@@_self_intersections_bool
+ &&
+ \l_@@_splits_bool
+ }
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ \spath_segments_to_seq:Nv \l_@@_segments_seq {knot strand #1}
+ \seq_map_function:NN \l_@@_segments_seq \knot_split_self_intersects:N
+ \tl_set_eq:cN {knot strand #1} \l_@@_tmpa_tl
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_split_self_intersects:N}
+% This is the macro that does the split.
+% Figuring out whether a Bezier cubic self intersects is apparently a difficult problem so we don't bother.
+% We compute a point such that if there is an intersection then it lies on either side of the point.
+% I don't recall where the formula came from!
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_split_self_intersects:N #1
+{
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_item:nn {#1} {4}}
+ \tl_case:NnF \l_@@_tmpc_tl
+ {
+ \c_spath_curvetoa_tl
+ {
+ \fp_set:Nn \l_@@_tmpa_fp
+ {
+ (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6} + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12})
+ *
+ (3 * \tl_item:nn {#1} {8} - 3 * \tl_item:nn {#1} {11})
+ -
+ (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5} + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11})
+ *
+ (3 * \tl_item:nn {#1} {9} - 3 * \tl_item:nn {#1} {12})
+ }
+ \fp_set:Nn \l_@@_tmpb_fp
+ {
+ (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5} + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11})
+ *
+ (3 * \tl_item:nn {#1} {6} - 6 * \tl_item:nn {#1} {9} + 3 * \tl_item:nn {#1} {12})
+ -
+ (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6} + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12})
+ *
+ (3 * \tl_item:nn {#1} {5} - 6 * \tl_item:nn {#1} {8} + 3 * \tl_item:nn {#1} {11})
+ }
+ \fp_compare:nTF
+ {
+ \l_@@_tmpb_fp != 0
+ }
+ {
+ \fp_set:Nn \l_@@_tmpa_fp {.5 * \l_@@_tmpa_fp / \l_@@_tmpb_fp}
+ \fp_compare:nTF
+ {
+ 0 < \l_@@_tmpa_fp && \l_@@_tmpa_fp < 1
+ }
+ {
+ \spath_split_curve:NNnV \l_@@_tmpc_tl \l_@@_tmpd_tl {#1} \l_@@_tmpa_fp
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_set:Nx \l_@@_tmpd_tl {\tl_tail:N \l_@@_tmpd_tl}
+ \tl_set:Nx \l_@@_tmpd_tl {\tl_tail:N \l_@@_tmpd_tl}
+ \tl_set:Nx \l_@@_tmpd_tl {\tl_tail:N \l_@@_tmpd_tl}
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpc_tl
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpd_tl
+ }
+ {
+ \tl_set:Nn \l_@@_tmpc_tl {#1}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpc_tl
+ }
+ }
+ {
+ \tl_set:Nn \l_@@_tmpc_tl {#1}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpc_tl
+ }
+ }
+ \c_spath_lineto_tl
+ {
+ \tl_set:Nn \l_@@_tmpc_tl {#1}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpc_tl
+ }
+ }
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {#1}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_intersections:nn}
+% This computes the intersections of two pieces and steps through them.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_intersections:nn #1#2
+{
+ \group_begin:
+ \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_prefix_tl
+ \tl_put_right:Nn \l_@@_tmpa_tl {#1}
+ \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_prefix_tl
+ \tl_put_right:Nn \l_@@_tmpb_tl {#2}
+ \tl_set_eq:Nc \l_@@_tmpc_tl {knot \tl_use:N \l_@@_tmpa_tl}
+ \tl_set_eq:Nc \l_@@_tmpd_tl {knot \tl_use:N \l_@@_tmpb_tl}
+
+ \bool_if:nTF {
+ \l_@@_save_bool
+ &&
+ \tl_if_exist_p:c {knot~ intersections~ \tl_use:N \l_@@_name_tl - \tl_use:N \l_@@_tmpa_tl - \tl_use:N \l_@@_tmpb_tl}
+ }
+ {
+ \tl_use:c {knot~ intersections~ \tl_use:N \l_@@_name_tl - \tl_use:N \l_@@_tmpa_tl - \tl_use:N \l_@@_tmpb_tl}
+ }
+ {
+\pgfintersectionofpaths{\pgfsetpath\l_@@_tmpc_tl}{\pgfsetpath\l_@@_tmpd_tl}
+
+ }
+
+ \int_compare:nT {\pgfintersectionsolutions > 0}
+ {
+ \int_step_function:nnnN {1} {1} {\pgfintersectionsolutions} \knot_do_intersection:n
+ }
+
+ \knot_save_intersections:VV \l_@@_tmpa_tl \l_@@_tmpb_tl
+ \group_end:
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_save_intersections:nn}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_save_intersections:nn #1#2
+{
+ \bool_if:NT \l_@@_save_bool
+ {
+ \tl_clear:N \l_@@_aux_tl
+ \tl_put_right:Nn \l_@@_aux_tl
+ {
+ \def\pgfintersectionsolutions
+ }
+ \tl_put_right:Nx \l_@@_aux_tl
+ {
+ {\int_eval:n {\pgfintersectionsolutions}}
+ }
+ \int_compare:nT {\pgfintersectionsolutions > 0}
+ {
+ \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions}
+ {
+ \pgfpointintersectionsolution{##1}
+ \dim_set:Nn \l_@@_tmpa_dim {\pgf@x}
+ \dim_set:Nn \l_@@_tmpb_dim {\pgf@y}
+ \tl_put_right:Nn \l_@@_aux_tl
+ {
+ \expandafter\def\csname pgfpoint@intersect@solution@##1\endcsname
+ }
+ \tl_put_right:Nx \l_@@_aux_tl
+ {
+ {\exp_not:N \pgf@x=\dim_use:N \l_@@_tmpa_dim\exp_not:N\relax\exp_not:N \pgf@y =\dim_use:N \l_@@_tmpb_dim\relax}
+ }
+ }
+ \tl_set:Nn \l_@@_auxa_tl {\expandafter \gdef \csname knot~ intersections~}
+ \tl_put_right:Nx \l_@@_auxa_tl {\tl_use:N \l_@@_name_tl - #1 - #2}
+ \tl_put_right:Nn \l_@@_auxa_tl {\endcsname}
+ \tl_put_right:Nx \l_@@_auxa_tl {{\tl_to_str:N \l_@@_aux_tl}}
+ \protected@write\@auxout{}{\tl_to_str:N \l_@@_auxa_tl}
+ }
+ }
+}
+\cs_generate_variant:Nn \knot_save_intersections:nn {VV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_do_intersection:n}
+% This handles a specific intersection.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_do_intersection:n #1
+{
+% \end{macrocode}
+% Get the intersection coordinates.
+% \begin{macrocode}
+ \pgfpointintersectionsolution{#1}
+ \dim_set:Nn \l_@@_tmpa_dim {\pgf@x}
+ \dim_set:Nn \l_@@_tmpb_dim {\pgf@y}
+% \end{macrocode}
+% If we're dealing with filaments, we can get false positives from the end points.
+% \begin{macrocode}
+ \bool_set_false:N \l_@@_skip_bool
+ \bool_if:NT \l_@@_self_intersections_bool
+ {
+% \end{macrocode}
+% If one filament preceded the other, test for the intersection being at the relevant end point.
+% \begin{macrocode}
+ \tl_set:Nn \l_@@_tmpc_tl {knot previous}
+ \tl_put_right:NV \l_@@_tmpc_tl \l_@@_tmpa_tl
+ \tl_set:Nv \l_@@_tmpc_tl \l_@@_tmpc_tl
+ \tl_if_eq:NNT \l_@@_tmpc_tl \l_@@_tmpb_tl
+ {
+ \knot_test_endpoint:VnT \l_@@_tmpb_tl {final point}
+ {
+ \bool_set_true:N \l_@@_skip_bool
+ }
+ }
+
+ \tl_set:Nn \l_@@_tmpc_tl {knot previous}
+ \tl_put_right:NV \l_@@_tmpc_tl \l_@@_tmpb_tl
+ \tl_set:Nv \l_@@_tmpc_tl \l_@@_tmpc_tl
+ \tl_if_eq:NNT \l_@@_tmpc_tl \l_@@_tmpa_tl
+ {
+ \knot_test_endpoint:VnT \l_@@_tmpa_tl {final point}
+ {
+ \bool_set_true:N \l_@@_skip_bool
+ }
+ }
+ }
+% \end{macrocode}
+% The user can also say that end points of filaments (or strands) should simply be ignored anyway.
+% \begin{macrocode}
+ \bool_if:NT \l_@@_ignore_ends_bool
+ {
+ \knot_test_endpoint:VnT \l_@@_tmpa_tl {initial point}
+ {
+ \bool_set_true:N \l_@@_skip_bool
+ }
+ \knot_test_endpoint:VnT \l_@@_tmpa_tl {final point}
+ {
+ \bool_set_true:N \l_@@_skip_bool
+ }
+ \knot_test_endpoint:VnT \l_@@_tmpb_tl {initial point}
+ {
+ \bool_set_true:N \l_@@_skip_bool
+ }
+ \knot_test_endpoint:VnT \l_@@_tmpb_tl {final point}
+ {
+ \bool_set_true:N \l_@@_skip_bool
+ }
+ }
+% \end{macrocode}
+% Assuming that we passed all the above tests, we render the crossing.
+% \begin{macrocode}
+ \bool_if:NF \l_@@_skip_bool
+ {
+
+ \int_gincr:N \g_@@_intersections_int
+% \end{macrocode}
+% This is the intersection test.
+% If the intersection finder finds too many, it might be useful to ignore some.
+% \begin{macrocode}
+ \bool_if:nF
+ {
+ \tl_if_exist_p:c {l_@@_ignore_crossing_ \int_use:N
+ \g_@@_intersections_int}
+ &&
+ ! \tl_if_empty_p:c {l_@@_ignore_crossing_ \int_use:N
+ \g_@@_intersections_int}
+ }
+ {
+% \end{macrocode}
+% This is the flip test.
+% We only render one of the paths.
+% The ``flip'' swaps which one we render.
+% \begin{macrocode}
+ \bool_if:nTF
+ {
+ \tl_if_exist_p:c {l_@@_crossing_ \int_use:N
+ \g_@@_intersections_int}
+ &&
+ ! \tl_if_empty_p:c {l_@@_crossing_ \int_use:N
+ \g_@@_intersections_int}
+ }
+ {
+ \tl_set_eq:NN \l_@@_tmpg_tl \l_@@_tmpb_tl
+ }
+ {
+ \tl_set_eq:NN \l_@@_tmpg_tl \l_@@_tmpa_tl
+ }
+% \end{macrocode}
+% Now we know which one we're rendering, we test to see if we should also render its predecessor or successor to ensure that we render a path through the entire crossing region.
+% \begin{macrocode}
+ \bool_if:NT \l_@@_self_intersections_bool
+ {
+ \knot_test_endpoint:VnT \l_@@_tmpg_tl {initial point}
+ {
+ \bool_set_true:N \l_@@_prepend_prev_bool
+ }
+ {
+ \bool_set_false:N \l_@@_prepend_prev_bool
+ }
+ \knot_test_endpoint:VnT \l_@@_tmpg_tl {final point}
+ {
+ \bool_set_true:N \l_@@_append_next_bool
+ }
+ {
+ \bool_set_false:N \l_@@_append_next_bool
+ }
+% \end{macrocode}
+% If either of those tests succeeded, do the appending or prepending.
+% \begin{macrocode}
+ \bool_if:nT
+ {
+ \l_@@_prepend_prev_bool || \l_@@_append_next_bool
+ }
+ {
+ \tl_clear_new:c {knot \tl_use:N \l_@@_prefix_tl -1}
+ \tl_set_eq:cc {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:N \l_@@_tmpg_tl}
+
+ \tl_clear_new:c {l_@@_options_ \tl_use:N \l_@@_prefix_tl -1}
+ \tl_set_eq:cc {l_@@_options_ \tl_use:N \l_@@_prefix_tl -1} {l_@@_options_ \tl_use:N \l_@@_tmpg_tl}
+
+ \bool_if:nT
+ {
+ \l_@@_prepend_prev_bool
+ &&
+ \tl_if_exist_p:c {knot previous \tl_use:N \l_@@_tmpg_tl}
+ &&
+ !\tl_if_empty_p:c {knot previous \tl_use:N \l_@@_tmpg_tl}
+ }
+ {
+ \spath_prepend_no_move:cv {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:N \l_@@_tmpg_tl}}
+% \end{macrocode}
+% If we split potentially self intersecting curves, we test to see if we should prepend yet another segment.
+% \begin{macrocode}
+ \bool_if:nT
+ {
+ \l_@@_splits_bool
+ &&
+ \tl_if_exist_p:c {knot previous \tl_use:N \l_@@_tmpg_tl}
+ &&
+ !\tl_if_empty_p:c {knot previous \tl_use:N \l_@@_tmpg_tl}
+ }
+ {
+ \knot_test_endpoint:vnT {knot previous \tl_use:N \l_@@_tmpg_tl} {initial point}
+ {
+
+ \spath_prepend_no_move:cv {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:c {knot previous \tl_use:N \l_@@_tmpg_tl}}}
+ \tl_set_eq:Nc \l_@@_tmpa_tl {knot \tl_use:N \l_@@_prefix_tl -1}
+ }
+ }
+ }
+% \end{macrocode}
+% Now the same for appending.
+% \begin{macrocode}
+ \bool_if:nT
+ {
+ \l_@@_append_next_bool
+ &&
+ \tl_if_exist_p:c {knot next \tl_use:N \l_@@_tmpg_tl}
+ &&
+ !\tl_if_empty_p:c {knot previous \tl_use:N \l_@@_tmpg_tl}
+ }
+ {
+ \spath_append_no_move:cv {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:N \l_@@_tmpg_tl}}
+ \bool_if:nT
+ {
+ \l_@@_splits_bool
+ &&
+ \tl_if_exist_p:c {knot previous \tl_use:N
+ \l_@@_tmpg_tl}
+ &&
+ !\tl_if_empty_p:c {knot previous \tl_use:N \l_@@_tmpg_tl}
+ }
+ {
+ \knot_test_endpoint:vnT {knot previous \tl_use:N \l_@@_tmpg_tl} {final point}
+ {
+ \spath_append_no_move:cv {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:c {knot next \tl_use:N \l_@@_tmpg_tl}}}
+
+ }
+ }
+ }
+
+ \tl_set:Nn \l_@@_tmpg_tl {\tl_use:N \l_@@_prefix_tl -1}
+ }
+ }
+% \end{macrocode}
+% Now we render the crossing.
+% \begin{macrocode}
+ \pgfscope
+ \group_begin:
+ \tikzset{knot~ diagram/every~ intersection/.try, every~ intersection/.try, knot~ diagram/intersection~ \int_use:N \g_@@_intersections_int/.try}
+ \knot_draw_crossing:VVV \l_@@_tmpg_tl \l_@@_tmpa_dim \l_@@_tmpb_dim
+ \coordinate (\l_@@_name_tl \c_space_tl \int_use:N \g_@@_intersections_int) at (\dim_use:N \l_@@_tmpa_dim, \dim_use:N \l_@@_tmpb_dim);
+ \group_end:
+ \endpgfscope
+% \end{macrocode}
+% This ends the boolean as to whether to consider the intersection at all
+% \begin{macrocode}
+ }
+% \end{macrocode}
+% And possibly stick a coordinate with a label at the crossing.
+% \begin{macrocode}
+ \tl_if_empty:NF \l_@@_node_tl
+ {
+ \seq_gpush:Nx \g_@@_nodes_seq { \l_@@_node_tl at (\dim_use:N \l_@@_tmpa_dim, \dim_use:N \l_@@_tmpb_dim) {};}
+ }
+ }
+}
+
+\cs_generate_variant:Nn \knot_intersections:nn {VV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_test_endpoint:N}
+% Test whether the point is near the intersection point.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \knot_test_endpoint:N #1 {p,T,F,TF}
+{
+ \dim_compare:nTF
+ {
+ \dim_abs:n { \l_@@_tmpa_dim - \tl_item:Nn #1 {1}}
+ +
+ \dim_abs:n { \l_@@_tmpb_dim - \tl_item:Nn #1 {2}}
+ <
+ \l_@@_tolerance_dim
+ }
+ {
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_test_endpoint:nn}
+% Wrapper around the above.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \knot_test_endpoint:nn #1#2 {T,F,TF}
+{
+ \use:c {spath_#2:Nv} \l_@@_tmpd_tl {knot #1}
+ \knot_test_endpoint:NTF \l_@@_tmpd_tl
+ {
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+}
+
+\cs_generate_variant:Nn \knot_test_endpoint:nnT {VnT,vnT}
+\cs_generate_variant:Nn \knot_test_endpoint:nnF {VnF,vnF}
+\cs_generate_variant:Nn \knot_test_endpoint:nnTF {VnTF,vnTF}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_draw_crossing:nnn}
+% This is the code that actually renders a crossing.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_draw_crossing:nnn #1#2#3
+{
+ \group_begin:
+ \pgfscope
+ \path[knot~ diagram/background~ clip] (#2, #3) circle[radius=\l_@@_clip_bg_radius_dim];
+
+ \tl_set:Nn \l_@@_tmpa_tl {knot~ diagram/every~ strand/.try,}
+ \tl_if_exist:cT {l_@@_options_ #1}
+ {
+ \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_options_ #1}
+ }
+ \tl_put_right:Nn \l_@@_tmpa_tl {,knotbg,line~ width= \tl_use:N \l_@@_clip_width_tl * \pgflinewidth}
+ \spath_tikz_path:Vv \l_@@_tmpa_tl {knot #1}
+
+ \endpgfscope
+
+ \pgfscope
+ \path[knot~ diagram/clip] (#2, #3) circle[radius=\l_@@_clip_draw_radius_dim];
+
+ \tl_set:Nn \l_@@_tmpa_tl {knot~ diagram/every~ strand/.try,}
+ \tl_if_exist:cT {l_@@_options_ #1}
+ {
+ \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_options_ #1}
+ }
+ \tl_put_right:Nn \l_@@_tmpa_tl {,knot~ diagram/only~ when~ rendering/.try,only~ when~ rendering/.try}
+ \spath_tikz_path:Vv \l_@@_tmpa_tl {knot #1}
+
+ \endpgfscope
+ \group_end:
+}
+
+\cs_generate_variant:Nn \knot_draw_crossing:nnn {nVV, VVV}
+
+\cs_new_protected_nopar:Npn \knot_draw_crossing:nn #1#2
+{
+ \tikz@scan@one@point\pgfutil@firstofone #2 \relax
+ \knot_draw_crossing:nVV {#1} \pgf@x \pgf@y
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_split_strands:}
+% This, and the following macros, are for splitting strands into filaments.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_split_strands:
+{
+ \int_gzero:N \g_@@_filaments_int
+ \int_step_function:nnnN {1} {1} {\l_@@_strands_int} \knot_split_strand:n
+ \int_step_function:nnnN {1} {1} {\g_@@_filaments_int} \knot_compute_nexts:n
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_compute_nexts:n}
+% Each filament needs to know its predecessor and successor.
+% We work out the predecessors as we go along, this fills in the successors.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_compute_nexts:n #1
+{
+ \tl_clear_new:c {knot next \tl_use:c {knot previous filament #1}}
+ \tl_set:cn {knot next \tl_use:c {knot previous filament #1}} {filament #1}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_split_strand:n}
+% Sets up the split for a single strand.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_split_strand:n #1
+{
+ \int_set_eq:NN \l_@@_component_start_int \g_@@_filaments_int
+ \int_incr:N \l_@@_component_start_int
+ \tl_set_eq:Nc \l_@@_tmpa_tl {l_@@_options_strand #1}
+ \spath_segments_to_seq:Nv \l_@@_segments_seq {knot strand #1}
+ \seq_map_function:NN \l_@@_segments_seq \knot_save_filament:N
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\knot_save_filament:N}
+% Saves a filament as a new \Verb+spath+ object.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \knot_save_filament:N #1
+{
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_item:nn {#1} {4}}
+ \tl_case:NnF \l_@@_tmpb_tl
+ {
+ \c_spath_moveto_tl
+ {
+ \int_compare:nT {\l_@@_component_start_int < \g_@@_filaments_int}
+ {
+ \int_set_eq:NN \l_@@_component_start_int \g_@@_filaments_int
+ }
+ }
+ \c_spath_lineto_tl
+ {
+ \int_gincr:N \g_@@_filaments_int
+ \tl_clear_new:c {knot filament \int_use:N \g_@@_filaments_int}
+ \tl_set:cn {knot filament \int_use:N \g_@@_filaments_int} {#1}
+
+ \tl_clear_new:c {l_@@_options_filament \int_use:N \g_@@_filaments_int}
+ \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int} \l_@@_tmpa_tl
+
+ \tl_clear_new:c {knot previous filament \int_use:N \g_@@_filaments_int}
+ \int_compare:nF {\l_@@_component_start_int == \g_@@_filaments_int}
+ {
+ \tl_set:cx {knot previous filament \int_use:N \g_@@_filaments_int} {filament \int_eval:n {\g_@@_filaments_int - 1}}
+ }
+ }
+ \c_spath_curvetoa_tl
+ {
+ \int_gincr:N \g_@@_filaments_int
+ \tl_clear_new:c {knot filament \int_use:N \g_@@_filaments_int}
+ \tl_set:cn {knot filament \int_use:N \g_@@_filaments_int} {#1}
+ \tl_clear_new:c {l_@@_options_filament \int_use:N \g_@@_filaments_int}
+ \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int} \l_@@_tmpa_tl
+
+ \tl_clear_new:c {knot previous filament \int_use:N \g_@@_filaments_int}
+ \int_compare:nF {\l_@@_component_start_int == \g_@@_filaments_int}
+ {
+ \tl_set:cx {knot previous filament \int_use:N \g_@@_filaments_int} {filament \int_eval:n {\g_@@_filaments_int - 1}}
+ }
+ }
+ \c_spath_closepath_tl
+ {
+ \int_gincr:N \g_@@_filaments_int
+ \tl_clear_new:c {knot filament \int_use:N \g_@@_filaments_int}
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_put_right:Nx {\tl_item:nn {#1} {1}\tl_item:nn {#1} {2}\tl_item:nn {#1} {3}}
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_lineto_tl
+ \tl_put_right:Nx {\tl_item:nn {#1} {5}\tl_item:nn {#1} {6}}
+
+ \tl_set:cV {knot filament \int_use:N \g_@@_filaments_int} \l_@@_tmpa_tl
+ \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int} \l_@@_tmpa_tl
+ \tl_clear_new:c {knot previous filament \int_use:N \g_@@_filaments_int}
+ \int_compare:nF {\l_@@_component_start_int == \g_@@_filaments_int}
+ {
+ \tl_set:cx {knot previous filament \int_use:N \g_@@_filaments_int} {filament \int_eval:n {\g_@@_filaments_int - 1}}
+ }
+ \tl_set:cx {knot previous filament \int_use:N \l_@@_component_start_int} {filament \int_use:N \g_@@_filaments_int}
+ }
+ }
+ {
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\redraw}
+% The user can redraw segments of the strands at specific locations.
+% \begin{macrocode}
+\NewDocumentCommand \redraw { m m }
+{
+% \tikz@scan@one@point\pgfutil@firstofone #2 \relax
+ \tl_put_right:Nn \l_@@_redraws_tl {\knot_draw_crossing:nn}
+ \tl_put_right:Nx \l_@@_redraws_tl {
+ {strand #1} {#2}% {\dim_use:N \pgf@x} {\dim_use:N \pgf@y}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\ExplSyntaxOff
+% \end{macrocode}
+%<@@=>
+%
+% \begin{macro}[internal]{\pgf@sh@@knotanchor}
+% Add the extra anchors for the knot crossing nodes.
+% \begin{macrocode}
+\def\pgf@sh@@knotanchor#1#2{%
+ \anchor{#2 north west}{%
+ \csname pgf@anchor@knot #1@north west\endcsname%
+ \pgf@x=#2\pgf@x%
+ \pgf@y=#2\pgf@y%
+ }%
+ \anchor{#2 north east}{%
+ \csname pgf@anchor@knot #1@north east\endcsname%
+ \pgf@x=#2\pgf@x%
+ \pgf@y=#2\pgf@y%
+ }%
+ \anchor{#2 south west}{%
+ \csname pgf@anchor@knot #1@south west\endcsname%
+ \pgf@x=#2\pgf@x%
+ \pgf@y=#2\pgf@y%
+ }%
+ \anchor{#2 south east}{%
+ \csname pgf@anchor@knot #1@south east\endcsname%
+ \pgf@x=#2\pgf@x%
+ \pgf@y=#2\pgf@y%
+ }%
+ \anchor{#2 north}{%
+ \csname pgf@anchor@knot #1@north\endcsname%
+ \pgf@x=#2\pgf@x%
+ \pgf@y=#2\pgf@y%
+ }%
+ \anchor{#2 east}{%
+ \csname pgf@anchor@knot #1@east\endcsname%
+ \pgf@x=#2\pgf@x%
+ \pgf@y=#2\pgf@y%
+ }%
+ \anchor{#2 west}{%
+ \csname pgf@anchor@knot #1@west\endcsname%
+ \pgf@x=#2\pgf@x%
+ \pgf@y=#2\pgf@y%
+ }%
+ \anchor{#2 south}{%
+ \csname pgf@anchor@knot #1@south\endcsname%
+ \pgf@x=#2\pgf@x%
+ \pgf@y=#2\pgf@y%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{knot crossing}
+% \begin{macrocode}
+\pgfdeclareshape{knot crossing}
+{
+ \inheritsavedanchors[from=circle] % this is nearly a circle
+ \inheritanchorborder[from=circle]
+ \inheritanchor[from=circle]{north}
+ \inheritanchor[from=circle]{north west}
+ \inheritanchor[from=circle]{north east}
+ \inheritanchor[from=circle]{center}
+ \inheritanchor[from=circle]{west}
+ \inheritanchor[from=circle]{east}
+ \inheritanchor[from=circle]{mid}
+ \inheritanchor[from=circle]{mid west}
+ \inheritanchor[from=circle]{mid east}
+ \inheritanchor[from=circle]{base}
+ \inheritanchor[from=circle]{base west}
+ \inheritanchor[from=circle]{base east}
+ \inheritanchor[from=circle]{south}
+ \inheritanchor[from=circle]{south west}
+ \inheritanchor[from=circle]{south east}
+ \inheritanchorborder[from=circle]
+ \pgf@sh@@knotanchor{crossing}{2}
+ \pgf@sh@@knotanchor{crossing}{3}
+ \pgf@sh@@knotanchor{crossing}{4}
+ \pgf@sh@@knotanchor{crossing}{8}
+ \pgf@sh@@knotanchor{crossing}{16}
+ \pgf@sh@@knotanchor{crossing}{32}
+ \backgroundpath{
+ \pgfutil@tempdima=\radius%
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \advance\pgfutil@tempdima by-\pgf@yb%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@xb%
+ \fi%
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{knot over cross}
+% \begin{macrocode}
+\pgfdeclareshape{knot over cross}
+{
+ \inheritsavedanchors[from=rectangle] % this is nearly a circle
+ \inheritanchorborder[from=rectangle]
+ \inheritanchor[from=rectangle]{north}
+ \inheritanchor[from=rectangle]{north west}
+ \inheritanchor[from=rectangle]{north east}
+ \inheritanchor[from=rectangle]{center}
+ \inheritanchor[from=rectangle]{west}
+ \inheritanchor[from=rectangle]{east}
+ \inheritanchor[from=rectangle]{mid}
+ \inheritanchor[from=rectangle]{mid west}
+ \inheritanchor[from=rectangle]{mid east}
+ \inheritanchor[from=rectangle]{base}
+ \inheritanchor[from=rectangle]{base west}
+ \inheritanchor[from=rectangle]{base east}
+ \inheritanchor[from=rectangle]{south}
+ \inheritanchor[from=rectangle]{south west}
+ \inheritanchor[from=rectangle]{south east}
+ \inheritanchorborder[from=rectangle]
+ \backgroundpath{
+ \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ }
+ \foregroundpath{
+% store lower right in xa/ya and upper right in xb/yb
+ \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{knot under cross}
+% \begin{macrocode}
+\pgfdeclareshape{knot under cross}
+{
+ \inheritsavedanchors[from=rectangle] % this is nearly a circle
+ \inheritanchorborder[from=rectangle]
+ \inheritanchor[from=rectangle]{north}
+ \inheritanchor[from=rectangle]{north west}
+ \inheritanchor[from=rectangle]{north east}
+ \inheritanchor[from=rectangle]{center}
+ \inheritanchor[from=rectangle]{west}
+ \inheritanchor[from=rectangle]{east}
+ \inheritanchor[from=rectangle]{mid}
+ \inheritanchor[from=rectangle]{mid west}
+ \inheritanchor[from=rectangle]{mid east}
+ \inheritanchor[from=rectangle]{base}
+ \inheritanchor[from=rectangle]{base west}
+ \inheritanchor[from=rectangle]{base east}
+ \inheritanchor[from=rectangle]{south}
+ \inheritanchor[from=rectangle]{south west}
+ \inheritanchor[from=rectangle]{south east}
+ \inheritanchorborder[from=rectangle]
+ \backgroundpath{
+ \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
+ }
+ \foregroundpath{
+% store lower right in xa/ya and upper right in xb/yb
+ \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{knot vert}
+% \begin{macrocode}
+\pgfdeclareshape{knot vert}
+{
+ \inheritsavedanchors[from=rectangle] % this is nearly a circle
+ \inheritanchorborder[from=rectangle]
+ \inheritanchor[from=rectangle]{north}
+ \inheritanchor[from=rectangle]{north west}
+ \inheritanchor[from=rectangle]{north east}
+ \inheritanchor[from=rectangle]{center}
+ \inheritanchor[from=rectangle]{west}
+ \inheritanchor[from=rectangle]{east}
+ \inheritanchor[from=rectangle]{mid}
+ \inheritanchor[from=rectangle]{mid west}
+ \inheritanchor[from=rectangle]{mid east}
+ \inheritanchor[from=rectangle]{base}
+ \inheritanchor[from=rectangle]{base west}
+ \inheritanchor[from=rectangle]{base east}
+ \inheritanchor[from=rectangle]{south}
+ \inheritanchor[from=rectangle]{south west}
+ \inheritanchor[from=rectangle]{south east}
+ \inheritanchorborder[from=rectangle]
+ \backgroundpath{
+% store lower right in xa/ya and upper right in xb/yb
+ \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
+ \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{knot horiz}
+% \begin{macrocode}
+\pgfdeclareshape{knot horiz}
+{
+ \inheritsavedanchors[from=rectangle] % this is nearly a circle
+ \inheritanchorborder[from=rectangle]
+ \inheritanchor[from=rectangle]{north}
+ \inheritanchor[from=rectangle]{north west}
+ \inheritanchor[from=rectangle]{north east}
+ \inheritanchor[from=rectangle]{center}
+ \inheritanchor[from=rectangle]{west}
+ \inheritanchor[from=rectangle]{east}
+ \inheritanchor[from=rectangle]{mid}
+ \inheritanchor[from=rectangle]{mid west}
+ \inheritanchor[from=rectangle]{mid east}
+ \inheritanchor[from=rectangle]{base}
+ \inheritanchor[from=rectangle]{base west}
+ \inheritanchor[from=rectangle]{base east}
+ \inheritanchor[from=rectangle]{south}
+ \inheritanchor[from=rectangle]{south west}
+ \inheritanchor[from=rectangle]{south east}
+ \inheritanchorborder[from=rectangle]
+ \foregroundpath{
+% store lower right in xa/ya and upper right in xb/yb
+ \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
+ \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
+ \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
+ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \iffalse
+%</knots>
+% \fi
+%\Finale
+\endinput
diff --git a/graphics/pgf/contrib/spath3/spath3_code.pdf b/graphics/pgf/contrib/spath3/spath3_code.pdf
index be1f2941bd..77d3e3b723 100644
--- a/graphics/pgf/contrib/spath3/spath3_code.pdf
+++ b/graphics/pgf/contrib/spath3/spath3_code.pdf
Binary files differ
diff --git a/macros/latex/contrib/eqexam/README.md b/macros/latex/contrib/eqexam/README.md
index ab464cabca..5e0bc68ab3 100644
--- a/macros/latex/contrib/eqexam/README.md
+++ b/macros/latex/contrib/eqexam/README.md
@@ -1,5 +1,5 @@
The eqexam Package
-Dated: 2020-03-14
+Dated: 2021-01-20
Author: D. P. Story
eqExam is a LaTeX package for writing exams, tests, quizzes,
@@ -40,6 +40,9 @@ this package are as follows:
folder. See also the series of blogs at
http://www.acrotex.net/blog/?tag=fortextbook
+What's New (2021-01-20) Defined \trackProblemsOn and \numPtsOfProblem;
+added \doNoRandomizeChoices and \allowRandomizedChoices. See documentation.
+
What's New (2020-03-14) Defined several commands and one environment to
support the insertion of a figure into a problem. Demo file that illustrates
these new commands and environment is found at
diff --git a/macros/latex/contrib/eqexam/aebrandom.def b/macros/latex/contrib/eqexam/aebrandom.def
index f2952e463e..defbed5737 100644
--- a/macros/latex/contrib/eqexam/aebrandom.def
+++ b/macros/latex/contrib/eqexam/aebrandom.def
@@ -18,11 +18,11 @@
%% License, or (at your option) any later version. %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ProvidesFile{aebrandom.def}
- [2020/03/14 v8.5.10 %
+ [2021/01/20 v8.6.2 %
Exerquiz support for randomization (dps)]
\@ifundefined{nextrandom}{\input{random.tex}}{}
\def\nextrandom{\begingroup
- \ifnum\randomi<\@ne % then initialize with time
+ \ifnum\randomi<\@ne % then initialize with time
\global\randomi\time
\global\multiply\randomi388 \global\advance\randomi\year
\global\multiply\randomi31 \global\advance\randomi\day
@@ -30,139 +30,138 @@
\message{Randomizer initialized to \the\randomi.}%
\nextrandom \nextrandom \nextrandom
\xdef\InitSeedValue{\the\randomi}%
- \fi
- \count@ii\randomi
- \divide\count@ii 127773 % modulus = multiplier * 127773 + 2836
- \count@\count@ii
- \multiply\count@ii 127773
- \global\advance\randomi-\count@ii % random mod 127773
- \global\multiply\randomi 16807
- \multiply\count@ 2836
- \global\advance\randomi-\count@
- \ifnum\randomi<\z@ \global\advance\randomi 2147483647\relax\fi
+ \fi
+ \count@ii\randomi
+ \divide\count@ii 127773 % modulus = multiplier * 127773 + 2836
+ \count@\count@ii
+ \multiply\count@ii 127773
+ \global\advance\randomi-\count@ii % random mod 127773
+ \global\multiply\randomi 16807
+ \multiply\count@ 2836
+ \global\advance\randomi-\count@
+ \ifnum\randomi<\z@\global\advance\randomi 2147483647\relax\fi
\endgroup
}
\def\writeSeedToSolnFile{\writeT@ExSolns{\string\randomi=\the\randomi}}
-\def\@ansChoices[#1]%
-{%
- \global\let\@tempholdSaveAns\@empty % 5/24
- \global\let\@tempholdSaveChoice\@empty % 5/24
- \global\let\bChoiceLabel\@empty % 5/24
- \ifeq@randomizeallChoices
- \setkeys{bchoice}{#1,random=true}\else
- \setkeys{bchoice}{#1}\fi
- \global\eq@tabColCnt=0
- \ifeq@randomizeChoices\expandafter\@@bChoices
- \else\expandafter\@@ansChoices\fi
+\def\@ansChoices[#1]{%
+ \global\let\@tempholdSaveAns\@empty
+ \global\let\@tempholdSaveChoice\@empty
+ \global\let\bChoiceLabel\@empty
+ \ifeq@randomizeallChoices
+ \setkeys{bchoice}{#1,random=true}\else
+ \setkeys{bchoice}{#1}\fi
+ \global\eq@tabColCnt=\z@
+ \if@DoNotRandomize\eq@randomizeChoicesfalse\fi
+ \ifeq@randomizeChoices\expandafter\@@bChoices
+ \else\expandafter\@@ansChoices\fi
}
\def\@@ansChoices{%
- \ifnum\aeb@numCols=1 % list mode
- \def\eq@next{\@layoutListAns}%
- \else % tabular mode
- \edef\eq@next{\noexpand\@layoutTabularAns{\bChoiceNumCols}}%
- \fi
- \eq@next
+ \ifnum\aeb@numCols=\@ne % list mode
+ \def\eq@next{\@layoutListAns}%
+ \else % tabular mode
+ \edef\eq@next{\noexpand\@layoutTabularAns{\bChoiceNumCols}}%
+ \fi
+ \eq@next
}
\newcount\aeb@numChoices
\newcount\aeb@ranChoice
\newtoks\aeb@hold\aeb@hold={}
\def\@@bChoices{\gdef\@temphold{}\gdef\@tempholdrandom{}%
- \gdef\@tempholdfreeze{}\aeb@searchfortoken{\@getAns}%
+ \gdef\@tempholdfreeze{}\aeb@searchfortoken{\@getAns}%
}
\def\aeb@searchfortoken#1{%
- \@ifnextchar\Ans{\advance\aeb@numChoices1\relax#1}
- {\@ifnextchar\eFreeze{\expandafter\@getFreezeAns\@gobble}
- {\@ifnextchar\par{\def\@@temp{\aeb@searchfortoken{#1}}%
- \expandafter\@@temp\@gobble}{\@eChoices}}}%
+ \@ifnextchar\Ans{\advance\aeb@numChoices1\relax#1}
+ {\@ifnextchar\eFreeze{\expandafter\@getFreezeAns\@gobble}
+ {\@ifnextchar\par{\def\@@temp{\aeb@searchfortoken{#1}}%
+ \expandafter\@@temp\@gobble}{\@eChoices}}}%
}
\long\def\@getAns\Ans#1\eAns{%
- \g@addto@macro\@temphold{{\Ans#1\eAns}}%
- \aeb@searchfortoken{\@getAns}%
+ \g@addto@macro\@temphold{{\Ans#1\eAns}}%
+ \aeb@searchfortoken{\@getAns}%
}
\def\@getFreezeAns{\aeb@searchfortoken{\@@getFreezeAns}}
\long\def\@@getFreezeAns\Ans#1\eAns{%
- \g@addto@macro\@tempholdfreeze{\Ans#1\eAns}%
- \aeb@searchfortoken{\@@getFreezeAns}%
+ \g@addto@macro\@tempholdfreeze{\Ans#1\eAns}%
+ \aeb@searchfortoken{\@@getFreezeAns}%
}
\long\def\@eChoices#1\eChoices{%
- \aeb@randomizeChoices{\the\aeb@numChoices}%
+ \aeb@randomizeChoices{\the\aeb@numChoices}%
}
\def\aeb@randomizeChoices#1{%
- \setrannum{\aeb@ranChoice}{1}{#1}
- \eqtmpcnta\z@\aeb@hold=\expandafter{\@temphold}\def\@temphold{}%
- \expandafter\@tfor\expandafter
- \@temp\expandafter:\expandafter=\the\aeb@hold \do {%
- \advance\eqtmpcnta\@ne
- \ifnum\eqtmpcnta=\aeb@ranChoice\relax
- \aeb@hold=\expandafter\expandafter\expandafter
- {\expandafter\@tempholdrandom\@temp}%
- \edef\@tempholdrandom{\the\aeb@hold}%
- \else
- \aeb@hold=\expandafter\expandafter\expandafter
- {\expandafter\@temphold\expandafter{\@temp}}%
- \edef\@temphold{\the\aeb@hold}%
- \fi
- }%
- \aeb@numChoices=#1
- \advance\aeb@numChoices-1
- \ifnum\aeb@numChoices=0\relax
- \def\aeb@next{\aeb@finishedRandomizing}\else
- \def\aeb@next{\aeb@randomizeChoices{\the\aeb@numChoices}}\fi
- \aeb@next
+ \setrannum{\aeb@ranChoice}{1}{#1}
+ \eqtmpcnta\z@\aeb@hold=\expandafter{\@temphold}\def\@temphold{}%
+ \expandafter\@tfor\expandafter
+ \@temp\expandafter:\expandafter=\the\aeb@hold \do {%
+ \advance\eqtmpcnta\@ne
+ \ifnum\eqtmpcnta=\aeb@ranChoice\relax
+ \aeb@hold=\expandafter\expandafter\expandafter
+ {\expandafter\@tempholdrandom\@temp}%
+ \edef\@tempholdrandom{\the\aeb@hold}%
+ \else
+ \aeb@hold=\expandafter\expandafter\expandafter
+ {\expandafter\@temphold\expandafter{\@temp}}%
+ \edef\@temphold{\the\aeb@hold}%
+ \fi
+ }%
+ \aeb@numChoices=#1
+ \advance\aeb@numChoices\m@ne
+ \ifnum\aeb@numChoices=\z@
+ \def\aeb@next{\aeb@finishedRandomizing}\else
+ \def\aeb@next{\aeb@randomizeChoices{\the\aeb@numChoices}}\fi
+ \aeb@next
}
\def\aeb@finishedRandomizing{%
- \aeb@hold=\expandafter\expandafter\expandafter
- {\expandafter\@tempholdrandom\@tempholdfreeze}%
- \gdef\@temphold{}\gdef\@tempholdrandom{}\gdef\@tempholdfreeze{}%
- \edef\finished@Randomizing{%
- \noexpand\@@ansChoices
- \the\aeb@hold
- \noexpand\eChoices}%
- \finished@Randomizing
+ \aeb@hold=\expandafter\expandafter\expandafter
+ {\expandafter\@tempholdrandom\@tempholdfreeze}%
+ \gdef\@temphold{}\gdef\@tempholdrandom{}\gdef\@tempholdfreeze{}%
+ \edef\finished@Randomizing{%
+ \noexpand\@@ansChoices
+ \the\aeb@hold
+ \noexpand\eChoices}%
+ \finished@Randomizing
}
\def\saveRandomSeed{\PackageInfo{exerquiz}
- {The command \string\saveRandomSeed\space
- is deprecated.\MessageBreak Seed automatically saved}}
+ {The command \string\saveRandomSeed\space
+ is deprecated.\MessageBreak Seed automatically saved}}
\@ifpackageloaded{ran_toks}{%
- \let\inputRandomSeed\useLastAsSeed
- \let\useRandomSeed\useThisSeed
+ \let\inputRandomSeed\useLastAsSeed
+ \let\useRandomSeed\useThisSeed
}{%
- \def\inputRandomSeed{\eq@readRandomData}%
- \def\useRandomSeed#1{\saveseedfalse\randomi=#1}%
+ \def\inputRandomSeed{\eq@readRandomData}%
+ \def\useRandomSeed#1{\saveseedfalse\randomi=#1}%
}
\def\InitSeedValue{\the\randomi} % dps
\@ifundefined{ifsaveseed}{\newif\ifsaveseed\saveseedtrue}{} % dps
-\def\eq@writeRandomData
-{%
- \ifsaveseed
- \@ifundefined{saveseedinfo}{\newwrite\saveseedinfo}{}
- \immediate\openout \saveseedinfo \jobname_rt.sav
- \let\verbatim@out\saveseedinfo
- \def\eqrt@msgi{initializing seed value}%
- \def\eqrt@msgii{last random number used}%
- \uccode`c=`\%\uppercase{%
- \immediate\write\verbatim@out
- {\InitSeedValue\space c \eqrt@msgi}%
- \immediate\write\verbatim@out
- {\the\randomi\space c \eqrt@msgii}%
- }\immediate\closeout\saveseedinfo
- \fi
+\def\eq@writeRandomData{%
+ \ifsaveseed
+ \@ifundefined{saveseedinfo}{\newwrite\saveseedinfo}{}
+ \immediate\openout \saveseedinfo \jobname_rt.sav
+ \let\verbatim@out\saveseedinfo
+ \def\eqrt@msgi{initializing seed value}%
+ \def\eqrt@msgii{last random number used}%
+ \uccode`c=`\%\uppercase{%
+ \immediate\write\verbatim@out
+ {\InitSeedValue\space c \eqrt@msgi}%
+ \immediate\write\verbatim@out
+ {\the\randomi\space c \eqrt@msgii}%
+ }\immediate\closeout\saveseedinfo
+ \fi
}
\AtEndDocument{\eq@writeRandomData}
\def\eq@readRandomData{\IfFileExists{\jobname_rt.sav}{%
- \PackageInfo{exerquiz}{Inputting \jobname_rt.sav}%
- \@ifundefined{readsavfile}{\newread\readsavfile}{}%
- \openin\readsavfile=\jobname_rt.sav
- \read\readsavfile to \InitSeedValue
- \read\readsavfile to \eqlastRandomNum
- \closein\readsavfile
- \randomi=\eqlastRandomNum
- \xdef\InitSeedValue{\the\randomi}%
- \immediate\closeout\readsavfile
+ \PackageInfo{exerquiz}{Inputting \jobname_rt.sav}%
+ \@ifundefined{readsavfile}{\newread\readsavfile}{}%
+ \openin\readsavfile=\jobname_rt.sav
+ \read\readsavfile to \InitSeedValue
+ \read\readsavfile to \eqlastRandomNum
+ \closein\readsavfile
+ \randomi=\eqlastRandomNum
+ \xdef\InitSeedValue{\the\randomi}%
+ \immediate\closeout\readsavfile
}{%
- \PackageInfo{exerquiz}{\jobname_rt.sav cannot
- be found, \MessageBreak
- using the random initializer}%
+ \PackageInfo{exerquiz}{\jobname_rt.sav cannot
+ be found, \MessageBreak
+ using the random initializer}%
}}
\endinput
%%
diff --git a/macros/latex/contrib/eqexam/doc/eqexam.pdf b/macros/latex/contrib/eqexam/doc/eqexam.pdf
index ea03c1f8fb..59d7861b27 100644
--- a/macros/latex/contrib/eqexam/doc/eqexam.pdf
+++ b/macros/latex/contrib/eqexam/doc/eqexam.pdf
Binary files differ
diff --git a/macros/latex/contrib/eqexam/doc/eqexamman.pdf b/macros/latex/contrib/eqexam/doc/eqexamman.pdf
index 9684fd4f9b..1fe69fa3bf 100644
--- a/macros/latex/contrib/eqexam/doc/eqexamman.pdf
+++ b/macros/latex/contrib/eqexam/doc/eqexamman.pdf
Binary files differ
diff --git a/macros/latex/contrib/eqexam/doc/eqexamman.tex b/macros/latex/contrib/eqexam/doc/eqexamman.tex
index 258bf56245..d580d1a4db 100644
--- a/macros/latex/contrib/eqexam/doc/eqexamman.tex
+++ b/macros/latex/contrib/eqexam/doc/eqexamman.tex
@@ -11,6 +11,8 @@
\usepackage[bypasspkgpagestyle,nomarginwrite,usecustomdesign,
useclassmaketitle,flextended
]{eqexam}
+
+
%\usepackage[designv,
% latextoc,forcolorpaper,
% centertitlepage]{web}
@@ -150,7 +152,7 @@ part of the\texorpdfstring{\\}{ }\texorpdfstring{\AcroTeX}{AcroTeX} eDucation Bu
\keywords{LaTeX, hyperref, PDF, exercises, quizzes}
\university{{\AcroT} Software Development Team}
\email{dpstory@acrotex.net}
-\version{5.1.10, 2020/03/14}
+\version{5.1.13, 2021/01/20}
\copyrightyears{2005-\the\year}
\renewcommand{\exsectitletext}{Solutions to exams in this manual}
@@ -1603,7 +1605,7 @@ necessary in two situations:
removing questions that have randomization).
\end{enumerate}
-\newtopic\textbf{Things to look for:} If \textsf{eqexam} is not rearranging the order
+\newtopic\textbf{Things to look for: } If \textsf{eqexam} is not rearranging the order
of the choices as you expect it to, it could be that
\textsf{eqexam} is reading an old \texttt{.sav} file. Either delete that file
in your source folder, or comment out \cs{inputRandomSeed} in your document.
@@ -1624,10 +1626,19 @@ use that seed value for that class, for example
\end{Verbatim}
Of course comment out \cs{inputRandomSeed}.
-\begin{Verbatim}[xleftmargin=\amtIndent]
+\newtopic\textbf{Controlling randomization.} There are several commands that control whether
+randomization occurs.
+\settowidth{\aebdimen}{\cs{allowRandomizedChoices}}%
+\begin{dCmd}[commandchars=!()]{\aebdimen+2\fboxsep+2\fboxrule}
\turnOnRandomize
\obeyLocalRandomize
-\end{Verbatim}
+\doNotRandomizeChoices
+\allowRandomizedChoices
+\end{dCmd}
+%\begin{Verbatim}[xleftmargin=\amtIndent]
+%\turnOnRandomize
+%\obeyLocalRandomize
+%\end{Verbatim}
The command \cs{turnOnRandomize} overrides all local settings of \cs{bChoices}
and causes all choice lists to be randomized. While \cs{obeyLocalRandomize}
@@ -1658,13 +1669,19 @@ the choices will not be randomized, because the \texttt{random}
option was not specified; or they will be randomized if the
\texttt{random} option is used.
+\newtopic\indent The command \cs{doNotRandomizeChoices} overrides the
+\opt{allowrandomize} option; when in effect, randomization of the choices
+does not occur. The companion command \cs{allowRandomizedChoices} restores the
+authority of the \opt{allowrandomize} option.
+
\newtopic\textcolor{red}{Limitations:} There are natural limitations on the use
of \cs{bChoices} and \cs{eChoices} and consequently, there are
limitations on the randomization. The content between \cs{Ans} and
\cs{eAns} cannot have any verbatim text. This is usually not a
problem for mathematical content, but could be a limitation for
-computer science where questions about syntax may be posed. I have
-in mind a work-around, but haven't pursued the problem as of yet.
+computer science where questions about syntax may be posed.
+
+%I have in mind a work-around, but haven't pursued the problem as of yet.
\subsection{Labeling Choices}
@@ -5186,6 +5203,23 @@ the figure around the text of the question.
environment, named \texttt{\href{\urlAcroTeXBlog/?p=1419}{ins-fig.pdf}},
is found on the {\AcroBlog}.
+\subsection{Tracking problem values}
+
+As an application to the \pkg{skills} package, three new commands are introduced
+into the \pkg{eqexam} core.
+
+\settowidth{\aebdimen}{\ttfamily\string\numPtsOfProblem[\meta{exam-label}]\darg{\meta{prob-num}}}%
+\def\1{\rlap{\hskip\linewidth\texttt{ \%}\textsf{ turn on problem tracking}}}%
+\def\2{\rlap{\hskip\linewidth\texttt{ \%}\textsf{ turn off problem tracking}}}%
+\def\3{\rlap{\hskip\linewidth\texttt{ \%}\textsf{ typeset points for problem}}}%
+\begin{dCmd}[commandchars=!()]{\aebdimen+2\fboxsep+2\fboxrule}
+!1\trackProblemsOn
+!2\trackProblemsOff
+!3\numPtsOfProblem[!meta(exam-label)]{!meta(prob-num)}
+\end{dCmd}
+When tracking is on (\cs{trackProblemsOn}), the number of points for each problem
+is written to the AUX file. Use \cs{numPtsOfProblem} to typeset the amount of points for \ameta{prob-num}
+of exam part \ameta{exam-label}. Turn off tracking with \cs{trackProblemsOff}.
\newpage
\markright{References}
diff --git a/macros/latex/contrib/eqexam/eqexam.def b/macros/latex/contrib/eqexam/eqexam.def
index 0d865559a7..55f3a9bcab 100644
--- a/macros/latex/contrib/eqexam/eqexam.def
+++ b/macros/latex/contrib/eqexam/eqexam.def
@@ -7,7 +7,7 @@
%% exerquiz.dtx (with options: `eqexam')
%%
\ProvidesFile{eqexam.def}
- [2020/03/14 v8.5.10 %
+ [2021/01/20 v8.6.2 %
Exerquiz support file for eqexam (dps)]
\let\eq@YES=y \let\eq@NO=n
\let\eq@One=1 \let\eq@Zero=0
@@ -41,8 +41,11 @@
\expandafter#2\fi}
\newif\ifeq@randomizeChoices \eq@randomizeChoicesfalse
\newif\ifeq@randomizeallChoices \eq@randomizeallChoicesfalse
+\newif\if@DoNotRandomize \@DoNotRandomizefalse
\def\turnOnRandomize{\eq@randomizeallChoicestrue}
\def\obeyLocalRandomize{\eq@randomizeallChoicesfalse}
+\def\doNotRandomizeChoices{\@DoNotRandomizetrue}
+\def\allowRandomizedChoices{\@DoNotRandomizefalse}
\let\saveRandomSeed\relax
\let\inputRandomSeed\relax
\newcommand{\exsolafter}{\eq@exsolafterDefault}
@@ -1115,45 +1118,44 @@
\let\propQ@labelwidth\@empty
\define@key{props@ques}{topsep}[\the\topsep]{\edef\propQ@topsep{#1}}
\define@key{props@ques}{partopsep}[\the\partopsep]%
- {\edef\propQ@partopsep{#1}}
+ {\edef\propQ@partopsep{#1}}
\define@key{props@ques}{parsep}[\the\parsep]{\edef\propQ@parsep{#1}}
\define@key{props@ques}{itemsep}[\the\itemsep]{\edef\propQ@itemsep{#1}}
\define@key{props@ques}{labelsepTo}[\normalsize\normalfont\ ]%
- {\def\propQ@labelsepTo{#1}}
+ {\def\propQ@labelsepTo{#1}}
\define@key{props@ques}{labelsep}[\@empty]{\def\propQ@labelsep{#1}}
\let\propQ@labelsep\@empty
\define@key{props@ques}{color}[blue]{\quesNumColor{#1}}
\setkeys{props@ques}{labelwidthTo,topsep,partopsep,parsep,%
itemsep,labelsepTo,color}%
-\newenvironment{questions}[1][]
-{%
- \ifnum\@eqquestiondepth>\tw@\@toodeep\else
- \advance\@eqquestiondepth\@ne\fi
- \def\@quesctr{eqquestionno\romannumeral\the\@eqquestiondepth}%
- \toks@=\expandafter\expandafter\expandafter{#1}\expandafter
- \xdef\csname quesOpts\@quesctr\endcsname{\the\toks@}%
- \edef\tempexp{\noexpand\setkeys{props@ques}{\the\toks@}}\tempexp
- \list{\qMark@Hook\prior@questionsHook
- \insE@rlyAtQues\gdef\eqPTs{1}%
- \global\let\eqQT\eq@na%
- {\@tempcnta=0 \let\@thispr@b\@empty
- \@whilenum\@tempcnta<\@eqquestiondepth\do{\advance\@tempcnta\@ne
- \ifx\@thispr@b\@empty\edef\@thispr@b{%
- \csname theeqquestionno\romannumeral\the\@tempcnta\endcsname}\else
- \edef\@thispr@b{\@thispr@b%
- \csname theeqquestionno\romannumeral\the\@tempcnta\endcsname}\fi
- }\xdef\@currentQues{\@thispr@b}}%
- \makebox[\labelwidth][r]{\normalfont\@nameuse{label\@quesctr}}%
- \xdef\eq@pageThisQ{\the\c@page}%
- \post@questionsHook}{\usecounter{\@quesctr}%
+\newenvironment{questions}[1][]{%
+ \ifnum\@eqquestiondepth>\tw@\@toodeep\else
+ \advance\@eqquestiondepth\@ne\fi
+ \def\@quesctr{eqquestionno\romannumeral\the\@eqquestiondepth}%
+ \toks@=\expandafter\expandafter\expandafter{#1}\expandafter
+ \xdef\csname quesOpts\@quesctr\endcsname{\the\toks@}%
+ \edef\tempexp{\noexpand\setkeys{props@ques}{\the\toks@}}\tempexp
+ \list{\qMark@Hook\prior@questionsHook
+ \insE@rlyAtQues\gdef\eqPTs{1}%
+ \global\let\eqQT\eq@na%
+ {\@tempcnta=0 \let\@thispr@b\@empty
+ \@whilenum\@tempcnta<\@eqquestiondepth\do{\advance\@tempcnta\@ne
+ \ifx\@thispr@b\@empty\edef\@thispr@b{%
+ \csname theeqquestionno\romannumeral\the\@tempcnta\endcsname}\else
+ \edef\@thispr@b{\@thispr@b%
+ \csname theeqquestionno\romannumeral\the\@tempcnta\endcsname}\fi
+ }\xdef\@currentQues{\@thispr@b}}%
+ \makebox[\labelwidth][r]{\normalfont\@nameuse{label\@quesctr}}%
+ \xdef\eq@pageThisQ{\the\c@page}%
+ \post@questionsHook}{\usecounter{\@quesctr}%
\ifx\propQ@labelsep\@empty
- \settowidth{\labelsep}{\propQ@labelsepTo}\else
- \setlength{\labelsep}{\propQ@labelsep}\fi
+ \settowidth{\labelsep}{\propQ@labelsepTo}\else
+ \setlength{\labelsep}{\propQ@labelsep}\fi
\ifx\propQ@labelwidth\@empty
- \settowidth{\labelwidth}%
- {\propQ@labelwidthTo\hspace{\labelsep}}\else
- \settowidth{\labelwidth}{\hspace{\propQ@labelwidth}%
- \hspace{\labelsep}}\fi
+ \settowidth{\labelwidth}%
+ {\propQ@labelwidthTo\hspace{\labelsep}}\else
+ \settowidth{\labelwidth}{\hspace{\propQ@labelwidth}%
+ \hspace{\labelsep}}\fi
\setlength{\topsep}{\propQ@topsep}%
\setlength{\partopsep}{\propQ@partopsep}%
\ifdim\parskip>\z@\addtolength{\topsep}{-\parskip}\fi
@@ -1191,16 +1193,16 @@
}{\aeb@endshortquiz}
\newenvironment{shortquiz*}
{%
- \xdef\eq@pageThisQ{\the\c@page}%
- {\eqtmpcnta\@shortquizCnt\relax\advance\eqtmpcnta\@ne
- \xdef\@shortquizCnt{\the\eqtmpcnta}}%
- \sqForms\@shortquiz
+ \xdef\eq@pageThisQ{\the\c@page}%
+ {\eqtmpcnta\@shortquizCnt\relax\advance\eqtmpcnta\@ne
+ \xdef\@shortquizCnt{\the\eqtmpcnta}}%
+ \sqForms\@shortquiz
}{\aeb@endshortquiz}
\def\@shortquiz{\@ifnextchar[%
- {\@@shortquiz}{\@@shortquiz[\@sqGenBaseName]}}
+ {\@@shortquiz}{\@@shortquiz[\@sqGenBaseName]}}
\def\sq@setCLN#1{\ifx\aebTitleQuiz\@empty
- \protected@edef\@currentlabelname{#1}\else
- \protected@edef\@currentlabelname{\@currentlabelname}\fi
+ \protected@edef\@currentlabelname{#1}\else
+ \protected@edef\@currentlabelname{\@currentlabelname}\fi
}
\let\isQZ=q \let\isSQZ=s
\let\eqQuizType\relax
@@ -1217,7 +1219,7 @@
\let\@Ans\Ans@sq@f
\ifx\oField\@empty
\typeout{^^JExerquiz: Base field name required when using
- shortquiz with '*' option}%
+ shortquiz with '*' option}%
\PackageInfo{exerquiz}{Assuming link style^^J}%
\let\@Ans\Ans@sq@l
\fi
@@ -1329,22 +1331,22 @@
\let\endeqQt\relax
\let\prior@quizSolnHeaderHook\@empty
\newcommand\quizSolnHeader[3][]{%
- \prior@quizSolnHeaderHook
- \ifeqforpaper\else\webnewpage\fi\noindent
- #2%
- \solnspace
+ \prior@quizSolnHeaderHook
+ \ifeqforpaper\else\webnewpage\fi\noindent
+ #2%
+ \solnspace
}
\newif\iftherearequizsolutions \therearequizsolutionsfalse
\let\aeb@FLOverride\relax
\def\includequizsolutions{\@ifstar
- {\let\resetQZtsolns\relax\includequizsolutionsi}
- {\def\resetQZtsolns{\global\let\include@quizsolutions\relax}%
- \includequizsolutionsi}}
+ {\let\resetQZtsolns\relax\includequizsolutionsi}
+ {\def\resetQZtsolns{\global\let\include@quizsolutions\relax}%
+ \includequizsolutionsi}}
\newcommand{\includequizsolutionsi}[1][]{%
- \filterFor{#1}\includequizsolutionsii}
+ \filterFor{#1}\includequizsolutionsii}
\def\includequizsolutionsii{\include@quizsolutions
- \resetQZtsolns
- \let\eqFilterArg\@empty}
+ \resetQZtsolns
+ \let\eqFilterArg\@empty}
\newcommand\useForms{\def\aeb@FLOverride{f}}
\newcommand\useLinks{\def\aeb@FLOverride{l}}
\newcommand\restoreFLTypeDefault{\global\let\aeb@FLOverride\relax}
@@ -1517,243 +1519,245 @@
\eq@hspanner\ignorespaces}
\let\Ans@ck@sq@l\Ans@sq@l
\let\rbf@Opts\@empty
-\def\Ans@sq@f{%
- \if\eq@listType\eq@One\stepcounter{quizno}\else
- \@ifundefined{ifwithinsoldoc}{\refstepcounter{quizno}}
- {\ifwithinsoldoc\stepcounter{quizno}\else
- \refstepcounter{quizno}\fi}\fi\PBS\raggedright
- \settowidth{\eq@tmplength}{\eq@lw@f}%
- \eq@tmpdima=\wd\eq@tmpbox%
- \hangindent=\eq@tmplength\hangafter=1\relax
- \insertGrayLetters % 6.3d
- \Ans@sq@f@driver
-\eq@hspanner\ignorespaces}
+\def\Ans@sq@f{\if\eq@listType\eq@One
+ \stepcounter{quizno}\else
+ \@ifundefined{ifwithinsoldoc}{\refstepcounter{quizno}}
+ {\ifwithinsoldoc\stepcounter{quizno}\else
+ \refstepcounter{quizno}\fi}\fi
+ \PBS\raggedright
+ \settowidth{\eq@tmplength}{\eq@lw@f}%
+ \eq@tmpdima=\wd\eq@tmpbox%
+ \hangindent=\eq@tmplength\hangafter=1\relax
+ \insertGrayLetters
+ \Ans@sq@f@driver
+ \eq@hspanner\ignorespaces}
\let\Ans@ck@sq@f\Ans@sq@f
\newskip\aboveanswersSkip
\setlength\aboveanswersSkip{3pt}
\providecommand\graylettersColor{gray}
\def\insertGrayLetters{\ifaebshowgrayletters
- \rlap{\makebox[\RadioFieldSize]%
- {\textcolor{\graylettersColor}{\Alph{quizno}}}}\else\relax\fi}
+ \rlap{\makebox[\RadioFieldSize]%
+ {\textcolor{\graylettersColor}{\Alph{quizno}}}}\else\relax\fi}
\newcount\eq@tabColCnt
\define@key{bchoice}{nCols}{\def\bChoiceNumCols{#1}}
\@for\eqi:=1,2,3,4,5,6,7,8,9,10 \do{\edef\temp@expand@def{%
- \noexpand\define@key{bchoice}{\eqi}[\eqi]{%
- \noexpand\def\noexpand\bChoiceNumCols{\eqi}}%
- }\temp@expand@def
+ \noexpand\define@key{bchoice}{\eqi}[\eqi]{%
+ \noexpand\def\noexpand\bChoiceNumCols{\eqi}}%
+ }\temp@expand@def
}
\def\bChoiceNumCols{\aeb@numCols}
\define@key{bchoice}{random}[true]{%
- \csname if#1\endcsname\eq@randomizeChoicestrue
- \else\eq@randomizeChoicesfalse\fi
+ \csname if#1\endcsname\eq@randomizeChoicestrue
+ \else\eq@randomizeChoicesfalse\fi
}
\define@key{bchoice}{label}[]{\xdef\bChoiceLabel{#1}}
\def\bChoices{\@ifnextchar[{\@ansChoices}{\@ansChoices[\aeb@numCols]}}
-\def\@ansChoices[#1]%
-{%
- \global\let\@tempholdSaveAns\@empty %4/5
- \global\let\@tempholdSaveChoice\@empty %4/5
- \global\let\bChoiceLabel\@empty %4/5
- \setkeys{bchoice}{#1}%
- \global\eq@tabColCnt=0
- \ifnum\aeb@numCols=1 % list mode
- \def\eq@next{\@layoutListAns}\else % tabular mode
- \def\eq@next{\@layoutTabularAns{\bChoiceNumCols}}\fi
- \eq@next
+\def\@ansChoices[#1]{%
+ \global\let\@tempholdSaveAns\@empty %4/5
+ \global\let\@tempholdSaveChoice\@empty %4/5
+ \global\let\bChoiceLabel\@empty %4/5
+ \setkeys{bchoice}{#1}%
+ \global\eq@tabColCnt=\z@
+ \ifnum\aeb@numCols=\@ne % list mode
+ \def\eq@next{\@layoutListAns}\else % tabular mode
+ \def\eq@next{\@layoutTabularAns{\bChoiceNumCols}}\fi
+ \eq@next
}
\let\eChoices\relax
\def\@layoutListAns{\@ifnextchar\Ans{\@getListAns}%
- {\@lookforendansChoices{\@layoutListAns}}%
+ {\@lookforendansChoices{\@layoutListAns}}%
}
\newcommand{\eq@saveAns}[2][]{%
- \let\eq@next\@@@SaveAnsGobbleAns
- \ifx\bChoiceLabel\@empty\else
- \def\eq@savedAnsOpt{#1}\def\eq@savedAnsZO{#2}%
- \if\eq@savedAnsZO1 \let\eq@next\@@@SaveAns\fi
- \fi\eq@next
+ \let\eq@next\@@@SaveAnsGobbleAns
+ \ifx\bChoiceLabel\@empty\else
+ \def\eq@savedAnsOpt{#1}\def\eq@savedAnsZO{#2}%
+ \if\eq@savedAnsZO1\let\eq@next\@@@SaveAns\fi
+ \fi\eq@next
}
\long\def\@@@SaveAns#1\eAns{% 4/5
- \g@addto@macro\@tempholdSaveAns{\\{\ignorespaces#1}}%
- \addtocounter{quizno}{1}%
- \edef\temp@expand{\noexpand\g@addto@macro\noexpand
+ \g@addto@macro\@tempholdSaveAns{\\{\ignorespaces#1}}%
+ \addtocounter{quizno}{1}%
+ \edef\temp@expand{\noexpand\g@addto@macro\noexpand
\@tempholdSaveChoice{%
- \noexpand\\{\ifx\sqstar\@empty\aebChoiceAltFmt\else
- \ifaebshowgrayletters\Alph{quizno}\else
- \linkContentFormat\fi\fi}}}\temp@expand
- \addtocounter{quizno}{-1}%
+ \noexpand\\{\ifx\sqstar\@empty\aebChoiceAltFmt\else
+ \ifaebshowgrayletters\Alph{quizno}\else
+ \linkContentFormat\fi\fi}}}\temp@expand
+ \addtocounter{quizno}{-1}%
}
\newif\ifoxfordcomma \oxfordcommatrue
\def\oxfordCommaOn{\oxfordcommatrue}
\def\oxfordCommaOff{\oxfordcommafalse}
\def\eq@insertComma{%
- \ifx\eq@comma\@empty
- \ifnum\@nameuse{NumAns\eq@namearg}>2\relax
- \def\eq@comma{,}\fi
- \else\ifx\eq@insertAnd\@empty\eq@comma\space
- \else\ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}%
- \ifoxfordcomma\eq@comma\fi\else\eq@comma\fi\space
- \fi
+ \ifx\eq@comma\@empty
+ \ifnum\@nameuse{NumAns\eq@namearg}>\tw@
+ \def\eq@comma{,}\fi
+ \else\ifx\eq@insertAnd\@empty\eq@comma\space
+ \else\ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}%
+ \ifoxfordcomma\eq@comma\fi\else\eq@comma\fi\space
\fi
+ \fi
}
\newcommand\eqAnd{and}\def\eq@insertAnd{%
- \ifnum\@nameuse{NumAns\eq@namearg}<2\relax\else
- \ifnum\@nameuse{NumAns\eq@namearg}>2\relax
- \else\leavevmode\space\fi\eqAnd\space\fi}
-\long\def\eq@displayAns#1{\advance\@tempcnta1\relax
- \eq@insertComma
- \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi#1}
+ \ifnum\@nameuse{NumAns\eq@namearg}<\tw@\else
+ \ifnum\@nameuse{NumAns\eq@namearg}>\tw@\relax
+ \else\leavevmode\space\fi\eqAnd\space\fi
+}
+\long\def\eq@displayAns#1{\advance\@tempcnta\@ne
+ \eq@insertComma
+ \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi#1}
\def\eq@displayAlts#1{\advance\@tempcnta1
- \eq@insertComma
- \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi
- \savedAltFmt{#1}}
+ \eq@insertComma
+ \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi
+ \savedAltFmt{#1}}
\def\eq@displayAltsAns#1{\advance\@tempcnta1\relax
- \eq@insertComma
- \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi#1}
+ \eq@insertComma
+ \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi#1}
\newcommand{\savedAltFmt}[1]{(#1)}
\newcommand{\useSavedAns}{\bgroup\@ifstar{\useSavedAns@i}
- {\let\eq@insertAnd\@empty\useSavedAns@i}}
+ {\let\eq@insertAnd\@empty\useSavedAns@i}}
\newcommand{\useSavedAns@i}[2][]{\@tempcnta=0\relax
- \def\eq@namearg{#2}\let\label\@gobble
- \def\eq@argi{#1}\ifx\eq@argi\@empty
- \let\eq@comma\@empty
- \let\\\eq@displayAns\@nameuse{SavedAns#2}\else
- \@nameuse{SavedAns#2-Idx#1}\fi
- \egroup
+ \def\eq@namearg{#2}\let\label\@gobble
+ \def\eq@argi{#1}\ifx\eq@argi\@empty
+ \let\eq@comma\@empty
+ \let\\\eq@displayAns\@nameuse{SavedAns#2}\else
+ \@nameuse{SavedAns#2-Idx#1}\fi
+ \egroup
}
\newcommand{\useSavedAlts}{\bgroup\@ifstar{\useSavedAlts@i}
- {\let\eq@insertAnd\@empty\useSavedAlts@i}}
+ {\let\eq@insertAnd\@empty\useSavedAlts@i}}
\newcommand{\useSavedAlts@i}[2][]{\@tempcnta=0\relax
- \def\eq@namearg{#2}\@nameuse{caseFor#2}%
- \def\eq@argi{#1}\ifx\eq@argi\@empty
- \let\eq@comma\@empty
- \let\\\eq@displayAlts\@nameuse{SavedAlts#2}\else
- \savedAltFmt{\@nameuse{SavedAlts#2-Idx#1}}\fi
- \egroup
+ \def\eq@namearg{#2}\@nameuse{caseFor#2}%
+ \def\eq@argi{#1}\ifx\eq@argi\@empty
+ \let\eq@comma\@empty
+ \let\\\eq@displayAlts\@nameuse{SavedAlts#2}\else
+ \savedAltFmt{\@nameuse{SavedAlts#2-Idx#1}}\fi
+ \egroup
}
\newcommand{\useSavedAltsAns}{\bgroup\@ifstar{\useSavedAltsAns@i}
- {\let\eq@insertAnd\@empty\useSavedAltsAns@i}}
+ {\let\eq@insertAnd\@empty\useSavedAltsAns@i}}
\newcommand{\useSavedAltsAns@i}[2][]{\@tempcnta=0\relax
- \def\eq@namearg{#2}\@nameuse{caseFor#2}\let\label\@gobble
- \def\eq@argi{#1}\ifx\eq@argi\@empty
- \let\eq@comma\@empty
- \let\\\eq@displayAltsAns\@nameuse{SavedAltsAns#2}\else
- \savedAltFmt{\@nameuse{SavedAlts#2-Idx#1}}
- \@nameuse{SavedAns#2-Idx#1}\fi
- \egroup
+ \def\eq@namearg{#2}\@nameuse{caseFor#2}\let\label\@gobble
+ \def\eq@argi{#1}\ifx\eq@argi\@empty
+ \let\eq@comma\@empty
+ \let\\\eq@displayAltsAns\@nameuse{SavedAltsAns#2}\else
+ \savedAltFmt{\@nameuse{SavedAlts#2-Idx#1}}
+ \@nameuse{SavedAns#2-Idx#1}\fi
+ \egroup
}
\newcommand{\useSavedNumAns}[1]{\@nameuse{NumAns#1}}
-\long\def\@@@SaveAnsGobbleAns#1\eAns{} % 4/5
-\long\def\@getListAns\Ans#1\eAns{%\@@par %start new paragraph
- \eq@saveAns#1\eAns % 4/5
- \Ans#1\vspace{\@rowskip}%
- \@layoutListAns
+\long\def\@@@SaveAnsGobbleAns#1\eAns{}
+\long\def\@getListAns\Ans#1\eAns{%\@@par
+ \eq@saveAns#1\eAns
+ \Ans#1\vspace{\@rowskip}%
+ \@layoutListAns
}
\long\def\@lookforendansChoices#1{%
- \@ifnextchar\eChoices{\rowsep{\rowsep@default}%
- \expandafter\@findendans\@gobble}{\expandafter#1\@gobble}%
+ \@ifnextchar\eChoices{\rowsep{\rowsep@default}%
+ \expandafter\@findendans\@gobble}{\expandafter#1\@gobble}%
}
\def\@layoutTabularAns#1{%
- \let\eq@tabSep\@empty
- \xdef\numShortCols{#1}%
- \ifnum#1>\aeb@numCols \xdef\numShortCols{\aeb@numCols}\fi
- \@@layoutTabularAns
+ \let\eq@tabSep\@empty
+ \xdef\numShortCols{#1}%
+ \ifnum#1>\aeb@numCols \xdef\numShortCols{\aeb@numCols}\fi
+ \@@layoutTabularAns
}
\def\@@layoutTabularAns{%
- \@ifnextchar\Ans{\@getTabAns}%
- {\@lookforendansChoices{\@@layoutTabularAns}}%
+ \@ifnextchar\Ans{\@getTabAns}%
+ {\@lookforendansChoices{\@@layoutTabularAns}}%
}
\def\rowsep#1{\gdef\@rowsep{[#1]}\gdef\@rowskip{#1}}%
\rowsep{\rowsep@default}
\def\rowsepDefault#1{\def\rowsep@default{#1}}
\def\rowsep@default{0pt}
\long\def\@getTabAns\Ans#1\eAns{%
- \eq@saveAns#1\eAns
- \global\advance\eq@tabColCnt1
- \let\@save@tabSep=\eq@tabSep
- \ifnum\eq@tabColCnt=\numShortCols
- \global\eq@tabColCnt=0
- \xdef\eq@tabSep{\noexpand\\\noalign{\kern\@rowskip\relax}}%
- \else
- \gdef\eq@tabSep{&}%
- \fi
- \@ifnextchar\eChoices{\@save@tabSep\Ans#1\rowsep{\rowsep@default}
- \expandafter\@findendans\@gobble}%
- {\@save@tabSep\Ans#1\@@layoutTabularAns}%
+ \eq@saveAns#1\eAns
+ \global\advance\eq@tabColCnt1
+ \let\@save@tabSep=\eq@tabSep
+ \ifnum\eq@tabColCnt=\numShortCols
+ \global\eq@tabColCnt=0
+ \xdef\eq@tabSep{\noexpand\\\noalign{\kern\@rowskip\relax}}%
+ \else
+ \gdef\eq@tabSep{&}%
+ \fi
+ \@ifnextchar\eChoices{\@save@tabSep\Ans#1\rowsep{\rowsep@default}
+ \expandafter\@findendans\@gobble}%
+ {\@save@tabSep\Ans#1\@@layoutTabularAns}%
}
-\def\@findendans{\@ifnextchar\end{% 4/5
- \ifx\bChoiceLabel\@empty\else
- \processLabeledAns\fi
- }{\expandafter\@findendans\@gobble}}%
+\def\@findendans{\@ifnextchar\end{%
+ \ifx\bChoiceLabel\@empty\else
+ \processLabeledAns\fi
+ }{\expandafter\@findendans\@gobble}}%
\def\defineEachAns#1{\advance\eqtmpcnta\@ne
- \@temptokena={#1}\csarg\xdef
- {SavedAns\bChoiceLabel-Idx\the\eqtmpcnta}{\the\@temptokena}%
- \ifsolutionsonly\else
- {\let\\\relax\eq@IWDefs{\string
- \csarg\string\gdef{SavedAns\bChoiceLabel-Idx\the\eqtmpcnta}%
- {\the\@temptokena}}}\fi
+ \@temptokena={#1}\csarg\xdef
+ {SavedAns\bChoiceLabel-Idx\the\eqtmpcnta}{\the\@temptokena}%
+ \ifsolutionsonly\else
+ {\let\\\relax\eq@IWDefs{\string
+ \csarg\string\gdef{SavedAns\bChoiceLabel-Idx\the\eqtmpcnta}%
+ {\the\@temptokena}}}%
+ \fi
}
\def\defineEachChoice#1{\advance\eqtmpcnta\@ne
- \@temptokena={#1}\csarg\xdef
- {SavedAlts\bChoiceLabel-Idx\the\eqtmpcnta}%
- {\the\@temptokena}\ifsolutionsonly\else
- {\let\\\relax\eq@IWDefs{\string
- \csarg\string
- \gdef{SavedAlts\bChoiceLabel-Idx\the\eqtmpcnta}%
- {\the\@temptokena}}}\fi
+ \@temptokena={#1}\csarg\xdef
+ {SavedAlts\bChoiceLabel-Idx\the\eqtmpcnta}%
+ {\the\@temptokena}\ifsolutionsonly\else
+ {\let\\\relax\eq@IWDefs{\string
+ \csarg\string
+ \gdef{SavedAlts\bChoiceLabel-Idx\the\eqtmpcnta}%
+ {\the\@temptokena}}}\fi
}
\def\processLabeledAns{%
- \bgroup
- \let\label\@gobble
-\if\aeb@FLOverride\eq@l
- \global\@namedef{caseFor\bChoiceLabel}{\graylettersOff}\else
- \ifaebshowgrayletters
+ \bgroup
+ \let\label\@gobble
+ \if\aeb@FLOverride\eq@l
+ \global\@namedef{caseFor\bChoiceLabel}{\graylettersOff}\else
+ \ifaebshowgrayletters
\global\@namedef{caseFor\bChoiceLabel}{\graylettersOn}\else
\global\@namedef{caseFor\bChoiceLabel}{\graylettersOff}\fi
-\fi
- \toks@=\expandafter{\@tempholdSaveAns}\csarg
- \xdef{SavedAns\bChoiceLabel}{\the\toks@}%
- \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string
- \csarg\string\gdef{SavedAns\bChoiceLabel}{\the\toks@}}}\fi
- \eqtmpcnta\z@\let\\\defineEachAns\the\toks@
- \xdef\@currNCntAns{\the\eqtmpcnta}\csarg
- \xdef{NumAns\bChoiceLabel}{\@currNCntAns}%
- \ifsolutionsonly\else{\eq@IWDefs{\string
- \csarg\string\gdef{NumAns\bChoiceLabel}{\the\eqtmpcnta}}}\fi
- \toks@=\expandafter{\@tempholdSaveChoice}\csarg
- \xdef{SavedAlts\bChoiceLabel}{\the\toks@}%
- \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string
- \csarg\string\gdef{SavedAlts\bChoiceLabel}{\the\toks@}}}\fi
- \eqtmpcnta\z@\relax\let\\\defineEachChoice\the\toks@
- \eqtmpcnta\@ne\toks@={}%{\ignorespaces\@gobble}%
- \loop
- \edef\temp@exp{\the\toks@\noexpand\\{%
- \noexpand\useSavedAlts[\the\eqtmpcnta]{\bChoiceLabel}
- \noexpand\useSavedAns[\the\eqtmpcnta]{\bChoiceLabel}}}%
- \toks@=\expandafter{\temp@exp}%
- \ifnum\eqtmpcnta<\@currNCntAns\relax
- \advance\eqtmpcnta\@ne
- \repeat
- \csarg\xdef{SavedAltsAns\bChoiceLabel}{\the\toks@}%
- \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string
- \csarg\string\gdef{SavedAltsAns\bChoiceLabel}{\the\toks@}}}\fi
- \egroup
+ \fi
+ \toks@=\expandafter{\@tempholdSaveAns}\csarg
+ \xdef{SavedAns\bChoiceLabel}{\the\toks@}%
+ \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string
+ \csarg\string\gdef{SavedAns\bChoiceLabel}{\the\toks@}}}\fi
+ \eqtmpcnta\z@\let\\\defineEachAns\the\toks@
+ \xdef\@currNCntAns{\the\eqtmpcnta}\csarg
+ \xdef{NumAns\bChoiceLabel}{\@currNCntAns}%
+ \ifsolutionsonly\else{\eq@IWDefs{\string
+ \csarg\string\gdef{NumAns\bChoiceLabel}{\the\eqtmpcnta}}}\fi
+ \toks@=\expandafter{\@tempholdSaveChoice}\csarg
+ \xdef{SavedAlts\bChoiceLabel}{\the\toks@}%
+ \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string
+ \csarg\string\gdef{SavedAlts\bChoiceLabel}{\the\toks@}}}\fi
+ \eqtmpcnta\z@\relax\let\\\defineEachChoice\the\toks@
+ \eqtmpcnta\@ne\toks@={}%{\ignorespaces\@gobble}%
+ \loop
+ \edef\temp@exp{\the\toks@\noexpand\\{%
+ \noexpand\useSavedAlts[\the\eqtmpcnta]{\bChoiceLabel}
+ \noexpand\useSavedAns[\the\eqtmpcnta]{\bChoiceLabel}}}%
+ \toks@=\expandafter{\temp@exp}%
+ \ifnum\eqtmpcnta<\@currNCntAns\relax
+ \advance\eqtmpcnta\@ne
+ \repeat
+ \csarg\xdef{SavedAltsAns\bChoiceLabel}{\the\toks@}%
+ \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string
+ \csarg\string\gdef{SavedAltsAns\bChoiceLabel}{\the\toks@}}}\fi
+ \egroup
}
\def\graylettersOn{\aebshowgrayletterstrue}
\def\graylettersOff{\aebshowgraylettersfalse}
\def\aeb@exiii{\expandafter\expandafter\expandafter}
\def\REF{\@ifstar{\let\isREFstar\eq@One\aeb@REFstar}
- {\let\isREFstar\eq@Zero\aeb@REF}}
+ {\let\isREFstar\eq@Zero\aeb@REF}}
\def\aeb@REFstar#1{\@ifundefined{r@#1}{\hbox{\reset@font\bfseries ??}}
- {\ifaebshowgrayletters\aeb@buildUpperCaseRef{#1}%
- \else\ref*{#1}\fi}%
+ {\ifaebshowgrayletters\aeb@buildUpperCaseRef{#1}%
+ \else\ref*{#1}\fi}%
}
\def\aeb@REF#1{\@ifundefined{r@#1}{\hbox{\reset@font\bfseries ??}}
- {\ifaebshowgrayletters\aeb@buildUpperCaseRef{#1}%
- \else\ref{#1}\fi}%
+ {\ifaebshowgrayletters\aeb@buildUpperCaseRef{#1}%
+ \else\ref{#1}\fi}%
}
\def\aeb@buildUpperCaseRef#1{%
- \xdef\tmp@expand{\aeb@exiii\@firstoftwo\csname r@#1\endcsname}%
- \xdef\tmp@expand{\uppercase{\tmp@expand}}\tmp@expand
+ \xdef\tmp@expand{\aeb@exiii\@firstoftwo\csname r@#1\endcsname}%
+ \xdef\tmp@expand{\uppercase{\tmp@expand}}\tmp@expand
}
\endinput
%%
diff --git a/macros/latex/contrib/eqexam/eqexam.dtx b/macros/latex/contrib/eqexam/eqexam.dtx
index d27fe47511..b9cc28503f 100644
--- a/macros/latex/contrib/eqexam/eqexam.dtx
+++ b/macros/latex/contrib/eqexam/eqexam.dtx
@@ -4,7 +4,7 @@
%<*copyright>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% eqexam.sty package, %%
-%% Copyright (C) 2005--2020 D. P. Story %%
+%% Copyright (C) 2005--2021 D. P. Story %%
%% dpstory@uakron.edu %%
%% %%
%% This program can redistributed and/or modified under %%
@@ -16,8 +16,8 @@
%</copyright>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{eqexam}
-%<package> [2020/03/14 v5.1.10 An Exam Construction Package (dps)]
-%<package>\def\eqexamdefReq{2020/03/14}
+%<package> [2021/01/20 v5.1.13 An Exam Construction Package (dps)]
+%<package>\def\eqexamdefReq{2021/01/20}
%<*driver>
\documentclass{ltxdoc}
\GlossaryPrologue{\section{{Change History}}}%
@@ -26,7 +26,7 @@
\value{GlossaryColumns}=2
\usepackage{makeidx}
\usepackage[colorlinks,hyperindex=false]{hyperref}
-\def\darg#1{\texttt{\{#1\}}}
+\gdef\darg#1{\texttt{\char123\relax#1\char125\relax}}
\let\env\texttt
\let\opt\texttt
\let\app\textsf
@@ -2291,8 +2291,8 @@
% \end{macrocode}
% \DescribeMacro{\optsMlTxtFld} is used to pass options to the multi-line
% text field.
-% \changes{v5.1.10}{2020/03/14}{Introduced control over width of text field in
-% for \string\texttt{online} option.}
+% \changes{v5.1.10}{2020/03/14}{ \string\cs{optsMsTxtFld}: Pass options to the multi-line
+% text field. in for \string\texttt{online} option.}
% \begin{macrocode}
\def\optsMlTxtFld#1{\def\eqe@optsmltf{#1}}
\let\eqe@optsmltf\@empty
@@ -4215,6 +4215,7 @@
% \end{macrocode}
% Since everything is put a box, we set the \cs{linewidth}, and
% set \cs{solutionparshape} to \cs{@empty}.
+% \changes{v5.1.11}{2020/11/16}{Adj \string\cs{linewidth} in soln file}
% \begin{macrocode}
\ifx\solutionparshape\@empty\else
\advance\linewidth-\leadinIndentPrtSep\fi %%dps
@@ -4224,8 +4225,10 @@
{\vfill}\hfill\fi
\minipage[b][\eqedepth][t]{\mp@Width}%
{\lccode`C=`\%\lowercase{\eqe@IW{%
- \string\def\string\panelgap{\panelgap}%
- \string\setlength{\string\panelwidth}{\ss@Argiii}%
+ \string\def\string\panelgap{\panelgap}C^^J%
+ \string\setlength{\string\panelwidth}{\ss@Argiii}C^^J%
+ \string\setlength{\string\linewidth}{\string
+ \linewidth-\string\eqemargin}C^^J%
\string\def\string\eqedepth
{\ifeq@nosolutions\ss@Argii\else\ss@Argii\fi}C}}}%
% \end{macrocode}
@@ -5082,6 +5085,37 @@
\def\hidden@ttr{[#1]}\let\numpoints\@empty\else
\let\hidden@ttr\relax\def\numpoints{#1}\fi
\problem@cont}
+% \end{macrocode}
+% \DescribeMacro\probV@luesInsert This command writes the number of points to the AUX
+% file; form of the macro name written is \texttt{value\ameta{exam-label}Prob\ameta{prob-no}}.
+% \changes{v5.1.12}{2021/01/07}{Added \string\cs{probV@luesInsert} to support \string\pkg{skills} package}
+% \begin{macrocode}
+\let\probV@luesInsert\relax
+\def\probV@@luesInsert{\bgroup\@tempcnta\value{eqquestionnoi}\advance
+ \@tempcnta\@ne % Jan21
+ \eqe@IWO\@auxout{\string\csarg\string
+ \gdef{value\thisexamlabel Prob\the\@tempcnta}{\numpoints}}\egroup
+}
+% \end{macrocode}
+% \DescribeMacro\trackProblemsOn This command (\cs{trackProblemsOn}) activates problem tracking (ie, write problems and values
+% to the AUX file; \DescribeMacro\trackProblemsOff\cs{trackProblemsOff} turns off tracking. Tracking is
+% off by default. When tracing is on, the value of each problem is saved in the form
+% |\csarg\gdef{value|\ameta{exam-label}\texttt{Prob}\ameta{prob-num}|}|. This feature was developed to support
+% the \pkg{skills} package.
+% \changes{v5.1.12}{2021/01/07}{Added \string\cs{trackProblemsOn} and \string\cs{trackProblemsOff} to support \string\pkg{skills} package}
+% \begin{macrocode}
+\def\trackProblemsOn{\let\probV@luesInsert\probV@@luesInsert}
+\def\trackProblemsOff{\let\probV@luesInsert\relax}
+\trackProblemsOff
+% \end{macrocode}
+% \DescribeMacro\numPtsOfProblem\hskip-\marginparsep\texttt{[\ameta{exam-label}]\darg{\ameta{prob-num}}}
+% The command \cs{numPtsOfProblem} typesets the number of points of problem \ameta{prob-num} from part \ameta{label-name}.
+% \begin{macrocode}
+\newcommand{\numPtsOfProblem}[2][\thisexamlabel]%
+ {\@nameuse{value#1Prob#2}}
+% \end{macrocode}
+% The \env{problem} environment continues.
+% \begin{macrocode}
\newcommand{\problem@cont}[1][]{\let\isProbEnv\eqe@YES
\def\@rgi{#1}\ifx\hidden@ttr\relax % assume a number or empty
\ifx\@rgi\@empty\else\def\hidden@ttr{[#1]}\fi\fi
@@ -5107,6 +5141,7 @@
\def\@ltii{\let\@isitstar\eqe@Zero\eqe@gobbletoend}%
\expandafter\@ifstar\expandafter\@lti
\expandafter\@ltii\numpoints\end
+ \probV@luesInsert % Jan21
\if\@isitstar\eqe@One\addtocounter{eqpointvalue}{\numpoints}%
\@marktotalvalue
\ifdispl@yPoints
@@ -5137,7 +5172,8 @@
% \begin{macrocode}
\edef\ctrld@exp@exercise{\noexpand
\begin{exercise}[eqquestionnoi]\hidden@ttr}%
- \ctrld@exp@exercise\ignorespaces\eqe@p@gobnxtp@r}
+ \ctrld@exp@exercise\ignorespaces\eqe@p@gobnxtp@r
+}
% \end{macrocode}
% \textbf{end problem env.} The code for the end of the problem environment.
% \begin{macrocode}
@@ -5719,6 +5755,7 @@
% \begin{macrocode}
\let\marginpoints\@empty
\else
+ \probV@luesInsert % Jan21
% \end{macrocode}
% Points are displayed in margins or inline
% \begin{macrocode}
@@ -5727,6 +5764,7 @@
% \paragraph*{Total points specified}
% \begin{macrocode}
\ifx\marginpoints\@empty\else
+ \probV@luesInsert % Jan21
\if\@isitstar\eqe@One
% \end{macrocode}
% Points to appear ``in-line'' rather than in the margins
@@ -5797,6 +5835,7 @@
\fi
% \addtocounter{eqpointvalue}{\numpoints}\@marktotalvalue
\ifx\marginpoints\@empty\else
+ \probV@luesInsert % Jan21
\ifdispl@yPoints
\if\@isitstar\eqe@One
% \end{macrocode}
@@ -7242,6 +7281,7 @@
%The \cs{eqTWSave} is the saved value of the \cs{textwidth} in effect when
%the \env{exam} environment is opened. The right totals box is placed in the right
%margin based on this value.
+%\changes{v5.1.10}{2020/03/14}{Define \string\cs{probInMinipage}}
% \begin{macrocode}
\def\probInMinipage{%
\ifanswerkey
@@ -7269,11 +7309,11 @@
% the total height of the typeset solution. It then calculates the difference between
% \cs{sameVspace}, which should hold the value of the optional argument of \env{solution},
% and the actual height of the solution. It then executes a \cs{vspace} for that amount calculated.
-%
+% \changes{v5.1.10}{2020/03/14}{Add \string\env{vadjForSolnInBx} to correct for vertical space for a
+% problem in a \string\env{minipage}}
% \begin{macrocode}
\newenvironment{vadjForSolnInBx}[1]{%
- \setlength\@tempdima{#1}%
- \setbox\z@\vbox\bgroup\hsize\@tempdima
+ \setlength\@tempdima{#1}\setbox\z@\vbox\bgroup\hsize\@tempdima
}{%
\egroup
\ifanswerkey
@@ -7296,6 +7336,7 @@
% use \cs{bProbInsert} with its argument. Place \DescribeMacro{\eProbInsert}\cs{eProbInsert} at the end of the statement of the
% question, as illustrated below. \cs{bProbInsert} puts the question into a group,
% \cs{eProbInsert} gets us out of the group.
+% \changes{v5.1.10}{2020/03/14}{Define \string\cs{bProbInsert} and \string\cs{bItemInsert}}
%\begin{verbatim}
%\def\insertFig{\parpic[r]{\FIG}}
%\bProbInsert{\insertFig}
diff --git a/macros/latex/contrib/eqexam/examples/fig1.pdf b/macros/latex/contrib/eqexam/examples/fig1.pdf
index 054fe38f56..134d03dfde 100644
--- a/macros/latex/contrib/eqexam/examples/fig1.pdf
+++ b/macros/latex/contrib/eqexam/examples/fig1.pdf
Binary files differ
diff --git a/macros/latex/contrib/eqexam/examples/hw.cfg.txt b/macros/latex/contrib/eqexam/examples/hw.cfg.txt
deleted file mode 100644
index 57511627ea..0000000000
--- a/macros/latex/contrib/eqexam/examples/hw.cfg.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-\renewcommand\maketitledesign
-{%
- \makebox[\textwidth]{\normalsize
- \shortstack[l]{\strut\underbar{\websubject}\\\@date}\hfill
- \shortstack[l]{\underbar{\webtitle}\\\strut}\hfill
- \shortstack[l]{\strut\underbar{Due \theduedate}\\\webauthor}}%
-}
-\rhead{\webauthor}
-\def\exrtnlabelformat{$\square$}
-\def\exrtnlabelformatwp{}
-\def\eq@sqslrtnlabel{}
-\everymath{\displaystyle}
diff --git a/macros/latex/contrib/eqexam/examples/quiz.cfg.txt b/macros/latex/contrib/eqexam/examples/quiz.cfg.txt
deleted file mode 100644
index bc9a15aed6..0000000000
--- a/macros/latex/contrib/eqexam/examples/quiz.cfg.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-\renewcommand\maketitledesign
-{%
- \makebox[\textwidth]{\normalsize
- \shortstack[l]{\strut\websubject\\\webauthor, \@date}\hfill
- \shortstack[l]{\webtitle\\\strut}\hfill
- \shortstack[l]{\strut\eq@ExamName\\\eq@SID}}%
-}
diff --git a/macros/latex/contrib/eqexam/examples/test01.pdf b/macros/latex/contrib/eqexam/examples/test01.pdf
new file mode 100644
index 0000000000..92b9d6c52b
--- /dev/null
+++ b/macros/latex/contrib/eqexam/examples/test01.pdf
Binary files differ
diff --git a/macros/latex/contrib/eqexam/examples/test01.tex b/macros/latex/contrib/eqexam/examples/test01.tex
index 102b7b61e0..a52cfafbf1 100644
--- a/macros/latex/contrib/eqexam/examples/test01.tex
+++ b/macros/latex/contrib/eqexam/examples/test01.tex
@@ -28,7 +28,7 @@
\turnContAnnotOn
\optsFillIn{\BC{0.847 0.847 0.847}}
-\optsMlTextField{\BC{0.847 0.847 0.847}}
+\optsMlTxtFld{\BC{0.847 0.847 0.847}}
\eqExamName[\Ff\FfRequired\BC{0.847 0.847 0.847}]{2.25in}
\eqSID[\Ff\FfRequired\BC{0.847 0.847 0.847}]{2.25in}
\cpSetSumryWidth{.55\textwidth-1em}
@@ -45,7 +45,7 @@
\begin{instructions}[Part I.]
Solve each of the problems without error. If you make an error,
-points will be subtracted from your total score.
+points will be subtracted from your total score.
\end{instructions}
\begin{problem}[5]
diff --git a/macros/latex/contrib/eqexam/examples/test02.pdf b/macros/latex/contrib/eqexam/examples/test02.pdf
new file mode 100644
index 0000000000..2a4c84b5d8
--- /dev/null
+++ b/macros/latex/contrib/eqexam/examples/test02.pdf
Binary files differ
diff --git a/macros/latex/contrib/eqexam/examples/test03.pdf b/macros/latex/contrib/eqexam/examples/test03.pdf
new file mode 100644
index 0000000000..58998f261c
--- /dev/null
+++ b/macros/latex/contrib/eqexam/examples/test03.pdf
Binary files differ
diff --git a/macros/latex/contrib/eqexam/examples/test_matching.pdf b/macros/latex/contrib/eqexam/examples/test_matching.pdf
deleted file mode 100644
index 56eff4053c..0000000000
--- a/macros/latex/contrib/eqexam/examples/test_matching.pdf
+++ /dev/null
Binary files differ
diff --git a/macros/latex/contrib/fnpct/README b/macros/latex/contrib/fnpct/README
index 5a230d16e4..c9c58a4381 100644
--- a/macros/latex/contrib/fnpct/README
+++ b/macros/latex/contrib/fnpct/README
@@ -1,23 +1,22 @@
--------------------------------------------------------------------------
-the FNPCT package v0.5
+the FNPCT package v1.0 2021/01/21
footnote kerning
-2019/10/05
--------------------------------------------------------------------------
Clemens Niederberger
-Web: https://bitbucket.org/cgnieder/fnpct/
+Web: https://github.com/cgnieder/fnpct/
E-Mail: contact@mychemistry.eu
--------------------------------------------------------------------------
-Copyright 2012--2019 Clemens Niederberger
+Copyright 2012--2021 Clemens Niederberger
This work may be distributed and/or modified under the
-conditions of the LaTeX Project Public License, either version 1.3
+conditions of the LaTeX Project Public License, either version 1.3c
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.
+and version 1.3c or later is part of all distributions of LaTeX
+version 2008/05/04 or later.
This work has the LPPL maintenance status `maintained'.
diff --git a/macros/latex/contrib/fnpct/fnpct-manual.cls b/macros/latex/contrib/fnpct/fnpct-manual.cls
new file mode 100644
index 0000000000..0abdf7e405
--- /dev/null
+++ b/macros/latex/contrib/fnpct/fnpct-manual.cls
@@ -0,0 +1,331 @@
+% --------------------------------------------------------------------------
+% the FNPCT package
+%
+% footnote kerning
+%
+% --------------------------------------------------------------------------
+% Clemens Niederberger
+% Web: https://github.com/cgnieder/fnpct/
+% E-Mail: contact@mychemistry.eu
+% --------------------------------------------------------------------------
+% Copyright 2012--2021 Clemens Niederberger
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% 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.3c or later is part of all distributions of LaTeX
+% version 2008/05/04 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Clemens Niederberger.
+% --------------------------------------------------------------------------
+\RequirePackage[multiple]{fnpct}
+\ProvidesClass{fnpct-manual}[2021/01/17]
+
+\LoadClass[load-preamble,add-index]{cnltx-doc}
+\RequirePackage{imakeidx}
+
+\setcnltx{
+ package = {fnpct} ,
+ info = {Footnote kerning and multiple footnotes} ,
+ authors = Clemens Niederberger ,
+ email = contact@mychemistry.eu ,
+ url = https://github.com/cgnieder/fnpct/ ,
+ abstract = {%
+ The \fnpct\ package basically does two things to footnotes: if footnote
+ marks are followed by a punctuation mark the order of footnote and
+ punctuation mark is reversed and the kerning gets adjusted. As a side
+ effect mutiple footnotes and footnote ranges are easily obtained..%
+ },
+ add-cmds = {
+ AdaptNote,
+ AdaptNoteName,
+ AddPunctuation,
+ % kfc,
+ % kfp,
+ multfootnote,
+ MultVariant,
+ setfnpct
+ } ,
+ add-silent-cmds = {
+ @mpfn,
+ anote,
+ anotecontent,
+ arabic,
+ DeclareNewFootnote,
+ endnote,
+ footcite
+ footnoteB,
+ footref,
+ IfBooleanTF,
+ IfNoValueTF,
+ multendnote,
+ multfootcite,
+ multparnote,
+ multsidenote,
+ myfn,
+ newfootnotes,
+ parnote,
+ parnotes,
+ sidenote,
+ theendnotes,
+ thempfootnote
+ } ,
+ makeindex-setup = {options={-s cnltx.ist},columns=3,columnsep=1em} ,
+ index-setup = {othercode=\footnotesize,level=\addsec}
+}
+
+\RequirePackage{array,booktabs}
+
+\RequirePackage{endnotes}
+\RequirePackage{parnotes}
+\RequirePackage{sepfootnotes}
+
+\newfootnotes{a}
+
+\renewcommand\thempfootnote{\arabic{mpfootnote}}
+
+\DeclareTranslation{english}{cnltx-default}{Initial}
+
+\protected\def\@versionstar{\raisebox{-.25em}{*}}
+\newcommand\versionstar{\texorpdfstring{\@versionstar}{*}}
+
+\newcommand*\TF{\textcolor{red}{\uline{\code{\textcolor{cs}{\textit{TF}}}}}}
+
+\RequirePackage{fontawesome}
+\RequirePackage{datetime2}
+\DTMsetup{useregional=numeric,datesep=/}
+\newrobustcmd*\fnpct@add@version[2]{%
+ \csdef{ac@ver@#2}{%
+ \DTMdate{#1}%
+ \csgdef{ac@ver@#2used}{}%
+ \csdef{ac@ver@#2}{\DTMdate{#1}}%
+ }%
+}
+
+\newrobustcmd*\ac@date[1]{\ifcsdef{ac@ver@#1used}{}{ (\csuse{ac@ver@#1})}}
+\newrobustcmd*\ac@ifnew[1]{\ifcsstring{c_fnpct_version_tl}{#1}}
+\newrobustcmd*\ac@NEW{\faStarO\ New}
+
+\renewrobustcmd*\sinceversion[1]{%
+ \ac@ifnew{#1}%
+ {\cnltx@version@note{\textcolor{red}{\ac@NEW}}}%
+ {\cnltx@version@note{\GetTranslation{cnltx-introduced}~v#1\ac@date{#1}}}%
+}
+\renewrobustcmd*\changedversion[1]{%
+ \cnltx@version@note{\GetTranslation{cnltx-changed}~v#1\ac@date{#1}}%
+}
+
+\newnote*\sincechanged[2]{%
+ \GetTranslation{cnltx-introduced}~#1\ac@date{#1},
+ changed with ~v#2\ac@date{#2}\ac@ifnew{#2}{ \ac@NEW}{}%
+}
+
+\RenewDocumentEnvironment{commands}{}
+ {%
+ \cnltx@set@catcode_{12}%
+ \let\command\cnltx@command
+ \cnltxlist
+ }
+ {\endcnltxlist}
+
+\RequirePackage{tcolorbox,xsimverb}
+\tcbuselibrary{skins,breakable}
+\tcbset{enhanced,enhanced jigsaw}
+
+\newtcolorbox{bewareofthedog}{
+ colback = red!2!white!98 ,
+ colframe = red ,
+ underlay={%
+ \path[draw=none]
+ (interior.south west)
+ rectangle node[red]{\Huge\bfseries !}
+ ([xshift=-4mm]interior.north west);
+ }%
+}
+
+\newtcolorbox{cnltxcode}[1][]{
+ boxrule = 1pt ,
+ colback = cnltxbg ,
+ colframe = cnltx ,
+ arc = 5pt ,
+ beforeafter skip = .5\baselineskip ,%
+ #1%
+}
+
+\newcommand*\fnpctman@readoptions[1]{%
+ \catcode`\^^M=13
+ \fnpctman@read@options{#1}%
+}
+
+\begingroup
+\catcode`\^^M=13
+\gdef\fnpctman@read@options#1#2^^M{%
+ \endgroup
+ \ifblank{#2}{}{\fnpctman@read@options@#2}%
+ #1%
+ \XSIMfilewritestart*{\jobname.tmp}%
+}%
+\endgroup
+\def\fnpctman@read@options@[#1]{\pgfqkeys{/cnltx}{#1}}
+
+\RenewDocumentEnvironment{sourcecode}{}
+ {%
+ \begingroup
+ \fnpctman@readoptions{%
+ \setlength\cnltx@sidebysidewidth
+ {\dimexpr .45\columnwidth -\lst@xleftmargin -\lst@xrightmargin\relax}%
+ \expanded{%
+ \noexpand\lstset{
+ style=cnltx,
+ \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} }
+ {linewidth=\cnltx@sidebysidewidth,}{}%
+ \expandonce\cnltx@local@listings@options
+ }%
+ }%
+ \XSIMgobblechars{2}%
+ }%
+ }
+ {%
+ \XSIMfilewritestop
+ \cnltxcode[breakable]%
+ \lstinputlisting[style=cnltx]{\jobname.tmp}%
+ \endcnltxcode
+ }
+
+\RenewDocumentEnvironment{example}{}
+ {%
+ \begingroup
+ \fnpctman@readoptions{%
+ \setlength\cnltx@sidebysidewidth
+ {\dimexpr .45\columnwidth -\lst@xleftmargin -\lst@xrightmargin\relax}%
+ \expanded{%
+ \noexpand\lstset{
+ style=cnltx,
+ \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} }
+ {linewidth=\cnltx@sidebysidewidth,}{}%
+ \expandonce\cnltx@local@listings@options
+ }%
+ }%
+ \XSIMgobblechars{2}%
+ }%
+ }
+ {%
+ \XSIMfilewritestop
+ \ifbool{cnltx@sidebyside}
+ {%
+ \cnltxcode
+ \noindent
+ \minipage[c]{\cnltx@sidebysidewidth}%
+ \cnltx@pre@source@hook
+ \lstinputlisting[style=cnltx] {\jobname.tmp}%
+ \cnltx@after@source@hook
+ \endminipage\hfill
+ \minipage[c]{\cnltx@sidebysidewidth}%
+ \cnltx@pre@example@hook
+ \input {\jobname.tmp}%
+ \cnltx@after@example@hook
+ \endminipage
+ }
+ {%
+ \cnltxcode[breakable]%
+ \cnltx@pre@source@hook
+ \lstinputlisting{\jobname.tmp}%
+ \cnltx@after@source@hook
+ \ifbool{cnltx@float}{}{%
+ \tcblower
+ \cnltx@pre@example@hook
+ \input {\jobname.tmp}%
+ \cnltx@after@example@hook
+ }
+ }%
+ \endcnltxcode
+ \ifbool{cnltx@float}{%
+ \cnltx@float@start
+ \ifdefvoid\cnltx@float@caption{}{\caption{\cnltx@float@caption}}%
+ \expandafter\end\expandafter{\cnltx@float@type}%
+ }{}%
+ }
+
+\RequirePackage[
+ backend=biber,
+ style=cnltx,
+ sortlocale=en_US,
+ indexing=cite]{biblatex}
+\RequirePackage{csquotes,varioref}
+
+\defbibheading{bibliography}[\bibname]{\addsec{#1}}
+
+\RequirePackage[biblatex]{embrac}[2012/06/29]
+\ChangeEmph{[}[,.02em]{]}[.055em,-.08em]
+\ChangeEmph{(}[-.01em,.04em]{)}[.04em,-.05em]
+
+\NewDocumentCommand\noranges{sm}{%
+ \begin{bewareofthedog}
+ \IfBooleanTF{#1}{\pkg*}{\pkg}{#2} cannot be used together with
+ \keyis{ranges}{true}.
+ \end{bewareofthedog}
+}
+
+\RequirePackage{hyperref}
+
+% additional packages:
+\RequirePackage{longtable,array,booktabs,enumitem,amssymb}
+
+% ----------------------------------------------------------------------------
+\newrobustcmd*\pdfdisable[2]{%
+ \csdef{fnpct@@\cnltx@stripbs#1}##1{#2}%
+ \def#1##1{%
+ \csuse{fnpct_if_star_gobble:nTF}{##1}%
+ {\csuse{fnpct@@\cnltx@stripbs#1}}%
+ {\csuse{fnpct@@\cnltx@stripbs#1}{##1}}%
+ }%
+}
+
+\pdfstringdefDisableCommands{%
+ \pdfdisable\template{#1}%
+ \pdfdisable\property{#1}
+ \pdfdisable\cs{\string\\#1}%
+ \pdfdisable\cmd{\string\\#1}%
+ \pdfdisable\option{#1}%
+ \def\oarg#1{[<#1>]}%
+ \def\Oarg#1{[#1]}%
+ \def\marg#1{\{<#1>\}}%
+ \def\Marg#1{\{#1\}}%
+ \def\fnpct{fnpct}%
+ \def\LaTeX{LaTeX}%
+ \def\TeX{TeX}%
+}
+% ----------------------------------------------------------------------------
+\fnpct@add@version{2012-05-22}{0.1}
+\fnpct@add@version{2012-05-23}{0.1a}
+\fnpct@add@version{2012-05-26}{0.2}
+\fnpct@add@version{2012-06-01}{0.2a}
+\fnpct@add@version{2012-06-07}{0.2b}
+\fnpct@add@version{2012-06-28}{0.2c}
+\fnpct@add@version{2012-07-07}{0.2d}
+\fnpct@add@version{2012-07-24}{0.2e}
+\fnpct@add@version{2012-08-27}{0.2f}
+\fnpct@add@version{2012-11-14}{0.2g}
+\fnpct@add@version{2013-01-18}{0.2h}
+\fnpct@add@version{2013-01-21}{0.2i}
+\fnpct@add@version{2013-02-22}{0.2j}
+\fnpct@add@version{2013-04-07}{0.2k}
+\fnpct@add@version{2013-04-16}{0.3}
+\fnpct@add@version{2013-06-14}{0.3a}
+\fnpct@add@version{2013-12-22}{0.4}
+\fnpct@add@version{2013-12-23}{0.4a}
+\fnpct@add@version{2014-03-10}{0.4b}
+\fnpct@add@version{2015-02-20}{0.4c}
+\fnpct@add@version{2015-04-23}{0.4d}
+\fnpct@add@version{2016-03-25}{0.4e}
+\fnpct@add@version{2019-02-17}{0.4f}
+\fnpct@add@version{2019-09-30}{0.4g}
+\fnpct@add@version{2019-10-05}{0.5}
+\fnpct@add@version{2020-01-12}{0.5a}
+\fnpct@add@version{2021-01-21}{1.0}
+
+\endinput
diff --git a/macros/latex/contrib/fnpct/fnpct-manual.pdf b/macros/latex/contrib/fnpct/fnpct-manual.pdf
new file mode 100644
index 0000000000..dc85988bb4
--- /dev/null
+++ b/macros/latex/contrib/fnpct/fnpct-manual.pdf
Binary files differ
diff --git a/macros/latex/contrib/fnpct/fnpct-manual.tex b/macros/latex/contrib/fnpct/fnpct-manual.tex
new file mode 100644
index 0000000000..2dbc17dcdb
--- /dev/null
+++ b/macros/latex/contrib/fnpct/fnpct-manual.tex
@@ -0,0 +1,615 @@
+% arara: pdflatex: { shell: on , interaction: nonstopmode }
+% !arara: biber
+% !arara: pdflatex
+% !arara: pdflatex
+% --------------------------------------------------------------------------
+% the FNPCT package
+%
+% footnote kerning
+%
+% --------------------------------------------------------------------------
+% Clemens Niederberger
+% Web: https://github.com/cgnieder/fnpct/
+% E-Mail: contact@mychemistry.eu
+% --------------------------------------------------------------------------
+% Copyright 2012--2021 Clemens Niederberger
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% 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.3c or later is part of all distributions of LaTeX
+% version 2008/05/04 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Clemens Niederberger.
+% --------------------------------------------------------------------------
+\documentclass{fnpct-manual}
+
+\setfnpct{
+ add-trailing-token = [0pt]:[-.05em]{colon} ,
+ after-comma-space = -0.1em ,
+ after-dot-space = -0.1em ,
+ before-comma-space = -0.05em ,
+ before-dot-space = -0.05em ,
+ before-footnote-space = 0.05em
+}
+
+\addbibresource{cnltx.bib}
+\addbibresource{\jobname.bib}
+\addbibresource{biblatex-examples.bib}
+\begin{filecontents*}{\jobname.bib}
+@book{bringhurst04,
+ title = {The Elements of Typographic Style},
+ author = {Robert Bringhurst},
+ year = {2004},
+ version = {3.2},
+ isbn = {978-0-88179-205-5},
+ publisher = {Hartley \&\ Marks, Canada}
+}
+\end{filecontents*}
+
+\AdaptNote\footcite{m}{#NOTE{#1}}
+
+\newname\bringhurst{Robert Bringhurst}
+\newname\lefloch{Bruno Le Floch}
+
+\setlength\parfillskip{0pt plus .8\textwidth}
+
+\begin{document}
+
+\section{Preface for those upgrading from version 0.x}
+
+\begin{bewareofthedog}
+ For those upgrading from versions~0 to version~1: a number of options have
+ been dropped or renamed. Please have a close look at your log file for
+ warnings. Also, the way commands are adapted and hence the syntax of
+ \cs{AdaptNote} has changed completely. In many if not all cases leaving them
+ as they were will lead to errors. \par
+ The \cs*{mult...} variants are not defined by default anymore. They can be
+ retained through the load-time option \option{multiple} if needed. Letting
+ the note commands behave as their \cs*{mult...} variants is not supported
+ any more. \par
+ \cs{innernote} is not provided anymore. Depending on user feedback I might
+ try to add it again to \fnpct. \par
+ Please read this manual carefully so you detect all changes. \par
+ \emph{I am sorry for the inconvenience but I am convinced that the new
+ syntax is more powerful and more flexible in the long run.}
+\end{bewareofthedog}
+
+\section{License}
+\license
+
+\section{What's it all about?}
+\subsection{Introduction}
+The purpose of this package is to offer kerning for footnote marks, \ie\ the
+superscripts. This is not appropriate for all superscripts. Symbols must be
+handled differently than numbers. And of course the amount depends on the
+chosen font. \bringhurst\ says in \citetitle{bringhurst04}:
+
+\begin{cnltxquote}[\emph{\citetitle{bringhurst04}} \cite{bringhurst04}]
+ Superscripts frequently come at the ends of phrases or sentences. If they
+ are high above the line, they can be kerned over a comma or period, but this
+ may endanger readability, especially if the text is set in a modest size.
+\end{cnltxquote}
+
+\fnpct\ can not make these decisions for you. It sets some initial values for
+the comma and the full stop which looked good to me with the tested fonts.
+Additionally it kerns the superscripts away from words when it follows
+directly. The amounts of the kerning can be changed using options.
+
+\fnpct\ also switches the order of the superscript and the following comma or
+full stop. Additional punctuation marks can be added to the switching
+behavior and the amount of kerning can be set for each punctuation mark
+individually. This behavior can also be turned off.
+
+\subsection{Basics}
+The \fnpct\ package basically does two things to footnotes:
+\begin{itemize}
+ \item if footnote marks are followed by a comma or a full stop\footnote{More
+ punctuation marks can be added through a package option.} the order of
+ footnote and punctuation mark is reversed
+\item and the kerning gets adjusted.
+\end{itemize}
+As a side effect a new method of creating multiple
+footnotes\multfootnote{like;this} is provided.
+
+In what way is the kerning adjusted? After being placed behind the
+punctuation mark the footnote mark is moved a little bit back, namely by the
+amount specified with the option \option{after-punct-space}. If the footnote
+mark follows a word \emph{without} being followed by a
+punctuation\footnote{Well, it does not necessarily have to follow a
+ \emph{word}. The important point is \emph{not being followed} by a
+ punctuation mark.}, there (obviously) is no order switching and a little
+space is inserted before the footnote mark, namely the amount specified by the
+option \option{before-footnote-space}.
+
+Now, let's see some action:
+\begin{example}
+ The three little pigs built their houses out of straw\footnote{not to be
+ confused with hay}, sticks\footnote{or lumber according to some sources}
+ and bricks\footnote{probably fired clay bricks}.
+\end{example}
+
+To ensure that the kerning is set the right way the footnote \emph{must} be
+placed \emph{before} the full stop or the comma. \emph{The command can look
+ ahead but not look back}. This means if you place the \cs{footnote} command
+after a full stop or a comma it is treated as if following a word, \ie\ a thin
+space is inserted: effectively the opposite of the desired behavior. The
+effects are demonstrated in figure~\vref{fig:effects}.
+
+The order-switching can be prevented using the option \option{reverse} since
+not all countries and languages have the same typographic conventions. In
+this case the full stop and the comma are moved a bit back, namely by the
+amount specified with the option \option{before-punct-space}.
+
+\begin{figure}
+ \centering
+ \begin{tabular}{>{\setfnpct{dont-mess-around}}ll}
+ \toprule
+ without \fnpct &
+ with \fnpct \\
+ \midrule
+ \strut\quad text.\footnotemark[1] &
+ \strut\quad text\footnotemark[1]. \\
+ \strut\quad text\footnotemark[1]. &
+ \setfnpct{reverse}\strut\quad text\footnotemark[1]. \\
+ \strut\quad text\footnotemark[1] &
+ \strut\quad text\footnotemark[1] \\
+ \bottomrule
+ \end{tabular}
+ \caption{The effect of \fnpct.}\label{fig:effects}
+\end{figure}
+
+\subsection{Temporarily disable (or enable) switching -- new syntax of the
+ \cs*{footnote} command}
+One maybe want to put some footnote marks \emph{before} the punctuation and
+some after, for example because the first one describes a single word but the
+second one a whole sentence. For this purpose \fnpct\ adds a \sarg\ argument
+to \cs{footnote} and \cs{footnotemark}. The complete new syntax now is as
+follows:
+\begin{commands}
+ \command{footnote}[\sarg\oarg{num>}\marg{footnote text}\meta{tpunct}]
+ new \sarg\ argument added. \meta{tpunct} is the optional trailing
+ punctuation mark.
+ \command{footnotemark}[\sarg\oarg{num>}\meta{tpunct}]
+ new \sarg\ argument added. \meta{tpunct} is the optional trailing
+ punctuation mark.
+\end{commands}
+The \sarg\ argument temporarily turns off the punctuation/footnote switching.
+In case you set \keyis{reverse}{true} the \sarg\ argument temporarily
+\emph{enables} the switching.
+
+\begin{example}
+ \begin{minipage}{.4\linewidth}
+ \noindent The three little pigs built their houses
+ out of straw\footnote*{not to be confused with hay},
+ sticks\footnote{or lumber according to some sources}
+ and bricks\footnote{probably fired clay bricks}.
+ \end{minipage}\hfil
+ \setfnpct{reverse}
+ \begin{minipage}{.4\linewidth}
+ \noindent The three little pigs built their houses
+ out of straw\footnote*{not to be confused with hay},
+ sticks\footnote{or lumber according to some sources}
+ and bricks\footnote{probably fired clay bricks}.
+ \end{minipage}
+\end{example}
+
+\section{Options}\label{sec:options}
+\begin{commands}
+ \command{setfnpct}[\marg{options}]
+ All available options are listed below. They are set with \cs{setfnpct}.
+ \default{Underlined} values are set if the option is used without value.
+\end{commands}
+\begin{options}
+ \keybool{dont-mess-around}\Default{false}
+ Switches of \fnpct's mechanism.
+ \keybool{reverse}\Default{false}
+ This option reverses the behavior of starred and un-starred footnotes.
+ \keybool{ranges}\Default{false}
+ Activates ranges for multiple footnotes. This is not compatible with
+ \pkg{hyperref} and does not work for the marks of some packages.
+ \keylit{add-trailing-token}{\oarg{before}\meta{token}\oarg{after}\marg{name}}
+ Adds \meta{token} to \fnpct's mechanism and activates it. \meta{before}
+ sets the default value for the newly created option
+ \option{before-\meta{name}-space}. \meta{after} sets the default value for
+ the newly created option \option{after-\meta{name}-space}.
+ Instead of the option you can also use the command \cs*{AddPunctuation},
+ see section~\ref{sec:adapt}.
+ \keyval{activate-trailing-tokens}{tokenlist}\Default{.,}
+ Activates tokens that have been added with \option{add-trailing-token}.
+ \keyval{deactivate-trailing-tokens}{tokenlist}
+ Deactivates tokens that have been added with \option{add-trailing-token}.
+ \keyval{before-footnote-space}{dimension}\Default{.06em}
+ Sets the space that is inserted before a footnote that \emph{does not
+ follow a punctuation or other note} to \meta{dimension}.
+ \keyval{before-dot-space}{dimension}\Default{-.16em}
+ Sets the space that is inserted before a dot if the dot follows a footnote
+ mark to \meta{dimension}.
+ \keyval{before-comma-space}{dimension}\Default{-.16em}
+ Sets the space that is inserted before a comma if the dot follows a footnote
+ mark to \meta{dimension}.
+ \keyval{before-punct-space}{dimension}
+ Sets the space that is inserted before any punctuation mark known to
+ \fnpct\ if the punctuation mark follows a footnote mark to
+ \meta{dimension}.
+ \keyval{after-dot-space}{dimension}\Default{-.06em}
+ Sets the space that is inserted after a dot if the dot precedes a footnote
+ mark to \meta{dimension}.
+ \keyval{after-comma-space}{dimension}\Default{-.06em}
+ Sets the space that is inserted after a comma if the dot precedes a
+ footnote mark to \meta{dimension}.
+ \keyval{after-punct-space}{dimension}
+ Sets the space that is inserted after any punctuation mark known to
+ \fnpct\ if the punctuation mark precedes a footnote mark to
+ \meta{dimension}.
+ \keyval{mult-fn-delim}{code}\Default{\code{;}}
+ Sets the symbol that divides the seperate notes in the \cs*{mult...}
+ variants.
+ \keyval{separation-symbol}{value}\default{\code{,}}
+ Redefines \cs{multfootsep} to \meta{value}. This symbol separates
+ multiple footnotes if \keyis{ranges}{false}.
+ \keyval{range-symbol}{value}\Default{\code{--}}
+ Redefines \cs{multfootrange} to \meta{value}. This symbol separates
+ multiple footnotes if \keyis{ranges}{true}.
+ \keyval{print-separation}{code}\Default{\cs*{textsuperscript}\Marg{\cs*{multfootsep}}}
+ The actual code placed between multiple footnotes if \keyis{ranges}{false}.
+ \keyval{print-range}{code}\Default{\cs*{textsuperscript}\Marg{\cs*{multfootrange}}}
+ The actual code placed between multiple footnotes if \keyis{ranges}{true}.
+\end{options}
+
+% \subsection{Language Specific Settings}
+% Package \pkg{babel}'s~\cite{pkg:babel} French settings redefine
+% \cs*{@footnotemark}. \fnpct\ resets this redefinition but sets the
+% \option{before-footnote-space} equal to a thin space (\code{.16667em}).
+
+% In case the automatic kerning doesn't work for whatever reason the spaces are
+% available as user commands as well:
+% \begin{commands}
+% \command{kfp}
+% Insert \option{after-dot-space} or (if \keyis{punct-after}{true})
+% \option{before-dot-space}.
+% \command{kfc}
+% Insert \option{after-comma-space} or (if \keyis{punct-after}{true})
+% \option{before-comma-space}.
+% \end{commands}
+
+\section{Multiple footnotes}\label{sec:multiple}
+\subsection{Basics}
+Since multiple footnotes have to be treated differently\footnote{see these
+ footnotes}\footnote{for an example}, \fnpct\ recognizes if \cs*{footnote} is
+used multiple times in a row:
+
+\begin{example}
+ The three little pigs built their houses out of straw\footnote{not to be
+ confused with hay}, sticks\footnote{or lumber according to some sources}
+ and bricks\footnote{probably fired clay bricks}\footnote{or something else}.
+\end{example}
+
+\subsection{Ranges}
+Starting with a minimum number of three footnotes in a row \fnpct\ can also
+display the footnote marks as a range.
+\begin{example}
+ \setfnpct{ ranges = true }
+ The three little pigs built their houses out of straw\footnote{not to be
+ confused with hay}, sticks\footnote{or lumber according to some sources}
+ and bricks\footnote{probably fired clay bricks}%
+ \footnote{or something else}\footnote{what do I know}.
+\end{example}
+It is important to note that this has limits: ranges do not work well with
+\pkg{hyperref}. For that reason \fnpct' disables ranges if it detects that
+\pkg{hyperref} has been loaded. If you insist on using ranges together with
+\pkg{hyperref} use
+\begin{options}
+ \keybool{keep-ranges}\Default{false}
+ to enable them again.
+\end{options}
+
+\subsection{The delimiter and separator}
+Some packages or classes like the \KOMAScript\ classes define
+\cs{multfootsep}. If it is not predefined it is defined by \fnpct:
+\begin{commands}
+ \command{multfootsep}\Default{,}
+ In its default definition this command simply expands to a comma.
+ \command{multfootrange}\Default{--}
+ In its default definition this command simply expands to an endash.
+\end{commands}
+This commands can be redefined to adapt to your needs. You can do this with
+\cs*{renewcommand} or by using these options:
+\begin{options}
+ \keyval{separation-symbol}{value}\default{\code{,}}
+ Redefines \cs{multfootsep} to \meta{value}. This symbol separates
+ multiple footnotes if \keyis{ranges}{false}.
+ \keyval{range-symbol}{value}\Default{\code{--}}
+ Redefines \cs{multfootrange} to \meta{value}. This symbol separates
+ multiple footnotes if \keyis{ranges}{true}.
+\end{options}
+Both symbols are placed inside \cs*{textsuperscript}. This can also be
+redefined if necessary:
+\begin{options}
+ \keyval{print-separation}{code}\Default{\cs*{textsuperscript}\Marg{\cs*{multfootsep}}}
+ The actual code placed between multiple footnotes if \keyis{ranges}{false}.
+ \keyval{print-range}{code}\Default{\cs*{textsuperscript}\Marg{\cs*{multfootrange}}}
+ The actual code placed between multiple footnotes if \keyis{ranges}{true}.
+\end{options}
+
+\subsection{\cs*{mult...} variants}
+
+\begin{bewareofthedog}
+ The commands presented in this section are defined to keep some backwards
+ compatibility to versions of \fnpct\ prior to v1.0. In order to use them
+ you have to call the package with
+ \cs*{usepackage}\Oarg{multiple}\Marg{fnpct}.
+\end{bewareofthedog}
+In earlier versions of \fnpct\ detecting following footnotes was not as
+reliable as it is now. For that reason it defined the following command:
+\begin{commands}
+ \command{multfootnote}[\sarg\Marg{\meta{list};\meta{of};\meta{footnotes}}\meta{tpunct}]
+ Different footnotes are separated with a semicolon. The \sarg\ turns the
+ footnote/punctuation switching temporarily off.
+\end{commands}
+\begin{example}
+ The three little pigs built their houses out of straw\footnote{not to be
+ confused with hay}, sticks\footnote{or lumber according to some sources}
+ and bricks\multfootnote{probably fired clay bricks;or something else}.
+\end{example}
+This command splits its content at every occurrence of \code{;} and creates a
+footnote for each. This delimiter can be changed:
+\begin{options}
+ \keyval{mult-fn-delim}{code}\Default{;}
+ Sets the symbol that divides the seperate notes in the \cs*{mult...}
+ variants.
+\end{options}
+
+Since the semicolon might be part of the footnote text you might have some
+trouble. Enclosing it in braces should work:
+\begin{example}
+ The three little pigs built their houses out of straw\footnote{not to be
+ confused with hay}, sticks\footnote{or lumber according to some sources}
+ and bricks\multfootnote{probably fired clay bricks{;} or something else;what
+ do I know}.
+\end{example}
+
+\section{Extend \fnpct}
+\subsection{Additional punctuation marks}
+So if you want to extend the punctuation switching and kerning to other punctuation
+marks you can do something like this:
+\begin{sourcecode}
+ \setfnpct{ add-trailing-token = !{bang} }
+\end{sourcecode}
+\setfnpct{ add-trailing-token = !{bang} }
+After that the bang is recognized and footnotes switch position:
+\begin{example}
+ The three little pigs built their houses out of straw\footnote{not to be
+ confused with hay}? Sticks\footnote{or lumber according to some sources}
+ and bricks\footnote{probably fired clay bricks}!
+\end{example}
+
+New options have also been defined:
+\begin{example}
+ \setfnpct{ after-bang-space = .03em }
+ The three little pigs built their houses out of straw\footnote{not to be
+ confused with hay}? Sticks\footnote{or lumber according to some sources}
+ and bricks\footnote{probably fired clay bricks}!
+\end{example}
+
+And option \option{after-punct-space} is obeyed:
+\begin{example}
+ \setfnpct{ after-punct-space = 2pt }
+ The three little pigs built their houses out of straw\footnote{not to be
+ confused with hay}? Sticks\footnote{or lumber according to some sources}
+ and bricks\footnote{probably fired clay bricks}!
+\end{example}
+
+\begin{bewareofthedog}
+ Please note that you should not use \option{add-trailing-token} inside a
+ group. Ideally it is used in the document preamble only. Using it inside of
+ a group can lead to unwanted side effects and should not be attempted.
+\end{bewareofthedog}
+
+\setfnpct{ deactivate-trailing-tokens = ! }
+
+\subsection{Make note commands known to \fnpct}\label{sec:adapt}
+If a package is not natively supported you can try and adapt commands
+yourself. Before you do so please check section~\vref{sec:other:packages}.
+\begin{commands}
+ % \AdaptNote
+ \command{AdaptNote}[\Marg{\cs*{cs}}\marg{arguments}\oarg{counter name}\marg{code}]
+ This redefines \cs*{cs}. How the redefinition works is best demonstrated
+ with an example. See below for an example. The arguments \meta{arguments}
+ are defined with the same syntax as \pkg{xparse}'s
+ \cs*{NewDocumentCommand}. See the \pkg{xparse} manual~\cite{pkg:xparse}
+ for a complete description. Within \meta{code} \code{\#NOTE} is replaced
+ with the original command. If the optional argument is not used the
+ counter name \code{cs} for a note command \cs*{cs} is assumed.
+
+ In addition to the arguments specified in \meta{arguments} an optional
+ star as first argument is defined which reverses \fnpct's behavior.
+ \meta{code} is also placed inside a group.
+ % \AdaptNoteName
+ \command{AdaptNoteName}[\marg{csname}\marg{arguments}\oarg{counter name}\marg{code}]
+ Like \cs{AdaptNote} but the first argument expects a csname instead of a
+ command sequence token.
+ % \MultVariant
+ \command{MultVariant}[\Marg{\cs*{cs}}]
+ Defines a command \cs*{multcs} which splits is argument at each occurence
+ of the token set by the option \option{mult-fn-delim} and turns it into a
+ series of calls of \cs*{cs}. \cs*{multcs} also has a starred variant in
+ order to create a series of starred calls of \cs*{cs}.
+ % \MultVariantName
+ \command{MultVariantName}[\marg{csname}]
+ Like \cs{MultVariant} but the argument expects a csname instead of a
+ command sequence token.
+ % \AddPunctuation
+ \command*{AddPunctuation}[\oarg{before}\meta{token}\oarg{after}\marg{name}]
+ Adds \meta{token} to \fnpct's mechanism and activates it. \meta{before}
+ sets the default value for the newly created option
+ \option{before-\meta{name}-space}. \meta{after} sets the default value for
+ the newly created option \option{after-\meta{name}-space}. This is the
+ same as using option \option{add-trailing-token}.
+\end{commands}
+
+\fnpct\ adapts \LaTeX's standard footnote commands the following
+way\footnote{Using \cs*{@mpfn} as counter name is essential to make ranges
+ work in minipages.}:
+\begin{sourcecode}
+ \AdaptNote\footnote{o+m}[\@mpfn]{\IfNoValueTF{#1}{#NOTE{#2}}{#NOTE[#1]{#2}}}
+ \AdaptNote\footnotemark{o}{\IfNoValueTF{#1}{#NOTE}{#NOTE[#1]}}
+ \MultVariant\footnote
+ % KOMA-Script's or memoir's \footref:
+ \AdaptNote\footref{m}{#NOTE{#1}}
+\end{sourcecode}
+You essentially have to rebuild the syntax of the original command and place
+\code{\#NOTE} in the code where it should be called. This may seem cumbersome
+at first but allows to adapt commands with a more or less arbitrary kind of
+syntax.
+
+The command \cs{AdaptNote} can be used multiple times on the same command in
+order to change a previous redefinition.
+
+\section{Other packages}\label{sec:other:packages}
+\fnpct\ tries its best to support other footnote and related
+packages\footnote{If you find some package missing please let me know.}. Each
+of the following subsections is dedicated to one of these packages and if and
+how they work together with \fnpct. Fortunately most of them do quite well.
+
+Most notably the \option{ranges} option cannot deal with some packages, often
+due to the lack of a suiting \cs*{...text}
+
+\subsection{bigfoot}\label{sec:bigfoot}
+The package \pkg{bigfoot}~\cite{pkg:bigfoot} is supported.
+
+You need to be a bit cautious, though: \emph{verbatim material won't work
+ inside footnotes anymore}. You might use \lefloch's \pkg{cprotect}
+package~\cite{pkg:cprotect} if you really need verbatim material in footnotes
+\emph{and} want to use \fnpct. Since \fnpct\ does not redefine any
+\cs{footnotetext} like command it will still work inside one of them.
+
+\subsection{endnotes}\label{sec:endnotes}
+The package \pkg{endnotes}~\cite{pkg:endnotes} is supported.
+
+\subsection{enotez}\label{sec:enotez}
+The package \pkg{enotez}~\cite{pkg:enotez} is supported.
+
+\subsection{fixfoot}\label{sec:fixfoot}
+The \pkg{fixfoot}~\cite{pkg:fixfoot} package provides a possibility to create
+repeating footnotes. \fnpct\ supports this package provided you take care of
+the following:
+
+\emph{Use \cs{DeclareFixedFootnote} only in the preamble but \emph{after}
+ loading \fnpct.}
+
+\cs*{DeclareFixedFootnote}\Marg{\cs*{cs}}\marg{footnote text} is used to store
+the \meta{footnote text} in \cs*{cs} which in turn creates a footnote mark for
+it but doesn't repeat the footnote text on the same page in the bottom. The
+document needs several runs to get all the numbers and footnotes right.
+
+Every fixed footnote declared with \cs{DeclareFixedFootnote} gets an optional
+\sarg\ to prevent the punctuation switching.
+
+\noranges{fixfoot}
+
+\subsection{footmisc}\label{sec:footmisc}
+The \pkg{footmisc} package~\cite{pkg:footmisc} provides a range of options to
+customize footnotes, for example output them as margin notes or count
+footnotes per page.
+
+Testing showed no incompatibilities with \pkg{footmisc}. The only thing is
+that you won't have to (and shouldn't) use its \option{multiple} option.
+
+\subsection{footnote}\label{sec:footnote}
+
+Testing showed no incompatibilities with \pkg{footnote}. It cannot adapt its
+environment \env*{footnote}, though.
+
+\subsection{manyfoot}\label{sec:manyfoot}
+The package \pkg{manyfoot}~\cite{pkg:manyfoot} is supported.
+
+\subsection{pagenote}\label{sec:pagenote}
+The package \pkg{pagenote}~\cite{pkg:pagenote} is supported.
+
+\noranges{pagenote}
+
+\subsection{parnotes}\label{sec:parnotes}
+The package \pkg{parnotes}~\cite{pkg:parnotes} is supported.
+
+\noranges{parnotes}
+
+\subsection{sepfootnotes}\label{sec:sepfootnotes}
+The package \pkg{sepfootnotes}~\cite{pkg:sepfootnotes} is supported. Define
+new footnote types \emph{after} \fnpct\ has been loaded.
+
+\subsection{sidenotes}\label{sec:sidenotes}
+\begin{bewareofthedog}
+ The package \pkg{sidenotes}~\cite{pkg:sidenotes} is \emph{not} supported!
+\end{bewareofthedog}
+\fnpct\ is not able to adapt \pkg{sidenotes}' commands due to the current
+implementation of \pkg{sidenotes}.
+
+\subsection{snotez}\label{sec:snotez}
+The package \pkg{snotes}~\cite{pkg:snotez} is supported.
+
+\subsection{tablefootnote}\label{sec:tablefootnote}
+The package \pkg{tablefootnote}~\cite{pkg:tablefootnote} is supported.
+
+\noranges{tablefootnote}
+
+\subsection{tufte-latex's \cs*{sidenote}}\label{sec:tufte}
+The \cs*{sidenote} command from the \pkg*{tufte-latex} classes
+\cls{tufte-book} and \cls{tufte-handout} is supported.
+
+\noranges*{tufte-latex}
+
+More precisely: the \cs*{sidenote} command from \pkg*{tufte-latex} does not
+work with \option{ranges}. But since \cs*{sidenote} is only a synonym for
+\cs*{footnote} for \pkg*{tufte-latex} you can use the latter.
+
+\subsection{biblatex's \cs*{footcite}}\label{sec:biblatex}
+If you're willing to sacrifice \cs*{footcite}'s \sarg\ argument (which it has
+in some styles) you can adapt the commands provided by
+\pkg{biblatex}~\cite{pkg:biblatex} as well:
+\begin{sourcecode}
+ \AdaptNote\footcite{oo+m}[footnote]{%
+ \setfnpct{dont-mess-around}%
+ \IfNoValueTF{#1}
+ {#NOTE{#3}}
+ {\IfNoValueTF{#2}{#NOTE[#1]{#3}}{#NOTE[#1][#2]{#3}}}%
+ }
+\end{sourcecode}
+You could use another token for the star, though, if needed:
+\begin{sourcecode}
+ \AdaptNote\footcite{t+oo+m}[footnote]{%
+ \setfnpct{dont-mess-around}%
+ \IfBooleanTF{#1}{%
+ \IfNoValueTF{#2}
+ {#NOTE{#4}}
+ {\IfNoValueTF{#3}{#NOTE[#2]{#4}}{#NOTE[#2][#3]{#4}}}%
+ }{%
+ \IfNoValueTF{#2}
+ {#NOTE*{#4}}
+ {\IfNoValueTF{#3}{#NOTE*[#2]{#4}}{#NOTE*[#2][#3]{#4}}}%
+ }
+\end{sourcecode}
+Testing showed no problems whatsoever but \fnpct\ does not adapt the command
+itself.
+
+\begin{bewareofthedog}
+ Turning \fnpct\ off inside of \cs*{footcite} is advised as shown in above
+ examples. \cs*{footcite} calls \cs*{footnote} internally which else might
+ lead to inconsistent and unwanted spaces.
+\end{bewareofthedog}
+
+
+\appendix
+
+\printbibliography
+
+\end{document}
+TODO:
+- memoir, \mutfootsep
+- \thanks
+- French
+- nested notes and \AdaptText\footnotetext{om}{\IfNoValueTF{#1}{#NOTE{#2}}{#NOTE[#1]{#2}}}
diff --git a/macros/latex/contrib/fnpct/fnpct.sty b/macros/latex/contrib/fnpct/fnpct.sty
index bdd63448cd..4485a3bada 100644
--- a/macros/latex/contrib/fnpct/fnpct.sty
+++ b/macros/latex/contrib/fnpct/fnpct.sty
@@ -5,35 +5,31 @@
%
% --------------------------------------------------------------------------
% Clemens Niederberger
-% Web: https://bitbucket.org/cgnieder/fnpct/
+% Web: https://github.com/cgnieder/fnpct/
% E-Mail: contact@mychemistry.eu
% --------------------------------------------------------------------------
-% Copyright 2012--2019 Clemens Niederberger
+% Copyright 2012--2021 Clemens Niederberger
%
% This work may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License, either version 1.3
+% conditions of the LaTeX Project Public License, either version 1.3c
% 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.
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008/05/04 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Clemens Niederberger.
% --------------------------------------------------------------------------
-% If you have any ideas, questions, suggestions or bugs to report, please
-% feel free to contact me.
-% --------------------------------------------------------------------------
-% the package is inspired by the following question on TeX.SE:
-% http://tex.stackexchange.com/q/56094/5049
-% --------------------------------------------------------------------------
-\RequirePackage {xparse,l3keys2e,scrlfile}
+\RequirePackage {l3keys2e}
\ExplSyntaxOn
-\tl_const:Nn \c_fnpct_date_tl {2019/10/05}
-\tl_const:Nn \c_fnpct_version_major_number_tl {0}
-\tl_const:Nn \c_fnpct_version_minor_number_tl {5}
+\DeclareHookRule {begindocument} {fnpct} {after} {hyperref}
+
+\tl_const:Nn \c_fnpct_date_tl {2021/01/21}
+\tl_const:Nn \c_fnpct_version_major_number_tl {1}
+\tl_const:Nn \c_fnpct_version_minor_number_tl {0}
\tl_const:Nn \c_fnpct_version_subrelease_tl {}
\tl_const:Nx \c_fnpct_version_number_tl
{
@@ -54,107 +50,129 @@
{\c_fnpct_info_tl}
% --------------------------------------------------------------------------
-% this is plain's \nobreak:
-\cs_new:Npn \fnpct_no_break: { \tex_penalty:D 10000 \scan_stop: }
-
-% --------------------------------------------------------------------------
-% variables:
+% scratch variables and variants of kernel functions:
\tl_new:N \l__fnpct_tmpa_tl
-\tl_new:N \l__fnpct_tmpb_tl
-\dim_new:N \l__fnpct_tmpa_dim
-\dim_new:N \l__fnpct_tmpb_dim
+\seq_new:N \l__fnpct_tmpa_seq
-\int_new:N \l__fnpct_tmpa_int
+\cs_generate_variant:Nn \tl_remove_all:Nn {NV}
+\cs_generate_variant:Nn \prop_item:Nn {NV}
+\cs_generate_variant:Nn \prop_get:NnN {NV}
+\cs_generate_variant:Nn \prop_put:Nnn {Nx,Nnx,Nxx}
+\cs_generate_variant:Nn \seq_put_right:Nn {Nx}
+\cs_generate_variant:Nn \seq_set_split:Nnn {NV}
+\cs_generate_variant:Nn \regex_replace_all:nnN {nx}
+\cs_generate_variant:Nn \str_remove_once:Nn {NV}
+\cs_generate_variant:Nn \msg_warning:nnn {nnV}
+\cs_generate_variant:Nn \msg_warning:nnnn {nnV}
+\cs_generate_variant:Nn \msg_error:nnn {nnV}
-\seq_new:N \l__fnpct_tmpa_seq
-\seq_new:N \l__fnpct_tmpb_seq
-
-\dim_new:N \l__fnpct_after_comma_dim
-\dim_set:Nn \l__fnpct_after_comma_dim {-.06em}
-\dim_new:N \l__fnpct_after_dot_dim
-\dim_set:Nn \l__fnpct_after_dot_dim {-.06em}
-\dim_new:N \l__fnpct_before_comma_dim
-\dim_set:Nn \l__fnpct_before_comma_dim {-.16em}
-\dim_new:N \l__fnpct_before_dot_dim
-\dim_set:Nn \l__fnpct_before_dot_dim {-.16em}
-\dim_new:N \l__fnpct_before_footnote_dim
-\dim_set:Nn \l__fnpct_before_footnote_dim {.06em}
-\dim_new:N \l__fnpct_normal_mark_width_dim
-\dim_set:Nn \l__fnpct_normal_mark_width_dim {1em}
-\dim_new:N \l__fnpct_normal_indent_dim
-\dim_set:Nn \l__fnpct_normal_indent_dim {1.5em}
-\dim_new:N \l__fnpct_normal_parindent_dim
-\dim_set:Nn \l__fnpct_normal_parindent_dim {1em}
-\dim_new:N \l__fnpct_french_before_footnote_space_dim
-\dim_set:Nn \l__fnpct_french_before_footnote_space_dim {.16667em}
-
-\int_new:N \l__fnpct_multiple_notes_int
-
-\tl_new:N \l__fnpct_multiple_footnotes_delimiter_tl
-\tl_set:Nn \l__fnpct_multiple_footnotes_delimiter_tl {;}
-\tl_new:N \l__fnpct_multiple_footnote_separator_tl
-\tl_new:N \l__fnpct_last_punct_mark_tl
-\tl_new:N \l__fnpct_punctuation_marks_tl
-\tl_set:Nn \l__fnpct_punctuation_marks_tl {.,}
-\tl_new:N \l__fnpct_multiple_true_tl
-\tl_new:N \l__fnpct_multiple_false_tl
-
-\bool_new:N \l__fnpct_strict_bool
-\bool_new:N \l__fnpct_punct_after_bool
+\prg_generate_conditional_variant:Nnn \tl_if_eq:nn {v,V} {T,F,TF}
+
+% --------------------------------------------------------------------------
+% variables
+\bool_new:N \l_fnpct_trailing_action_bool
+\bool_new:N \l__fnpct_trailing_tokens_bool
\bool_new:N \l__fnpct_dont_mess_around_bool
-\bool_new:N \l__fnpct_multiple_default_bool
-\bool_new:N \l__fnpct_multiple_footnotes_bool
-\bool_new:N \l__fnpct_reverse_switch_bool
-\bool_new:N \l__fnpct_normal_marks_bool
-\bool_new:N \l__fnpct_hyperref_bool
-\bool_new:N \g__fnpct_after_punctuation_bool
-\bool_new:N \g__fnpct_only_text_bool
-\bool_new:N \l__fnpct_makepagenote_bool
-
-\seq_new:N \l__fnpct_multiple_footnotes_seq
+\bool_new:N \l__fnpct_ranges_bool
+\bool_new:N \l__fnpct_inside_range_bool
+\bool_new:N \l__fnpct_collection_bool
+\bool_new:N \l__fnpct_switched_bool
+\bool_new:N \l__fnpct_end_collection_bool
+\bool_new:N \l__fnpct_automatic_adaption_bool
+\bool_new:N \l__fnpct_reverse_bool
+\bool_new:N \l__fnpct_keep_ranges_bool
+\bool_new:N \g__fnpct_multiple_bool
+\bool_new:N \g__fnpct_text_bool
+\bool_new:N \l__fnpct_debug_bool
+
+\tl_new:N \l_fnpct_action_tl
+\tl_new:N \l_fnpct_last_action_tl
+\tl_new:N \l_fnpct_trailing_token_tl
+\tl_new:N \l__fnpct_trailing_tokens_tl
+\tl_new:N \l__fnpct_range_tl
+\tl_new:N \l__fnpct_separate_tl
+\tl_new:N \l__fnpct_multiple_footnotes_delimiter_tl
+\tl_set:Nn \l__fnpct_multiple_footnotes_delimiter_tl {;}
+\tl_new:N \g__fnpct_this_note_tl
+
+\prop_new:N \l__fnpct_trailing_tokens_prop
+\prop_new:N \l__fnpct_trailing_actions_prop
+\prop_new:N \l__fnpct_trailing_classes_prop
+\prop_new:N \g__fnpct_actions_prop
+\prop_new:N \g__fnpct_action_classes_prop
+
+\seq_new:N \l__fnpct_trailing_tokens_seq
+\seq_new:N \l__fnpct_classes_seq
+\seq_new:N \g__fnpct_actions_seq
\seq_new:N \l__fnpct_footnote_class_seq
+\seq_new:N \l__fnpct_collection_seq
+\seq_new:N \g__fnpct_inner_seq
+\seq_new:N \l__fnpct_adapted_commands_seq
-\prop_new:N \l__fnpct_punctuation_marks_after_prop
-\prop_new:N \l__fnpct_punctuation_marks_before_prop
-\prop_new:N \l__fnpct_sepfootnote_foot_classes_prop
-\prop_new:N \l__fnpct_sepfootnote_end_classes_prop
-\prop_new:N \l__fnpct_sepfootnote_symbol_classes_prop
-\prop_new:N \g__fnpct_adapted_notes_prop
-\prop_new:N \g__fnpct_inner_footnote_prop
-\prop_new:N \g__fnpct_inner_footnote_hyperref_prop
-\prop_new:N \l__fnpct_footnote_fixfoot_prop
+\int_new:N \l__fnpct_collection_int
-% --------------------------------------------------------------------------
-% variants:
-\cs_generate_variant:Nn \str_remove_once:Nn {NV}
-\cs_generate_variant:Nn \tl_remove_all:Nn {NV}
-\cs_generate_variant:Nn \tl_put_right:Nn {NV}
-\cs_generate_variant:Nn \seq_set_split:Nnn {NnV,NV}
-\cs_generate_variant:Nn \prop_gput:Nnn {Nxn,Nxo}
-\cs_generate_variant:Nn \prop_put:Nnn {Nnx}
-\cs_generate_variant:Nn \prop_if_in:NnTF {Nx}
+\dim_new:N \l__fnpct_before_footnote_dim
% --------------------------------------------------------------------------
% messages:
-\cs_new_protected:Npn \fnpct_dont_mess_around:
+\msg_new:nnn {fnpct} {load-time-option}
+ {
+ `#1'~ is~ a~ load-time~ option! \\
+ You~ cannot~ set~ it~ with~ \token_to_str:N \setfnpct ! \\
+ You~ need~ to~ use~ \token_to_str:N \usepackage [#1] {fnpct} .
+ }
+
+\msg_new:nnn {fnpct} {unknown-option}
+ {
+ Unknown~ option~ `#1'! \\
+ I~ don't~ know~ the~ option~ `#1'.~ Please~ make~ sure~ there~ is~ no~
+ typo.~ Check~ the~ manual~ for~ help.
+ }
+
+\msg_new:nnn {fnpct} {dont-mess-around}
+ {
+ All~ right,~ not~ messing~ around.~ :( \\
+ I'd~ really~ love~ to,~ though! \\
+ https://www.youtube.com/results?search_query=mess+around+ray+charles
+ }
+
+\msg_new:nnn {fnpct} {class-not-defined}
+ { The~ action~ class~ `#1'~ is~ not~ defined~ \msg_line_context: }
+
+\msg_new:nnn {fnpct} {command-not-adapted}
+ { The~ command~ `#1'~ doesn't~ seem~ to~ be~ adapted,~ yet,~ \msg_line_context: }
+
+\msg_new:nnn {fnpct} {cannot-adapt}
+ {
+ Due~ to~ the~ implementation~ of~ the~ `#1'~ package~ I~ am~ not~ yet~
+ able~ to~ adapt~ its~ commands.
+ }
+
+\msg_new:nnn {fnpct} {cannot-adapt-with-ranges}
{
- \iow_log:n { ................................................. }
- \iow_log:n { . ~ fnpct~info: }
- \iow_log:n { . }
- \iow_log:n { . ~ All~right,~not~messing~around.~:( }
- \iow_log:n { . ~ But~I'd~really~love~to. }
- \iow_log:n { . ~ (https://www.youtube.com/results?search_query=mess+around+ray+charles) }
- \iow_log:n { ................................................. }
+ Due~ to~ the~ implementation~ of~ the~ `#1'~ package~ I~ am~ not~ yet~
+ able~ to~ adapt~ its~ commands~ while~ also~ using~ the~ option~ `ranges~
+ =~ true'.~ #2
}
-\msg_new:nnn {fnpct} {already-adapted}
+\msg_new:nnn {fnpct} {ranges-hyperref}
{
- The~ command~ \token_to_str:N #1 \c_space_tl has~ already~ been~
- adapted. \\
- I~ will~ do~ nothing~ instead.
+ Using~ the~ option~ `ranges~ =~ true'~ together~ with~ package~
+ `hyperref'~ does~ not~ work~ well.~ Disabling~ ranges.~ If~ you~ insist~
+ then~ set~ `keep-ranges~ =~ true'.
}
+\msg_new:nnn {fnpct} {keep-ranges-hyperref}
+ {
+ Using~ the~ option~ `ranges~ =~ true'~ together~ with~ package~
+ `hyperref'~ does~ not~ work~ well.~ Keeping~ them~ anyway.~ But~ don't~
+ say~ you~ haven't~ been~ warned.
+ }
+
+\msg_new:nnn {fnpct} {ranges-disabled}
+ { Using~ ranges~ is~ disabled~ \msg_line_context: . }
+
\msg_new:nnn {fnpct} {pagenote}
{
If~ you~ use~ the~ `pagenote'~ package~ with~ `fnpct'~ please~ make~ sure~
@@ -162,20 +180,64 @@
`fnpct'!
}
-\msg_new:nnn {fnpct} {deprecated}
+\msg_new:nnn {fnpct} {option-deprecated}
{
- You've~ tried~ setting~ #1~ `#2'~ \msg_line_context: .~ However,~
- #1~ `#2'~ is~ deprecated.~
- \tl_if_blank:nF {#3} {Please~ use~ #1~ `#3'~ instead.~}
- Refer~ to~ the~ manual~ for~ details.
+ The~ option~ `#1'~ is~ deprecated
+ \tl_if_blank:nF {#2}
+ { .~ Please~ use~ option~ `#2'~ instead }
+ \c_space_tl \msg_line_context: .
}
-\cs_new_protected:Npn \fnpct_message:nx #1#2
+\msg_new:nnn {fnpct} {command-removed}
+ { The~ command~ #1~ has~ been~ removed~ from~ fnpct. }
+
+% --------------------------------------------------------------------------
+\cs_new_protected:Npn \__fnpct_loadtime_error:n #1
+ { \msg_error:nnV {fnpct} {#1} \l_keys_key_str }
+
+\cs_new_protected:Npn \__fnpct_loadtime_warning:n #1
+ { \msg_warning:nnV {fnpct} {#1} \l_keys_key_str }
+
+\keys_define:nn {fnpct/package}
{
- \bool_if:NTF \l__fnpct_strict_bool
- { \msg_error:nnx {fnpct} {#1} }
- { \msg_warning:nnx {fnpct} {#1} }
- {#2}
+ multiple .bool_gset:N = \g__fnpct_multiple_bool ,
+ multiple .initial:n = false ,
+ debug .bool_gset:N = \g__fnpct_debug_bool ,
+ debug .initial:n = false ,
+ dont-mess-around .choice: ,
+ dont-mess-around / true .code:n =
+ \bool_set_true:N \l__fnpct_dont_mess_around_bool
+ \msg_info:nn {fnpct} {dont-mess-around} ,
+ dont-mess-around / false .code:n =
+ \bool_set_false:N \l__fnpct_dont_mess_around_bool ,
+ dont-mess-around .default:n = true ,
+ dont-mess-around .initial:n = false ,
+ unknown .code:n =
+ \__fnpct_loadtime_warning:n {unknown-option}
+ }
+
+\ProcessKeysPackageOptions {fnpct/package}
+
+\keys_define:nn {fnpct/package}
+ {
+ multiple .code:n = \__fnpct_loadtime_error:n {load-time-option} ,
+ debug .code:n = \__fnpct_loadtime_error:n {load-time-option} ,
+ dont-mess-around .code:n = \__fnpct_loadtime_error:n {load-time-option}
+ }
+
+% --------------------------------------------------------------------------
+\prg_new_conditional:Npnn \fnpct_if_multiple: {T,F,TF}
+ {
+ \bool_if:NTF \g__fnpct_multiple_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\prg_new_conditional:Npnn \fnpct_if_debug: {T,F,TF}
+ {
+ \bool_if:NTF \g__fnpct_debug_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
}
% --------------------------------------------------------------------------
@@ -186,979 +248,1098 @@
{ \prg_return_false: }
}
-% --------------------------------------------------------------------------
-% multiple footnote input and output variables:
-% check for KOMA-Script's \multfootsep:
-\cs_if_exist:NTF \KOMAClassName
- { \tl_set:Nn \l__fnpct_multiple_footnote_separator_tl { \multfootsep } }
- { \tl_set:Nn \l__fnpct_multiple_footnote_separator_tl {,} }
+\prg_new_conditional:Npnn \fnpct_if_class_loaded:n #1 {p,T,F,TF}
+ {
+ \@ifclassloaded {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
% --------------------------------------------------------------------------
-% #1: before/after
-% #2: punctuation mark
-% #3: dimension
-\cs_new_protected:Npn \fnpct_set_punctuation_dim:nnn #1#2#3
+% #1: cs
+\prg_new_conditional:Npnn \fnpct_if_adapted:N #1 {T,F,TF}
{
- \prop_put:cnx { l__fnpct_punctuation_marks_#1_prop }
- {#2}
- { \dim_eval:n {#3} }
+ \seq_if_in:NnTF \l__fnpct_adapted_commands_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
}
-\cs_generate_variant:Nn \fnpct_set_punctuation_dim:nnn {nV}
-\fnpct_set_punctuation_dim:nnn {after} {.} { \l__fnpct_after_dot_dim }
-\fnpct_set_punctuation_dim:nnn {after} {,} { \l__fnpct_after_comma_dim }
-\fnpct_set_punctuation_dim:nnn {before} {.} { \l__fnpct_before_dot_dim }
-\fnpct_set_punctuation_dim:nnn {before} {,} { \l__fnpct_before_comma_dim }
+\prg_generate_conditional_variant:Nnn \fnpct_if_adapted:N {c} {T,F,TF}
-\cs_new_protected:Npn \fnpct_rm_punctuation:n #1
+% --------------------------------------------------------------------------
+\cs_new_protected:Npn \fnpct_nobreak: { \tex_penalty:D 10000 \scan_stop: }
+\cs_new_protected:Npn \fnpct_skip_nobreak:N #1
{
- \tl_remove_all:Nn \l__fnpct_punctuation_marks_tl {#1}
- \prop_del:Nn \l__fnpct_punctuation_marks_after_prop {#1}
- \prop_del:Nn \l__fnpct_punctuation_marks_before_prop {#1}
+ \fnpct_nobreak:
+ \skip_horizontal:N #1
+ \fnpct_nobreak:
}
+\cs_generate_variant:Nn \fnpct_skip_nobreak:N {c}
-\cs_new_protected:Npn \fnpct_add_punctuation:n #1
- { \__fnpct_add_punctuation:w #1 [ \q_no_value ] \q_no_value \q_stop }
-\cs_generate_variant:Nn \fnpct_add_punctuation:n {V}
+% --------------------------------------------------------------------------
+% checking for trailing tokens - reuse an idea from acro
+% #1: name
+\cs_new_protected:Npn \fnpct_new_class:n #1
+ {
+ \seq_put_right:Nn \l__fnpct_classes_seq {#1}
+ \seq_new:c {g__fnpct_class_#1_seq}
+ }
-\cs_new_protected:Npn \__fnpct_add_punctuation:w #1[#2]#3 \q_stop
+\prg_new_conditional:Npnn \fnpct_class_if_exist:n #1 {p,T,F,TF}
{
- \quark_if_no_value:nTF {#2}
- {
- % there is no option at all
- \tl_map_inline:nn {#1}
- {
- \tl_put_right:Nn \l__fnpct_punctuation_marks_tl {##1}
- \fnpct_set_punctuation_dim:nnn {after} {##1} {0pt}
- \fnpct_set_punctuation_dim:nnn {before} {##1} {0pt}
- \tl_set:No \l__fnpct_last_punct_mark_tl {##1}
- }
- }
+ \seq_if_in:NnTF \l__fnpct_classes_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% #1: name
+% #2: code
+\cs_new_protected:Npn \fnpct_do_action:nnw #1#2 \fnpct_end:
+ {
+ \prop_if_in:NnTF \g__fnpct_actions_prop {#1}
+ { \fnpct_end: \prop_item:Nn \g__fnpct_actions_prop {#1} }
+ { \fnpct_end: \use:n }
+ {#2}
+ }
+\cs_generate_variant:Nn \fnpct_do_action:nnw {V}
+
+% #1: name
+% #2: class
+% #3: default before dim
+% #4: default after dim
+% #5: code requiring two n-type arguments (code and token)
+\cs_new_protected:Npn \fnpct_new_action:nnnnn #1#2#3#4#5
+ {
+ \fnpct_class_if_exist:nTF {#2}
{
- \tl_if_blank:nTF {#1}
- {
- % #2 is a second option (= before space)
- \fnpct_set_punctuation_dim:nVn {before}
- \l__fnpct_last_punct_mark_tl
- {#2}
- }
+ \seq_if_in:NnTF \g__fnpct_actions_seq {#1}
{
- % #2 is a first option (= after space), #1 might be more than one token:
- \tl_if_single_token:nTF {#1}
+ \keys_set:nn {fnpct}
{
- \tl_put_right:Nn \l__fnpct_punctuation_marks_tl {#1}
- \fnpct_set_punctuation_dim:nnn {after} {#1} {#2}
- \fnpct_set_punctuation_dim:nnn {before} {#1} {0pt}
- \tl_set:No \l__fnpct_last_punct_mark_tl {#1}
- }
- {
- \int_zero:N \l__fnpct_tmpa_int
- \tl_map_inline:nn {#1}
- {
- \tl_put_right:Nn \l__fnpct_punctuation_marks_tl {##1}
- \int_compare:nTF { \l__fnpct_tmpa_int < ( \tl_count:n {#1} - 1 ) }
- {
- \fnpct_set_punctuation_dim:nnn {after} {##1} {0pt}
- \fnpct_set_punctuation_dim:nnn {before} {##1} {0pt}
- }
- {
- \fnpct_set_punctuation_dim:nnn {after} {##1} {#2}
- \fnpct_set_punctuation_dim:nnn {before} {##1} {0pt}
- }
- \tl_set:No \l__fnpct_last_punct_mark_tl {##1}
- \int_incr:N \l__fnpct_tmpa_int
- }
+ before-#1-space = #3 ,
+ after-#1-space = #4
}
}
- }
- % is there more?
- \tl_if_eq:nnF {#3} { [\q_no_value]\q_no_value }
- {
- \quark_if_no_value:nF {#3}
{
- \tl_set:Nn \l__fnpct_tmpa_tl {#3}
- \tl_remove_all:Nn \l__fnpct_tmpa_tl { [\q_no_value]\q_no_value }
- \fnpct_add_punctuation:V \l__fnpct_tmpa_tl
+ \seq_gput_right:Nn \g__fnpct_actions_seq {#1}
+ \prop_gput:Nnn \g__fnpct_action_classes_prop {#1} {#2}
+ \prop_gput:Nnn \g__fnpct_actions_prop {#1} {#5}
+ \seq_gput_right:cn {g__fnpct_class_#2_seq} {#1}
+ \dim_new:c {l__fnpct_before_#1_dim}
+ \dim_new:c {l__fnpct_after_#1_dim}
+ \keys_define:nn {fnpct}
+ {
+ before-#1-space .dim_set:c = {l__fnpct_before_#1_dim} ,
+ before-#1-space .initial:n = #3 ,
+ after-#1-space .dim_set:c = {l__fnpct_after_#1_dim} ,
+ after-#1-space .initial:n = #4
+ }
}
}
+ { \msg_error:nnn {fnpct} {class-not-defined} {#2} }
}
-% --------------------------------------------------------------------------
-% options:
-\keys_define:nn {fnpct}
+\prg_new_conditional:Npnn \fnpct_action_if_exist:n #1 {p,T,F,TF}
{
- bigfoot-default-top .code:n =
- \msg_warning:nnnn {fnpct} {deprecated} {option} {bigfoot-default-top} ,
- strict .bool_set:N = \l__fnpct_strict_bool ,
- after-comma-space .code:n =
- \fnpct_set_punctuation_dim:nnn {after} {,} {#1} ,
- after-dot-space .code:n =
- \fnpct_set_punctuation_dim:nnn {after} {.} {#1} ,
- before-comma-space .code:n =
- \fnpct_set_punctuation_dim:nnn {before} {,} {#1} ,
- before-dot-space .code:n =
- \fnpct_set_punctuation_dim:nnn {before} {.} {#1} ,
- after-punct-space .code:n =
- \prop_map_inline:Nn \l__fnpct_punctuation_marks_after_prop
- { \fnpct_set_punctuation_dim:nnn {after} {##1} {#1} } ,
- before-punct-space .code:n =
- \prop_map_inline:Nn \l__fnpct_punctuation_marks_before_prop
- { \fnpct_set_punctuation_dim:nnn {before} {##1} {#1} } ,
- before-footnote-space .dim_set:N = \l__fnpct_before_footnote_dim ,
- french-before-footnote-space .dim_set:N =
- \l__fnpct_french_before_footnote_space_dim ,
- punct-after .bool_set:N = \l__fnpct_punct_after_bool ,
- dont-mess-around .code:n =
- \prop_map_inline:Nn \l__fnpct_punctuation_marks_after_prop
- { \fnpct_set_punctuation_dim:nnn {after} {##1} {0pt} }
- \prop_map_inline:Nn \l__fnpct_punctuation_marks_before_prop
- { \fnpct_set_punctuation_dim:nnn {before} {##1} {0pt} }
- \dim_zero:N \l__fnpct_before_footnote_dim
- \bool_set_true:N \l__fnpct_punct_after_bool
- \bool_set_true:N \l__fnpct_dont_mess_around_bool
- \fnpct_dont_mess_around: ,
- mult-fn-delim .tl_set:N = \l__fnpct_multiple_footnotes_delimiter_tl ,
- mult-fn-sep .tl_set:N = \l__fnpct_multiple_footnote_separator_tl ,
- multiple .bool_set:N = \l__fnpct_multiple_default_bool ,
- normal-marks .bool_set:N = \l__fnpct_normal_marks_bool ,
- normal-mark-width .dim_set:N = \l__fnpct_normal_mark_width_dim ,
- normal-indent .dim_set:N = \l__fnpct_normal_indent_dim ,
- normal-parindent .dim_set:N = \l__fnpct_normal_parindent_dim ,
- verb-format .tl_set:N = \l__fnpct_verbatim_format_tl ,
- add-punct-marks .code:n = \fnpct_add_punctuation:n {#1} ,
- remove-punct-marks .code:n =
- \tl_map_function:nN {#1} \fnpct_rm_punctuation:n
- }
-
-\ProcessKeysOptions {fnpct}
+ \seq_if_in:NnTF \g__fnpct_actions_seq {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
-% --------------------------------------------------------------------------
-% MAIN INTERNAL FOOTNOTE FUNCTION:
-% write the notes:
-\cs_new:Npn \__fnpct_no_value_or_quark_no_value:nTF #1#2#3
+% register a new token but don't activate its action:
+% #1: token
+% #2: action
+\cs_new_protected:Npn \fnpct_new_trailing_token:Nn #1#2
{
- \IfNoValueTF {#1} {#2}
- { \quark_if_no_value:nTF {#1} {#2} {#3} }
+ \prop_put:Nnn \l__fnpct_trailing_tokens_prop {#1} {#1}
+ \prop_put:Nnn \l__fnpct_trailing_actions_prop {#1} {#2}
+ \prop_put:Nnx \l__fnpct_trailing_classes_prop {#1}
+ { \prop_item:Nn \g__fnpct_action_classes_prop {#2} }
+ \seq_put_right:Nn \l__fnpct_trailing_tokens_seq {#1}
}
-\cs_new:Npn \fnpct_write_note:Nnnn #1#2#3#4
+% #1: class
+% #2: code where `#1' refers to the action name
+\cs_new:Npn \fnpct_foreach_action:nn #1#2
{
- \__fnpct_no_value_or_quark_no_value:nTF {#2}
- { #1 {#4} }
- {
- \__fnpct_no_value_or_quark_no_value:nTF {#3}
- { #1 [#2] {#4} }
- { #1 [#2] [#3] {#4} }
- }
+ \fnpct_class_if_exist:nT {#1}
+ { \seq_map_inline:cn {g__fnpct_class_#1_seq} {#2} }
}
-% check for punctuation:
-\cs_new_protected:Npn \fnpct_check_punctuation:TF #1#2
- { \__fnpct_check_punctuation:nTF {0} {#1} {#2} }
+\cs_new_eq:NN \fnpct_action_break: \seq_map_break:
-\cs_new_protected:Npn \__fnpct_check_punctuation:nTF #1#2#3
+% #1: token
+\cs_new_protected:Npn \fnpct_remove_trailing_token:N #1
{
- \__fnpct_get_head:NN
- \l__fnpct_current_punct_mark_tl
- \l__fnpct_punctuation_marks_tl
- \exp_args:NV \peek_meaning_remove:NTF \l__fnpct_current_punct_mark_tl
- {#2}
- {
- \__fnpct_check_punctuation_aux:nnn {#1}
- { \__fnpct_check_punctuation:VTF \l__fnpct_tmpa_int {#2} {#3} }
- {#3}
- }
+ \seq_remove_all:Nn \l__fnpct_trailing_tokens_seq {#1}
+ \prop_remove:Nn \l__fnpct_trailing_tokens_prop {#1}
+ \prop_remove:Nn \l__fnpct_trailing_actions_prop {#1}
+ \prop_remove:Nn \l__fnpct_trailing_classes_prop {#1}
}
-\cs_new_protected:Npn \__fnpct_check_punctuation_aux:nnn #1#2#3
+\cs_new_protected:Npn \fnpct_for_all_trailing_tokens_do:n #1
+ { \seq_map_inline:Nn \l__fnpct_trailing_tokens_seq {#1} }
+
+% activate a token:
+\cs_new_protected:Npn \fnpct_activate_trailing_token:n #1
{
- \int_set:Nn \l__fnpct_tmpa_int {#1}
- \int_incr:N \l__fnpct_tmpa_int
- \tl_set:Nx \l__fnpct_tmpb_tl { \int_to_arabic:n { \l__fnpct_tmpa_int } }
- \tl_remove_all:NV \l__fnpct_punctuation_marks_tl
- \l__fnpct_current_punct_mark_tl
- \tl_put_right:NV \l__fnpct_punctuation_marks_tl
- \l__fnpct_current_punct_mark_tl
- \int_compare:nTF { \l__fnpct_tmpa_int < \tl_count:V \l__fnpct_punctuation_marks_tl }
- {#2}
- {#3}
+ \prop_get:NnN \l__fnpct_trailing_tokens_prop {#1} \l__fnpct_tmpa_tl
+ \tl_put_right:NV \l__fnpct_trailing_tokens_tl \l__fnpct_tmpa_tl
}
-\cs_generate_variant:Nn \__fnpct_check_punctuation:nTF {V}
-
-\cs_new_protected:Npn \__fnpct_get_head:NN #1#2
- { \tl_set:Nx #1 { \tl_head:V #2 } }
-% check for multiple notes:
-\cs_new_protected:Npn \fnpct_check_multiple:TF #1#2
+% deactivate a token:
+\cs_new_protected:Npn \fnpct_deactivate_trailing_token:n #1
{
- \tl_set:Nn \l__fnpct_multiple_true_tl {#1}
- \tl_set:Nn \l__fnpct_multiple_false_tl {#2}
- \bool_gset_false:N \g__fnpct_after_punctuation_bool
- \peek_after:Nw \__fnpct_check_multiple:
+ \prop_get:NnN \l__fnpct_trailing_tokens_prop {#1} \l__fnpct_tmpa_tl
+ \tl_remove_all:NV \l__fnpct_trailing_tokens_tl \l__fnpct_tmpa_tl
}
-\cs_new_protected:Npn \__fnpct_check_multiple:
+% #1: tokenlist
+\prg_new_protected_conditional:Npnn \fnpct_if_trailing_tokens:n #1 {T,F,TF}
{
- \prop_map_inline:Nn \g__fnpct_adapted_notes_prop
+ \bool_set_false:N \l__fnpct_trailing_tokens_bool
+ \tl_map_inline:nn {#1}
{
- \tl_set_rescan:Nnn \l__fnpct_tmpb_tl {} {##1}
- \exp_args:NV
- \token_if_eq_meaning:NNTF \l__fnpct_tmpb_tl \l_peek_token
+ \bool_if:cT {l__fnpct_trailing_##1_bool}
{
- \bool_set_true:N \l__fnpct_multiple_footnotes_bool
- \prop_map_break:
+ \bool_set_true:N \l__fnpct_trailing_tokens_bool
+ \tl_map_break:
}
- { \bool_set_false:N \l__fnpct_multiple_footnotes_bool }
- }
- \bool_if:NTF \l__fnpct_multiple_footnotes_bool
- { \tl_use:N \l__fnpct_multiple_true_tl }
- { \tl_use:N \l__fnpct_multiple_false_tl }
- }
-
-% check which mode is active:
-\prg_new_conditional:Npnn \fnpct_punct_if_after: {T,TF}
- {
- \bool_if:nTF
- {
- \bool_xor_p:nn
- { \l__fnpct_punct_after_bool }
- { \l__fnpct_reverse_switch_bool }
}
+ \bool_if:NTF \l__fnpct_trailing_tokens_bool
{ \prg_return_true: }
{ \prg_return_false: }
}
-% this is where the magic happens:
-\cs_new_protected:Npn \fnpct_handle_punctuation:n #1
+% --------------------------------------------------------------------------
+% #1: token
+\prg_new_protected_conditional:Npnn \__fnpct_check_trail:N #1 {T,F,TF}
{
- \fnpct_check_punctuation:TF
- {
- % this is need as some commands like biblatex's \autocite may in turn
- % call \footnote. It then must not insert the pre-footnote-space:
- \bool_gset_true:N \g__fnpct_after_punctuation_bool
- % A: after=1 && reverse=0
- % after=0 && reverse=1
- % B: after=1 && reverse=1
- % after=0 && reverse=0
- \fnpct_punct_if_after:TF
- {
- \fnpct_no_break:
- \skip_horizontal:N \l__fnpct_before_footnote_dim
- }
- {
- \tl_use:N \l__fnpct_current_punct_mark_tl
- \prop_get:NVNT \l__fnpct_punctuation_marks_after_prop
- \l__fnpct_current_punct_mark_tl
- \l__fnpct_tmpa_tl
- {
- \dim_set:Nn \l__fnpct_tmpa_dim { \l__fnpct_tmpa_tl }
- \fnpct_no_break:
- \skip_horizontal:N \l__fnpct_tmpa_dim
- \fnpct_no_break:
- \skip_horizontal:N \c_zero_skip
- \fnpct_no_break:
- }
- }
- #1
- \bool_gset_false:N \g__fnpct_after_punctuation_bool
- \fnpct_punct_if_after:T
- {
- \fnpct_no_break:
- \prop_get:NVNT \l__fnpct_punctuation_marks_before_prop
- \l__fnpct_current_punct_mark_tl
- \l__fnpct_tmpa_tl
- {
- \dim_set:Nn \l__fnpct_tmpa_dim { \l__fnpct_tmpa_tl }
- \fnpct_no_break:
- \skip_horizontal:N \l__fnpct_tmpa_dim
- \fnpct_no_break:
- \skip_horizontal:N \c_zero_skip
- \fnpct_no_break:
- }
- \tl_use:N \l__fnpct_current_punct_mark_tl
- }
- \bool_set_false:N \l__fnpct_reverse_switch_bool
- }
+ \bool_set_false:N \l_fnpct_trailing_action_bool
+ \tl_clear:N \l_fnpct_trailing_token_tl
+ \bool_if:NTF \l__fnpct_dont_mess_around_bool
+ { \prg_return_false: }
{
- % what about multiple footnotes? (their usage is discouraged with
- % this package, but anyway...)
- % this check should probably/maybe be removed (?!)
- \fnpct_check_multiple:TF
- {
- \bool_set_true:N \l__fnpct_multiple_footnotes_bool
- \fnpct_no_break:
- \bool_if:NF \g__fnpct_after_punctuation_bool
- { \skip_horizontal:N \l__fnpct_before_footnote_dim }
- #1
- \fnpct_no_break:
- \textsuperscript { \l__fnpct_multiple_footnote_separator_tl }
- }
+ \tl_if_empty:NTF \l__fnpct_trailing_tokens_tl
+ { \prg_return_false: }
{
- % else insert space and then note
- \bool_if:NTF \l__fnpct_multiple_footnotes_bool
- { \bool_set_false:N \l__fnpct_multiple_footnotes_bool }
+ \tl_map_inline:Nn \l__fnpct_trailing_tokens_tl
{
- \fnpct_no_break:
- \bool_if:NF \g__fnpct_after_punctuation_bool
- { \skip_horizontal:N \l__fnpct_before_footnote_dim }
+ \token_if_eq_meaning:NNT #1 ##1
+ {
+ \bool_set_true:N \l_fnpct_trailing_action_bool
+ \tl_set:Nn \l_fnpct_trailing_token_tl {##1}
+ \tl_map_break:
+ }
}
- #1
- \bool_set_false:N \l__fnpct_reverse_switch_bool
+ \bool_if:NTF \l_fnpct_trailing_action_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
}
}
}
-
-% #1: original command
-% #2: optional argument of original command
-% #3: second optional argument of original command
-% #4: mandatory argument of original command
-% #5: boolean flag for starred version
-\cs_new_protected:Npn \fnpct_handle_note:Nnnnn #1#2#3#4#5
+% #1: class name
+\prg_new_protected_conditional:Npnn \fnpct_if_class:n #1 {T,F,TF}
{
- % if a punctuation mark follows remove it, insert dot, skip back
- % and then insert footnote
- \bool_if:NF \l__fnpct_dont_mess_around_bool
+ \bool_if:NTF \l_fnpct_trailing_action_bool
{
- \IfBooleanT {#5}
- { \bool_set_true:N \l__fnpct_reverse_switch_bool }
- }
- \fnpct_handle_punctuation:n
- {
- \fnpct_write_note:Nnnn #1 {#2} {#3} {#4}
- \fnpct_write_inner:N #1
+ \prop_get:NVN \l__fnpct_trailing_classes_prop
+ \l_fnpct_trailing_token_tl
+ \l__fnpct_tmpa_tl
+ \tl_if_eq:VnTF \l__fnpct_tmpa_tl {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
}
+ { \prg_return_false: }
}
-\cs_generate_variant:Nn \fnpct_handle_note:Nnnnn { cnnnn }
-% --------------------------------------------------------------------------
-% MULTIPLE FOOTNOTES
-% #1: original note command
-% #2: star
-% #3: multiple notes separated by \l__fnpct_multiple_footnotes_delimiter_tl
-\cs_new_protected:Npn \fnpct_mult_note:Nnn #1#2#3
+% #1: action name
+\prg_new_protected_conditional:Npnn \fnpct_if_action:n #1 {T,F,TF}
{
- \bool_if:NF \l__fnpct_dont_mess_around_bool
+ \bool_if:NTF \l_fnpct_trailing_action_bool
{
- \IfBooleanT {#2}
- { \bool_set_true:N \l__fnpct_reverse_switch_bool }
+ \prop_get:NVN \l__fnpct_trailing_actions_prop
+ \l_fnpct_trailing_token_tl
+ \l__fnpct_tmpa_tl
+ \tl_if_eq:VnTF \l__fnpct_tmpa_tl {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
}
- % split input:
- \seq_set_split:NVn \l__fnpct_multiple_footnotes_seq
- \l__fnpct_multiple_footnotes_delimiter_tl
- {#3}
- \fnpct_handle_punctuation:n
- { \fnpct_write_notes:NN #1 \l__fnpct_multiple_footnotes_seq }
-
+ { \prg_return_false: }
}
-\cs_generate_variant:Nn \fnpct_mult_note:Nnn {cnn}
-% #1: original note command
-% #2: sequence variable holding the note arguments
-\cs_new_protected:Npn \fnpct_write_notes:NN #1#2
- {
- \int_zero:N \l__fnpct_multiple_notes_int
- \seq_map_inline:Nn #2
- {
- \__fnpct_read_note_with_option:w ##1 \q_stop {#1}
- \int_incr:N \l__fnpct_multiple_notes_int
- }
- }
+% --------------------------------------------------------------------------
+% saving and using the note commands:
+\cs_new:Npn \__fnpct_remove_backslash:N #1
+ { \exp_after:wN \use_none:n \token_to_str:N #1 }
-% this shouldn't be a document command but is a really easy way to make
-% biblatex's \footcite et.al. compatible with the `multiple' option
-% #1: optional star => only invoke \footnotetext
-% #2: optional argument to original note command
-% #3: second optional argument to original note command
-% #4: mandatory argument to original note command
-% #5: original note command
-\NewDocumentCommand \__fnpct_read_note_with_option:w { soo+u{\q_stop}m }
+% this is dangerous - it relies on undocumented innards of xparse - however,
+% it should probably be rather safe, anyway:
+\cs_new_protected:Npn \fnpct_save_note_command:N #1
{
- \bool_if:nT
- {
- \int_compare_p:n { \l__fnpct_multiple_notes_int > 0 }
- &&
- \int_compare_p:n
- {
- \l__fnpct_multiple_notes_int
- <
- \seq_count:N \l__fnpct_multiple_footnotes_seq
- }
- }
- {
- \IfBooleanTF {#1}
- { \tex_unskip:D }
- { \textsuperscript { \l__fnpct_multiple_footnote_separator_tl } }
+ \cs_undefine:c {fnpct_original_ \__fnpct_remove_backslash:N #1 :w}
+ \cs_if_exist:cTF { \__fnpct_remove_backslash:N #1 ~ code }
+ {% xparse command
+ \cs_new_eq:cc
+ { fnpct_original_ \__fnpct_remove_backslash:N #1 :w }
+ { \__fnpct_remove_backslash:N #1 ~ code }
}
- \IfBooleanTF {#1}
{
- % TODO: maybe provide option to change \footnotetext? Or do it
- % automatically?
- \bool_gset_true:N \g__fnpct_only_text_bool
- \IfNoValueTF {#2}
- { \footnotetext {#4} }
- { \footnotetext [#2] {#4} }
+ \cs_if_exist:cTF { \__fnpct_remove_backslash:N #1 ~ }
+ {% robust command
+ \cs_new_eq:cc
+ { fnpct_original_ \__fnpct_remove_backslash:N #1 :w }
+ { \__fnpct_remove_backslash:N #1 ~ }
+ }
+ { \cs_new_eq:cN { fnpct_original_ \__fnpct_remove_backslash:N #1 :w } #1 }
}
- { \fnpct_write_note:Nnnn #5 {#2} {#3} {#4} }
- \fnpct_write_inner:N #5
+ \seq_put_right:Nn \l__fnpct_adapted_commands_seq {#1}
+ \fnpct_set_counter_name:Nx #1 { \__fnpct_remove_backslash:N #1 }
}
-% --------------------------------------------------------------------------
-% NESTED FOOTNOTES:
-% 1 layer of nesting...
-% this shouldn't be a document command! But for the time being I'll stick to
-% this easy solution...
-\NewDocumentCommand \fnpct_inner_footnote:w {o+m}
+\cs_new_protected:Npn \fnpct_set_counter_name:Nn #1#2
+ { \cs_set:cpn { fnpct_ \__fnpct_remove_backslash:N #1 _counter: } {#2} }
+\cs_generate_variant:Nn \fnpct_set_counter_name:Nn {c,Nx}
+
+\cs_new:Npn \__fnpct_counter:N #1
+ { \use:c { fnpct_ \__fnpct_remove_backslash:N #1 _counter: } }
+
+\hook_new:n {fnpct/rangesetup}
+
+\cs_new_protected:Npn \fnpct_use_note_command:N #1
{
- \IfNoValueTF {#1}
+ \fnpct_if_debug:T
+ { \iow_term:x { fnpct~ info:~ \exp_not:N #1 \msg_line_context:} }
+ \tl_gset:Nx \g__fnpct_this_note_tl { \__fnpct_remove_backslash:N #1 }
+ \cs_if_exist:cTF {fnpct_original_ \__fnpct_remove_backslash:N #1 :w}
{
- % TODO: maybe detect what type of note we're in and use the appropriate mark?
- % Or provide a user interface to choose the appropriate mark?
- \fnpct_orig_footnotemark:w
- \prop_gput:Nxn \g__fnpct_inner_footnote_prop { \thefootnote } {#2}
- \bool_if:NT \l__fnpct_hyperref_bool
+ \fnpct_inside_range:TF
{
- \prop_gput:Nxo \g__fnpct_inner_footnote_hyperref_prop
- { \thefootnote } { \Hy@footnote@currentHref }
+ \refstepcounter { \__fnpct_counter:N #1 }
+ \tl_set_eq:NN \l__fnpct_current_tl #1
+ \hook_use:n {fnpct/rangesetup}
+ \use:c { \__fnpct_remove_backslash:N #1 text }
}
+ { \use:c {fnpct_original_ \__fnpct_remove_backslash:N #1 :w} }
}
+ { \msg_error:nnn {fnpct} {command-not-adapted} {#1} }
+ }
+\cs_generate_variant:Nn \fnpct_use_note_command:N {c}
+
+\prg_new_conditional:Npnn \fnpct_if_current:N #1 {T,F,TF}
+ {
+ \tl_if_eq:NNTF \l__fnpct_current_tl #1
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn \fnpct_if_current:N {c} {T}
+
+% --------------------------------------------------------------------------
+% action macros
+\prg_new_conditional:Npnn \fnpct_if_collection: {p,T,F,TF}
+ {
+ \bool_if:NTF \l__fnpct_collection_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\prg_new_conditional:Npnn \fnpct_if_ranges: {T,F,TF}
+ {
+ \bool_if:NTF \l__fnpct_ranges_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+\prg_new_conditional:Npnn \fnpct_inside_range: {T,F,TF}
+ {
+ \bool_if:NTF \l__fnpct_inside_range_bool
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+
+% swapping:
+% #1: all the new footnote code, arguments already read
+% #2: the trailing punctuation
+\cs_new_protected:Npn \fnpct_swap:nn #1#2
+ {
+ \fnpct_if_collection:TF
{
- \fnpct_orig_footnotemark:w [#1]
- \prop_gput:Nnn \g__fnpct_inner_footnote_prop {#1} {#2}
- \bool_if:NT \l__fnpct_hyperref_bool
+ \__fnpct_swap:nn
{
- \prop_gput:Nno \g__fnpct_inner_footnote_hyperref_prop
- {#1} { \Hy@footnote@currentHref }
+ \fnpct_before:
+ \fnpct_print_collection:
+ \fnpct_print_note:w #1
+ \fnpct_after:
}
+ {#2}
}
+ { \__fnpct_swap:nn {#1} {#2} }
}
-\cs_new_protected:Npn \fnpct_write_inner:N #1
+\cs_new_protected:Npn \__fnpct_swap:nn #1#2
{
- \token_if_eq_meaning:NNF #1 \fnpct_inner_footnote:w
+ \fnpct_if_switched:TF
{
- \prop_map_inline:Nn \g__fnpct_inner_footnote_prop
- {
- \footnotetext [##1]
- {
- \bool_if:NT \l__fnpct_hyperref_bool
- {
- \prop_get:NnN \g__fnpct_inner_footnote_hyperref_prop
- {##1} \l__fnpct_tmpa_tl
- \Hy@raisedlink
- { \exp_args:NV \hyper@@anchor \l__fnpct_tmpa_tl }
- }
- ##2
- }
- }
- \prop_gclear:N \g__fnpct_inner_footnote_prop
+ \use:nn
+ { \fnpct_skip_nobreak:N \l__fnpct_before_footnote_dim #1 }
+ { \fnpct_add_punctuation_space:n {before} #2 }
}
+ { \use_ii_i:nn {#1} {#2} }
}
-\NewDocumentCommand \writeinnernotes {}
- { \fnpct_write_inner:N X }
+\cs_new:Npn \fnpct_print_note:w \fnpct_before: #1 \fnpct_after:
+{ \exp_not:n { #1 } }
-% --------------------------------------------------------------------------
-% MANUAL KERNING:
-\cs_new_protected:Npn \fnpct_kfp:
+% multiple footnotes and ranges:
+\cs_new_protected:Npn \__fnpct_collect:n #1
{
- \fnpct_no_break:
- \prop_get:NnNT \l__fnpct_punctuation_marks_before_prop {.}
- \l__fnpct_tmpa_tl
- { \dim_set:Nn \l__fnpct_tmpa_dim { \l__fnpct_tmpa_tl } }
- \prop_get:NnNT \l__fnpct_punctuation_marks_after_prop {.}
- \l__fnpct_tmpb_tl
- { \dim_set:Nn \l__fnpct_tmpb_dim { \l__fnpct_tmpb_tl } }
- \bool_if:NTF \l__fnpct_punct_after_bool
- { \skip_horizontal:N \l__fnpct_tmpa_dim }
- { \skip_horizontal:N \l__fnpct_tmpb_dim }
+ \int_incr:N \l__fnpct_collection_int
+ \seq_put_right:Nx \l__fnpct_collection_seq { \fnpct_print_note:w #1 }
}
-\cs_new_protected:Npn \fnpct_kfc:
+% #1: all the new footnote code, arguments already read
+% #2: e.g. the token \footnote
+\cs_new_protected:Npn \fnpct_collect:nn #1#2
{
- \fnpct_no_break:
- \prop_get:NnNT \l__fnpct_punctuation_marks_before_prop {,}
- \l__fnpct_tmpa_tl
- { \dim_set:Nn \l__fnpct_tmpa_dim { \l__fnpct_tmpa_tl } }
- \prop_get:NnNT \l__fnpct_punctuation_marks_after_prop {,}
- \l__fnpct_tmpb_tl
- { \dim_set:Nn \l__fnpct_tmpb_dim { \l__fnpct_tmpb_tl } }
- \bool_if:NTF \l__fnpct_punct_after_bool
- { \skip_horizontal:N \l__fnpct_tmpa_dim }
- { \skip_horizontal:N \l__fnpct_tmpb_dim }
+ \fnpct_if_collection:F
+ {
+ % we're starting a collection
+ \seq_clear:N \l__fnpct_collection_seq
+ \int_set:Nn \l__fnpct_collection_int {1}
+ \bool_set_true:N \l__fnpct_collection_bool
+ }
+ \__fnpct_collect:n {#1}
+ #2
}
-\NewDocumentCommand \kfp {} { \fnpct_kfp: }
-\NewDocumentCommand \kfc {} { \fnpct_kfc: }
-
-% --------------------------------------------------------------------------
-% NORMAL MARKS:
-\AtBeginDocument
+\cs_new_protected:Npn \fnpct_print_collection:
{
- \bool_if:NT \l__fnpct_normal_marks_bool
+ \bool_set_false:N \l__fnpct_collection_bool
+ \bool_set_true:N \l__fnpct_end_collection_bool
+ % DEBUG:
+ \fnpct_if_ranges:TF
{
- \cs_if_exist:NF \KOMAoption
- { \RequirePackage { scrextend } }
- \deffootnote
- [ \l__fnpct_normal_mark_width_dim ]
- { \l__fnpct_normal_indent_dim }
- { \l__fnpct_normal_parindent_dim }
- { \thefootnotemark . \enskip }
+ \seq_item:Nn \l__fnpct_collection_seq {1}
+ \seq_pop_left:NN \l__fnpct_collection_seq \l__fnpct_tmpa_tl
+ \tl_clear:N \l__fnpct_tmpa_tl
+ \bool_set_true:N \l__fnpct_inside_range_bool
+ \seq_use:Nn \l__fnpct_collection_seq { }
+ \bool_set_false:N \l__fnpct_inside_range_bool
+ \int_compare:nNnTF \l__fnpct_collection_int = {2}
+ { \__fnpct_separate: }
+ { \l__fnpct_range_tl }
}
+ {
+ \seq_use:Nn \l__fnpct_collection_seq { \__fnpct_separate: }
+ \__fnpct_separate:
+ }
+ }
+
+\cs_new_protected:Npn \__fnpct_separate:
+ {
+ \bool_if:NTF \g__fnpct_text_bool
+ { \bool_gset_false:N \g__fnpct_text_bool }
+ { \l__fnpct_separate_tl }
+ }
+
+% --------------------------------------------------------------------------
+% define some classes and actions:
+\fnpct_new_class:n {punctuation}
+\fnpct_new_class:n {note}
+
+\fnpct_new_action:nnnnn {dot} {punctuation} {-.16em} {-0.06em} { \fnpct_swap:nn }
+\fnpct_new_action:nnnnn {comma} {punctuation} {-.16em} {-0.06em} { \fnpct_swap:nn }
+\fnpct_new_action:nnnnn {collect} {note} {0pt} {0pt} { \fnpct_collect:nn }
+
+\fnpct_new_trailing_token:Nn . {dot}
+\fnpct_new_trailing_token:Nn , {comma}
+
+% #1: default before dim
+% #2: token
+% #3: default after dim
+% #4: name
+\NewDocumentCommand \AddPunctuation {O{0pt}mO{0pt}m}
+ {
+ \fnpct_new_action:nnnnn {#4} {punctuation} {#1} {#3} { \fnpct_swap:nn }
+ \fnpct_new_trailing_token:Nn #2 {#4}
+ \keys_set:nn {fnpct} { activate-trailing-tokens = #2 }
}
% --------------------------------------------------------------------------
-% LET'S MAKE IT EASIER TO ADAPT EXISTING FUNCTIONS:
-% COPY, RENEW AND CREATE MULT
+% build up the frame for the adapted note commands:
-\prg_new_conditional:Npnn \fnpct_if_adapted:N #1 {p,T,F,TF}
+\prg_new_conditional:Npnn \fnpct_if_switched: {p,T,F,TF}
{
- \prop_if_in:NnTF \g__fnpct_adapted_notes_prop {#1}
+ \bool_if:NTF \l__fnpct_switched_bool
{ \prg_return_true: }
{ \prg_return_false: }
}
-\cs_new_protected:Npn \fnpct_add_to_adapted:NN #1#2
- {
- % \tl_show:n {1:~#1} \tl_show:n {2:~#2}
- \prop_gput:Nnn \g__fnpct_adapted_notes_prop {#1} {#2}
- }
+\cs_new_protected:Npn \__fnpct_execute: {}
-% standard \footnote[<mark>]{<text>} like commands
-% #1: old new name
-% #2: internal name of old definition
-% #3: mult-variant
-%
-% \footnote[<mark>]{<text>} like:
-\cs_new_protected:Npn \fnpct_renew_and_mult:NNN #1#2#3
+% #1: boolean
+\cs_new_protected:Npn \fnpct_begin:
+ { \__fnpct_check_after_end:w }
+
+% #1: code
+\cs_new_protected:Npn \__fnpct_check_after_end:w #1 \fnpct_end:
{
- \fnpct_if_adapted:NF #1
+ \cs_set_protected:Npn \__fnpct_execute:
{
- \fnpct_add_to_adapted:NN #1#2
- \cs_new_eq:NN #2#1
- \fnpct_create_mult_variant:NN #3#2
- \bool_if:NTF \l__fnpct_multiple_default_bool
- { \cs_set_eq:NN #1#3 }
+ \__fnpct_check_trail:NTF \l_peek_token
{
- \RenewDocumentCommand #1 {so+m}
- { \fnpct_handle_note:Nnnnn #2 {##2} { \q_no_value } {##3} {##1} }
+ \prop_get:NVN \l__fnpct_trailing_actions_prop
+ \l_fnpct_trailing_token_tl
+ \l_fnpct_action_tl
+ \fnpct_do_action:Vnw \l_fnpct_action_tl {#1}
}
- }
- }
-\cs_generate_variant:Nn \fnpct_renew_and_mult:NNN {ccc,NcN}
-
-% \footnote{<text>} like:
-\cs_new_protected:Npn \fnpct_renew_and_mult_no_opt:NNN #1#2#3
- {
- \fnpct_if_adapted:NF #1
- {
- \fnpct_add_to_adapted:NN #1#2
- \cs_new_eq:NN #2#1
- \fnpct_create_mult_variant:NN #3#2
- \bool_if:NTF \l__fnpct_multiple_default_bool
- { \cs_set_eq:NN #1#3 }
{
- \RenewDocumentCommand #1 {s+m}
+ % no trailing punctuation
+ \bool_lazy_or:nnT
+ { \fnpct_if_collection_p: }
+ { \fnpct_if_switched_p: }
{
- \fnpct_handle_note:Nnnnn #2 { \q_no_value } { \q_no_value }
- {##2} {##1}
+ \fnpct_skip_nobreak:N \l__fnpct_before_footnote_dim
+ \fnpct_if_collection:T { \fnpct_print_collection: }
}
+ #1
}
+ \fnpct_end:
}
+ \peek_after:Nw \__fnpct_execute:
}
-\cs_generate_variant:Nn \fnpct_renew_and_mult_no_opt:NNN {Nc,ccc}
-% renew but don't create mult-variant:
-% \footnote[<mark>]{<text>} like:
-\cs_new_protected:Npn \fnpct_renew:NN #1#2
+\cs_new_protected:Npn \fnpct_end: { }
+
+\cs_new_protected:Npn \fnpct_before:
{
- \fnpct_if_adapted:NF #1
+ \bool_if:NF \l__fnpct_dont_mess_around_bool
{
- \fnpct_add_to_adapted:NN #1#2
- \cs_new_eq:NN #2#1
- \RenewDocumentCommand #1 {so+m}
- { \fnpct_handle_note:Nnnnn #2 {##2} { \q_no_value } {##3} {##1} }
+ \fnpct_if_switched:F
+ { \fnpct_add_punctuation_space:n {after} }
+ \bool_if:NF \l_fnpct_trailing_action_bool
+ { % no punctiation following
+ \bool_if:NF \l__fnpct_end_collection_bool
+ { \fnpct_skip_nobreak:N \l__fnpct_before_footnote_dim }
+ }
}
}
-\cs_generate_variant:Nn \fnpct_renew:NN {cc,Nc}
-% new
-\cs_new_protected:Npn \fnpct_new:NN #1#2
+\cs_new_protected:Npn \fnpct_add_punctuation_space:n #1
{
- \fnpct_if_adapted:NF #1
+ \fnpct_if_class:nT {punctuation}
{
- \fnpct_add_to_adapted:NN #1#2
- \NewDocumentCommand #1 {so+m}
- { \fnpct_handle_note:Nnnnn #2 {##2} { \q_no_value } {##3} {##1} }
+ \fnpct_foreach_action:nn {punctuation}
+ {
+ \fnpct_if_action:nT {##1}
+ {
+ \fnpct_skip_nobreak:c {l__fnpct_#1_##1_dim}
+ \fnpct_action_break:
+ }
+ }
}
}
-\cs_generate_variant:Nn \fnpct_new:NN {cc,Nc}
-
-% \note[<mark>][<oarg>]{<text>} like:
-\cs_new_protected:Npn \fnpct_renew_and_mult_opt:NNN #1#2#3
+
+\cs_new_protected:Npn \fnpct_after:
{
- \fnpct_if_adapted:NF #1
+ \bool_if:NF \l__fnpct_dont_mess_around_bool
{
- \fnpct_add_to_adapted:NN #1#2
- \cs_new_eq:NN #2#1
- \fnpct_create_mult_variant:NN #3#2
- \bool_if:NTF \l__fnpct_multiple_default_bool
- { \cs_set_eq:NN #1#3 }
+ \fnpct_if_switched:T
{
- \RenewDocumentCommand #1 {soo+m}
- { \fnpct_handle_note:Nnnnn #2 {##2} {##3} {##4} {##1} }
+ \fnpct_if_class:nT {punctuation}
+ {
+ \bool_set_false:N \l__fnpct_collection_bool
+ \fnpct_foreach_action:nn {punctuation}
+ {
+ \fnpct_if_action:nT {##1}
+ {
+ \fnpct_skip_nobreak:c {l__fnpct_before_##1_dim}
+ \fnpct_action_break:
+ }
+ }
+ }
+ \bool_set_false:N \l__fnpct_end_collection_bool
+ \bool_set_false:N \l__fnpct_switched_bool
}
}
}
-\cs_generate_variant:Nn \fnpct_renew_and_mult_opt:NNN {ccc,NcN}
-\cs_new_protected:Npn \fnpct_renew_opt:NN #1#2
+% #1: command
+% #2: argument spec
+% #3: code where #NOTE refers to the original note
+
+\cs_new_protected:Npn \fnpct_adapt_note:Nnn #1#2#3
{
\fnpct_if_adapted:NF #1
{
- \fnpct_add_to_adapted:NN #1#2
- \cs_new_eq:NN #2#1
- \RenewDocumentCommand #1 {soo+m}
- { \fnpct_handle_note:Nnnnn #2 {##2} {##3} {##4} {##1} }
+ \fnpct_save_note_command:N #1
+ \fnpct_new_trailing_token:Nn #1 {collect}
+ \keys_set:nn {fnpct} { activate-trailing-tokens = {#1} }
+ }
+ \tl_set:Nn \l__fnpct_tmpa_tl {#3}
+ \regex_replace_all:nnN {\cP\#\cP\#} {$$$$} \l__fnpct_tmpa_tl
+ \regex_replace_all:nnN {\cP\#8} {\cP\#9} \l__fnpct_tmpa_tl
+ \regex_replace_all:nnN {\cP\#7} {\cP\#8} \l__fnpct_tmpa_tl
+ \regex_replace_all:nnN {\cP\#6} {\cP\#7} \l__fnpct_tmpa_tl
+ \regex_replace_all:nnN {\cP\#5} {\cP\#6} \l__fnpct_tmpa_tl
+ \regex_replace_all:nnN {\cP\#4} {\cP\#5} \l__fnpct_tmpa_tl
+ \regex_replace_all:nnN {\cP\#3} {\cP\#4} \l__fnpct_tmpa_tl
+ \regex_replace_all:nnN {\cP\#2} {\cP\#3} \l__fnpct_tmpa_tl
+ \regex_replace_all:nnN {\cP\#1} {\cP\#2} \l__fnpct_tmpa_tl
+ \regex_replace_all:nxN
+ {\cP\#NOTE}
+ {
+ \exp_not:N \c{fnpct_use_note_command:N}
+ \exp_not:N \c{\__fnpct_remove_backslash:N #1}
+ }
+ \l__fnpct_tmpa_tl
+ % we need to double inner arguments yet one more, so it can appear inside
+ % the replacement text of \__fnpct_execute:
+ \regex_replace_all:nnN {\$\$\$\$} {\cP\#\cP\#\cP\#\cP\#} \l__fnpct_tmpa_tl
+ \tl_put_left:Nn \l__fnpct_tmpa_tl { \fnpct_start:w }
+ \tl_put_right:Nn \l__fnpct_tmpa_tl { \fnpct_stop: }
+ \use:x
+ {
+ \exp_not:n { \RenewDocumentCommand #1 {s#2} }
+ {
+ \exp_not:n { \fnpct_reverse:n {##1} }
+ \exp_not:V \l__fnpct_tmpa_tl
+ }
}
}
-\cs_generate_variant:Nn \fnpct_renew_opt:NN {cc,Nc}
+\cs_generate_variant:Nn \fnpct_adapt_note:Nnn {c}
-% \note{<arg>} like
-\cs_new_protected:Npn \fnpct_renew_no_opt:NN #1#2
+\cs_new_protected:Npn \fnpct_reverse:n #1
{
- \fnpct_if_adapted:NF #1
- {
- \fnpct_add_to_adapted:NN #1#2
- \cs_new_eq:NN #2#1
- \RenewDocumentCommand #1 {s+m}
- { \fnpct_handle_note:Nnnnn #2 { \q_no_value } { \q_no_value } {##2} {##1} }
- }
+ \bool_if:NTF \l__fnpct_reverse_bool
+ { \bool_if:nF }
+ { \bool_if:NT }
+ {#1} { \bool_set_true:N \l__fnpct_switched_bool }
}
-\cs_generate_variant:Nn \fnpct_renew_no_opt:NN {cc,Nc}
-% \note like
-\cs_new_protected:Npn \fnpct_renew_no_arg:NN #1#2
+% #1: code
+\cs_new_protected:Npn \fnpct_start:w #1 \fnpct_stop:
{
- \fnpct_if_adapted:NF #1
- {
- \fnpct_add_to_adapted:NN #1#2
- \cs_new_eq:NN #2#1
- \RenewDocumentCommand #1 {s}
- { \fnpct_handle_note:Nnnnn #2 { \q_no_value } { \q_no_value } { } {##1} }
- }
+ \fnpct_begin:
+ \fnpct_before:
+ \group_begin:
+ #1
+ \group_end:
+ \fnpct_after:
+ \fnpct_end:
}
-\cs_generate_variant:Nn \fnpct_renew_no_arg:NN {cc}
-% create mult-variant
-\cs_new_protected:Npn \fnpct_create_mult_variant:NN #1#2
+\cs_new_protected:Npn \fnpct_text:
{
- \NewDocumentCommand #1 {s+m}
- { \fnpct_mult_note:Nnn #2 {##1} {##2} }
+ \bool_set_false:N \l__fnpct_inside_range_bool
+ \bool_gset_true:N \g__fnpct_text_bool
}
-% \footnotemark[<mark>] like commands:
-\cs_new_protected:Npn \fnpct_renew_mark:NN #1#2
+% --------------------------------------------------------------------------
+% #1: note command
+% #2: arguments
+% #3: counter name
+% #4: code
+\NewDocumentCommand \AdaptNote {mmom}
{
- \fnpct_if_adapted:NF #1
- {
- \fnpct_add_to_adapted:NN #1#2
- \cs_new_eq:NN #2#1
- \RenewDocumentCommand #1 {so}
- { \fnpct_handle_note:Nnnnn #2 {##2} { \q_no_value } { } {##1} }
- }
+ \fnpct_adapt_note:Nnn #1 {#2} {#4}
+ \IfNoValueF {#3}
+ { \fnpct_set_counter_name:Nn #1 {#3} }
}
-\cs_generate_variant:Nn \fnpct_renew_mark:NN {cc,Nc}
-% user commands:
-\NewDocumentCommand \AdaptNote {mm}
+\NewDocumentCommand \AdaptNoteName {mmom}
{
- \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w }
- { \fnpct_message:nx {already-adapted} {#1} }
- { \fnpct_renew_and_mult:NcN #1 { fnpct_orig_ \cs_to_str:N #1 :w } #2 }
+ \fnpct_adapt_note:cnn {#1} {#2} {#4}
+ \IfNoValueF {#3}
+ { \fnpct_set_counter_name:cn {#1} {#3} }
}
-\NewDocumentCommand \AdaptNoteNoMult {m}
+\NewDocumentCommand \AdaptText {mmm}
{
- \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w }
- { \fnpct_message:nx {already-adapted} {#1} }
- { \fnpct_renew:Nc #1 { fnpct_orig_ \cs_to_str:N #1 :w } }
+ \fnpct_adapt_note:Nnn #1 {#2}
+ { \fnpct_text: #3 }
}
-\NewDocumentCommand \AdaptNoteOpt {mm}
+\NewDocumentCommand \innernote {+m}
+ { \msg_warning:nn {fnpct} {command-removed} \use:n {#1} }
+
+\NewExpandableDocumentCommand \ifcurrentnoteTF {m}
+ { \fnpct_if_current:NTF #1 }
+
+\NewExpandableDocumentCommand \ifcurrentnoteT {m}
+ { \fnpct_if_current:NT #1 }
+
+\NewExpandableDocumentCommand \ifcurrentnoteF {m}
+ { \fnpct_if_current:NF #1 }
+
+% --------------------------------------------------------------------------
+% OPTIONS
+\NewDocumentCommand \setfnpct {m}
+ { \keys_set:nn {fnpct} {#1} }
+
+\cs_new_protected:Npn \fnpct_deprecate_option:n #1
+ { \msg_warning:nnVn {fnpct} {option-deprecated} \l_keys_key_str {#1} }
+
+\cs_new_protected:Npn \fnpct_deprecate_option:
+ { \msg_warning:nnV {fnpct} {option-deprecated} \l_keys_key_str }
+
+\keys_define:nn {fnpct}
{
- \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w }
- { \fnpct_message:nx {already-adapted} {#1} }
- { \fnpct_renew_and_mult_opt:NcN #1 { fnpct_orig_ \cs_to_str:N #1 :w } #2 }
+ add-trailing-token .code:n = \AddPunctuation #1 ,
+ activate-trailing-tokens .code:n =
+ \tl_map_inline:nn {#1} { \fnpct_activate_trailing_token:n {##1} } ,
+ activate-trailing-tokens .initial:n = {.,} ,
+ deactivate-trailing-tokens .code:n =
+ \tl_map_inline:nn {#1} { \fnpct_deactivate_trailing_token:n {##1} } ,
+ before-footnote-space .dim_set:N = \l__fnpct_before_footnote_dim ,
+ before-footnote-space .initial:n = .06em ,
+ ranges .bool_set:N = \l__fnpct_ranges_bool ,
+ ranges .initial:n = false ,
+ keep-ranges .bool_set:N = \l__fnpct_keep_ranges_bool ,
+ keep-ranges .initial:n = false ,
+ dont-mess-around .bool_set:N = \l__fnpct_dont_mess_around_bool ,
+ dont-mess-around .initial:n = false ,
+ mult-fn-delim .code:n =
+ \tl_set:Nn \l__fnpct_multiple_footnotes_delimiter_tl {#1} ,
+ separation-symbol .code:n =
+ \renewcommand* \multfootsep {#1} ,
+ range-symbol .code:n =
+ \renewcommand* \multfootrange {#1} ,
+ print-separation .tl_set:N = \l__fnpct_separate_tl ,
+ print-separation .initial:n = \textsuperscript { \multfootsep } ,
+ print-range .tl_set:N = \l__fnpct_range_tl ,
+ print-range .initial:n = \textsuperscript { \multfootrange } ,
+ reverse .bool_set:N = \l__fnpct_reverse_bool ,
+ after-punct-space .code:n =
+ \fnpct_foreach_action:nn {punctuation}
+ { \keys_set:nn {fnpct} { after-##1-space = #1 } } ,
+ before-punct-space .code:n =
+ \fnpct_foreach_action:nn {punctuation}
+ { \keys_set:nn {fnpct} { before-##1-space = #1 } }
}
-\NewDocumentCommand \AdaptNoteOptNoMult {m}
+% deprecate options of earlier version unless it still exists:
+\clist_map_inline:nn
{
- \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w }
- { \fnpct_message:nx {already-adapted} {#1} }
- { \fnpct_renew_opt:Nc #1 { fnpct_orig_ \cs_to_str:N #1 :w } }
+ bigfoot-default-top ,
+ strict ,
+ after-comma-space ,
+ after-dot-space ,
+ before-comma-space ,
+ before-dot-space ,
+ after-punct-space ,
+ before-punct-space ,
+ before-footnote-space ,
+ french-before-footnote-space ,
+ punct-after ,
+ dont-mess-around ,
+ mult-fn-delim ,
+ mult-fn-sep ,
+ multiple ,
+ normal-marks ,
+ normal-mark-width ,
+ normal-indent ,
+ normal-parindent ,
+ verb-format ,
+ add-punct-marks ,
+ remove-punct-marks ,
}
+ {
+ \keys_if_exist:nnF {fnpct} {#1}
+ { \keys_define:nn {fnpct} { #1 .code:n = \fnpct_deprecate_option: } }
+ }
+
+% --------------------------------------------------------------------------
+% define \multfootnote and friends for some transition period
-\NewDocumentCommand \AdaptNoteNoOpt {mm}
+\cs_new_protected:Npn \fnpct_create_mult_variant:N #1
{
- \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w }
- { \fnpct_message:nx {already-adapted} {#1} }
- { \fnpct_renew_and_mult_no_opt:NcN #1 { fnpct_orig_ \cs_to_str:N #1 :w } #2 }
+ \exp_args:Nc \NewDocumentCommand
+ { mult \__fnpct_remove_backslash:N #1 }
+ { sm }
+ {
+ \seq_set_split:NVn \l__fnpct_tmpa_seq
+ \l__fnpct_multiple_footnotes_delimiter_tl
+ {##2}
+ \tl_clear:N \l__fnpct_tmpa_tl
+ \seq_map_inline:Nn \l__fnpct_tmpa_seq
+ {
+ \tl_put_right:Nx \l__fnpct_tmpa_tl
+ { \exp_not:n {#1} \IfBooleanT{##1}{*} \exp_not:n {{####1}} }
+ }
+ \l__fnpct_tmpa_tl
+ }
}
+\cs_generate_variant:Nn \fnpct_create_mult_variant:N {c}
+
+\NewDocumentCommand \MultVariant {m}
+ { \fnpct_create_mult_variant:N #1 }
+
+\NewDocumentCommand \MultVariantName {m}
+ { \fnpct_create_mult_variant:c {#1} }
-\NewDocumentCommand \AdaptNoteNoOptNoMult {m}
+% --------------------------------------------------------------------------
+% TAKE CARE OF FRENCH SETTINGS
+\RequirePackage {translations}
+\hook_gput_code:nnn {begindocument/end} {fnpct}
{
- \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1:w }
- { \fnpct_message:nx {already-adapted} {#1} }
- { \fnpct_renew_no_opt:Nc #1 { fnpct_orig_ \cs_to_str:N #1:w } }
+ \ifcurrentbaselanguage {French}
+ {
+ \cs_set_eq:NN \@footnotemark \@footnotemarkORI
+ \StandardFootnotes
+ \keys_set:nn {fnpct} { before-footnote-space = .16667em }
+ }
+ {}
}
-\NewDocumentCommand \AdaptNoteMark {m}
+% --------------------------------------------------------------------------
+
+\hook_gput_code:nnn {begindocument} {fnpct}
{
- \cs_if_exist:cTF { fnpct_orig_ \cs_to_str:N #1 :w }
- { \fnpct_message:nx {already-adapted} {#1} }
- { \fnpct_renew_mark:Nc #1 { fnpct_orig_ \cs_to_str:N #1 :w } }
+ \fnpct_if_class_loaded:nTF {memoir}
+ { \renewcommand* }
+ { \providecommand* }
+ \multfootsep {,}
+ \providecommand* \multfootrange {--}
+ \tl_set:Nn \l__fnpct_range_tl { \textsuperscript { \multfootrange } }
}
% --------------------------------------------------------------------------
% DO THE REDEFINING:
%
-% `bigfoot' loads `manyfoot' which saves its footnote classes in a 2e list:
-\str_const:Nn \c__fnpct_footins_str {\footins}
-\str_remove_once:Nn \c__fnpct_footins_str {~}
+% before we start make the testing more comfortable:
+\cs_new_protected:Npn \fnpct_treatment:nn #1#2
+ { \fnpct_if_package_loaded:nT {#1} {#2} }
+
+\cs_new_protected:Npn \fnpct_special_treatment:nn #1#2
+ {
+ \fnpct_if_package_loaded:nTF {#1} {#2}
+ { \hook_gput_code:nnn {package/after/#1} {fnpct} {#2} }
+ }
+
+% `manyfoot' (loaded by `bigfoot') saves its footnote classes in a 2e list:
+\str_new:N \l__fnpct_footins_str
+\str_set:Nn \l__fnpct_footins_str {\footins}
+\str_remove_once:Nn \l__fnpct_footins_str {~}
\cs_new_protected:Npn \__fnpct_grab_second:Nnw #1#2#3 \q_stop
{
\str_set:Nn \l__fnpct_tmpa_str {#3}
\str_remove_once:Nn \l__fnpct_tmpa_str {~}
- \str_remove_once:NV \l__fnpct_tmpa_str \c__fnpct_footins_str
+ \str_remove_once:NV \l__fnpct_tmpa_str \l__fnpct_footins_str
\seq_put_right:Nx #1 { \l__fnpct_tmpa_str }
}
\cs_new_protected:Npn \__fnpct_get_fnclasses:NN #1#2
{
- \seq_set_split:NnV \l__fnpct_tmpa_seq {\@elt } #1
+ \seq_set_split:NnV \l__fnpct_tmpa_seq { \@elt } #1
\seq_pop_left:NN \l__fnpct_tmpa_seq \l__fnpct_tmpa_tl
\seq_map_inline:Nn \l__fnpct_tmpa_seq
{ \__fnpct_grab_second:Nnw #2 ##1 \q_stop }
\seq_remove_duplicates:N #2
}
-% before we start make the testing more comfortable:
-\cs_new_protected:Npn \fnpct_treatment:nn #1#2
- { \fnpct_if_package_loaded:nT {#1} {#2} }
-
-\cs_new_protected:Npn \fnpct_special_treatment:nn #1#2
- { \fnpct_if_package_loaded:nTF {#1} {#2} { \AfterPackage* {#1} {#2} } }
-
-% and now get going:
-\AtBeginDocument
+% `fixfoot' package
+\fnpct_special_treatment:nn {fixfoot}
{
- \fnpct_if_package_loaded:nTF {hyperref}
- { \bool_set_true:N \l__fnpct_hyperref_bool }
+ % hook into \DeclareFixedFootnote so we can redefine all fixed footnotes
+ % defined be users
+ \seq_new:N \l__fnpct_footnote_fixfoot_seq
+ \cs_new_eq:NN \fnpct_new_fixnote:w \DeclareFixedFootnote
+ \RenewDocumentCommand \DeclareFixedFootnote {smm}
{
- \cs_if_exist:NF \AfterBeginDocument
- { \cs_new:Npn \AfterBeginDocument #1 {#1} }
+ \seq_put_right:Nn \l__fnpct_footnote_fixfoot_seq {#2}
+ \IfBooleanTF {#1}
+ { \fnpct_new_fixnote:w * {#2} {#3} }
+ { \fnpct_new_fixnote:w {#2} {#3} }
}
- \AfterBeginDocument
+ }
+
+% `pagenote' package:
+\fnpct_special_treatment:nn {pagenote}
+ {
+ \bool_new:N \l__fnpct_makepagenote_bool
+ \tl_put_left:Nn \makepagenote
+ { \bool_set_true:N \l__fnpct_makepagenote_bool }
+ }
+
+\fnpct_special_treatment:nn {sepfootnotes}
+ {
+ \cs_new_eq:NN \fnpct_sepfootnote_new:n \sep@new
+ \seq_new:N \l__fnpct_sepfootnotes_seq
+ \cs_set_protected:Npn \sep@new #1 {
+ \seq_put_right:Nn \l__fnpct_sepfootnotes_seq {#1}
+ \fnpct_sepfootnote_new:n {#1}
+ }
+ }
+
+\hook_gput_code:nnn {begindocument} {fnpct}
+ {
+ \fnpct_if_package_loaded:nT {hyperref}
{
- \AdaptNote \footnote \multfootnote
- \AdaptNoteMark \footnotemark
- \cs_if_exist:NT \footref
- { \AdaptNoteNoOptNoMult \footref }
- \fnpct_new:NN \innernote \fnpct_inner_footnote:w
- %% the `endnotes' package:
- \fnpct_treatment:nn {endnotes}
+ \fnpct_if_ranges:T
{
- \AdaptNote \endnote \multendnote
- \AdaptNoteMark \endnotemark
+ \bool_if:NTF \l__fnpct_keep_ranges_bool
+ { \msg_warning:nn {fnpct} {keep-ranges-hyperref} }
+ {
+ \msg_warning:nn {fnpct} {ranges-hyperref}
+ \bool_set_false:N \l__fnpct_ranges_bool
+ \keys_define:nn {fnpct}
+ { ranges .code:n = \msg_warning:nn {fnpct} {ranges-disabled} }
+ }
}
- %% the `enotez' package:
- \fnpct_treatment:nn {enotez}
- { \AdaptNote \endnote \multendnote }
- %% the `snotez' package:
- \fnpct_treatment:nn {snotez}
+ }
+ %% LaTeX's defaults:
+ \fnpct_if_class_loaded:nTF {beamer}
+ {
+ \AdaptNote \footnote{d<>o+m} [\beamer@mpfn]
{
- \AdaptNoteOpt \sidenote \multsidenote
- \AdaptNoteMark \sidenotemark
+ \IfNoValueTF{#1}
+ {\IfNoValueTF{#2}{#NOTE{#3}}{#NOTE[#2]{#3}}}
+ {\IfNoValueTF{#2}{#NOTE<#1>{#3}}{#NOTE<#1>[#2]{#3}}}
}
- %% the `parnotes' package:
- \fnpct_treatment:nn {parnotes}
- { \AdaptNote \parnote \multparnote }
- %% the `pagenote' package:
- \fnpct_treatment:nn {pagenote}
+ \AdaptNote \footnotemark {o} [\beamer@mpfn]
+ { \IfNoValueTF {#1} {#NOTE} {#NOTE[#1]} }
+ }
+ {
+ \AdaptNote \footnote {o+m} [\@mpfn]
+ { \IfNoValueTF {#1} {#NOTE{#2}} {#NOTE[#1]{#2}} }
+ \AdaptNote \footnotemark {o} [\@mpfn]
+ { \IfNoValueTF {#1} {#NOTE} {#NOTE[#1]} }
+ }
+ \fnpct_if_multiple:T { \MultVariant \footnote }
+ % TODO: should we adapt \thanks? Not with memoir, though...
+ % \AdaptNote \thanks {+m} { \cs_set_eq:NN \rlap \use:n #NOTE{#1} }
+ %% KOMA-Script and memoir:
+ \cs_if_exist:NT \footref
+ { \AdaptNote \footref {m} { #NOTE{#1} } }
+ %% snotez:
+ \fnpct_treatment:nn {snotez}
+ {
+ \AdaptNote \sidenote {d()oo+m}
{
- \bool_if:NTF \l__fnpct_makepagenote_bool
- { \AdaptNote \pagenote \multpagenote }
- { \msg_warning:nn {fnpct} {pagenote} }
+ \IfNoValueTF {#1}
+ {
+ \IfNoValueTF {#2}
+ {#NOTE{#4}}
+ { \IfNoValueTF {#3} {#NOTE[#2]{#4}} {#NOTE[#2][#3]{#4}} }
+ }
+ { \IfNoValueTF {#2} {#NOTE(#1){#4}} {#NOTE(#1)[#2]{#4}} }
}
- %% the `tablefootnote' package:
- \fnpct_treatment:nn {tablefootnote}
- { \AdaptNote \tablefootnote \multtablefootnote }
- %% the `manyfoot' package (also loaded by `bigfoot'):
- \fnpct_treatment:nn {manyfoot}
+ \AdaptNote \sidenotemark {o} [sidenote]
+ { \IfNoValueTF {#1} {#NOTE} {#NOTE[#1]} }
+ \fnpct_if_multiple:T { \MultVariant \sidenote }
+ }
+ % sidenotes:
+ \fnpct_treatment:nn {sidenotes}
+ {
+ % `sidenotes' implements its \sidenote in terms of the user
+ % commands \sidenotemark and \sidenotetext; this makes it quite
+ % difficult if not impossible to adapt its commands
+ \msg_warning:nnn {fnpct} {cannot-adapt} {sidenotes}
+ }
+ \bool_lazy_or:nnT
+ { \fnpct_if_class_loaded_p:n {tufte-handout} }
+ { \fnpct_if_class_loaded_p:n {tufte-book} }
+ {
+ \fnpct_if_ranges:TF
{
- \__fnpct_get_fnclasses:NN \MFL@list \l__fnpct_footnote_class_seq
- \seq_map_inline:Nn \l__fnpct_footnote_class_seq
+ \msg_warning:nnnn {fnpct} {cannot-adapt-with-ranges}
+ {tufte-latex}
{
- \str_if_eq:nnTF {#1} {default}
- {
- \cs_if_exist:NT \footnotedefault
- {
- \fnpct_renew_and_mult:ccc {footnote#1}
- {fnpct_orig_footnote#1:w}
- {multfootnote#1}
- \fnpct_renew_mark:cc {footnotemark#1}
- {fnpct_orig_footnotemark#1:w}
- }
- }
- {
- \fnpct_renew_and_mult:ccc {footnote#1}
- {fnpct_orig_footnote#1:w}
- {multfootnote#1}
- \fnpct_renew_mark:cc {footnotemark#1}
- {fnpct_orig_footnotemark#1:w}
- }
+ The~ command~ \sidenote~ misses~ a~ suitable~ \sidenotetext~
+ version.
}
}
- %% the `bigfoot' package:
- \fnpct_special_treatment:nn {bigfoot}
{
- \cs_if_exist:NT \footnotedefault
+ \AdaptNote \sidenote {oo+m} [\@mpfn]
{
- % re-set basics:
- \cs_set_eq:NN \footnote \footnotedefault
- \cs_set_eq:NN \footnotemark \footnotemarkdefault
- \cs_set_eq:NN \multfootnote \multfootnotedefault
+ \IfNoValueTF {#1}
+ {#NOTE{#3}}
+ { \IfNoValueTF {#2} {#NOTE[#1]{#3}} {#NOTE[#1][#2]{#3}} }
}
}
- %% the `fixfoot' package:
- \fnpct_treatment:nn {fixfoot}
+ }
+ %% endnotes:
+ \fnpct_treatment:nn {endnotes}
+ {
+ \AdaptNote \endnote {o+m}
+ { \IfNoValueTF {#1} {#NOTE{#2}} {#NOTE[#1]{#2}} }
+ \AdaptNote \endnotemark {o} [endnote]
+ { \IfNoValueTF {#1} {#NOTE} {#NOTE[#1]} }
+ \fnpct_if_multiple:T { \MultVariant \endnote }
+ }
+ % enotez:
+ \fnpct_treatment:nn {enotez}
+ {
+ \AdaptNote \endnote {o+m} { \IfNoValueTF {#1} {#NOTE{#2}} {#NOTE[#1]{#2}} }
+ \AdaptNote \endnotemark {o} [endnote] { \IfNoValueTF {#1} {#NOTE} {#NOTE{#1}} }
+ \fnpct_if_multiple:T { \MultVariant \endnote }
+ \hook_gput_code:nnn {fnpct/rangesetup} {enotez}
{
- \prop_map_inline:Nn \l__fnpct_footnote_fixfoot_prop
- { \fnpct_renew_no_arg:cc {#2} {fnpct_orig_fix_#2:w} }
+ \fnpct_if_current:NT \endnote
+ { \int_gincr:N \g__enotez_endnote_id_int }
}
- %% the `sepfootnotes' package:
- \fnpct_treatment:nn {sepfootnotes}
+ }
+ %% manyfoot/bigfoot
+ \fnpct_treatment:nn {manyfoot}
+ {
+ \__fnpct_get_fnclasses:NN \MFL@list \l__fnpct_footnote_class_seq
+ \seq_map_inline:Nn \l__fnpct_footnote_class_seq
{
- \prop_map_inline:Nn \l__fnpct_sepfootnote_foot_classes_prop
+ \str_if_eq:nnTF {#1} {default}
{
- \fnpct_renew_and_mult_no_opt:ccc {#2note}
- {fnpct_orig_sep_#2:w} {#2multnote}
- \fnpct_renew_and_mult_no_opt:ccc {#2quicknote}
- {fnpct_orig_sep_#2_quick:w} {#2multquicknote}
- \fnpct_renew_no_opt:cc {#2notemark} {fnpct_orig_sep_#2_mark:w}
+ \cs_if_exist:NT \footnotedefault
+ {
+ \AdaptNoteName {footnote#1} {o+m}
+ { \IfNoValueTF {##1} {##NOTE{##2}} {##NOTE[##1]{##2}} }
+ \AdaptNoteName {footnotemark#1} {o} [footnote#1]
+ { \IfNoValueTF {##1} {##NOTE} {##NOTE[##1]} }
+ \fnpct_if_multiple:T { \MultVariantName {footnote#1} }
+ }
}
- \prop_map_inline:Nn \l__fnpct_sepfootnote_end_classes_prop
{
- \fnpct_renew_and_mult_no_opt:ccc {#2note}
- {fnpct_orig_sep_#2:w} {#2multnote}
- \fnpct_renew_no_opt:cc {#2notemark} {fnpct_orig_sep_#2_mark:w}
+ \AdaptNoteName {footnote#1} {o+m}
+ { \IfNoValueTF {##1} {##NOTE{##2}} {##NOTE[##1]{##2}} }
+ \AdaptNoteName {footnotemark#1} {o} [footnote#1]
+ { \IfNoValueTF {##1} {##NOTE} {##NOTE[##1]} }
+ \fnpct_if_multiple:T { \MultVariantName {footnote#1} }
}
}
}
- }
-
-% `bigfoot' package
-% \fnpct_special_treatment:nn {fixfoot}
-% {
-% \bool_if:NT \l__fnpct_bigfoot_default_top_bool
-% { \DeclareNewFootnote {default} }
-% }
-
-% `fixfoot' package
-\fnpct_special_treatment:nn {fixfoot}
- {
- % hook into \DeclareFixedFootnote so we can redefine all footnote
- % classes defined be users
- \cs_new_eq:NN \fnpct_new_fixnote:w \DeclareFixedFootnote
- \RenewDocumentCommand \DeclareFixedFootnote {smm}
+ %% fixfoot
+ \fnpct_treatment:nn {fixfoot}
{
- \prop_put:Nnx \l__fnpct_footnote_fixfoot_prop {#2}
- { \cs_to_str:N #2 }
- \IfBooleanTF {#1}
- { \fnpct_new_fixnote:w * {#2} {#3} }
- { \fnpct_new_fixnote:w {#2} {#3} }
+ \fnpct_if_ranges:TF
+ {
+ \msg_warning:nnnn {fnpct} {cannot-adapt-with-ranges}
+ {fixfoot}
+ {
+ There~ cannot~ be~ suitable~ \..text~ versions~ for~ the~
+ fixed~ notes.
+ }
+ }
+ {
+ \seq_map_inline:Nn \l__fnpct_footnote_fixfoot_seq
+ { \AdaptNote #1 {} { ##NOTE } }
+ }
}
- }
-
-% `pagenote' package:
-\fnpct_special_treatment:nn {pagenote}
- {
- \tl_put_left:Nn \makepagenote
- { \bool_set_true:N \l__fnpct_makepagenote_bool }
- }
-
-% `sepfootnotes' package:
-\fnpct_special_treatment:nn {sepfootnotes}
- {
- \cs_new_eq:NN \fnpct_orig_new_footnotes:w \newfootnotes
- \cs_new_eq:NN \fnpct_orig_new_endnotes:n \newendnotes
- \cs_new_eq:NN \fnpct_orig_new_symbolnotes:w \newsymbolfootnotes
- \RenewDocumentCommand \newfootnotes {sm}
+ %% pagenote
+ \fnpct_treatment:nn {pagenote}
{
- \prop_put:Nnn \l__fnpct_sepfootnote_foot_classes_prop {#2} {#2}
- \IfBooleanTF {#1}
- { \fnpct_orig_new_footnotes:w * {#2} }
- { \fnpct_orig_new_footnotes:w {#2} }
+ \fnpct_if_ranges:TF
+ {
+ \msg_warning:nnnn {fnpct} {cannot-adapt-with-ranges}
+ {pagenote}
+ {
+ The~ command~ \pagenote~ misses~ a~ suitable~ \pagenotetext~
+ version.
+ }
+ }
+ {
+ \bool_if:NTF \l__fnpct_makepagenote_bool
+ {
+ \AdaptNote \pagenote {o+m}
+ { \IfNoValueTF {#1} {#NOTE{#2}} {#NOTE[#1]{#2}} }
+ \fnpct_if_multiple:T { \MultVariant \pagenote }
+ }
+ { \msg_warning:nn {fnpct} {pagenote} }
+ }
}
- \RenewDocumentCommand \newendnotes {m}
+ %% parnotes
+ \fnpct_treatment:nn {parnotes}
{
- \prop_put:Nnn \l__fnpct_sepfootnote_end_classes_prop {#1} {#1}
- \fnpct_orig_new_endnotes:n {#1}
+ \fnpct_if_ranges:TF
+ {
+ \msg_warning:nnnn {fnpct} {cannot-adapt-with-ranges}
+ {parnotes}
+ {
+ The~ command~ \parnote~ misses~ a~ suitable~ \parnotetext~
+ version.
+ }
+ }
+ {
+ \AdaptNote \parnote {o+m}
+ { \IfNoValueTF {#1} {#NOTE{#2}} {#NOTE[#1]{#2}} }
+ \fnpct_if_multiple:T { \MultVariant \parnote }
+ }
}
- \RenewDocumentCommand \newsymbolfootnotes {om}
+ %% tablefootnote
+ \fnpct_treatment:nn {tablefootnote}
{
- \prop_put:Nnn \l__fnpct_sepfootnote_symbol_classes_prop {#2} {#2}
- \IfNoValueTF {#1}
- { \fnpct_orig_new_symbolnotes:w {#2} }
- { \fnpct_orig_new_symbolnotes:w [#1] {#2} }
+ \fnpct_if_ranges:TF
+ {
+ \msg_warning:nnnn {fnpct} {cannot-adapt-with-ranges}
+ {tablefootnote}
+ {
+ The~ command~ \tablefootnote~ misses~ a~ suitable~
+ \tablefootnotetext~ version.
+ }
+ }
+ {
+ \AdaptNote \tablefootnote {o+m} [footnote]
+ { \IfNoValueTF {#1} {#NOTE{#2}} {#NOTE[#1]{#2}} }
+ }
}
- }
-
-% --------------------------------------------------------------------------
-\RequirePackage{translations}
-\AtBeginDocument{
- \ifcurrentbaselanguage{French}
+ %% sepfootnotes
+ \fnpct_treatment:nn {sepfootnotes}
{
- \AfterBeginDocument{
- \cs_if_exist:NT \@footnotemarkORI
+ \cs_set:Nn \__fnpct_sep_mark:n {\footnotemark}
+ \seq_map_inline:Nn \l__fnpct_sepfootnotes_seq
{
- \let\@footnotemark\@footnotemarkORI
- \setfnpct{
- before-footnote-space =
- \l__fnpct_french_before_footnote_space_dim
- }
+ \cs_if_eq:cNTF {#1notemark} \__fnpct_sep_mark:n
+ {% defined with \newfootnotes
+ \AdaptNoteName {#1note} {m} [\@mpfn] {##NOTE{##1}}
+ }
+ {% defined with \newfootnotes* or \newendnotes
+ \AdaptNoteName {#1note} {m} {##NOTE{##1}}
+ \hook_gput_code:nnn {fnpct/rangesetup} {sepfootnotes}
+ {
+ \fnpct_if_current:cT {#1note}
+ {
+ \addtocounter {#1note} {-1}
+ \sep@refstepcounter {#1note}
+ }
+ }
+ }
+ \AdaptNoteName {#1notemark} {m} {##NOTE{##1}}
+ \AdaptNoteName {#1quicknote} {m} {##NOTE{##1}}
+ \fnpct_if_multiple:T { \MultVariantName {#1note} }
+ \fnpct_if_multiple:T { \MultVariantName {#1quicknote} }
}
}
- }{}
-}
+ }
+\file_input_stop:
% --------------------------------------------------------------------------
-% SETUP COMMAND:
-\NewDocumentCommand \setfnpct {m}
- { \keys_set:nn {fnpct} {#1} }
-
-\file_input_stop:
+% OTHER PACKAGES:
+# should just work:
+footnpag
+ednotes
+yafoot
+
+# cannot be adapted for the time being:
+sidenotes
+
+# works:
+endnotes
+snotez
+footmisc
+footnote (not the environment)
+manyfoot
+bigfoot
+enotez
+sepfootnotes
+
+# works, but not with ranges:
+fixfoot
+pagenote
+parnotes
+tablefootnote
% --------------------------------------------------------------------------
% HISTORY:
-2012/05/18 v0.1alpha - various changes still possible without announcement
- until declared `v0.1'
-2012/05/19 v0.1beta - considered ready for public use, needs feedback, though
-2012/05/20 v0.1beta-a - minor changes
-2012/05/20 v0.1beta-b - added `pagenote' support
- - added `tablefootnote' support
-2012/05/20 v0.1beta-c - optional star argument to \multfootnote that only invokes
- \footnotetext
- - option `dont-mess-around': disable switching and kerning
-2012/05/21 v0.1beta-d - \innernote for nesting
- - `hyperref' support
- - bugfix in \multfootnote
-2012/05/21 v0.1beta-e - `sepfootnotes' support
-2012/05/22 v0.1beta-f - reorganized code
-2012/05/22 v0.1 - a bit more cleaning up of the code
- - completed documentation
- - ready for CTAN
+2012/05/22 v0.1 - ready for CTAN
2012/05/23 v0.1a - \AdaptNoteNoMult, \AdaptNoteOpt, \AdaptNoteOptNoMult
- support `sidenotes' package
- better support for citing commands
@@ -1212,9 +1393,11 @@
2019/10/05 v0.5 - fix issue 18
- remove option `bigfoot-default-top'
- support `manyfoot' package
-
-% --------------------------------------------------------------------------
-% NOTES:
-- `footnote' package => not compatible
-- `ednotes' package => not tested; who knows?
-- `sidenotes' package => mot easily patchable, see pull request #1
+2020/01/12 v0.5a - support `snotez' with `dblrg=false'
+2021/01/21 v1.0 - new implementation:
+ * support footnote ranges when possible
+ * support more packages
+ * more flexible way to adapt unknown note commands
+ with less commands
+ * drop support of \innernote (maybe re-implement it in
+ future versions, depending on user feedback)
diff --git a/macros/latex/contrib/fnpct/fnpct_en.pdf b/macros/latex/contrib/fnpct/fnpct_en.pdf
deleted file mode 100644
index 7ce6a35d4a..0000000000
--- a/macros/latex/contrib/fnpct/fnpct_en.pdf
+++ /dev/null
Binary files differ
diff --git a/macros/latex/contrib/fnpct/fnpct_en.tex b/macros/latex/contrib/fnpct/fnpct_en.tex
deleted file mode 100644
index e84a68f15e..0000000000
--- a/macros/latex/contrib/fnpct/fnpct_en.tex
+++ /dev/null
@@ -1,1044 +0,0 @@
-% arara: pdflatex: { shell: on , interaction: nonstopmode }
-% !arara: biber
-% !arara: pdflatex
-% !arara: pdflatex
-% --------------------------------------------------------------------------
-% the FNPCT package
-%
-% footnote kerning
-%
-% --------------------------------------------------------------------------
-% Clemens Niederberger
-% Web: https://bitbucket.org/cgnieder/fnpct/
-% E-Mail: contact@mychemistry.eu
-% --------------------------------------------------------------------------
-% Copyright 2012--2019 Clemens Niederberger
-%
-% This work 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 has the LPPL maintenance status `maintained'.
-%
-% The Current Maintainer of this work is Clemens Niederberger.
-% --------------------------------------------------------------------------
-% If you have any ideas, questions, suggestions or bugs to report, please
-% feel free to contact me.
-% --------------------------------------------------------------------------
-% the package is inspired by the following question on TeX.SE:
-% http://tex.stackexchange.com/q/56094/5049
-% --------------------------------------------------------------------------
-\documentclass[load-preamble+]{cnltx-doc}
-\usepackage{sepfootnotes,fnpct}
-\setcnltx{
- package = fnpct ,
- authors = Clemens Niederberger ,
- email = contact@mychemistry.eu ,
- url = https://bitbucket.org/cgnieder/fnpct/ ,
- abstract = {
- The \fnpct\ package basically does two things to footnotes: if footnote
- marks are followed by a punctuation mark the order of footnote and
- punctuation mark is reversed and the kerning gets adjusted. As a side
- effect a new method of creating multiple footnotes and some other
- features are provided.%
- },
- add-cmds = {
- AdaptNote,
- AdaptNoteMark,
- innernote,
- kfc,
- kfp,
- multfootnote,
- setfnpct,
- writeinnernotes
- } ,
- add-silent-cmds = {
- anote,
- anotecontent,
- arabic,
- DeclareNewFootnote,
- endnote,
- footnoteB,
- multendnote,
- multfootcite,
- multparnote,
- multsidenote,
- myfn,
- newfootnotes,
- parnote,
- parnotes,
- sidenote,
- theendnotes,
- thempfootnote,
- },
- makeindex-setup = {options={-s cnltx.ist},columns=3,columnsep=1em} ,
- index-setup = {othercode=\footnotesize,level=\addsec}
-}
-
-\defbibheading{bibliography}[\bibname]{\addsec{#1}}
-
-\usepackage{array,booktabs}
-
-\setfnpct{multiple,add-punct-marks=:[0pt][-.05em]}
-
-\usepackage{endnotes}
-\usepackage{parnotes}
-
-\newfootnotes{a}
-
-\renewcommand\thempfootnote{\arabic{mpfootnote}}
-
-\addbibresource{\jobname.bib}
-\addbibresource{biblatex-examples.bib}
-\usepackage{filecontents}
-\begin{filecontents*}{\jobname.bib}
-@book{bringhurst04,
- title = {The Elements of Typographic Style},
- author = {Robert Bringhurst},
- year = {2004},
- version = {3.2},
- isbn = {978-0-88179-205-5},
- publisher = {Hartley \&\ Marks, Canada}
-}
-\end{filecontents*}
-
-\AdaptNoteOpt\footcite\multfootcite
-
-\newname\bringhurst{Robert Bringhurst}
-\newname\lefloch{Bruno Le Floch}
-
-\begin{document}
-
-\section{License and Requirements}
-\license\
-
-\fnpct\ depends on the packages \bnd{l3kernel}~\cite{bnd:l3kernel},
-\pkg{xparse} and \pkg{l3keys2e} from the \bnd{l3packages}
-bundle~\cite{bnd:l3packages}, \pkg{scrlfile} from the \KOMAScript\
-bundle~\cite{bnd:koma-script}, and \pkg{translations}~\cite{pkg:translations}.
-
-\section{What's it all about?}
-\subsection{Introduction}
-The purpose of this package is to offer kerning for footnote marks, \ie\ the
-superscripts. This is not appropriate for all superscripts. Symbols must be
-handled differently than numbers. And of course the amount depends on the
-chosen font. \bringhurst\ says in \citetitle{bringhurst04}:
-
-\begin{cnltxquote}[\emph{\citetitle{bringhurst04}} \cite{bringhurst04}]
- Superscripts frequently come at the ends of phrases or sentences. If they
- are high above the line, they can be kerned over a comma or period, but this
- may endanger readability, especially if the text is set in a modest size.
-\end{cnltxquote}
-
-\fnpct\ can not make these decisions for you. It sets some initial values for
-the comma and the full stop which looked good to me with the tested fonts.
-Additionally it kerns the superscripts away from words when it follows
-directly. The amounts of the kerning can be changed using an option.
-
-As a side effect \fnpct\ switches the order of the superscript and the
-following comma or full stop. Additional punctuation marks can be added to
-the switching behaviour and the amount of kerning can be set for each
-punctuation mark individually.
-
-\subsection{Basics}
-The \fnpct\ package basically does two things to footnotes: if footnote marks
-are followed by a comma or a full stop\footnote{More punctuation marks can be
- added through a package option.} the order of footnote and punctuation mark
-is reversed and the kerning gets adjusted. As a side effect a new method of
-creating multiple footnotes\footnote{like;this} is provided, see
-section~\ref{sec:multiple} for details.
-
-In what way is the kerning adjusted? After being placed behind the
-punctuation mark the footnote mark is moved a little bit back, namely by the
-amount specified with the option \option{after-punct-space} (see
-section~\ref{sec:options}). If the footnote mark follows a word
-\emph{without} being followed by a punctuation\footnote{Well, it does not
- necessarily have to follow a \emph{word}. The important point is \emph{not
- being followed} by a punctuation mark.}, there (obviously) is no order
-switching and a little space is inserted before the footnote mark, namely the
-amount specified by the option \option{before-footnote-space} (see
-section~\ref{sec:options}).
-
-\begin{sourcecode}
- \renewcommand\thempfootnote{\arabic{mpfootnote}}
-\end{sourcecode}
-
-Now, let's see some action:
-\begin{example}
- \begin{minipage}{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably fired clay bricks}.
- \end{minipage}
-\end{example}
-
-To ensure that the kerning is set the right way the footnote \emph{must} be
-placed \emph{before} the full stop or the comma. \emph{The command can look
- ahead but not look back}. This means if you place the \cs{footnote} command
-after a full stop or a comma it is treated as if following a word, \ie\ a thin
-space is inserted: effectively the opposite of the desired behaviour.
-
-The order-switching can be prevented using a package option since not all
-countries and languages have the same typographic conventions. In this case
-the full stop and the comma are moved a bit back.
-
-\begin{figure}[ht]
- \centering
- \begin{tabular}{>{\setfnpct{dont-mess-around}}ll}
- \toprule
- without \fnpct &
- with \fnpct \\
- \midrule
- \strut\quad text.\footnotemark[1] &
- \strut\quad text\footnotemark[1]. \\
- \strut\quad text\footnotemark[1]. &
- \setfnpct{punct-after}\strut\quad text\footnotemark[1]. \\
- \strut\quad text\footnotemark[1] &
- \strut\quad text\footnotemark[1] \\
- \bottomrule
- \end{tabular}
- \caption{The effect of \fnpct.}
-\end{figure}
-
-\begin{options}
- \keybool{punct-after}\Default{false}
- When \code{true} the punctuation sign will be placed \emph{after} the
- footnote.
-\end{options}
-Like all options it can also be set using the setup command.
-\begin{commands}
- \command{setfnpct}[\marg{options}]
- Set up options. Can be used anywhere in the document. Some options can
- only be set in the preamble, though.
-\end{commands}
-\begin{example}
- \setfnpct{punct-after}
- \begin{minipage}{\linewidth}
- \noindent The three little pigs built
- their houses out of straw\footnote{not
- to be confused with hay}, sticks%
- \footnote{or lumber according to some
- sources} and bricks\footnote{probably
- fired clay bricks}.
- \end{minipage}
-\end{example}
-
-\subsection{Temporarily disable or enable switching}
-One maybe want to put some footnote marks \emph{before} the punctuation and
-some after, for example because the first one describes a single word but the
-second one a whole sentence. For this purpose \fnpct\ adds a \sarg\ argument
-to \cs{footnote} and \cs{footnotemark}. The complete new syntax now is as
-follows:
-\begin{commands}
- \command{footnote}[\sarg\oarg{num>}\marg{footnote text}\meta{tpunct}]
- new \sarg\ argument added. \meta{tpunct} is the optional trailing
- punctuation mark.
- \command{footnotemark}[\sarg\oarg{num>}\meta{tpunct}]
- new \sarg\ argument added. \meta{tpunct} is the optional trailing
- punctuation mark.
-\end{commands}
-The \sarg\ argument temporarily turns off the punctuation/footnote switching.
-In case you set \keyis{punct-after}{true} the \sarg\ argument temporarily
-\emph{enables} the switching.
-\begin{example}
- \begin{minipage}{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote*{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably fired clay bricks}.
- \end{minipage}\hfil
- \setfnpct{punct-after}
- \begin{minipage}{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote*{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably fired clay bricks}.
- \end{minipage}
-\end{example}
-
-\subsection{Language Specific Settings}
-Package \pkg{babel}'s~\cite{pkg:babel} French settings redefine
-\cs*{@footnotemark}. \fnpct\ resets this redefinition but sets the
-\option{before-footnote-space} equal to a thin space (\code{.16667em}).
-
-\subsection{Changes in v0.5}\label{ssec:news}
-
-\begin{itemize}
- \item the option \option{bigfoot-default-top} has been removed
- \item the \pkg{manyfoot} package is now supported
-\end{itemize}
-
-\section{Options}\label{sec:options}
-Most package options are listed below. They all can be set as a package
-option or with the \cs{setfnpct} command. Most of them are for adjusting the
-kerning.
-
-\default{Underlined} values are set if the option is used without value.
-\begin{options}
- \keychoice{add-punct-marks}{\meta{mark}\oarg{space after}\oarg{space before}}
- Add another punctuation mark for the position switching and spacify
- kerning if necessary. An existing entry will be overwritten. This option
- accepts a list of marks.
- %
- \keyval{remove-punct-marks}{mark}
- Remove punctuation mark from the kerning/position switching behaviour.
- This option accepts a list of marks.
- %
- \keyval{after-dot-space}{dim}\Default{-.06em}
- Space to be inserted after a footnote mark and before the full stop
- (``footnote \emph{after} dot''). A negative space will move the full stop
- further to the footnote mark.
- %
- \keyval{after-comma-space}{dim}\Default{-.06em}
- Space to be inserted after a footnote mark and before the comma
- (``footnote \emph{after} comma''). A negative space will move the comma
- further to the footnote mark.
- %
- \keyval{after-punct-space}{dim}
- Set \emph{all} spaces, \ie\ also the ones for marks you've added with
- \option{add-punct-marks}.
- %
- \keybool{punct-after}\Default{false}
- When \code{true} the punctuation sign will be placed \emph{after} the
- footnote.
- %
- \keyval{before-dot-space}{dim}\Default{-.16em}
- Space to be inserted after a footnote mark and before the full stop
- (``footnote \emph{before} dot''), \ie\ with \keyis{punct-after}{true}.
- %
- \keyval{before-comma-space}{dim}\Default{-.16em}
- space to be inserted after a footnote mark and before the comma
- (``footnote \emph{before} comma''), \ie\ with \keyis{punct-after}{true}.
- %
- \keyval{before-punct-space}{dim}
- Set \emph{all} spaces, \ie\ also the ones for marks you've added with
- \option{add-punct-marks}.
- %
- \keyval{before-footnote-space}{dim}\Default{.06em}
- Space to be inserted between a word and the following footnote mark.
- %
- \keybool{dont-mess-around}\Default{false}
- Sets all mentioned lengths to \code{0pt} and \keyis{punct-after}{true}.
- Basically this should look like as if you hadn't loaded \fnpct\ except the
- multiple footnote commands and \cs{innernote} are still available, see
- sections~\ref{sec:multiple} and~\ref{sec:nested}, respectively.
- %
- \keybool{multiple}\Default{false}
- Lets \cs{footnote} be equal to \cs{multfootnote}.
- %
- \keyval{mult-fn-delim}{delimiter}\Default{;}
- Sets the delimiter for the \cs{multfootnote} command.
- %
- \keyval{mult-fn-sep}{separator}\Default{,}
- Sets the separator between multiple footnote marks.
- %
- \keybool{normal-marks}\Default{false}\label{opt:normal-marks}
- Sets the footnote marks in the foot not as superscripts but as normal
- font. If you're not using a \KOMAScript\ class this option will load
- the package \pkg{scrextend}. See section~\ref{sec:normal} for more
- information. \emph{This option can only be set in the preamble}.
-\end{options}
-
-So if you want to extend the punctuation switching and kerning to other punctuation
-marks you can do something like this:
-\begin{example}
- \setfnpct{add-punct-marks=!?}
- \begin{minipage}{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay}?
- Sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably fired clay bricks}!
- \end{minipage}
-\end{example}
-
-Or with some additional spacing:
-\begin{example}
- \setfnpct{add-punct-marks=![.03em]?[.03em]}
- \begin{minipage}{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay}?
- Sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably fired clay bricks}!
- \end{minipage}
-\end{example}
-
-Let's take a look at an example with some ridiculous settings:
-\begin{example}
- % some ridiculous settings:
- \setfnpct{after-punct-space=2pt,before-footnote-space=2pt}
- \begin{minipage}{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably fired clay bricks}.
- \end{minipage}
-\end{example}
-
-And now the same with switched order:
-\begin{example}
- % some ridiculous settings:
- \setfnpct{punct-after,before-punct-space=2pt,before-footnote-space=2pt}
- \begin{minipage}{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably fired clay bricks}.
- \end{minipage}
-\end{example}
-
-In case the automatic kerning doesn't work for whatever reason the spaces are
-available as user commands as well:
-\begin{commands}
- \command{kfp}
- Insert \option{after-dot-space} or (if \keyis{punct-after}{true})
- \option{before-dot-space}.
- \command{kfc}
- Insert \option{after-comma-space} or (if \keyis{punct-after}{true})
- \option{before-comma-space}.
-\end{commands}
-
-Some of the options are explained in a bit more detail in the next sections.
-
-\section{Multiple footnotes}\label{sec:multiple}
-\subsection{Basics}
-Since multiple footnotes have to be treated differently\footnote{see these
- footnotes;for an example}, \fnpct\ provides an extra command for that:
-\begin{commands}
- \command{multfootnote}[\sarg\Marg{\meta{list};\meta{of};\meta{footnotes}}\meta{tpunct}]
- Different footnotes are separated with a semicolon. The \sarg\ turns the
- footnote/punctuation switching temporarily off.
-\end{commands}
-\begin{example}
- \begin{minipage}{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\multfootnote{probably fired clay bricks;or
- something else}.
- \end{minipage}
-\end{example}
-
-Every of the items of the list has an optional argument equivalent to the
-optional argument of \cs{footnotetext}:
-\begin{commands}
- \command{multfootnote}[\Marg{\sarg\oarg{mark}\meta{footnote text};\ldots}]
- The syntax of \cs{multfootnote}'s footnote text argument.
-\end{commands}
-\begin{example}
- \begin{minipage}{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\multfootnote{probably fired clay bricks;[5]or
- something else}.
- \end{minipage}
-\end{example}
-
-Additionally every item has an optional \sarg\ which only invokes
-\cs{footnotetext}. This enables for example to set nested footnotes without
-disrupting the multiple setting. The following example is shown in
-figure~\ref{fig:nested:mult}:
-\begin{example}[compile,float,caption={Nested footnotes.\label{fig:nested:mult}}]
- \documentclass{article}
- \usepackage[
- paperwidth=.5\textwidth,
- paperheight=12\baselineskip,
- margin=5pt,
- bottom=1.5cm]{geometry}
-
- \usepackage{fnpct}
-
- \begin{document}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\multfootnote{probably fired clay bricks%
- \footnotemark;*or something else;what do I know}.
- \end{document}
-\end{example}
-
-\subsection{The delimiter and separator}
-Since the semicolon might be part of the footnote text you might have some
-trouble. But there are ways around. Maybe try enclosing it in braces:
-\begin{example}
- \begin{minipage}{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\multfootnote{probably fired clay bricks{;}
- or something else;what do I know}.
- \end{minipage}
-\end{example}
-
-There also are options which lets you choose the (input) delimiter and the (output)
-separator:
-\begin{options}
- \keyval{mult-fn-delim}{delimiter}\Default{;}
- Choose delimiter for the \cs{multfootnote}.
- \keyval{mult-fn-sep}{separator}\Default{,}
- Choose the separator that is put between footnote marks.
-\end{options}
-\begin{example}
- \setfnpct{mult-fn-delim=//,mult-fn-sep=;}
- \begin{minipage}[t]{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\multfootnote{probably fired clay bricks;
- or something else//what do I know}.
- \end{minipage}\hfil
- \setfnpct{mult-fn-delim=;,mult-fn-sep=}
- \renewcommand*\thempfootnote{\fnsymbol{mpfootnote}}
- \begin{minipage}[t]{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\multfootnote{probably fired clay bricks;
- or something else}.
- \end{minipage}
-\end{example}
-
-\subsection{Automagic}
-If you want you can turn all footnotes into \cs{multfootnote}s.
-\begin{options}
- \keybool{multiple}\Default{false}
- Let \cs{footnote} behave like \cs{multfootnote}. \emph{This option can
- only be set in the preamble}.
-\end{options}
-\begin{example}
- % in preamble: \setfnpct{multiple}
- % or \usepackage[multiple]{fnpct}
- \begin{minipage}{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably fired clay bricks;or
- something else}.
- \end{minipage}
-\end{example}
-
-\section{Nested Footnotes}\label{sec:nested}
-\fnpct\ provides preliminary support for nested footnotes. There are some
-restrictions, though. The command below can be used inside \cs{footnote} and
-\cs{multfootnote}, but not inside another \cs{innernote}. \cs{innernote}
-really is a ``inner footnote'', it doesn't work with endnotes, for example.
-\begin{commands}
- \command{innernote}[\sarg\oarg{mark}\marg{text}\meta{tpunct}]
- A nested footnote.
-\end{commands}
-The inner node uses a \cs{footnotemark} internally and the mark will be set
-with the definition it has at begin document.
-
-The output of the following code can be seen in figure~\ref{fig:nested:a}.
-\begin{example}[compile,float,caption={\cs*{innernote} example (a)\label{fig:nested:a}}]
- \documentclass{article}
- \usepackage[
- paperwidth=.5\textwidth,
- paperheight=12\baselineskip,
- margin=5pt,
- bottom=1.5cm]{geometry}
-
- \usepackage{fnpct}
-
- \begin{document}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably fired clay bricks%
- \innernote{or not}}.
- \end{document}
-\end{example}
-
-This is especially useful if you have more than one additional footnote inside
-a footnote, a case that can't be solved in a satisfying (\ie\ automatic) way
-with the method mentioned in section~\ref{sec:multiple}. See
-figure~\ref{fig:nested:b} for the output of this code:
-\begin{example}[compile,float,caption={\cs*{innernote} example (b)\label{fig:nested:b}}]
- \documentclass{article}
- \usepackage[
- paperwidth=.5\textwidth,
- paperheight=12\baselineskip,
- margin=5pt,
- bottom=1.5cm]{geometry}
-
- \usepackage{fnpct}
-
- \begin{document}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably\innernote{just guessing}
- fired clay bricks\innernote{or not}}.
- \end{document}
-\end{example}
-
-\cs{innernote} can also be used to escape minipages. In this case use
-\cs{innernote} as a replacement for \cs{footnote} and call this command later:
-\begin{commands}
- \command{writeinnernotes}
- Writes all \cs{footnotetext}s to the inner footnotes when invoked. This
- is usually done automatically by the \cs{footnote} command but there are
- possible needs for it.
-\end{commands}
-See figure~\ref{fig:nested:c} for the output of the following code:
-\begin{example}[compile,float,caption={\cs*{innernote} example (c)\label{fig:nested:c}}]
- \documentclass{article}
- \usepackage[
- paperwidth=.5\textwidth,
- paperheight=12\baselineskip,
- margin=5pt,
- bottom=1.5cm]{geometry}
-
- \usepackage{fnpct}
-
- \begin{document}
- \noindent\fbox{%
- \begin{minipage}{.9\linewidth}
- The three little pigs built their houses
- out of straw\innernote{not to be confused with hay},
- sticks\innernote{or lumber according to some sources}
- and bricks\innernote{probably}.
- \end{minipage}}\writeinnernotes
- \end{document}
-\end{example}
-
-\section{Normal notes}\label{sec:normal}
-The package option \option{normal-marks} (see p.\,\pageref{opt:normal-marks})
-changes the layout of the footnote marks in the foot by using \KOMAScript's
-\cs{deffootnote} command:
-\begin{commands}
- \command{deffootnote}[\oarg{mark indent}\marg{indent}\marg{par
- indent}\marg{format code}]
- \KOMAScript's command to define the output of the footnote text in the
- foot.
-\end{commands}
-
-The following code is shown in figure~\ref{fig:normal}.
-\begin{example}[compile,float,caption={Demonstration of the
- \option*{normal-marks} option.\label{fig:normal}}]
- \documentclass{article}
- \usepackage[
- paperwidth=.5\textwidth,
- paperheight=12\baselineskip,
- margin=5pt,
- bottom=1.5cm]{geometry}
-
- \usepackage[normal-marks]{fnpct}
-
- \begin{document}
-
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably fired clay bricks}.
-
- \end{document}
-\end{example}
-
-The three indent values used by \fnpct\ can be changed with the following
-options:
-\begin{options}
- \keyval{normal-mark-width}{dim}\Default{1em}
- The width of the box within which the marks are set.
- \keyval{normal-indent}{dim}\Default{1.5em}
- The indent of each footnote line \emph{except} the first.
- \keyval{normal-par-indent}{dim}\Default{1em}
- Additional indent of a new paragraph inside the footnote text.
-\end{options}
-
-\section{Other packages}\label{sec:other:packages}
-\fnpct\ tries its best to support other footnote and related
-packages\footnote{If you find some package missing please let me know.}. Each
-of the following subsections is dedicated to one of these packages and if and
-how they work together with \fnpct. Fortunately most of them do quite well.
-
-\subsection{bigfoot and manyfoot}\label{ssec:bigfoot}
-The \pkg{bigfoot}~\cite{pkg:bigfoot} package extends the possibilities of the
-\pkg{manyfoot} package~\cite{pkg:manyfoot} (see section~\ref{ssec:manyfoot}).
-The main visible feature is to use different classes of footnotes which are
-typeset in different apparatus on the bottom of the page.
-
-\fnpct\ is compatible with \pkg{bigfoot}.
-
-You need to be a bit cautious, though: \emph{verbatim material won't work
- inside footnotes anymore}. You can of course use \lefloch's
-\pkg{cprotect}~\cite{pkg:cprotect} if you really need verbatim material in
-footnotes \emph{and} want to use \fnpct. Since \fnpct\ does not redefine any
-\cs{footnotetext} like command it will still work inside one of them.
-
-For every footnote class defined with \cs*{DeclareNewFootnote} the commands
-\cs*{footnote\meta{class}} and \cs*{footnotemark\meta{class}} are redefined
-with the starred variant and a \cs*{multfootnote\meta{class}} is defined. The
-\option{multiple} option will turn all \cs*{footnote\meta{class}} commands
-into the corresponding \cs*{multfootnote\meta{class}}.
-
-Since this document cannot easily combine \emph{every} footnote package at the
-same time for demonstration purposes the following code is shown in
-figure~\ref{fig:bigfoot}:
-\begin{example}[compile,float,caption={\pkg*{bigfoot} example\label{fig:bigfoot}}]
- \documentclass{article}
- \usepackage[
- paperwidth=.5\textwidth,
- paperheight=12\baselineskip,
- margin=5pt,
- bottom=1.5cm]{geometry}
-
- \usepackage{bigfoot}
- \usepackage{fnpct}
- \setfnpct{multiple}
- \DeclareNewFootnote{default}
- \DeclareNewFootnote[para]{B}[alph]
-
- \begin{document}
-
- \noindent The three little pigs built their houses
- out of straw\footnote*{not to be confused with hay%
- \footnoteB{let alone grass}}, sticks\footnote{or
- lumber according to some sources} and bricks%
- \footnote{probably fired clay bricks;or something}.
-
- \end{document}
-\end{example}
-
-\subsection{endnotes}
-The \pkg{endnotes}~\cite{pkg:endnotes} package povides the commands
-\cs{endnote} and \cs{endnotemark} which can be used to output all notes at the
-end of a chapter, say.
-
-If the package is loaded both commands are adapted\footnote*{see
- section~\ref{sec:adapt} on manual adaption}:
-\begin{sourcecode}
- % `fnpct' does this for you:
- \AdaptNote\endnote\multendnote
- \AdaptNoteMark\endnotemark
-\end{sourcecode}
-
-Everything else stays the same:
-\begin{example}
- \begin{minipage}[t]{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\endnote{not to be confused with hay},
- sticks\endnote{or lumber according to some sources}
- and bricks\endnote{probably fired clay bricks}.
-
- \theendnotes
- \end{minipage}\hfil
- \begin{minipage}[t]{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\endnote*{not to be confused with hay},
- sticks\endnote{or lumber according to some sources}
- and bricks\multendnote{probably fired clay bricks;or
- something else}.
-
- \theendnotes
- \end{minipage}
-\end{example}
-
-\subsection{enotez}
-The \pkg{enotez}~\cite{pkg:enotez} package povides the command \cs{endnote}
-which can be used to output all notes at the end of a chapter, say.
-
-If the package is loaded the command is adapted\footnote*{see
- section~\ref{sec:adapt} on manual adaption}:
-\begin{sourcecode}
- % `fnpct' does this for you:
- \AdaptNote\endnote\multendnote
-\end{sourcecode}
-
-\subsection{fixfoot}
-The \pkg{fixfoot}~\cite{pkg:fixfoot} package provides a possibility to create
-repeating footnotes. \fnpct\ supports this package provided you take care of
-the following:
-
-\emph{Use \cs{DeclareFixedFootnote} only in the preamble but \emph{after}
- loading \fnpct.}
-
-\cs*{DeclareFixedFootnote}\Marg{\cs*{cs}}\marg{footnote text} is used to store
-the \meta{footnote text} in \cs*{cs} which in turn creates a footnote mark for
-it but doesn't repeat the footnote text on the same page in the bottom. The
-document needs several runs to get all the numbers and footnotes right.
-
-Every fixed footnote declared with \cs{DeclareFixedFootnote} gets an optional
-\sarg\ to prevent the punctuation switching. \emph{There is \emph{no}
- mult-variant of the fixed notes!}
-
-Since this document cannot easily combine \emph{every} footnote package at the
-same time for demonstration purposes the following code is shown in
-figure~\ref{fig:fixfoot}:
-\begin{example}[compile,float,caption={\pkg*{fixfoot}
- example\label{fig:fixfoot}}]
- \documentclass{article}
- \usepackage[
- paperwidth=.55\textwidth,
- paperheight=12\baselineskip,
- margin=5pt,
- bottom=1.5cm]{geometry}
-
- \usepackage{fixfoot}
- \usepackage{fnpct}
-
- \DeclareFixedFootnote{\myfn}{I'm confused: what do I want to say?}
-
- \begin{document}
-
- \noindent The three little pigs\myfn\ built their houses
- out of straw\myfn*, sticks\footnote{or lumber according
- to some sources} and bricks\footnote{probably fired clay
- bricks}.
-
- \end{document}
-\end{example}
-
-\subsection{footmisc}\label{ssec:footmisc}
-The \pkg{footmisc} package~\cite{pkg:footmisc} provides a range of options to
-customize footnotes, for example output them as margin notes or count
-footnotes per page.
-
-Testing showed no incompatibilities with \pkg{footmisc}. The only thing is
-that you won't have to (and shouldn't) use its \option{multiple} option.
-
-\subsection{footnote}\label{ssec:footnote}
-Unfortunately \fnpct\ is not compatible with the \pkg{footnote}
-package~\cite{pkg:footnote}. Or more precisely it is not compatible if the
-command pair \cs*{savenotes}/\cs*{spewnotes} is invoked. This disables
-\pkg{footnote}'s environments as well as its environment escaping mechanism
-through \cs{makesavenoteenv}.
-
-\subsection{manyfoot}\label{ssec:manyfoot}
-The package \pkg{manyfoot}~\cite{pkg:manyfoot} is supported. See
-section~\ref{ssec:bigfoot} for more details.
-
-\subsection{pagenote}\label{ssec:pagenote}
-The package \pkg{pagenote}~\cite{pkg:pagenote} is supported and its
-\cs*{pagenote} command is treated the same way as all other note commands: it
-got an optional \sarg\ argument and an additional \cs*{multpagenote} is
-defined.
-
-\subsection{parnotes}\label{ssec:parnotes}
-The function of the package \pkg{parnotes}~\cite{pkg:parnotes} is similar to the
-\pkg{endnotes} package. basically it allows to output the footnote text after
-a paragraph, either by using a special environment or by invoking
-\cs*{parnotes}.
-
-If \pkg{parnotes} is loaded \fnpct\ extends its functionality analogous to the
-one of \pkg{endnotes}.
-
-Again the \option{multiple} option turns all \cs*{parnote}s into
-\cs*{multparnote}s.
-\begin{example}
- \begin{minipage}[t]{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\parnote{not to be confused with hay},
- sticks\parnote{or lumber according to some sources}
- and bricks\parnote{probably fired clay bricks}.
-
- \parnotes
- \end{minipage}\hfil
- \begin{minipage}[t]{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\parnote*{not to be confused with hay},
- sticks\parnote{or lumber according to some sources}
- and bricks\multparnote{probably fired clay bricks;or
- something else}.
-
- \parnotes
- \end{minipage}
-\end{example}
-
-\subsection{sepfootnotes}\label{ssec:sepfootnotes}
-\fnpct\ supports the \pkg{sepfootnotes} package~\cite{pkg:sepfootnotes}. Each
-note type you have created with with one of the commands
-\begin{description}
- \item \cs*{newfootnotes}\marg{prefix},
- \item \cs*{newendnotes}\marg{prefix} or
- \item \cs*{newsymbolfootnotes}\marg{prefix}
-\end{description}
-gets the additional optional \sarg\ to prevent punctuation switching. Also
-the corresponding mult-variant \cs*{\meta{prefix}multnote} is defined. The
-option \option{multiple} again turns all note commands into their
-mult-variant.
-
-You have to use the \cs*{newfootnotes} commands in the document preamble after
-loading \fnpct.
-
-\begin{example}
- % preamble \newfootnotes{a}
- \anotecontent{first}{not to be confused with hay}
- \anotecontent{second}{or lumber according to some sources}
- \anotecontent{third}{probably fired clay bricks}
- \begin{minipage}{.4\linewidth}
- \noindent The three little pigs built their houses
- out of straw\anote{first}, sticks\anote{second} and
- bricks\anote{third}.
- \end{minipage}
-\end{example}
-
-\subsection{sidenotes}\label{ssec:sidenotes}
-The package \pkg{sidenotes}~\cite{pkg:sidenotes} is \emph{not} supported.
-For the time being users can use the following code\footnote{Since the code
- depends on the implementation of \pkg{sidenotes} this may break with each
- update of \pkg{sidenotes}.;Thanks to Marijn van Vliet for
- providing it!}:
-\begin{sourcecode}
- \ExplSyntaxOn
- \makeatletter
- \NewDocumentCommand \origsidenotemark {o}
- {
- \@sidenotes@multichecker
- \IfNoValueOrEmptyTF {#1}
- { \@sidenotes@thesidenotemark { \thesidenote } }
- { \@sidenotes@thesidenotemark {#1} }
- \@sidenotes@multimarker
- }
-
- \NewDocumentCommand \origsidenote {oo+m}
- {
- \origsidenotemark [#1]
- \sidenotetext [#1] [#2] {#3}
- \@sidenotes@multimarker
- }
-
- \fnpct_create_mult_variant:NN \multsidenote \origsidenote
-
- \RenewDocumentCommand \sidenote {soo+m}
- { \fnpct_handle_note:Nnnnn \origsidenote {#2} {#3} {#4} {#1} }
-
- \RenewDocumentCommand \sidenotemark {so}
- { \fnpct_handle_note:Nnnnn \origsidenotemark {#2} { \q_no_value } { } {#1} }
- \makeatother
- \ExplSyntaxOff
-\end{sourcecode}
-
-\subsection{snotez}\label{ssec:snotez}
-The package \pkg{snotez}~\cite{pkg:snotez} is supported and its commands
-\cs*{sidenote} and \cs*{sidenotemark} are treated the same way as footnotes:
-they got an optional \sarg\ argument and the additional \cs*{multsidenote} is
-created. The option \option{multiple} turns all note commands into their
-mult-variant.
-
-\subsection{tablefootnote}\label{ssec:tablefootnote}
-The package \pkg{tablefootnote}~\cite{pkg:tablefootnote} is supported and its
-\cs*{tablefootnote} command is treated the same way as all other note
-commands: it got an optional \sarg\ argument and an additional
-\cs*{multtablefootnote} is defined. The option \option{multiple} turns all
-note commands into their mult-variant.
-
-\subsection{yafoot}\label{ssec:yafoot}
-Currently no issues are known when using \fnpct\ with one or all of the
-packages of the \bnd{yafoot}~\cite{bnd:yafoot} bundle. Just for reference:
-these packages are \pkg*{pfnote}, \pkg*{fnpos} and \pkg*{dblfnote}.
-
-\section{Adapting note commands}\label{sec:adapt}
-If a package is not natively supported you can try and adapt commands yourself.
-You'll need to use one of the following commands. Please be aware that if the
-adapted command does not match the required syntax it will get the required syntax
-afterwards. This can result in dummy arguments or an overwritten \code{*} argument.
-
-\begin{commands}
- % \AdaptNote
- \command{AdaptNote}[\Marg{\cs*{cs}}\Marg{\cs*{multcs}}]
- This lets \cs*{cs} adapt to the kerning behaviour and adds an optional
- \sarg. It also creates a corresponding mult-variant. The package option
- \option{multiple} will now turn \cs*{cs} into its mult-variant. Required
- syntax: \cs*{cs}\oarg{oarg}\marg{marg}
- % \AdaptNoteNoMult
- \command{AdaptNoteNoMult}[\Marg{\cs*{cs}}]
- Like \cs{AdaptNote} but doesn't create a mult-variant and thus there is no
- change in behaviour when the option \option{multiple} is used. Required
- syntax: \cs*{cs}\oarg{oarg}\marg{marg}
- % \AdaptNoteOpt
- \command{AdaptNoteOpt}[\Marg{\cs*{cs}}\Marg{\cs*{multcs}}]
- This lets \cs*{cs} adapt to the kerning behaviour and adds an optional
- \sarg. It also creates a corresponding mult-variant. The package option
- \option{multiple} will now turn \cs*{cs} into its mult-variant. Required
- syntax: \cs*{cs}\oarg{oarg}\oarg{oarg}\marg{marg}
- % \AdaptNoteOptNoMult
- \command{AdaptNoteOptNoMult}[\Marg{\cs*{cs}}]
- Like \cs{AdaptNoteOpt} but doesn't create a mult-variant and thus there is
- no change in behaviour when the option \option{multiple} is used.
- Required syntax: \cs*{cs}\oarg{oarg}\oarg{oarg}\marg{marg}
- % \AdaptNoteNoOpt
- \command{AdaptNoteNoOpt}[\Marg{\cs*{cs}}\Marg{\cs*{multcs}}]
- \sinceversion{0.3}Like \cs{AdaptNote} but requires \cs*{cs} not to have an
- optional argument. If it had one it wouldn't have it any more after the
- adaption. The package option \option{multiple} will now turn \cs*{cs}
- into its mult-variant. Required syntax: \cs*{cs}\marg{marg}
- % \AdaptNoteNoOptNoMult
- \command{AdaptNoteNoOptNoMult}[\Marg{\cs*{cs}}]
- \sinceversion{0.3}Like \cs{AdaptNoteNoOpt} but doesn't create a
- mult-variant. Required syntax: \cs*{cs}\Marg{marg}
- % \AdaptNoteMark
- \command{AdaptNoteMark}[\Marg{\cs*{cs}}]
- This lets \cs*{cs} adapt to the kerning behaviour and adds an optional
- \sarg. Required syntax: \cs*{cs}\oarg{oarg}
- % strict
-\end{commands}
-\begin{options}
- \keybool{strict}\Default{false} When \code{true}
- \cs{AdaptNote} (and the others) will issue errors if the note command in
- question has already been adapted.
-\end{options}
-
-\subsection{tufte-latex's side notes}
-For example using the \cs{sidenote} command from the \cls*{tufte-handout}
-class is easily possible, see also figure~\ref{fig:tufte}:
-\begin{example}[compile,float,caption={Adapt
- \bnd*{tufte-latex}.\label{fig:tufte}},graphics={trim=2.5cm 24.5cm 2cm
- 1cm,scale=.65}]
- \documentclass{tufte-handout}
- \usepackage[multiple]{fnpct}
- \AdaptNote\sidenote\multsidenote
- \begin{document}
- Some text in the document body\sidenote{Some
- text in a sidenote.;A second sidenote.}.
- \end{document}
-\end{example}
-
-\subsection{Adapting \cs*{footcite} and siblings}\label{ssec:adapt:footcite}
-If you're willing to sacrifice \cs*{footcite}'s \sarg\ argument (which it has
-in some styles) you can adapt the commands provided by
-\pkg{biblatex}~\cite{pkg:biblatex} as well:
-
-\begin{example}
- % used in preamble: \AdaptNoteOpt\footcite\multfootcite
- \begin{minipage}{.5\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably fired clay bricks}. The
- companion has nothing on this topic\multfootcite{[see]
- [but there's nothing there]companion;[or see][but there's
- also nothing]knuth:ct:a}.
- \end{minipage}
-\end{example}
-
-The option \option{multiple} turns all \cs*{footcite}s into
-\cs*{multfootcite}s now. Remember that the optional arguments then are inside
-the braces!
-
-\begin{example}
- % used in preamble: \AdaptNoteOpt\footcite\multfootcite
- % with option `multiple':
- \begin{minipage}{.5\linewidth}
- \noindent The three little pigs built their houses
- out of straw\footnote{not to be confused with hay},
- sticks\footnote{or lumber according to some sources}
- and bricks\footnote{probably fired clay bricks}. The
- companion has nothing on this topic\footcite{[see][but
- there's nothing there]companion;[or see][but there's also
- nothing]knuth:ct:a}.
- \end{minipage}
-\end{example}
-
-
-\appendix
-
-\end{document}
-
-% TODO: update documentation and explain what happens when babel's french is
-% used
diff --git a/support/xml2pmx/MacOS/xml2pmx b/support/xml2pmx/MacOS/xml2pmx
index 90a4de323c..18c1569b10 100755
--- a/support/xml2pmx/MacOS/xml2pmx
+++ b/support/xml2pmx/MacOS/xml2pmx
Binary files differ
diff --git a/support/xml2pmx/README b/support/xml2pmx/README
index 6cb7b5249a..538e03dced 100644
--- a/support/xml2pmx/README
+++ b/support/xml2pmx/README
@@ -1,4 +1,4 @@
-xml2pmx, version 2020-08-12.
+xml2pmx, version 2021-01-23.
Summary: xml2pmx translates MusicXML into PMX notation.
@@ -12,10 +12,11 @@ is an easy to use, yet powerful preprocessor
for the music typesetting system MusiXTeX.
http://icking-music-archive.org/software/htdocs/
-xml2pmx has been developed by Dieter
-Gloetzel with the "Oberon Plugin for Windows
-Version 2.5" of ETHZ Zurich on Windows 10.
+xml2pmx has been developed by Dieter Gloetzel with the "Oberon Plugin
+for Windows Version 2.5" of ETHZ Zurich on Windows 10
https://github.com/Spirit-of-Oberon/ETH-Oberon-PlugIn-Win32
+and OLR (Oberon Linux Revival)
+http://oberon.wikidot.com/oberon-linux-revival-olr
Coverage of MusicXML by xml2pmx
*******************************
@@ -23,21 +24,25 @@ Coverage of MusicXML by xml2pmx
The following MusicXML features are detected and translated
to PMX:
-- maximum of 24 staves/voices and 400 measures
-- two voices per staff
-- maximum of two staves per instrument
-- notes and rests up to 64th, including tuplets and grace notes,
-- maximum of 2 dots
-- chords, accidentals
-- some annotations like Fermata, Staccato, Tremolo etc.
-- ties, slurs and beams
-- definition of meter, fifths, clefs and their changes on the fly
-- dynamic marks: hairpins, "ff" etc., piano damping pedal
-- title and composer, and texts above or below the staff
-- barlines, repeats, volta
-- instrument names,
-- origin of XML file copied to the resulting PMX file
-- accepts Windows files (records ended by 0DX OAX)
+The following MusicXML features are detected and translated to PMX:
+
+ - up to 24 staves/voices and 600 bars
+ - up to 83 notes per instrument and bar
+ - two voices per staff
+ - maximum of two staves per instrument
+ - notes and rests up to 64th, including tuplets and grace notes,
+ - maximum of 2 dots
+ - chords, accidentals
+ - some annotations like Fermata, Staccato, Tremolo etc.
+ - ties, slurs and beams
+ - definition of meter, fifths, clefs and their changes on the fly
+ - dynamic marks: hairpins, "ff" etc., piano damping pedal
+ - title and composer, and texts above or below the staff
+ - barlines, repeats, volta
+ - instrument names
+
+Windows and Unix line terminations are accepted. UTF-16
+input is not accepted.
This package is based on a runtime system developed by Mike
Spivey (mike(at)cs.ox.ac.uk) as part of the Oxford Oberon
@@ -52,8 +57,8 @@ relevant folders.
To build and install an executable xml2pmx on a system
with conventional development tools:
- tar xvf xml2pmx-2020-08-12.tar.gz
- cd xml2pmx-2020-08-12
+ tar xvf xml2pmx-2021-01-23.tar.gz
+ cd xml2pmx-2021-01-23
./configure
make
sudo make install
@@ -73,25 +78,25 @@ If it is necessary to edit the resulting pmx file, use the
Licencing
*********
-The source files for xml2pmx are Copyright 2015-2020 by
+The source files for xml2pmx are Copyright 2015-2021 by
Dieter Gloetzel (d.gloetzel(a)web.de) and the source files
-for the runtime system are Copyright 2020 by Mike Spivey
+for the runtime system are Copyright 2021 by Mike Spivey
(mike(a)cs.ox.ac.uk). They may be modified and distributed
according to the terms of the GNU General Public Licence
version 3 or at your option any later version.
-musixtex.lua is Copyright 2011-2020 by Bob
+musixtex.lua is Copyright 2011-2021 by Bob
Tennent (rdt(a)cs.queensu.ca) and Dirk Laurie
-(dirk.laurie(at)gmail.com). It may be modified and distributed
-according to the terms of the GNU General Public Licence
-version 2 or at your option any later version.
+(dirk.laurie(at)gmail.com). It may be modified and
+distributed according to the terms of the GNU General Public
+Licence version 2 or at your option any later version.
This README and the man pages xml2pmx.1 and musixtex.1 were
written by Bob Tennent and may be modified and distributed
according to the terms of the LaTeX Project Public License.
-Please report problems with the executables or the Linux
-build system to Bob Tennent (rdt(a)cs.queensu.ca). Problems
-with the XML to PMX translation should be reported to Dieter
+Please report problems with the executables or the build
+system to Bob Tennent (rdt(a)cs.queensu.ca). Problems with
+the XML to PMX translation should be reported to Dieter
Gloetzel (d.gloetzel(at)web.de).
diff --git a/support/xml2pmx/doc/Readme.XML2PMX b/support/xml2pmx/doc/Readme.XML2PMX
index 04165c2269..75024a33b4 100644
--- a/support/xml2pmx/doc/Readme.XML2PMX
+++ b/support/xml2pmx/doc/Readme.XML2PMX
@@ -1,5 +1,6 @@
+XML2PMX Readme
(***************************************************************************)
-(****************Copyright 2015,2016,2017 Dieter Gloetzel ******************)
+(****************Copyright 2015 -- 2020 Dieter Gloetzel ******************)
(***************************************************************************)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,32 +19,37 @@
1. Introduction
"MusicXML", ( http://www.musicxml.com/ ) originally developed by Recordare INC
and now owned by Finale ( https://www.finalemusic.com/ ), is the leading
- musical data exchange format. XML2PMX provides an import facility for
+ music data exchange format. XML2PMX provides an import facility for
sheet music stored in MusicXML format to PMX and MusiXTeX, the leading free
- software for musical typesetting. Thus we are now able to import published MusicXML sources
- as well as MusicXML sources created by OCR scanning,
- e.g. with Sharpeye of VISIV ( http://www.visiv.co.uk ).
+ software for musical typesetting. Thus PMX is able to import published
+ MusicXML sources as well as MusicXML sources created by OCR scanning,
+ e.g. with Sharpeye of VISIV ( http://www.visiv.co.uk )or PhotoScore.
2. PMX
developed by Don Simons (dsimons(at)roadrunner(dot)com) is an easy to use,
- yet powerful preprocessor for the musical typesetting system MusiXTeX.
+ yet powerful preprocessor for the musical typesetting system MusiXTeX.
http://icking-music-archive.org/software/htdocs/index.html
An excellent introduction to using PMX is
- http://icking-music-archive.org/software/pmx/pmxccn.pdf
+ http://icking-music-archive.org/software/pmx/pmxccn.pdf
+ In order to work successfully with XML2PMX a good knowledge of
+ PMX is required, and of MusiXTeX will be helpful.
3. XML2PMX
has been developed by the author with "Oberon Plugin for Windows
Version 2.5" of ETHZ Zürich on Windows 10.
https://github.com/Spirit-of-Oberon/ETH-Oberon-PlugIn-Win32
+ and OLR (Oberon Linux Revival)
+ http://oberon.wikidot.com/oberon-linux-revival-olr
- XML2PMX is available as Windows-EXE (32 Bit) and as Linux binary (32 Bit).
+ XML2PMX is available as Windows-EXE (32 Bit) and as Linux binary (32 Bit).
XML2PMX requires a TeX, MusiXTeX and PMX installation.
For Unix please see: https://tug.org/texlive/
For Windows please see: https://miktex.org/2.9/setup
-4. Coverage of MusicXML
+4. Coverage of MusicXML features
The following MusicXML features are detected and translated to PMX:
- - maximum of 24 staves/voices and 400 measures
+ - 24 staves/voices and 600 bars
+ - 83 notes per instrument and bar
- two voices per staff
- maximum of two staves per instrument
- notes and rests up to 64th, including tuplets and grace notes,
@@ -56,58 +62,67 @@
- title and composer, and texts above or below the staff
- barlines, repeats, volta
- instrument names,
- - origin of XML file copied to the resulting PMX file
- - accepts Windows files (records ended by 0DX OAX)
- as well as Unix files (records ended by 0AX)
- - resulting PMX-file on Unix has records ended by 0AX.
- - resulting PMX-file on Windows has records ended by 0DX 0AX.
+ - Accepts Windows files (records ended by 0DX OAX)
+ as well as Unix files (records ended by 0AX).
+ - Resulting PMX-file on Unix has records ended by 0AX.
+ - Resulting PMX-file on Windows has records ended by 0DX 0AX.
+ - will not accept UTF16
+
+5. Additional features:
+ - command line input fields: "options" and "maxbar".
+ "options" may contain one or several of the nine letters "pdvalstgr"
+ in arbitrary sequence in upper or lower case and without spaces.
+ Option "r" removes any note which has been marked in XML with
+ print-object = "no".
+ "maxbar" is a limit on the number of bars to be processed.
+ When maxbar = 0 then all bars will be processed.
+ - With option = "L" Lyrics can be extracted and stored in a separate file: "songtext.txt".
+ - Automatic detection of pickup
-5. New features:
- - There is a new command line field "options",
- which may contain one or several of the five letters "PDVSL"
- in arbitrary sequence in upper or lower case.
- - Lyrics are extracted and stored in a separate file (option L=Lyrics)
- - several options for console output (P=parsed data, D=directions, V=voices, S=statistics,)
- - automatic detection of pickup
- - incomplete measures or voices are automatically filled with blind rests
-
6. Limitations
Some more elaborate situations like beams crossing staves or chords crossing staves
have not yet been covered.
+ MusicXML attributes are enclosed with double quotes.
-7. Usage on MS Windows command line:
- ===================================================================
- XML2PMX "xml-file with path" "pmx-file with path" "options"
- ===================================================================
- The doublequotes are required.
- "options" contains a sequence (without blanks) of one or several of
- the letters "p", "d", "v", "s" and "l" .
+7. Usage on MS Windows command line (quotes not required):
+ ============================================================================
+ XML2PMX_2020.exe
+ "xml-file with path" "pmx-result-file with path" "output options" "maxbar"
+ ============================================================================
+ There are two obligatory inputs: "xml-file" and "pmx-result-file".
+ "output options" and "maxbar" are optional parameters.
+ "output options" contains a sequence (without blanks) of one or several of
+ the letters "p", "d", "v", "a", "l", "r", "s", "t" and "g" .
Their meaning is the following:
- _______________________________________________________________
- | p | XML parser output; not recommended unless the terminal |
- | | window process has enough storage |
+ _____ _______________________________________________________
+ | p | XML parser: can produce much output |
|-------------------------------------------------------------|
| d | information on "directions" (dynamical marks etc) |
|-------------------------------------------------------------|
| v | distribution of voices over instruments and measures |
|-------------------------------------------------------------|
- | s | statistics of MusicXML tags like <note>, <measure> etc|
+ | a | statistics of MusicXML tags like <note>, <measure>, |
|-------------------------------------------------------------|
- | l | for extracting lyrics in a separate file |
- |_____________________________________________________________|
-
- The generated PMX file will in general be complete and can be processed by "musixtex".
-
- If not, you can often solve the problem with minor changes in the PMX code.
-
- After the XML2PMX run you will find intermediate results in the
- terminal window which may be helpful for debugging.
+ | l | extracts lyrics in a separate file |
+ |-------------------------------------------------------------|
+ | s | removes all slurs |
+ |-------------------------------------------------------------|
+ | t | removes all ties |
+ |-------------------------------------------------------------|
+ | g | uses PMX slur option inside grace note | |
+ |-------------------------------------------------------------|
+ | r | remove Notes with Print-object = "no" |
+ ---------------------------------------------------------------
+ The generated PMX file will in general be complete and can be
+ processed by PMX.If not, you can often solve the problem with
+ minor changes in the PMX code.
- Once you have a generated PMX file with all of the notes extracted, the bulk work has been done.
- It is then easy to improve the results on the PMX side.
+ Depending on the options chosen, you will find intermediate results in the
+ console window which may be helpful for debugging.
+
8.1 MusicXML test data
- You will find MusicXML-sources for testing under:
+ You will find MusicXML-sources for testing under:
http://www.musicxml.com/music-in-musicxml/example-set/
@@ -117,19 +132,55 @@
- Beethoven: "An die ferne Geliebte", Op. 98 "BeetAnGeSample.xml"
- - Lee Actor "Prelude to a tragedy": "ActorPreludeSample.xml"
- sample with 22 instruments and 41 measures
-
- Mahler: "Lieder eines fahrenden Gesellen", "MahlFaGe4Sample.xml"
8.2 OCR scanned sheet music
- The MusicXML results from the tool Sharpeye from VISIV
+ MusicXML results from the tool Sharpeye of VISIV
(http://www.visiv.co.uk/) have been tested successfully.
-Contact:
+9.1 Contents for Windows:
+ Main folder "XML2PMX_Windows_2020" contains:
+ - this Readme.txt
+ - Folder "XML", containing the MusicXML code of
+ a Telemann Fantasy for Recorder: "Telemann.xml"
+ - Folder "PMX", will take the test results *.pmx, *.pdf
+ - Folder "example" with sample results for comparison
+ - Folder "source" with the Oberon source code for Windows
+ - XML2PMX_2020.exe: Windows-Exe
+ - GNU-GPL.txt: GNU Licence
+ - Runxml_Telemann.bat : sample batch file
+9.2 Contents Linux:
+ Main folder "XML2PMX_LINUX_2020" contains:
+ - this Readme.txt
+ - Folder "XML", containing the MusicXML code of
+ a Telemann Fantasy for Recorder: "Telemann.xml"
+ - Folder "PMX" holds the test results *.pmx, *.pdf
+ - Folder "example" with sample results for comparison
+ - Folder "source" with the Oberon source code for LINUX
+ - XML2PMX_2020: LINUX Binary
+ - GNU-GPL.txt: GNU Licence
+ - RunTelemann : sample command
+
+10. XML2PMX installation
+ 10.1 Prerequisites: TeXLive installation on Unix or
+ MikTeX installation on Windows
+ including MusiXTeX and PMX.
+ 10.2 unpack the folder XML2PMX_LINUX_2020
+ or XML2PMX_Windows_2020 to a convenient place.
+ 10.3 for Windows: register XML2PMX_2020.exe, i.e. doubleclick on XML2PMX.reg.
+
+
+11. Usage example
- Feel free to contact me at <d.gloetzel(at)web(dot)de>
- in order to report errors, propose improvements or
- other comments.
+11.1 XML2PMX usage example Windows
+ double click on runxml_Telemann.bat
+11.2 XML2PMX usage example Linux
+ open a command line
+ move to folder XML2PMX_LINUX_2020
+ enter in the command line and execute: ./RunTelemann
+12. Contact:
+ Feel free to join me under <d.gloetzel(at)web(dot)de> in order to report errors, propose improvements or other comments.
+
+
diff --git a/support/xml2pmx/doc/xml2pmx.1 b/support/xml2pmx/doc/xml2pmx.1
index 3fc9c14219..09bdb4d543 100644
--- a/support/xml2pmx/doc/xml2pmx.1
+++ b/support/xml2pmx/doc/xml2pmx.1
@@ -1,4 +1,4 @@
-.TH XML2PMX 1 2020-05-21 "" ""
+.TH XML2PMX 1 2021-01-23 "" ""
.SH DESCRIPTION
@@ -35,13 +35,25 @@ The meanings of the letter options are as follows:
l for extracting lyrics in a separate file
+.SH BUGS
+
+.B xml2pmx
+processes input in UTF-8 encoding only. MusicXML files in UTF-16 encoding should be
+converted using, for example,
+.B recode
+(in Unix-like systems) or by importing into an editor like
+.B notepad
+and saving in UTF-8 encoding.
+
.SH SEE ALSO
.BR pmx (1)
.BR obc (1)
.BR musixtex (1)
+.BR recode (1)
.SH AUTHORS
This man page was written by Bob Tennent <rdt@cs.queensu.ca>.
-XML2PMX was written by Dieter Gloetzel <d.gloetzel@web.de> and
+.B xml2pmx
+was written by Dieter Gloetzel <d.gloetzel@web.de> and
adapted for compilation by obc (the Oxford Oberon Compiler) by Mike Spivey <mike@cs.ox.ac.uk>.
diff --git a/support/xml2pmx/doc/xml2pmx.pdf b/support/xml2pmx/doc/xml2pmx.pdf
index 987e7496b3..1a699aeaa6 100644
--- a/support/xml2pmx/doc/xml2pmx.pdf
+++ b/support/xml2pmx/doc/xml2pmx.pdf
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb b/systems/texlive/tlnet/tlpkg/texlive.tlpdb
index d48e67b722..02fc48ee63 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/2020
-depend revision/57492
+depend revision/57497
name 00texlive.image
category TLCore
-revision 57491
+revision 57497
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
@@ -197985,14 +197985,14 @@ catalogue-version 1.0.1
name moderncv
category Package
-revision 52669
+revision 57496
shortdesc A modern curriculum vitae class
relocated 1
longdesc The class provides facilities for typesetting modern
longdesc curriculums vitae, both in a classic and in a casual style. It
longdesc is fairly customizable, allowing you to define your own style
-longdesc by changing the colours, the fonts, etc. A number of templates
-longdesc are provided in the distribution examples subdirectory.
+longdesc by changing the colours, the fonts, etc. The template.tex file
+longdesc can be used as an example.
depend etoolbox
depend fancyhdr
depend graphics
@@ -198003,36 +198003,22 @@ depend microtype
depend tools
depend url
depend xcolor
-containersize 21988
-containerchecksum d45dadcbe35356b64c6e81173e02d08f03f148333aab7f40f7ade71c6818a9be0fd649472ee9b7605bd0437054e304ba9fcd991c9092f7550b8cc925b66b6522
-doccontainersize 839416
-doccontainerchecksum ff121a7936943ca52f5bf9007b34004e8a8af6a0161a96e42eec9b08947df72df289e7dd324eae539ff7eba93f512ae441118d53dce1bd7763c93adfbcc32ab4
-docfiles size=460
+containersize 30884
+containerchecksum 5afe854478a689c648695480bcece97a3c940e1be7cd0e32f3e1ddb1240e823ffae82f53a5b6a127c62f30a1e339f5dcaf9f7ac8b5da361fd3de80feca719614
+doccontainersize 245668
+doccontainerchecksum 032a9ccb6e91fea7db129146292f3e59866019729f056e4f9e6bcf8db42a0d81a181b214240689fc6643d49a63580e2e8c61e0b9a47562f04af0d24f14bd37b3
+docfiles size=116
RELOC/doc/latex/moderncv/CHANGELOG
RELOC/doc/latex/moderncv/KNOWN_BUGS
- RELOC/doc/latex/moderncv/README details="Readme"
- RELOC/doc/latex/moderncv/examples/Makefile
- RELOC/doc/latex/moderncv/examples/picture.eps
- RELOC/doc/latex/moderncv/examples/picture.jpg
- RELOC/doc/latex/moderncv/examples/publications.bib
- RELOC/doc/latex/moderncv/examples/template-es.pdf
- RELOC/doc/latex/moderncv/examples/template-es.tex
- RELOC/doc/latex/moderncv/examples/template-multibib.pdf
- RELOC/doc/latex/moderncv/examples/template-multibib.tex
- RELOC/doc/latex/moderncv/examples/template-zh.pdf
- RELOC/doc/latex/moderncv/examples/template-zh.tex
- RELOC/doc/latex/moderncv/examples/template.tex
- RELOC/doc/latex/moderncv/examples/template_banking_red-fullrules-center.pdf
- RELOC/doc/latex/moderncv/examples/template_banking_red-norules.pdf
- RELOC/doc/latex/moderncv/examples/template_banking_red-shortrules-right.pdf
- RELOC/doc/latex/moderncv/examples/template_banking_red.pdf
- RELOC/doc/latex/moderncv/examples/template_casual_orange-left.pdf
- RELOC/doc/latex/moderncv/examples/template_casual_orange.pdf
- RELOC/doc/latex/moderncv/examples/template_classic_green-right.pdf
- RELOC/doc/latex/moderncv/examples/template_classic_green.pdf
- RELOC/doc/latex/moderncv/examples/template_fancy_purple.pdf
- RELOC/doc/latex/moderncv/examples/template_oldstyle_grey.pdf
-runfiles size=61
+ RELOC/doc/latex/moderncv/LICENSE.txt
+ RELOC/doc/latex/moderncv/README.md details="Readme"
+ RELOC/doc/latex/moderncv/manual/moderncv_userguide.pdf details="Package documentation"
+ RELOC/doc/latex/moderncv/manual/moderncv_userguide.tex
+ RELOC/doc/latex/moderncv/picture.eps
+ RELOC/doc/latex/moderncv/picture.jpg
+ RELOC/doc/latex/moderncv/publications.bib
+ RELOC/doc/latex/moderncv/template.tex
+runfiles size=81
RELOC/tex/latex/moderncv/moderncv.cls
RELOC/tex/latex/moderncv/moderncvbodyi.sty
RELOC/tex/latex/moderncv/moderncvbodyii.sty
@@ -198060,6 +198046,7 @@ runfiles size=61
RELOC/tex/latex/moderncv/moderncviconsawesome.sty
RELOC/tex/latex/moderncv/moderncviconsletters.sty
RELOC/tex/latex/moderncv/moderncviconsmarvosym.sty
+ RELOC/tex/latex/moderncv/moderncvskillmatrix.sty
RELOC/tex/latex/moderncv/moderncvstylebanking.sty
RELOC/tex/latex/moderncv/moderncvstylecasual.sty
RELOC/tex/latex/moderncv/moderncvstyleclassic.sty
@@ -198067,11 +198054,14 @@ runfiles size=61
RELOC/tex/latex/moderncv/moderncvstylefancy.sty
RELOC/tex/latex/moderncv/moderncvstyleoldstyle.sty
RELOC/tex/latex/moderncv/tweaklist.sty
-catalogue-contact-repository http://www.launchpad.net/moderncv
+catalogue-contact-bugs https://github.com/moderncv/moderncv/issues
+catalogue-contact-development https://github.com/moderncv
+catalogue-contact-home https://github.com/moderncv/moderncv
+catalogue-contact-repository https://github.com/moderncv/moderncv.git
catalogue-ctan /macros/latex/contrib/moderncv
-catalogue-license lppl1.3
+catalogue-license lppl1.3c
catalogue-topics cv class
-catalogue-version 2.0.0
+catalogue-version 2.1.0
name modernposter
category Package
@@ -295932,16 +295922,16 @@ docfiles size=591
name texlive-docindex
category TLCore
-revision 57481
+revision 57494
shortdesc top-level TeX Live doc.html, etc.
longdesc These files are regenerated as needed, which is often, so we
longdesc make them a separate package. See the tl-update-auto script for
longdesc the process.
containersize 388
-containerchecksum 72ac5d3e67934b1a96f364c2d92f25ece517744e046e14c23c46aedcb5d0e1de54c00b966c2cc340ec51cb93d5ce95333054173816783d5828d2f08300fe0958
-doccontainersize 171652
-doccontainerchecksum c0e44f404aae25cad39ed850a286b9a07095ffe16659ffbda09415a918e26c313f7fc1cb559545b7434df2ae9df638cd9cba3f5df4ece7836dbc3434f690afdb
-docfiles size=340
+containerchecksum 130cb468e2fbd78e9c3ce49530b9f0ee41bb0eeb5e9e755df8e1ad8aee9c1f0251d1193e072a6fb7cfb1f5e7ec456483281289dc500994912d51a334699c2566
+doccontainersize 172040
+doccontainerchecksum 58492a6873277919b97e4a4c033fea0061c1555e23efdb6f8359c90fe3b6136e4a433f27584f8cb765192e41d4a03c4d3852bea0009301a099903181564f4f71
+docfiles size=341
doc.html
name texlive-en
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
index 2958a45bda..88e5c0cc57 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
@@ -1 +1 @@
-35e04ea78c80c566f961212e9c9e99f7 texlive.tlpdb
+1f67c1788b6fb261b2a4a4352c9c0738 texlive.tlpdb
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
index ea56264589..4f3319abd1 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
@@ -1 +1 @@
-629edd06be3a258d45571da34ae669a71dfded4e119e44fd6aa5bc6823dcc413b63b23ee3c268f4bb00fe3dffec90c80dbcb9e460540f45907be5f5648296db5 texlive.tlpdb
+63121d9c1b8450869d0b860789463123c9730053cc7a41c4552e48b848677137bf1ed7be4ac3c5fa82a6c9b42b326fb788a91bb78556959221f35989ff93879b texlive.tlpdb
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
index 94413ff729..f1128ea7db 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
@@ -1,10 +1,10 @@
-----BEGIN PGP SIGNATURE-----
-iQEcBAEBCgAGBQJgCiMUAAoJEEzhh34ZQ4xwoDwH/ie8w7k5v2bgpi1Crg7biufJ
-NVxP/RoprvVrS5C95tGnr4Lw+SjuOErIenYSWzUmKfhEGFxk4v7NPprY2awX5n4k
-kcWz74V1yqXsDTri8eI/ZhNAUKkGCN1Hiq4g2kF+GWrKXAxxMlbvI1yZufn1rkty
-cgbDfDGFwpRZLva4vweRR0mP7FIVZKWosl12fq7IY/J2BYPsHV6RDxCq7gRull3n
-GsRbmN8y5JAAqyY8Webtc5addqu8BIXFDeLeow4/U1G3f/KzOmo+ba0Aq9HqmiVW
-oRast64rE+iaDqerMyAAJqifP4ISHqG00e2q04E2ZQqdOuvtz16SlVEMldGz+sw=
-=EM97
+iQEcBAEBCgAGBQJgC3RMAAoJEEzhh34ZQ4xwcu8H/Rwb9X4hOojYvgkHH/v9Bn8M
+Fts7Ve0Begb3PrDPe7CO63yJvD0C+zfuOt5/dlKYy+RwBl61+ZvbZCD06u+sJjBK
+1+j8/a2kTeyW8x+vmUEM8WMK5GJ/7SYfecCitUgDGXeD4fbF8Gb3FTe4MJ0LvWqM
+EutWSUzBkDJW5LXaFZYieDH9kH42UGji0OZdJhGGyOFaqIc1HTu0nvHK9gZYLDZh
+NxsQru1LKuH5vTVXFFV7y0iQ4Sr8iVYVUEfgvgtDikSobMJwXvcDtzmK3HNw7sRp
+AjgYG0kVPPRrjFWtNH7rwDusC2LkQ5ZG7hUSg30dmprx3qHvWkJA4o5vwdHD99I=
+=RVBG
-----END PGP SIGNATURE-----
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
index 2f85892d20..def71a9ceb 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
Binary files differ
diff --git a/systems/win32/miktex/tm/packages/next/pr.ini b/systems/win32/miktex/tm/packages/next/pr.ini
index 3de9ff455b..cf34be7c21 100644
--- a/systems/win32/miktex/tm/packages/next/pr.ini
+++ b/systems/win32/miktex/tm/packages/next/pr.ini
@@ -1,13 +1,13 @@
[repository]
-date=1611350204
+date=1611436479
lastupd=miktex-arctrl-bin-2.9 miktex-arctrl-bin-x64-2.9 miktex-asymptote-bin-2.9 miktex-asymptote-bin-x64-2.9 miktex-autosp-bin-2.9 miktex-autosp-bin-x64-2.9 miktex-axohelp-bin-2.9 miktex-axohelp-bin-x64-2.9 miktex-bibarts-bin-2.9 miktex-bibarts-bin-x64-2.9 miktex-bibtex-bin-2.9 miktex-bibtex-bin-x64-2.9 miktex-bibtex8bit-bin-2.9 miktex-bibtex8bit-bin-x64-2.9 miktex-bzip2-bin-2.9 miktex-bzip2-bin-x64-2.9 miktex-cairo-bin-2.9 miktex-cairo-bin-x64-2.9 miktex-chktex-bin-2.9 miktex-chktex-bin-x64-2.9
-lstdigest=ee91d12253fd566e920f12355e77e622
+lstdigest=4f95fbd1fbc8d226193a8768dc1fd3be
numpkg=4043
relstate=next
-version=7692
+version=7693
;;;;This configuration file is signed by a MiKTeX maintainer. The signature follows.
;;;;-----BEGIN MIKTEX SIGNATURE-----
-;;;; signature/miktex: jxxN8jla+8fBhxZd7q6yi75uy2TK/309Oe+kPM41GRaGHilCQw/52WXzkr1+VHuousG/smHJTbpJj43KtlkDPSec7BmXy1ZXXyyuP9DfeYIVehRIfUQ+rOurW8jDIw8QmEGw/Tur7FtyhCdR93IITBoQLokK83YZhrkJ/HkLKOtH8js+KX4f53ceyrFihGEG8M5hepYsauSEUnDEHDCPcAV372nv/wUUjCi8AAjAU+MCtOmmDPWT91nwgy64cDey5H51QJCve/CNii7zyTr4naCM2Vg5kMrFoxIDHYckR8MVgm03SeJDly9zLVHiAjmVB/Zm+3KFkhtJ2JTNnAS/uw==
+;;;; signature/miktex: KEFjhMVZ4iBdLZ4r1FLe31GURhFBOLklDN7IfBFHoWisJbXI+V8gtIWan4TQYVmvn+WwG1LCeySOik6ESLVojFmpc1Lbd30kzDrGlXR5TVGUNp4ghrmSCSbq/km92EUXfBuQaZl2/1EbJp59xGFjf5hJ08MZ7TWFOEWcVVc9UGta6eW/upvxe+Py6rNlTDK0jbbaeEhw7ZQl+1gCmmKR21v0n3KsNnYDus6jKIOhzuFbM6lo+vXH+mWw2CEmhQV8by3qvA6p+0eypEesAc7KGTLgsX00W1Bz78yAFjARAsmYhiCfRJWB2pwVapBoY4oegbK7VVsOoAbW+gMoztCPBQ==
;;;;-----END MIKTEX SIGNATURE-----
diff --git a/systems/win32/miktex/tm/packages/pr.ini b/systems/win32/miktex/tm/packages/pr.ini
index 08b25638a8..018c5c4d6e 100644
--- a/systems/win32/miktex/tm/packages/pr.ini
+++ b/systems/win32/miktex/tm/packages/pr.ini
@@ -1,13 +1,13 @@
[repository]
-date=1611349921
+date=1611436313
lastupd=aalok achemso asmeconf biblatex-gb7714-2015 biblatex-oxref cascadia-code chemnum chhaya circuitikz easybook erewhon everysel fancyvrb logix luakeys matapli miktex-misc mlmodern ms newcomputermodern
-lstdigest=8e60572b55ce644052b4ac28b19c32fe
+lstdigest=21b2a098a1b34def6d0a152400da72ad
numpkg=4043
relstate=stable
-version=7692
+version=7693
;;;;This configuration file is signed by a MiKTeX maintainer. The signature follows.
;;;;-----BEGIN MIKTEX SIGNATURE-----
-;;;; signature/miktex: LWGuxFWDTyahNhh4Rt+AcwVApSFYJUnZOBjB9yR4cY6kjch1aGF/vmX+WNll2H8l6wqqjlu6Kll8BxHcmgM01jvTgP6weqlbnfehmQxdmraVsX8jnr6bgeg73RkzKQvd+DtkEksMQaIjWFb8efGUTCF3IDEF5F6L5sZJYye1PfAT5SLB87vd3FoIzsg3RJhrNt0tR9gqvXH96ZWP3rZa29hOcVsWvVrHLCizsldbHdjhwCkdr6GasapnfHh950nXE4GjR6KHtPMWDrfbwIkLXfnU1yM0bwkcUxawU1BlPYic+4sdKxQ6MK8mCiTpOqUdgjofyxljcQB1eTexZ0OqJw==
+;;;; signature/miktex: Ap3gm/XyLXD3JqNl7u8UwURlevUbC+84IFiiNBR1E1Upg99esh1azu3buYn/Z4zp/6G6GVHcl+DGinequ9HvHpVK6VRXlsMkaxjrvpNT8V1jgmnmswDQZe/6zDC5Ufpsl55iwDF08bvVemZrY4mZJIToWnulxLEUqnSB2WCYwAS1T2KU3Asl9A0fN9buRQz6l46BzEVanPct8upZL9AR9PpeeV5X/58Q7zI/duzlSRbfktttmKjbf8F7NaXOWEvEeQnLmJ1mSP6bc7syPceQXQc47oP+l7SjRbxlji5+rd6gPxLbHDpF5y9UYCZRlUbO9G+YW99zkCOmhwCDHGxT1w==
;;;;-----END MIKTEX SIGNATURE-----
diff --git a/systems/win32/w32tex/ChangeLog b/systems/win32/w32tex/ChangeLog
index 403f9a898c..ad84b8b2da 100644
--- a/systems/win32/w32tex/ChangeLog
+++ b/systems/win32/w32tex/ChangeLog
@@ -1,5 +1,29 @@
W32TeX (x86 & x64) ChangeLog
+[2021/01/22]
+(01) dvipdfm-w32.tar.xz
+ Update dvipdfmx.dll (20210122).
+(02) dvitools-w32.tar.xz
+ Update dvisvgm.exe (2.11.1).
+(03) ltxpkgs.tar.xz
+ Update chemnum, reledmac and teubner.
+(04) pgfcontrib.tar.xz
+ Add tkz-berge and tkz-graph.
+(05) ptex-ng-w32.tar.xz
+ Update libdpx
+(06) tex4htk-w32.tar.xz
+ Add newcomputermodern-hooks.4ht. Update usepackage.4ht.
+(07) xetex-w32.tar.xz
+ Update dvipdfmx.dll (20210122).
+(08) win64/dvipdfm-w64.tar.xz
+ Update dvipdfmx.dll (20210122).
+(09) win64/dvitools-w64.tar.xz
+ Update dvisvgm.exe (2.11.1).
+(10) win64/ptex-ng-w64.tar.xz
+ Update libdpx.
+(11) win64/xetex-w64.tar.xz
+ Update dvipdfmx.dll (20210122).
+
[2021/01/21]
(01) context.tar.xz
Update format files for pdftex.
diff --git a/timestamp b/timestamp
index dcde1c0cc7..8aa4b3ae15 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:
-2021-01-23-02-02
+2021-01-24-02-02