summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2022-01-17 20:58:06 +0000
committerKarl Berry <karl@freefriends.org>2022-01-17 20:58:06 +0000
commitff3d8cdee7284dec8be1092a253ba6bca6f2a93b (patch)
tree18fc35d8308e8f428123df84af74d8f05911b2bd /Master
parente4d6bacce38f34441ff02a9509c5c90c0c620ff8 (diff)
kanbun (17jan22)
git-svn-id: svn://tug.org/texlive/trunk@61636 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/latex/kanbun/README.md24
-rw-r--r--Master/texmf-dist/doc/latex/kanbun/kanbun-example.pdfbin0 -> 45616 bytes
-rw-r--r--Master/texmf-dist/doc/latex/kanbun/kanbun-example.tex44
-rw-r--r--Master/texmf-dist/doc/latex/kanbun/kanbun.lua224
-rw-r--r--Master/texmf-dist/doc/latex/kanbun/kanbun.pdfbin0 -> 376249 bytes
-rw-r--r--Master/texmf-dist/doc/latex/kanbun/kanbun.tex301
-rw-r--r--Master/texmf-dist/tex/latex/kanbun/kanbun.sty317
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rw-r--r--Master/tlpkg/tlpsrc/collection-langjapanese.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/kanbun.tlpsrc0
10 files changed, 912 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/kanbun/README.md b/Master/texmf-dist/doc/latex/kanbun/README.md
new file mode 100644
index 00000000000..3b6e755d2df
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/kanbun/README.md
@@ -0,0 +1,24 @@
+# The `kanbun` package
+
+The `kanbun` package, like other *kanbun-kundoku* (漢文訓読) LaTeX packages (such as `gckanbun`), allows users to manually input macros for elements in a *kanbun-kundoku* paragraph.
+
+More importantly, it accepts plain text input in the “*kanbun* annotation” form when used with LuaLaTeX, which allows typesetting *kanbun-kundoku* paragraphs efficiently.
+
+## Licence
+
+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`.
diff --git a/Master/texmf-dist/doc/latex/kanbun/kanbun-example.pdf b/Master/texmf-dist/doc/latex/kanbun/kanbun-example.pdf
new file mode 100644
index 00000000000..f437066ba93
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/kanbun/kanbun-example.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/kanbun/kanbun-example.tex b/Master/texmf-dist/doc/latex/kanbun/kanbun-example.tex
new file mode 100644
index 00000000000..0ae963112fc
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/kanbun/kanbun-example.tex
@@ -0,0 +1,44 @@
+%% 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.
+%
+% example text from https://phesoca.com/kanbun-html/
+\documentclass{ltjtarticle}
+
+\usepackage[match]{luatexja-fontspec}
+\setmainjfont{Kozuka Mincho Pr6N}
+
+\newlength\myzw
+\setlength\myzw{2.25\zw}
+\usepackage[kumi=beta, unit=\myzw, yokoaki=3.5]{kanbun}
+
+\usepackage[margin=0pt]{geometry}
+
+\usepackage{xcolor}
+
+\Kanbun
+初メテ,帝ノ母劉貴人ハ賜(たま)ハリ[レ]死ヲ,太祖ハ告ゲ[レ]帝ニ曰ハク「昔漢武帝ハ將‹し›«テ»ニ[レ]立タセント[二]其ノ子ヲ[一]而殺シ[二]其ノ母ヲ[一],不[下]令(し)メ[三]婦人ヲ後ロニ與(あづか)ラ[二]國政ニ[一],使(し)メ[中]外家ヲ為(な)サ[上レ]亂ヲ。汝當ニ‹べ›«ク»[二]繼統ス[一],故ニ吾レ遠クシテ同ズルコト[二]漢武ト[一],為(た)リ[二]長久之計[一]。」帝素ヨリ純孝ナリ,哀シク泣キ不[レ]能ハ[二]自ラ勝ツコト[一],太祖怒ル[レ]之レヲ。帝ハ還リ[レ]宮ニ,哀シク不[二]自ラ止マ[一],日夜ニシテ號泣ス。太祖知リテ而又タ召ス[レ]之レヲ。帝欲シ[レ]入ラント,左右曰ハク「孝子事ヘバ[レ]父ニ,小杖則チ受ケ,大杖避ク[レ]之レヲ。今陛下ノ怒ルコト盛ンナリ,入レバ或イハ不測ナリ,陷ラス[二]帝ヲ於不義ニ[一]。不[レ]如カ[二]且(しばら)ク出ヅルニ[一],待チテ[二]怒リノ解クルヲ[一]而進ムコト,不ル[レ]晚カラ也。」帝ハ懼レ,從ヒ[レ]之レニ,乃チ游行シ逃グ[二]於外ニ[一]。
+\EndKanbun
+
+\begin{document}
+\color[HTML]{e0e0e0}
+\pagestyle{empty}
+\vspace*{\fill}
+\begin{minipage}{0.5\pageheight}
+ \printkanbun
+\end{minipage}
+\vspace*{\fill}
+\end{document} \ No newline at end of file
diff --git a/Master/texmf-dist/doc/latex/kanbun/kanbun.lua b/Master/texmf-dist/doc/latex/kanbun/kanbun.lua
new file mode 100644
index 00000000000..9f8f01aab39
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/kanbun/kanbun.lua
@@ -0,0 +1,224 @@
+function directtex(str)
+ coroutine.yield(str)
+end
+
+function to_TeX_box(str)
+ directtex("\\ExplSyntaxOn\\newbox\\kanbun_lua_box\\sbox\\kanbun_lua_box{"..str.."}\\ExplSyntaxOff")
+ return tex.getbox('kanbun_lua_box')
+end
+
+function has_value (tab, val)
+ for index, value in ipairs(tab) do
+ if value == val then
+ return true
+ end
+ end
+ return false
+end
+
+function main_loop()
+ brackets = {}
+ --
+ brackets["furigana"] = {"(", ")"}
+ brackets["okurigana"] = {"{","}"} -- allow user to omit
+ brackets["kaeriten"] = {"[","]"}
+ brackets["furigana4saidokumoji"] = {"‹","›"}
+ brackets["okurigana4saidokumoji"] = {"«","»"}
+ --
+ -- other_brackets["punctuation"] = {"⦉","⦊"}
+ -- other_brackets["kanji"] = {"⌊","⌋"}
+ -- other_brackets["multikanji"] = {"‘","’"}
+ -- other_brackets["unit"] = {"“","”"}
+ --
+ left_brackets = {}
+ right_brackets = {}
+ for k,v in pairs(brackets) do
+ table.insert(left_brackets, v[1])
+ table.insert(right_brackets, v[2])
+ end
+
+ -- punctuation_str = "〻―・、,。…「」『』"
+ punctuation_str = "㆐〻―—・、,。…「」『』!?:"
+ left_punctuation_str = "「『"
+
+ lines_chars_table = {}
+ tex_kana_bool = token.create("g_kana_bool")
+ tex_true_bool = token.create("c_true_bool")
+ for i,l in ipairs(verb_table) do
+ split_line = {}
+ for c in l:gmatch(utf8.charpattern) do
+ table.insert(split_line, c)
+ end
+
+ -- some unknown bug (in \matchkana ?) solved by changing the last entry to an empty string if not ascii
+ for i,c in ipairs(split_line) do
+ last_index = i
+ end
+ if utf8.codepoint(split_line[last_index] or " ") < 128 then
+ split_line[last_index+1]=""
+ else
+ split_line[last_index]=""
+ end
+
+ last_bracket_index = 0
+ for j,c in ipairs(split_line) do
+ if has_value(left_brackets, c) then
+ last_bracket_index = j
+ end
+ if last_bracket_index == 0 then
+ directtex("\\matchkana{"..c.."}")
+ if tex_kana_bool.mode == tex_true_bool.mode then
+ split_line[j] = brackets["okurigana"][1]..c..brackets["okurigana"][2]
+ else
+ split_line[j] = "“⌊"..c.."⌋”"
+ end
+ end
+ if has_value(right_brackets, c) then
+ last_bracket_index = 0
+ end
+ end
+ table.insert(lines_chars_table, split_line)
+ end
+
+ annotated_lines_table = {}
+ for i,l in ipairs(lines_chars_table) do
+ line = table.concat(l, "")
+
+ line = string.gsub(line, brackets["okurigana"][2]..brackets["okurigana"][1], "")
+ for k,v in pairs(brackets) do
+ line = string.gsub(line, "”(%"..v[1]..")", "%1")
+ line = string.gsub(line, "(%"..v[2]..")(“)", "%1”%2")
+ end
+ for c in line:gmatch(utf8.charpattern) do
+ last = c
+ end
+ if has_value(right_brackets, last) then
+ str = str .. '”'
+ end
+ line = string.gsub(line, "⌊‘⌋”", "‘")
+ line = string.gsub(line, "“⌊’⌋", "’")
+ for p in punctuation_str:gmatch(utf8.charpattern) do
+ line = string.gsub(line, "”“⌊("..p..")⌋", "⦉%1⦊")
+ end
+ line = string.gsub(line, "⦊⦉", "")
+
+ -- reverse the makeshift bug fix to \matchkana
+ line = string.gsub(line, "“⌊⌋”", "")
+
+ -- process annotated text
+ tmp_number_of_multikanji_braces = {utf8.char(61442), utf8.char(61443)}
+ -- process line into units
+ split_line = {}
+ for c in line:gmatch(utf8.charpattern) do
+ table.insert(split_line, c)
+ end
+ units = {}
+ unit_content = {}
+ last_bracket_index = 0
+ for j,c in ipairs(split_line) do
+ if c == "”" then
+ last_bracket_index = last_bracket_index - 1
+ end
+ if last_bracket_index < 1 then
+ table.insert(units, table.concat(unit_content, ""))
+ unit_content = {}
+ else
+ table.insert(unit_content, c)
+ end
+ if c == "“" then
+ last_bracket_index = last_bracket_index + 1
+ end
+ end
+ -- account for multikanji
+ for j,u in ipairs(units) do
+ split_unit = {}
+ for c in u:gmatch(utf8.charpattern) do
+ table.insert(split_unit, c)
+ end
+ number_of_multikanji = 0
+ local last_k
+ for k,c in ipairs(split_unit) do
+ if c == "“" then
+ number_of_multikanji = number_of_multikanji + 1
+ last_k = k
+ end
+ end
+ for m,c in ipairs(split_unit) do
+ if m == last_k then
+ split_unit[m] = "“"..tmp_number_of_multikanji_braces[1]..number_of_multikanji..tmp_number_of_multikanji_braces[2]
+ end
+ end
+ units[j] = table.concat(split_unit, "")
+ if number_of_multikanji > 0 then
+ units[j] = string.gsub(units[j], "“(.-)”’(.*)", "“%1%2”")
+ units[j] = string.gsub(units[j], "‘", "")
+ tmp_unit = units[j]
+ table.remove(units, j)
+ for new_unit in tmp_unit:gmatch"“(.-)”" do
+ table.insert(units, j, new_unit)
+ j = j + 1
+ end
+ end
+ end
+ for j,u in ipairs(units) do
+ if u == "" then
+ table.remove(units, j)
+ end
+ end
+ next_left_punct_ = ""
+ for j,u in ipairs(units) do
+ right_okuri_ = u:match("%{(.-)%}") or ""
+ kanji_ = u:match("⌊(.-)⌋") or ""
+ right_furi_ = u:match("%((.-)%)") or ""
+ left_furi_ = u:match("‹(.-)›") or ""
+ left_okuri_ = u:match("«(.-)»") or ""
+ punct_ = u:match("⦉(.-)⦊") or ""
+ --
+ -- punct_ = punct_:gsub("―", "\\tateten")
+ -- punct_ = punct_:gsub("—", "\\tateten")
+ -- punct_ = punct_:gsub("〻", "\\ninojiten")
+ --
+ kaeriten_ = u:match("%[(.-)%]") or ""
+ multikanji_ = u:match(tmp_number_of_multikanji_braces[1].."(.-)"..tmp_number_of_multikanji_braces[2]) or 0
+ if punctuation_str:match(kanji_) then
+ punct_ = kanji_
+ kanji_ = ""
+ end
+ left_punct_ = next_left_punct_
+ next_left_punct_ = ""
+ for p_ in punct_:gmatch(utf8.charpattern) do
+ if left_punctuation_str:match(p_) then
+ next_left_punct_ = next_left_punct_ .. p_
+ end
+ end
+ for p_ in left_punctuation_str:gmatch(utf8.charpattern) do
+ punct_ = string.gsub(punct_, p_, "")
+ end
+ if u:match(tmp_number_of_multikanji_braces[1]) then
+ multiruby_raise_by_ = 0
+ for trace_back_index = 1, multikanji_-1 do
+ multiruby_raise_by_ = multiruby_raise_by_ + to_TeX_box(units[j - trace_back_index]).width/(kanbunzwtosp)
+ end
+ units[j - multikanji_ + 1] = units[j - multikanji_ + 1]:gsub("\\kanjiunit", "\\hbox{\\kanjiunit")
+ units[j] = "\\kanjiunit{\\multifuriokuri["..multiruby_raise_by_.."]{"..right_furi_.."}{"..right_okuri_.."}}{"..left_punct_.."}{"..kanji_.."}{"..punct_.."}{"..kaeriten_.."}{\\multifuriokuri["..multiruby_raise_by_.."]{"..left_furi_.."}{"..left_okuri_.."}}}"
+ else
+ if kanji_ == "" then
+ units[j] = ""
+ else
+ units[j] = "\\kanjiunit{\\furiokuri{"..right_furi_.."}{"..right_okuri_.."}}{"..left_punct_.."}{"..kanji_.."}{"..punct_.."}{"..kaeriten_.."}{\\furiokuri{"..left_furi_.."}{"..left_okuri_.."}}"
+ end
+ end
+ end
+ line = table.concat(units, "")
+
+ table.insert(annotated_lines_table, line)
+ end
+
+ -- ouput
+ output = "{\\kanbunfont"..table.concat(annotated_lines_table, "\\par").."\\par}"
+ directtex("\\def\\printkanbun{"..output.."}")
+ directtex("\\def\\printkanbuncode{\\directlua{print('')print(output)}}")
+
+ -- end loop in TeX
+ directtex("\\continuefalse")
+end
diff --git a/Master/texmf-dist/doc/latex/kanbun/kanbun.pdf b/Master/texmf-dist/doc/latex/kanbun/kanbun.pdf
new file mode 100644
index 00000000000..a3b0cbdd30f
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/kanbun/kanbun.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/kanbun/kanbun.tex b/Master/texmf-dist/doc/latex/kanbun/kanbun.tex
new file mode 100644
index 00000000000..02e4c0e9187
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/kanbun/kanbun.tex
@@ -0,0 +1,301 @@
+%% 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.
+%
+\documentclass[12pt]{ltxdockit}
+
+\AfterTOCHead[toc]{\sffamily}
+\makeatletter
+ \def\@seccntformat#1{\protect\makebox[0pt][r]{\csname the#1\endcsname\hspace{\marglistsep}}}
+\makeatother
+
+\usepackage{shortvrb}
+\MakeShortVerb{|}
+
+\lstnewenvironment{example}[1][]
+ {\lstset{
+ basicstyle=\ttfamily,
+ frame=single,
+ columns=flexible,
+ language=[LaTeX]TeX,
+ breaklines=true,
+ postbreak=\mbox{\textcolor{spot}{$\hookrightarrow$}\space},
+ % morekeywords={drawuntpoint,untpoint,linkuntpoints},
+ % escapeinside={<@}{@>},
+ }}
+ {}
+
+\usepackage{luatexja}
+ \ltjdefcharrange{10}{"2E3A}
+ \ltjdefcharrange{11}{"2039-"203A}
+ \ltjsetparameter{jacharrange={-1, +2, +3, -4, -5, +6, +7, -8, +9, +10, -11}}
+\usepackage[match]{luatexja-fontspec}
+\defaultfontfeatures{Numbers=OldStyle, Scale=MatchLowercase}
+\defaultjfontfeatures{Scale=MatchLowercase}
+\setmainjfont{Kozuka Mincho Pr6N}
+\setsansjfont{Sarasa Mono J}
+\setmonojfont[YokoFeatures={JFM=prop}]{Sarasa Mono J}
+\setmainfont{Minion Pro}
+\setsansfont{Myriad Pro}
+\setmonofont{Sarasa Mono J}
+\newfontfamily{\kanbunfamily}{Kozuka Mincho Pr6N}
+
+\usepackage{luatexja-ruby}
+ \ltjsetruby{fontcmd=\addjfontfeature{RawFeature={+ruby}}}
+
+\usepackage{kanbun}
+\newcommand{\printkanbunblock}[2]{
+ {
+ \parindent=0pt
+ \vspace*{1\zw}
+ \hfill
+ \vbox{
+ \hsize=#1\zw
+ {
+ \tate
+ \addjfontfeature{Scale=1}
+ #2
+ }
+ }
+ \hfill
+ \vspace*{1\zw}
+ }
+}
+
+\usepackage{bxtexlogo}
+\usepackage{realscripts}
+\usepackage{microtype}
+
+\usepackage{wallpaper}
+
+\Kanbun
+以テ[二]羅(ら)蝶(てふ)ヲ[一]作ルガ[二]漢文訓読ヲ[一]用(ため)ノ包(ぱつけーぢ)
+\EndKanbun
+\title{The \sty{kanbun} package}
+\subtitle{\normalsize\normalfont\addjfontfeature{Scale=1}\printkanbun}
+\author{Yuanhao Chen (\ruby[rubysmash=true]{陳|元|鎬}{ちん|げん|こう})}
+\date{\scshape 15 january 2022, v1.0}
+
+
+\begin{document}
+
+\ThisCenterWallPaper{1}{kanbun-example.pdf}
+\ExplSyntaxOn
+\tl_set:Nn \kanbun_kumi { beta }
+\ExplSyntaxOff
+\maketitle
+\tableofcontents
+
+
+\section{Introduction}
+The \sty{kanbun} package, like other \emph{kanbun-kundoku} (漢文訓読) \LaTeX{} packages (such as \sty{gckanbun}), allows users to manually input macros for elements in a \emph{kanbun-kundoku} paragraph.
+
+More importantly, it accepts plain text input in the ``\emph{kanbun} annotation'' form when used with \LuaLaTeX, which allows typesetting \emph{kanbun-kundoku} paragraphs efficiently\footnote{The idea comes from \href{https://phesoca.com/kanbun-html/}{漢文\textsc{html}} by UntPhesoca, which is a JavaScript and \textsc{css} implementation.}.
+
+
+\section{Basic example with \LuaLaTeX}
+As seen in the following example, typesetting a \emph{kanbun-kundoku} paragraph with the \sty{kanbun} package requires only light annotations --- it automatically transforms the annotated plain text into \LaTeX{} macros through Lua, rather than having users type in macros themselves.
+
+\ExplSyntaxOn
+\tl_set:Nn \kanbun_tateaki { 1 }
+\tl_set:Nn \kanbun_kumi { aki }
+\ExplSyntaxOff
+\Kanbun
+月落チ烏啼キテ霜満ツ[レ]天ニ,
+江楓漁火対ス[二]愁眠ニ[一]。
+姑(こ)蘇(そ)城外ノ寒山寺,
+夜半ノ鐘声到ル[二]客船ニ[一]。
+\EndKanbun
+
+\penalty0
+\printkanbunblock{13}{\printkanbun}
+\vspace{-2\zw}
+
+\begin{example}
+\documentclass{ltjtarticle}
+\usepackage[kumi=aki, tateaki=1]{kanbun}
+\begin{document}
+\Kanbun
+月落チ烏啼キテ霜満ツ[レ]天ニ,
+江楓漁火対ス[二]愁眠ニ[一]。
+姑(こ)蘇(そ)城外ノ寒山寺,
+夜半ノ鐘声到ル[二]客船ニ[一]。
+\EndKanbun
+\printkanbun
+\end{document}
+\end{example}
+
+Note that if you want to use this functionality, you have to run this document with \LuaLaTeX.
+
+
+\section{Usage}
+
+\subsection{Package options}
+Load the package with
+\begin{ltxsyntax}
+ \cmditem{usepackage}\oprm{\sty{kanbun} options}|{kanbun}|
+\end{ltxsyntax}
+
+This package provides a variety of customisable features in \emph{kanbun-kundoku}.
+
+\begin{optionlist}
+ \optitem[]{scale}{\prm{ratio}}
+ Sets the ratio of the size of \emph{kanji} to that of ruby texts. Default: \verb|2|.
+
+ \optitem[]{fontcmd}{\prm{font command}}
+ Sets the font command to use for \emph{kanji}. If \sty{luatexja-fontspec} is loaded, it is set default to \verb|\addjfontfeatures{RawFeature={+trad}}| to obtain traditional \emph{kanji} if applicable.
+
+ \optitem[]{rubyfontcmd}{\prm{font command}}
+ Sets the font command to use for ruby texts. If \sty{luatexja-fontspec} is loaded, it is set default to \verb|\addjfontfeatures{RawFeature={+ruby}}| to obtain ruby glyphs when applicable.
+
+ \optitem[]{unit}{\prm{length}}
+ Sets the base size (size of \emph{kanji}). Default: \verb|\kanbun_zw|, which is initialised as \verb|1em|.
+
+ \optitem[]{yokoaki}{\prm{ratio}}
+ Sets the horizontal space between \emph{kanji} with respect to the size of ruby texts. Default: \verb|2|.
+
+ \optitem[]{tateaki}{\prm{ratio}}
+ Sets the vertical space between \emph{kanji} with respect to the size of ruby texts. Default: \verb|2|.
+
+ \optitem[]{okuriprotrusion}{\prm{ratio}}
+ Sets how much \emph{okurigana} should be vertically tucked into the space of \emph{kanji} with respect to the size of ruby texts, if that does not cause an overlap with \emph{furigana}. Default: \verb|1|.
+
+ \optitem[]{kumi}{\opt{aki}, \opt{beta}}
+ Sets whether to use \emph{aki-gumi} (typeset with uniform inter-character spacing) or \emph{beta-gumi} (typeset with no inter-character space between adjacent character frames). Or simply call \opt{aki} or \opt{beta} without \opt{kumi=}. Default: \opt{aki}.
+\end{optionlist}
+
+After initialising the options, you can still change the option values through \sty{exlp3} syntax, with a prefix \verb|\kanbun_| to option names. For example, to switch to \emph{beta-gumi}, you could use
+\begin{example}
+\ExplSyntaxOn
+\tl_set:Nn \kanbun_kumi { beta }
+\ExplSyntaxOff
+\end{example}
+
+\subsection[Basic usage without \LuaLaTeX]{Basic usage without \LuaLaTeX{} (not recommended)}
+When not using the advanced \emph{kanbun}-annotation functionality, it is possible to typeset \emph{kanbun} with any engine with \textsc{cjk} support, such as using \XeLaTeX{} with the \sty{xeCJK} package, or using \upLaTeX{} with \sty{utarticle} or other appropriate class.
+
+\begin{ltxsyntax}
+ \cmditem{kanjiunit}\verb|{ |\cmd{furiokuri}\mprm{right furigana}\mprm{right okurigana}\verb| }|\vspace{-5pt}\\
+ \mprm{left punctuation (e.g.~`「')}\\
+ \mprm{kanji}\\
+ \mprm{other punctuation}\\
+ \mprm{kaeriten}\\
+ \verb|{ |\cmd{furiokuri}\mprm{left furigana}\mprm{left okurigana}\verb| }|
+
+ \cmditem{kanbunfont}
+
+ Sets the font size of \emph{kanji}. Use when the \opt{unit} option is set different to the document's default font size.
+
+ Use \cmd{multifuriokuri} instead of \cmd{furiokuri} if you are putting \emph{furigana} to multiple kanji.
+
+ \cmditem{multifuriokuri}\oprm{length by which {furigana} is raised}\mprm{furigana}\mprm{okurigana}
+\end{ltxsyntax}
+
+For example, the code
+\begin{example}
+% example text from https://phesoca.com/kanbun-html/
+\kanbunfont
+\kanjiunit{}{}{子}{}{}{}
+\kanjiunit{\furiokuri{}{ク}}{}{曰}{,}{}{}
+\kanjiunit{\furiokuri{}{ゾ}}{}{盍}{}{三}{\furiokuri{}{ル}}
+\kanjiunit{}{}{各}{〻}{}{}
+\kanjiunit{\furiokuri{}{ハ}}{}{言}{}{二}{}
+\kanjiunit{\furiokuri{}{ノ}}{}{爾}{}{}{}
+\kanjiunit{\furiokuri{}{ヲ}}{}{志}{。}{一}{}
+\par
+\end{example}
+outputs
+
+\printkanbunblock{6}{
+\kanbunfont
+\kanjiunit{}{}{子}{}{}{}
+\kanjiunit{\furiokuri{}{ク}}{}{曰}{,}{}{}
+\kanjiunit{\furiokuri{}{ゾ}}{}{盍}{}{三}{\furiokuri{}{ル}}
+\kanjiunit{}{}{各}{〻}{}{}
+\kanjiunit{\furiokuri{}{ハ}}{}{言}{}{二}{}
+\kanjiunit{\furiokuri{}{ノ}}{}{爾}{}{}{}
+\kanjiunit{\furiokuri{}{ヲ}}{}{志}{。}{一}{}
+\par
+}
+
+\noindent
+with \opt{tateaki} set to \verb|1|.
+
+\subsection{Usage with \LuaLaTeX}
+\emph{Kanbun} annotation uses the following brackets to mark different elements in \emph{kanbun-kundoku} (as described in \href{https://phesoca.com/kanbun-html/}{漢文\textsc{html}} by UntPhesoca).
+\begin{itemize}
+ \item \verb|( )|: \emph{furigana} (振り仮名)
+ \item \verb|{ }|: \emph{okurigana} (送り仮名) (these brackets can be omitted)
+ \item \verb|‹ ›|: \emph{furigana} (振り仮名) of \emph{saidoku-moji} (再読文字)
+ \item \verb|« »|: \emph{okurigana} (送り仮名) of \emph{saidoku-moji} (再読文字)
+ \item \verb|[ ]|: \emph{kaeriten} (返り点)
+ \item \verb|‘ ’|: multiple \emph{kanji}, potentially with \emph{tateten} inserted, as a ruby base; group ruby (グループルビ)
+ \item no annotation: \emph{kanji} (漢字) and punctuation.
+\end{itemize}
+\emph{Tateten} (竪点) can be input with either \verb|―| (\verb|U+2015|), \verb|—| (\verb|U+2014|) or \verb|㆐| (\verb|U+3190|).
+
+\begin{ltxsyntax}
+ \cmditem{Kanbun}\cmditem{EndKanbun}
+
+ Write the annotated \emph{kanbun} between the commands \cmd{Kanbun} and \cmd{EndKanbun}, and it will be processed and saved, ready to be used later.
+
+ \cmditem{printkanbun}
+
+ Where you would like to use the most recently saved \emph{kanbun-kundoku} paragraph, use \cmd{printkanbun}.
+
+ \cmditem{printkanbuncode}
+
+ If you wish to make modifications on the result or to use the result with a non-\LuaTeX{} engine, it is possible to obtain the macros using \cmd{printkanbuncode} (prints in the terminal), and continue to work from there.
+\end{ltxsyntax}
+
+You can always save \cmd{printkanbun} to a macro and start a new annotated \emph{kanbun} block, as in the following example.
+\begin{example}
+% example text from https://phesoca.com/kanbun-html/
+\documentclass{ltjtarticle}
+\usepackage[kumi=beta]{kanbun}
+
+\Kanbun
+此レ乃チ信(しん)之‘所―[三]以’(ゆゑん)為ル[二]陛下ノ禽(とりこ)ト[一]也。
+\EndKanbun
+\let\信\printkanbun
+
+\Kanbun
+孤之有ルハ[二]孔明[一],猶ホ‹ごと›«キ»[二]魚之有ルガ[一レ]水也。
+\EndKanbun
+\let\孔明\printkanbun
+
+\begin{document}
+\孔明\par\bfseries\信
+\end{document}
+\end{example}
+
+\Kanbun
+此レ乃チ信(しん)之‘所―[三]以’(ゆゑん)為ル[二]陛下ノ禽(とりこ)ト[一]也。
+\EndKanbun
+\let\信\printkanbun
+
+\Kanbun
+孤之有ルハ[二]孔明[一],猶ホ‹ごと›«キ»[二]魚之有ルガ[一レ]水也。
+\EndKanbun
+\let\孔明\printkanbun
+
+\ExplSyntaxOn
+\tl_set:Nn \kanbun_kumi { beta }
+\ExplSyntaxOff
+\printkanbunblock{16}{\孔明\par\bfseries\信}
+
+
+\end{document}
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
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 6266a05300c..f587188c9d0 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -425,7 +425,7 @@ my @TLP_working = qw(
jmb jmlr jneurosci jnuexam josefin jpsj jsclasses
jslectureplanner jumplines junicode jupynotex
jura juraabbrev jurabib juramisc jurarsp js-misc jvlisting
- kalendarium kanaparser kantlipsum karnaugh karnaugh-map karnaughmap
+ kalendarium kanaparser kanbun kantlipsum karnaugh karnaugh-map karnaughmap
kastrup kaytannollista-latexia
kblocks kdgdocs kdpcover kerkis kerntest ketcindy
keycommand keyfloat keyindex keyparse keyreader keystroke
diff --git a/Master/tlpkg/tlpsrc/collection-langjapanese.tlpsrc b/Master/tlpkg/tlpsrc/collection-langjapanese.tlpsrc
index e5a5ed6b426..d2c43a365c5 100644
--- a/Master/tlpkg/tlpsrc/collection-langjapanese.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-langjapanese.tlpsrc
@@ -30,6 +30,7 @@ depend japanese-otf-uptex
depend jlreq
depend jlreq-deluxe
depend jsclasses
+depend kanbun
depend lshort-japanese
depend luatexja
depend mendex-doc
diff --git a/Master/tlpkg/tlpsrc/kanbun.tlpsrc b/Master/tlpkg/tlpsrc/kanbun.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/kanbun.tlpsrc