summaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-01-04 03:00:45 +0000
committerNorbert Preining <norbert@preining.info>2021-01-04 03:00:45 +0000
commitb49dd7c340dbe68a28c8a976cd6a1429ca8aafff (patch)
tree1e22dd36991a3910a34ab5c5a8721c51e439a9fd /macros
parent1a272a3cba66aebe829cd28965c0e8acc8c44681 (diff)
CTAN sync 202101040300
Diffstat (limited to 'macros')
-rw-r--r--macros/latex/contrib/easybook/README.md42
-rw-r--r--macros/latex/contrib/easybook/doc/easybook.pdfbin0 -> 173570 bytes
-rw-r--r--macros/latex/contrib/easybook/easybook-demo.pdfbin0 -> 315098 bytes
-rw-r--r--macros/latex/contrib/easybook/easybook-demo.tex65
-rw-r--r--macros/latex/contrib/easybook/easybook.cls1176
-rw-r--r--macros/latex/contrib/easybook/pages/appendix.tex11
-rw-r--r--macros/latex/contrib/easybook/pages/chapter1.tex125
-rw-r--r--macros/latex/contrib/easybook/pages/chapter2.tex77
-rw-r--r--macros/latex/contrib/easybook/pages/chapter3.tex52
-rw-r--r--macros/latex/contrib/easybook/pages/preface.tex21
-rw-r--r--macros/latex/contrib/easybook/ref/refs.bib31
-rw-r--r--macros/latex/contrib/skeldoc/skeldoc.pdfbin216738 -> 217555 bytes
-rw-r--r--macros/latex/contrib/skeldoc/skeldoc.sty6
-rw-r--r--macros/luatex/generic/chickenize/README.md4
-rw-r--r--macros/luatex/generic/chickenize/chickenize.dtx678
-rw-r--r--macros/luatex/generic/chickenize/chickenize.lua965
-rw-r--r--macros/luatex/generic/chickenize/chickenize.pdfbin195033 -> 230758 bytes
-rw-r--r--macros/luatex/generic/chickenize/chickenize.sty32
-rw-r--r--macros/luatex/generic/chickenize/chickenize.tex441
-rw-r--r--macros/luatex/generic/luatexja/README10
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja-en.pdfbin699627 -> 699665 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja-ja.pdfbin1136733 -> 1135849 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja-ruby.pdfbin380466 -> 382321 bytes
-rw-r--r--macros/luatex/generic/luatexja/doc/luatexja-ruby.tex11
-rw-r--r--macros/luatex/generic/luatexja/src/addons/luatexja-ruby.sty10
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-latex.sty10
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-otf.lua7
-rw-r--r--macros/luatex/generic/luatexja/src/ltj-ruby.lua4
-rw-r--r--macros/luatex/generic/luatexja/src/luatexja-core.sty6
-rw-r--r--macros/luatex/generic/luatexja/src/luatexja.sty4
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjfont.sty18
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty9
-rw-r--r--macros/luatex/generic/luatexja/src/patches/lltjp-listings.sty4
-rwxr-xr-xmacros/luatex/generic/luatexja/tool/jfm-convert.lua12
34 files changed, 2282 insertions, 1549 deletions
diff --git a/macros/latex/contrib/easybook/README.md b/macros/latex/contrib/easybook/README.md
new file mode 100644
index 0000000000..8f75b0f891
--- /dev/null
+++ b/macros/latex/contrib/easybook/README.md
@@ -0,0 +1,42 @@
+# Easybook book document class
+Easybook is a minimalist style template based on the ctexbook book document class. It is mainly suitable for typesetting Chinese books or notes, and can even be slightly modified to become a dissertation template. Some commonly used macro packages have been loaded to achieve general typesetting requirements. Although some details have been considered as much as possible, there are still deficiencies.
+## Compilation method
+Please use the UTF8 encoding and enter the following command on the command line
+```
+xelatex -shell-escape easybook-demo
+bibtex easybook-demo
+makeindex easybook-demo
+xelatex -shell-escape easybook-demo
+xelatex -shell-escape easybook-demo
+```
+## Reference documents
+- [CTeX macro collection manual](https://ctan.org/pkg/ctex)
+- [Xiamen University graduation thesis template](https://github.com/CamuseCao/XMU-thesis)
+- [Fudan University graduation thesis template](https://github.com/stone-zeng/fduthesis)
+- [Wuhan University graduation thesis template](https://github.com/mtobeiyf/whu-thesis)
+- [ElegantBook book template](https://ctan.org/pkg/elegantbook)
+## Website
+| [Gitee](https://gitee.com/TeX-doc/easybook) | [Github](https://github.com/TeX-doc/easybook) | [CTAN]() | [Font](https://wws.lanzous.com/b01ns361i) |
+
+
+
+# easybook 书籍文档类
+
+easybook 是基于 ctexbook 书籍文档类的极简风格模板。它主要适用于中文书籍或笔记的排版,甚至可以稍作修改成为论文模板。已加载一些常用的宏程序包以实现一般的排版要求。尽管已尽可能多地考虑了一些细节,但仍然存在不足。
+## 编制方法
+请使用 UTF8 编码,并在命令行上输入以下命令
+```
+xelatex -shell-escape easybook-demo
+bibtex easybook-demo
+makeindex easybook-demo
+xelatex -shell-escape easybook-demo
+xelatex -shell-escape easybook-demo
+```
+## 参考文档
+- [CTeX 宏集手册](https://ctan.org/pkg/ctex)
+- [厦门大学毕业论文模板](https://github.com/CamuseCao/XMU-thesis)
+- [复旦大学毕业论文模板](https://github.com/stone-zeng/fduthesis)
+- [武汉大学毕业论文模板](https://github.com/mtobeiyf/whu-thesis)
+- [ElegantBook 书籍模板](https://ctan.org/pkg/elegantbook)
+## 网址
+| [Gitee](https://gitee.com/TeX-doc/easybook) | [Github](https://github.com/TeX-doc/easybook) | [CTAN]() | [字体](https://wws.lanzous.com/b01ns361i) | \ No newline at end of file
diff --git a/macros/latex/contrib/easybook/doc/easybook.pdf b/macros/latex/contrib/easybook/doc/easybook.pdf
new file mode 100644
index 0000000000..19b4476b98
--- /dev/null
+++ b/macros/latex/contrib/easybook/doc/easybook.pdf
Binary files differ
diff --git a/macros/latex/contrib/easybook/easybook-demo.pdf b/macros/latex/contrib/easybook/easybook-demo.pdf
new file mode 100644
index 0000000000..7ec299677d
--- /dev/null
+++ b/macros/latex/contrib/easybook/easybook-demo.pdf
Binary files differ
diff --git a/macros/latex/contrib/easybook/easybook-demo.tex b/macros/latex/contrib/easybook/easybook-demo.tex
new file mode 100644
index 0000000000..91a0848dd0
--- /dev/null
+++ b/macros/latex/contrib/easybook/easybook-demo.tex
@@ -0,0 +1,65 @@
+\documentclass[zihao = -4,openany]{easybook}
+\ctexset
+ {
+ style =
+ {
+ color = navygreen,
+ % cite = authoryear,
+ thmbox = true,
+ % capdash = true,
+ % multoc = true,
+ % withpart = true,
+ % perpart = true,
+ perpage = true
+ },
+ link =
+ {
+ hyperlink = various,
+ linkcolor = lightblue,
+ linktopage = false
+ },
+ spread =
+ {
+ linespread = 1.355,
+ tabspread = 1.05,
+ mathspread = 1,
+ capspread = 1,
+ fnspread = 1
+ },
+ % secnumdepth = 2,
+ % tocdepth = 2
+ }
+
+\AfterPreamble
+ {
+ \title{\sffamily easybook书籍文档类}
+ \author
+ {
+ Qu Yi\thanks{texeasybook@foxmail.com.} \\
+ \textcolor[HTML]{c71d23}{\faGit}~\url{https://gitee.com/TeX-doc/easybook}\thanks{Gitee为项目的主要发布地址。} \\
+ \faGithub~\url{https://github.com/TeX-doc/easybook} \\
+ \textcolor[HTML]{00c2ff}{\faEdge}~\url{https://latexstudio.net}
+ }
+ \date{2021/01/03\hskip\ccwd\relax v1.0}
+ }
+
+\begin{document}
+\frontmatter
+\maketitle
+\subfile{pages/preface}
+\tableofcontents
+
+\mainmatter
+\part{使用示例}
+\subfile{pages/chapter1}
+\subfile{pages/chapter2}
+\subfile{pages/chapter3}
+\subfile{pages/appendix}
+
+\backmatter
+\bibliography{ref/refs}
+\listoffigures
+\listoftables
+\listoflistings
+\printindex
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/easybook/easybook.cls b/macros/latex/contrib/easybook/easybook.cls
new file mode 100644
index 0000000000..71b1d47f47
--- /dev/null
+++ b/macros/latex/contrib/easybook/easybook.cls
@@ -0,0 +1,1176 @@
+%%
+%% This is file `easybook.cls',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% easybook.dtx (with options: `class')
+%% Copyright (C) 2021 by Qu Yi <texeasybook@foxmail.com>
+%% This work may be distributed and/or modified under the
+%% conditions of the CC-BY-NC 4.0 License.
+%% Gitee: https://gitee.com/TeX-doc/easybook
+%% Github: https://github.com/TeX-doc/easybook
+\NeedsTeXFormat{LaTeX2e}
+\RequirePackage{l3keys2e}
+\ProvidesExplClass{easybook}{2021/01/03}{v1.0}{}
+
+\cs_generate_variant:Nn \keys_define:nn {nx}
+\cs_generate_variant:Nn \int_to_arabic:n {v}
+\cs_new_protected:Npn \__appto_cmd:Nn #1#2
+ {\ctex_appto_cmd:NnnTF #1{}{#2}{}{\ctex_patch_failure:N #1}}
+
+\bool_set_false:N \l__draft_bool
+\bool_set_false:N \l__newline_bool
+\bool_set_false:N \l__enstyle_bool
+\bool_set_true:N \l__zhtitle_bool
+\bool_set_true:N \l__myfont_bool
+\bool_set_true:N \l__lang_chinese_bool
+\bool_set_false:N \l__paper_bfive_bool
+\bool_set_true:N \l__paper_afour_bool
+\bool_set_true:N \l__page_twoside_bool
+\bool_new:N \l__thmbox_bool
+\bool_new:N \l__capdash_bool
+\bool_new:N \l__multoc_bool
+\bool_new:N \l__chap_withpart_bool
+\bool_new:N \l__foot_perpart_bool
+\clist_new:N \g__hyperref_clist
+\clist_new:N \g__options_clist
+
+\keys_define:nn {easybook}
+ {
+ draft .code:n = {\bool_set_true:N \l__draft_bool},
+ newline .code:n = {\bool_set_true:N \l__newline_bool},
+ enstyle .code:n = {\bool_set_true:N \l__enstyle_bool},
+ entitle .code:n = {\bool_set_false:N \l__zhtitle_bool},
+ english .code:n = {\bool_set_false:N \l__lang_chinese_bool},
+
+ font .choice:,
+ font/adobe .code:n =
+ {
+ \PassOptionsToClass{fontset = #1}{ctexbook}
+ \bool_set_false:N \l__myfont_bool
+ },
+ font/founder .code:n =
+ {
+ \PassOptionsToClass{fontset = #1}{ctexbook}
+ \bool_set_false:N \l__myfont_bool
+ },
+ font/mac .code:n =
+ {
+ \PassOptionsToClass{fontset = #1}{ctexbook}
+ \bool_set_false:N \l__myfont_bool
+ },
+ font/windows .code:n =
+ {
+ \PassOptionsToClass{fontset = #1}{ctexbook}
+ \bool_set_false:N \l__myfont_bool
+ },
+ font/linux .code:n =
+ {
+ \PassOptionsToClass{fontset = ubuntu}{ctexbook}
+ \bool_set_false:N \l__myfont_bool
+ },
+ font/overleaf .code:n =
+ {\bool_set_false:N \l__myfont_bool},
+ font/none .code:n =
+ {
+ \PassOptionsToClass{fontset = #1}{ctexbook}
+ \bool_set_false:N \l__myfont_bool
+ },
+ font .default:n = windows,
+
+ paper .choice:,
+ paper/a4 .code:n = {},
+ paper/b5 .code:n = {\bool_set_true:N \l__paper_bfive_bool},
+ paper .initial:n = a4,
+
+ oneside .value_forbidden:n = true,
+ twoside .value_forbidden:n = true,
+ oneside .code:n =
+ {\bool_set_false:N \l__page_twoside_bool},
+
+ unknown .code:n =
+ {\clist_gput_right:No \g__options_clist{\CurrentOption}}
+ }
+
+\ProcessKeysOptions{easybook}
+
+\bool_if:NT \l__myfont_bool{\PassOptionsToClass{fontset = none}{ctexbook}}
+\bool_if:NT \l__enstyle_bool
+ {
+ \bool_set_false:N \l__lang_chinese_bool
+ \bool_set_false:N \l__zhtitle_bool
+ \bool_set_true:N \l__newline_bool
+ }
+\bool_if:NTF \l__lang_chinese_bool
+ {\PassOptionsToClass{scheme = chinese}{ctexbook}}
+ {\PassOptionsToClass{scheme = plain}{ctexbook}}
+
+\PassOptionsToClass{\g__options_clist}{ctexbook}
+\PassOptionsToPackage{CJKmath = true}{xeCJK}
+\LoadClass[UTF8]{ctexbook}
+
+\tl_new:N \g__keys_color_tl
+\tl_new:N \g__keys_cite_tl
+\fp_new:N \g__line_spread_fp
+\fp_new:N \g__tab_spread_fp
+\tl_new:N \g__math_spread_tl
+\tl_new:N \g__cap_spread_tl
+\tl_new:N \g__foot_spread_tl
+
+\ctex_define:n
+ {
+ style .meta:nn = {ctex/style}{#1},
+ link .meta:nn = {ctex/link}{#1},
+ spread .meta:nn = {ctex/spread}{#1},
+ style/color .choices:nn =
+ {black,navygreen,navyblue}
+ {\tl_set_eq:NN \g__keys_color_tl\l_keys_choice_tl},
+ style/color .initial:n = black,
+ style/cite .choices:nn =
+ {number,authoryear}
+ {\tl_set_eq:NN \g__keys_cite_tl\l_keys_choice_tl},
+ style/cite .initial:n = number,
+
+ style/thmbox .bool_set:N = \l__thmbox_bool,
+ style/thmbox .default:n = true,
+ style/thmbox .initial:n = false,
+ style/capdash .bool_set:N = \l__capdash_bool,
+ style/capdash .default:n = true,
+ style/capdash .initial:n = false,
+ style/multoc .bool_set:N = \l__multoc_bool,
+ style/multoc .default:n = true,
+ style/multoc .initial:n = false,
+ style/withpart .bool_set:N = \l__chap_withpart_bool,
+ style/withpart .default:n = true,
+ style/withpart .initial:n = false,
+ style/perpart .bool_set:N = \l__foot_perpart_bool,
+ style/perpart .default:n = true,
+ style/perpart .initial:n = false,
+ style/perpage .bool_set:N = \l__foot_perpage_bool,
+ style/perpage .default:n = true,
+ style/perpage .initial:n = false,
+
+ spread/linespread .fp_set:N = \g__line_spread_fp,
+ spread/linespread .initial:n = 1.3,
+ spread/tabspread .fp_set:N = \g__tab_spread_fp,
+ spread/tabspread .initial:n = 1,
+ spread/mathspread .tl_set:N = \g__math_spread_tl,
+ spread/mathspread .initial:n = 1,
+ spread/capspread .tl_set:N = \g__cap_spread_tl,
+ spread/capspread .initial:n = 1,
+ spread/fnspread .tl_set:N = \g__foot_spread_tl,
+ spread/fnspread .initial:n = 1,
+
+ lstlistlistingname .tl_set:N = \lstlistlistingname,
+ lstlistingname .tl_set:N = \lstlistingname
+ }
+
+\RequirePackage[svgnames]{xcolor}
+\cs_new_protected:Nn \__load_color_black:
+ {\definecolorset{HTML}{ctex@}{}{frame,000000;emph,000000;verb,000000}}
+\cs_new_protected:Nn \__load_color_navygreen:
+ {\definecolorset{HTML}{ctex@}{}{frame,005752;emph,004986;verb,a40000}}
+\cs_new_protected:Nn \__load_color_navyblue:
+ {\definecolorset{HTML}{ctex@}{}{frame,005982;emph,eb6877;verb,a4005b}}
+\cs_new_protected:Nn \__load_color:
+ {\use:c {__load_color_ \g__keys_color_tl :}}
+\ctex_at_end_preamble:n {\__load_color:}
+
+\RequirePackage{pdfpages,subfiles}
+\includepdfset{fitpaper = true}
+\RequirePackage[hang,stable]{footmisc}
+\RequirePackage{setspace,zhlineskip}
+\RequirePackage{amsthm,thmtools,cases}
+\RequirePackage[noto,upint]{newtxmath}
+\RequirePackage{chemformula}
+\RequirePackage{chemfig}
+\RequirePackage{siunitx,physics,bm}
+\RequirePackage[normalem]{ulem}
+\RequirePackage[protrusion = false]{microtype}
+\RequirePackage{hologo}
+\hologoSetup{discretionarybreak = true}
+\RequirePackage{rotfloat}
+\RequirePackage{geometry,marginnote,nccfoots,tablefootnote}
+\RequirePackage{fancyhdr,titletoc}
+\RequirePackage{caption,bicaption,subcaption}
+\RequirePackage{graphicx,wrapfig}
+\RequirePackage{zhlipsum,fontawesome,pifont}
+\RequirePackage{tabularx,multirow,makecell,tabu,booktabs}
+\RequirePackage{paralist,tasks}
+\RequirePackage[shortlabels,inline]{enumitem}
+\RequirePackage[most]{tcolorbox}
+\RequirePackage[sort&compress]{gbt7714}
+\RequirePackage[xindy]{imakeidx}
+
+\sys_if_engine_xetex:TF
+ {
+ \cs_new_eq:NN \__set_family:nnn \xeCJK_set_family:nnn
+ \cs_new_eq:NN \__switch_family:n \xeCJK_switch_family:n
+ }{
+ \cs_new_eq:NN \__set_family:nnn \ctex_ltj_set_family:nnn
+ \cs_new_eq:NN \__switch_family:n \ctex_ltj_switch_family:n
+ }
+
+\cs_new_protected:Npn \__setmainfont:nn #1#2
+ {\__fontspec_main_setmainfont:nn {#2}{#1}}
+\cs_new_protected:Npn \__setsansfont:nn #1#2
+ {\__fontspec_main_setsansfont:nn {#2}{#1}}
+\cs_new_protected:Npn \__setmonofont:nn #1#2
+ {\__fontspec_main_setmonofont:nn {#2}{#1}}
+\cs_new_protected:Npn \__setCJKmainfont:nn #1#2
+ {\__set_family:nnn {\CJKrmdefault}{#2}{#1}}
+\cs_new_protected:Npn \__setCJKsansfont:nn #1#2
+ {\__set_family:nnn {\CJKsfdefault}{#2}{#1}}
+\cs_new_protected:Npn \__setCJKmonofont:nn #1#2
+ {\__set_family:nnn {\CJKttdefault}{#2}{#1}}
+\cs_new_protected:Npn \__set_zhfont_songti:nn #1#2
+ {\__set_family:nnn {songti}{#2}{#1}}
+\cs_new_protected:Npn \__set_zhfont_heiti:nn #1#2
+ {\__set_family:nnn {heiti}{#2}{#1}}
+\cs_new_protected:Npn \__set_zhfont_kaishu:nn #1#2
+ {\__set_family:nnn {kaishu}{#2}{#1}}
+\cs_new_protected:Npn \__set_zhfont_fangsong:nn #1#2
+ {\__set_family:nnn {fangsong}{#2}{#1}}
+
+\tl_const:Nn \__option_zhfont:
+ {UprightFont = *,AutoFakeBold = 1.5,ItalicFont = *}
+\cs_new_protected:Npx \__setCJKmainfont:n #1
+ {\__setCJKmainfont:nn {#1}{\__option_zhfont:}}
+\cs_new_protected:Npx \__setCJKsansfont:n #1
+ {\__setCJKsansfont:nn {#1}{\__option_zhfont:}}
+\cs_new_protected:Npx \__setCJKmonofont:n #1
+ {\__setCJKmonofont:nn {#1}{\__option_zhfont:}}
+\cs_new_protected:Npx \__set_zhfont_songti:n #1
+ {\__set_zhfont_songti:nn {#1}{\__option_zhfont:}}
+\cs_new_protected:Npx \__set_zhfont_heiti:n #1
+ {\__set_zhfont_heiti:nn {#1}{\__option_zhfont:}}
+\cs_new_protected:Npx \__set_zhfont_kaishu:n #1
+ {\__set_zhfont_kaishu:nn {#1}{\__option_zhfont:}}
+\cs_new_protected:Npx \__set_zhfont_fangsong:n #1
+ {\__set_zhfont_fangsong:nn {#1}{\__option_zhfont:}}
+
+\bool_if:NT \l__myfont_bool
+ {
+ \__setmainfont:nn {NotoSerif}
+ {
+ Extension = .ttf,
+ UprightFont = *-Regular,
+ BoldFont = *-Bold,
+ ItalicFont = *-Italic
+ }
+ \__setsansfont:nn {NotoSans}
+ {
+ Extension = .ttf,
+ UprightFont = *-Regular,
+ BoldFont = *-Bold,
+ ItalicFont = *-Italic
+ }
+ \__setmonofont:nn {NotoSansMono}
+ {
+ Extension = .ttf,
+ UprightFont = *-Regular,
+ BoldFont = *-Bold
+ }
+ \__setCJKmainfont:nn {FZShuSong-Z01S}
+ {
+ UprightFont = *,
+ BoldFont = FZHei-B01S,
+ ItalicFont = FZKai-Z03S
+ }
+ \__setCJKsansfont:n {FZHei-B01S}
+ \__setCJKmonofont:n {FZFangSong-Z02S}
+ \__set_zhfont_songti:n {FZShuSong-Z01S}
+ \__set_zhfont_heiti:n {FZHei-B01S}
+ \__set_zhfont_kaishu:n {FZKai-Z03S}
+ \__set_zhfont_fangsong:n {FZFangSong-Z02S}
+ \cs_new_protected:Npn \songti{\__switch_family:n {songti}}
+ \cs_new_protected:Npn \heiti{\__switch_family:n {heiti}}
+ \cs_new_protected:Npn \kaishu{\__switch_family:n {kaishu}}
+ \cs_new_protected:Npn \fangsong{\__switch_family:n {fangsong}}
+ }
+\cs_if_exist:NF \kaishu{\cs_gset_eq:NN \kaishu\normalfont}
+
+\bool_if:NT \l__paper_afour_bool
+ {
+ \geometry
+ {
+ a4paper,
+ columnsep = 2\ccwd,
+ vmargin = 2.54cm,
+ hmargin = 3.17cm,
+ headheight = 2.04cm,
+ headsep = 0.5cm,
+ footskip = 0.79cm,
+ footnotesep = 0.5cm,
+ marginparsep = 8pt,
+ marginparwidth = 2.54cm
+ }
+ }
+\bool_if:NT \l__paper_bfive_bool
+ {
+ \geometry
+ {
+ b5paper,
+ columnsep = 2\ccwd,
+ margin = 2.54cm,
+ headheight = 2.09cm,
+ headsep = 0.45cm,
+ footskip = 0.7cm,
+ footnotesep = 0.45cm,
+ marginparsep = 0.25cm,
+ marginparwidth = 2.25cm
+ }
+ }
+
+\cs_gset:Npn \cleardoublepage
+ {
+ \clearpage
+ \bool_if:NT \l__page_twoside_bool
+ {
+ \int_if_odd:nF \c@page
+ {\hbox:n {}\thispagestyle{empty}\clearpage}
+ }
+ }
+\cs_gset:Npn \frontmatter
+ {
+ \cleardoublepage
+ \@mainmatterfalse
+ \pagenumbering{Roman}
+ }
+\pagestyle{fancy}
+\fancyhf{}
+\bool_if:NTF \l__page_twoside_bool
+ {
+ \cs_gset:Npn \chaptermark#1
+ {
+ \markboth
+ {
+ \MakeUppercase
+ {
+ \ifnum\c@secnumdepth>\m@ne
+ \if@mainmatter
+ \ifodd\CTEX@chapter@numbering
+ \CTEXthechapter\hspace{\ccwd}
+ \fi
+ \fi
+ \fi#1
+ }
+ }{
+ \MakeUppercase
+ {
+ \ifnum\c@secnumdepth>\m@ne
+ \if@mainmatter
+ \ifodd\CTEX@chapter@numbering
+ \CTEXthechapter\hspace{\ccwd}
+ \fi
+ \fi
+ \fi#1
+ }
+ }
+ }
+ \fancyhead[EC]{\color{ctex@frame}\kaishu\leftmark}
+ \fancyhead[OC]{\color{ctex@frame}\kaishu\rightmark}
+ \fancyhead[EL,OR]{\color{ctex@frame}\thepage}
+ \cs_gset_eq:NN \ps@plain\ps@empty
+ }{
+ \cs_gset:Npn \chaptermark#1
+ {
+ \markboth
+ {
+ \MakeUppercase
+ {
+ \ifnum\c@secnumdepth>\m@ne
+ \if@mainmatter
+ \ifodd\CTEX@chapter@numbering
+ \CTEXthechapter\hspace{\ccwd}
+ \fi
+ \fi
+ \fi#1
+ }
+ }{}
+ }
+ \fancyhead[L]{\color{ctex@frame}\kaishu\leftmark}
+ \fancyhead[R]{\color{ctex@frame}\kaishu\rightmark}
+ \fancyfoot[C]{\color{ctex@frame}\thepage}
+ \fancypagestyle{plain}
+ {
+ \fancyhf{}\cs_gset:Npn\headrule{}
+ \fancyfoot[C]{\color{ctex@frame}\thepage}
+ }
+ }
+\cs_gset:Npn \sectionmark#1
+ {
+ \markright
+ {
+ \ifnum\c@secnumdepth>\z@
+ \ifodd\CTEX@section@numbering
+ \CTEXthesection\hspace{0.5\ccwd}
+ \fi
+ \fi#1
+ }
+ }
+\cs_gset:Npn \headrule
+ {
+ \color{ctex@frame}\vspace{2.5pt}
+ \hrule width\textwidth height 0.75pt
+ }
+\bool_if:NT \l__draft_bool
+ {
+ \bool_if:NTF \l__page_twoside_bool
+ {\fancyfoot[C]{\color{gray!60}\sffamily\today}}
+ {\fancyhead[C]{\color{gray!60}\sffamily\today}}
+ \geometry{showframe}
+ }
+
+\titlecontents{part}
+ [0\ccwd]
+ {\addvspace{1pc}\sffamily\large}
+ {}
+ {}
+ {\normalsize\titlerule*{}\bf\contentspage}
+\titlecontents{chapter}
+ [0\ccwd]
+ {\addvspace{1pc}\sffamily\large}
+ {\thecontentslabel\hspace{\ccwd}}
+ {}
+ {\normalsize\titlerule*[0.55pc]{\scalebox{1.2}{$\cdot$}}\bf\contentspage}
+\titlecontents{section}
+ [1.5\ccwd]
+ {\addvspace{0.35pc}}
+ {\thecontentslabel\hspace{\ccwd}}
+ {}
+ {\titlerule*[0.55pc]{\scalebox{1.2}{$\cdot$}}\contentspage}
+\titlecontents{subsection}
+ [3.8\ccwd]
+ {\addvspace{0.35pc}}
+ {\thecontentslabel\hspace{\ccwd}}
+ {}
+ {\titlerule*[0.55pc]{\scalebox{1.2}{$\cdot$}}\contentspage}
+\titlecontents{figure}
+ [0\ccwd]
+ {\addvspace{0.2pc}}
+ {\thecontentslabel\hspace{\ccwd}}
+ {}
+ {\titlerule*[0.55pc]{\scalebox{1.2}{$\cdot$}}\contentspage}
+\titlecontents{table}
+ [0\ccwd]
+ {\addvspace{0.2pc}}
+ {\thecontentslabel\hspace{\ccwd}}
+ {}
+ {\titlerule*[0.55pc]{\scalebox{1.2}{$\cdot$}}\contentspage}
+\contentsuse{lstlisting}{lol}
+\titlecontents{lstlisting}
+ [0\ccwd]
+ {\addvspace{0.2pc}}
+ {\thecontentslabel\hspace{\ccwd}}
+ {}
+ {\titlerule*[0.55pc]{\scalebox{1.2}{$\cdot$}}\contentspage}
+
+\cs_gset:Npn \tableofcontents
+ {
+ \if@twocolumn
+ \@restonecoltrue\onecolumn
+ \bool_if:NT \l__multoc_bool{\twocolumn}
+ \else
+ \@restonecolfalse
+ \bool_if:NT \l__multoc_bool{\twocolumn}
+ \fi
+ \chapter*{\contentsname}
+ \bool_if:NTF \l__page_twoside_bool
+ {\markboth{\MakeUppercase\contentsname}{\MakeUppercase\contentsname}}
+ {\markboth{\MakeUppercase\contentsname}{}}
+ \vspace*{-1pc}
+ \@starttoc{toc}
+ \if@restonecol
+ \twocolumn
+ \else
+ \onecolumn
+ \fi
+ }
+\cs_gset:Npn \listoffigures
+ {
+ \if@twocolumn
+ \@restonecoltrue\onecolumn
+ \bool_if:NT \l__multoc_bool{\twocolumn}
+ \else
+ \@restonecolfalse
+ \bool_if:NT \l__multoc_bool{\twocolumn}
+ \fi
+ \chapter*{\phantomsection\listfigurename}
+ \addcontentsline{toc}{chapter}{\listfigurename}
+ \bool_if:NTF \l__page_twoside_bool
+ {\markboth{\MakeUppercase\listfigurename}{\MakeUppercase\listfigurename}}
+ {\markboth{\MakeUppercase\listfigurename}{}}
+ \vspace*{-1pc}
+ \@starttoc{lof}
+ \if@restonecol
+ \twocolumn
+ \else
+ \onecolumn
+ \fi
+ }
+\cs_gset:Npn \listoftables
+ {
+ \if@twocolumn
+ \@restonecoltrue\onecolumn
+ \bool_if:NT \l__multoc_bool{\twocolumn}
+ \else
+ \@restonecolfalse
+ \bool_if:NT \l__multoc_bool{\twocolumn}
+ \fi
+ \chapter*{\phantomsection\listtablename}
+ \addcontentsline{toc}{chapter}{\listtablename}
+ \bool_if:NTF \l__page_twoside_bool
+ {\markboth{\MakeUppercase\listtablename}{\MakeUppercase\listtablename}}
+ {\markboth{\MakeUppercase\listtablename}{}}
+ \vspace*{-1pc}
+ \@starttoc{lot}
+ \if@restonecol
+ \twocolumn
+ \else
+ \onecolumn
+ \fi
+ }
+\cs_new:Npn \listoflistings
+ {
+ \begingroup
+ \@ifundefined{@restonecoltrue}{}
+ {
+ \if@twocolumn
+ \@restonecoltrue\onecolumn
+ \bool_if:NT \l__multoc_bool{\twocolumn}
+ \else
+ \@restonecolfalse
+ \bool_if:NT \l__multoc_bool{\twocolumn}
+ \fi
+ }
+ \chapter*{\phantomsection\lstlistlistingname}
+ \addcontentsline{toc}{chapter}{\lstlistlistingname}
+ \bool_if:NTF \l__page_twoside_bool
+ {\markboth{\MakeUppercase\lstlistlistingname}{\MakeUppercase\lstlistlistingname}}
+ {\markboth{\MakeUppercase\lstlistlistingname}{}}
+ \vspace*{-0.2pc}
+ \@starttoc{lol}
+ \@ifundefined{@restonecoltrue}{}
+ {
+ \if@restonecol
+ \twocolumn
+ \else
+ \onecolumn
+ \fi
+ }
+ \endgroup
+ }
+
+\cs_gset:Npn \bibsection{\chapter{\bibname}}
+\skip_set:Nn \bibsep{0ex}
+\cs_new_protected:Npn \__load_cite_number:
+ {
+ \setcitestyle{square,comma,super}
+ \bibliographystyle{gbt7714-numerical}
+ }
+\cs_new_protected:Nn \__load_cite_authoryear:
+ {\bibliographystyle{gbt7714-author-year}}
+\cs_new_protected:Nn \__load_cite:
+ {\use:c {__load_cite_ \g__keys_cite_tl :}}
+\ctex_at_end_preamble:n {\__load_cite:}
+\makeindex[
+ intoc,
+ options = -M~texindy~-C~utf8,
+ program = truexindy,
+ columns = 2,
+ columnsep = 2\ccwd
+ ]
+\indexsetup
+ {
+ level = \chapter*,
+ toclevel = chapter,
+ firstpagestyle = plain
+ }
+\patchcmd\imki@indexheaders
+ {\@mkboth{\MakeUppercase\indexname}{\MakeUppercase\indexname}}
+ {
+ \bool_if:NTF \l__page_twoside_bool
+ {\markboth{\MakeUppercase\indexname}{\MakeUppercase\indexname}}
+ {\markboth{\MakeUppercase\indexname}{}}
+ }
+ {}{}
+
+\DeclareCaptionLabelSeparator{ccwd}{\hspace{\ccwd}}
+\DeclareCaptionLabelFormat{parens}{\bothIfFirst{#1}{~}(#2)}
+\captionsetup
+ {
+ format = hang,
+ % figurewithin = section,
+ % tablewithin = section,
+ labelfont = {sf,small,color = ctex@frame},
+ labelsep = ccwd,
+ textfont = {sf,small,stretch = \g__cap_spread_tl},
+ belowskip = 0pt,aboveskip = 10pt
+ }
+\captionsetup[subfigure]
+ {
+ labelfont = {sf,small,color = ctex@frame},
+ labelformat = parens,
+ belowskip = 2pt,aboveskip = 6pt
+ }
+\captionsetup[lstlisting]{singlelinecheck = false}
+\captionsetup[figure][bi-second]{name = Figure}
+\captionsetup[table][bi-second]{name = Table}
+\cs_new:Npn \__arabic:n #1{\int_to_arabic:v {c@#1}}
+\AtBeginDocument
+ {
+ \bool_if:NT \l__capdash_bool
+ {
+ \cs_gset:Npn \thefigure{\thechapter\textendash\__arabic:n {figure}}
+ \cs_gset:Npn \thetable{\thechapter\textendash\__arabic:n {table}}
+ \cs_gset:Npn \thelstlisting{\thechapter\textendash\__arabic:n {lstlisting}}
+ }
+ }
+\AtBeginEnvironment{tabularx}
+ {\exp_args:Nx \linespread{\fp_use:N \g__tab_spread_fp}\selectfont\ignorespaces}
+\AtBeginEnvironment{tabular}
+ {\exp_args:Nx \linespread{\fp_use:N \g__tab_spread_fp}\selectfont\ignorespaces}
+
+\skip_set:Nn \parskip{0pt plus 2pt minus 1pt}
+\skip_set:Nn \floatsep{12pt plus 2pt minus 2pt}
+\skip_set:Nn \intextsep{14pt plus 2pt minus 2pt}
+\skip_set:Nn \textfloatsep{16pt plus 2pt minus 4pt}
+\skip_set:Nn \dbltextfloatsep{16pt plus 2pt minus 4pt}
+\skip_set:Nn \@fpsep{8pt plus 2.0fil}
+\setcounter{topnumber}{4}
+\setcounter{bottomnumber}{4}
+\setcounter{totalnumber}{8}
+\cs_gset:Npn \textfraction{0.18}
+\cs_gset:Npn \topfraction{0.85}
+\cs_gset:Npn \bottomfraction{0.65}
+\cs_gset:Npn \floatpagefraction{0.60}
+\ctex_after_end_preamble:n
+ {\exp_args:Nx \linespread{\fp_use:N \g__line_spread_fp}\selectfont}
+
+\newcolumntype{L}{X}
+\newcolumntype{C}{>{\centering\arraybackslash}X}
+\newcolumntype{R}{>{\raggedleft\arraybackslash}X}
+\graphicspath{{figures/}}
+\DeclareGraphicsExtensions{.pdf,.png,.jpg,.eps,.tif}
+
+\setlist
+ {
+ labelsep = .75\ccwd,listparindent = 2\ccwd,
+ itemsep = .75ex plus .1ex,parsep = 0ex,topsep = .75ex plus .1ex,partopsep = 0ex
+ }
+\setlist[itemize,1]
+ {label = \color{ctex@emph}\ensuremath{\bullet},leftmargin = *}
+\setlist[itemize,2]
+ {label = \color{ctex@emph}\ensuremath{\circ},leftmargin = *}
+\setlist[enumerate,1]
+ {label = \color{ctex@emph}\arabic*.,ref = \arabic*,leftmargin = *}
+\setlist[enumerate,2]
+ {label = \color{ctex@emph}(\alph*),ref = \theenumi(\alph*),leftmargin = *}
+\setlist[description]
+ {font = \color{ctex@emph}\sf,labelwidth = *,leftmargin = 2\ccwd}
+\newlist{outlinelist}{itemize}{1}
+\setlist[outlinelist]
+ {label = \color{ctex@emph}\upshape\ding{112},itemsep = .5ex plus .1ex,leftmargin = *}
+\skip_set:Nn \pltopsep{.75ex plus .1ex}
+\skip_set:Nn \plpartopsep{0ex}
+\skip_set:Nn \plitemsep{.75ex plus .1ex}
+\skip_set:Nn \plparsep{0ex}
+\cs_new:Npn \circled#1
+ {
+ \lower .7ex
+ \hbox{\tikz\draw(0pt,0pt)circle(.5\ccwd)node{\makebox[\ccwd][c]{\small#1}};}
+ }
+
+\tl_new:N \theoremname
+\tl_new:N \definitioname
+\tl_new:N \lemmaname
+\tl_new:N \corollaryname
+\tl_new:N \propositioname
+\tl_new:N \examplename
+\tl_new:N \remarkname
+\tl_new:N \exercisename
+
+\bool_if:NTF \l__lang_chinese_bool
+ {
+ \tl_set:Nn \theoremname{定理}
+ \tl_set:Nn \definitioname{定义}
+ \tl_set:Nn \lemmaname{引理}
+ \tl_set:Nn \corollaryname{推论}
+ \tl_set:Nn \propositioname{性质}
+ \tl_set:Nn \examplename{例}
+ \tl_set:Nn \remarkname{注}
+ \tl_set:Nn \exercisename{练习}
+ }{
+ \tl_set:Nn \theoremname{Theorem}
+ \tl_set:Nn \definitioname{Definition}
+ \tl_set:Nn \lemmaname{Lemma}
+ \tl_set:Nn \corollaryname{Corollary}
+ \tl_set:Nn \propositioname{Proposition}
+ \tl_set:Nn \examplename{Example}
+ \tl_set:Nn \remarkname{Remark}
+ \tl_set:Nn \exercisename{Exercise}
+ }
+
+\declaretheoremstyle[
+ spaceabove = .75ex plus .1ex,
+ spacebelow = .75ex plus .1ex,
+ headindent = 0\ccwd,
+ headfont = \color{ctex@emph}\sffamily,
+ notefont = {},
+ notebraces = {}{},
+ bodyfont = \normalfont,
+ headpunct = {.},
+ postheadspace = \ccwd,
+ numberwithin = chapter,
+ headformat = \NAME\space\NUMBER\NOTE
+ ]{mythm}
+\declaretheorem[style = mythm,name = \theoremname]{theorem}
+\declaretheorem[style = mythm,name = \definitioname]{definition}
+\declaretheorem[style = mythm,name = \lemmaname]{lemma}
+\declaretheorem[style = mythm,name = \corollaryname]{corollary}
+\declaretheorem[style = mythm,name = \propositioname]{proposition}
+\declaretheorem[style = mythm,name = \examplename]{example}
+\cs_gset_eq:NN \proof\relax
+\declaretheorem{remark}[
+ style = mythm,
+ name = \faCommentingO\space\remarkname,
+ numbered = no
+ ]
+\declaretheorem{proof}[
+ style = mythm,
+ name = \faPencilSquareO\space\proofname,
+ numbered = no,
+ qed = \qedsymbol
+ ]
+
+\settasks
+ {
+ label = (\Alph*),
+ after-item-skip = 0ex plus .1ex,
+ column-sep = .5\ccwd,
+ item-indent = 2\ccwd,
+ label-width = 1.5\ccwd
+ }
+\setchemformula
+ {
+ math-scripts = false,
+ charge-hshift = 0.25\ccwd,
+ subscript-vshift = -0.2ex
+ }
+\sisetup
+ {
+ detect-family,
+ detect-weight,
+ detect-shape,
+ detect-inline-family = math,
+ detect-inline-weight = math,
+ detect-display-math,
+ unit-math-rm = \mathrm,
+ number-math-rm = \mathrm,
+ table-parse-only,
+ group-digits = false
+ }
+\allowdisplaybreaks[4]
+\cs_gset:Npn \ULthickness{.75pt}
+\SetMathEnvironmentSinglespace{\g__math_spread_tl}
+\skip_set:Nn \jot{4pt plus 1pt minus 1pt}
+\ctex_after_end_preamble:n
+ {
+ \skip_set:Nn \abovedisplayskip{5pt plus 1pt minus 1pt}
+ \skip_set:Nn \belowdisplayskip{5pt plus 1pt minus 1pt}
+ \skip_set:Nn \abovedisplayshortskip{0pt}
+ \skip_set:Nn \belowdisplayshortskip{5pt plus 1pt minus 1pt}
+ }
+\cs_gset:Npn \tagform@#1
+ {\maketag@@@{\color{ctex@emph}(\ignorespaces#1\unskip\@@italiccorr)}}
+
+\tcbset
+ {
+ thmsty/.style =
+ {
+ enhanced~jigsaw,pad~at~break* = 3pt,
+ opacityback = 0,
+ colframe = ctex@emph,
+ left = .2pc,right = .2pc,top = .5pc,bottom = .5pc,middle= .5pc,
+ arc = 0pt
+ },
+ outlinesty/.style =
+ {
+ enhanced,nofloat,
+ tikznode~boxed~title,
+ interior~style = white,colframe = ctex@emph,
+ colbacktitle = white,coltitle = ctex@emph,
+ fonttitle = \large\sffamily,fontupper = \itshape,
+ boxed~title~style = {size = normal,opacityframe = 0,boxrule = 0pt},
+ attach~boxed~title~to~top~center = {yshift = -\tcboxedtitleheight/2},
+ arc = 3pt,
+ after~skip = 3ex,
+ left = 1.5pc,right = 1.5pc,top = 1pc,bottom = 0.5pc,
+ boxsep = 5pt
+ },
+ exsty/.style =
+ {
+ enhanced,on~line,
+ arc = 5pt,
+ fontupper = \sffamily\Large,
+ boxrule = 1pt,boxsep = 0pt,
+ left = 6pt,right = 6pt,top = 3.5pt,bottom = 3.5pt,
+ before~skip = 4ex,after~skip = 2.25ex
+ },
+ breakable,
+ boxrule = .75pt
+ }
+\ctex_at_end_preamble:n
+ {
+ \bool_if:NT \l__thmbox_bool
+ {
+ \tcolorboxenvironment{theorem}{thmsty}
+ \tcolorboxenvironment{definition}{thmsty}
+ \tcolorboxenvironment{lemma}{thmsty}
+ \tcolorboxenvironment{corollary}{thmsty}
+ \tcolorboxenvironment{proposition}{thmsty}
+ \tcolorboxenvironment{example}{thmsty}
+ }
+ }
+\NewDocumentEnvironment{outline}{O{\abstractname}}
+ {
+ \begin{tcolorbox}[outlinesty,title = #1]
+ \begin{outlinelist}
+ }{
+ \end{outlinelist}
+ \end{tcolorbox}
+ }
+\NewDocumentEnvironment{exercise}{sO{black}O{1.}O{\exercisename}}
+ {
+ \IfBooleanF{#1}
+ {
+ \refstepcounter{section}
+ \addcontentsline{toc}{section}{\CTEXthesection\hspace{\ccwd}#4}
+ \markright
+ {
+ \ifnum\c@secnumdepth>\z@
+ \CTEXthesection\hspace{0.5\ccwd}
+ \fi#4
+ }
+ }
+ \begin{center}
+ \bool_if:NTF \l__thmbox_bool
+ {
+ \tcbox[
+ exsty,
+ colback = #2!8!white,colframe = #2!50!black,
+ drop~fuzzy~shadow = #2!50!white,
+ ]{\IfBooleanF{#1}{\CTEXthesection\hspace{0.5\ccwd}}#4}
+ }{
+ \sffamily\Large\IfBooleanF{#1}{\CTEXthesection\hspace{0.5\ccwd}}#4
+ }
+ \end{center}
+ \begin{compactenum}[#3]
+ }{
+ \end{compactenum}
+ }
+\DeclareTColorBox{mybox}{so}
+ {
+ enhanced~jigsaw,pad~at~break* = 3pt,
+ IfBooleanF = {#1}{opacityback = 0,colframe = ctex@emph},
+ coltitle = black,opacitybacktitle = 0,
+ fonttitle = \sffamily,
+ left = .2pc,right = .2pc,top = .5pc,bottom = .5pc,middle= .5pc,
+ arc = 0pt,
+ toptitle = 2pt,bottomtitle = 2pt,
+ beforeafter~skip=2ex,
+ halign~upper = left,halign~lower = left,
+ center~title,
+ IfValueT = {#2}{title = #2}
+ }
+\NewTCBox{\fuzzy}{O{yellow}O{}}
+ {nobeforeafter,tcbox~raise~base,blank,fuzzy~halo = 2pt~with~#1,#2}
+\DeclareTotalTCBox{\concise}{O{Aqua}O{}v}
+ {
+ nobeforeafter,tcbox~raise~base,
+ top = 2pt,bottom = 2.5pt,left = 2pt,right = 2pt,
+ boxsep = 0pt,arc = 1pt,
+ colback = #1!15!white,#2
+ }{#3}
+
+\skip_set:Nn \footnotemargin{0.5\ccwd}
+\skip_set:Nn \footnotesep{0ex}
+\cs_gset:Npn \hangfootparskip{0ex}
+\cs_gset:Npn \footnoterule
+ {
+ \color{ctex@frame}\hrule width 0.35\columnwidth height 0.75pt
+ \vspace*{2.6pt}\color{black}
+ }
+\bool_if:NT \l__lang_chinese_bool
+ {\cs_gset:Npn \hangfootparindent{2\ccwd}}
+\ctex_at_end_preamble:n
+ {
+ \bool_if:NT \l__chap_withpart_bool
+ {\counterwithin*{chapter}{part}}
+ \bool_if:NT \l__foot_perpart_bool
+ {
+ \counterwithout*{footnote}{chapter}
+ \counterwithin*{footnote}{part}
+ }
+ \bool_if:NT \l__foot_perpage_bool
+ {
+ \counterwithout*{footnote}{chapter}
+ \counterwithin*{footnote}{page}
+ }
+ }
+\patchcmd\@footnotetext
+ {\def\baselinestretch{\ZhLS@footlinespread}}
+ {\def\baselinestretch{\g__foot_spread_tl}}
+ {}{}
+\patchcmd\@mpfootnotetext
+ {\def\baselinestretch{\ZhLS@footlinespread}}
+ {\def\baselinestretch{\g__foot_spread_tl}}
+ {}{}
+\patchcmd\@makefnmark
+ {\normalfont}
+ {\normalfont\rmfamily}
+ {}{}
+\cs_gset:Npn \marginfont{\sffamily\footnotesize}
+
+\lstdefinestyle{mystyle}
+ {
+ language = [LaTeX]TeX,
+ texcsstyle = *\lst@ifdisplaystyle\bfseries\color{ctex@emph}\else\color{ctex@verb}\fi,
+ basicstyle = \ttfamily\lst@ifdisplaystyle\small\else\color{ctex@verb}\fi,
+ framexleftmargin = 0pt,
+ framexrightmargin = 0pt,
+ xleftmargin = 0pt,
+ xrightmargin = 0pt,
+ framesep = 3pt,
+ frame = lines,
+ rulecolor = \color{ctex@frame},
+ commentstyle = \color{gray},
+ emphstyle = \color{ctex@emph},
+ emph =
+ {
+ amsmath,align,aligned,chemfig,cleveref,cases,caption,chemformula,compactenum,description,enumitem,enumerate,exercise,easybook,footmisc,hang,itemize,imakeidx,listings,LaTeX,multline,mybox,paralist,Python,siunitx,split,subnumcases,subcaption,tabularx,thmtools,xcolor
+ },
+ keywordstyle = \lst@ifdisplaystyle\bfseries\color{ctex@emph}\else\color{ctex@verb}\fi,
+ morekeywords =
+ {
+ includegraphics,setmainfont,setsansfont,setmonofont,setCJKmainfont,setCJKsansfont,setCJKmonofont,setCJKfamilyfont,RequirePackage
+ }
+ }
+\lstset
+ {
+ style = mystyle,
+ breaklines = true,
+ resetmargins = true,
+ numbers = left,
+ numberstyle = \small,
+ abovecaptionskip = -1ex,
+ belowcaptionskip = 1ex,
+ aboveskip = 1.5ex plus .2ex minus .1ex,
+ belowskip = 0.55ex plus .2ex minus .1ex,
+ keepspaces = true,
+ framerule = 0.75pt,
+ columns = flexible
+ }
+\lstloadlanguages{C,C++,Java,Python,Matlab}
+\AtBeginEnvironment{verbatim}{\microtypesetup{activate=false}}
+
+\cs_new_protected:Npn \__clist_put_hyperref:n #1
+ {\clist_gput_right:Nn \g__hyperref_clist{#1}}
+\cs_new_protected:Npn \__define_linkcolor:nnn #1#2#3
+ {\definecolorset{HTML}{ctex@}{}{link,#1;url,#2;cite,#3}}
+\cs_new:Npn \__set_linkcolor:n #1
+ {
+ linkcolor/\clist_item:nn {#1}{1} .code:n =
+ {
+ \__define_linkcolor:nnn
+ {\clist_item:nn {#1}{2}}
+ {\clist_item:nn {#1}{3}}
+ {\clist_item:nn {#1}{4}}
+ \__clist_put_hyperref:n
+ {
+ linkcolor = ctex@link,linkbordercolor = ctex@link,
+ urlcolor = ctex@url,urlbordercolor = ctex@url,
+ citecolor = ctex@cite,citebordercolor = ctex@cite
+ }
+ },
+ }
+\cs_new:Npn \__allow_urlbreak:
+ {
+ \cs_new:Npn \__add_urlbreak_points:
+ {\tl_map_function:NN \c__urlbreak_points_tl\do}
+ \__appto_cmd:Nn
+ \UrlBreaks{\UrlOrds\__add_urlbreak_points:}
+ }
+\tl_const:Nn \c__urlbreak_points_tl
+ {ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789}
+
+\keys_define:nx {ctex/link}
+ {
+ hyperlink .choice:,
+ hyperlink .value_required:n = true,
+ hyperlink/edge .code:n = {},
+ hyperlink/various .code:n = {\__clist_put_hyperref:n {colorlinks}},
+ hyperlink/none .code:n = {\__clist_put_hyperref:n {hidelinks}},
+ hyperlink .default:n = edge,
+ hyperlink .initial:n = edge,
+
+ linkcolor .choice:,
+ linkcolor .value_required:n = true,
+ \clist_map_function:nN
+ {
+ {darkgray, 626262,0000B2,005752},
+ {lightblue, 0000ff,004986,eb6877},
+ {crimson, dc143c,00c1c9,afcd20},
+ {hotpink, ff69b4,9d5196,57b5e5}
+ }
+ \__set_linkcolor:n,
+ linkcolor .default:n = darkgray,
+ linkcolor .initial:n = darkgray,
+
+ linktopage .choice:,
+ linktopage .value_required:n = true,
+ linktopage/true .code:n = {\__clist_put_hyperref:n {linktocpage}},
+ linktopage/false .code:n = {\__clist_put_hyperref:n {linktocpage = false}},
+ linktopage .default:n = true,
+ linktopage .initial:n = false
+ }
+
+\RequirePackage[
+ lang = {chinese-utf8},
+ type = {CC},
+ modifier = {by-nc},
+ version = {4.0}
+ ]{doclicense}
+
+\ctex_at_end_preamble:n
+ {
+ \RequirePackage[pdfstartview = FitH,bookmarksnumbered]{hyperref}
+ \RequirePackage{cleveref}
+ \urlstyle{same}
+ \exp_args:NV \hypersetup\g__hyperref_clist
+ \__allow_urlbreak:
+
+ \bool_if:NTF \l__lang_chinese_bool
+ {
+ \keys_set_known:nn {ctex}
+ {
+ contentsname = {目\hspace{\ccwd}录},
+ indexname = {索\hspace{\ccwd}引},
+ listfigurename = {图片索引},
+ listtablename = {表格索引},
+ abstractname = {摘\hspace{\ccwd}要},
+ lstlistlistingname = {代码索引},
+ lstlistingname = {\faCode 代码}
+ }
+ \crefformat{equation}{#2式(#1)#3}
+ \crefformat{align}{#2式(#1)#3}
+ \crefformat{multline}{#2式(#1)#3}
+ \crefformat{gather}{#2式(#1)#3}
+ \crefformat{figure}{#2图#1#3}
+ \crefformat{table}{#2表#1#3}
+ \crefformat{chapter}{#2第#1章#3}
+ \crefformat{section}{#2节#1#3}
+ \crefformat{subsection}{#2小节#1#3}
+ \crefformat{theorem}{#2定理#1#3}
+ \crefformat{definition}{#2定义#1#3}
+ \crefformat{lemma}{#2引理#1#3}
+ \crefformat{corollary}{#2推论#1#3}
+ \crefformat{proposition}{#2性质#1#3}
+ \crefformat{example}{#2例#1#3}
+ }{
+ \keys_set_known:nn {ctex}
+ {
+ abstractname = {Abstract},
+ lstlistlistingname = {List~of~Listings},
+ lstlistingname = {\faCode\space Code}
+ }
+ \crefformat{equation}{#2Equation~(#1)#3}
+ \crefformat{align}{#2Equation~(#1)#3}
+ \crefformat{multline}{#2Equation~(#1)#3}
+ \crefformat{gather}{#2Equation~(#1)#3}
+ \crefformat{figure}{#2Figure~#1#3}
+ \crefformat{table}{#2Table~#1#3}
+ \crefformat{chapter}{#2Chapter~#1#3}
+ \crefformat{section}{#2Section~#1#3}
+ \crefformat{subsection}{#2Subsection~#1#3}
+ \crefformat{theorem}{#2Theorem~#1#3}
+ \crefformat{definition}{#2Definition~#1#3}
+ \crefformat{lemma}{#2Lemma~#1#3}
+ \crefformat{corollary}{#2Corollary~#1#3}
+ \crefformat{proposition}{#2Proposition~#1#3}
+ \crefformat{example}{#2Example~#1#3}
+ }
+ }
+
+\ctex_set:n
+ {
+ secnumdepth = 3,
+ tocdepth = 1,
+ part =
+ {
+ pagestyle = empty,
+ number =
+ {\bool_if:NTF \l__zhtitle_bool{\chinese{part}}{\thepart}},
+ format = {\color{ctex@frame}\sffamily\Huge},
+ aftername =
+ {\bool_if:NTF \l__newline_bool{\par\nobreak}{\hspace{\ccwd}}},
+ tocline = {\CTEXifname{\CTEXthepart\hspace{\ccwd}}{}#2}
+ },
+ chapter =
+ {
+ % pagestyle = fancy,
+ number =
+ {\bool_if:NTF \l__zhtitle_bool{\chinese{chapter}}{\thechapter}},
+ format =
+ {
+ \color{ctex@frame}\sffamily\LARGE
+ \bool_if:NF \l__newline_bool{\centering}
+ },
+ aftername =
+ {\bool_if:NTF \l__newline_bool{\par\nobreak\vskip 1.5pc}{\hspace{\ccwd}}},
+ beforeskip = -1.5ex,
+ afterskip = 3ex,
+ lotskip = 0.8pc,
+ lofskip = 0.8pc,
+ tocline = {\CTEXifname{\protect\numberline{\CTEXthechapter}}{}#2}
+ },
+ section =
+ {
+ hang = true,
+ format = {\color{ctex@frame}\sffamily\Large},
+ aftername = {\hspace{0.5\ccwd}},
+ beforeskip = 1.5ex plus .2ex minus .1ex,
+ afterskip = 1.5ex plus .2ex minus .1ex,
+ tocline = {\CTEXifname{\protect\numberline{\CTEXthesection}}{}#2}
+ },
+ subsection =
+ {
+ hang = true,
+ format = {\color{ctex@frame}\sffamily\large},
+ aftername = {\hspace{0.5\ccwd}},
+ beforeskip = 1.3ex plus .2ex minus .1ex,
+ afterskip = 1.3ex plus .2ex minus .1ex,
+ tocline = {\CTEXifname{\protect\numberline{\CTEXthesubsection}}{}#2}
+ },
+ subsubsection =
+ {
+ hang = true,
+ format = {\color{ctex@frame}\sffamily},
+ aftername = {\hspace{0.5\ccwd}},
+ beforeskip = \parskip,
+ afterskip = \parskip
+ }
+ }
+
+\bool_if:NF \l__newline_bool
+ {
+ \ctex_set:n
+ {
+ part/hang = true,
+ chapter/hang = true
+ }
+ }
+%%
+%% End of file `easybook.cls'. \ No newline at end of file
diff --git a/macros/latex/contrib/easybook/pages/appendix.tex b/macros/latex/contrib/easybook/pages/appendix.tex
new file mode 100644
index 0000000000..f5981487b1
--- /dev/null
+++ b/macros/latex/contrib/easybook/pages/appendix.tex
@@ -0,0 +1,11 @@
+% 附录
+\documentclass[../easybook-demo]{subfiles}
+\begin{document}
+
+\appendix
+\chapter{维基百科}
+
+\section{阿司匹林}
+\zhlipsum[50-52][name = aspirin]
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/easybook/pages/chapter1.tex b/macros/latex/contrib/easybook/pages/chapter1.tex
new file mode 100644
index 0000000000..280e356900
--- /dev/null
+++ b/macros/latex/contrib/easybook/pages/chapter1.tex
@@ -0,0 +1,125 @@
+% Chapter 1
+\documentclass[../easybook-demo]{subfiles}
+\begin{document}
+
+\chapter{常用环境}
+
+\section{公式}\index{g@公式}
+\lstinline{amsmath} 宏包提供多种公式环境以及许多相关的排版命令,可用以改进和提高数学结构的排版效果。\textsf{注意,公式前不要空行。}
+\begin{equation}\label{eq1}
+ \bm{A} = \left[
+ \begin{matrix}
+ a_{11} & a_{12} & \cdots & a_{1n} \\
+ a_{21} & a_{22} & \cdots & a_{2n} \\
+ \vdots & \vdots & \ddots & \vdots \\
+ a_{m1} & a_{m2} & \cdots & a_{mn} \\
+ \end{matrix}
+ \right] = \left[
+ \begin{matrix}
+ \bm{a}_1 & \bm{a}_2 & \cdots & \bm{a}_n
+ \end{matrix}
+ \right]
+\end{equation}
+可以通过添加标签在正文中引用公式,如带有中文括号的引用\cref{eq1}。
+
+\lstinline{align} 环境用于\textsf{两个及以上}需要垂直对齐的公式,一般的像等于号之类的二元算符是被对齐的。变体的块环境 \lstinline{aligned} 使得内容的长度就是它的\textsf{实际长度},可以用作包含表达式的组件。\lstinline{split} 环境是针对\textsf{单个长公式},使用\& 标记对齐点。\lstinline{split} 环境不提供编号,只能在其他行间公式结构中使用。
+\begin{equation}
+ \begin{split}
+ \iint_{A}E\rho(\bm{v}\cdot\bm{n})\mathrm{d}A+\frac{\partial}{\partial t}\iiint_{V}E\rho \mathrm{d}V & = \frac{\delta Q}{\mathrm{d}t}-\frac{\delta W}{\mathrm{d}t}
+ \\
+ \iint_{A}\left(U+\frac{v^{2}}{2}+gz+\frac{P}{\rho}\right)\rho(\bm{v}\cdot\bm{n})\mathrm{d}A+\frac{\partial}{\partial t}\iiint_{V}E\rho\mathrm{d}V & = \frac{\delta Q}{\mathrm{d}t}-\frac{\delta W_{s}}{\mathrm{d}t}
+ \end{split}
+\end{equation}
+
+调用 \lstinline{cases} 括号宏包提供的左花括号 \lstinline{subnumcases} 环境,可将花括号右侧的每行公式都给出一个子序号。
+\begin{subnumcases}{y =}
+ C_1e^{r_1x}+C_2e^{r_2x} & \quad $p^2-4q > 0$
+ \\
+ \left(C_1+C_2\right)e^{r_1x} & \quad $p^2-4q=0$
+ \\
+ e^{\alpha x}\left(C_1\cos\beta x+C_2\sin\beta x\right) & \quad $p^2-4q<0$
+\end{subnumcases}
+
+\lstinline{multline} 环境适用于一行无法放下的公式。\lstinline{multline} 的第一行在最左边,最后一行在最右边,除了在两边有缩进量,中间的任何其他行都会在行间公式宽度内独立居中,例子见\cref{defi1}。
+
+\clearpage
+\section{插图}\index{c@插图}
+当我们需要排列一组子图共享标题的图片时,可以使用依赖于 \lstinline{caption} 宏包的 \lstinline{subcaption} 宏包的功能,效果见\cref{fig1}。
+\begin{figure}[htbp]
+ \centering
+ \subcaptionbox{并排子图1}
+ {\includegraphics[width=0.4\textwidth]{example-image-4x3}}
+ \hspace{1.2em}
+ \subcaptionbox{并排子图2}
+ {\includegraphics[width=0.4\textwidth]{example-image-4x3}}
+ \bicaption[使用subcaption排版子图]{使用subcaption宏包的subcaptionbox命令排版子图}[Use subcaption to typeset subgraphs]{Use the subcaptionbox command of the subcaption package to typeset sub-pictures}\label{fig1}
+\end{figure}
+
+\section{表格}\index{b@表格}
+合并表格列使用 \lstinline{\multicolumn} 命令,合并行使用 \lstinline{\multirowcell} 命令。当插入的表格内容过长以至于一行放不下的情况可以使用 \lstinline{tabularx} 环境,设置了\textsf{L、C和R}三个列对齐选项,一个例子如\cref{tab1} 所示。
+\begin{table}[htbp]
+ \centering
+ \bicaption{使用tabularx创建内容过长表格}{Use tabularx to create a table with too long content}\label{tab1}\small
+ \begin{tabularx}{0.87\textwidth}{@{}llL@{}}
+ \toprule
+ Aliquam & Integer & Pellentesque tincidunt purus
+ vel magna. \\
+ \midrule
+ viverra & \multirowcell{3}[0ex][l]{metus} & Nulla malesuada porttitor diam. Vestibulum lectus. Proin mauris. Proin eu nunc eu urna hendrerit faucibus. \\
+ semper & & Nullam elementum, urna vel imperdiet sodales, elit ipsum pharetra ligula, ac pretium ante justo a nulla. Curabitur tristique arcu eu metus. \\
+ \multicolumn{2}{c}{\multirowcell{3}{convallis}} & Nunc elementum fermentum wisi. Aenean placerat. Ut imperdiet, enim sed gravida sollicitudin, felis odio placerat quam, ac pulvinar elit purus eget enim. \\
+ \bottomrule
+ \end{tabularx}
+\end{table}
+
+\clearpage
+\section{列表}\index{l@列表}
+\lstinline{enumitem} 宏包为系统自带的列表环境提供了更灵活的标签以及间距的控制。已设置默认格式,若自定义标签可例如
+\begin{lstlisting}[numbers = none]
+\begin{enumerate}[label = \arabic*(a),leftmargin = 1cm,resume]
+\begin{itemize}[label = \textbullet]
+\begin{description}[font = \sffamily\bfseries,style = nextline]
+\end{lstlisting}
+
+\subsection{排序列表}\label{subsec1}\index{l@列表!p@排序列表}
+\begin{enumerate}
+ \item 使用 \lstinline{enumerate} 环境可创建有序列表。
+ \item 第二项
+ \begin{enumerate}
+ \item 第二项中的第一项
+ \end{enumerate}
+\end{enumerate}
+使用 \lstinline{enumerate*} 环境产生行内部列表。可以使用\textsf{A、a、I、i和1}作为可选项为 \lstinline{enumerate*} 与 \lstinline{enumerate} 格式化标签,
+\begin{enumerate*}[(a)]
+ \item 行内第一项
+ \item 行内第二项
+\end{enumerate*}。
+若生成\textbf{Item I、Item II、Item III}格式可以这样
+\begin{lstlisting}[numbers = none]
+\begin{enumerate*}[(a)]
+\begin{enumerate}[\bfseries{Item}I]
+\end{lstlisting}
+
+\subsection{常规列表}\index{l@列表!c@常规列表}
+\begin{itemize}
+ \item 第一项 \\
+ 使用 \lstinline{itemize} 环境可创建不计数列表,若换行不缩进。 \par
+ 若在列表中分段后则缩进两字符。
+ \item 第二项
+ \begin{itemize}
+ \item \lstinline{itemize*} 为行内常规列表,也提供一个可选参数。
+ \end{itemize}
+\end{itemize}
+用$\star$取代默认的符号
+\begin{lstlisting}[numbers = none]
+\begin{itemize*}[$\star$]
+\begin{itemize}[$\star$]
+\end{lstlisting}
+
+\subsection{主题列表}\index{l@列表!z@主题列表}
+\begin{description}
+ \item[主题一] 使用 \lstinline{description} 环境可创建带有主题词的列表。
+ \item[主题二] 详细内容
+\end{description}
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/easybook/pages/chapter2.tex b/macros/latex/contrib/easybook/pages/chapter2.tex
new file mode 100644
index 0000000000..5b59aad56b
--- /dev/null
+++ b/macros/latex/contrib/easybook/pages/chapter2.tex
@@ -0,0 +1,77 @@
+% Chapter 2
+\documentclass[../easybook-demo]{subfiles}
+\begin{document}
+
+\chapter{定理盒子}
+
+\begin{outline}\index{zhaiyao@摘要盒子}
+ \item 这是一个摘要盒子。
+ \item 它的标题是可选参数,默认标题是摘要。
+\end{outline}
+
+\section{定理}\index{d@定理}
+\begin{theorem}[(高斯公式\footnote{选自高等数学公式。})]\label{theo1}\index{d@定理!g@高斯公式}
+设空间闭区域$\Omega$是由分片光滑的闭曲面$\Sigma$围成,若函数$P(x,y,z)$,$Q(x,y,z)$,$R(x,y,z)$在$\Omega$上具有一节连续偏导数,则有
+\begin{align}
+ \iiint_\Omega\left(\frac{\partial P}{\partial x}+\frac{\partial Q}{\partial y}+\frac{\partial R}{\partial x}\right)\mathrm{d}V & =\oiint_\Sigma P\mathrm{d}y\mathrm{d}z+Q\mathrm{d}z\mathrm{d}x+R\mathrm{d}x\mathrm{d}y
+ \\
+ & =\oiint_\Sigma \left(P\cos\alpha+Q\cos\beta+R\cos\gamma\right)\mathrm{d}S
+\end{align}
+这里$\Sigma$是整个边界曲面$\Omega$的外侧,$\cos\alpha,\cos\beta,\cos\gamma$是$\Sigma$在点$(x,y,z)$处的法向量的方向余弦。引用这个公式如\cref{theo1}。
+\end{theorem}
+
+\begin{definition}[(Stokes formula)]\label{defi1}\index{d@定理!s@Stokes formula}
+Let $\Gamma$ be a piecewise smooth directed closed curve, $\Sigma$ is a piecewise smooth directed surface bounded by $\Gamma$, the side of $\Gamma$ and the positive direction of $\Sigma$ According to the right-hand rule, if the function $P(x,y,z)$, $Q(x,y,z)$, $R(x,y,z)$ has a first-order continuous deviation on the curve $\Sigma$ Derivative, then
+\begin{multline}
+ \iint_\Sigma\left(\frac{\partial R}{\partial y}-\frac{\partial Q}{\partial z}\right)\mathrm{d}y\mathrm{d}z+\left(\frac{\partial P}{\partial z}-\frac{\partial R}{\partial x}\right)\mathrm{d}z\mathrm{d}x+\left(\frac{\partial Q}{\partial x}-\frac{\partial P}{\partial y}\right)\mathrm{d}x\mathrm{d}y
+ \\
+ = \oint_\Gamma P\mathrm{d}x+Q\mathrm{d}y+R\mathrm{d}z
+\end{multline}
+The Stokes formula is an extension of the basic calculus formula in the case of surface integration. It is also an extension of the Green formula. This formula gives the second type of surface integral on the surface block and the second type of curve on the boundary curve Link between points.
+\end{definition}
+
+\clearpage
+\begin{lemma}
+定理环境的边框和习题标题盒子可使用 \lstinline{thmbox = false} 关闭。
+\end{lemma}
+
+\begin{corollary}
+这是一个推论。
+\end{corollary}
+
+\begin{proposition}
+这是一个性质。
+\end{proposition}
+
+\begin{example}
+这是一个例。
+\end{example}
+
+\begin{remark}
+这是一个注。
+\end{remark}
+
+\begin{proof}
+这是一个证明,末尾自动添加证明结束符。
+\end{proof}
+
+\begin{mybox}*[My title]\index{z@自定义盒子}
+环境 \lstinline{mybox} 创建一个段落盒子,可以添加可选参数的标题,否则无标题框。
+\tcblower
+带有星号的环境会生成浅灰背景,否则是纯白背景。
+\end{mybox}
+
+习题环境 \lstinline{exercise} 的标题紧接上一节编号并加入目录与页眉,当使用星号环境时不进行编号。它含有三个可选参数 \lstinline{[<颜色>][<编号>][<标题>]},其中颜色为自定义或 \lstinline{xcolor} 包含的颜色名称(深色),正文编号格式与\cref{subsec1} 相同,标题名默认为摘要,参数只能\textsf{从右往左}省略。
+\begin{exercise}[black][1.][习题]\index{x@习题环境}
+ \item 设$w = f(x+y+z,xyz)$,$f$具有二阶连续偏导数,求$\dfrac{{\partial w}}{{\partial x}}$和$\dfrac{{{\partial ^2}w}}{{\partial x\partial z}}$。
+ \item 已知$y = y(x)$在任意点$x$处的增量$\Delta y = \dfrac{y\Delta x}{1+x^2}+\alpha$,其中$\alpha$是$\Delta x$的高阶无穷小($\Delta x\to 0$时),$y(0) = \pi$,则$y(1) = \uline{\mbox{\hspace{2em}}}$。
+ \item 设函数$f(x)$在$(-\infty,+\infty)$上有定义,则下述命题中正确的是 \mbox{(\hspace{1.5em})}
+ \begin{tasks}
+ \task 若$f(x)$在$(-\infty,+\infty)$上可导且单调增加,则对一切$x\in (-\infty,+\infty)$,都有$f'(x) > 0$。
+ \task 若$f(x)$在点$x_0$处取得极值,则$f'(x_0) = 0$。
+ \task 若$f''(x_0) = 0$,则$(x_0,f(x_0))$是曲线$y = f(x)$的拐点坐标。
+ \task 若$f'(x_0) = 0$, $f''(x_0) = 0$,$f'''(x_0)\ne 0$,则$x_0$一定不是$f(x)$的极值点。
+ \end{tasks}
+\end{exercise}
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/easybook/pages/chapter3.tex b/macros/latex/contrib/easybook/pages/chapter3.tex
new file mode 100644
index 0000000000..2c7c27ce7f
--- /dev/null
+++ b/macros/latex/contrib/easybook/pages/chapter3.tex
@@ -0,0 +1,52 @@
+% Chapter 3
+\documentclass[../easybook-demo]{subfiles}
+\begin{document}
+
+\chapter{其它格式}\label{chap1}
+
+\section{代码}\index{d@代码}
+使用 \lstinline{listings} 宏包可以对代码格式进行高度定制,默认语言为 \lstinline{LaTeX},这里以 \lstinline{Python} 为例
+\begin{lstlisting}[language = Python,caption = {python程序练习题}]
+#!/usr/bin/python
+# -*- coding: UTF-8 -*-
+
+if __name__ == '__main__':
+ ptr = []
+ for i in range(5):
+ num = int(raw_input('please input a number:\n'))
+ ptr.append(num)
+ print ptr
+\end{lstlisting}
+
+\section{物理量}\index{w@物理量}
+\lstinline{siunitx} 宏包的 \lstinline{\num} 命令可以输出科学计数法 \num{-21x.3e5},而 \lstinline{\SI} 命令可用来输出带有单位的量,比如 \SI{.5}{mol}。
+
+\section{化学式}\index{h@化学式}
+除了以普通公式的方式,化学式还可用 \lstinline{chemformula} 实现,无机化学式例如\ch{(NH4)2S}、\ch{[Cu(NH3)4]^2+}。
+\[\ch{$x$ Na(NH4)HPO4 ->[$\Delta$] (NaPO3)_{$x$} + $x$ NH3 ^ + $x$ H2O}\]
+有机化学式推荐使用 \lstinline{chemfig} 完成。
+\[\zihao{-5}\chemfig[cram width=5pt]{*6((-HO)-=-(-(<[::60]OH)-[::-60]-[::-60,,,2]
+HN-[::+60]CH_3)=-(-HO)=)}\]
+
+\clearpage
+\section{引用}\index{y@引用}
+使用 \lstinline{cleveref} 宏包的 \lstinline{\cref} 命令进行引用,将会自动检测环境并添加相应的前缀。
+\subsection{索引}\index{y@引用!s@索引}
+使用 \lstinline{imakeidx} 生成索引,仅做了简单的设置如将索引设为双栏并加入目录,其他选项可另外配置。
+
+\subsection{脚注}\index{y@引用!j@脚注}
+脚注应在注释与正文之间加细线分隔,使用 \lstinline{footmisc} 宏包设置,选项为悬挂缩进(\lstinline{hang})形式\footnote{这是一个悬挂缩进的脚注。\par 这是分段将会缩进两字符。}。这是自定义标记的脚注且不影响正常编号\Footnote{*}{这是可以自定义标记的脚注。}。
+
+\subsection{边注}\index{y@引用!b@边注}
+命令 \lstinline{\marginnote} 可以生成简单的边注\marginnote{这是一个边注。}。
+
+\subsection{引用章节}\label{sec1}\index{y@引用!s@索引}
+如引用\cref{chap1}、\cref{sec1}。
+
+\subsection{参考文献}\index{y@引用!c@参考文献}
+这是一个参考文献引用的范例\cite{1979Prospect}。引用多个文献,将引用标号中的多个文献序号按升序排列,若其中有2个以上的连续序号,则改用范围序号,例如\cite{1979Prospect,1989The,2010An}。
+
+\section{行内盒子}\index{h@行内盒子}
+设置了两个行内盒子,这个盒子 \concise[Aqua][fontupper = \rmfamily]{concise} 可以为抄录盒子有三个参数 \lstinline{[<颜色>][<配置>][<内容>]},行内盒子内容是必选参数其他可选。设置等宽字体可在配置参数中 \lstinline{fontupper = \ttfamily}。这个盒子 \fuzzy[yellow][fontupper = \ttfamily,colupper = black]{fuzzy} 的参数选项与上个盒子相同,具有模糊边缘类似高亮的效果。
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/easybook/pages/preface.tex b/macros/latex/contrib/easybook/pages/preface.tex
new file mode 100644
index 0000000000..559df6d5be
--- /dev/null
+++ b/macros/latex/contrib/easybook/pages/preface.tex
@@ -0,0 +1,21 @@
+% Preface
+\documentclass[../easybook-demo]{subfiles}
+\begin{document}
+
+\chapter*{前言}
+
+\lstinline{easybook} 使用\LaTeX 3语法将选项扩展入\CTeX 宏集接口命令 \lstinline{\ctexset} 的列表。如果无法编译以及选项说明细节参见~\href{./doc/easybook.pdf}{easybook使用帮助}。
+
+\begin{enumerate}[label=\color{DarkBlue}\protect\circled{\arabic*}]
+\item 优化页眉页脚,单面或双面排版适配了不同风格。
+\item 增加章前摘要、定理和段落、行内盒子,增加习题环境。
+\item 更改草稿选项,与标准文类行为一致并显示页面边框。
+\item 增加超链接颜色风格及目录链接格式,调整配色,删除文章模式。
+\item 使用功能更丰富的 \lstinline{thmtools} 设置定理环境。
+\item 可自定义正文、表格、公式环境、图表标题以及脚注的行距。
+\item 图表可以使用双语标题,增加代码索引和索引目录,脚注标记可以设置为自定义的符号。
+\end{enumerate}
+
+\vfill{\small\doclicenseThis}
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/easybook/ref/refs.bib b/macros/latex/contrib/easybook/ref/refs.bib
new file mode 100644
index 0000000000..187a693805
--- /dev/null
+++ b/macros/latex/contrib/easybook/ref/refs.bib
@@ -0,0 +1,31 @@
+% Encoding: UTF-8
+
+@article{1979Prospect,
+ title={Prospect Theory: An Analysis of Decision under Risk},
+ author={ Tversky, Kahneman Amos },
+ journal={Econometrica},
+ volume={47},
+ number={2},
+ pages={263-291},
+ year={1979},
+}
+
+@article{2010An,
+ title={An Introduction to Sociolinguistics},
+ author={ Grabe, William and Wardhaugh, Ronald },
+ journal={Language in Society},
+ volume={36},
+ number={2},
+ pages={605-605},
+ year={2010},
+}
+
+@article{1989The,
+ title={The structural transformation of the public sphere: an inquiry into a cstergory of burgeois society},
+ author={ Scaff, Lawrence A. and Habermas, Jurgen and Burger, Thomas and Nicholson, Shierry Weber },
+ journal={American Political Science Review},
+ volume={84},
+ number={3},
+ pages={967},
+ year={1989},
+} \ No newline at end of file
diff --git a/macros/latex/contrib/skeldoc/skeldoc.pdf b/macros/latex/contrib/skeldoc/skeldoc.pdf
index 541a42cad5..102bda1f88 100644
--- a/macros/latex/contrib/skeldoc/skeldoc.pdf
+++ b/macros/latex/contrib/skeldoc/skeldoc.pdf
Binary files differ
diff --git a/macros/latex/contrib/skeldoc/skeldoc.sty b/macros/latex/contrib/skeldoc/skeldoc.sty
index 5afb1c9c5f..2938b545b7 100644
--- a/macros/latex/contrib/skeldoc/skeldoc.sty
+++ b/macros/latex/contrib/skeldoc/skeldoc.sty
@@ -18,8 +18,8 @@
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
% SOFTWARE.
-\def \skelversion {0.1}
-\def \skeldate {2020-12-30}
+\def \skelversion {0.1.1}
+\def \skeldate {2021-01-03}
\RequirePackage{expl3}
@@ -44,6 +44,8 @@
\RequirePackage{enumitem}
+\cs_generate_variant:Nn \tl_set:Nn { Ne }
+
\cs_new:Npn \skel_tl_from_key:N #1 {
\tl_set_rescan:Nno #1 { } { \l_keys_key_str }
}
diff --git a/macros/luatex/generic/chickenize/README.md b/macros/luatex/generic/chickenize/README.md
index 0943366201..0481bc7186 100644
--- a/macros/luatex/generic/chickenize/README.md
+++ b/macros/luatex/generic/chickenize/README.md
@@ -6,14 +6,14 @@ To produce the package files, run lualatex on chickinize.dtx, wich should result
chickenize.sty (LaTeX user interface)
chickenize.lua (Lua package code) [does the actual work]
-You need an up-to-date TeX Live (2017, if possible) to use this package. Maybe a full MiKTeX will will also work. (Not tested!) Lua\TeX > 1.0.4 is required for some features since the corresponding syntax has changed!
+You need an up-to-date TeX Live (2020, if possible) to use this package. Maybe a full MiKTeX will also work. (Not tested!) Lua\TeX > 1.0.4 is required for some features since the corresponding syntax has changed; tested with Lua\TeX 1.12.0 (TeX Live 2020)
For any comments or suggestions, contact me:
arno dot trautmann at gmx dot de
Hope you have fun with this package!
-This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+This package is copyright © 2021 Arno L. Trautmann. It 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. This work has the LPPL mainten-
ance status ‘maintained’.
diff --git a/macros/luatex/generic/chickenize/chickenize.dtx b/macros/luatex/generic/chickenize/chickenize.dtx
index 6da6c1b4c1..0aa643571c 100644
--- a/macros/luatex/generic/chickenize/chickenize.dtx
+++ b/macros/luatex/generic/chickenize/chickenize.dtx
@@ -12,14 +12,14 @@ To produce the package files, run lualatex on chickinize.dtx, wich should result
chickenize.sty (LaTeX user interface)
chickenize.lua (Lua package code) [does the actual work]
-You need an up-to-date TeX Live (2017, if possible) to use this package. Maybe a full MiKTeX will will also work. (Not tested!) Lua\TeX > 1.0.4 is required for some features since the corresponding syntax has changed!
+You need an up-to-date TeX Live (2020, if possible) to use this package. Maybe a full MiKTeX will also work. (Not tested!) Lua\TeX > 1.0.4 is required for some features since the corresponding syntax has changed; tested with Lua\TeX 1.12.0 (TeX Live 2020)
For any comments or suggestions, contact me:
arno dot trautmann at gmx dot de
Hope you have fun with this package!
-This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+This package is copyright © 2021 Arno L. Trautmann. It 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. This work has the LPPL mainten-
ance status ‘maintained’.
@@ -37,7 +37,7 @@ ance status ‘maintained’.
EXPERIMENTAL CODE
-This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+This package is copyright © 2021 Arno L. Trautmann. It 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. This work has the LPPL mainten-
ance status ‘maintained’.
@@ -79,8 +79,9 @@ ance status ‘maintained’.
hyperref,
longtable,
microtype,
- scrpage2,
- tabu
+ scrlayer-scrpage,
+ tabu,
+ xcolor
}
\hypersetup{
colorlinks=true,
@@ -103,7 +104,7 @@ ance status ‘maintained’.
}
\begin{document}
-{\hspace*{-2cm}{\scalebox{.2}{\drawchicken}
+{\hspace*{-2cm}{\scalebox{.2}{\drawchicken\hspace*{20cm}\reflectbox{\chickenizesetup{drawwidth=5}\drawunicorn}}
\hfill\hfill \parbox{6.3cm}{{\TGChorus{\Large »\,}\large The Monty Pythons, were they \TeX~users,\\\hspace*{.2em} could have written the chickenize macro.{\Large \textit «}}\\[1ex]
\hspace*{4cm}\small Paul Isambert}\kern-2.5cm
}
@@ -116,14 +117,14 @@ chickenize
\unrainbowcolor
-\centerline{v0.2.5}
+\centerline{v0.3}
\centerline{\hspace*{2cm} Arno L. Trautmann {\Large \ALT}}
\centerline{\href{mailto:arno.trautmann@gmx.de}{arno.trautmann@gmx.de}}
\kern.5cm
\textcolor{blue}{\Large How to read this document.}
-This is the documentation of the package |chickenize|. It allows manipulations of any Lua\TeX\ document\footnote{The code is based on pure Lua\TeX\ features, so don't even try to use it with any other \TeX\ flavour. The package is tested under plain Lua\TeX\ and Lua\LaTeX. If you tried using it with Con\TeX t, please share your experience, I will gladly try to make it compatible!} exploiting the possibilities offered by the callbacks that influence line breaking (and some other stuff). Most of this package's content is just for fun and educational use, but there are also some functions that can be useful in a normal document.
+This is the documentation of the package |chickenize|. It allows manipulations of any Lua\TeX\ document\footnote{The code is based on pure Lua\TeX\ features, so don't even try to use it with any other \TeX\ flavour. The package is (partially) tested under plain Lua\TeX\ and (fully) under Lua\LaTeX. If you tried using it with Con\TeX t, please share your experience, I will gladly try to make it compatible!} exploiting the possibilities offered by the callbacks that influence line breaking (and~some other stuff). Most of this package's content is just for fun and educational use, but there are also some functions that can be useful in a normal production document.
The table on the next page shortly informs you about some of your possibilities and provides links to the (documented) Lua functions. The \TeX\ interface is presented \hyperlink{texinterface}{below}.
@@ -131,7 +132,7 @@ The documentation of this package is far from being well-readable, consistent or
For a better understanding of what's going on in the code of this package, there is a small \hyperlink{tutorial}{tutorial} below that explains shortly the most important features used here.
-\emph{Attention}: This package is under development and everything presented here might be subject to incompatible changes. If, by any reason, you decide to use this package for an important document, please make a local copy of the source code and use that. This package will not be considered stable until it reaches at least v0.5, which might never happen.
+\emph{Attention}: This package is under development and everything presented here might be subject to incompatible changes. If, by any reason, you decide to use this package for an important document, please make a local copy of the source code and use that. This package will only be considered stable and long-term compatible should it reach version 1.0.
If you have any suggestions or comments, just drop me a mail, I’ll be happy to get any response! The latet source code is hosted on github: \url{https://github.com/alt/chickenize}. Feel free to comment or report bugs there, to fork, pull, etc.
@@ -139,7 +140,7 @@ If you have any suggestions or comments, just drop me a mail, I’ll be happy to
\small\noindent
\fbox{\parbox{.97\textwidth}{
-This package is copyright © 2017 Arno L. Trautmann. It may be distributed and/or
+This package is copyright © 2021 Arno L. Trautmann. It 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. This work has the LPPL maintenance status ‘maintained’.}}
\vspace*{1cm}
@@ -149,7 +150,7 @@ of this license or (at your option) any later version. This work has the LPPL ma
\section*{\rainbowcolor For the Impatient:}
\unrainbowcolor
-A small and incomplete overview of the functionalities offered by this package. I try to keep this list as complete as possible.\footnote{If you notice that something is missing, please help me improving the documentation!} Of course, the label “complete nonsense” depends on what you are doing …\\[2ex]
+A small and incomplete overview of the functionalities offered by this package.\footnote{If you notice that something is missing, please help me improving the documentation!} Of course, the label “complete nonsense” depends on what you are doing … The links will take you to the source code, while a more complete list with explanations is given \hyperlink{texinterface}{further below}.
\noindent
\tabulinesep=.5ex
@@ -178,11 +179,16 @@ A small and incomplete overview of the functionalities offered by this package.
\hbox to 0cm{\bfseries \hspace*{2cm} complete nonsense} \\
\cmidrule(lr){1-2}
\hyperref[sec:chickenize]{chickenize} & replaces every word with “chicken” (or user-adjustable words)\\
+\hyperref[sec:drawchicken]{drawchicken} & draws a nice chicken with random, “hand-sketch”-type lines\\
+\hyperref[sec:drawcov]{drawcov} & draws a corona virus\\
+\hyperref[sec:drawchicken]{drawhorse} & draws a horse\\
\hyperref[sec:guttenbergenize]{guttenbergenize} & deletes every quote and footnotes\\
\hyperref[sec:hammertime]{hammertime} & U can't touch this!\\
+\hyperref[sec:italianize]{italianize} & Mamma mia!! \\
+\hyperref[sec:italianizerandwords]{italianizerandwords} & Will put the word order in a sentence at random. (tbi)\\
\hyperref[sec:kernmanipulate]{kernmanipulate} & manipulates the kerning (tbi)\\
\hyperref[sec:matrixize]{matrixize} & replaces every glyph by its ASCII value in binary code\\
-\hyperref[sec:randomerror]{randomerror} & just throws random (La)\TeX\ errors at random times\\
+\hyperref[sec:randomerror]{randomerror} & just throws random (La)\TeX\ errors at random times (tbi)\\
\hyperref[sec:randomfonts]{randomfonts} & changes the font randomly between every letter\\
\hyperref[sec:randomchars]{randomchars} & randomizes the (letters of the) whole input\\
\bottomrule
@@ -199,23 +205,26 @@ All functions traverse the node list of a paragraph and manipulate the nodes' pr
\hypertarget{texinterface}{}
\section{Commands – How You Can Use It}
-There are several ways to make use of the \emph{chickenize} package – you can either stay on the \TeX\ side or use the Lua functions directly. In fact, the \TeX\ macros are simple wrappers around the functions.
+There are several ways to make use of the \emph{chickenize} package – you can either stay on the \TeX\ side or use the Lua functions directly. In fact, the \TeX\ macros are in most cases simple wrappers around the functions.
\subsection{\TeX\ Commands – Document Wide}
You have a number of commands at your hand, each of which does some manipulation of the input or output. In fact, the code is simple and straightforward, but be careful, especially when combining things. Apply features step by step so your brain won't be damaged …
-The effect of the commands can be influenced, not with arguments, but only via the |\chickenizesetup| described \hyperlink{adjustment}{below}.
+The effect of the commands can be influenced, not with arguments, but only via the |\chickenizesetup| described \hyperlink{adjustment}{below}. The links provide here will bring you to the more relevant part of the implementation, i.\,e.~either the \TeX\ code or the Lua code, depending on what is doing the main job. Mostly it's the Lua part.
\begin{description}
-\def\command#1{\item[\ttfamily \color{blue} \textbackslash#1]}
+\def\command#1{\item[{\hyperref[sec:#1]{\textbackslash #1}}]}
+
\command{allownumberincommands} Normally, you cannot use numbers as part of a control sequence (or, command) name. This makes perfect sense and is good as it is. However, just to raise awareness to this, we provide a command here that changes the chategory codes of numbers 0–9 to 11, i.\,e.~normal character. So they \emph{can} be used in command names. However, this will break many packages, so do \emph{not} expect anything to work! At least use it \emph{after} all packages are loaded.
\command{boustrophedon} Reverts every second line. This immitates archaic greek writings where one line was right-to-left, the next one left-to-right etc.\footnote{\url{en.wikipedia.org/wiki/Boustrophedon}} Interestingly, also every glyph was adaptet to the writing direction, so all glyphs are inverted in the right-to-left lines. Actually, there are two versions of this command that differ in their implementation: |\boustrophedon| rotates the whole line, while |\boustrophedonglyphs| changes the writing direction and reverses glyph-wise. The second one takes much more compilation time, but may be more reliable. A Rongorongo\footnote{\url{en.wikipedia.org/wiki/Rongorongo}} similar style boustrophedon is available with |\boustrophedoninverse| or |\rongorongonize|, where subsequent lines are rotated by 180° instead of mirrored.
\command{countglyphs} \textcolor{blue}{\texttt{\textbackslash countwords}} Counts every printed character (or word, respectively) that appears in anything that is a paragraph. Which is quite everything, in fact, \emph{exept} math mode! The total number of glyphs/words will be printed at the end of the log file/console output. For glyphs, also the number of use for every letter is printed separately.
\command{chickenize} Replaces every word of the input with the word “chicken”. Maybe sometime the replacement will be made configurable, but up to now, it's only chicken. To be a bit less static, about every 10\textsuperscript{th} chicken is uppercase. However, the beginning of a sentence is not recognized automatically.\footnote{If you have a nice implementation idea, I'd love to include this!}
+\command{drawchicken} Draws a chicken based on some low-level lua drawing code. Each stroke is parameterized with random numbers so the chicken will always look different.
\command{colorstretch} Inspired by Paul Isambert's code, this command prints boxes instead of lines. The greyness of the first (left-hand) box corresponds to the badness of the line, i.\,e. it is a measure for how much the space between words has been extended to get proper paragraph justification. The second box on the right-hand side shows the amount of stretching/shrinking when font expansion is used. Together, the greyness of both boxes indicate how well the greyness is distributed over the typeset page.
\command{dubstepize} wub wub wub wub wub BROOOOOAR WOBBBWOBBWOBB BZZZRRRRRRROOOOOOAAAAA … (inspired by \url{http://www.youtube.com/watch?v=ZFQ5EpO7iHk} and \url{http://www.youtube.com/watch?v=nGxpSsbodnw})
\command{dubstepenize} synomym for |\dubstepize| as I am not sure what is the better name. Both macros are just a special case of |chickenize| with a very special “zoo” … there is no |\undubstepize| – once you go dubstep, you cannot go back …
\command{explainbackslashes} A small list that gives hints on how many |\| characters you actually need for a backslash. I's supposed to be funny. At least my head thinks it's funny. Inspired (and mostly copied from, actually) xkcd.
+\command{gameofchicken} This is a temptative implementation of Conway's classic Game of Life. This is actually a rather powerful code with some choices for you. The game itself is played on a matrix in Lua and can be output either on the console (for quick checks) or in a pdf. The latter case needs a LaTeX document, and the packages |geometry|, |placeat|, and |graphicx|. You can choose which \LaTeX\ code represents the cells or you take the pre-defined – a \kern-1.5em\raisebox{.75ex}{\scalebox{0.075}{\drawchicken}}\kern2.5em , of course! Additionally, there are |anticells| which is basically just a second set of cells. However, they can interact, and you have full control over the rules, i.\,e.~how many neighbors a cell or anticell may need to be born, die, or stay alive, and what happens if cell and anticell collide. See below for parameters; all of them start with GOC for clarity.
\command{gameoflife} Try it.
\command{hammertime} STOP! —— Hammertime!
\command{leetspeak} Translates the input into 1337 speak. If you don't understand that, lern it, n00b.
@@ -227,6 +236,7 @@ The effect of the commands can be influenced, not with arguments, but only via t
\command{randomfonts} Changes the font randomly for every character. If no parameters are given, all fonts that have been loaded are used, especially including math fonts.
\command{randomcolor} Does what its name says.
\command{rainbowcolor} Instead of random colors, this command causes the text color to change gradually according to the colors of a rainbow. Do not mix this with |randomcolor|, as that doesn't make any sense.
+\command{relationship} Draws the relationship. A ship made of relations.
\command{pancakenize} This is a dummy command that does nothing. However, every time you use it, you owe a pancake to the package author. You can either send it via mail or bring it to some (local) \TeX\ user's group meeting.
\command{substitutewords} You have to specify pairs of words by using |\addtosubstitutions{word1}{word2}|. Then call |\substitutewords| (or the other way round, doesn't matter) and each occurance of |word1| will be replaced by |word2|. You can add replacement pairs by repeated calls to |\addtosubstitutions|. Take care! This function works with the input stream directly, therefore it does \emph{not} work on text that is inserted by macros, but it \emph{will} work on macro names itself! This way, you may use it to change macros (or environments) at will. Bug or feature? I'm not sure right now …
\command{suppressonecharbreak} \TeX~normally does not suppress a linebreak after words with only one character (“I“, “a” etc.) This command suppresses line breaks. It is very similar to the code provided by the |impnattypo| package and based on the same ideas. However, the code in |chickenize| has been written before the author knew |impnattypo|, and the code differs a bit, might even be a bit faster. Well, test it!
@@ -267,12 +277,15 @@ The following list tries to kind of keep track of the options and variables. The
\def\default#1{\textcolor{black}{\ttfamily #1}}
\begin{description}
\item[\opt{randomfontslower}, \opt{randomfontsupper} = \arg{int}] These two integer variables determine the span of fonts used for the font randomization. Just play around with them a bit to find out what they are doing.
-\item[\opt{chickenstring} = \arg{table}] The string that is printed when using |\chickenize|. In fact, |chickenstring| is a table which allows for some more random action. To specify the default string, say |chickenstring[1] = 'chicken'|. For more than one animal, just step the index: |chickenstring[2] = 'rabbit'|. All existing table entries will be used randomly. Remember that we are dealing with Lua strings here, so use |' '| to mark them. (|" "| can cause problems with |babel|.)
+\subsection{options for chickenization}
+\item[\opt{chickenstring} = \arg{table}] The string that is printed when using |\chickenize|. In fact, |chickenstring| is a table which allows for some more random action. To specify the default string, say |chickenstring[1] = 'chicken'|. For more than one animal, just step the index:\\
+ |chickenstring[2] = 'rabbit'|. All existing table entries will be used randomly. Remember that we are dealing with Lua strings here, so use |' '| to mark them. (|" "| can cause problems with |babel|.)
\item[\opt{chickenizefraction} = \arg{float} \default{1}] Gives the fraction of words that get replaced by the |chickenstring|. The default means that every word is substituted. However, with a value of, say, |0.0001|, only one word in ten thousand will be |chickenstring|. |chickenizefraction| must be specified \emph{after} |\begin{document}|. No idea, why …
-\item[\opt{chickencount} = \arg{true}] Activates the counting of substituted words and prints the number at the end of the terminal output.
-\item[\opt{colorstretchnumbers} = \arg{true} \default{0}] If true, the amount of stretching or shrinking of each line is printed into the margin as a green, red or black number.
+\item[\opt{chickencount} = \arg{bool} \default{true}] Activates the counting of substituted words and prints the number at the end of the terminal output.
+\item[\opt{colorstretchnumbers} = \arg{bool} \default{false}] If true, the amount of stretching or shrinking of each line is printed into the margin as a green, red or black number.
\item[\opt{chickenkernamount} = \arg{int}] The amount the kerning is set to when using |\kernmanipulate|.
\item[\opt{chickenkerninvert} = \arg{bool}] If set to true, the kerning is inverted (to be used with |\kernmanipulate|.
+\item[\opt{drawwidth} = \arg{float} \default{1}] Defines the widths of the sloppy drawings of chickens, horses, etc.
\item[\opt{leettable} = \arg{table}] From this table, the substitution for 1337 is taken. If you want to add or change an entry, you have to provide the unicode numbers of the characters, e.\,g. |leettable[101] = 50| replaces every |e| (|101|) with the number |3| (|50|).
\item[\opt{uclcratio} = \arg{float} \default{0.5}] Gives the fraction of uppercases to lowercases in the |\randomuclc| mode. A higher number (up to 1) gives more uppercase letters. Guess what a lower number does.
\item[\opt{randomcolor\_grey} = \arg{bool} \default{false}] For a printer-friendly version, this offers a grey scale instead of an rgb value for |\randomcolor|.
@@ -282,6 +295,40 @@ The following list tries to kind of keep track of the options and variables. The
\item[\opt{colorexpansion} = \arg{bool} \default{true}] If |true|, two bars are shown of which the second one denotes the font expansion. Only useful if font expansion is used. (You \emph{do} use font expansion, don’t you?)
\end{description}
+\subsection{Options for Game of Chicken}
+This deserves a separate section since there are some more options and they need some explanation. So here goes the parameters for the GOC:
+\begin{description}
+\item[\opt{GOCrule\_live} = \arg{\{int,int,...\}} \default{\{2,3\}}] This gives the number of neighbors for an existing cell to keep it alive. This is a list, so you can say |\chickenizesetup{GOCrule_live = {2,3,7}| or similar.
+\item[\opt{GOCrule\_spawn} = \arg{\{int,int,...\}} \default{\{3\}}] The number of neighbors to spawn a new cell.
+\item[\opt{GOCrule\_antilive} = \arg{int} \default{2,3}] The number of neighbors to keep an anticell alive.
+\item[\opt{GOCrule\_antispawn} = \arg{int} \default{3}] The number of neighbors to spawn a new anticell.
+\item[\opt{GOCcellcode} = \arg{string} \default {"\\scalebox\{0.03\}\{\\drawchicken\}"}] The \LaTeX\ code for graphical representation of a living cell. You can use basically any valid \LaTeX\ code in here. A chicken is the default, of course.
+\item[\opt{GOCanticellcode} = \arg{string} \default {"O"}] The \LaTeX\ code for graphical representation of a living anticell.
+\item[\opt{GOCx} = \arg{int} \default{100}] Grid size in |x| direction (vertical).
+\item[\opt{GOCy} = \arg{int} \default{100}] Grid size in |y| direction (horizontal).
+\item[\opt{GOCiter} = \arg{int} \default{150}] Number of iterations to run the game.
+\item[\opt{GOC\_console} = \arg{bool} \default{false}] Activate output on the console.
+\item[\opt{GOC\_pdf} = \arg{bool} \default{true}] Activate output in the pdf.
+\item[\opt{GOCsleep} = \arg{int} \default{0}] Wait after one cycle of the game. This helps especially on the console, or for debugging. By dafault no wait time is added.
+\item[\opt{GOCmakegif} = \arg{bool} \default{false}] Produce a gif. This requires the command line tool |convert| since I use it for the creation. If you have troubles with this feel free to contact me.
+\item[\opt{GOCdensity} = \arg{int} \default{100}] Defines the density of the gif export. 100 is quite dense and it might take quite some time to get your gif done.
+\end{description}
+I recommend to use the |\gameofchicken| with a code roughly like this:
+\begin{verbatim}
+\documentclass{scrartcl}
+\usepackage{chickenize}
+\usepackage[paperwidth=10cm,paperheight=10cm,margin=5mm]{geometry}
+\usepackage{graphicx}
+\usepackage{placeat}
+\placeatsetup{final}
+\begin{document}
+\gameofchicken{GOCiter=50}
+%\gameofchicken{GOCiter=50 GOCmakegif = true}
+% \directlua{ os.execute("gwenview test.gif")} % substitute your filename
+\end{document}
+\end{verbatim}
+Keep in mind that for convenience |\gameofchicken{}| has one argument which is equivalent to using |\chickenizesetup{}| and actually just executes the argument as Lua code …
+
\clearpage
\part[Tutorial]{Tutorial\hypertarget{tutorial}}
I thought it might be helpful to add a small tutorial to this package as it is mainly written with instructional purposes in mind. However, the following is \emph{not} intended as a comprehensive guide to Lua\TeX\. It's just to get an idea how things work here. For a deeper understanding of Lua\TeX\ you should consult both the Lua\TeX\ manual and some introduction into Lua proper like “Programming in Lua“. (See the section \hyperref[sec:literature]{Literature} at the end of the manual.)
@@ -308,19 +355,19 @@ While Lua code can be inserted using |\directlua| at any point in the input, a v
Callbacks are employed at several stages of \TeX's work – e.\,g. for font loading, paragraph breaking, shipping out etc. In this package, we make heavy use of mostly two callbacks: The |pre_linebreak_filter| and the |post_linebreak| filter. These callbacks are called just before (or after, resp.) \TeX\ breaks a paragraph into lines. Normally, these callbacks are empty, so they are a great playground. In between these callbacks, the |linebreak_filter| takes care of \TeX's line breaking mechanism. We won't touch this as I have no idea of what's going on there ;)
-\subsection{How to use a callback}
+\section{How to use a callback}
The normal way to use a callback is to “register” a function in it. This way, the function is called each time the callback is executed. Typically, the function takes a node list (see below) as an argument, does something with it, and returns it. So a basic use of the |post_linebreak_filter| would look like:
\begin{verbatim}
-function my_new_filter(head)
+function my_filter(head)
return head
end
-callback.register("post_linebreak_filter",my_new_filter)
+callback.register("post_linebreak_filter",my_filter)
\end{verbatim}
The function |callback.register| takes the name of the callback and your new function. However, there are some reasons why we avoid this syntax here. Instead, we rely on the function |luatexbase.add_to_callback|. This is provided by the \LaTeX\ kernel table |luatexbase| which was initially a package by Manuel Pégourié-Gonnard and Élie Roux.\footnote{Since the late 2015 release of \LaTeX, the package has not to be loaded anymore since the functionality is absorbed by the kernel. Plain\TeX~users can load the |ltluatex| file which provides the needed functionality.} This function has a more extended syntax:
\begin{verbatim}
-luatexbase.add_to_callback("post_linebreak_filter",my_new_filter,"a fancy new filter")
+luatexbase.add_to_callback("post_linebreak_filter",my_filter,"a fancy new filter")
\end{verbatim}
The third argument is a name you can (have to) give to your function in the callback. That is necessary because the package also allows for removing functions from callbacks, and then you need a unique identifier for the function:
\begin{verbatim}
@@ -334,7 +381,7 @@ Everything I have written here is not the complete truth – please consult the
\section{Nodes}
Essentially everything that Lua\TeX\ deals with are nodes – letters, spaces, colors, rules etc. In this package, we make heavy use of different types of nodes, so an understanding of the concept is crucial for the functionality.
-A node is an object that has different properties, depending on its type which is stored in its |.id| field. For example, a node of type |glyph| has |id| 27 (up to Lua\TeX~0.80., it was 37) has a number |.char| that represents its unicode codepoint, a |.font| entry that determines the font used for this glyph, a |.height|, |.depth| and |.width| etc.
+A node is an object that has different properties, depending on its type which is stored in its |.id| field. For example, a node of type |glyph| has |id| 27 (up to Lua\TeX~0.80, it was 37) has a number |.char| that represents its unicode codepoint, a |.font| entry that determines the font used for this glyph, a |.height|, |.depth| and |.width| etc.
Also, a node typically has a non-empty field |.next| and |.prev|. In a list, these point to the – guess it – next or previous node. Using this, one can walk over a list of nodes step by step and manipulate the list.
@@ -386,11 +433,13 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t
\bgroup%
\fontspec{Latin Modern Sans}%
A%
- \kern-.4em \raisebox{.65ex}{\scalebox{0.3}{L}}%
- \kern-.0em \raisebox{-0.98ex}{T}%
+ \kern-.375em \raisebox{.65ex}{\scalebox{0.3}{L}}%
+ \kern.03em \raisebox{-.99ex}{T}%
\egroup%
}
-
+% \end{macrocode}
+% \subsection{allownumberincommands}\label{sec:allownumberincommands}
+% \begin{macrocode}
\def\allownumberincommands{
\catcode`\0=11
\catcode`\1=11
@@ -538,9 +587,40 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t
\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash... the true name of Ba'al, the soul-eater}
}
+\def\francize{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",francize,"francize")}}
+
+\def\unfrancize{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter",francize)}}
+
\def\gameoflife{
Your Life Is Tetris. Stop Playing It Like Chess.
}
+% \end{macrocode}
+% This is just the activation of the command, the typesetting is done in the Lua code/loop as explained below. Use this macro \emph{after} |\begin{document}|. Remember that |graphicx| and |placeat| are required!
+% \begin{macrocode}
+\def\gameofchicken#1{\directlua{
+GOCrule_live = {2,3}
+GOCrule_spawn = {3}
+GOCrule_antilive = {2,3}
+GOCrule_antispawn = {3}
+GOCcellcode = "\\scalebox{0.03}{\\drawchicken}"
+GOCcellcode = "\\scalebox{0.03}{\\drawcov}"
+GOCx = 100
+GOCy = 100
+GOCiter = 150
+GOC_console = false
+GOC_pdf = true
+GOCsleep = 0
+GOCdensity = 100
+#1
+gameofchicken()
+
+if (GOCmakegif == true) then
+ luatexbase.add_to_callback("wrapup_run",make_a_gif,"makeagif")
+end
+}}
+\let\gameofchimken\gameofchicken % yeah, that had to be.
\def\guttenbergenize{ %% makes only sense when using LaTeX
\AtBeginDocument{
@@ -577,6 +657,16 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t
\let\hendlnize\chickenize % homage to Hendl/Chicken
\let\unhendlnize\unchickenize % may the soldering strength always be with him
+\def\italianizerandwords{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",italianizerandwords,"italianizerandwords")}}
+\def\unitalianizerandwords{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","italianizerandwords")}}
+
+\def\italianize{
+ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",italianize,"italianize")}}
+\def\unitalianize{
+ \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","italianize")}}
+
% \def\itsame{
% \directlua{drawmario}} %%% does not exist
@@ -671,6 +761,13 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t
\def\unrandomuclc{
\directlua{luatexbase.remove_from_callback("pre_linebreak_filter","randomuclc")}}
+\def\relationship{%
+ \directlua{luatexbase.add_to_callback("post_linebreak_filter",cutparagraph,"cut paragraph")
+ luatexbase.add_to_callback("stop_run",missingcharstext,"charsmissing")
+ relationship()
+ }
+}
+
\let\rongorongonize\boustrophedoninverse
\let\unrongorongonize\unboustrophedoninverse
@@ -777,7 +874,8 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t
% \begin{macrocode}
\def\chickenizesetup#1{\directlua{#1}}
% \end{macrocode}
-% The following is the very first try of implementing a small drawing language in Lua. It draws a beautiful chicken.
+% \subsection{drawchicken}\label{sec:drawchicken}
+% The following is the very first try of implementing a small drawing language in Lua. It draws a beautiful (?) chicken. TODO: Make it scalable by giving relative sizes. Also: Allow it to look to the other side if wanted.
% \begin{macrocode}
\long\def\luadraw#1#2{%
\vbox to #1bp{%
@@ -817,6 +915,105 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t
}
}
% \end{macrocode}
+% \subsection{drawcov}\label{sec:drawcov}
+% This draws a corona virus since I had some time to work on this package due to the shutdown caused by COVID-19.
+% \begin{macrocode}
+\long\def\drawcov{
+ \luadraw{90}{
+ covbody = {200,50}
+ covbody_rad = 50
+
+ covcrown_rad = 5
+ crownno = 13
+ for i=1,crownno do
+ crownpos = {covbody[1]+1.4*covbody_rad*math.sin(2*math.pi/crownno*i),covbody[2]+1.4*covbody_rad*math.cos(2*math.pi/crownno*i)}
+ crownconnect = {covbody[1]+covbody_rad*math.sin(2*math.pi/crownno*i),covbody[2]+covbody_rad*math.cos(2*math.pi/crownno*i)}
+ sloppycircle(crownpos,covcrown_rad)
+ sloppyline(crownpos,crownconnect)
+ end
+
+ covcrown_rad = 6
+ crownno = 8
+ for i=1,crownno do
+ crownpos = {covbody[1]+0.8*covbody_rad*math.sin(2*math.pi/crownno*i),covbody[2]+0.8*covbody_rad*math.cos(2*math.pi/crownno*i)}
+ crownconnect = {covbody[1]+0.5*covbody_rad*math.sin(2*math.pi/crownno*i),covbody[2]+0.5*covbody_rad*math.cos(2*math.pi/crownno*i)}
+ sloppycircle(crownpos,covcrown_rad)
+ sloppyline(crownpos,crownconnect)
+ end
+
+ covcrown_rad = 8
+ sloppycircle(covbody,covcrown_rad)
+ sloppycircle(covbody,covbody_rad)
+ sloppyline(covbody,covbody)
+ }
+}
+% \end{macrocode}
+% \subsection{drawhorse}\label{sec:drawhorse}
+% Well … guess what this does.
+% \begin{macrocode}
+\long\def\drawhorse{
+ \luadraw{90}{
+ horsebod = {100,-40}
+ sloppyellipsis(horsebod,50,20)
+ horsehead = {20,0}
+ sloppyellipsis(horsehead,25,15)
+ sloppyline({35,-10},{50,-40})
+ sloppyline({45,5},{80,-25})
+ sloppyline({60,-50},{60,-90})
+ sloppyline({70,-50},{70,-90})
+ sloppyline({130,-50},{130,-90})
+ sloppyline({140,-50},{140,-90})
+ sloppyline({150,-40},{160,-60})
+ sloppyline({150,-38},{160,-58})
+ sloppyline({150,-42},{160,-62})
+ sloppyline({-5,-10},{10,-5})
+ sloppyellipsis({30,5},5,2) %% it's an eye, aye?
+ sloppyline({27,15},{34,25})
+ sloppyline({34,25},{37,13})
+ }
+}
+% \end{macrocode}
+% There's also a version with a bit more … meat to the bones:
+% \begin{macrocode}
+\long\def\drawfathorse{
+ \luadraw{90}{
+ horsebod = {100,-40}
+ sloppyellipsis(horsebod,50,40)
+ horsehead = {20,0}
+ sloppyellipsis(horsehead,25,15)
+ sloppyline({35,-10},{50,-40})
+ sloppyline({45,5},{70,-15})
+ sloppyline({60,-70},{60,-90})
+ sloppyline({70,-70},{70,-90})
+ sloppyline({130,-70},{130,-90})
+ sloppyline({140,-70},{140,-90})
+ sloppyline({150,-40},{160,-60})
+ sloppyline({150,-38},{160,-58})
+ sloppyline({150,-42},{160,-62})
+ sloppyline({-5,-10},{10,-5})
+ sloppyellipsis({30,5},5,2) %% it's an eye, aye?
+ sloppyline({27,15},{34,25})
+ sloppyline({34,25},{37,13})
+ }
+}
+% intentioally not documented:
+\long\def\drawunicorn{
+\color{pink!90!black}
+ \drawhorse
+ \luadraw{0}{
+ sloppyline({15,20},{15,50})
+ sloppyline({15,50},{25,20})
+ }
+}
+\long\def\drawfatunicorn{
+\color{pink!90!black}
+ \drawfathorse
+ \luadraw{0}{
+ sloppyline({15,20},{15,50})
+ sloppyline({15,50},{25,20})
+ }
+}
+% \end{macrocode}
% \iffalse
%</tex>
%<*package>
@@ -827,12 +1024,12 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t
% Some code might be implemented to manipulate figures for full chickenization. However, I will \emph{not} load any packages at this place, as loading of expl3 or TikZ or whatever takes too much time for such a tiny package like this one. If you require any of the features presented here, you have to load the packages on your own. Maybe this will change.
% \begin{macrocode}
\ProvidesPackage{chickenize}%
- [2017/08/19 v0.2.5 chickenize package]
+ [2021/01/03 v0.3 chickenize package]
\input{chickenize}
% \end{macrocode}
% \subsection{Free Compliments}
% \begin{macrocode}
-
+%
% \end{macrocode}
% \subsection{Definition of User-Level Macros}
% Nothing done so far, just some minor ideas. If you want to implement some cool things, contact me! :)
@@ -855,7 +1052,7 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t
%\fi
% \section{Lua Module}
% \label{sec:luamodule}
-% This file contains all the necessary functions and is the actual work horse of this package. The functions are sorted strictly alphabetically (or, they \emph{should} be …) and not by sense, functionality or anything.
+% This file contains all the necessary functions and is the actual work horse of this package. The functions are sorted alphabetically (or, they \emph{should} be …) and not by sense, functionality or anything.
%
% First, we set up some constants that are used by many of the following functions. These are made global so the code can be manipulated at the document level, too.
% \begin{macrocode}
@@ -901,8 +1098,8 @@ chicken_pagenumbers = true
chickenstring = {}
chickenstring[1] = "chicken" -- chickenstring is a table, please remeber this!
-chickenizefraction = 0.5
--- set this to a small value to fool somebody, or to see if your text has been read carefully. This is also a great way to lay easter eggs for your own class / package …
+chickenizefraction = 0.5 -- set this to a small value to fool somebody,
+-- or to see if your text has been read carefully. This is also a great way to lay easter eggs for your own class / package …
chicken_substitutions = 0 -- value to count the substituted chickens. Makes sense for testing your proofreaders.
local match = unicode.utf8.match
@@ -1129,7 +1326,7 @@ end
% \begin{macrocode}
countwords = function(head)
for glyph in nodetraverseid(GLYPH,head) do
- if (glyph.next.id == 10) then
+ if (glyph.next.id == GLUE) then
wordnumber = wordnumber + 1
end
end
@@ -1146,7 +1343,7 @@ end
% \subsection{detectdoublewords}\label{sec:detectdoublewords}
% \begin{macrocode} %% FIXME: Does this work? …
-function detectdoublewords(head)
+detectdoublewords = function(head)
prevlastword = {} -- array of numbers representing the glyphs
prevfirstword = {}
newlastword = {}
@@ -1161,10 +1358,128 @@ texio.write_nl("nfw:"..#newfirstword)
end
end
-function printdoublewords()
+printdoublewords = function()
texio.write_nl("finished")
end
% \end{macrocode}
+% \subsection{francize}\label{sec:francize}
+% This function is intentionally undocumented. It randomizes all numbers digit by digit. Why? Because.
+% \begin{macrocode}
+francize = function(head)
+ for n in nodetraverseid(GLYPH,head) do
+ if ((n.char > 47) and (n.char < 58)) then
+ n.char = math.random(48,57)
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% \subsection{gamofchicken}\label{sec:gamofchicken}
+% The |gameofchicken| is an implementation of the Game of Life by Conway. The standard cell here is a chicken, while there are also anticells. For both you can adapt the \LaTeX\ code to represent the cells.
+%
+% I also kick in some code to convert the pdf into a gif after the pdf has been finalized and Lua\TeX\ is about to end. This uses a system call to |convert|; especially the latter one will change. For now this is a convenient implementation for me and maybe most Linux environments to get the gif by one-click-compiling the |tex| document.
+% \begin{macrocode}
+function gameofchicken()
+ GOC_lifetab = {}
+ GOC_spawntab = {}
+ GOC_antilifetab = {}
+ GOC_antispawntab = {}
+ -- translate the rules into an easily-manageable table
+ for i=1,#GOCrule_live do; GOC_lifetab[GOCrule_live[i]] = true end
+ for i=1,#GOCrule_spawn do; GOC_spawntab[GOCrule_spawn[i]] = true end
+ for i=1,#GOCrule_antilive do; GOC_antilifetab[GOCrule_antilive[i]] = true end
+ for i=1,#GOCrule_antispawn do; GOC_antispawntab[GOCrule_antispawn[i]] = true end
+% \end{macrocode}
+% Initialize the arrays for cells and anticells with zeros.
+% \begin{macrocode}
+-- initialize the arrays
+local life = {}
+local antilife = {}
+local newlife = {}
+local newantilife = {}
+for i = 0, GOCx do life[i] = {}; newlife[i] = {} for j = 0, GOCy do life[i][j] = 0 end end
+for i = 0, GOCx do antilife[i] = {}; newantilife[i] = {} for j = 0, GOCy do antilife[i][j] = 0 end end
+% \end{macrocode}
+% These are the functions doing the actual work, checking the neighbors and applying the rules defined above.
+% \begin{macrocode}
+function applyruleslife(neighbors, lifeij, antineighbors, antilifeij)
+ if GOC_spawntab[neighbors] then myret = 1 else -- new cell
+ if GOC_lifetab[neighbors] and (lifeij == 1) then myret = 1 else myret = 0 end end
+ if antineighbors > 1 then myret = 0 end
+ return myret
+end
+function applyrulesantilife(neighbors, lifeij, antineighbors, antilifeij)
+ if (antineighbors == 3) then myret = 1 else -- new cell or keep cell
+ if (((antineighbors > 1) and (antineighbors < 4)) and (lifeij == 1)) then myret = 1 else myret = 0 end end
+ if neighbors > 1 then myret = 0 end
+ return myret
+end
+% \end{macrocode}
+% Preparing the initial state with a default pattern:
+% \begin{macrocode}
+-- prepare some special patterns as starter
+life[53][26] = 1 life[53][25] = 1 life[54][25] = 1 life[55][25] = 1 life[54][24] = 1
+% \end{macrocode}
+% And the main loop running from here:
+% \begin{macrocode}
+ print("start");
+ for i = 1,GOCx do
+ for j = 1,GOCy do
+ if (life[i][j]==1) then texio.write("X") else if (antilife[i][j]==1) then texio.write("O") else texio.write("_") end end
+ end
+ texio.write_nl(" ");
+ end
+ os.sleep(GOCsleep)
+
+ for i = 0, GOCx do
+ for j = 0, GOCy do
+ newlife[i][j] = 0 -- Fill the values from the start settings here
+ newantilife[i][j] = 0 -- Fill the values from the start settings here
+ end
+ end
+
+ for k = 1,GOCiter do -- iterate over the cycles
+ texio.write_nl(k);
+ for i = 1, GOCx-1 do -- iterate over lines
+ for j = 1, GOCy-1 do -- iterate over columns -- prevent edge effects
+ local neighbors = (life[i-1][j-1] + life[i-1][j] + life[i-1][j+1] + life[i][j-1] + life[i][j+1] + life[i+1][j-1] + life[i+1][j] + life[i+1][j+1])
+ local antineighbors = (antilife[i-1][j-1] + antilife[i-1][j] + antilife[i-1][j+1] + antilife[i][j-1] + antilife[i][j+1] + antilife[i+1][j-1] + antilife[i+1][j] + antilife[i+1][j+1])
+
+ newlife[i][j] = applyruleslife(neighbors, life[i][j],antineighbors, antilife[i][j])
+ newantilife[i][j] = applyrulesantilife(neighbors,life[i][j], antineighbors,antilife[i][j])
+ end
+ end
+
+ for i = 1, GOCx do
+ for j = 1, GOCy do
+ life[i][j] = newlife[i][j] -- copy the values
+ antilife[i][j] = newantilife[i][j] -- copy the values
+ end
+ end
+
+ for i = 1,GOCx do
+ for j = 1,GOCy do
+ if GOC_console then
+ if (life[i][j]==1) then texio.write("X") else if (antilife[i][j]==1) then texio.write("O") else texio.write("_") end end
+ end
+ if GOC_pdf then
+ if (life[i][j]==1) then tex.print("\\placeat("..(i/10)..","..(j/10).."){"..GOCcellcode.."}") end
+ if (antilife[i][j]==1) then tex.print("\\placeat("..(i/10)..","..(j/10).."){"..GOCanticellcode.."}") end
+ end
+ end
+ end
+ tex.print(".\\newpage")
+ os.sleep(GOCsleep)
+ end
+end --end function gameofchicken
+% \end{macrocode}
+% The following is a function calling some tool from your operating system. This requires of course that you have them present – that should be the case on a typical Linux distribution. Take care that |convert| normally does not allow for conversion from pdf, please check that this is allowed by the rules. So this is more an example code that can help you to add it to your game so you can enjoy your chickens developing as a gif.
+% \begin{macrocode}
+function make_a_gif()
+ os.execute("convert -verbose -dispose previous -background white -alpha remove -alpha off -density "..GOCdensity.." "..tex.jobname ..".pdf " ..tex.jobname..".gif")
+ os.execute("gwenview "..tex.jobname..".gif")
+end
+% \end{macrocode}
% \subsection{guttenbergenize}\label{sec:guttenbergenize}
% A function in honor of the German politician Guttenberg.\footnote{Thanks to Jasper for bringing me to this idea!} Please do \emph{not} confuse him with the grand master Gutenberg!
%
@@ -1185,7 +1500,7 @@ local quotestrings = {
% \subsubsection{guttenbergenize – the function}
% \begin{macrocode}
guttenbergenize_rq = function(head)
- for n in nodetraverseid(nodeid"glyph",head) do
+ for n in nodetraverseid(GLYPH,head) do
local i = n.char
if quotestrings[i] then
noderemove(head,n)
@@ -1220,6 +1535,124 @@ hammertime = function(head)
return head
end
% \end{macrocode}
+% \subsection{italianize}\label{sec:italianize}
+% This is inspired by some of the more melodic pronounciations of the english language. The command will add randomly an |h| in front of every word starting with a vowel or remove |h| from words starting with one. Also, it will ad randomly an |e| to words ending in consonants. This is tricky and might fail – I'm happy to receive and try to solve ayn bug reports.
+% \begin{macrocode}
+italianizefraction = 0.5 --%% gives the amount of italianization
+mynode = nodenew(GLYPH) -- prepare a dummy glyph
+
+italianize = function(head)
+ -- skip "h/H" randomly
+ for n in node.traverse_id(GLYPH,head) do -- go through all glyphs
+ if n.prev.id ~= GLYPH then -- check if it's a word start
+ if ((n.char == 72) or (n.char == 104)) and (tex.normal_rand() < italianizefraction) then -- if it's h/H, remove randomly
+ n.prev.next = n.next
+ end
+ end
+ end
+
+ -- add h or H in front of vowels
+ for n in nodetraverseid(GLYPH,head) do
+ if math.random() < italianizefraction then
+ x = n.char
+ if x == 97 or x == 101 or x == 105 or x == 111 or x == 117 or
+ x == 65 or x == 69 or x == 73 or x == 79 or x == 85 then
+ if (n.prev.id == GLUE) then
+ mynode.font = n.font
+ if x > 90 then -- lower case
+ mynode.char = 104
+ else
+ mynode.char = 72 -- upper case – convert into lower case
+ n.char = x + 32
+ end
+ node.insert_before(head,n,node.copy(mynode))
+ end
+ end
+ end
+ end
+
+ -- add e after words, but only after consonants
+ for n in node.traverse_id(GLUE,head) do
+ if n.prev.id == GLYPH then
+ x = n.prev.char
+ -- skip vowels and randomize
+ if not(x == 97 or x == 101 or x == 105 or x == 111 or x == 117 or x == 44 or x == 46) and math.random() > 0.2 then
+ mynode.char = 101 -- it's always a lower case e, no?
+ mynode.font = n.prev.font -- adapt the current font
+ node.insert_before(head,n,node.copy(mynode)) -- insert the e in the node list
+ end
+ end
+ end
+
+ return head
+end
+% \end{macrocode}
+% \subsection{italianizerandwords}\label{sec:italianizerandwords}
+% This is inspired by my dearest colleagues and their artistic interpretation of the english grammar. The command will cause LuaTeX to read a sentence (i.\,e.~text until the next full stop), then randomizes the words (i.\,e.~units separated by a space) in it and throws the result back to the typesetting. Useless? Very.
+% \begin{macrocode}
+italianizerandwords = function(head)
+words = {}
+wordnumber = 0
+-- head.next.next is the very first word. However, let's try to get the first word after the first space correct.
+ for n in nodetraverseid(GLUE,head) do -- let's try to count words by their separators
+ wordnumber = wordnumber + 1
+ if n.next then
+ words[wordnumber] = {}
+ words[wordnumber][1] = node.copy(n.next)
+
+ glyphnumber = 1
+ myglyph = n.next
+ while myglyph.next do
+ node.tail(words[wordnumber][1]).next = node.copy(myglyph.next)
+ myglyph = myglyph.next
+ end
+ end
+ print(#words)
+ if #words > 0 then
+ print("lengs is: ")
+ print(#words[#words])
+ end
+ end
+--myinsertnode = head.next.next -- first letter
+--node.tail(words[1][1]).next = myinsertnode.next
+--myinsertnode.next = words[1][1]
+
+ return head
+end
+
+italianize_old = function(head)
+ local wordlist = {} -- here we will store the number of words of the sentence.
+ local words = {} -- here we will store the words of the sentence.
+ local wordnumber = 0
+ -- let's first count all words in one sentence, howboutdat?
+ wordlist[wordnumber] = 1 -- let's save the word *length* in here …
+
+
+ for n in nodetraverseid(GLYPH,head) do
+ if (n.next.id == GLUE) then -- this is a space
+ wordnumber = wordnumber + 1
+ wordlist[wordnumber] = 1
+ words[wordnumber] = n.next.next
+ end
+ if (n.next.id == GLYPH) then -- it's a glyph
+ if (n.next.char == 46) then -- this is a full stop.
+ wordnumber = wordnumber + 1
+ texio.write_nl("this sentence had "..wordnumber.."words.")
+ for i=0,wordnumber-1 do
+ texio.write_nl("word "..i.." had " .. wordlist[i] .. "glyphs")
+ end
+ texio.write_nl(" ")
+ wordnumber = -1 -- to compensate the fact that the next node will be a space, this would count one word too much.
+ else
+
+ wordlist[wordnumber] = wordlist[wordnumber] + 1 -- the current word got 1 glyph longer
+ end
+ end
+ end
+ return head
+end
+% \end{macrocode}
+
% \subsection{itsame}\label{sec:itsame}
% The (very first, very basic, very stupid) code to draw a small mario. You need to input luadraw.tex or do luadraw.lua for the rectangle function.
% \begin{macrocode}
@@ -1342,8 +1775,8 @@ end
% Why the synonym |stealsheep|? Because of a comment of Paul on the |texhax| mailing list: \url{http://tug.org/pipermail/texhax/2011-October/018374.html}
% \subsubsection{setup of variables}
% \begin{macrocode}
-local letterspace_glue = nodenew(nodeid"glue")
-local letterspace_pen = nodenew(nodeid"penalty")
+local letterspace_glue = nodenew(GLUE)
+local letterspace_pen = nodenew(PENALTY)
letterspace_glue.width = tex.sp"0pt"
letterspace_glue.stretch = tex.sp"0.5pt"
@@ -1352,8 +1785,8 @@ letterspace_pen.penalty = 10000
% \subsubsection{function implementation}
% \begin{macrocode}
letterspaceadjust = function(head)
- for glyph in nodetraverseid(nodeid"glyph", head) do
- if glyph.prev and (glyph.prev.id == nodeid"glyph" or glyph.prev.id == nodeid"disc" or glyph.prev.id == nodeid"kern") then
+ for glyph in nodetraverseid(GLYPH, head) do
+ if glyph.prev and (glyph.prev.id == GLYPH or glyph.prev.id == DISC or glyph.prev.id == KERN) then
local g = nodecopy(letterspace_glue)
nodeinsertbefore(head, glyph, g)
nodeinsertbefore(head, g, nodecopy(letterspace_pen))
@@ -1366,9 +1799,9 @@ end
% The |\text...|-version of |letterspaceadjust|. Just works, without the need to call |\letterspaceadjust| globally or anything else. Just put the |\textletterspaceadjust| around the part of text you want the function to work on. Might have problems with surrounding spacing, take care!
% \begin{macrocode}
textletterspaceadjust = function(head)
- for glyph in nodetraverseid(nodeid"glyph", head) do
+ for glyph in nodetraverseid(GLYPH, head) do
if node.has_attribute(glyph,luatexbase.attributes.letterspaceadjustattr) then
- if glyph.prev and (glyph.prev.id == node.id"glyph" or glyph.prev.id == node.id"disc" or glyph.prev.id == nodeid"kern") then
+ if glyph.prev and (glyph.prev.id == node.id"glyph" or glyph.prev.id == node.id"disc" or glyph.prev.id == KERN) then
local g = node.copy(letterspace_glue)
nodeinsertbefore(head, glyph, g)
nodeinsertbefore(head, g, nodecopy(letterspace_pen))
@@ -1384,8 +1817,8 @@ end
% \begin{macrocode}
matrixize = function(head)
x = {}
- s = nodenew(nodeid"disc")
- for n in nodetraverseid(nodeid"glyph",head) do
+ s = nodenew(DISC)
+ for n in nodetraverseid(GLYPH,head) do
j = n.char
for m = 0,7 do -- stay ASCII for now
x[7-m] = nodecopy(n) -- to get the same font etc.
@@ -1470,7 +1903,7 @@ pancaketext = function()
end
% \end{macrocode}
% \subsection{randomerror}\label{sec:randomerror}
-
+% Not yet implemented, sorry.
% \subsection{randomfonts}\label{sec:randomfonts}
% Traverses the output and substitutes fonts randomly. A check is done so that the font number is existing.
@@ -1600,9 +2033,68 @@ randomcolor = function(head)
return head
end
% \end{macrocode}
-% \subsection{randomerror}\label{sec:randomerror}
+% \subsection{relationship}\label{sec:relationship}
+% It literally is what is says: A ship made of relations. Or a boat, rather. There are four parameters, |sailheight|, |mastheight|, |hullheight|, and |relnumber| which you can adjust.
% \begin{macrocode}
-%
+ sailheight = 12
+ mastheight = 4
+ hullheight = 5
+ relnumber = 402
+function relationship()
+--%% check if there's a problem with any character in the current font
+ f = font.getfont(font.current())
+ fullfont = 1
+ for i = 8756,8842 do
+ if not(f.characters[i]) then texio.write_nl((i).." not available") fullfont = 0 end
+ end
+--%% store the result of the check for later, then go on to construct the ship:
+ shipheight = sailheight + mastheight + hullheight
+ tex.print("\\parshape "..(shipheight)) --%% prepare the paragraph shape ...
+ for i =1,sailheight do
+ tex.print(" "..(4.5-i/3.8).."cm "..((i-0.5)/2.5).."cm ")
+ end
+ for i =1,mastheight do
+ tex.print(" "..(3.2).."cm "..(1).."cm ")
+ end
+ for i =1,hullheight do
+ tex.print(" "..((i-1)/2).."cm "..(10-i).."cm ")
+ end
+ tex.print("\\noindent") --%% ... up to here, then insert relations
+ for i=1,relnumber do
+ tex.print("\\ \\char"..math.random(8756,8842))
+ end
+ tex.print("\\break")
+end
+% \end{macrocode}
+% And this is a helper function to prevent too many relations to be typeset. Problem: The relations are chosen randomly, and each might take different horizontial space. So we cannot make sure the same number of lines for each version. To catch this, we typeset more lines and just remove excess lines with a simple function in our beloved |post_linebreak_filter|.
+% \begin{macrocode}
+function cutparagraph(head)
+ local parsum = 0
+ for n in nodetraverseid(HLIST,head) do
+ parsum = parsum + 1
+ if parsum > shipheight then
+ node.remove(head,n)
+ end
+ end
+ return head
+end
+% \end{macrocode}
+% And finally a helper function to inform our dear users that they have to use a font that actually can display all the necessary symbols.
+% \begin{macrocode}
+function missingcharstext()
+ if (fullfont == 0) then
+ local separator = string.rep("=", 28)
+local texiowrite_nl = texio.write_nl
+ texiowrite_nl("Output written on "..tex.jobname..".pdf ("..status.total_pages.." chicken,".." eggs).")
+ texiowrite_nl(" ")
+ texiowrite_nl(separator)
+ texiowrite_nl("CAREFUL!!")
+ texiowrite_nl("\\relationship needs special characters (unicode points 8756 to 8842)")
+ texiowrite_nl("Your font does not support all of them!")
+ texiowrite_nl("consider using another one, e.g. the XITS font supplied with TeXlive.")
+ texiowrite_nl(separator .. "\n")
+ end
+end
% \end{macrocode}
% \subsection{rickroll}\label{sec:rickroll}
% Another tribute to pop culture. Either: substitute word-by-word as in pancake. OR: substitute each link to a youtube-rickroll …
@@ -1651,9 +2143,9 @@ end
tabularasa_onlytext = false
tabularasa = function(head)
- local s = nodenew(nodeid"kern")
- for line in nodetraverseid(nodeid"hlist",head) do
- for n in nodetraverseid(nodeid"glyph",line.head) do
+ local s = nodenew(KERN)
+ for line in nodetraverseid(HLIST,head) do
+ for n in nodetraverseid(GLYPH,line.head) do
if not(tabularasa_onlytext) or node.has_attribute(n,luatexbase.attributes.tabularasaattr) then
s.kern = n.width
nodeinsertafter(line.list,n,nodecopy(s))
@@ -1667,7 +2159,7 @@ end
% \subsection{tanjanize}\label{sec:tanjanize}
% \begin{macrocode}
tanjanize = function(head)
- local s = nodenew(nodeid"kern")
+ local s = nodenew(KERN)
local m = nodenew(GLYPH,1)
local use_letter_i = true
scale = nodenew(WHAT,PDF_LITERAL)
@@ -1675,8 +2167,8 @@ tanjanize = function(head)
scale.data = "0.5 0 0 0.5 0 0 cm"
scale2.data = "2 0 0 2 0 0 cm"
- for line in nodetraverseid(nodeid"hlist",head) do
- for n in nodetraverseid(nodeid"glyph",line.head) do
+ for line in nodetraverseid(HLIST,head) do
+ for n in nodetraverseid(GLYPH,line.head) do
mimicount = 0
tmpwidth = 0
while ((n.next.id == GLYPH) or (n.next.id == 11) or (n.next.id == 7) or (n.next.id == 0)) do --find end of a word
@@ -1780,11 +2272,18 @@ colorstretch = function (head)
local rule_bad = nodenew(RULE)
if colorexpansion then -- if also the font expansion should be shown
+--%% here use first_glyph function!!
local g = line.head
+n = node.first_glyph(line.head.next)
+texio.write_nl(line.head.id)
+texio.write_nl(line.head.next.id)
+texio.write_nl(line.head.next.next.id)
+texio.write_nl(n.id)
while not(g.id == GLYPH) and (g.next) do g = g.next end -- find first glyph on line. If line is empty, no glyph:
if (g.id == GLYPH) then -- read width only if g is a glyph!
- exp_factor = g.width / f[g.char].width
- exp_color = colorstretch_coloroffset + (1-exp_factor)*10 .. " g"
+ exp_factor = g.expansion_factor/10000 --%% neato, luatex now directly gives me this!!
+ exp_color = colorstretch_coloroffset + (exp_factor*0.1) .. " g"
+texio.write_nl(exp_factor)
rule_bad.width = 0.5*line.width -- we need two rules on each line!
end
else
@@ -1902,10 +2401,10 @@ substlist[1514] = 64296
% \begin{macrocode}
function variantjustification(head)
math.randomseed(1)
- for line in nodetraverseid(nodeid"hhead",head) do
+ for line in nodetraverseid(Hhead,head) do
if (line.glue_sign == 1 and line.glue_order == 0) then -- exclude the last line!
substitutions_wide = {} -- we store all “expandable” letters of each line
- for n in nodetraverseid(nodeid"glyph",line.head) do
+ for n in nodetraverseid(GLYPH,line.head) do
if (substlist[n.char]) then
substitutions_wide[#substitutions_wide+1] = n
end
@@ -1946,12 +2445,12 @@ zebracolorarray_bg[2] = "0.1 g"
% \begin{macrocode}
function zebranize(head)
zebracolor = 1
- for line in nodetraverseid(nodeid"hhead",head) do
+ for line in nodetraverseid(Hhead,head) do
if zebracolor == #zebracolorarray then zebracolor = 0 end
zebracolor = zebracolor + 1
color_push.data = zebracolorarray[zebracolor]
line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push))
- for n in nodetraverseid(nodeid"glyph",line.head) do
+ for n in nodetraverseid(GLYPH,line.head) do
if n.next then else
nodeinsertafter(line.head,n,nodecopy(color_pull))
end
@@ -1979,6 +2478,7 @@ end
% Well, it's not the whole story so far. I plan to test some drawing using only Lua code, writing directly to the pdf file. This section will grow and get better in parallel to my understandings of what's going on. I.e. it will be very slowly … Nothing here is to be taken as good and/or correct LuaTeXing, and most code is plain ugly. However, it kind of works already {\XITS ☺}
% \section{Drawing}
% A \emph{very} first, experimental implementation of a drawing of a chicken. The parameters should be consistent, easy to change and that monster should look more like a cute chicken. However, it is chicken, it is Lua, so it belongs into this package. So far, all numbers and positions are hard coded, this will of course change!
+% The parameters |sloppinessh| and |sloppinessv| give the amount of sloppiness, i.\,e.~how strongly the points are “wiggled” randomly to make the drawings more dynamically. You can set them at any time in the document
% \begin{macrocode}
--
function pdf_print (...)
@@ -1988,24 +2488,42 @@ function pdf_print (...)
pdf.print("\n")
end
-function move (p)
- pdf_print(p[1],p[2],"m")
+function move (p1,p2)
+ if (p2) then
+ pdf_print(p1,p2,"m")
+ else
+ pdf_print(p1[1],p1[2],"m")
+ end
end
-function line (p)
- pdf_print(p[1],p[2],"l")
+function line(p1,p2)
+ if (p2) then
+ pdf_print(p1,p2,"l")
+ else
+ pdf_print(p1[1],p1[2],"l")
+ end
end
-function curve(p1,p2,p3)
+function curve(p11,p12,p21,p22,p31,p32)
+ if (p22) then
+ p1,p2,p3 = {p11,p12},{p21,p22},{p31,p32}
+ else
+ p1,p2,p3 = p11,p12,p21
+ end
pdf_print(p1[1], p1[2],
- p2[1], p2[2],
- p3[1], p3[2], "c")
+ p2[1], p2[2],
+ p3[1], p3[2], "c")
end
function close ()
pdf_print("h")
end
+% \end{macrocode}
+% By setting |drawwidth| to something different than 1 you can adjust the thickness of the strokes. Any stroke done with the |sloppy| functions will by varied between |0.5 drawwidth| and |1.5 drawwidth|.
+% \begin{macrocode}
+drawwidth = 1
+
function linewidth (w)
pdf_print(w,"w")
end
@@ -2029,9 +2547,12 @@ function strictcircle(center,radius)
stroke()
end
+sloppynessh = 5
+sloppynessv = 5
+
function disturb_point(point)
- return {point[1] + math.random()*5 - 2.5,
- point[2] + math.random()*5 - 2.5}
+ return {point[1] + (math.random() - 1/2)*sloppynessh,
+ point[2] + (math.random() - 1/2)*sloppynessv}
end
function sloppycircle(center,radius)
@@ -2047,7 +2568,24 @@ function sloppycircle(center,radius)
move (right)
curve (rightbot, leftbot, left)
curve (lefttop, righttop, right_end)
- linewidth(math.random()+0.5)
+ linewidth(drawwidth*(math.random()+0.5))
+ stroke()
+end
+
+function sloppyellipsis(center,radiusx,radiusy)
+ local left = disturb_point({center[1] - radiusx, center[2]})
+ local lefttop = disturb_point({left[1], left[2] + 1.45*radiusy})
+ local leftbot = {lefttop[1], lefttop[2] - 2.9*radiusy}
+ local right = disturb_point({center[1] + radiusx, center[2]})
+ local righttop = disturb_point({right[1], right[2] + 1.45*radiusy})
+ local rightbot = disturb_point({right[1], right[2] - 1.45*radiusy})
+
+ local right_end = disturb_point(right)
+
+ move (right)
+ curve (rightbot, leftbot, left)
+ curve (lefttop, righttop, right_end)
+ linewidth(drawwidth*(math.random()+0.5))
stroke()
end
@@ -2057,7 +2595,7 @@ function sloppyline(start,stop)
start = disturb_point(start)
stop = disturb_point(stop)
move(start) curve(start_line,stop_line,stop)
- linewidth(math.random()+0.5)
+ linewidth(drawwidth*(math.random()+0.5))
stroke()
end
% \end{macrocode}
diff --git a/macros/luatex/generic/chickenize/chickenize.lua b/macros/luatex/generic/chickenize/chickenize.lua
deleted file mode 100644
index c25aa75b75..0000000000
--- a/macros/luatex/generic/chickenize/chickenize.lua
+++ /dev/null
@@ -1,965 +0,0 @@
---
--- This is file `chickenize.lua',
--- generated with the docstrip utility.
---
--- The original source files were:
---
--- chickenize.dtx (with options: `lua')
---
--- EXPERIMENTAL CODE
---
--- This package is copyright © 2017 Arno L. Trautmann. It 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. This work has the LPPL mainten-
--- ance status ‘maintained’.
-
-local nodeid = node.id
-local nodecopy = node.copy
-local nodenew = node.new
-local nodetail = node.tail
-local nodeslide = node.slide
-local noderemove = node.remove
-local nodetraverseid = node.traverse_id
-local nodeinsertafter = node.insert_after
-local nodeinsertbefore = node.insert_before
-
-Hhead = nodeid("hhead")
-RULE = nodeid("rule")
-GLUE = nodeid("glue")
-WHAT = nodeid("whatsit")
-COL = node.subtype("pdf_colorstack")
-DISC = nodeid("disc")
-GLYPH = nodeid("glyph")
-GLUE = nodeid("glue")
-HLIST = nodeid("hlist")
-KERN = nodeid("kern")
-PUNCT = nodeid("punct")
-PENALTY = nodeid("penalty")
-PDF_LITERAL = node.subtype("pdf_literal")
-color_push = nodenew(WHAT,COL)
-color_pop = nodenew(WHAT,COL)
-color_push.stack = 0
-color_pop.stack = 0
-color_push.command = 1
-color_pop.command = 2
-chicken_pagenumbers = true
-
-chickenstring = {}
-chickenstring[1] = "chicken" -- chickenstring is a table, please remeber this!
-
-chickenizefraction = 0.5
--- set this to a small value to fool somebody, or to see if your text has been read carefully. This is also a great way to lay easter eggs for your own class / package …
-chicken_substitutions = 0 -- value to count the substituted chickens. Makes sense for testing your proofreaders.
-
-local match = unicode.utf8.match
-chickenize_ignore_word = false
-chickenize_real_stuff = function(i,head)
- while ((i.next.id == GLYPH) or (i.next.id == KERN) or (i.next.id == DISC) or (i.next.id == HLIST)) do --find end of a word
- i.next = i.next.next
- end
-
- chicken = {} -- constructing the node list.
-
--- Should this be done only once? No, otherwise we lose the freedom to change the string in-document.
--- But it could be done only once each paragraph as in-paragraph changes are not possible!
-
- chickenstring_tmp = chickenstring[math.random(1,#chickenstring)]
- chicken[0] = nodenew(GLYPH,1) -- only a dummy for the loop
- for i = 1,string.len(chickenstring_tmp) do
- chicken[i] = nodenew(GLYPH,1)
- chicken[i].font = font.current()
- chicken[i-1].next = chicken[i]
- end
-
- j = 1
- for s in string.utfvalues(chickenstring_tmp) do
- local char = unicode.utf8.char(s)
- chicken[j].char = s
- if match(char,"%s") then
- chicken[j] = nodenew(GLUE)
- chicken[j].width = space
- chicken[j].shrink = shrink
- chicken[j].stretch = stretch
- end
- j = j+1
- end
-
- nodeslide(chicken[1])
- lang.hyphenate(chicken[1])
- chicken[1] = node.kerning(chicken[1]) -- FIXME: does not work
- chicken[1] = node.ligaturing(chicken[1]) -- dito
-
- nodeinsertbefore(head,i,chicken[1])
- chicken[1].next = chicken[2] -- seems to be necessary … to be fixed
- chicken[string.len(chickenstring_tmp)].next = i.next
-
- -- shift lowercase latin letter to uppercase if the original input was an uppercase
- if (chickenize_capital and (chicken[1].char > 96 and chicken[1].char < 123)) then
- chicken[1].char = chicken[1].char - 32
- end
-
- return head
-end
-
-chickenize = function(head)
- for i in nodetraverseid(GLYPH,head) do --find start of a word
- -- Random determination of the chickenization of the next word:
- if math.random() > chickenizefraction then
- chickenize_ignore_word = true
- elseif chickencount then
- chicken_substitutions = chicken_substitutions + 1
- end
-
- if (chickenize_ignore_word == false) then -- normal case: at the beginning of a word, we jump into chickenization
- if (i.char > 64 and i.char < 91) then chickenize_capital = true else chickenize_capital = false end
- head = chickenize_real_stuff(i,head)
- end
-
--- At the end of the word, the ignoring is reset. New chance for everyone.
- if not((i.next.id == GLYPH) or (i.next.id == DISC) or (i.next.id == PUNCT) or (i.next.id == KERN)) then
- chickenize_ignore_word = false
- end
- end
- return head
-end
-
-local separator = string.rep("=", 28)
-local texiowrite_nl = texio.write_nl
-nicetext = function()
- texiowrite_nl("Output written on "..tex.jobname..".pdf ("..status.total_pages.." chicken,".." eggs).")
- texiowrite_nl(" ")
- texiowrite_nl(separator)
- texiowrite_nl("Hello my dear user,")
- texiowrite_nl("good job, now go outside and enjoy the world!")
- texiowrite_nl(" ")
- texiowrite_nl("And don't forget to feed your chicken!")
- texiowrite_nl(separator .. "\n")
- if chickencount then
- texiowrite_nl("There were "..chicken_substitutions.." substitutions made.")
- texiowrite_nl(separator)
- end
-end
-boustrophedon = function(head)
- rot = node.new(WHAT,PDF_LITERAL)
- rot2 = node.new(WHAT,PDF_LITERAL)
- odd = true
- for line in node.traverse_id(0,head) do
- if odd == false then
- w = line.width/65536*0.99625 -- empirical correction factor (?)
- rot.data = "-1 0 0 1 "..w.." 0 cm"
- rot2.data = "-1 0 0 1 "..-w.." 0 cm"
- line.head = node.insert_before(line.head,line.head,nodecopy(rot))
- nodeinsertafter(line.head,nodetail(line.head),nodecopy(rot2))
- odd = true
- else
- odd = false
- end
- end
- return head
-end
-boustrophedon_glyphs = function(head)
- odd = false
- rot = nodenew(WHAT,PDF_LITERAL)
- rot2 = nodenew(WHAT,PDF_LITERAL)
- for line in nodetraverseid(0,head) do
- if odd==true then
- line.dir = "TRT"
- for g in nodetraverseid(GLYPH,line.head) do
- w = -g.width/65536*0.99625
- rot.data = "-1 0 0 1 " .. w .." 0 cm"
- rot2.data = "-1 0 0 1 " .. -w .." 0 cm"
- line.head = node.insert_before(line.head,g,nodecopy(rot))
- nodeinsertafter(line.head,g,nodecopy(rot2))
- end
- odd = false
- else
- line.dir = "TLT"
- odd = true
- end
- end
- return head
-end
-boustrophedon_inverse = function(head)
- rot = node.new(WHAT,PDF_LITERAL)
- rot2 = node.new(WHAT,PDF_LITERAL)
- odd = true
- for line in node.traverse_id(0,head) do
- if odd == false then
-texio.write_nl(line.height)
- w = line.width/65536*0.99625 -- empirical correction factor (?)
- h = line.height/65536*0.99625
- rot.data = "-1 0 0 -1 "..w.." "..h.." cm"
- rot2.data = "-1 0 0 -1 "..-w.." "..0.5*h.." cm"
- line.head = node.insert_before(line.head,line.head,node.copy(rot))
- node.insert_after(line.head,node.tail(line.head),node.copy(rot2))
- odd = true
- else
- odd = false
- end
- end
- return head
-end
-function bubblesort(head)
- for line in nodetraverseid(0,head) do
- for glyph in nodetraverseid(GLYPH,line.head) do
-
- end
- end
- return head
-end
--- Take care: This will slow down the compilation extremely, by about a factor of 2! Only use for playing around or counting a final version of your document!
-countglyphs = function(head)
- for line in nodetraverseid(0,head) do
- for glyph in nodetraverseid(GLYPH,line.head) do
- glyphnumber = glyphnumber + 1
- if (glyph.next.next) then
- if (glyph.next.id == 10) and (glyph.next.next.id == GLYPH) then
- spacenumber = spacenumber + 1
- end
- counted_glyphs_by_code[glyph.char] = counted_glyphs_by_code[glyph.char] + 1
- end
- end
- end
- return head
-end
-printglyphnumber = function()
- texiowrite_nl("\nNumber of glyphs by character code (only up to 127):")
- for i = 1,127 do --%% FIXME: should allow for more characters, but cannot be printed to console output – print into document?
- texiowrite_nl(string.char(i)..": "..counted_glyphs_by_code[i])
- end
-
- texiowrite_nl("\nTotal number of glyphs in this document: "..glyphnumber)
- texiowrite_nl("Number of spaces in this document: "..spacenumber)
- texiowrite_nl("Glyphs plus spaces: "..glyphnumber+spacenumber.."\n")
-end
-countwords = function(head)
- for glyph in nodetraverseid(GLYPH,head) do
- if (glyph.next.id == 10) then
- wordnumber = wordnumber + 1
- end
- end
- wordnumber = wordnumber + 1 -- add 1 for the last word in a paragraph which is not found otherwise
- return head
-end
-printwordnumber = function()
- texiowrite_nl("\nNumber of words in this document: "..wordnumber)
-end
-
-function detectdoublewords(head)
- prevlastword = {} -- array of numbers representing the glyphs
- prevfirstword = {}
- newlastword = {}
- newfirstword = {}
- for line in nodetraverseid(0,head) do
- for g in nodetraverseid(GLYPH,line.head) do
-texio.write_nl("next glyph",#newfirstword+1)
- newfirstword[#newfirstword+1] = g.char
- if (g.next.id == 10) then break end
- end
-texio.write_nl("nfw:"..#newfirstword)
- end
-end
-
-function printdoublewords()
- texio.write_nl("finished")
-end
-local quotestrings = {
- [171] = true, [172] = true,
- [8216] = true, [8217] = true, [8218] = true,
- [8219] = true, [8220] = true, [8221] = true,
- [8222] = true, [8223] = true,
- [8248] = true, [8249] = true, [8250] = true,
-}
-guttenbergenize_rq = function(head)
- for n in nodetraverseid(nodeid"glyph",head) do
- local i = n.char
- if quotestrings[i] then
- noderemove(head,n)
- end
- end
- return head
-end
-hammertimedelay = 1.2
-local htime_separator = string.rep("=", 30) .. "\n" -- slightly inconsistent with the “nicetext”
-hammertime = function(head)
- if hammerfirst then
- texiowrite_nl(htime_separator)
- texiowrite_nl("============STOP!=============\n")
- texiowrite_nl(htime_separator .. "\n\n\n")
- os.sleep (hammertimedelay*1.5)
- texiowrite_nl(htime_separator .. "\n")
- texiowrite_nl("==========HAMMERTIME==========\n")
- texiowrite_nl(htime_separator .. "\n\n")
- os.sleep (hammertimedelay)
- hammerfirst = false
- else
- os.sleep (hammertimedelay)
- texiowrite_nl(htime_separator)
- texiowrite_nl("======U can't touch this!=====\n")
- texiowrite_nl(htime_separator .. "\n\n")
- os.sleep (hammertimedelay*0.5)
- end
- return head
-end
-itsame = function()
-local mr = function(a,b) rectangle({a*10,b*-10},10,10) end
-color = "1 .6 0"
-for i = 6,9 do mr(i,3) end
-for i = 3,11 do mr(i,4) end
-for i = 3,12 do mr(i,5) end
-for i = 4,8 do mr(i,6) end
-for i = 4,10 do mr(i,7) end
-for i = 1,12 do mr(i,11) end
-for i = 1,12 do mr(i,12) end
-for i = 1,12 do mr(i,13) end
-
-color = ".3 .5 .2"
-for i = 3,5 do mr(i,3) end mr(8,3)
-mr(2,4) mr(4,4) mr(8,4)
-mr(2,5) mr(4,5) mr(5,5) mr(9,5)
-mr(2,6) mr(3,6) for i = 8,11 do mr(i,6) end
-for i = 3,8 do mr(i,8) end
-for i = 2,11 do mr(i,9) end
-for i = 1,12 do mr(i,10) end
-mr(3,11) mr(10,11)
-for i = 2,4 do mr(i,15) end for i = 9,11 do mr(i,15) end
-for i = 1,4 do mr(i,16) end for i = 9,12 do mr(i,16) end
-
-color = "1 0 0"
-for i = 4,9 do mr(i,1) end
-for i = 3,12 do mr(i,2) end
-for i = 8,10 do mr(5,i) end
-for i = 5,8 do mr(i,10) end
-mr(8,9) mr(4,11) mr(6,11) mr(7,11) mr(9,11)
-for i = 4,9 do mr(i,12) end
-for i = 3,10 do mr(i,13) end
-for i = 3,5 do mr(i,14) end
-for i = 7,10 do mr(i,14) end
-end
-chickenkernamount = 0
-chickeninvertkerning = false
-
-function kernmanipulate (head)
- if chickeninvertkerning then -- invert the kerning
- for n in nodetraverseid(11,head) do
- n.kern = -n.kern
- end
- else -- if not, set it to the given value
- for n in nodetraverseid(11,head) do
- n.kern = chickenkernamount
- end
- end
- return head
-end
-
-leetspeak_onlytext = false
-leettable = {
- [101] = 51, -- E
- [105] = 49, -- I
- [108] = 49, -- L
- [111] = 48, -- O
- [115] = 53, -- S
- [116] = 55, -- T
-
- [101-32] = 51, -- e
- [105-32] = 49, -- i
- [108-32] = 49, -- l
- [111-32] = 48, -- o
- [115-32] = 53, -- s
- [116-32] = 55, -- t
-}
-leet = function(head)
- for line in nodetraverseid(Hhead,head) do
- for i in nodetraverseid(GLYPH,line.head) do
- if not leetspeak_onlytext or
- node.has_attribute(i,luatexbase.attributes.leetattr)
- then
- if leettable[i.char] then
- i.char = leettable[i.char]
- end
- end
- end
- end
- return head
-end
-leftsideright = function(head)
- local factor = 65536/0.99626
- for n in nodetraverseid(GLYPH,head) do
- if (leftsiderightarray[n.char]) then
- shift = nodenew(WHAT,PDF_LITERAL)
- shift2 = nodenew(WHAT,PDF_LITERAL)
- shift.data = "q -1 0 0 1 " .. n.width/factor .." 0 cm"
- shift2.data = "Q 1 0 0 1 " .. n.width/factor .." 0 cm"
- nodeinsertbefore(head,n,shift)
- nodeinsertafter(head,n,shift2)
- end
- end
- return head
-end
-local letterspace_glue = nodenew(nodeid"glue")
-local letterspace_pen = nodenew(nodeid"penalty")
-
-letterspace_glue.width = tex.sp"0pt"
-letterspace_glue.stretch = tex.sp"0.5pt"
-letterspace_pen.penalty = 10000
-letterspaceadjust = function(head)
- for glyph in nodetraverseid(nodeid"glyph", head) do
- if glyph.prev and (glyph.prev.id == nodeid"glyph" or glyph.prev.id == nodeid"disc" or glyph.prev.id == nodeid"kern") then
- local g = nodecopy(letterspace_glue)
- nodeinsertbefore(head, glyph, g)
- nodeinsertbefore(head, g, nodecopy(letterspace_pen))
- end
- end
- return head
-end
-textletterspaceadjust = function(head)
- for glyph in nodetraverseid(nodeid"glyph", head) do
- if node.has_attribute(glyph,luatexbase.attributes.letterspaceadjustattr) then
- if glyph.prev and (glyph.prev.id == node.id"glyph" or glyph.prev.id == node.id"disc" or glyph.prev.id == nodeid"kern") then
- local g = node.copy(letterspace_glue)
- nodeinsertbefore(head, glyph, g)
- nodeinsertbefore(head, g, nodecopy(letterspace_pen))
- end
- end
- end
- luatexbase.remove_from_callback("pre_linebreak_filter","textletterspaceadjust")
- return head
-end
-matrixize = function(head)
- x = {}
- s = nodenew(nodeid"disc")
- for n in nodetraverseid(nodeid"glyph",head) do
- j = n.char
- for m = 0,7 do -- stay ASCII for now
- x[7-m] = nodecopy(n) -- to get the same font etc.
-
- if (j / (2^(7-m)) < 1) then
- x[7-m].char = 48
- else
- x[7-m].char = 49
- j = j-(2^(7-m))
- end
- nodeinsertbefore(head,n,x[7-m])
- nodeinsertafter(head,x[7-m],nodecopy(s))
- end
- noderemove(head,n)
- end
- return head
-end
-medievalumlaut = function(head)
- local factor = 65536/0.99626
- local org_e_node = nodenew(GLYPH)
- org_e_node.char = 101
- for line in nodetraverseid(0,head) do
- for n in nodetraverseid(GLYPH,line.head) do
- if (n.char == 228 or n.char == 246 or n.char == 252) then
- e_node = nodecopy(org_e_node)
- e_node.font = n.font
- shift = nodenew(WHAT,PDF_LITERAL)
- shift2 = nodenew(WHAT,PDF_LITERAL)
- shift2.data = "Q 1 0 0 1 " .. e_node.width/factor .." 0 cm"
- nodeinsertafter(head,n,e_node)
-
- nodeinsertbefore(head,e_node,shift)
- nodeinsertafter(head,e_node,shift2)
-
- x_node = nodenew(KERN)
- x_node.kern = -e_node.width
- nodeinsertafter(head,shift2,x_node)
- end
-
- if (n.char == 228) then -- ä
- shift.data = "q 0.5 0 0 0.5 " ..
- -n.width/factor*0.85 .." ".. n.height/factor*0.75 .. " cm"
- n.char = 97
- end
- if (n.char == 246) then -- ö
- shift.data = "q 0.5 0 0 0.5 " ..
- -n.width/factor*0.75 .." ".. n.height/factor*0.75 .. " cm"
- n.char = 111
- end
- if (n.char == 252) then -- ü
- shift.data = "q 0.5 0 0 0.5 " ..
- -n.width/factor*0.75 .." ".. n.height/factor*0.75 .. " cm"
- n.char = 117
- end
- end
- end
- return head
-end
-local separator = string.rep("=", 28)
-local texiowrite_nl = texio.write_nl
-pancaketext = function()
- texiowrite_nl("Output written on "..tex.jobname..".pdf ("..status.total_pages.." chicken,".." eggs).")
- texiowrite_nl(" ")
- texiowrite_nl(separator)
- texiowrite_nl("Soo ... you decided to use \\pancakenize.")
- texiowrite_nl("That means you owe me a pancake!")
- texiowrite_nl(" ")
- texiowrite_nl("(This goes by document, not compilation.)")
- texiowrite_nl(separator.."\n\n")
- texiowrite_nl("Looking forward for my pancake! :)")
- texiowrite_nl("\n\n")
-end
-
-randomfontslower = 1
-randomfontsupper = 0
-randomfonts = function(head)
- local rfub
- if randomfontsupper > 0 then -- fixme: this should be done only once, no? Or at every paragraph?
- rfub = randomfontsupper -- user-specified value
- else
- rfub = font.max() -- or just take all fonts
- end
- for line in nodetraverseid(Hhead,head) do
- for i in nodetraverseid(GLYPH,line.head) do
- if not(randomfonts_onlytext) or node.has_attribute(i,luatexbase.attributes.randfontsattr) then
- i.font = math.random(randomfontslower,rfub)
- end
- end
- end
- return head
-end
-uclcratio = 0.5 -- ratio between uppercase and lower case
-randomuclc = function(head)
- for i in nodetraverseid(GLYPH,head) do
- if not(randomuclc_onlytext) or node.has_attribute(i,luatexbase.attributes.randuclcattr) then
- if math.random() < uclcratio then
- i.char = tex.uccode[i.char]
- else
- i.char = tex.lccode[i.char]
- end
- end
- end
- return head
-end
-randomchars = function(head)
- for line in nodetraverseid(Hhead,head) do
- for i in nodetraverseid(GLYPH,line.head) do
- i.char = math.floor(math.random()*512)
- end
- end
- return head
-end
-randomcolor_grey = false
-randomcolor_onlytext = false --switch between local and global colorization
-rainbowcolor = false
-
-grey_lower = 0
-grey_upper = 900
-
-Rgb_lower = 1
-rGb_lower = 1
-rgB_lower = 1
-Rgb_upper = 254
-rGb_upper = 254
-rgB_upper = 254
-rainbow_step = 0.005
-rainbow_Rgb = 1-rainbow_step -- we start in the red phase
-rainbow_rGb = rainbow_step -- values x must always be 0 < x < 1
-rainbow_rgB = rainbow_step
-rainind = 1 -- 1:red,2:yellow,3:green,4:blue,5:purple
-randomcolorstring = function()
- if randomcolor_grey then
- return (0.001*math.random(grey_lower,grey_upper)).." g"
- elseif rainbowcolor then
- if rainind == 1 then -- red
- rainbow_rGb = rainbow_rGb + rainbow_step
- if rainbow_rGb >= 1-rainbow_step then rainind = 2 end
- elseif rainind == 2 then -- yellow
- rainbow_Rgb = rainbow_Rgb - rainbow_step
- if rainbow_Rgb <= rainbow_step then rainind = 3 end
- elseif rainind == 3 then -- green
- rainbow_rgB = rainbow_rgB + rainbow_step
- rainbow_rGb = rainbow_rGb - rainbow_step
- if rainbow_rGb <= rainbow_step then rainind = 4 end
- elseif rainind == 4 then -- blue
- rainbow_Rgb = rainbow_Rgb + rainbow_step
- if rainbow_Rgb >= 1-rainbow_step then rainind = 5 end
- else -- purple
- rainbow_rgB = rainbow_rgB - rainbow_step
- if rainbow_rgB <= rainbow_step then rainind = 1 end
- end
- return rainbow_Rgb.." "..rainbow_rGb.." "..rainbow_rgB.." rg"
- else
- Rgb = math.random(Rgb_lower,Rgb_upper)/255
- rGb = math.random(rGb_lower,rGb_upper)/255
- rgB = math.random(rgB_lower,rgB_upper)/255
- return Rgb.." "..rGb.." "..rgB.." ".." rg"
- end
-end
-randomcolor = function(head)
- for line in nodetraverseid(0,head) do
- for i in nodetraverseid(GLYPH,line.head) do
- if not(randomcolor_onlytext) or
- (node.has_attribute(i,luatexbase.attributes.randcolorattr))
- then
- color_push.data = randomcolorstring() -- color or grey string
- line.head = nodeinsertbefore(line.head,i,nodecopy(color_push))
- nodeinsertafter(line.head,i,nodecopy(color_pop))
- end
- end
- end
- return head
-end
-substitutewords_strings = {}
-
-addtosubstitutions = function(input,output)
- substitutewords_strings[#substitutewords_strings + 1] = {}
- substitutewords_strings[#substitutewords_strings][1] = input
- substitutewords_strings[#substitutewords_strings][2] = output
-end
-
-substitutewords = function(head)
- for i = 1,#substitutewords_strings do
- head = string.gsub(head,substitutewords_strings[i][1],substitutewords_strings[i][2])
- end
- return head
-end
-suppressonecharbreakpenaltynode = node.new(PENALTY)
-suppressonecharbreakpenaltynode.penalty = 10000
-function suppressonecharbreak(head)
- for i in node.traverse_id(GLUE,head) do
- if ((i.next) and (i.next.next.id == GLUE)) then
- pen = node.copy(suppressonecharbreakpenaltynode)
- node.insert_after(head,i.next,pen)
- end
- end
-
- return head
-end
-tabularasa_onlytext = false
-
-tabularasa = function(head)
- local s = nodenew(nodeid"kern")
- for line in nodetraverseid(nodeid"hlist",head) do
- for n in nodetraverseid(nodeid"glyph",line.head) do
- if not(tabularasa_onlytext) or node.has_attribute(n,luatexbase.attributes.tabularasaattr) then
- s.kern = n.width
- nodeinsertafter(line.list,n,nodecopy(s))
- line.head = noderemove(line.list,n)
- end
- end
- end
- return head
-end
-tanjanize = function(head)
- local s = nodenew(nodeid"kern")
- local m = nodenew(GLYPH,1)
- local use_letter_i = true
- scale = nodenew(WHAT,PDF_LITERAL)
- scale2 = nodenew(WHAT,PDF_LITERAL)
- scale.data = "0.5 0 0 0.5 0 0 cm"
- scale2.data = "2 0 0 2 0 0 cm"
-
- for line in nodetraverseid(nodeid"hlist",head) do
- for n in nodetraverseid(nodeid"glyph",line.head) do
- mimicount = 0
- tmpwidth = 0
- while ((n.next.id == GLYPH) or (n.next.id == 11) or (n.next.id == 7) or (n.next.id == 0)) do --find end of a word
- n.next = n.next.next
- mimicount = mimicount + 1
- tmpwidth = tmpwidth + n.width
- end
-
- mimi = {} -- constructing the node list.
- mimi[0] = nodenew(GLYPH,1) -- only a dummy for the loop
- for i = 1,string.len(mimicount) do
- mimi[i] = nodenew(GLYPH,1)
- mimi[i].font = font.current()
- if(use_letter_i) then mimi[i].char = 109 else mimi[i].char = 105 end
- use_letter_i = not(use_letter_i)
- mimi[i-1].next = mimi[i]
- end
---]]
-
-line.head = nodeinsertbefore(line.head,n,nodecopy(scale))
-nodeinsertafter(line.head,n,nodecopy(scale2))
- s.kern = (tmpwidth*2-n.width)
- nodeinsertafter(line.head,n,nodecopy(s))
- end
- end
- return head
-end
-uppercasecolor_onlytext = false
-
-uppercasecolor = function (head)
- for line in nodetraverseid(Hhead,head) do
- for upper in nodetraverseid(GLYPH,line.head) do
- if not(uppercasecolor_onlytext) or node.has_attribute(upper,luatexbase.attributes.uppercasecolorattr) then
- if (((upper.char > 64) and (upper.char < 91)) or
- ((upper.char > 57424) and (upper.char < 57451))) then -- for small caps! nice ☺
- color_push.data = randomcolorstring() -- color or grey string
- line.head = nodeinsertbefore(line.head,upper,nodecopy(color_push))
- nodeinsertafter(line.head,upper,nodecopy(color_pop))
- end
- end
- end
- end
- return head
-end
-upsidedown = function(head)
- local factor = 65536/0.99626
- for line in nodetraverseid(Hhead,head) do
- for n in nodetraverseid(GLYPH,line.head) do
- if (upsidedownarray[n.char]) then
- shift = nodenew(WHAT,PDF_LITERAL)
- shift2 = nodenew(WHAT,PDF_LITERAL)
- shift.data = "q 1 0 0 -1 0 " .. n.height/factor .." cm"
- shift2.data = "Q 1 0 0 1 " .. n.width/factor .." 0 cm"
- nodeinsertbefore(head,n,shift)
- nodeinsertafter(head,n,shift2)
- end
- end
- end
- return head
-end
-keeptext = true
-colorexpansion = true
-
-colorstretch_coloroffset = 0.5
-colorstretch_colorrange = 0.5
-chickenize_rule_bad_height = 4/5 -- height and depth of the rules
-chickenize_rule_bad_depth = 1/5
-
-colorstretchnumbers = true
-drawstretchthreshold = 0.1
-drawexpansionthreshold = 0.9
-colorstretch = function (head)
- local f = font.getfont(font.current()).characters
- for line in nodetraverseid(Hhead,head) do
- local rule_bad = nodenew(RULE)
-
- if colorexpansion then -- if also the font expansion should be shown
- local g = line.head
- while not(g.id == GLYPH) and (g.next) do g = g.next end -- find first glyph on line. If line is empty, no glyph:
- if (g.id == GLYPH) then -- read width only if g is a glyph!
- exp_factor = g.width / f[g.char].width
- exp_color = colorstretch_coloroffset + (1-exp_factor)*10 .. " g"
- rule_bad.width = 0.5*line.width -- we need two rules on each line!
- end
- else
- rule_bad.width = line.width -- only the space expansion should be shown, only one rule
- end
- rule_bad.height = tex.baselineskip.width*chickenize_rule_bad_height -- this should give a better output
- rule_bad.depth = tex.baselineskip.width*chickenize_rule_bad_depth
-
- local glue_ratio = 0
- if line.glue_order == 0 then
- if line.glue_sign == 1 then
- glue_ratio = colorstretch_colorrange * math.min(line.glue_set,1)
- else
- glue_ratio = -colorstretch_colorrange * math.min(line.glue_set,1)
- end
- end
- color_push.data = colorstretch_coloroffset + glue_ratio .. " g"
-
--- set up output
- local p = line.head
-
- -- a rule to immitate kerning all the way back
- local kern_back = nodenew(RULE)
- kern_back.width = -line.width
-
- -- if the text should still be displayed, the color and box nodes are inserted additionally
- -- and the head is set to the color node
- if keeptext then
- line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push))
- else
- node.flush_list(p)
- line.head = nodecopy(color_push)
- end
- nodeinsertafter(line.head,line.head,rule_bad) -- then the rule
- nodeinsertafter(line.head,line.head.next,nodecopy(color_pop)) -- and then pop!
- tmpnode = nodeinsertafter(line.head,line.head.next.next,kern_back)
-
- -- then a rule with the expansion color
- if colorexpansion then -- if also the stretch/shrink of letters should be shown
- color_push.data = exp_color
- nodeinsertafter(line.head,tmpnode,nodecopy(color_push))
- nodeinsertafter(line.head,tmpnode.next,nodecopy(rule_bad))
- nodeinsertafter(line.head,tmpnode.next.next,nodecopy(color_pop))
- end
- if colorstretchnumbers then
- j = 1
- glue_ratio_output = {}
- for s in string.utfvalues(math.abs(glue_ratio)) do -- using math.abs here gets us rid of the minus sign
- local char = unicode.utf8.char(s)
- glue_ratio_output[j] = nodenew(GLYPH,1)
- glue_ratio_output[j].font = font.current()
- glue_ratio_output[j].char = s
- j = j+1
- end
- if math.abs(glue_ratio) > drawstretchthreshold then
- if glue_ratio < 0 then color_push.data = "0.99 0 0 rg"
- else color_push.data = "0 0.99 0 rg" end
- else color_push.data = "0 0 0 rg"
- end
-
- nodeinsertafter(line.head,node.tail(line.head),nodecopy(color_push))
- for i = 1,math.min(j-1,7) do
- nodeinsertafter(line.head,node.tail(line.head),glue_ratio_output[i])
- end
- nodeinsertafter(line.head,node.tail(line.head),nodecopy(color_pop))
- end -- end of stretch number insertion
- end
- return head
-end
-
-function scorpionize_color(head)
- color_push.data = ".35 .55 .75 rg"
- nodeinsertafter(head,head,nodecopy(color_push))
- nodeinsertafter(head,node.tail(head),nodecopy(color_pop))
- return head
-end
-substlist = {}
-substlist[1488] = 64289
-substlist[1491] = 64290
-substlist[1492] = 64291
-substlist[1499] = 64292
-substlist[1500] = 64293
-substlist[1501] = 64294
-substlist[1512] = 64295
-substlist[1514] = 64296
-function variantjustification(head)
- math.randomseed(1)
- for line in nodetraverseid(nodeid"hhead",head) do
- if (line.glue_sign == 1 and line.glue_order == 0) then -- exclude the last line!
- substitutions_wide = {} -- we store all “expandable” letters of each line
- for n in nodetraverseid(nodeid"glyph",line.head) do
- if (substlist[n.char]) then
- substitutions_wide[#substitutions_wide+1] = n
- end
- end
- line.glue_set = 0 -- deactivate normal glue expansion
- local width = node.dimensions(line.head) -- check the new width of the line
- local goal = line.width
- while (width < goal and #substitutions_wide > 0) do
- x = math.random(#substitutions_wide) -- choose randomly a glyph to be substituted
- oldchar = substitutions_wide[x].char
- substitutions_wide[x].char = substlist[substitutions_wide[x].char] -- substitute by wide letter
- width = node.dimensions(line.head) -- check if the line is too wide
- if width > goal then substitutions_wide[x].char = oldchar break end -- substitute back if the line would be too wide and break out of the loop
- table.remove(substitutions_wide,x) -- if further substitutions have to be done, remove the just substituted node from the list
- end
- end
- end
- return head
-end
-zebracolorarray = {}
-zebracolorarray_bg = {}
-zebracolorarray[1] = "0.1 g"
-zebracolorarray[2] = "0.9 g"
-zebracolorarray_bg[1] = "0.9 g"
-zebracolorarray_bg[2] = "0.1 g"
-function zebranize(head)
- zebracolor = 1
- for line in nodetraverseid(nodeid"hhead",head) do
- if zebracolor == #zebracolorarray then zebracolor = 0 end
- zebracolor = zebracolor + 1
- color_push.data = zebracolorarray[zebracolor]
- line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push))
- for n in nodetraverseid(nodeid"glyph",line.head) do
- if n.next then else
- nodeinsertafter(line.head,n,nodecopy(color_pull))
- end
- end
-
- local rule_zebra = nodenew(RULE)
- rule_zebra.width = line.width
- rule_zebra.height = tex.baselineskip.width*4/5
- rule_zebra.depth = tex.baselineskip.width*1/5
-
- local kern_back = nodenew(RULE)
- kern_back.width = -line.width
-
- color_push.data = zebracolorarray_bg[zebracolor]
- line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_pop))
- line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push))
- nodeinsertafter(line.head,line.head,kern_back)
- nodeinsertafter(line.head,line.head,rule_zebra)
- end
- return (head)
-end
---
-function pdf_print (...)
- for _, str in ipairs({...}) do
- pdf.print(str .. " ")
- end
- pdf.print("\n")
-end
-
-function move (p)
- pdf_print(p[1],p[2],"m")
-end
-
-function line (p)
- pdf_print(p[1],p[2],"l")
-end
-
-function curve(p1,p2,p3)
- pdf_print(p1[1], p1[2],
- p2[1], p2[2],
- p3[1], p3[2], "c")
-end
-
-function close ()
- pdf_print("h")
-end
-
-function linewidth (w)
- pdf_print(w,"w")
-end
-
-function stroke ()
- pdf_print("S")
-end
---
-
-function strictcircle(center,radius)
- local left = {center[1] - radius, center[2]}
- local lefttop = {left[1], left[2] + 1.45*radius}
- local leftbot = {left[1], left[2] - 1.45*radius}
- local right = {center[1] + radius, center[2]}
- local righttop = {right[1], right[2] + 1.45*radius}
- local rightbot = {right[1], right[2] - 1.45*radius}
-
- move (left)
- curve (lefttop, righttop, right)
- curve (rightbot, leftbot, left)
-stroke()
-end
-
-function disturb_point(point)
- return {point[1] + math.random()*5 - 2.5,
- point[2] + math.random()*5 - 2.5}
-end
-
-function sloppycircle(center,radius)
- local left = disturb_point({center[1] - radius, center[2]})
- local lefttop = disturb_point({left[1], left[2] + 1.45*radius})
- local leftbot = {lefttop[1], lefttop[2] - 2.9*radius}
- local right = disturb_point({center[1] + radius, center[2]})
- local righttop = disturb_point({right[1], right[2] + 1.45*radius})
- local rightbot = disturb_point({right[1], right[2] - 1.45*radius})
-
- local right_end = disturb_point(right)
-
- move (right)
- curve (rightbot, leftbot, left)
- curve (lefttop, righttop, right_end)
- linewidth(math.random()+0.5)
- stroke()
-end
-
-function sloppyline(start,stop)
- local start_line = disturb_point(start)
- local stop_line = disturb_point(stop)
- start = disturb_point(start)
- stop = disturb_point(stop)
- move(start) curve(start_line,stop_line,stop)
- linewidth(math.random()+0.5)
- stroke()
-end
---
--- End of File `chickenize.lua'.
diff --git a/macros/luatex/generic/chickenize/chickenize.pdf b/macros/luatex/generic/chickenize/chickenize.pdf
index 2e4c7d9aa4..40fbd75867 100644
--- a/macros/luatex/generic/chickenize/chickenize.pdf
+++ b/macros/luatex/generic/chickenize/chickenize.pdf
Binary files differ
diff --git a/macros/luatex/generic/chickenize/chickenize.sty b/macros/luatex/generic/chickenize/chickenize.sty
deleted file mode 100644
index 82e4b2129a..0000000000
--- a/macros/luatex/generic/chickenize/chickenize.sty
+++ /dev/null
@@ -1,32 +0,0 @@
-%%
-%% This is file `chickenize.sty',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% chickenize.dtx (with options: `package')
-%%
-%% EXPERIMENTAL CODE
-%%
-%% This package is copyright © 2017 Arno L. Trautmann. It 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. This work has the LPPL mainten-
-%% ance status ‘maintained’.
-\ProvidesPackage{chickenize}%
- [2017/08/19 v0.2.5 chickenize package]
-\input{chickenize}
-
-\iffalse
- \DeclareDocumentCommand\includegraphics{O{}m}{
- \fbox{Chicken} %% actually, I'd love to draw an MP graph showing a chicken …
- }
-%%%% specials: the balmerpeak. A tribute to http://xkcd.com/323/.
-%% So far, you have to load pgfplots yourself.
-%% As it is a mighty package, I don't want the user to force loading it.
-\NewDocumentCommand\balmerpeak{G{}O{-4cm}}{
-%% to be done using Lua drawing.
-}
-\fi
-%%
-%%
-%% End of file `chickenize.sty'.
diff --git a/macros/luatex/generic/chickenize/chickenize.tex b/macros/luatex/generic/chickenize/chickenize.tex
deleted file mode 100644
index aa48c98457..0000000000
--- a/macros/luatex/generic/chickenize/chickenize.tex
+++ /dev/null
@@ -1,441 +0,0 @@
-%%
-%% This is file `chickenize.tex',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% chickenize.dtx (with options: `tex')
-%%
-%% EXPERIMENTAL CODE
-%%
-%% This package is copyright © 2017 Arno L. Trautmann. It 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. This work has the LPPL mainten-
-%% ance status ‘maintained’.
-\directlua{dofile(kpse.find_file("chickenize.lua"))}
-
-\def\ALT{%
- \bgroup%
- \fontspec{Latin Modern Sans}%
- A%
- \kern-.4em \raisebox{.65ex}{\scalebox{0.3}{L}}%
- \kern-.0em \raisebox{-0.98ex}{T}%
- \egroup%
-}
-
-\def\allownumberincommands{
- \catcode`\0=11
- \catcode`\1=11
- \catcode`\2=11
- \catcode`\3=11
- \catcode`\4=11
- \catcode`\5=11
- \catcode`\6=11
- \catcode`\7=11
- \catcode`\8=11
- \catcode`\9=11
-}
-
-\def\BEClerize{
- \chickenize
- \directlua{
- chickenstring[1] = "noise noise"
- chickenstring[2] = "atom noise"
- chickenstring[3] = "shot noise"
- chickenstring[4] = "photon noise"
- chickenstring[5] = "camera noise"
- chickenstring[6] = "noising noise"
- chickenstring[7] = "thermal noise"
- chickenstring[8] = "electronic noise"
- chickenstring[9] = "spin noise"
- chickenstring[10] = "electron noise"
- chickenstring[11] = "Bogoliubov noise"
- chickenstring[12] = "white noise"
- chickenstring[13] = "brown noise"
- chickenstring[14] = "pink noise"
- chickenstring[15] = "bloch sphere"
- chickenstring[16] = "atom shot noise"
- chickenstring[17] = "nature physics"
- }
-}
-
-\def\boustrophedon{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",boustrophedon,"boustrophedon")}}
-\def\unboustrophedon{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","boustrophedon")}}
-
-\def\boustrophedonglyphs{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",boustrophedon_glyphs,"boustrophedon_glyphs")}}
-\def\unboustrophedonglyphs{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","boustrophedon_glyphs")}}
-
-\def\boustrophedoninverse{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",boustrophedon_inverse,"boustrophedon_inverse")}}
-\def\unboustrophedoninverse{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","boustrophedon_inverse")}}
-
-\def\bubblesort{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",bubblesort,"bubblesort")}}
-\def\unbubblesort{
- \directlua{luatexbase.remove_from_callback("bubblesort","bubblesort")}}
-
-\def\chickenize{
- \directlua{luatexbase.add_to_callback("pre_linebreak_filter",chickenize,"chickenize")
- luatexbase.add_to_callback("start_page_number",
- function() texio.write("["..status.total_pages) end ,"cstartpage")
- luatexbase.add_to_callback("stop_page_number",
- function() texio.write(" chickens]") end,"cstoppage")
- luatexbase.add_to_callback("stop_run",nicetext,"a nice text")
- }
-}
-\def\unchickenize{
- \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","chickenize")
- luatexbase.remove_from_callback("start_page_number","cstartpage")
- luatexbase.remove_from_callback("stop_page_number","cstoppage")}}
-
-\def\coffeestainize{ %% to be implemented.
- \directlua{}}
-\def\uncoffeestainize{
- \directlua{}}
-
-\def\colorstretch{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",colorstretch,"stretch_expansion")}}
-\def\uncolorstretch{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","stretch_expansion")}}
-
-\def\countglyphs{
- \directlua{
- counted_glyphs_by_code = {}
- for i = 1,10000 do
- counted_glyphs_by_code[i] = 0
- end
- glyphnumber = 0 spacenumber = 0
- luatexbase.add_to_callback("post_linebreak_filter",countglyphs,"countglyphs")
- luatexbase.add_to_callback("stop_run",printglyphnumber,"printglyphnumber")
- }
-}
-
-\def\countwords{
- \directlua{wordnumber = 0
- luatexbase.add_to_callback("pre_linebreak_filter",countwords,"countwords")
- luatexbase.add_to_callback("stop_run",printwordnumber,"printwordnumber")
- }
-}
-
-\def\detectdoublewords{
- \directlua{
- luatexbase.add_to_callback("post_linebreak_filter",detectdoublewords,"detectdoublewords")
- luatexbase.add_to_callback("stop_run",printdoublewords,"printdoublewords")
- }
-}
-
-\def\dosomethingfunny{
- %% should execute one of the “funny” commands, but randomly. So every compilation is completely different. Maybe a list of commands could be specified to exclude total nonesense-functions. Maybe also on a per-paragraph-basis?
-}
-
-\def\dubstepenize{
- \chickenize
- \directlua{
- chickenstring[1] = "WOB"
- chickenstring[2] = "WOB"
- chickenstring[3] = "WOB"
- chickenstring[4] = "BROOOAR"
- chickenstring[5] = "WHEE"
- chickenstring[6] = "WOB WOB WOB"
- chickenstring[7] = "WAAAAAAAAH"
- chickenstring[8] = "duhduh duhduh duh"
- chickenstring[9] = "BEEEEEEEEEW"
- chickenstring[10] = "DDEEEEEEEW"
- chickenstring[11] = "EEEEEW"
- chickenstring[12] = "boop"
- chickenstring[13] = "buhdee"
- chickenstring[14] = "bee bee"
- chickenstring[15] = "BZZZRRRRRRROOOOOOAAAAA"
-
- chickenizefraction = 1
- }
-}
-\let\dubstepize\dubstepenize
-
-\def\explainbackslashes{ %% inspired by xkcd #1638
- {\tt\noindent
-\textbackslash escape character\\
-\textbackslash\textbackslash line end or escaped escape character in tex.print("")\\
-\textbackslash\textbackslash\textbackslash real, real backslash\\
-\textbackslash\textbackslash\textbackslash\textbackslash line end in tex.print("")\\
-\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash elder backslash \\
-\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash backslash which escapes the screen and enters your brain\\
-\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash backslash so real it transcends time and space \\
-\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash backslash to end all other text\\
-\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash\textbackslash... the true name of Ba'al, the soul-eater}
-}
-
-\def\gameoflife{
- Your Life Is Tetris. Stop Playing It Like Chess.
-}
-
-\def\guttenbergenize{ %% makes only sense when using LaTeX
- \AtBeginDocument{
- \let\grqq\relax\let\glqq\relax
- \let\frqq\relax\let\flqq\relax
- \let\grq\relax\let\glq\relax
- \let\frq\relax\let\flq\relax
- \gdef\footnote##1{}
- \gdef\cite##1{}\gdef\parencite##1{}
- \gdef\Cite##1{}\gdef\Parencite##1{}
- \gdef\cites##1{}\gdef\parencites##1{}
- \gdef\Cites##1{}\gdef\Parencites##1{}
- \gdef\footcite##1{}\gdef\footcitetext##1{}
- \gdef\footcites##1{}\gdef\footcitetexts##1{}
- \gdef\textcite##1{}\gdef\Textcite##1{}
- \gdef\textcites##1{}\gdef\Textcites##1{}
- \gdef\smartcites##1{}\gdef\Smartcites##1{}
- \gdef\supercite##1{}\gdef\supercites##1{}
- \gdef\autocite##1{}\gdef\Autocite##1{}
- \gdef\autocites##1{}\gdef\Autocites##1{}
- %% many, many missing … maybe we need to tackle the underlying mechanism?
- }
- \directlua{luatexbase.add_to_callback("pre_linebreak_filter",guttenbergenize_rq,"guttenbergenize_rq")}
-}
-
-\def\hammertime{
- \global\let\n\relax
- \directlua{hammerfirst = true
- luatexbase.add_to_callback("pre_linebreak_filter",hammertime,"hammertime")}}
-\def\unhammertime{
- \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","hammertime")}}
-
-\let\hendlnize\chickenize % homage to Hendl/Chicken
-\let\unhendlnize\unchickenize % may the soldering strength always be with him
-
-
-\def\kernmanipulate{
- \directlua{luatexbase.add_to_callback("pre_linebreak_filter",kernmanipulate,"kernmanipulate")}}
-\def\unkernmanipulate{
- \directlua{lutaexbase.remove_from_callback("pre_linebreak_filter",kernmanipulate)}}
-
-\def\leetspeak{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",leet,"1337")}}
-\def\unleetspeak{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","1337")}}
-
-\def\leftsideright#1{
- \directlua{luatexbase.add_to_callback("pre_linebreak_filter",leftsideright,"leftsideright")}
- \directlua{
- leftsiderightindex = {#1}
- leftsiderightarray = {}
- for _,i in pairs(leftsiderightindex) do
- leftsiderightarray[i] = true
- end
- }
-}
-\def\unleftsideright{
- \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","leftsideright")}}
-
-\def\letterspaceadjust{
- \directlua{luatexbase.add_to_callback("pre_linebreak_filter",letterspaceadjust,"letterspaceadjust")}}
-\def\unletterspaceadjust{
- \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","letterspaceadjust")}}
-
-\def\listallcommands{
- \directlua{
- for name in pairs(tex.hashtokens()) do
- print(name)
- end}
-}
-
-\let\stealsheep\letterspaceadjust %% synonym in honor of Paul
-\let\unstealsheep\unletterspaceadjust
-\let\returnsheep\unletterspaceadjust
-
-\def\matrixize{
- \directlua{luatexbase.add_to_callback("pre_linebreak_filter",matrixize,"matrixize")}}
-\def\unmatrixize{
- \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","matrixize")}}
-
-\def\milkcow{ %% FIXME %% to be implemented
- \directlua{}}
-\def\unmilkcow{
- \directlua{}}
-
-\def\medievalumlaut{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",medievalumlaut,"medievalumlaut")}}
-\def\unmedievalumlaut{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","medievalumlaut")}}
-
-\def\pancakenize{
- \directlua{luatexbase.add_to_callback("stop_run",pancaketext,"pancaketext")}}
-
-\def\rainbowcolor{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomcolor,"rainbowcolor")
- rainbowcolor = true}}
-\def\unrainbowcolor{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","rainbowcolor")
- rainbowcolor = false}}
-\let\nyanize\rainbowcolor
-\let\unnyanize\unrainbowcolor
-
-\def\randomchars{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomchars,"randomchars")}}
-\def\unrandomchars{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","randomchars")}}
-
-\def\randomcolor{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomcolor,"randomcolor")}}
-\def\unrandomcolor{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","randomcolor")}}
-
-\def\randomerror{ %% FIXME
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomerror,"randomerror")}}
-\def\unrandomerror{ %% FIXME
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","randomerror")}}
-
-\def\randomfonts{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomfonts,"randomfonts")}}
-\def\unrandomfonts{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","randomfonts")}}
-
-\def\randomuclc{
- \directlua{luatexbase.add_to_callback("pre_linebreak_filter",randomuclc,"randomuclc")}}
-\def\unrandomuclc{
- \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","randomuclc")}}
-
-\let\rongorongonize\boustrophedoninverse
-\let\unrongorongonize\unboustrophedoninverse
-
-\def\scorpionize{
- \directlua{luatexbase.add_to_callback("pre_linebreak_filter",scorpionize_color,"scorpionize_color")}}
-\def\unscorpionize{
- \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","scorpionize_color")}}
-
-\def\spankmonkey{ %% to be implemented
- \directlua{}}
-\def\unspankmonkey{
- \directlua{}}
-
-\def\substitutewords{
- \directlua{luatexbase.add_to_callback("process_input_buffer",substitutewords,"substitutewords")}}
-\def\unsubstitutewords{
- \directlua{luatexbase.remove_from_callback("process_input_buffer","substitutewords")}}
-
-\def\addtosubstitutions#1#2{
- \directlua{addtosubstitutions("#1","#2")}
-}
-
-\def\suppressonecharbreak{
- \directlua{luatexbase.add_to_callback("pre_linebreak_filter",suppressonecharbreak,"suppressonecharbreak")}}
-\def\unsuppressonecharbreak{
- \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","suppressonecharbreak")}}
-
-\def\tabularasa{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",tabularasa,"tabularasa")}}
-\def\untabularasa{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","tabularasa")}}
-
-\def\tanjanize{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",tanjanize,"tanjanize")}}
-\def\untanjanize{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","tanjanize")}}
-
-\def\uppercasecolor{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",uppercasecolor,"uppercasecolor")}}
-\def\unuppercasecolor{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","uppercasecolor")}}
-
-\def\upsidedown#1{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",upsidedown,"upsidedown")}
- \directlua{
- upsidedownindex = {#1}
- upsidedownarray = {}
- for _,i in pairs(upsidedownindex) do
- upsidedownarray[i] = true
- end
- }
-}
-\def\unupsidedown{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","upsidedown")}}
-
-\def\variantjustification{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",variantjustification,"variantjustification")}}
-\def\unvariantjustification{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","variantjustification")}}
-
-\def\zebranize{
- \directlua{luatexbase.add_to_callback("post_linebreak_filter",zebranize,"zebranize")}}
-\def\unzebranize{
- \directlua{luatexbase.remove_from_callback("post_linebreak_filter","zebranize")}}
-\newattribute\leetattr
-\newattribute\letterspaceadjustattr
-\newattribute\randcolorattr
-\newattribute\randfontsattr
-\newattribute\randuclcattr
-\newattribute\tabularasaattr
-\newattribute\uppercasecolorattr
-
-\long\def\textleetspeak#1%
- {\setluatexattribute\leetattr{42}#1\unsetluatexattribute\leetattr}
-
-\long\def\textletterspaceadjust#1{
- \setluatexattribute\letterspaceadjustattr{42}#1\unsetluatexattribute\letterspaceadjustattr
- \directlua{
- if (textletterspaceadjustactive) then else % -- if already active, do nothing
- luatexbase.add_to_callback("pre_linebreak_filter",textletterspaceadjust,"textletterspaceadjust")
- end
- textletterspaceadjustactive = true % -- set to active
- }
-}
-\let\textlsa\textletterspaceadjust
-
-\long\def\textrandomcolor#1%
- {\setluatexattribute\randcolorattr{42}#1\unsetluatexattribute\randcolorattr}
-\long\def\textrandomfonts#1%
- {\setluatexattribute\randfontsattr{42}#1\unsetluatexattribute\randfontsattr}
-\long\def\textrandomfonts#1%
- {\setluatexattribute\randfontsattr{42}#1\unsetluatexattribute\randfontsattr}
-\long\def\textrandomuclc#1%
- {\setluatexattribute\randuclcattr{42}#1\unsetluatexattribute\randuclcattr}
-\long\def\texttabularasa#1%
- {\setluatexattribute\tabularasaattr{42}#1\unsetluatexattribute\tabularasaattr}
-\long\def\textuppercasecolor#1%
- {\setluatexattribute\uppercasecolorattr{42}#1\unsetluatexattribute\uppercasecolorattr}
-\def\chickenizesetup#1{\directlua{#1}}
-\long\def\luadraw#1#2{%
- \vbox to #1bp{%
- \vfil
- \latelua{pdf_print("q") #2 pdf_print("Q")}%
- }%
-}
-\long\def\drawchicken{
- \luadraw{90}{
- chickenhead = {200,50} % chicken head center
- chickenhead_rad = 20
-
- neckstart = {215,35} % neck
- neckstop = {230,10} %
-
- chickenbody = {260,-10}
- chickenbody_rad = 40
- chickenleg = {
- {{260,-50},{250,-70},{235,-70}},
- {{270,-50},{260,-75},{245,-75}}
- }
-
- beak_top = {185,55}
- beak_front = {165,45}
- beak_bottom = {185,35}
-
- wing_front = {260,-10}
- wing_bottom = {280,-40}
- wing_back = {275,-15}
-
- sloppycircle(chickenhead,chickenhead_rad) sloppyline(neckstart,neckstop)
- sloppycircle(chickenbody,chickenbody_rad)
- sloppyline(chickenleg[1][1],chickenleg[1][2]) sloppyline(chickenleg[1][2],chickenleg[1][3])
- sloppyline(chickenleg[2][1],chickenleg[2][2]) sloppyline(chickenleg[2][2],chickenleg[2][3])
- sloppyline(beak_front,beak_top) sloppyline(beak_front,beak_bottom)
- sloppyline(wing_front,wing_bottom) sloppyline(wing_back,wing_bottom)
- }
-}
-%%
-%%
-%% End of file `chickenize.tex'.
diff --git a/macros/luatex/generic/luatexja/README b/macros/luatex/generic/luatexja/README
index 3a23ede8a4..e6c21ab100 100644
--- a/macros/luatex/generic/luatexja/README
+++ b/macros/luatex/generic/luatexja/README
@@ -1,6 +1,6 @@
-The LuaTeX-ja Package 20201224.0
+The LuaTeX-ja Package 20210103.0
--------------------------------
-Copyright (c) 2011--2020 The LuaTeX-ja project
+Copyright (c) 2011--2021 The LuaTeX-ja project
License: modified BSD (see COPYING)
LuaTeX-ja is a macro package for typesetting Japanese documents with LuaTeX.
@@ -45,9 +45,9 @@ Installation
2. If you must/want to install manually:
a. Download the source archive from CTAN,
- or tagged as 20201224.0 in the Git repository by
+ or tagged as 20210103.0 in the Git repository by
<http://git.osdn.jp/view?p=luatex-ja/luatexja.git
- ;a=snapshot;h=refs/tags/20201224.0;sf=tgz>
+ ;a=snapshot;h=refs/tags/20210103.0;sf=tgz>
b. Extract the archive and process following three files by LuaLaTeX
to generate classes for Japanese typesetting:
@@ -96,4 +96,4 @@ Notes
This file and ltj-kinsoku.lua are not used anymore.
(Do not remove ltj-kinsoku.tex.)
-Last commit date: Thu Dec 24 05:08:02 2020 +0900
+Last commit date: Sun Jan 3 09:48:34 2021 +0900
diff --git a/macros/luatex/generic/luatexja/doc/luatexja-en.pdf b/macros/luatex/generic/luatexja/doc/luatexja-en.pdf
index 7c0497cdbe..41fd1bd246 100644
--- a/macros/luatex/generic/luatexja/doc/luatexja-en.pdf
+++ b/macros/luatex/generic/luatexja/doc/luatexja-en.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/luatexja-ja.pdf b/macros/luatex/generic/luatexja/doc/luatexja-ja.pdf
index b06dc04aff..ea0025d79d 100644
--- a/macros/luatex/generic/luatexja/doc/luatexja-ja.pdf
+++ b/macros/luatex/generic/luatexja/doc/luatexja-ja.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/luatexja-ruby.pdf b/macros/luatex/generic/luatexja/doc/luatexja-ruby.pdf
index 5365af4335..31dc6d4270 100644
--- a/macros/luatex/generic/luatexja/doc/luatexja-ruby.pdf
+++ b/macros/luatex/generic/luatexja/doc/luatexja-ruby.pdf
Binary files differ
diff --git a/macros/luatex/generic/luatexja/doc/luatexja-ruby.tex b/macros/luatex/generic/luatexja/doc/luatexja-ruby.tex
index 7d5226e47c..08bb579204 100644
--- a/macros/luatex/generic/luatexja/doc/luatexja-ruby.tex
+++ b/macros/luatex/generic/luatexja/doc/luatexja-ruby.tex
@@ -221,7 +221,6 @@ plain \LuaTeX でのロードはまだサポートしておらず,
\end{lstlisting}
のようにしてルビ用字形を用いることが可能だが,現在の実装ではタイプセットに時間がかかるようになる.
-
\end{description}
\medskip
@@ -325,8 +324,13 @@ mode=9, stretch={1}{2}{1}, stretchruby={0}{0}{1}
の\ltjruby{紋}{もん}\ltjruby{章}{しよう}が
\end{LTXexample}
のように,複数回使用すること.
-また,全てのグループにおいて「ルビ文字列の長さは親文字列以下」であれば,
-単純グループルビの並びとして扱われる.すなわち,次の2行は全くの等価となる.
+また,全てのグループにおいて「ルビ文字列の長さは親文字列以下」
+\footnote{%
+ 実際には\TeX での長さの計算誤差($2^{-16}$~ptの整数倍として計算していることによる)を考慮し,
+ 親文字全角の$1/1000$だけルビ文字列が長くなることを許容している.
+}であれば,
+単純グループルビの並びとして扱われる.すなわち,次ページ冒頭の2行は全くの等価となる.
+\newpage
\begin{verbatim}
\ltjruby{普|通|車}{ふ|つう|しや}
\ltjruby{普}{ふ}\ltjruby{通}{つう}\ltjruby{車}{しや}
@@ -378,7 +382,6 @@ mode=9, stretch={1}{2}{1}, stretchruby={0}{0}{1}
\paragraph{前後からのルビ文字のはみ出し1}
「日本語組版処理の要件」の図117\footnote{2020-08-11版での番号.2012-04-03版では図3.82.}のように,
前後からのルビ文字のはみ出しが繋がらないようにする処理が組み込まれている.
-
例えば,
\begin{LTXexample}[preset=\Large,width=0.3\textwidth]
\ltjruby{陵}{りよう}と\ltjruby{陵}{みささぎ}\\
diff --git a/macros/luatex/generic/luatexja/src/addons/luatexja-ruby.sty b/macros/luatex/generic/luatexja/src/addons/luatexja-ruby.sty
index 90dfece2b9..0dacf32bf8 100644
--- a/macros/luatex/generic/luatexja/src/addons/luatexja-ruby.sty
+++ b/macros/luatex/generic/luatexja/src/addons/luatexja-ruby.sty
@@ -4,7 +4,7 @@
% LaTeX only!
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{luatexja-ruby}[2020-12-24 v0.5]
+\ProvidesPackage{luatexja-ruby}[2020-12-25 v0.51]
\RequirePackage{luatexja}
%%------------------
@@ -63,6 +63,10 @@
%% attr は sp 単位だが,ユーザーは親文字全角単位で指定
\ltj@@rkeydef{intergap}
+%% epsilon: モノルビ * n にする際に,ルビの方がどれだけ親文字より長い
+%% 状況を許容するか.親文字全角単位.計算誤差を想定.
+\ltj@@rkeydef{epsilon}
+
\ltj@@rkeydef{kenten}%% 圏点文字
\ltj@@rkeydef{fontcmd}%% フォント
\define@boolkey[ltj]{ruby}{rubysmash}[true]{}
@@ -98,6 +102,7 @@
\catcode`\_=11
\gdef\ltj@@ruby@create@table#1{% #1: ルビ全角
\string{
+ eps = \ltj@safe@dimen{\ltj@@rubyip@epsilon\zw},
before_jfmgk = 0, after_jfmgk = 0,
rubyzw = \ltj@safe@dimen{#1},
maxmargin = \ltj@safe@dimen{\ltj@@rubyip@maxmargin\zw},
@@ -244,7 +249,8 @@
stretchbol={0}{1}{1}, stretcheol={1}{1}{0},
maxmargin=0.5, size=0.5, intergap=0, rubysmash=false,
kenten=\textbullet, fontcmd=\relax, ybaseheight=0.88, tbaseheight=0.5,
- intrude_jfmgk, intrude_kanjiskip, intrude_xkanjiskip
+ intrude_jfmgk, intrude_kanjiskip, intrude_xkanjiskip,
+ epsilon=0.0001,
}
\endinput
diff --git a/macros/luatex/generic/luatexja/src/ltj-latex.sty b/macros/luatex/generic/luatexja/src/ltj-latex.sty
index 506adea2e7..213f2f7109 100644
--- a/macros/luatex/generic/luatexja/src/ltj-latex.sty
+++ b/macros/luatex/generic/luatexja/src/ltj-latex.sty
@@ -12,7 +12,7 @@
\def\luatexjalatexLoaded{\endinput}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{ltj-latex}[2020-10-09 LaTeX support of LuaTeX-ja]
+\ProvidesPackage{ltj-latex}[2020-12-29 LaTeX support of LuaTeX-ja]
% cleanup at end of the document
%\let\ltj@@orig@end=\@@end
@@ -27,8 +27,12 @@
\fi
\newif\ifltj@ltfilehook@avail
\@ifl@t@r\fmtversion{2020-10-01}{%
- \ifnum\patch@level<0\relax \ifnum\patch@level<-6 \ltj@ltfilehook@availtrue\fi
- \else\ltj@ltfilehook@availtrue\fi
+ \@ifl@t@r\fmtversion{2020-10-02}%
+ {\ltj@ltfilehook@availtrue}
+ {%
+ \ifnum\patch@level<0\relax \ifnum\patch@level<-6 \ltj@ltfilehook@availtrue\fi
+ \else\ltj@ltfilehook@availtrue\fi
+ }%
}{}
%%% patch for LaTeX
diff --git a/macros/luatex/generic/luatexja/src/ltj-otf.lua b/macros/luatex/generic/luatexja/src/ltj-otf.lua
index 42792769d7..770749f9ea 100644
--- a/macros/luatex/generic/luatexja/src/ltj-otf.lua
+++ b/macros/luatex/generic/luatexja/src/ltj-otf.lua
@@ -1,7 +1,6 @@
--
-- ltj-otf.lua
--
-require 'unicode'
require 'lualibs'
luatexja.load_module 'base'; local ltjb = luatexja.base
@@ -120,9 +119,9 @@ local function append_jglyph(char)
setfield(p, 'value', char); node_write(p)
end
-local utf
+local myutf
do
- utf = function (ucs)
+ myutf = function (ucs)
if ltjd_get_dir_count()==dir_tate then
ucs = ltju.replace_vert_variant(
tex_get_attr((ltjd_get_dir_count()==dir_tate) and attr_curtfnt or attr_curjfnt),
@@ -235,7 +234,7 @@ local disable_ivs = enable_ivs
luatexja.otf = {
append_jglyph = append_jglyph,
enable_ivs = enable_ivs, disable_ivs = disable_ivs,
- cid = cid, utf = utf,
+ cid = cid, utf = myutf,
}
diff --git a/macros/luatex/generic/luatexja/src/ltj-ruby.lua b/macros/luatex/generic/luatexja/src/ltj-ruby.lua
index 34cdc8c7fc..9824ff155a 100644
--- a/macros/luatex/generic/luatexja/src/ltj-ruby.lua
+++ b/macros/luatex/generic/luatexja/src/ltj-ruby.lua
@@ -278,9 +278,9 @@ function luatexja.ruby.texiface(rst, rtlr, rtlp)
'the body (' .. #rtlr .. ' != ' .. #rtlp .. ').',
'')
else
- local f = true
+ local f, eps = true, rst.eps
for i = 1,#rtlr do
- if getfield(rtlr[i], 'width') > getfield(rtlp[i], 'width') then
+ if getfield(rtlr[i], 'width') > getfield(rtlp[i], 'width') + eps then
f = false; break
end
end
diff --git a/macros/luatex/generic/luatexja/src/luatexja-core.sty b/macros/luatex/generic/luatexja/src/luatexja-core.sty
index 3ad5657432..e1baefbf19 100644
--- a/macros/luatex/generic/luatexja/src/luatexja-core.sty
+++ b/macros/luatex/generic/luatexja/src/luatexja-core.sty
@@ -65,7 +65,7 @@
\expandafter\let\csname ifltj@in@latex\expandafter\endcsname
\csname iftrue\endcsname
\NeedsTeXFormat{LaTeX2e}
- \ProvidesPackage{luatexja-core}[2020-12-22 Core of LuaTeX-ja]
+ \ProvidesPackage{luatexja-core}[2021-01-02 Core of LuaTeX-ja]
\fi %</LaTeX>
%% Load prerequisite packages.
@@ -526,9 +526,9 @@
\csname ltj@kcat5\endcsname="7FFFFFFF %"
\csname ltj@kcat6\endcsname="7FFFFFFF }%"
-\protected\def\ltjjachar{\afterassignment\ltj@@jachar\ltj@tempcnta}
+\protected\def\ltjjachar{\leavevmode\afterassignment\ltj@@jachar\ltj@tempcnta}
\def\ltj@@jachar{{\directlua{tex.globaldefs=0}\ltj@alljachar\ltj@@origchar\ltj@tempcnta}}
-\protected\def\ltjalchar{\afterassignment\ltj@@alchar\ltj@tempcnta}
+\protected\def\ltjalchar{\leavevmode\afterassignment\ltj@@alchar\ltj@tempcnta}
\def\ltj@@alchar{{\directlua{tex.globaldefs=0}\ltj@allalchar\ltj@@origchar\ltj@tempcnta}}
%%%%%%%% \ltjsetmathletter<number>, \ltjunsetmathletter<number>
diff --git a/macros/luatex/generic/luatexja/src/luatexja.sty b/macros/luatex/generic/luatexja/src/luatexja.sty
index 4d749c40ef..3448634592 100644
--- a/macros/luatex/generic/luatexja/src/luatexja.sty
+++ b/macros/luatex/generic/luatexja/src/luatexja.sty
@@ -35,13 +35,13 @@
\expandafter\let\csname ifltj@in@latex\expandafter\endcsname
\csname iftrue\endcsname
\NeedsTeXFormat{LaTeX2e}
- \ProvidesPackage{luatexja}[2020-12-24 Japanese Typesetting with Lua(La)TeX]
+ \ProvidesPackage{luatexja}[2021-01-03 Japanese Typesetting with Lua(La)TeX]
\DeclareOption{disablejfam}{\ltj@disablejfamtrue}
\DeclareOption*{}
\ProcessOptions\relax
\fi %</LaTeX>
%%%% VERSION
-\def\LuaTeXjaversion{20201224.0}
+\def\LuaTeXjaversion{20210103.0}
\directlua{require('ltj-unicode-ccfix.lua')}% catcode of ideographs
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjfont.sty b/macros/luatex/generic/luatexja/src/patches/lltjfont.sty
index bad7e6c7bc..287a3968f5 100644
--- a/macros/luatex/generic/luatexja/src/patches/lltjfont.sty
+++ b/macros/luatex/generic/luatexja/src/patches/lltjfont.sty
@@ -3,7 +3,7 @@
%
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{lltjfont}[2020-10-05 Patch to NFSS2 for LuaTeX-ja]
+\ProvidesPackage{lltjfont}[2020-12-29 Patch to NFSS2 for LuaTeX-ja]
%% patching \DeclareTextComposite
\def\ltj@chardef@text@cmd#1{%
@@ -634,7 +634,8 @@
\newcount\ltj@@latex@plv \ltj@@latex@plv=-1
\ifltj@ltfilehook@avail % 2020-10-01
- \ltj@@latex@plv=1000
+ \@ifl@t@r\fmtversion{2020-10-02}{\ltj@@latex@plv=1300}%
+ {\ifnum\patch@level>2 \ltj@@latex@plv=1300\else \ltj@@latex@plv=1000\fi}
\else\ifdefined\@rmfamilyhook % 2020-02-02
\ifx\@forced@seriestrue\@undefined % 2020-02-02 pl0--2
\@latex@error
@@ -768,12 +769,25 @@
\DeclareRobustCommand\romanshapeforce[1]{\edef\f@shape{#1}}
\DeclareRobustCommand\kanjishapeforce[1]{\edef\k@shape{#1}}
\DeclareRobustCommand\fontshapeforce[1]{\set@safe@kanji@shape{#1}{}\romanshapeforce{#1}}
+\ifnum\ltj@@latex@plv>1000
+%%%% LaTeX >= 2020-10-01 PL3
+\DeclareRobustCommand\usekanji[4]{%
+ \kanjiencoding{#1}\edef\k@family{#2}%
+ \set@target@series@kanji{#3}\edef\k@shape{#4}%
+ \selectfont\ignorespaces}
+\DeclareRobustCommand\useroman[4]{%
+ \romanencoding{#1}\edef\f@family{#2}%
+ \set@target@series{#3}\edef\f@shape{#4}%
+ \selectfont\ignorespaces}
+\else
+%%%% 2020-10-01 <= LaTeX < 2020-10-01 PL3
\DeclareRobustCommand\usekanji[4]{%
\kanjiencoding{#1}\edef\k@family{#2}\edef\k@series{#3}\edef\k@shape{#4}%
\selectfont\ignorespaces}
\DeclareRobustCommand\useroman[4]{%
\romanencoding{#1}\edef\f@family{#2}\edef\f@series{#3}\edef\f@shape{#4}%
\selectfont\ignorespaces}
+\fi
%%%% LaTeX >= 2020-02-02 END
\else
%%%% LaTeX 2019-10-01
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty
index 161029bd05..0be092eaaa 100644
--- a/macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-geometry.sty
@@ -3,7 +3,7 @@
%
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{lltjp-geometry}[2020-09-18 Patch to geometry for LuaTeX-ja with vertical writing mode]
+\ProvidesPackage{lltjp-geometry}[2020-12-29 Patch to geometry for LuaTeX-ja with vertical writing mode]
\RequirePackage{expl3}
\ifdefined\if@ltj@@geometry@tate\expandafter\endinput\fi
\newif\if@ltj@@geometry@tate
@@ -33,8 +33,11 @@
\unless\ifdefined\ltj@ExecuteAfterPackage
\expandafter\newif\csname ifltj@ltfilehook@avail\endcsname
\@ifl@t@r\fmtversion{2020-10-01}{%
- \ifnum\patch@level<0\relax \ifnum\patch@level<-6 \ltj@ltfilehook@availtrue\fi
- \else\ltj@ltfilehook@availtrue\fi
+ \@ifl@t@r\fmtversion{2020-10-02}{\ltj@ltfilehook@availtrue}
+ {%
+ \ifnum\patch@level<0\relax \ifnum\patch@level<-6 \ltj@ltfilehook@availtrue\fi
+ \else\ltj@ltfilehook@availtrue\fi
+ }%
}{}
\ifltj@ltfilehook@avail
\def\@@ltj@ExecuteAfterPackage#1{\AddToHook{package/after/#1}}
diff --git a/macros/luatex/generic/luatexja/src/patches/lltjp-listings.sty b/macros/luatex/generic/luatexja/src/patches/lltjp-listings.sty
index ee3c3aa14b..173b1ed94b 100644
--- a/macros/luatex/generic/luatexja/src/patches/lltjp-listings.sty
+++ b/macros/luatex/generic/luatexja/src/patches/lltjp-listings.sty
@@ -43,7 +43,7 @@
\directlua{
local cat_str = luatexbase.catcodetables['string']
local cat_lp = luatexbase.catcodetables['latex-package']
- local ubyte = unicode.utf8.byte
+ local ubyte = utf.byte
local spccmd = string.char(0x5C) .. 'ltj@lst@hss@normal'
luatexja.listings = {}
function luatexja.listings.althss(t)
@@ -229,7 +229,7 @@
}}
\directlua{
- local utfchar, getcount = unicode.utf8.char, tex.getcount
+ local utfchar, getcount = utf.char, tex.getcount
luatexja.listings.insert_cb = function()
if not luatexja.listings.patched then
luatexja.listings.patched = 1
diff --git a/macros/luatex/generic/luatexja/tool/jfm-convert.lua b/macros/luatex/generic/luatexja/tool/jfm-convert.lua
index 66b73a02cd..5f2baa8d8e 100755
--- a/macros/luatex/generic/luatexja/tool/jfm-convert.lua
+++ b/macros/luatex/generic/luatexja/tool/jfm-convert.lua
@@ -3,7 +3,7 @@
local stderr = io.stderr
local function show_usage(s)
stderr:write('Error: ' .. s .. '\n');
- stderr:write('Usage: jfm-convert [-J|-U] <ptex_jfm>\n');
+ stderr:write('Usage: texlua jfm-convert [-J|-U] <ptex_jfm>\n');
stderr:write('-J: JIS mode, -U: UCS mode \n');
stderr:write(' * The output will be written to stdout.\n');
stderr:write(' * I do not read virtual fonts which corresponded to <ptex_jfm>.\n');
@@ -13,20 +13,21 @@ local function show_usage(s)
os.exit(1)
end
-require('unicode'); local uchar = unicode.utf8.char
kpse.set_program_name('luatex')
+require('lualibs'); local uchar = utf.char
jisx0208 = require('ltj-jisx0208.lua').table_jisx0208_uptex
local function pass_ucs(s)
return "'" .. uchar(s) .. "'"
end
local function jis_to_ucs(s)
- local a = jisx0208[s-0x2020]
+ local i = s - 0x2020
+ local a = jisx0208[math.floor(i/256)*94+(i%256)-94] or 0
return a and pass_ucs(a) or string.format('0x%X',s+0x200000)
end
-------- 引数解釈 --------
-require('unicode')
+
local filename
local mode
@@ -207,7 +208,8 @@ jfm_ptex:close()
if not mode then
mode = jis_to_ucs
for i=1, #all_ctype do
- if not jisx0208[all_ctype[i]-0x2020] then
+ local i = all_ctype[i]-0x2020
+ if not jisx0208[math.floor(i/256)*94+(i%256)-94] then
mode = pass_ucs; break
end
end