diff mbox series

[bug#57963,v2] home: fontutils: Support user's fontconfig.

Message ID 20220922012033.30835-1-higashi@taiju.info
State New
Headers show
Series [bug#57963,v2] home: fontutils: Support user's fontconfig. | expand

Checks

Context Check Description
cbaines/comparison success View comparision
cbaines/git-branch success View Git branch
cbaines/applying patch success View Laminar job
cbaines/issue success View issue

Commit Message

Taiju HIGASHI Sept. 22, 2022, 1:20 a.m. UTC
* gnu/home/services/fontutils.scm (add-fontconfig-config-file): Support user's
fontconfig.
---
 gnu/home/services/fontutils.scm | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

Comments

Andrew Tropin Sept. 22, 2022, 6:14 a.m. UTC | #1
On 2022-09-22 10:20, Taiju HIGASHI wrote:

> * gnu/home/services/fontutils.scm (add-fontconfig-config-file): Support user's
> fontconfig.
> ---
>  gnu/home/services/fontutils.scm | 29 ++++++++++++++++++++++++-----
>  1 file changed, 24 insertions(+), 5 deletions(-)
>
> diff --git a/gnu/home/services/fontutils.scm b/gnu/home/services/fontutils.scm
> index 6062eaed6a..b57cccbaae 100644
> --- a/gnu/home/services/fontutils.scm
> +++ b/gnu/home/services/fontutils.scm
> @@ -1,6 +1,7 @@
>  ;;; GNU Guix --- Functional package management for GNU
>  ;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
>  ;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
> +;;; Copyright © 2022 Taiju HIGASHI <higashi@taiju.info>
>  ;;;
>  ;;; This file is part of GNU Guix.
>  ;;;
> @@ -21,6 +22,9 @@ (define-module (gnu home services fontutils)
>    #:use-module (gnu home services)
>    #:use-module (gnu packages fontutils)
>    #:use-module (guix gexp)
> +  #:use-module (srfi srfi-1)
> +  #:use-module (sxml simple)
> +  #:use-module (ice-9 match)
>  
>    #:export (home-fontconfig-service-type))
>  
> @@ -33,15 +37,28 @@ (define-module (gnu home services fontutils)
>  ;;;
>  ;;; Code:
>  
> -(define (add-fontconfig-config-file he-symlink-path)
> +(define (parse-extra-user-config extra-user-config)
> +  (map (match-lambda
> +         ((? pair? sxml) sxml)
> +         ((? string? xml) (xml->sxml xml))
> +         (_ (error "extra-user-config must be xml string or sxml.")))
> +       extra-user-config))
> +
> +(define (add-fontconfig-config-file extra-user-config)
>    `(("fontconfig/fonts.conf"
>       ,(mixed-text-file
>         "fonts.conf"
>         "<?xml version='1.0'?>
>  <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
> -<fontconfig>
> -  <dir>~/.guix-home/profile/share/fonts</dir>
> -</fontconfig>"))))
> +"
> +       (call-with-output-string
> +         (lambda (port)
> +           (sxml->xml
> +            `(fontconfig
> +              (dir "~/.guix-home/profile/share/fonts")
> +              ,@(parse-extra-user-config extra-user-config))
> +            port)
> +           (newline port)))))))
>  
>  (define (regenerate-font-cache-gexp _)
>    `(("profile/share/fonts"
> @@ -49,6 +66,8 @@ (define (regenerate-font-cache-gexp _)
>  
>  (define home-fontconfig-service-type
>    (service-type (name 'home-fontconfig)
> +                (compose concatenate)
> +                (extend append)
>                  (extensions
>                   (list (service-extension
>                          home-xdg-configuration-files-service-type
> @@ -59,7 +78,7 @@ (define home-fontconfig-service-type
>                         (service-extension
>                          home-profile-service-type
>                          (const (list fontconfig)))))
> -                (default-value #f)
> +                (default-value '())
>                  (description
>                   "Provides configuration file for fontconfig and make
>  fc-* utilities aware of font packages installed in Guix Home's profile.")))

I like the current approach, but I have two concerns:

1. Serialization happens on client side, not daemon side (during the
build), thus it doesn't support gexp and file-likes, so it would be hard
to append part of already existing file to the config or do similiar thing.

2. We had a discussion with Ludovic about rde home services vs guix home
services styles.  And this one looks like rde style, not guix.

rde takes arbitrary s-exps and g-exps with optional structure checks and
serializes them to target format.

guix uses nested records with rigid nesting structure.

rde services style examples:
https://git.sr.ht/~abcdw/rde/tree/8ec99884fad18a80a08a7c1d6a7cf46a006327c4/rde/home/services/wm.scm#L145
https://git.sr.ht/~abcdw/rde/tree/8ec99884fad18a80a08a7c1d6a7cf46a006327c4/rde/home/services/xdisorg.scm#L55

guix services style examples:
https://guix.gnu.org/manual/devel/en/guix.html#Web-Services

Related discussions:
https://issues.guix.gnu.org/53466
https://issues.guix.gnu.org/52698
https://yhetil.org/guix-devel/87h79qx5db.fsf@trop.in/

To sum up, personally I like and prefer the configuration style from
this patch, but to keep it consistent with guix system services we need
to use guix style.
Ludovic Courtès Sept. 22, 2022, 8:53 a.m. UTC | #2
Hi Andrew,

Andrew Tropin <andrew@trop.in> skribis:

> 2. We had a discussion with Ludovic about rde home services vs guix home
> services styles.  And this one looks like rde style, not guix.
>
> rde takes arbitrary s-exps and g-exps with optional structure checks and
> serializes them to target format.
>
> guix uses nested records with rigid nesting structure.

That’s generally true, but it’s not black and white and there’s room for
discussion.  :-)

In this case, Taiju’s proposal is to let users write snippets like this:

--8<---------------cut here---------------start------------->8---
    (define font-family-map
      '((sans-serif . "Noto Sans CJK JP")
        (serif . "Noto Serif CJK JP")))

    (home-environment
     (packages (list font-google-noto))
     (services
      (list
       (simple-service 'my-fontconfig-service
                       home-fontconfig-service-type
                       (list
                        (call-with-output-string
                          (lambda (port)
                            (sxml->xml
                             (map (lambda (pair)
                                    `(alias
                                      (family ,(car pair))
                                      (prefer
                                       (family ,(cdr pair)))))
                                  font-family-map)
                             port))))))))
