From nobody Thu Oct 2 18:15:59 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8D27531A554; Fri, 12 Sep 2025 14:27:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757687250; cv=none; b=SaAXn13+mG2ArjaDdv/99fR24iWgy5FII+aiRMP8ytngwQ3M1pYbIh5Fg1D7KO1yrg/JT9XuVuJ9GjQrBe7B8wGhHnbft9Wul7aQb2vELqvs98wReJ3TSmtA/pEn6NSNSCHkB0AwX8Hl+HuhPMH2zHoS67YG5D2JcOP2MvKx9/g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757687250; c=relaxed/simple; bh=klu+M+ZZ2Kd0Ga6TJk6qCeHC8u16TFHw6n/IkUvD2uc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=L45bs+Uvv0rDAWov8I/EZOkDwvtqRKMr+aFqRwHyXyQ41LJUG8ezcH8z8qTWVafalaF8huV6Hru+zNGZKZdg9ZJ060y+tGYprbefYYVp7e324ZSssFAwmX048TSxs8ZINahWyUs0P7lRsd6dAaUMm05+1uVXzBYF+UWbWPswOSA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=S1i6e29N; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="S1i6e29N" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 30C8EC4CEF9; Fri, 12 Sep 2025 14:27:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757687250; bh=klu+M+ZZ2Kd0Ga6TJk6qCeHC8u16TFHw6n/IkUvD2uc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=S1i6e29N3reelSH2BGrZTonAhkkJo0PiFXN4XhIttTCvCvINhVoqtExzhT/5oLuAr E/Ey/SVd76q8Ezkol0KyLSREKKKKI+d7VfDQtLmubneoRPB2JPQ4ImGpry00YkfgIP ojaUdZNDdc3rQ7aTxmZxG+iQwlVuDJoqo3QeoI33AwwNQwvgvrfEDi4Bvm8cXanvz2 D/3OeXNdowJrjILPI1z3FDlfhl0w1f4PEuT23RGRz5uQZTrCh7mNakeC3o0yO64dRG sB6i67Xx8mYkXv2b+NxpNO/eBJhTOCI0ECMZ14i4eMMqRIgICIbIKsLbQ2sFom796h M07yvrtVzxTtw== Received: from mchehab by mail.kernel.org with local (Exim 4.98.2) (envelope-from ) id 1ux4kK-00000008VrJ-1DkU; Fri, 12 Sep 2025 16:27:28 +0200 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , Akira Yokosawa , linux-kernel@vger.kernel.org Subject: [PATCH 1/3] scripts/check-variable-fonts.sh: convert to Python Date: Fri, 12 Sep 2025 16:27:20 +0200 Message-ID: <4fd882d4681f37f474aa771ecfea6e95df6be21c.1757685692.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: References: Content-Type: text/plain; charset="utf-8" Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab This script handle errors when trying to build translations with make pdfdocs. As part of our cleanup work to remove hacks from docs Makefile, convert this to python, preparing it to be part of a library to be called by sphinx-build-wrapper. Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 2 +- ...iable-fonts.sh =3D> check-variable-fonts.py} | 104 +++++++++++++----- 2 files changed, 78 insertions(+), 28 deletions(-) rename scripts/{check-variable-fonts.sh =3D> check-variable-fonts.py} (61%) diff --git a/MAINTAINERS b/MAINTAINERS index 06bbed30b788..8cc14c85fdf5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7301,7 +7301,7 @@ S: Maintained P: Documentation/doc-guide/maintainer-profile.rst T: git git://git.lwn.net/linux.git docs-next F: Documentation/ -F: scripts/check-variable-fonts.sh +F: scripts/check-variable-fonts.py F: scripts/checktransupdate.py F: scripts/documentation-file-ref-check F: scripts/get_abi.py diff --git a/scripts/check-variable-fonts.sh b/scripts/check-variable-fonts= .py similarity index 61% rename from scripts/check-variable-fonts.sh rename to scripts/check-variable-fonts.py index ce63f0acea5f..71b88b680a73 100755 --- a/scripts/check-variable-fonts.sh +++ b/scripts/check-variable-fonts.py @@ -1,7 +1,9 @@ -#!/bin/sh +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0-only # Copyright (C) Akira Yokosawa, 2024 # +# Ported to Python by (c) Mauro Carvalho Chehab, 2025 +# # For "make pdfdocs", reports of build errors of translations.pdf started # arriving early 2024 [1, 2]. It turned out that Fedora and openSUSE # tumbleweed have started deploying variable-font [3] format of "Noto CJK" @@ -87,29 +89,77 @@ # Denylisting should be less invasive, as it is effective only while # XeLaTeX runs in "make pdfdocs". =20 -# Default per-user fontconfig path (overridden by env variable) -: ${FONTS_CONF_DENY_VF:=3D$HOME/deny-vf} - -export XDG_CONFIG_HOME=3D${FONTS_CONF_DENY_VF} - -notocjkvffonts=3D`fc-list : file family variable | \ - grep 'variable=3DTrue' | \ - grep -E -e 'Noto (Sans|Sans Mono|Serif) CJK' | \ - sed -e 's/^/ /' -e 's/: Noto S.*$//' | sort | uniq` - -if [ "x$notocjkvffonts" !=3D "x" ] ; then - echo '=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D' - echo 'XeTeX is confused by "variable font" files listed below:' - echo "$notocjkvffonts" - echo - echo 'For CJK pages in PDF, they need to be hidden from XeTeX by denylist= ing.' - echo 'Or, CJK pages can be skipped by uninstalling texlive-xecjk.' - echo - echo 'For more info on denylisting, other options, and variable font, see= header' - echo 'comments of scripts/check-variable-fonts.sh.' - echo '=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D' -fi - -# As this script is invoked from Makefile's error path, always error exit -# regardless of whether any variable font is discovered or not. -exit 1 +import os +import re +import subprocess +import sys +import textwrap + +class LatexFontChecker: + """ + Detect problems with CJK variable fonts that affect PDF builds for + translations. + """ + + def __init__(self): + deny_vf =3D os.environ.get('FONTS_CONF_DENY_VF', "~/deny-vf") + + self.environ =3D os.environ.copy() + self.environ['XDG_CONFIG_HOMEF'] =3D os.path.expanduser(deny_vf) + + self.re_cjk =3D re.compile(r"([^:]+):\s*Noto\s+(Sans|Sans Mono|Ser= if) CJK") + + def get_noto_cjk_vf_fonts(self): + """Get Noto CJK fonts""" + + cjk_fonts =3D set() + cmd =3D ["fc-list", ":", "file", "family", "variable"] + try: + result =3D subprocess.run(cmd,stdout=3Dsubprocess.PIPE, + stderr=3Dsubprocess.PIPE, + universal_newlines=3DTrue, + env=3Dself.environ, + check=3DTrue) + + except subprocess.CalledProcessError as exc: + sys.exit(f"Error running fc-list: {repr(exc)}") + + for line in result.stdout.splitlines(): + if 'variable=3DTrue' not in line: + continue + + match =3D self.re_cjk.search(line) + if match: + cjk_fonts.add(match.group(1)) + + return sorted(cjk_fonts) + + def check(self): + """Check for problems with CJK fonts""" + + fonts =3D textwrap.indent("\n".join(self.get_noto_cjk_vf_fonts()),= " ") + if not fonts: + return None + + rel_file =3D os.path.relpath(__file__, os.getcwd()) + + msg =3D "=3D" * 77 + "\n" + msg +=3D 'XeTeX is confused by "variable font" files listed below:= \n' + msg +=3D fonts + "\n" + msg +=3D textwrap.dedent(f""" + For CJK pages in PDF, they need to be hidden from XeTeX by= denylisting. + Or, CJK pages can be skipped by uninstalling texlive-xecjk. + + For more info on denylisting, other options, and variable = font, see header + comments of {rel_file}. + """) + msg +=3D "=3D" * 77 + + return msg + +if __name__ =3D=3D "__main__": + msg =3D LatexFontChecker().check() + if msg: + print(msg) + + sys.exit(1) --=20 2.50.1 From nobody Thu Oct 2 18:15:59 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B341D242930; Fri, 12 Sep 2025 14:27:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757687250; cv=none; b=Ce0kWjR4OVq89+xWZT3N08ziTEBFjXIwC78Nke+t6ENSgiXg+DIyp27EFuG1eGFc8JynazWY70HuGyorPZJxwu2OFU/s/0wS+noHNPYDyKeFOYNsYzo+KMTcG8P3Dg5QSaMwmzBBuHd6IqUeYinAQqBsttnJMM6Ap1mJoPf0wDA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757687250; c=relaxed/simple; bh=bRXD+/xhUmvs2LfVdiulK3PDsb6VybJ4BlQnxqAQJ/A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=AdxM3uwxF3Z8t7w0rtafvOJbDuxWvlIWn2kZTAP+FA9U/0ISRf29sODtT6Pv42pTn9/bCF5hF2xO93H0kprmS8hi1JkOh4KGYM7wE6lfZDWsFhCHSMFcZXb3x6XvQ62Ibb7EKIPHg0Iok3rU4o4sClI2YtAxYiUXI76M3ZejjVE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=e9fjZeHk; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="e9fjZeHk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2CED7C4CEF1; Fri, 12 Sep 2025 14:27:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757687250; bh=bRXD+/xhUmvs2LfVdiulK3PDsb6VybJ4BlQnxqAQJ/A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e9fjZeHkLc5HM4tsY0h/6H67VrhZ82/c/A2yWZyRKVQ+mu3KiLng75ufn1DUgkEvo VDTR3g+GivAu99+zEM4RM12+fBKghnfiQqoDSy8/EI1Ff1VWQcwZI/iwn/FjbiYuRa BcrLhCfL4bXKI1/caXtmddvUWswiJP3HMMIoHtNCJfntivkxMLepwvoI/VzfOXcJXY MAI5FN5WpnKFiuamYsbel/cNmsOwlATfXx5mChXS+RFt2TDl4pLb4GjvXnQgGX+aY+ 7M7wpzwWaWcrgT0QwtfkEWtCUdnrGGU9sBEcqAFVoG+OFI3qbABIj6eosH7WcfMKz0 pRFfOlVYs84Aw== Received: from mchehab by mail.kernel.org with local (Exim 4.98.2) (envelope-from ) id 1ux4kK-00000008VrN-1KU9; Fri, 12 Sep 2025 16:27:28 +0200 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , Akira Yokosawa , linux-kernel@vger.kernel.org Subject: [PATCH 2/3] scripts: check-variable-fonts.py: split into a lib and an exec file Date: Fri, 12 Sep 2025 16:27:21 +0200 Message-ID: <82746b6ff491fe8a07d4b0511dc28615b5b3fde4.1757685692.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: References: Content-Type: text/plain; charset="utf-8" Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab As we'll be using the actual code inside sphinx-build-wrapper, split the library from the executable, placing the exec at the new place we've been using: tools/docs No functional changes. Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 1 - scripts/check-variable-fonts.py | 165 ----------------------------- tools/docs/check-variable-fonts.py | 23 ++++ tools/docs/lib/latex_fonts.py | 162 ++++++++++++++++++++++++++++ 4 files changed, 185 insertions(+), 166 deletions(-) delete mode 100755 scripts/check-variable-fonts.py create mode 100755 tools/docs/check-variable-fonts.py create mode 100755 tools/docs/lib/latex_fonts.py diff --git a/MAINTAINERS b/MAINTAINERS index 8cc14c85fdf5..16a5d6ab627d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7301,7 +7301,6 @@ S: Maintained P: Documentation/doc-guide/maintainer-profile.rst T: git git://git.lwn.net/linux.git docs-next F: Documentation/ -F: scripts/check-variable-fonts.py F: scripts/checktransupdate.py F: scripts/documentation-file-ref-check F: scripts/get_abi.py diff --git a/scripts/check-variable-fonts.py b/scripts/check-variable-fonts= .py deleted file mode 100755 index 71b88b680a73..000000000000 --- a/scripts/check-variable-fonts.py +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: GPL-2.0-only -# Copyright (C) Akira Yokosawa, 2024 -# -# Ported to Python by (c) Mauro Carvalho Chehab, 2025 -# -# For "make pdfdocs", reports of build errors of translations.pdf started -# arriving early 2024 [1, 2]. It turned out that Fedora and openSUSE -# tumbleweed have started deploying variable-font [3] format of "Noto CJK" -# fonts [4, 5]. For PDF, a LaTeX package named xeCJK is used for CJK -# (Chinese, Japanese, Korean) pages. xeCJK requires XeLaTeX/XeTeX, which -# does not (and likely never will) understand variable fonts for historical -# reasons. -# -# The build error happens even when both of variable- and non-variable-for= mat -# fonts are found on the build system. To make matters worse, Fedora enli= sts -# variable "Noto CJK" fonts in the requirements of langpacks-ja, -ko, -zh_= CN, -# -zh_TW, etc. Hence developers who have interest in CJK pages are more -# likely to encounter the build errors. -# -# This script is invoked from the error path of "make pdfdocs" and emits -# suggestions if variable-font files of "Noto CJK" fonts are in the list of -# fonts accessible from XeTeX. -# -# References: -# [1]: https://lore.kernel.org/r/8734tqsrt7.fsf@meer.lwn.net/ -# [2]: https://lore.kernel.org/r/1708585803.600323099@f111.i.mail.ru/ -# [3]: https://en.wikipedia.org/wiki/Variable_font -# [4]: https://fedoraproject.org/wiki/Changes/Noto_CJK_Variable_Fonts -# [5]: https://build.opensuse.org/request/show/1157217 -# -#=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D -# Workarounds for building translations.pdf -#=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D -# -# * Denylist "variable font" Noto CJK fonts. -# - Create $HOME/deny-vf/fontconfig/fonts.conf from template below, with -# tweaks if necessary. Remove leading "# ". -# - Path of fontconfig/fonts.conf can be overridden by setting an env -# variable FONTS_CONF_DENY_VF. -# -# * Template: -# ----------------------------------------------------------------- -# -# -# -# -# -# -# -# /usr/share/fonts/google-noto-*-cjk-vf-fonts -# -# /usr/share/fonts/truetype/Noto*CJK*-VF.otf -# -# -# -# ----------------------------------------------------------------- -# -# The denylisting is activated for "make pdfdocs". -# -# * For skipping CJK pages in PDF -# - Uninstall texlive-xecjk. -# Denylisting is not needed in this case. -# -# * For printing CJK pages in PDF -# - Need non-variable "Noto CJK" fonts. -# * Fedora -# - google-noto-sans-cjk-fonts -# - google-noto-serif-cjk-fonts -# * openSUSE tumbleweed -# - Non-variable "Noto CJK" fonts are not available as distro packag= es -# as of April, 2024. Fetch a set of font files from upstream Noto -# CJK Font released at: -# https://github.com/notofonts/noto-cjk/tree/main/Sans#super-otc -# and at: -# https://github.com/notofonts/noto-cjk/tree/main/Serif#super-otc -# , then uncompress and deploy them. -# - Remember to update fontconfig cache by running fc-cache. -# -# !!! Caution !!! -# Uninstalling "variable font" packages can be dangerous. -# They might be depended upon by other packages important for your wor= k. -# Denylisting should be less invasive, as it is effective only while -# XeLaTeX runs in "make pdfdocs". - -import os -import re -import subprocess -import sys -import textwrap - -class LatexFontChecker: - """ - Detect problems with CJK variable fonts that affect PDF builds for - translations. - """ - - def __init__(self): - deny_vf =3D os.environ.get('FONTS_CONF_DENY_VF', "~/deny-vf") - - self.environ =3D os.environ.copy() - self.environ['XDG_CONFIG_HOMEF'] =3D os.path.expanduser(deny_vf) - - self.re_cjk =3D re.compile(r"([^:]+):\s*Noto\s+(Sans|Sans Mono|Ser= if) CJK") - - def get_noto_cjk_vf_fonts(self): - """Get Noto CJK fonts""" - - cjk_fonts =3D set() - cmd =3D ["fc-list", ":", "file", "family", "variable"] - try: - result =3D subprocess.run(cmd,stdout=3Dsubprocess.PIPE, - stderr=3Dsubprocess.PIPE, - universal_newlines=3DTrue, - env=3Dself.environ, - check=3DTrue) - - except subprocess.CalledProcessError as exc: - sys.exit(f"Error running fc-list: {repr(exc)}") - - for line in result.stdout.splitlines(): - if 'variable=3DTrue' not in line: - continue - - match =3D self.re_cjk.search(line) - if match: - cjk_fonts.add(match.group(1)) - - return sorted(cjk_fonts) - - def check(self): - """Check for problems with CJK fonts""" - - fonts =3D textwrap.indent("\n".join(self.get_noto_cjk_vf_fonts()),= " ") - if not fonts: - return None - - rel_file =3D os.path.relpath(__file__, os.getcwd()) - - msg =3D "=3D" * 77 + "\n" - msg +=3D 'XeTeX is confused by "variable font" files listed below:= \n' - msg +=3D fonts + "\n" - msg +=3D textwrap.dedent(f""" - For CJK pages in PDF, they need to be hidden from XeTeX by= denylisting. - Or, CJK pages can be skipped by uninstalling texlive-xecjk. - - For more info on denylisting, other options, and variable = font, see header - comments of {rel_file}. - """) - msg +=3D "=3D" * 77 - - return msg - -if __name__ =3D=3D "__main__": - msg =3D LatexFontChecker().check() - if msg: - print(msg) - - sys.exit(1) diff --git a/tools/docs/check-variable-fonts.py b/tools/docs/check-variable= -fonts.py new file mode 100755 index 000000000000..79b28f0f7d85 --- /dev/null +++ b/tools/docs/check-variable-fonts.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) Akira Yokosawa, 2024 +# +# Ported to Python by (c) Mauro Carvalho Chehab, 2025 +# +# pylint: disable=3DC0103 + +""" +Detect problematic Noto CJK variable fonts. + +or more details, see lib/latex_fonts.py. +""" + +import sys + +from lib.latex_fonts import LatexFontChecker + +msg =3D LatexFontChecker().check() +if msg: + print(msg) + +sys.exit(1) diff --git a/tools/docs/lib/latex_fonts.py b/tools/docs/lib/latex_fonts.py new file mode 100755 index 000000000000..e03412e3947e --- /dev/null +++ b/tools/docs/lib/latex_fonts.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) Akira Yokosawa, 2024 +# +# Ported to Python by (c) Mauro Carvalho Chehab, 2025 + +""" +Detect problematic Noto CJK variable fonts. + +For "make pdfdocs", reports of build errors of translations.pdf started +arriving early 2024 [1, 2]. It turned out that Fedora and openSUSE +tumbleweed have started deploying variable-font [3] format of "Noto CJK" +fonts [4, 5]. For PDF, a LaTeX package named xeCJK is used for CJK +(Chinese, Japanese, Korean) pages. xeCJK requires XeLaTeX/XeTeX, which +does not (and likely never will) understand variable fonts for historical +reasons. + +The build error happens even when both of variable- and non-variable-format +fonts are found on the build system. To make matters worse, Fedora enlists +variable "Noto CJK" fonts in the requirements of langpacks-ja, -ko, -zh_CN, +-zh_TW, etc. Hence developers who have interest in CJK pages are more +likely to encounter the build errors. + +This script is invoked from the error path of "make pdfdocs" and emits +suggestions if variable-font files of "Noto CJK" fonts are in the list of +fonts accessible from XeTeX. + +References: +[1]: https://lore.kernel.org/r/8734tqsrt7.fsf@meer.lwn.net/ +[2]: https://lore.kernel.org/r/1708585803.600323099@f111.i.mail.ru/ +[3]: https://en.wikipedia.org/wiki/Variable_font +[4]: https://fedoraproject.org/wiki/Changes/Noto_CJK_Variable_Fonts +[5]: https://build.opensuse.org/request/show/1157217 + +#=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D +Workarounds for building translations.pdf +#=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D + +* Denylist "variable font" Noto CJK fonts. + - Create $HOME/deny-vf/fontconfig/fonts.conf from template below, with + tweaks if necessary. Remove leading "". + - Path of fontconfig/fonts.conf can be overridden by setting an env + variable FONTS_CONF_DENY_VF. + + * Template: +----------------------------------------------------------------- + + + + + + + + /usr/share/fonts/google-noto-*-cjk-vf-fonts + + /usr/share/fonts/truetype/Noto*CJK*-VF.otf + + + +----------------------------------------------------------------- + + The denylisting is activated for "make pdfdocs". + +* For skipping CJK pages in PDF + - Uninstall texlive-xecjk. + Denylisting is not needed in this case. + +* For printing CJK pages in PDF + - Need non-variable "Noto CJK" fonts. + * Fedora + - google-noto-sans-cjk-fonts + - google-noto-serif-cjk-fonts + * openSUSE tumbleweed + - Non-variable "Noto CJK" fonts are not available as distro packages + as of April, 2024. Fetch a set of font files from upstream Noto + CJK Font released at: + https://github.com/notofonts/noto-cjk/tree/main/Sans#super-otc + and at: + https://github.com/notofonts/noto-cjk/tree/main/Serif#super-otc + , then uncompress and deploy them. + - Remember to update fontconfig cache by running fc-cache. + +!!! Caution !!! + Uninstalling "variable font" packages can be dangerous. + They might be depended upon by other packages important for your work. + Denylisting should be less invasive, as it is effective only while + XeLaTeX runs in "make pdfdocs". +""" + +import os +import re +import subprocess +import textwrap +import sys + +class LatexFontChecker: + """ + Detect problems with CJK variable fonts that affect PDF builds for + translations. + """ + + def __init__(self): + deny_vf =3D os.environ.get('FONTS_CONF_DENY_VF', "~/deny-vf") + + self.environ =3D os.environ.copy() + self.environ['XDG_CONFIG_HOMEF'] =3D os.path.expanduser(deny_vf) + + self.re_cjk =3D re.compile(r"([^:]+):\s*Noto\s+(Sans|Sans Mono|Ser= if) CJK") + + def get_noto_cjk_vf_fonts(self): + """Get Noto CJK fonts""" + + cjk_fonts =3D set() + cmd =3D ["fc-list", ":", "file", "family", "variable"] + try: + result =3D subprocess.run(cmd,stdout=3Dsubprocess.PIPE, + stderr=3Dsubprocess.PIPE, + universal_newlines=3DTrue, + env=3Dself.environ, + check=3DTrue) + + except subprocess.CalledProcessError as exc: + sys.exit(f"Error running fc-list: {repr(exc)}") + + for line in result.stdout.splitlines(): + if 'variable=3DTrue' not in line: + continue + + match =3D self.re_cjk.search(line) + if match: + cjk_fonts.add(match.group(1)) + + return sorted(cjk_fonts) + + def check(self): + """Check for problems with CJK fonts""" + + fonts =3D textwrap.indent("\n".join(self.get_noto_cjk_vf_fonts()),= " ") + if not fonts: + return None + + rel_file =3D os.path.relpath(__file__, os.getcwd()) + + msg =3D "=3D" * 77 + "\n" + msg +=3D 'XeTeX is confused by "variable font" files listed below:= \n' + msg +=3D fonts + "\n" + msg +=3D textwrap.dedent(f""" + For CJK pages in PDF, they need to be hidden from XeTeX by= denylisting. + Or, CJK pages can be skipped by uninstalling texlive-xecjk. + + For more info on denylisting, other options, and variable = font, see header + comments of {rel_file}. + """) + msg +=3D "=3D" * 77 + + return msg --=20 2.50.1 From nobody Thu Oct 2 18:15:59 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B34C931AF2E; Fri, 12 Sep 2025 14:27:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757687250; cv=none; b=IDFftByF/qB3CHqv2wv8/berqJAYwAUpBd7+W6CszEl4/io6YftQ+8grOfQjaGaVBmbcaS7NFfTn9yWAextZUbGfo+i3zzxF2laF+gpMMDjtF6GqiPr0W8dmYE/s2AAZ7EQVGzU5/ksm3enRoLznV0mw0dy6St+DwqPwUjWLbm8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757687250; c=relaxed/simple; bh=+vR2LJGLDy8UnwSz3eUgz28ph+DI44nRr8Bevp/r3nA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=c3ettdTKbQ5+qsNwrbxtsfsvhta6DNBQdB0x0FqXB4SCex56EzOzNQ4QRbm243nHjQx1T4at5V8YpzTQaGd5m12ET3HuwUX/VzggnnNUq0qd87g0VdtTwZR7S9r5yY0UAhHet0KSF35F4DAWMWoGuvYnyU/YknSwCnkDJt8hHg4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=A6Sz+Abn; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="A6Sz+Abn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4A357C4CEF5; Fri, 12 Sep 2025 14:27:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757687250; bh=+vR2LJGLDy8UnwSz3eUgz28ph+DI44nRr8Bevp/r3nA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A6Sz+AbnPH43VtdLaOyL9qxT64MjgWKg9h66MPBtZ+4m++KxeHue1lpOgtnI6JVML Rx13UOxoiEPF5f0FBw8wcOIM05R+ut0NgUqZo8BvKL0smjno2fYkZfeCkTPpqEX1nd ZJXTcGXX06rvaddJfPynPe085ryrx2mIlka+8EqJAIrm8bRgXz1j+XBk5sggx4PieQ 111C+ybf4X03kQGyG1BEohGk3DYhXryusEdMr/DtREiFDkH2fK1Smx1XglAwvNp+a9 axOcAloR+Fh4skumKDkYXbG0W+IfPRgDRHfbZUTfMssssZVCjmAbs/VMBCyQwD794B jk9An8hxfyVHA== Received: from mchehab by mail.kernel.org with local (Exim 4.98.2) (envelope-from ) id 1ux4kK-00000008VrR-1RN9; Fri, 12 Sep 2025 16:27:28 +0200 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , Akira Yokosawa , linux-kernel@vger.kernel.org Subject: [PATCH 3/3] tools/docs: sphinx-build-wrapper: warn about broken PDF fonts Date: Fri, 12 Sep 2025 16:27:22 +0200 Message-ID: <0e7b63016b5493b21c011fe66639b770b2b8f25e.1757685692.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: References: Content-Type: text/plain; charset="utf-8" Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Depending on the latex install environment, translations can be broken because of CJK variable fonts. Add a warning in the end. Signed-off-by: Mauro Carvalho Chehab --- tools/docs/sphinx-build-wrapper | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/docs/sphinx-build-wrapper b/tools/docs/sphinx-build-wrap= per index c47f723391b9..d40fc25071c6 100755 --- a/tools/docs/sphinx-build-wrapper +++ b/tools/docs/sphinx-build-wrapper @@ -54,10 +54,11 @@ import subprocess import sys =20 from concurrent import futures - -from lib.python_version import PythonVersion from glob import glob =20 +from lib.python_version import PythonVersion +from lib.latex_fonts import LatexFontChecker + LIB_DIR =3D "../../scripts/lib" SRC_DIR =3D os.path.dirname(os.path.realpath(__file__)) =20 @@ -476,6 +477,10 @@ class SphinxBuilder: print() =20 if build_failed: + msg =3D LatexFontChecker().check() + if msg: + print(msg) + sys.exit("PDF build failed: not all PDF files were created.") else: print("All PDF files were built.") --=20 2.50.1