-
-
Save ernstki/2ae279ad89888e4099c9852bf0ba5d11 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl | |
## | |
## Easily disable fonts that aren't for your language, or language-specific | |
## variants from large font families like Noto -- WITHOUT uninstalling them | |
## | |
## Authors: Kevin Ernst <ernstki -at- mail.uc.edu>, @wdoekes | |
## License: MIT or CC-BY-SA-4.0, at your option | |
## Source: https://gist.github.com/ernstki/2ae279ad89888e4099c9852bf0ba5d11 | |
## | |
## Usage: | |
## ./fc-reject.pl > ~/.config/fontconfig/conf.d/88-reject.conf.new && \ | |
## mv ~/.config/fontconfig/conf.d/88-reject.conf{.new,} | |
## | |
use v5.12; | |
use warnings; | |
use autodie; | |
my $rejectlist = {}; | |
# languages I want to keep, e.g., my native language plus 'und-zsye' for emoji | |
# (ref: https://www.unicode.org/reports/tr35) | |
my $mylangs = 'en|de|und-zsye'; | |
# reject these fonts unconditionally, even if they claim to support my language | |
# (easier than uninstalling; they may be depends/recommends for other packages) | |
my $rejectfam = '^(Kacst|AR PL|Noto.*CJK)'; # Arabic and East Asian scripts | |
# filter out language-specific font variants for languages I don't use from any | |
# font family matched by the $filterfam regexp | |
my $filterfam = '^Noto'; | |
# always keep fonts that match the $keepfam regexp, regardless of lang. support | |
my $keepfam = '^Noto (Music|Symbols|Sans Linear [AB])'; | |
open my $fh, '-|', 'fc-cat'; | |
while (<$fh>) { | |
# a typical line of output from `fc-cat` looks like this: | |
# "NotoSerifHebrew-Regular.ttf" 0 "Noto Serif Hebrew:…:lang=he(|…):… | |
# …which would yield $name = 'Noto Serif Hebrew' and @langs = ('he') | |
if (/.* "([^:,]+).*:lang=([^:]*)/) { | |
my ($name, @langs) = ($1, split(/\|/, $2)); | |
next if $name =~ /$keepfam/; | |
if ($name =~ /$rejectfam/) { | |
$rejectlist->{$name} = 1; | |
next; | |
} | |
if ($name =~ /$filterfam/) { | |
unless (@langs) { | |
# if you want to retain any of these, add to $keepfam, above | |
warn "Family '$name' specified no languages\n"; | |
$rejectlist->{$name} = 1; | |
next; | |
} | |
$rejectlist->{$name} = 1 unless map { /$mylangs/ } @langs; | |
} | |
} | |
} | |
close $fh; | |
print <<EOF; | |
<?xml version="1.0"?> | |
<!DOCTYPE fontconfig SYSTEM "fonts.dtd"> | |
<fontconfig> | |
<selectfont> | |
<rejectfont> | |
EOF | |
foreach my $name (sort keys %$rejectlist) { | |
print <<EOF; | |
<pattern> | |
<patelt name="family"> | |
<string>$name</string> | |
</patelt> | |
</pattern> | |
EOF | |
} | |
print <<EOF; | |
</rejectfont> | |
</selectfont> | |
</fontconfig> | |
EOF | |
# vim: shiftwidth=4 tabstop=4 expandtab |
On Ubuntu 22.04 you might want to re-enable the emoji by removing Noto Color Emoji
from the output. Otherwise you won't even see the 👍 in GitHub.
And maybe Noto Music
and Noto Sans Symbols
and Noto Sans Symbols2
-- although I'm not sure how often you run into those.
As for the harmless warning, I suggest:
fc-reject.pl > ~/.config/fontconfig/conf.d/88-reject.conf.new &&
mv ~/.config/fontconfig/conf.d/88-reject.conf{.new,}
The atomic mv ensures that only the complete file is read.
Thanks for this gist, @ernstki !
My changes:
--- fc-reject.pl 2024-04-30 12:15:16.573580587 +0200
+++ /usr/local/bin/remove-noto-fonts 2024-04-30 12:18:46.764030790 +0200
@@ -1,6 +1,6 @@
#!/usr/bin/env perl
##
-## Usage: fc-reject.pl > ~/.config/fontconfig/conf.d/88-reject.conf
+## Usage: fc-reject.pl > ~/.config/fontconfig/conf.d/88-reject.conf.new && mv ~/.config/fontconfig/conf.d/88-reject.conf{.new,}
## Author: Kevin Ernst <ernstki -at- mail.uc.edu>
## License: MIT or CC-BY-SA-4.0, at your option
## Source: https://gist.github.com/ernstki/2ae279ad89888e4099c9852bf0ba5d11
@@ -9,17 +9,30 @@ use v5.12;
use warnings;
use autodie;
-my $mylang = 'en'; # use '(en|lang1|lang2)' for other languages
-my $rejectfam = 'Noto'; # use '(Noto|Other Family|Another Family)' for others
+my $mylang = 'en|nl|und-zsye'; # use 'en|lang1|lang2' for other languages
+ # 'und-zsye' is for Emoji
+my $rejectfam = '^Noto'; # use '^(Noto|Other Family|Another Family)' for others
+my $keepfam = '^Noto Music'; # use '^(Noto Music|Others to keep)' for others
my $rejectlist = {};
open my $fh, '-|', 'fc-cat';
while (<$fh>) {
- if (/.* "([^:,]+).*:lang=([^:]*):.*/) {
- my ($name, $lang) = ($1, $2);
- if ($name =~ /$rejectfam/ and (!$lang or $lang !~ /$mylang/)) {
- $rejectlist->{$name} = 1;
- }
+ if (/.* "([^:,]+).*:lang=([^:]*)/) {
+ my ($name, @langs) = ($1, split(/\|/, $2));
+ if ($name =~ /$rejectfam/) {
+ my $keep = 0;
+ foreach my $lang (@langs) {
+ if ($lang =~ /^($mylang)$/) {
+ $keep = 1;
+ }
+ }
+ if ($name =~ /$keepfam/) {
+ $keep = 1;
+ }
+ if ($keep == 0) {
+ $rejectlist->{$name} = 1;
+ }
+ }
}
}
close $fh;
@@ -32,7 +45,7 @@ print <<EOF;
<rejectfont>
EOF
-foreach my $name (keys %$rejectlist) {
+foreach my $name (sort keys %$rejectlist) {
print <<EOF;
<pattern>
<patelt name="family">
Many thanks! Solved my problem. I confess I inserted the key bit of 88-reject.conf into the 78-Reject.conf that Font Manager generates when you uncheck a font in the GUI, just so that Font Manager would know about the changes and still work as a management tool. I think it must only read 78-Reject.conf. (Says not to edit it manually, but no harm does as far as I can see.)
On Ubuntu 22.04 you might want to re-enable the emoji by removing
Noto Color Emoji
from the output. Otherwise you won't even see the 👍 in GitHub.
Thanks, @wdoekes. I updated the script with your helpful suggestions, so it's maybe less of a dirty hack now. Hope you're OK with the original license (MIT).
@DJGoossens I'm glad it helped, and that's a great idea of re-using Font Manager's own config so you can tweak it with a GUI later.
Hope you're OK with the original license (MIT).
Anything is fine. Thanks for asking.
Noto is an impressive accomplishment, no doubt. And it's a noble thing to want to enable all the people of the world to see their native writing systems accurately represented on their computers, by default, out of the box.
Sadly, the technical implementation (at least for Debian-derived Linux distros) leaves a lot to be desired, because of the hundreds of separate fonts that comprise Noto. These clog up font menus and make selecting from the fonts for the languages you actually use more of a chore.
This script allows you to selectively disable fonts that don't support your language(s), but easily re-enable them if necessary. While this is technically possible with point-and-click interfaces like Font Manager, it can take hundreds of clicks to get them all.1
It's a much better solution than what is commonly recommended, which is to remove a bunch of font packages, upon which other packages often depend. This can result in a broken system, or at least accidental removal of some applications that you didn't intend to remove.
Installation
This will hide any fonts matching the
$filterfam
regular expression which don't specify$mylangs
(also a regexp) as one of their supported languages. This greatly reduces the length of font selection drop-downs in applications like GIMP or LibreOffice, making it easier to find the fonts you do use.If you wish to name the file something else besides
88-reject.conf
, just make sure it ends in.conf
and begins with two digits. This is a requirement for fontconfig to find it.Tip
As suggested by @DJGoossens below, you may be able to re-use the same filename Font Manager uses, or at least copy-paste the relevant parts from the output of
fc-reject.pl
into an existing config. This allows you to employ the Font Manager GUI for further refinements.Testing if it worked
You can see whether or not it worked by
grep
ping the output offc-list
for fonts that you're sure should be excluded:fc-list | grep Devanagari
There should be no output, or at least no Noto fonts in the output. Obviously I'm writing this from the perspective of a Westerner who can't read non-Latin scripts, so substitute with something appropriate for you.
There may be rare cases (which I haven't encountered) where you need to regenerate fontconfig's caches from scratch. If you run into that situation
should do the trick for that.
Undoing / disabling what the script does
To undo what the script has done simply remove the
.conf
file. Changes take effect immediately. Some programs may need to be restarted, though.You can momentarily disable the config (re-enabling all the excluded fonts) by renaming it to not have a
.conf
extension, like so:Incidentally, visiting the Wikipedia article for Linear A is an effective test to see if Noto—and the above script—is doing its job. That is, if the font is properly installed, you should see "no tofu" (no Unicode replacement symbols) in that article.
See also
fc-cat
as JSONFootnotes
…at least with the version of Font Manager that's in the LTS repositories as of this writing ↩