--8<---------------cut here---------------end--------------->8---

(With v2 they’d provide SXML instead of XML-in-a-string, so it’s
slightly less verbose but quite similar.)

In this particular case, I would find it easier to use if one could
provide a set of <font-alias> records, let’s say along these lines:

  (simple-service 'my-fontconfig-service
                  home-fontconfig-service-type
                  (list (font-alias 'sans-serif "Noto Sans CJK JP") …))

That way, users wouldn’t need to know the details of the XML syntax for
fontconfig.

The downside is that it restricts what can be done: it lets you add font
aliases, but nothing more.

Do you have other use cases in mind, Taiju?

Thanks,
Ludo’.
Taiju HIGASHI Sept. 22, 2022, 9:50 a.m. UTC | #3
Hi Andrew and Ludovic,

Thanks for your input and background on the code style.

I'm not very knowledgeable about G-Expressions, so I don't understand
much of what you replied. (I will study it!).

Ludovic Courtès <ludo@gnu.org> writes:

> Hi Andrew,
>
> Andrew Tropin <andrew@trop.in> skribis:
>
>> 2. We had a discussion with Ludovic about rde home services vs guix home
>> services styles.  And this one looks like rde style, not guix.
>>
>> rde takes arbitrary s-exps and g-exps with optional structure checks and
>> serializes them to target format.
>>
>> guix uses nested records with rigid nesting structure.
>
> That’s generally true, but it’s not black and white and there’s room for
> discussion.  :-)
>
> In this case, Taiju’s proposal is to let users write snippets like this:
>
>     (define font-family-map
>       '((sans-serif . "Noto Sans CJK JP")
>         (serif . "Noto Serif CJK JP")))
>
>     (home-environment
>      (packages (list font-google-noto))
>      (services
>       (list
>        (simple-service 'my-fontconfig-service
>                        home-fontconfig-service-type
>                        (list
>                         (call-with-output-string
>                           (lambda (port)
>                             (sxml->xml
>                              (map (lambda (pair)
>                                     `(alias
>                                       (family ,(car pair))
>                                       (prefer
>                                        (family ,(cdr pair)))))
>                                   font-family-map)
>                              port))))))))
>
> (With v2 they’d provide SXML instead of XML-in-a-string, so it’s
> slightly less verbose but quite similar.)
>
> In this particular case, I would find it easier to use if one could
> provide a set of <font-alias> records, let’s say along these lines:
>
>   (simple-service 'my-fontconfig-service
>                   home-fontconfig-service-type
>                   (list (font-alias 'sans-serif "Noto Sans CJK JP") …))
>
> That way, users wouldn’t need to know the details of the XML syntax for
> fontconfig.
>
> The downside is that it restricts what can be done: it lets you add font
> aliases, but nothing more.
>
> Do you have other use cases in mind, Taiju?

My motivation for writing this patch is that I wanted to continue to use
the settings in the following file after switching to Guix Home.

https://git.sr.ht/~taiju/taix/tree/31a37c231ebba60e38f7fa9cfe1c7a5d7362d021/item/dotfiles/fontconfig/.config/fontconfig/fonts.conf

Honestly, I don't know why it is so complicated, but I refered it from
the following ArchWiki content.

https://wiki.archlinux.org/title/Font_configuration/Examples#Japanese

Therefore, just being able to set font aliasing is unfortunately not
enough to satisfy my use case.

Thanks,
--
Taiju
Ludovic Courtès Sept. 24, 2022, 3:52 p.m. UTC | #4
Hi,

Taiju HIGASHI <higashi@taiju.info> skribis:

> I'm not very knowledgeable about G-Expressions, so I don't understand
> much of what you replied. (I will study it!).

I didn’t mention gexps.  :-)

> Ludovic Courtès <ludo@gnu.org> writes:
> My motivation for writing this patch is that I wanted to continue to use
> the settings in the following file after switching to Guix Home.
>
> https://git.sr.ht/~taiju/taix/tree/31a37c231ebba60e38f7fa9cfe1c7a5d7362d021/item/dotfiles/fontconfig/.config/fontconfig/fonts.conf
>
> Honestly, I don't know why it is so complicated, but I refered it from
> the following ArchWiki content.
>
> https://wiki.archlinux.org/title/Font_configuration/Examples#Japanese
>
> Therefore, just being able to set font aliasing is unfortunately not
> enough to satisfy my use case.

Oh I see.  Do you need every single bit from the ‘fonts.conf’ file
above?

Anyway, it does look like your v2 is the way to go, with the obvious
caveat that using it is tricky: one needs to know about fontconfig’s
config file format and about sxml.

Maybe we can go with v2 for now (it provides a useful “escape hatch”)
but prepare for more conventional configuration bindings?

Thanks,
Ludo’.
Taiju HIGASHI Sept. 24, 2022, 10:58 p.m. UTC | #5
Ludovic Courtès <ludo@gnu.org> writes:

> Hi,
>
> Taiju HIGASHI <higashi@taiju.info> skribis:
>
>> I'm not very knowledgeable about G-Expressions, so I don't understand
>> much of what you replied. (I will study it!).
>
> I didn’t mention gexps.  :-)

Sorry, that comment of mine was in response to Andrew's comment.

>> Ludovic Courtès <ludo@gnu.org> writes:
>> My motivation for writing this patch is that I wanted to continue to use
>> the settings in the following file after switching to Guix Home.
>>
>> https://git.sr.ht/~taiju/taix/tree/31a37c231ebba60e38f7fa9cfe1c7a5d7362d021/item/dotfiles/fontconfig/.config/fontconfig/fonts.conf
>>
>> Honestly, I don't know why it is so complicated, but I refered it from
>> the following ArchWiki content.
>>
>> https://wiki.archlinux.org/title/Font_configuration/Examples#Japanese
>>
>> Therefore, just being able to set font aliasing is unfortunately not
>> enough to satisfy my use case.
>
> Oh I see.  Do you need every single bit from the ‘fonts.conf’ file
> above?

There may be some settings that are not needed.

> Anyway, it does look like your v2 is the way to go, with the obvious
> caveat that using it is tricky: one needs to know about fontconfig’s
> config file format and about sxml.
>
> Maybe we can go with v2 for now (it provides a useful “escape hatch”)
> but prepare for more conventional configuration bindings?

By conventional configuration binding, do you mean adding something like
home-fontconfig-configuration to provide a dedicated  fontconfig
configuration?

I have been reading the DTD and think it might be a bit of a challenge.
https://github.com/freedesktop/fontconfig/blob/e291fda7d42e5d64379555097a066d9c2c4efce3/fonts.dtd

However, I did notice one thing, and that is that there is an include
element.
I thought that if we had a configuration where the include element could
be added, we could handle most of the use cases.
What do you think of this idea?

Thanks,
Liliana Marie Prikler Sept. 25, 2022, 6:25 a.m. UTC | #6
Am Sonntag, dem 25.09.2022 um 07:58 +0900 schrieb Taiju HIGASHI:
> Ludovic Courtès <ludo@gnu.org> writes:
> 
> > Anyway, it does look like your v2 is the way to go, with the
> > obvious caveat that using it is tricky: one needs to know about
> > fontconfig’s config file format and about sxml.
> > 
> > Maybe we can go with v2 for now (it provides a useful “escape
> > hatch”) but prepare for more conventional configuration bindings?
> 
> By conventional configuration binding, do you mean adding something
> like home-fontconfig-configuration to provide a dedicated  fontconfig
> configuration?
I think Ludo means that we should provide the most useful options (like
the fontconfig dirs) as dedicated record fields, while leaving an
"extra-config" escape hatch, that can be used with SXML or a raw string
for stuff that's too complicated (my personal preference would still be
SXML over the raw string, but YMMV).

> I have been reading the DTD and think it might be a bit of a
> challenge.
> https://github.com/freedesktop/fontconfig/blob/e291fda7d42e5d64379555097a066d9c2c4efce3/fonts.dtd
> 
> However, I did notice one thing, and that is that there is an include
> element.  I thought that if we had a configuration where the include
> element could be added, we could handle most of the use cases.
> What do you think of this idea?
I'd prefer extra-config over include – extra-config doesn't need to go
through file-like objects and an additional layer of G-Expression
quoting.

Cheers
Taiju HIGASHI Sept. 25, 2022, 7:29 a.m. UTC | #7
Liliana Marie Prikler <liliana.prikler@gmail.com> writes:

> Am Sonntag, dem 25.09.2022 um 07:58 +0900 schrieb Taiju HIGASHI:
>> Ludovic Courtès <ludo@gnu.org> writes:
>>
>> > Anyway, it does look like your v2 is the way to go, with the
>> > obvious caveat that using it is tricky: one needs to know about
>> > fontconfig’s config file format and about sxml.
>> >
>> > Maybe we can go with v2 for now (it provides a useful “escape
>> > hatch”) but prepare for more conventional configuration bindings?
>>
>> By conventional configuration binding, do you mean adding something
>> like home-fontconfig-configuration to provide a dedicated  fontconfig
>> configuration?
> I think Ludo means that we should provide the most useful options (like
> the fontconfig dirs) as dedicated record fields, while leaving an
> "extra-config" escape hatch, that can be used with SXML or a raw string
> for stuff that's too complicated (my personal preference would still be
> SXML over the raw string, but YMMV).

I see.  For example,

For example, would it be as follows?

--8<---------------cut here---------------start------------->8---
(service home-fontconfig-service-type
  (home-fontconfig-configuration
    (dir "~/.config/fontconfig/my-fonts1.conf"))
  (extra-config
    (list
      "<dir>~/.config/fontconfig/my-fonts2.conf")))
--8<---------------cut here---------------end--------------->8---

>> I have been reading the DTD and think it might be a bit of a
>> challenge.
>> https://github.com/freedesktop/fontconfig/blob/e291fda7d42e5d64379555097a066d9c2c4efce3/fonts.dtd
>>
>> However, I did notice one thing, and that is that there is an include
>> element.  I thought that if we had a configuration where the include
>> element could be added, we could handle most of the use cases.
>> What do you think of this idea?
> I'd prefer extra-config over include – extra-config doesn't need to go
> through file-like objects and an additional layer of G-Expression
> quoting.
>
> Cheers

It is difficult to determine which rules to define as records, but I
thought that if I only had includes, I could handle most use cases.

For example, we assume that you will be able to write settings as
follows:

--8<---------------cut here---------------start------------->8---
(service home-fontconfig-service-type
  (home-fontconfig-configuration
    (includes
      (list
        (include
          (path "~/.config/fontconfig/my-fonts1.conf")
          (ignore-missing #t))))))
--8<---------------cut here---------------end--------------->8---

ref: https://github.com/freedesktop/fontconfig/blob/e291fda7d42e5d64379555097a066d9c2c4efce3/fonts.dtd#L59-L74

Would it also fit with your assumption if we could also specify
extra-config here?

It is difficult to judge whether the ability to specify includes is
useful or not, though, since extra-config alone will do the job.

Thanks,
Taiju HIGASHI Sept. 25, 2022, 7:34 a.m. UTC | #8
Taiju HIGASHI <higashi@taiju.info> writes:

> Liliana Marie Prikler <liliana.prikler@gmail.com> writes:
>
>> Am Sonntag, dem 25.09.2022 um 07:58 +0900 schrieb Taiju HIGASHI:
>>> Ludovic Courtès <ludo@gnu.org> writes:
>>>
>>> > Anyway, it does look like your v2 is the way to go, with the
>>> > obvious caveat that using it is tricky: one needs to know about
>>> > fontconfig’s config file format and about sxml.
>>> >
>>> > Maybe we can go with v2 for now (it provides a useful “escape
>>> > hatch”) but prepare for more conventional configuration bindings?
>>>
>>> By conventional configuration binding, do you mean adding something
>>> like home-fontconfig-configuration to provide a dedicated  fontconfig
>>> configuration?
>> I think Ludo means that we should provide the most useful options (like
>> the fontconfig dirs) as dedicated record fields, while leaving an
>> "extra-config" escape hatch, that can be used with SXML or a raw string
>> for stuff that's too complicated (my personal preference would still be
>> SXML over the raw string, but YMMV).
>
> I see.  For example,
>
> For example, would it be as follows?
>
> (service home-fontconfig-service-type
>   (home-fontconfig-configuration
>     (dir "~/.config/fontconfig/my-fonts1.conf"))
>   (extra-config
>     (list
>       "<dir>~/.config/fontconfig/my-fonts2.conf")))

It was wrong. The following is more correct.

--8<---------------cut here---------------start------------->8---
(service home-fontconfig-service-type
  (home-fontconfig-configuration
    (dirs
      (list "~/.config/fontconfig/my-fonts1.conf"))
    (extra-config
      (list
        "<match>...</match>"))))
--8<---------------cut here---------------end--------------->8---

Thanks,
Liliana Marie Prikler Sept. 25, 2022, 3:50 p.m. UTC | #9
Am Sonntag, dem 25.09.2022 um 16:29 +0900 schrieb Taiju HIGASHI:
> Liliana Marie Prikler <liliana.prikler@gmail.com> writes:
> 
> > Am Sonntag, dem 25.09.2022 um 07:58 +0900 schrieb Taiju HIGASHI:
> > > Ludovic Courtès <ludo@gnu.org> writes:
> > > 
> > > > Anyway, it does look like your v2 is the way to go, with the
> > > > obvious caveat that using it is tricky: one needs to know about
> > > > fontconfig’s config file format and about sxml.
> > > > 
> > > > Maybe we can go with v2 for now (it provides a useful “escape
> > > > hatch”) but prepare for more conventional configuration
> > > > bindings?
> > > 
> > > By conventional configuration binding, do you mean adding
> > > something
> > > like home-fontconfig-configuration to provide a dedicated 
> > > fontconfig
> > > configuration?
> > I think Ludo means that we should provide the most useful options
> > (like the fontconfig dirs) as dedicated record fields, while
> > leaving an "extra-config" escape hatch, that can be used with SXML
> > or a raw string for stuff that's too complicated (my personal
> > preference would still be SXML over the raw string, but YMMV).
> 
> I see.  For example,
> 
> For example, would it be as follows?
> 
> --8<---------------cut here---------------start------------->8---
> (service home-fontconfig-service-type
>   (home-fontconfig-configuration
>     (dir "~/.config/fontconfig/my-fonts1.conf"))
>   (extra-config
>     (list
>       "<dir>~/.config/fontconfig/my-fonts2.conf")))
> --8<---------------cut here---------------end--------------->8---
Since you can specify more than one dir, that'd be "dirs" or even
something more helpful like "font-directories".  Note that those are
directories and not config files.

You corrected the extra-config thing in your reply, but also be aware
of the extra-config as SXML option.

> 
> > > I have been reading the DTD and think it might be a bit of a
> > > challenge.
> > > https://github.com/freedesktop/fontconfig/blob/e291fda7d42e5d64379555097a066d9c2c4efce3/fonts.dtd
> > > 
> > > However, I did notice one thing, and that is that there is an
> > > include element.  I thought that if we had a configuration where
> > > the include element could be added, we could handle most of the
> > > use cases.  What do you think of this idea?
> > I'd prefer extra-config over include – extra-config doesn't need to
> > go through file-like objects and an additional layer of G-
> > Expression quoting.
> > 
> > Cheers
> 
> It is difficult to determine which rules to define as records, but I
> thought that if I only had includes, I could handle most use cases.
Go for the obvious low-hanging fruits and typical use cases first. 
Don't just add a field that requires a depth of 3 or more to be useful.

> For example, we assume that you will be able to write settings as
> follows:
> 
> --8<---------------cut here---------------start------------->8---
> (service home-fontconfig-service-type
>   (home-fontconfig-configuration
>     (includes
>       (list
>         (include
>           (path "~/.config/fontconfig/my-fonts1.conf")
>           (ignore-missing #t))))))
> --8<---------------cut here---------------end--------------->8---
> 
> ref:
> https://github.com/freedesktop/fontconfig/blob/e291fda7d42e5d64379555097a066d9c2c4efce3/fonts.dtd#L59-L74
> 
> Would it also fit with your assumption if we could also specify
> extra-config here?
> 
> It is difficult to judge whether the ability to specify includes is
> useful or not, though, since extra-config alone will do the job.
Except for possibly some fringe use cases, include will be pointless if
you have extra-config, which is a better include :)

Cheers
Taiju HIGASHI Sept. 26, 2022, 1:43 a.m. UTC | #10
Liliana Marie Prikler <liliana.prikler@gmail.com> writes:

> Am Sonntag, dem 25.09.2022 um 16:29 +0900 schrieb Taiju HIGASHI:
>> Liliana Marie Prikler <liliana.prikler@gmail.com> writes:
>>
>> > Am Sonntag, dem 25.09.2022 um 07:58 +0900 schrieb Taiju HIGASHI:
>> > > Ludovic Courtès <ludo@gnu.org> writes:
>> > >
>> > > > Anyway, it does look like your v2 is the way to go, with the
>> > > > obvious caveat that using it is tricky: one needs to know about
>> > > > fontconfig’s config file format and about sxml.
>> > > >
>> > > > Maybe we can go with v2 for now (it provides a useful “escape
>> > > > hatch”) but prepare for more conventional configuration
>> > > > bindings?
>> > >
>> > > By conventional configuration binding, do you mean adding
>> > > something
>> > > like home-fontconfig-configuration to provide a dedicated
>> > > fontconfig
>> > > configuration?
>> > I think Ludo means that we should provide the most useful options
>> > (like the fontconfig dirs) as dedicated record fields, while
>> > leaving an "extra-config" escape hatch, that can be used with SXML
>> > or a raw string for stuff that's too complicated (my personal
>> > preference would still be SXML over the raw string, but YMMV).
>>
>> I see.  For example,
>>
>> For example, would it be as follows?
>>
>> --8<---------------cut here---------------start------------->8---
>> (service home-fontconfig-service-type
>>   (home-fontconfig-configuration
>>     (dir "~/.config/fontconfig/my-fonts1.conf"))
>>   (extra-config
>>     (list
>>       "<dir>~/.config/fontconfig/my-fonts2.conf")))
>> --8<---------------cut here---------------end--------------->8---
> Since you can specify more than one dir, that'd be "dirs" or even
> something more helpful like "font-directories".  Note that those are
> directories and not config files.
>
> You corrected the extra-config thing in your reply, but also be aware
> of the extra-config as SXML option.
>
>>
>> > > I have been reading the DTD and think it might be a bit of a
>> > > challenge.
>> > > https://github.com/freedesktop/fontconfig/blob/e291fda7d42e5d64379555097a066d9c2c4efce3/fonts.dtd
>> > >
>> > > However, I did notice one thing, and that is that there is an
>> > > include element.  I thought that if we had a configuration where
>> > > the include element could be added, we could handle most of the
>> > > use cases.  What do you think of this idea?
>> > I'd prefer extra-config over include – extra-config doesn't need to
>> > go through file-like objects and an additional layer of G-
>> > Expression quoting.
>> >
>> > Cheers
>>
>> It is difficult to determine which rules to define as records, but I
>> thought that if I only had includes, I could handle most use cases.
> Go for the obvious low-hanging fruits and typical use cases first.
> Don't just add a field that requires a depth of 3 or more to be useful.
>
>> For example, we assume that you will be able to write settings as
>> follows:
>>
>> --8<---------------cut here---------------start------------->8---
>> (service home-fontconfig-service-type
>>   (home-fontconfig-configuration
>>     (includes
>>       (list
>>         (include
>>           (path "~/.config/fontconfig/my-fonts1.conf")
>>           (ignore-missing #t))))))
>> --8<---------------cut here---------------end--------------->8---
>>
>> ref:
>> https://github.com/freedesktop/fontconfig/blob/e291fda7d42e5d64379555097a066d9c2c4efce3/fonts.dtd#L59-L74
>>
>> Would it also fit with your assumption if we could also specify
>> extra-config here?
>>
>> It is difficult to judge whether the ability to specify includes is
>> useful or not, though, since extra-config alone will do the job.
> Except for possibly some fringe use cases, include will be pointless if
> you have extra-config, which is a better include :)
>
> Cheers

I have designed a configuration interface with a typical font
configuration pattern. (it implemented yet.)

--8<---------------cut here---------------start------------->8---
(service home-fontconfig-service-type
         (home-fontconfig-configuration
          (font-directories
           (list "~/fonts"))
          (prefered-default-font
           (sans-serif "Noto Sans CJK JP")
           (serif "Noto Serif CJK JP")
           (monospace "PlemolJP Console"))
          (extra-config ; Also accepts lists of XML strings.
           `((match (@ (target font))
                    (edit (@ (mode assign)
                             (name antialias))
                          (bool true)))))))
--8<---------------cut here---------------end--------------->8---

This is assumed to be serialized below. (actually, it not pretty-printed.)

--8<---------------cut here---------------start------------->8---
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
  <dir>~/.guix-home/profile/share/fonts</dir>
  <dir>~/fonts</dir>
  <alias>
    <family>sans-serif</family>
    <prefer>
      <family>Noto Sans CJK JP</family>
    </prefer>
  </alias>
  <alias>
    <family>serif</family>
    <prefer>
      <family>Noto Serif CJK JP</family>
    </prefer>
  </alias>
  <alias>
    <family>monospace</family>
    <prefer>
      <family>PlemolJP Console</family>
    </prefer>
  </alias>
  <match target="font">
    <edit mode="assign" name="antialias">
      <bool>true</bool>
    </edit>
  </match>
</fontconfig>
--8<---------------cut here---------------end--------------->8---

How about this?
Liliana Marie Prikler Sept. 26, 2022, 6:19 p.m. UTC | #11
Am Montag, dem 26.09.2022 um 10:43 +0900 schrieb Taiju HIGASHI:
> I have designed a configuration interface with a typical font
> configuration pattern. (it implemented yet.)
> 
> --8<---------------cut here---------------start------------->8---
> (service home-fontconfig-service-type
>          (home-fontconfig-configuration
>           (font-directories
>            (list "~/fonts"))
>           (prefered-default-font
>            (sans-serif "Noto Sans CJK JP")
>            (serif "Noto Serif CJK JP")
>            (monospace "PlemolJP Console"))
>           (extra-config ; Also accepts lists of XML strings.
>            `((match (@ (target font))
>                     (edit (@ (mode assign)
>                              (name antialias))
>                           (bool true)))))))
> --8<---------------cut here---------------end--------------->8---
> 
> This is assumed to be serialized below. (actually, it not pretty-
> printed.)
> 
> --8<---------------cut here---------------start------------->8---
> <?xml version='1.0'?>
> <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
> <fontconfig>
>   <dir>~/.guix-home/profile/share/fonts</dir>
>   <dir>~/fonts</dir>
>   <alias>
>     <family>sans-serif</family>
>     <prefer>
>       <family>Noto Sans CJK JP</family>
>     </prefer>
>   </alias>
>   <alias>
>     <family>serif</family>
>     <prefer>
>       <family>Noto Serif CJK JP</family>
>     </prefer>
>   </alias>
>   <alias>
>     <family>monospace</family>
>     <prefer>
>       <family>PlemolJP Console</family>
>     </prefer>
>   </alias>
>   <match target="font">
>     <edit mode="assign" name="antialias">
>       <bool>true</bool>
>     </edit>
>   </match>
> </fontconfig>
> --8<---------------cut here---------------end--------------->8---
LGTM
diff mbox series

Patch

diff --git a/gnu/home/services/fontutils.scm b/gnu/home/services/fontutils.scm
index 6062eaed6a..b57cccbaae 100644
--- a/gnu/home/services/fontutils.scm
+++ b/gnu/home/services/fontutils.scm
@@ -1,6 +1,7 @@ 
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
 ;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
+;;; Copyright © 2022 Taiju HIGASHI <higashi@taiju.info>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -21,6 +22,9 @@  (define-module (gnu home services fontutils)
   #:use-module (gnu home services)
   #:use-module (gnu packages fontutils)
   #:use-module (guix gexp)
+  #:use-module (srfi srfi-1)
+  #:use-module (sxml simple)
+  #:use-module (ice-9 match)
 
   #:export (home-fontconfig-service-type))
 
@@ -33,15 +37,28 @@  (define-module (gnu home services fontutils)
 ;;;
 ;;; Code:
 
-(define (add-fontconfig-config-file he-symlink-path)
+(define (parse-extra-user-config extra-user-config)
+  (map (match-lambda
+         ((? pair? sxml) sxml)
+         ((? string? xml) (xml->sxml xml))
+         (_ (error "extra-user-config must be xml string or sxml.")))
+       extra-user-config))
+
+(define (add-fontconfig-config-file extra-user-config)
   `(("fontconfig/fonts.conf"
      ,(mixed-text-file
        "fonts.conf"
        "<?xml version='1.0'?>
 <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
-<fontconfig>
-  <dir>~/.guix-home/profile/share/fonts</dir>
-</fontconfig>"))))
+"
+       (call-with-output-string
+         (lambda (port)
+           (sxml->xml
+            `(fontconfig
+              (dir "~/.guix-home/profile/share/fonts")
+              ,@(parse-extra-user-config extra-user-config))
+            port)
+           (newline port)))))))
 
 (define (regenerate-font-cache-gexp _)
   `(("profile/share/fonts"
@@ -49,6 +66,8 @@  (define (regenerate-font-cache-gexp _)
 
 (define home-fontconfig-service-type
   (service-type (name 'home-fontconfig)
+                (compose concatenate)
+                (extend append)
                 (extensions
                  (list (service-extension
                         home-xdg-configuration-files-service-type
@@ -59,7 +78,7 @@  (define home-fontconfig-service-type
                        (service-extension
                         home-profile-service-type
                         (const (list fontconfig)))))
-                (default-value #f)
+                (default-value '())
                 (description
                  "Provides configuration file for fontconfig and make
 fc-* utilities aware of font packages installed in Guix Home's profile.")))