Closed tanukihee closed 4 years ago
按《日本語組版処理の要件》,「割注そのものの行間は,一般に 0 である.つまり,行間をとらない」(夹注行距,一般为 0),也许需要增加调整夹注行距以及竖排基线位置的功能。
baselineshift
功能似乎会同时影响夹住后的正文基线位置
\documentclass{ltjarticle}
\usepackage{jiazhu}
\jiazhuset{
baselineshift=-9pt
}
\begin{document}
本文本文\jiazhu{割注割注}本文本文
\end{document}
我认为这个功能应该只影响夹注的基线位置
jiazhu 是一个高度实验性的宏包,还没有经过充分测试,目前的状态是仅仅能保证编译不报错,输出效果很难保证。
对于同一字体,在 LuaLaTeX 和 XeTeX 下行距不同 LuaLaTeX
\documentclass{ltjarticle}
\usepackage{luatexja-fontspec}
\usepackage{jiazhu}
\setmainjfont{Source Han Serif CN}
\begin{document}
本文本文\jiazhu{割注割注割注割注割注割注}本文本文
\end{document}
XeTeX
\documentclass{ctexart}
\usepackage{jiazhu}
\setCJKmainfont{Source Han Serif CN}
\begin{document}
本文本文\jiazhu{割注割注割注割注割注割注}本文本文
\end{document}
在 XeTeX 环境下行距更窄,更美观。
https://www.w3.org/TR/2012/NOTE-jlreq-20120403/ja/#inline_cutting_note
割注とは [……] 縦組での利用が多く,横組での例は非常に少ない.
直排场合下,夹注基本不出现「横躺」的西文,所以要求用「零行间距」密排夹注,也还合理。
横排用夹注太异常了,如果用户在夹注里面写西文,还坚持零行间距,那么小写字母的下降部一定会跟第二行的汉字打架的。
所以也许可以加一个「调整夹注行距」的功能? 不过夹注里写西文也不太合适吧
@tanukihee @qinglee 啊!夹注的行距过宽,跟横排直排无关,跟编译引擎也无关呀!
原因是你用了不一样的 document class……
ltjtarticle
,直排,默认 10pt 的字(汉字更小,9.62216pt),17pt 的行距;ltjarticle
,横排,默认 10pt 的字(汉字更小,9.62216pt),15pt 的行距;ctexart
,横排,默认 10.5bp 的字,12.6bp 的行距(10.5*1.2
),但是通过 \linespread{1.3}
机制扩大行距。可以修改 \@@_boot:nn
的定义:
\usepackage{jiazhu}
\usepackage{etoolbox}
\ExplSyntaxOn
\makeatletter
\patchcmd\__jiazhu_boot:nn
{%
\exp_args:Nxx \fontsize
{ \fp_eval:n { \l__jiazhu_ratio_fp * \f@size } }
{ \fp_eval:n { \l__jiazhu_ratio_fp * \f@baselineskip } }
}{%
\exp_args:Nxx \fontsize
{ \fp_eval:n { \l__jiazhu_ratio_fp * \f@size } }
{ \fp_eval:n { \l__jiazhu_ratio_fp * \f@size } }
}{}{}
\makeatother
\ExplSyntaxOff
@qinglee 由于 document classes 预设的行距不可控,我觉得应该预设夹注行距等于夹注字号,即上述提到的方案,然后提供 linespread
用户接口。这样改的默认方案,一来是根据《日本語組版処理の要件》实现的,二来 discourage 用户往夹注里面写西文,三来用户实在想扩大行距也支持。
@qinglee 基线(或者中线)的对齐问题是这段代码引入的: https://github.com/CTeX-org/ctex-kit/blob/4ab8fa717a6c572238200274f689f9f4929e72b4/jiazhu/jiazhu.dtx#L504-L509
其中这个 hard-coded 的 0.8
是经验值,应该提供用户接口。
0.5
;0.88
,中易系列应该是 0.859375
,华文系列才是 0.8
。\strutbox
相关的代码也需要留意,针对西文优化的 \strut
不一定跟汉字中线居中对齐。改倒也挺简单,例子从 jiazhu-test.tex
来的:
黑色全角方块是刻意加进去的,作诊断用。在 Windows 里编译,字体是中易宋体,仍然无法完美对齐(黑方块底端应该与中线对齐),甚是诡异。
下移量需要严格推导,已经在下面一条评论中给出方案。
总算推出来了,不仅夹注文字居中,夹注前后追加的括弧也居中:
需要直排的话,把 \ideographht
改成 1/2
就好了。
\documentclass{ctexart}
\usepackage{jiazhu}
\jiazhuset { opening = 〔 , closing = 〕 , shortcut = | }
\newcommand*\ideographht{220/256}
\newcommand*\ideographdp{36/256}
\usepackage{etoolbox}
\ExplSyntaxOn
\makeatletter
% 第一处修改,夹注内默认零行间距
\patchcmd\__jiazhu_boot:nn
{%
\exp_args:Nxx \fontsize
{ \fp_eval:n { \l__jiazhu_ratio_fp * \f@size } }
{ \fp_eval:n { \l__jiazhu_ratio_fp * \f@baselineskip } }
}{%
\lineskip = \z@skip
\exp_args:Nxx \fontsize
{ \fp_eval:n { \l__jiazhu_ratio_fp * \f@size } }
{ \fp_eval:n { \l__jiazhu_ratio_fp * \f@size } }
}{}{}
% 第二处修改,计算居中对齐的下移量
\cs_set_protected:Npn \__jiazhu_put_box:N #1
{
\box_move_down:nn
{
\l__jiazhu_unit_dim*\ideographht
- \l__jiazhu_outer_unit_dim*\ideographht
+ (
\l__jiazhu_lines_int \tex_baselineskip:D
- \tex_baselineskip:D
+ \l__jiazhu_outer_unit_dim
- \l__jiazhu_unit_dim
) / 2
}
{ \box_use_drop:N #1 }
}
% 第三处修改,夹注 opening、closing 符号的下移量需要另外计算
\cs_new_protected:Npn \__jiazhu_put_punct_box:N #1
{
\box_move_down:nn
{
\fp_eval:n
{ \l__jiazhu_bracket_ratio_fp * ( \ideographht - 0.5 ) }
\l__jiazhu_unit_dim
- \l__jiazhu_outer_unit_dim*\ideographht
+ \l__jiazhu_outer_unit_dim / 2
}
{ \box_use_drop:N #1 }
}
\patchcmd\__jiazhu_put_opening_box:
{%
\__jiazhu_put_box:N
}{%
\__jiazhu_put_punct_box:N
}{}{}
\patchcmd\__jiazhu_put_closing_box:
{%
\__jiazhu_put_box:N
}{%
\__jiazhu_put_punct_box:N
}{}{}
% 画一个黑色的全角方块
\patchcmd\__jiazhu_boot:nn
{%
\hbox_set:Nn \l__jiazhu_text_box { #2 \tex_unskip:D }
}{%
\hbox_set:Nn \l__jiazhu_text_box
{
\rule[-\dimexpr\f@size\p@*\ideographdp\relax]{\f@size\p@}{\f@size\p@}
#2
\tex_unskip:D
}
}{}{}
% 画正文底线、顶线、中线
\newcommand*\drawbounds{%
\leavevmode
\hbox to\z@{%
\hss
\rule[-\dimexpr\f@size\p@*\ideographdp\relax]{5in}{\dimexpr\f@size\p@/64\relax}%
\hss
}%
\hbox to\z@{%
\hss
\rule[\dimexpr\f@size\p@*\ideographht-\f@size\p@/64\relax]{5in}{\dimexpr\f@size\p@/64\relax}%
\hss
}%
\hbox to\z@{%
\hss
\rule[\dimexpr(\f@size\p@*\ideographht-\f@size\p@*\ideographdp)/2-\f@size\p@/128\relax]{5in}{\dimexpr\f@size\p@/64\relax}%
\hss
}%
}
\cs_if_exist_use:NT \xeCJKsetup
{ { AllowBreakBetweenPuncts } }
\makeatother
\ExplSyntaxOff
\begin{document}
\setlength\parskip{10pt}
世祖光武皇帝讳秀,字文叔,|{测礼“{祖有功而宗有德}”,光武中兴,故庙称世祖。谥法:“能绍前业曰光,克定祸乱曰武。”伏侯古今注曰:“秀之字曰茂。伯、仲、叔、季,兄弟之次。长兄伯升,次仲,故字文叔焉。”}南阳\drawbounds 蔡阳人,|{南阳,郡,今邓州县也。蔡阳,县,故城在今随州枣阳县西南。}高祖九世之孙也,
\jiazhuset { format = \linespread{1.5} }
世祖光武皇帝讳秀,字文叔,|{测礼“{祖有功而宗有德}”,光武中兴,故庙称世祖。谥法:“能绍前业曰光,克定祸乱曰武。”伏侯古今注曰:“秀之字曰茂。伯、仲、叔、季,兄弟之次。长兄伯升,次仲,故字文叔焉。”}南阳\drawbounds 蔡阳人,|{南阳,郡,今邓州县也。蔡阳,县,故城在今随州枣阳县西南。}高祖九世之孙也,
\jiazhuset { format = {} , lines = 3 }
世祖光武皇帝讳秀,字文叔,|{测礼“{祖有功而宗有德}”,光武中兴,故庙称世祖。谥法:“能绍前业曰光,克定祸乱曰武。”伏侯古今注曰:“秀之字曰茂。伯、仲、叔、季,兄弟之次。长兄伯升,次仲,故字文叔焉。”}南阳\drawbounds 蔡阳人,|{南阳,郡,今邓州县也。蔡阳,县,故城在今随州枣阳县西南。}高祖九世之孙也,
\jiazhuset { ratio=0.6 , lines = 2 }
世祖光武皇帝讳秀,字文叔,|{测礼“{祖有功而宗有德}”,光武中兴,故庙称世祖。谥法:“能绍前业曰光,克定祸乱曰武。”伏侯古今注曰:“秀之字曰茂。伯、仲、叔、季,兄弟之次。长兄伯升,次仲,故字文叔焉。”}南阳\drawbounds 蔡阳人,|{南阳,郡,今邓州县也。蔡阳,县,故城在今随州枣阳县西南。}高祖九世之孙也,
\end{document}
@qinglee 基线(或者中线)的对齐问题是这段代码引入的: https://github.com/CTeX-org/ctex-kit/blob/4ab8fa717a6c572238200274f689f9f4929e72b4/jiazhu/jiazhu.dtx#L504-L509
其中这个 hard-coded 的
0.8
是经验值,应该提供用户接口。
- 直排模式下,这个值应该统一修改为
0.5
;- 横排模式下,不同字体的汉字字框高度是不一样的,思源系列应该是
0.88
,中易系列应该是0.859375
,华文系列才是0.8
。- 凡是跟
\strutbox
相关的代码也需要留意,针对西文优化的\strut
不一定跟汉字中线居中对齐。
确实,当时写到这里的时候就知道中线对齐会有问题,0.8
只是图方便取的一个值,这个值依赖于字体。
可以提供选项让用户自行设置 \ideographht
和 \ideographdp
。但这对一般用户来说,设置这些值,可能有些困难。也许我们可以像 pLaTeX 设置 \Cht
和 \Cdp
一样,选一个汉字作为标志,把它放入盒子中,实际量取他的高度和深度,作为字体的数据,自动调整 \ideographht
和 \ideographdp
。
总算推出来了,不仅夹注文字居中,夹注前后追加的括弧也居中:
……
非常感谢!把你加入共同作者了,你如果有时间和兴趣,可以直接在 dtx
里修改。
@qinglee pLaTeX 的 \Cht
、\Cdp
是基于 JFM (pTeX-extended TFM) 的参数,每一个 ideograph 都有统一的高度、深度,这个参数度量的是「字框」。
一旦转到 OpenType 字体,参数就不一致了。这时,引擎直接读取「字面」的高度、深度,也就是说每个字的高度、深度都不一样,加起来的总高度也比字框的总高度要小。参见 https://github.com/CTeX-org/ctex-kit/issues/464#issuecomment-563459255
也就是说,在 XeTeX、LuaTeX 下,「选定标准字测量、再计算」这个方法不可靠。
常用字体的 \ideographht
、\ideographdp
值可以通过表格形式写进用户手册(华文、中易、Adobe 各自的产品相对统一,方正的则高矮不一),也当趁机「推广排印教育」,鼓励用户「去了解、去设置」。
@RuixiZhang42 luatexja 也模拟了 pTeX 的 JFM,每一个汉字都被打包到盒子里,设置好统一的高度和深度后再输出,所以对 pTeX 和 luateja 来说,汉字的高度和深度是由 JFM 决定的,跟字体关系不大,也就是说我们的测量结果不可靠。
XeTeX 可以设置 \XeTeXuseglyphmetrics
为零,让所有的汉字也使用统一的字框,但由此测量产生的结果好像不能反映字体的真实情况,也不可靠。
@qinglee 其实,我在想可不可以用中文字体里面的 U+2588
(Full Block) 作为可靠的度量……
修改的代码还得多调一会儿,今天试排思源字体出了点小问题,不过计算公式应该是没错的,这周有空就 push。直排调 \ideographht
为 0.5
大概这样:
@RuixiZhang42 还是别选特征字度量了,直接让用户设置 \ideographht
好了。
公式我也细看了,应该没问题。
最新的 jiazhu 中,夹注前后的括号放大了 2.5 倍,但好像并未居中,而是底部对齐的?
最新的 jiazhu 中,夹注前后的括号放大了 2.5 倍,但好像并未居中,而是底部对齐的?
抱歉,括号是相对正文居中对齐的,只不过是中易宋体的基线位置较低,默认的 ideographht = 0.8
与中易宋体不搭配造成夹注位置偏低,让括号看起来像是底部对齐了一样。
按下图
夹注前后括号应该刚好是夹注字号的两倍,而夹注字号不一定需要是正文字号的二分之一,如图中正文字号 9 点,夹注字号 6 点,前后括号字号 12 点,对应的
jiazhuset
应该是 ratio = 0.6667 , bracketratio = 2
,也许应该把 bracketratio = 2
设为默认值?
@tanukihee 之前预设 ideographht=0.88
,现在改为预设 ideographht=0.5
供直排用。横排数值请参考用户手册 ideographht
那部分的表格。
之前预设的 ratio=0.5
的确太小了(正文五号,夹注只有 5.25bp),也很影响页面灰度。现在改为预设 ratio=2/3
(正文五号,夹注 7bp)。bracketratio
也相应地改为预设 2
。
baselineshift
有 bug,有了新的对齐算法之后也没啥用了,未来(即发布前)可能会移除。
@RuixiZhang42 baselineshift
本意不是解决这里的对齐问题。
按照目前的实现,夹注前后的正文其实是放在不同的段落的,大概示意如下:
夹注前正文$$通过 \predisplaysize 获取前一行的剩余宽度$$\jiazhu{夹注}夹注后正文
前后的正文行距可能不统一,比如极端的例子:
夹注前正文\jiazhu{夹注}夹注后\rule{0pt}{20pt}正文
当然,这里是为了示意生造的例子,正常情况下不会出现这种情况,但我觉得保留一个调整的接口还是必要的。
@qinglee 原来如此!是我理解有误,以为 baselineshift
本意是仅仅为了调整夹注的位置而已……
这样看来,设了 baselineshift
的效果就应该是后面的正文一起被移,所以是个 feature 而不是 bug……这个生造的例子可以换个包装出现在用户手册里~~
两个问题想请教一下
opening
与 closing
的括号的前提下,beforeskip
与 afterskip
的距离是从哪里开始,如何计算的?beforeskip
与 afterskip
的长度若为相对长度,是相对于什么的长度?通过粗略观察,在 xeCJK
下,距离计算是从被「彻底削掉空白」后的括号边缘开始计算,而 luatexja
下是从半宽括号开始计算的。
代码与效果图如下,其中画字框借鉴了@RuixiZhang42 先生在 #488 中的代码
xe
\documentclass{ctexart}
\usepackage{jiazhu}
\jiazhuset{
beforeskip = 0\ccwd,
afterskip = 1\ccwd,
ratio = 1/2,
ideohtratio = 0.88
}
\setCJKmainfont{Source Han Serif CN}
\usepackage{xcolor}
\setlength{\fboxrule}{0.15625pt}
\setlength{\fboxsep}{-\fboxrule}
\newcommand*{\cstrut}{\rule[\dimexpr-1em*120/1000\relax]{0pt}{1em}}
\newcommand*{\drawfwbox}{\textcolor[HTML]{9999FF}{\fbox{\cstrut\quad}}}
\newcommand*{\drawhwbox}{\textcolor[HTML]{9999FF}{\fbox{\cstrut\enskip}}}
\begin{document}
\leavevmode\rlap{%
\drawfwbox
\drawfwbox
\drawhwbox
\drawfwbox
}%
正文\jiazhu[opening = (]{夹注夹注}
\leavevmode\rlap{%
\drawfwbox
\drawfwbox
\drawfwbox
\drawfwbox
}%
\jiazhu[closing = )]{夹注夹注}正文
\end{document}
lua
\documentclass{ltjarticle}
\usepackage{jiazhu}
\jiazhuset{
beforeskip = 0\zw,
afterskip = 1\zw,
ratio = 1/2,
ideohtratio = 0.88
}
\usepackage{luatexja-fontspec}
\setmainjfont{Source Han Serif CN}
\usepackage{xcolor}
\setlength{\fboxrule}{0.15625pt}
\setlength{\fboxsep}{-\fboxrule}
\newcommand*{\cstrut}{\rule[\dimexpr-1\zw*120/1000\relax]{0pt}{1\zw}}
\newcommand*{\drawfwbox}{\textcolor[HTML]{9999FF}{\fbox{\cstrut\hspace{1\zw}}}}
\newcommand*{\drawhwbox}{\textcolor[HTML]{9999FF}{\fbox{\cstrut\hspace{0.5\zw}}}}
\begin{document}
\leavevmode\rlap{%
\drawfwbox
\drawfwbox
\drawhwbox
\drawfwbox
}%
正文\jiazhu[opening = (]{夹注夹注}
\leavevmode\rlap{%
\drawfwbox
\drawfwbox
\drawfwbox
\drawfwbox
}%
\jiazhu[closing = )]{夹注夹注}正文
\end{document}
(从
lua-visual-debug
中看,luatexja
似乎还会对夹注汉字间进行压缩?而且行距也被撑开了)
插空盒子后效果如下
可见的确是从半宽括号开始计算的
同样可看出,若在 beforeskip
与 afterskip
中使用相对长度,似乎是相对于夹注字号的长度(虽然 afterskip = 1\ccwd
,但 ratio = 1/2
,图中表现出宽度只有正文字号宽度的一半),这一点要不要在文档里说明一下?
kanjiskip
的初始设置是 \z@ plus .4pt minus .5pt
,有 shrink 部分,按 jiazhu 的实现,可能会导致夹注汉字间距被压缩。@tanukihee 建议新的「提议」、「问题」另开 issue,也方便 commit 做 reference……这个关于 beforeskip/afterskip
的问题就不用新开了,留在这里吧……
拓展一下 @qinglee 的回答:
xeCJK
重构会涉及到「opening+偏右半边」这种标点,如果我们最后决定「统一抹掉左边二分空」而不是现在的「抹掉全部空白」,那么 xeCJK
和 luatexja
会更相似。beforeskip/afterskip
此时也不应该有正值。既然都没有了,也不会纠结相对于哪个 em 了。需要注意的一点是,「xeCJK
和 luatexja
100% 一致」是很困难的(很多东西涉及到 primitive,在引擎层面就不一致了),更主要的是没有这个必要。就像 kanjiskip
允许收缩这种设定,用在假名、少量汉字的日文里合适,用在几乎全汉字的中文(尤其是繁体中文)里就不合适。
谢谢回答,主要是我能猜出部分来,就没有新开了,只是验证一下 总之谢谢 @qinglee 与 @RuixiZhang42 的解答!
代码:
效果如图
可见夹注内行距过宽,且整体偏右。
而横排时效果很好