diff options
author | Karl Berry <karl@freefriends.org> | 2022-01-17 20:58:06 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2022-01-17 20:58:06 +0000 |
commit | ff3d8cdee7284dec8be1092a253ba6bca6f2a93b (patch) | |
tree | 18fc35d8308e8f428123df84af74d8f05911b2bd /Master/texmf-dist/tex/latex | |
parent | e4d6bacce38f34441ff02a9509c5c90c0c620ff8 (diff) |
kanbun (17jan22)
git-svn-id: svn://tug.org/texlive/trunk@61636 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex')
-rw-r--r-- | Master/texmf-dist/tex/latex/kanbun/kanbun.sty | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/kanbun/kanbun.sty b/Master/texmf-dist/tex/latex/kanbun/kanbun.sty new file mode 100644 index 00000000000..70994ab463f --- /dev/null +++ b/Master/texmf-dist/tex/latex/kanbun/kanbun.sty @@ -0,0 +1,317 @@ +%% Copyright 2022 Yuanhao Chen +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Yuanhao Chen. +% +% This work consists of the files kanbun.sty, kanbun.lua, +% kanbun-example.tex and kanbun.tex. +% +\NeedsTeXFormat{LaTeX2e}[2021/06/01] +\RequirePackage{expl3,xparse,l3keys2e,ifluatex} +\ProvidesExplClass{kanbun} + {2022/01/15} {1.0} {漢文の訓点文の組版} + +\ExplSyntaxOn +\cs_generate_variant:Nn \str_if_eq:nnTF { V } +\cs_generate_variant:Nn \str_case:nnTF { V } + +% vars used in options +\tl_set:Nn \kanbun_scale { 2 } +\newlength\kanbun_init_zw +\setlength\kanbun_init_zw{1em} +\@ifpackageloaded{luatexja-fontspec}{ + \tl_set:Nn \kanbun_rubyfontcmd_default { \addjfontfeatures{RawFeature={+ruby}} } + \tl_set:Nn \kanbun_fontcmd_default { \addjfontfeatures{RawFeature={+trad}} } +}{ + \tl_set:Nn \kanbun_rubyfontcmd_default {} + \tl_set:Nn \kanbun_fontcmd_default {} +} + +% options +\keys_define:nn { kanbun } + { + , scale .tl_set:N = \kanbun_scale + , scale .initial:n = { 2 } + , fontcmd .tl_set:N = \kanbun_fontcmd + , fontcmd .initial:n = \kanbun_fontcmd_default + , rubyfontcmd .tl_set:N = \kanbun_rubyfontcmd + , rubyfontcmd .initial:n = \kanbun_rubyfontcmd_default + , unit .tl_set:N = \kanbun_zw + , unit .initial:n = { \kanbun_init_zw } + , yokoaki .tl_set:N = \kanbun_yokoaki + , yokoaki .initial:n = { \kanbun_scale } + , tateaki .tl_set:N = \kanbun_tateaki + , tateaki .initial:n = { 2 } + , okuriprotrusion .tl_set:N = \kanbun_okuriprotrusion + , okuriprotrusion .initial:n = { 1 } + , kumi .tl_set:N = \kanbun_kumi + , kumi .initial:n = { aki } + , aki .code:n = \keys_set:nn { kanbun } { kumi = aki } + , beta .code:n = \keys_set:nn { kanbun } { kumi = beta } + } +\ProcessKeysOptions { kanbun } + +% other vars +\tl_set:Nn \kanbun_rubyfontsize_rubyfontcmd { \kanbun_rubyfontcmd\fontsize{\fp_eval:n {1/\kanbun_scale}\kanbun_zw}{0pt}\selectfont } +\newlength{\kanbun_furilen} +\tl_set:Nn \kanbun_tateten_width { 1/30 } +\tl_set:Nn \kanbunzwtosp { \fp_eval:n {\dim_ratio:nn { 1 \kanbun_zw } { 1 sp } } } +\tl_set:Nn \kanbun_unit_glue { + \str_if_eq:VnTF \kanbun_kumi { aki } { + \penalty0 + } + { + \hskip 0\kanbun_zw plus 0.25\kanbun_zw minus 0\kanbun_zw + } +} +\tl_set:Nn \kanbun_punct_glue { + \hskip 0\kanbun_zw plus 0.5\kanbun_zw minus 0\kanbun_zw +} + +% \kanjiunit and other macros to be used in a \kanjiunit +\NewDocumentCommand { \kanbun_ensure_height } { m m } + { + \vbox to #1{\vss{#2}\vss} + } +\newbox\kanbun_current_kanjiunit +\NewDocumentCommand { \kanjiunit } { m m m m m m } + { + \tl_set:Nn \ninojiten_punct {} + \tl_set:Nn \right_punct {} + \tl_set:Nn \central_punct {} + \process_punct{ #4 } + \tl_set:Nn \kanbun_central_punct_box { + \kanbun_ensure_height{1\kanbun_zw} { + \str_if_eq:VnTF \kanbun_kumi { aki } + { + \hbox{\kern 1\kanbun_zw{\hbox to \fp_eval:n { \kanbun_tateaki/\kanbun_scale }\kanbun_zw{\hss{\central_punct}\hss}}} + } + { + \hbox{\kern 1\kanbun_zw{\central_punct}} + } + } + } + \tl_set:Nn \kanbun_left_punct_phantom { + \kanbun_ensure_height{1\kanbun_zw} { + \str_if_eq:VnTF \kanbun_kumi { aki } { } + { + \str_if_eq:nnTF { #2 } { } { } { + \hbox{\phantom{\hbox to 0.5\kanbun_zw{\hss#2\hfil}}} + } + } + } + } + \tl_set:Nn \kanbun_right_punct_box { + \kanbun_ensure_height{1\kanbun_zw} { + \str_if_eq:VnTF \right_punct { } { } { + \hbox{\kern 1\kanbun_zw{\right_punct}} + } + } + } + % + \tl_set:Nn \unit_content { + \kanbun_left_punct_phantom % compensate for width of left punct + \vbox{ + \kanbun_ensure_height{\fp_eval:n { 1/\kanbun_scale }\kanbun_zw}{\hbox{\kanbun_rubyfontsize_rubyfontcmd{#1}}} % right kana + \nointerlineskip % + \kanbun_ensure_height{1\kanbun_zw}{\llap{#2}} % left punct + \nointerlineskip % + \vspace*{-1 \kanbun_zw} + \kanbun_ensure_height{1\kanbun_zw}{ + \hbox to 1\kanbun_zw{\hss{#3}\hss} + } % kanji + \nointerlineskip % + \vspace*{-1 \kanbun_zw} + \kanbun_ensure_height{\fp_eval:n { 1/\kanbun_scale }\kanbun_zw}{\hbox{\kern 1\kanbun_zw{\ninojiten_punct}}} % ninojiten + \nointerlineskip % + \vspace*{\fp_eval:n { -1/\kanbun_scale }\kanbun_zw} + \kanbun_right_punct_box % right punct + \nointerlineskip % + \vspace*{-1\kanbun_zw} + \kanbun_central_punct_box % central punct + \nointerlineskip % + \vspace*{ \fp_eval:n { -1/\kanbun_scale }\kanbun_zw } + \kanbun_ensure_height{\fp_eval:n { 1/\kanbun_scale }\kanbun_zw}{\hbox{\kanbun_rubyfontsize_rubyfontcmd\kern 1\kanbun_zw{\kaeriten{#5}}}} % kaeriten + \nointerlineskip % + \kanbun_ensure_height{\fp_eval:n { 1/\kanbun_scale }\kanbun_zw}{\hbox{\kanbun_rubyfontsize_rubyfontcmd{#6}}} % left kana + } + } + \str_if_eq:VnTF \kanbun_kumi { aki } { + \setbox\kanbun_current_kanjiunit \hbox to \fp_eval:n { 1+\kanbun_tateaki/\kanbun_scale }\kanbun_zw{ \unit_content } + }{ + \setbox\kanbun_current_kanjiunit \hbox{ \unit_content } + } + % + % output + \str_if_eq:VnTF \kanbun_kumi { aki } { } + { + \str_if_eq:nnTF { #2 } { } { } { + \kanbun_punct_glue + } + } + \nobreak + \str_if_eq:VnTF \kanbun_kumi { aki } + { + \usebox\kanbun_current_kanjiunit + } + { + \discretionary{ + \usebox\kanbun_current_kanjiunit\kern\dimexpr1\kanbun_zw-\wd\kanbun_current_kanjiunit\relax + }{ + % + }{ + \usebox\kanbun_current_kanjiunit + } + } + \nobreak + \str_if_eq:VnTF \kanbun_kumi { aki } { } + { + \str_if_eq:VnTF \right_punct { } { } { + \kanbun_punct_glue + } + } + \nobreak + \kanbun_unit_glue + } +\NewDocumentCommand { \furiokuri } { m m } + { + \settowidth{\kanbun_furilen}{#1} + \ifdim\kanbun_furilen < \fp_eval:n {1-\kanbun_okuriprotrusion/\kanbun_scale}\kanbun_zw + \makebox[\fp_eval:n {1-\kanbun_okuriprotrusion/\kanbun_scale}\kanbun_zw][l]{#1} + \else + #1 + \fi + #2 + } +\NewDocumentCommand { \kaeriten } { m } + { + \tl_set:Nn \kaeriten_output { #1 } + \sys_if_engine_xetex:TF {} { + \platex_if_direction_tate:TF { + \str_case:VnTF \kaeriten_output { + { 一レ } { \tl_set:Nn \kaeriten_output { \kern \fp_eval:n {-0.25/\kanbun_scale}\kanbun_zw 一\kern \fp_eval:n {-0.75/\kanbun_scale}\kanbun_zw レ } } + { 甲レ } { \tl_set:Nn \kaeriten_output { 甲\kern \fp_eval:n {-0.25/\kanbun_scale}\kanbun_zw レ } } + { 上レ } { \tl_set:Nn \kaeriten_output { 上\kern \fp_eval:n {-0.25/\kanbun_scale}\kanbun_zw レ } } + { 天レ } { \tl_set:Nn \kaeriten_output { 天\kern \fp_eval:n {-0.25/\kanbun_scale}\kanbun_zw レ } } + } {} {} + } {} + } + \tl_use:N \kaeriten_output + } +\NewDocumentCommand { \process_punct_map } { m } { + \str_case:nnTF { #1 } { + { — } { \tl_put_right:Nn \central_punct { \tateten } } + { ― } { \tl_put_right:Nn \central_punct { \tateten } } + { ㆐ } { \tl_put_right:Nn \central_punct { \tateten } } + % { : } { \tl_put_right:Nn \central_punct { \hbox to 1\kanbun_zw{\hss{:}\hss} } } + % { ・ } { \tl_put_right:Nn \central_punct { \hbox to 1\kanbun_zw{\hss{・}\hss} } } + { : } { \tl_put_right:Nn \right_punct { \hbox to 0.5\kanbun_zw{\hss{:}\hss} } } + { ・ } { \tl_put_right:Nn \right_punct { \hbox to 0.5\kanbun_zw{\hss{・}\hss} } } + { … } { \tl_put_right:Nn \central_punct { \hbox to 1\kanbun_zw{\hss{…}\hss} } } + { ! } { \tl_put_right:Nn \central_punct { \hbox to 1\kanbun_zw{\hss{!}\hss} } } + { ? } { \tl_put_right:Nn \central_punct { \hbox to 1\kanbun_zw{\hss{?}\hss} } } + { 〻 } { + \tl_put_right:Nn \ninojiten_punct { \ninojiten } + \tl_put_right:Nn \right_punct { \phantom{\ninojiten} } + } + } {} { + \tl_put_right:Nn \right_punct { \hbox to 0.5\kanbun_zw{\hfil#1\hss} } + } +} +\NewDocumentCommand { \process_punct } { m } + { + \str_map_function:nN { #1 } \process_punct_map + } +\NewDocumentCommand { \multifuriokuri } { O{2\kanbun_zw} m m } + { + \kanbun_rubyfontcmd + \kern \fp_eval:n { -(#1) }\kanbun_zw + \makebox[\fp_eval:n { (#1) + 1 - \kanbun_okuriprotrusion/\kanbun_scale }\kanbun_zw][s]{#2} + #3 + } + +% these commands are used as punct +\NewDocumentCommand { \tateten } {} + { + \str_if_eq:VnTF \kanbun_kumi { aki } { + \makebox[\fp_eval:n {\kanbun_tateaki/\kanbun_scale}\kanbun_zw][c]{ + \rule[\fp_eval:n {-\kanbun_tateten_width/2}\kanbun_zw]{\fp_eval:n {\kanbun_tateaki/\kanbun_scale}\kanbun_zw}{\fp_eval:n {\kanbun_tateten_width}\kanbun_zw} + } + }{ + \makebox[\fp_eval:n {1/\kanbun_scale}\kanbun_zw][c]{ + \rule[\fp_eval:n {-\kanbun_tateten_width/2}\kanbun_zw]{\fp_eval:n {1/\kanbun_scale}\kanbun_zw}{\fp_eval:n {\kanbun_tateten_width}\kanbun_zw} + } + } + } +\NewDocumentCommand { \ninojiten } {} + { \kanbun_rubyfontsize_rubyfontcmd 〻 } + +% corrects fontsize of ruby base +\NewDocumentCommand { \kanbunfont } {} { \parindent=0pt\kanbun_fontcmd\fontsize{\kanbun_zw}{\fp_eval:n {1+\kanbun_yokoaki/\kanbun_scale}\kanbun_zw}\selectfont} +\NewDocumentEnvironment { kanjipar } { +b } + { + { + \kanbunfont + #1 + \par + } + } {} + +% for LuaLaTeX to parse Kanbun annotation +\NewDocumentCommand{\matchkana}{ m }{ + \regex_set:Nn \c_kana_regex {[\x{3040}-\x{30FA}\x{30FC}-\x{30FF}\x{31F0}-\x{31FF}\x{FF66}-\x{FF9F}\x{1B100}-\x{1B122}\x{1AFF0}-\x{1AFFF}\x{1B000}-\x{1B0FF}\x{1B130}-\x{1B16F}]} + \regex_match:NnTF \c_kana_regex { #1 } { \bool_set_true:N \g_kana_bool } { \bool_set_false:N \g_kana_bool } +} +% +\ExplSyntaxOff +% +\ifluatex +% verbatim reader adapted from https://tex.stackexchange.com/a/361759 +\directlua{ +verb_table = {} +function store_lines (str) + if string.find (str , "\noexpand\\EndKanbun" ) then + luatexbase.remove_from_callback ( + "process_input_buffer" , "store_lines") + return "\\newif\\ifcontinue\\continuetrue\\directlua { co = coroutine.create(main_loop) }\\loop\\directlua{ ok,b=coroutine.resume(co) tex.sprint(b) }\\ifcontinue\\repeat" + else + table.insert(verb_table, str) + end + return "" +end +function register_verbatim () + verb_table = {} + luatexbase.add_to_callback( + "process_input_buffer" , store_lines , "store_lines") +end +% require main loop +kanbunzwtosp = \luaescapestring{\kanbunzwtosp} +require("kanbun.lua") +} +\def\Kanbun{\directlua{register_verbatim()}} +\def\createcatcodes{% + \bgroup% + \catcode`\\=12 \catcode`\{=12 \catcode`\}=12% + \catcode`\$=12 \catcode`\&=12 \catcode`\^^M=13% + \catcode`\#=12 \catcode`\^=12 \catcode`\_=12% + \catcode`\ =13 \catcode`\~=12 \catcode`\%=12% + \savecatcodetable 1% + \egroup% +} +\createcatcodes +\bgroup% + \catcode`\^^M=13\gdef^^M{\quitvmode\par}% + \catcode`\ = 13\gdef {\quitvmode\Space}% +\egroup% +\def\Space{ } +% +\fi |