CTeX-org / forum

A temporarily alternate forum of `bbs.ctex.org`
https://t.me/chinesetex
Apache License 2.0
211 stars 16 forks source link

关于ulem包与xeCJKfntef包连用hyperref包进行超链接下划线的疑惑 #327

Closed Mikachu2333 closed 1 month ago

Mikachu2333 commented 1 month ago

检查清单

操作系统

Linux(ubuntu 22.04.4 LTS)

TeX 发行版

Tex Live 2024

描述问题

  1. 我希望为 hyperref 包的超链接命令 \href{url}{text} 增加下划线
  2. 我尝试了 ulem 包的 \uline{} 命令,但发现其不能自动换行
  3. 我检索了已有issue,发现了关于 xeCJKfntef 的推荐
  4. 我尝试使用 \CJKunderline{} 替换 \uline{},但意外地发现竟然连英文也无法自动换行了
  5. 检索过程中我发现 hyperref 包本身自带有下划线命令,但是对CJK支持过于拉胯……

请问:

  1. 是否有其他办法能够改善 hyperref 包的输出?(优先精简依赖)
  2. 如果无法做到1,那么是否有其他办法能够帮助 \uline{} 命令实现CJK的自动换行下划线?
  3. 如果无法做到2,那么是否有其他方法能使 \CJKunderline{} 正确运行?

附:

最小工作示例(MWE)

% !TeX encoding = UTF-8
% !TEX TS-program = xelatex
\documentclass[a4paper,oneside,onecolumn,12pt]{ctexrep}
\usepackage{ulem}
\usepackage{xeCJKfntef}
\usepackage[final=true]{hyperref}

\begin{document}
\CJKunderline{This is a line aims to test the support of CJKunderline when linebreaking. This is a line aims to test the support of CJKunderline when linebreaking.}
%注,上面出现了Overfull hbox

\CJKunderline{这是一行文字,目的是测试CJKunderline在CJK文字换行时的表现。这是一行文字,目的是测试CJKunderline在CJK文字换行时的表现。}

\bigbreak

\uline{This is a line aims to test the CJK support of uline when linebreaking. This is a line aims to test the CJK support of uline when linebreaking.}

\uline{这是一行文字,目的是测试uline在CJK文字换行时的表现。这是一行文字,目的是测试uline在CJK文字换行时的表现。}

\bigbreak

