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

Showing the changes to scripts (1 of 5 files). Show all

Unified · Split

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
92import os
93import re
94import subprocess
95import sys
96import textwrap
97
98class 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
160if __name__ == "__main__":
161 msg = LatexFontChecker().check()
162 if msg:
163 print(msg)
164
165 sys.exit(1)