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.
Showing the changes to scripts (1 of 5 files). Show all
Unified · Split
| @@ -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) | ||