History

tools/docs: check-variable-fonts.py: split into a lib and an exec file

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.

Mauro Carvalho Chehab committed 1 year ago

Commit 4515ffd1 parent 75539be5 files · +186 −167Browse files

Unified · Split

5 files
  1. Documentation/Makefile +1 −1
  2. MAINTAINERS +0 −1
  3. scripts/check-variable-fonts.py +0 −165
  4. tools/docs/check-variable-fonts.py +23 −0
  5. tools/docs/lib/latex_fonts.py +162 −0
Documentation/Makefile+1−1
@@ -149,7 +149,7 @@ pdfdocs: DENY_VF = XDG_CONFIG_HOME=$(FONTS_CONF_DENY_VF) · 148 unmodified lines
149149 pdfdocs: latexdocs
150150 @$(srctree)/scripts/sphinx-pre-install --version-check
151151 $(foreach var,$(SPHINXDIRS), \
152− $(MAKE) PDFLATEX="$(PDFLATEX)" LATEXOPTS="$(LATEXOPTS)" $(DENY_VF) -C $(BUILDDIR)/$(var)/latex || $(PYTHON3) $(srctree)/scripts/check-variable-fonts.py || exit; \
152+ $(MAKE) PDFLATEX="$(PDFLATEX)" LATEXOPTS="$(LATEXOPTS)" $(DENY_VF) -C $(BUILDDIR)/$(var)/latex || $(PYTHON3) $(srctree)/tools/docs/check-variable-fonts.py || exit; \
153153 mkdir -p $(BUILDDIR)/$(var)/pdf; \
154154 mv $(subst .tex,.pdf,$(wildcard $(BUILDDIR)/$(var)/latex/*.tex)) $(BUILDDIR)/$(var)/pdf/; \
155155 )
MAINTAINERS+0−1
@@ -7301,7 +7301,6 @@ S: Maintained · 7300 unmodified lines
73017301 P: Documentation/doc-guide/maintainer-profile.rst
73027302 T: git git://git.lwn.net/linux.git docs-next
73037303 F: Documentation/
7304−F: scripts/check-variable-fonts.py
73057304 F: scripts/checktransupdate.py
73067305 F: scripts/documentation-file-ref-check
73077306 F: scripts/get_abi.py
scripts/check-variable-fonts.py+0−165
@@ -1,165 +0,0 @@
1−#!/usr/bin/env python3
2−# SPDX-License-Identifier: GPL-2.0-only
3−# Copyright (C) Akira Yokosawa, 2024
4−#
5−# Ported to Python by (c) Mauro Carvalho Chehab, 2025
6−#
7−# For "make pdfdocs", reports of build errors of translations.pdf started
8−# arriving early 2024 [1, 2]. It turned out that Fedora and openSUSE
9−# tumbleweed have started deploying variable-font [3] format of "Noto CJK"
10−# fonts [4, 5]. For PDF, a LaTeX package named xeCJK is used for CJK
11−# (Chinese, Japanese, Korean) pages. xeCJK requires XeLaTeX/XeTeX, which
12−# does not (and likely never will) understand variable fonts for historical
13−# reasons.
14−#
15−# The build error happens even when both of variable- and non-variable-format
16−# fonts are found on the build system. To make matters worse, Fedora enlists
17−# variable "Noto CJK" fonts in the requirements of langpacks-ja, -ko, -zh_CN,
18−# -zh_TW, etc. Hence developers who have interest in CJK pages are more
19−# likely to encounter the build errors.
20−#
21−# This script is invoked from the error path of "make pdfdocs" and emits
22−# suggestions if variable-font files of "Noto CJK" fonts are in the list of
23−# fonts accessible from XeTeX.
24−#
25−# References:
26−# [1]: https://lore.kernel.org/r/8734tqsrt7.fsf@meer.lwn.net/
27−# [2]: https://lore.kernel.org/r/1708585803.600323099@f111.i.mail.ru/
28−# [3]: https://en.wikipedia.org/wiki/Variable_font
29−# [4]: https://fedoraproject.org/wiki/Changes/Noto_CJK_Variable_Fonts
30−# [5]: https://build.opensuse.org/request/show/1157217
31−#
32−#===========================================================================
33−# Workarounds for building translations.pdf
34−#===========================================================================
35−#
36−# * Denylist "variable font" Noto CJK fonts.
37−# - Create $HOME/deny-vf/fontconfig/fonts.conf from template below, with
38−# tweaks if necessary. Remove leading "# ".
39−# - Path of fontconfig/fonts.conf can be overridden by setting an env
40−# variable FONTS_CONF_DENY_VF.
41−#
42−# * Template:
43−# -----------------------------------------------------------------
44−# <?xml version="1.0"?>
45−# <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
46−# <fontconfig>
47−# <!--
48−# Ignore variable-font glob (not to break xetex)
49−# -->
50−# <selectfont>
51−# <rejectfont>
52−# <!--
53−# for Fedora
54−# -->
55−# <glob>/usr/share/fonts/google-noto-*-cjk-vf-fonts</glob>
56−# <!--
57−# for openSUSE tumbleweed
58−# -->
59−# <glob>/usr/share/fonts/truetype/Noto*CJK*-VF.otf</glob>
60−# </rejectfont>
61−# </selectfont>
62−# </fontconfig>
63−# -----------------------------------------------------------------
64−#
65−# The denylisting is activated for "make pdfdocs".
66−#
67−# * For skipping CJK pages in PDF
68−# - Uninstall texlive-xecjk.
69−# Denylisting is not needed in this case.
70−#
71−# * For printing CJK pages in PDF
72−# - Need non-variable "Noto CJK" fonts.
73−# * Fedora
74−# - google-noto-sans-cjk-fonts
75−# - google-noto-serif-cjk-fonts
76−# * openSUSE tumbleweed
77−# - Non-variable "Noto CJK" fonts are not available as distro packages
78−# as of April, 2024. Fetch a set of font files from upstream Noto
79−# CJK Font released at:
80−# https://github.com/notofonts/noto-cjk/tree/main/Sans#super-otc
81−# and at:
82−# https://github.com/notofonts/noto-cjk/tree/main/Serif#super-otc
83−# , then uncompress and deploy them.
84−# - Remember to update fontconfig cache by running fc-cache.
85−#
86−# !!! Caution !!!
87−# Uninstalling "variable font" packages can be dangerous.
88−# They might be depended upon by other packages important for your work.
89−# Denylisting should be less invasive, as it is effective only while
90−# XeLaTeX runs in "make pdfdocs".
91−
92−import os
93−import re
94−import subprocess
95−import sys
96−import textwrap
97−
98−class LatexFontChecker:
99− """
100− Detect problems with CJK variable fonts that affect PDF builds for
101− translations.
102− """
103−
104− def __init__(self):
105− deny_vf = os.environ.get('FONTS_CONF_DENY_VF', "~/deny-vf")
106−
107− self.environ = os.environ.copy()
108− self.environ['XDG_CONFIG_HOME'] = os.path.expanduser(deny_vf)
109−
110− self.re_cjk = re.compile(r"([^:]+):\s*Noto\s+(Sans|Sans Mono|Serif) CJK")
111−
112− def get_noto_cjk_vf_fonts(self):
113− """Get Noto CJK fonts"""
114−
115− cjk_fonts = set()
116− cmd = ["fc-list", ":", "file", "family", "variable"]
117− try:
118− result = subprocess.run(cmd,stdout=subprocess.PIPE,
119− stderr=subprocess.PIPE,
120− universal_newlines=True,
121− env=self.environ,
122− check=True)
123−
124− except subprocess.CalledProcessError as exc:
125− sys.exit(f"Error running fc-list: {repr(exc)}")
126−
127− for line in result.stdout.splitlines():
128− if 'variable=True' not in line:
129− continue
130−
131− match = self.re_cjk.search(line)
132− if match:
133− cjk_fonts.add(match.group(1))
134−
135− return sorted(cjk_fonts)
136−
137− def check(self):
138− """Check for problems with CJK fonts"""
139−
140− fonts = textwrap.indent("\n".join(self.get_noto_cjk_vf_fonts()), " ")
141− if not fonts:
142− return None
143−
144− rel_file = os.path.relpath(__file__, os.getcwd())
145−
146− msg = "=" * 77 + "\n"
147− msg += 'XeTeX is confused by "variable font" files listed below:\n'
148− msg += fonts + "\n"
149− msg += textwrap.dedent(f"""
150− For CJK pages in PDF, they need to be hidden from XeTeX by denylisting.
151− Or, CJK pages can be skipped by uninstalling texlive-xecjk.
152−
153− For more info on denylisting, other options, and variable font, see header
154− comments of {rel_file}.
155− """)
156− msg += "=" * 77
157−
158− return msg
159−
160−if __name__ == "__main__":
161− msg = LatexFontChecker().check()
162− if msg:
163− print(msg)
164−
165− sys.exit(1)
tools/docs/check-variable-fonts.py+23−0
@@ -0,0 +1,23 @@
1+#!/usr/bin/env python3
2+# SPDX-License-Identifier: GPL-2.0-only
3+# Copyright (C) Akira Yokosawa, 2024
4+#
5+# Ported to Python by (c) Mauro Carvalho Chehab, 2025
6+#
7+# pylint: disable=C0103
8+
9+"""
10+Detect problematic Noto CJK variable fonts.
11+
12+or more details, see lib/latex_fonts.py.
13+"""
14+
15+import sys
16+
17+from lib.latex_fonts import LatexFontChecker
18+
19+msg = LatexFontChecker().check()
20+if msg:
21+ print(msg)
22+
23+sys.exit(1)
tools/docs/lib/latex_fonts.py+162−0
@@ -0,0 +1,162 @@
1+#!/usr/bin/env python3
2+# SPDX-License-Identifier: GPL-2.0-only
3+# Copyright (C) Akira Yokosawa, 2024
4+#
5+# Ported to Python by (c) Mauro Carvalho Chehab, 2025
6+
7+"""
8+Detect problematic Noto CJK variable fonts.
9+
10+For "make pdfdocs", reports of build errors of translations.pdf started
11+arriving early 2024 [1, 2]. It turned out that Fedora and openSUSE
12+tumbleweed have started deploying variable-font [3] format of "Noto CJK"
13+fonts [4, 5]. For PDF, a LaTeX package named xeCJK is used for CJK
14+(Chinese, Japanese, Korean) pages. xeCJK requires XeLaTeX/XeTeX, which
15+does not (and likely never will) understand variable fonts for historical
16+reasons.
17+
18+The build error happens even when both of variable- and non-variable-format
19+fonts are found on the build system. To make matters worse, Fedora enlists
20+variable "Noto CJK" fonts in the requirements of langpacks-ja, -ko, -zh_CN,
21+-zh_TW, etc. Hence developers who have interest in CJK pages are more
22+likely to encounter the build errors.
23+
24+This script is invoked from the error path of "make pdfdocs" and emits
25+suggestions if variable-font files of "Noto CJK" fonts are in the list of
26+fonts accessible from XeTeX.
27+
28+References:
29+[1]: https://lore.kernel.org/r/8734tqsrt7.fsf@meer.lwn.net/
30+[2]: https://lore.kernel.org/r/1708585803.600323099@f111.i.mail.ru/
31+[3]: https://en.wikipedia.org/wiki/Variable_font
32+[4]: https://fedoraproject.org/wiki/Changes/Noto_CJK_Variable_Fonts
33+[5]: https://build.opensuse.org/request/show/1157217
34+
35+#===========================================================================
36+Workarounds for building translations.pdf
37+#===========================================================================
38+
39+* Denylist "variable font" Noto CJK fonts.
40+ - Create $HOME/deny-vf/fontconfig/fonts.conf from template below, with
41+ tweaks if necessary. Remove leading "".
42+ - Path of fontconfig/fonts.conf can be overridden by setting an env
43+ variable FONTS_CONF_DENY_VF.
44+
45+ * Template:
46+-----------------------------------------------------------------
47+<?xml version="1.0"?>
48+<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
49+<fontconfig>
50+<!--
51+ Ignore variable-font glob (not to break xetex)
52+-->
53+ <selectfont>
54+ <rejectfont>
55+ <!--
56+ for Fedora
57+ -->
58+ <glob>/usr/share/fonts/google-noto-*-cjk-vf-fonts</glob>
59+ <!--
60+ for openSUSE tumbleweed
61+ -->
62+ <glob>/usr/share/fonts/truetype/Noto*CJK*-VF.otf</glob>
63+ </rejectfont>
64+ </selectfont>
65+</fontconfig>
66+-----------------------------------------------------------------
67+
68+ The denylisting is activated for "make pdfdocs".
69+
70+* For skipping CJK pages in PDF
71+ - Uninstall texlive-xecjk.
72+ Denylisting is not needed in this case.
73+
74+* For printing CJK pages in PDF
75+ - Need non-variable "Noto CJK" fonts.
76+ * Fedora
77+ - google-noto-sans-cjk-fonts
78+ - google-noto-serif-cjk-fonts
79+ * openSUSE tumbleweed
80+ - Non-variable "Noto CJK" fonts are not available as distro packages
81+ as of April, 2024. Fetch a set of font files from upstream Noto
82+ CJK Font released at:
83+ https://github.com/notofonts/noto-cjk/tree/main/Sans#super-otc
84+ and at:
85+ https://github.com/notofonts/noto-cjk/tree/main/Serif#super-otc
86+ , then uncompress and deploy them.
87+ - Remember to update fontconfig cache by running fc-cache.
88+
89+!!! Caution !!!
90+ Uninstalling "variable font" packages can be dangerous.
91+ They might be depended upon by other packages important for your work.
92+ Denylisting should be less invasive, as it is effective only while
93+ XeLaTeX runs in "make pdfdocs".
94+"""
95+
96+import os
97+import re
98+import subprocess
99+import textwrap
100+import sys
101+
102+class LatexFontChecker:
103+ """
104+ Detect problems with CJK variable fonts that affect PDF builds for
105+ translations.
106+ """
107+
108+ def __init__(self):
109+ deny_vf = os.environ.get('FONTS_CONF_DENY_VF', "~/deny-vf")
110+
111+ self.environ = os.environ.copy()
112+ self.environ['XDG_CONFIG_HOME'] = os.path.expanduser(deny_vf)
113+
114+ self.re_cjk = re.compile(r"([^:]+):\s*Noto\s+(Sans|Sans Mono|Serif) CJK")
115+
116+ def get_noto_cjk_vf_fonts(self):
117+ """Get Noto CJK fonts"""
118+
119+ cjk_fonts = set()
120+ cmd = ["fc-list", ":", "file", "family", "variable"]
121+ try:
122+ result = subprocess.run(cmd,stdout=subprocess.PIPE,
123+ stderr=subprocess.PIPE,
124+ universal_newlines=True,
125+ env=self.environ,
126+ check=True)
127+
128+ except subprocess.CalledProcessError as exc:
129+ sys.exit(f"Error running fc-list: {repr(exc)}")
130+
131+ for line in result.stdout.splitlines():
132+ if 'variable=True' not in line:
133+ continue
134+
135+ match = self.re_cjk.search(line)
136+ if match:
137+ cjk_fonts.add(match.group(1))
138+
139+ return sorted(cjk_fonts)
140+
141+ def check(self):
142+ """Check for problems with CJK fonts"""
143+
144+ fonts = textwrap.indent("\n".join(self.get_noto_cjk_vf_fonts()), " ")
145+ if not fonts:
146+ return None
147+
148+ rel_file = os.path.relpath(__file__, os.getcwd())
149+
150+ msg = "=" * 77 + "\n"
151+ msg += 'XeTeX is confused by "variable font" files listed below:\n'
152+ msg += fonts + "\n"
153+ msg += textwrap.dedent(f"""
154+ For CJK pages in PDF, they need to be hidden from XeTeX by denylisting.
155+ Or, CJK pages can be skipped by uninstalling texlive-xecjk.
156+
157+ For more info on denylisting, other options, and variable font, see header
158+ comments of {rel_file}.
159+ """)
160+ msg += "=" * 77
161+
162+ return msg