\href{https://github.com}{This is a line aims to test the CJK support of href when linebreaking. This is a line aims to test the CJK support of href when linebreaking.}

\href{https://github.com}{这是一行文字,目的是测试hyperref在CJK文字换行时的表现。这是一行文字,目的是测试hyperref在CJK文字换行时的表现。}

\bigbreak

\CJKunderline{\href{https://github.com}{This is a line aims to test the support of CJKunderline when linebreaking. This is a line aims to test the support of CJKunderline when linebreaking.}}
%注,上面出现了Overfull hbox

%\CJKunderanyline{这是一行文字,目的是测试CJKunderanyline在CJK文字换行时的表现。这是一行文字,目的是测试CJKunderanyline在CJK文字换行时的表现。}
%注:直接报错,href命令连试都免了

\bigbreak

\uline{\href{https://github.com}{This is a line aims to test the support of uline when linebreaking. This is a line aims to test the support of uline when linebreaking.}}
%\uline{\href{https://github.com}{这是一行文字,目的是测试uline在CJK文字换行时的表现。这是一行文字,目的是测试uline在CJK文字换行时的表现。}}
%注:报错

\end{document}

其他日志见附件

链接

其他信息

No response

附件

uline_error.log xecjk_uline_error.log

Mikachu2333 commented 1 month ago
20240731_23-38-12
Mikachu2333 commented 1 month ago

更新:刚刚 hyperref 来了消息,说是由于xelatex导致的问题,可以换用lualatex看看,目前发现lualatex配合hyperhref可以临时解决我的问题,不过我还是想暂时让issue开着,因为自己也确实好奇其他的问题是否有解决方案……

https://github.com/latex3/hyperref/issues/349

muzimuzhi commented 1 month ago

5. 检索过程中我发现 hyperref 包本身自带有下划线命令,但是对CJK支持过于拉胯……

首先,建议总是具体描述问题(下划线高度不对、表现为横穿文字),不要只定性评价(这里的「过于拉垮」)。

试了试,这更像是 FandolSong 字体的问题。Fandol 系列的其他字体和 macOS 内置的 STSong 都没这个问题。@clerkma

% !TeX program = xelatex
\documentclass{article}
\usepackage{fontspec}
\usepackage[urlbordercolor={0 0 0},pdfborderstyle={/S/U/W 1}]{hyperref}

\NewDocumentCommand{\test}{ m }{%
  {\fontspec{#1}%
  \noindent Font: #1\par
  正常文字\href{https://github.com/latex3/hyperref}{测试测试测试}正常文字\par}}

\begin{document}
\noindent Font: Latin Modern Roman\par
Normal Text \href{https://github.com/latex3/hyperref}{test test test} normal text\par

\test{FandolSong}
\test{FandolFang}
\test{FandolHei}
\test{FandolKai}
\end{document}

image

Mikachu2333 commented 1 month ago

试了试,这更像是 FandolSong 字体的问题。Fandol 系列的其他字体和 macOS 内置的 STSong 都没这个问题。@clerkma

似乎确实如此。补充:梦源宋体系列也有此问题,不过表现的不如FandolSong明显,只是下划线距离文字的宽度不均一。


另:今天发现了昨天解决方案的另一个大毛病,在全局设置hyperref宏包后,目录和脚注、表注都有一道下划线,找了一堆doc看也没能找到解决方案,似乎还是得继续加个package用……

% !TeX encoding = UTF-8
% !TEX TS-program = xelatex
\documentclass[a4paper,oneside,onecolumn,12pt,fontset=none]{ctexrep}
\usepackage[colorlinks=false,allbordercolors={0 0 0},pdfborderstyle={/S/U/W 1}]{hyperref}

\setmainfont[BoldFont=Source Han Serif SC]{Source Han Serif SC}
\setCJKmainfont{Source Han Serif SC}[BoldFont=Source Han Serif SC]
\setCJKsansfont[BoldFont=Source Han Serif SC]{Source Han Serif SC}

\begin{document}
This is a line to test footnote\footnotemark and \hyperref[aaa]{ref}.
\footnotetext{这是脚注。}

\bigbreak
{
    \label{aaa}
    这是引用的内容。
}

\end{document}
Mikachu2333 commented 1 month ago

更新,图片如下:

20240801_11-27-53
muzimuzhi commented 1 month ago

不像选项 <TYPE>color (link color) 和 <TYPE>bordercolor (border color) 可以为每一 <TYPE> 单独设置,

<TYPE> ::= "cite" | "file" | "link" | "menu" | "run" | "url"

选项 pdfborderstyle 对所有类型都生效,没有只修改单一类型的选项。你可以定义新命令,只为需要加下划线的 \href{<url>}{<text>} 局部设置 \hypersetup{...}

LaTeX3 团队开发中的 pdfmanagement (texdoc pdfmanagement-testphase) 的 l3pdfannot 模块为每种链接都提供了 hook (texdoc l3pdfannot, sec. 1.4 Link annotations),可以更自由地按类别设置样式。(l3pdfannot 里的「样式」列表沿用了 PDF Specification 里的名称,和 hyperref 里的不同。)一个例子见 https://github.com/latex3/hyperref/issues/195#issuecomment-875004675

% !TeX program = xelatex
\DocumentMetadata{}
\documentclass{article}
\usepackage{fontspec}
\usepackage{hyperref}

\NewDocumentCommand{\test}{ m }{%
  {\fontspec{#1}%
  \noindent Font: #1\par
  正常文字\href{https://github.com/latex3/hyperref}{测试测试测试}正常文字\par}}

\AddToHook{pdfannot/link/URI/before}{\hypersetup{urlbordercolor=,pdfborderstyle={/S/U/W 1}}}

\begin{document}
\tableofcontents
\section{title}
Text\footnote{text}

\noindent Font: Latin Modern Roman\par
Normal Text \href{https://github.com/latex3/hyperref}{test test test} normal text\par

\test{FandolSong}
\test{FandolFang}
\test{FandolHei}
\test{FandolKai}
\end{document}

image

注意,pdfmanagement 修改了超链接的默认 border color,见 texdoc pdfmanagement-testphase, sec. 7.1 hyperref.

Mikachu2333 commented 1 month ago

非常感谢您的耐心解答!因为我还是一个latex新手,并未开始涉猎关于hook与latex编译具体实现的部分,看到您的回答以后才刚开始看 lthooks 的相关文档,部分hook的内容没法彻底理解,所以暂时就直接简单改下照搬了 (TヘT)

再次感谢!

Mikachu2333 commented 1 month ago

不像选项 <TYPE>color (link color) 和 <TYPE>bordercolor (border color) 可以为每一 <TYPE> 单独设置,

<TYPE> ::= "cite" | "file" | "link" | "menu" | "run" | "url"

选项 pdfborderstyle 对所有类型都生效,没有只修改单一类型的选项。你可以定义新命令,只为需要加下划线的 \href{<url>}{<text>} 局部设置 \hypersetup{...}

LaTeX3 团队开发中的 pdfmanagement (texdoc pdfmanagement-testphase) 的 l3pdfannot 模块为每种链接都提供了 hook (texdoc l3pdfannot, sec. 1.4 Link annotations),可以更自由地按类别设置样式。(l3pdfannot 里的「样式」列表沿用了 PDF Specification 里的名称,和 hyperref 里的不同。)一个例子见 latex3/hyperref#195 (comment)

% !TeX program = xelatex
\DocumentMetadata{}
\documentclass{article}
\usepackage{fontspec}
\usepackage{hyperref}

\NewDocumentCommand{\test}{ m }{%
  {\fontspec{#1}%
  \noindent Font: #1\par
  正常文字\href{https://github.com/latex3/hyperref}{测试测试测试}正常文字\par}}

\AddToHook{pdfannot/link/URI/before}{\hypersetup{urlbordercolor=,pdfborderstyle={/S/U/W 1}}}

\begin{document}
\tableofcontents
\section{title}
Text\footnote{text}

\noindent Font: Latin Modern Roman\par
Normal Text \href{https://github.com/latex3/hyperref}{test test test} normal text\par

\test{FandolSong}
\test{FandolFang}
\test{FandolHei}
\test{FandolKai}
\end{document}

image

注意,pdfmanagement 修改了超链接的默认 border color,见 texdoc pdfmanagement-testphase, sec. 7.1 hyperref.

还是不能关issue啊 :rofl:

今天研究了半天,发现您发的办法2,采用hook时不可取的,因为/ref/footnote属于同一类型(GoTo)。即,如果使用了 \AddToHook{pdfannot/link/GoTo/before}{\hypersetup{urlbordercolor=black,pdfborderstyle={/S/U/W 1}}} 命令,则页脚在正文部分的数字上标和正常在正文中\ref的部分都会变成一样的格式,而我恰恰不希望页脚的数字出现任何的额外格式……

所以说最后还是得回到自定义命令上去……(但是自己自定义命令以后又得考虑特殊符号的处理,真的是重复造轮子了……),所以最后我给它又开了个issue https://github.com/latex3/hyperref/issues/350

muzimuzhi commented 1 month ago
  1. 我希望为 hyperref 包的超链接命令 \href{url}{text} 增加下划线

采用hook时不可取的,因为/ref/footnote属于同一类型(GoTo)

你的真实需求,是「给 \href{<url>}{<text>} 排版结果加下划线」和「只给 \ref{<label>} 的排版内容加下划线」的哪种组合?

Mikachu2333 commented 1 month ago

啊,抱歉,这个地方没说明白。

一开始确实是只是想给\href{}{}加个下划线,结果发现hyperref宏包似乎有机会能支持给\hyperref[]{}加下划线所以增加了需求

目前的需求是希望仅使用hyperref一个package实现\href{}{}\hyperref[]{}都显示为下划线,而\footnote{}\footnotemark、目录中不显示下划线

结果发现似乎有些天方夜谭了 (눈▂눈)

Mikachu2333 commented 1 month ago

果然还是回到自定义命令上来吧……相对简便易行一些

此法最大的好处就是无须担忧相同类型链接的自动生成导致的格式问题,例如前面提到的hook,正文没问题了但是自动生成的目录又出了下划线……这样只有在手动调用时才会生成下划线,平时啥也没有就好了

代码见下方链接: https://github.com/latex3/hyperref/issues/350#issuecomment-2266358654

Mikachu2333 commented 3 weeks ago

好吧,上面的实现方式还是有一点小问题,在底部脚注中使用 \uref{}{} 的话下划线与文字的距离会奇怪地增大……

还是换回了老传统的ulem……

\newcommand{\uhref}[2]{%
\uline{\href{#1}{#2}}%
}
\newcommand{\uref}[1]{%
\uline{\ref{#1}}%
}