;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014, 2015, 2016, 2018, 2019 Ludovic Courtès ;;; Copyright © 2014, 2017 Mark H Weaver ;;; Copyright © 2014 Joshua Grant ;;; Copyright © 2014 Alex Kost ;;; Copyright © 2015 Sou Bunnbu ;;; Copyright © 2015 Eric Dvorsak ;;; Copyright © 2015, 2017 Ricardo Wurmus ;;; Copyright © 2015, 2016 Leo Famulari ;;; Copyright © 2016, 2017, 2018 Nikita ;;; Copyright © 2016 Jookia <166291@gmail.com> ;;; Copyright © 2016 Eric Bavier ;;; Copyright © 2016 Dmitry Nikolaev ;;; Copyright © 2016, 2017, 2018, 2019, 2020 Efraim Flashner ;;; Copyright © 2016, 2020 Marius Bakke ;;; Copyright © 2016 Toni Reina ;;; Copyright © 2017–2021 Tobias Geerinckx-Rice ;;; Copyright © 2017 José Miguel S
aboutsummaryrefslogtreecommitdiff
blob: e14ceca231cf511d36308423854acf37c933ce22 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2013, 2014, 2015, 2016, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
;;; Copyright © 2018 Carlo Zancanaro <carlo@zancanaro.id.au>
;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu services shepherd)
  #:use-module (guix ui)
  #:use-module (guix sets)
  #:use-module (guix gexp)
  #:use-module (guix store)
  #:use-module (guix records)
  #:use-module (guix derivations)                 ;imported-modules, etc.
  #:use-module (guix utils)
  #:use-module (gnu services)
  #:use-module (gnu services herd)
  #:use-module (gnu packages admin)
  #:use-module (ice-9 match)
  #:use-module (ice-9 vlist)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-26)
  #:use-module (srfi srfi-34)
  #:use-module (srfi srfi-35)
  #:export (shepherd-root-service-type
            %shepherd-root-service
            shepherd-service-type

            shepherd-service
            shepherd-service?
            shepherd-service-documentation
            shepherd-service-provision
            shepherd-service-canonical-name
            shepherd-service-requirement
            shepherd-service-one-shot?
            shepherd-service-respawn?
            shepherd-service-start
            shepherd-service-stop
            shepherd-service-auto-start?
            shepherd-service-modules

            shepherd-action
            shepherd-action?
            shepherd-action-name
            shepherd-action-documentation
            shepherd-action-procedure

            %default-modules

            shepherd-service-file

            shepherd-service-lookup-procedure
            shepherd-service-back-edges
            shepherd-service-upgrade

            user-processes-service-type))

;;; Commentary:
;;;
;;; Instantiating system services as a shepherd configuration file.
;;;
;;; Code:


(define (shepherd-boot-gexp services)
  #~(begin
      ;; Keep track of the booted system.
      (false-if-exception (delete-file "/run/booted-system"))
      (symlink (readlink "/run/current-system")
               "/run/booted-system")

      ;; Close any remaining open file descriptors to be on the safe
      ;; side.  This must be the very last thing we do, because
      ;; Guile has internal FDs such as 'sleep_pipe' that need to be
      ;; alive.
      (let loop ((fd 3))
        (when (< fd 1024)
          (false-if-exception (close-fdes fd))
          (loop (+ 1 fd))))

      ;; Start shepherd.
      (execl #$(file-append shepherd "/bin/shepherd")
             "shepherd" "--config"
             #$(shepherd-configuration-file services))))

(define shepherd-root-service-type
  (service-type
   (name 'shepherd-root)
   ;; Extending the root shepherd service (aka. PID 1) happens by
   ;; concatenating the list of services provided by the extensions.
   (compose concatenate)
   (extend append)
   (extensions (list (service-extension boot-service-type
                                        shepherd-boot-gexp)
                     (service-extension profile-service-type
                                        (const (list shepherd)))))
   (description
    "Run the GNU Shepherd as PID 1---i.e., the operating system's first
process.  The Shepherd takes care of managing services such as daemons by
ensuring they are started and stopped in the right order.")))

(define %shepherd-root-service
  ;; The root shepherd service, aka. PID 1.  Its parameter is a list of
  ;; <shepherd-service> objects.
  (service shepherd-root-service-type '()))

(define-syntax shepherd-service-type
  (syntax-rules ()
    "Return a <service-type> denoting a simple shepherd service--i.e., the type
for a service that extends SHEPHERD-ROOT-SERVICE-TYPE and nothing else.  When
DEFAULT is given, use it as the service's default value."
    ((_ service-name proc default)
     (service-type
      (name service-name)
      (extensions
       (list (service-extension shepherd-root-service-type
                                (compose list proc))))
      (default-value default)))
    ((_ service-name proc)
     (service-type
      (name service-name)
      (extensions
       (list (service-extension shepherd-root-service-type
                                (compose list proc))))))))

(define %default-imported-modules
  ;; Default set of modules imported for a service's consumption.
  '((guix build utils)
    (guix build syscalls)))

(define %default-modules
  ;; Default set of modules visible in a service's file.
  `((shepherd service)
    (oop goops)
    ((guix build utils) #:hide (delete))
    (guix build syscalls)))

(define-record-type* <shepherd-service>
  shepherd-service make-shepherd-service
  shepherd-service?
  (documentation shepherd-service-documentation        ;string
                 (default "[No documentation.]"))
  (provision     shepherd-service-provision)           ;list of symbols
  (requirement   shepherd-service-requirement          ;list of symbols
                 (default '()))
  (one-shot?     shepherd-service-one-shot?            ;Boolean
                 (default #f))
  (respawn?      shepherd-service-respawn?             ;Boolean
                 (default #t))
  (start         shepherd-service-start)               ;g-expression (procedure)
  (stop          shepherd-service-stop                 ;g-expression (procedure)
                 (default #~(const #f)))
  (actions       shepherd-service-actions              ;list of <shepherd-action>
                 (default '()))
  (auto-start?   shepherd-service-auto-start?          ;Boolean
                 (default #t))
  (modules       shepherd-service-modules              ;list of module names
                 (default %default-modules)))

(define-record-type* <shepherd-action>
  shepherd-action make-shepherd-action
  shepherd-action?
  (name          shepherd-action-name)            ;symbol
  (procedure     shepherd-action-procedure)       ;gexp
  (documentation shepherd-action-documentation))  ;string

(define (shepherd-service-canonical-name service)
  "Return the 'canonical name' of SERVICE."
  (first (shepherd-service-provision service)))

(define (assert-valid-graph services)
  "Raise an error if SERVICES does not define a valid shepherd service graph,
for instance if a service requires a nonexistent service, or if more than one
service uses a given name.

These are constraints that shepherd's 'register-service' verifies but we'd
better verify them here statically than wait until PID 1 halts with an
assertion failure."
  (define provisions
    ;; The set of provisions (symbols).  Bail out if a symbol is given more
    ;; than once.
    (fold (lambda (service set)
            (define (assert-unique symbol)
              (when (set-contains? set symbol)
                (raise (condition
                        (&message
                         (message
                          (format #f (G_ "service '~a' provided more than once")
                                  symbol)))))))

            (for-each assert-unique (shepherd-service-provision service))
            (fold set-insert set (shepherd-service-provision service)))
          (setq 'shepherd)
          services))

  (define (assert-satisfied-requirements service)
    ;; Bail out if the requirements of SERVICE aren't satisfied.
    (for-each (lambda (requirement)
                (unless (set-contains? provisions requirement)
                  (raise (condition
                          (&message
                           (message
                            (format #f (G_ "service '~a' requires '~a', \
which is not provided by any service")
                                    (match (shepherd-service-provision service)
                                      ((head . _) head)
                                      (_          service))
                                    requirement)))))))
              (shepherd-service-requirement service)))

  (for-each assert-satisfied-requirements services))

(define (shepherd-service-file-name service)
  "Return the file name where the initialization code for SERVICE is to be
stored."
  (let ((provisions (string-join (map symbol->string
                                      (shepherd-service-provision service)))))
    (string-append "shepherd-"
                   (string-map (match-lambda
                                 (#\/ #\-)
                                 (#\  #\-)
                                 (chr chr))
                               provisions)
                   ".scm")))

(define (shepherd-service-file service)
  "Return a file defining SERVICE."
  (scheme-file (shepherd-service-file-name service)
               (with-imported-modules %default-imported-modules
                 #~(begin
                     (use-modules #$@(shepherd-service-modules service))

                     (make <service>
                       #:docstring '#$(shepherd-service-documentation service)
                       #:provides '#$(shepherd-service-provision service)
                       #:requires '#$(shepherd-service-requirement service)

                       ;; The 'one-shot?' slot is new in Shepherd 0.6.0.
                       ;; Older versions ignore it.
                       #:one-shot? '#$(shepherd-service-one-shot? service)

                       #:respawn? '#$(shepherd-service-respawn? service)
                       #:start #$(shepherd-service-start service)
                       #:stop #$(shepherd-service-stop service)
                       #:actions
                       (make-actions
                        #$@(map (match-lambda
                                  (($ <shepherd-action> name proc doc)
                                   #~(#$name #$doc #$proc)))
                                (shepherd-service-actions service))))))))

(define (scm->go file)
  "Compile FILE, which contains code to be loaded by shepherd's config file,
and return the resulting '.go' file."
  (let-system (system target)
    (with-extensions (list shepherd)
      (computed-file (string-append (basename (scheme-file-name file) ".scm")
                                    ".go")
                     #~(begin
                         (use-modules (system base compile)
                                      (system base target))

                         ;; Do the same as the Shepherd's 'load-in-user-module'.
                         (let ((env (make-fresh-user-module)))
                           (module-use! env (resolve-interface '(oop goops)))
                           (module-use! env (resolve-interface '(shepherd service)))
                           (with-target #$(or target #~%host-type)
                             (lambda _
                               (compile-file #$file #:output-file #$output
                                             #:env env)))))

                     ;; It's faster to build locally than to download.
                     #:options '(#:local-build? #t
                                 #:substitutable? #f)))))

(define (shepherd-configuration-file services)
  "Return the shepherd configuration file for SERVICES."
  (assert-valid-graph services)

  (let ((files (map shepherd-service-file services)))
    (define config
      #~(begin
          (use-modules (srfi srfi-34)
                       (system repl error-handling))

          ;; Specify the default environment visible to all the services.
          ;; Without this statement, all the environment variables of PID 1
          ;; are inherited by child services.
          (default-environment-variables
            '("PATH=/run/current-system/profile/bin"))

          ;; Booting off a DVD, especially on a slow machine, can make
          ;; everything slow.  Thus, increase the timeout compared to the
          ;; default 5s in the Shepherd 0.7.0.  See
          ;; <https://bugs.gnu.org/40572>.
          (default-pid-file-timeout 30)

          ;; Arrange to spawn a REPL if something goes wrong.  This is better
          ;; than a kernel panic.
          (call-with-error-handling
            (lambda ()
              (apply register-services
                     (parameterize ((current-warning-port
                                     (%make-void-port "w")))
                       (map load-compiled '#$(map scm->go files))))))

          (format #t "starting services...~%")
          (for-each (lambda (service)
                      ;; In the Shepherd 0.3 the 'start' method can raise
                      ;; '&action-runtime-error' if it fails, so protect
                      ;; against it.  (XXX: 'action-runtime-error?' is not
                      ;; exported is 0.3, hence 'service-error?'.)
                      (guard (c ((service-error? c)
                                 (format (current-error-port)
                                         "failed to start service '~a'~%"
                                         service)))
                        (start service)))
                    '#$(append-map shepherd-service-provision
                                   (filter shepherd-service-auto-start?
                                           services)))

          ;; Hang up stdin.  At this point, we assume that 'start' methods
          ;; that required user interaction on the console (e.g.,
          ;; 'cryptsetup open' invocations, post-fsck emergency REPL) have
          ;; completed.  User interaction becomes impossible after this
          ;; call; this avoids situations where services wrongfully lead
          ;; PID 1 to read from stdin (the console), which users may not
          ;; have access to (see <https://bugs.gnu.org/23697>).
          (redirect-port (open-input-file "/dev/null")
                         (current-input-port))))

    (scheme-file "shepherd.conf" config)))

(define* (shepherd-service-lookup-procedure services
                                            #:optional
                                            (provision
                                             shepherd-service-provision))
  "Return a procedure that, when passed a symbol, return the item among
SERVICES that provides this symbol.  PROVISION must be a one-argument
procedure that takes a service and returns the list of symbols it provides."
  (let ((services (fold (lambda (service result)
                          (fold (cut vhash-consq <> service <>)
                                result
                                (provision service)))
                        vlist-null
                        services)))
    (lambda (name)
      (match (vhash-assq name services)
        ((_ . service) service)
        (#f            #f)))))

(define* (shepherd-service-back-edges services
                                      #:key
                                      (provision shepherd-service-provision)
                                      (requirement shepherd-service-requirement))
  "Return a procedure that, when given a <shepherd-service> from SERVICES,
returns the list of <shepherd-service> that depend on it.

Use PROVISION and REQUIREMENT as one-argument procedures that return the
symbols provided/required by a service."
  (define provision->service
    (shepherd-service-lookup-procedure services provision))

  (define edges
    (fold (lambda (service edges)
            (fold (lambda (requirement edges)
                    (vhash-consq (provision->service requirement) service
                                 edges))
                  edges
                  (requirement service)))
          vlist-null
          services))

  (lambda (service)
    (vhash-foldq* cons '() service edges)))

(define (shepherd-service-upgrade live target)
  "Return two values: the subset of LIVE (a list of <live-service>) that needs
to be unloaded, and the subset of TARGET (a list of <shepherd-service>) that
need to be restarted to complete their upgrade."
  (define (essential? service)
    (memq (first (live-service-provision service))
          '(root shepherd)))

  (define lookup-target
    (shepherd-service-lookup-procedure target
                                       shepherd-service-provision))

  (define lookup-live
    (shepherd-service-lookup-procedure live
                                       live-service-provision))

  (define (running? service)
    (and=> (lookup-live (shepherd-service-canonical-name service))
           live-service-running))

  (define live-service-dependents
    (shepherd-service-back-edges live
                                 #:provision live-service-provision
                                 #:requirement live-service-requirement))

  (define (obsolete? service)
    (match (lookup-target (first (live-service-provision service)))
      (#f (every obsolete? (live-service-dependents service)))
      (_  #f)))

  (define to-restart
    ;; Restart services that are currently running.
    (filter running? target))

  (define to-unload
    ;; Unload services that are no longer required.
    (remove essential? (filter obsolete? live)))

  (values to-unload to-restart))


;;;
;;; User processes.
;;;

(define %do-not-kill-file
  ;; Name of the file listing PIDs of processes that must survive when halting
  ;; the system.  Typical example is user-space file systems.
  "/etc/shepherd/do-not-kill")

(define (user-processes-shepherd-service requirements)
  "Return the 'user-processes' Shepherd service with dependencies on
REQUIREMENTS (a list of service names).

This is a synchronization point used to make sure user processes and daemons
get started only after crucial initial services have been started---file
system mounts, etc.  This is similar to the 'sysvinit' target in systemd."
  (define grace-delay
    ;; Delay after sending SIGTERM and before sending SIGKILL.
    4)

  (list (shepherd-service
         (documentation "When stopped, terminate all user processes.")
         (provision '(user-processes))
         (requirement requirements)
         (start #~(const #t))
         (stop #~(lambda _
                   (define (kill-except omit signal)
                     ;; Kill all the processes with SIGNAL except those listed
                     ;; in OMIT and the current process.
                     (let ((omit (cons (getpid) omit)))
                       (for-each (lambda (pid)
                                   (unless (memv pid omit)
                                     (false-if-exception
                                      (kill pid signal))))
                                 (processes))))

                   (define omitted-pids
                     ;; List of PIDs that must not be killed.
                     (if (file-exists? #$%do-not-kill-file)
                         (map string->number
                              (call-with-input-file #$%do-not-kill-file
                                (compose string-tokenize
                                         (@ (ice-9 rdelim) read-string))))
                         '()))

                   (define (now)
                     (car (gettimeofday)))

                   (define (sleep* n)
                     ;; Really sleep N seconds.
                     ;; Work around <http://bugs.gnu.org/19581>.
                     (define start (now))
                     (let loop ((elapsed 0))
                       (when (> n elapsed)
                         (sleep (- n elapsed))
                         (loop (- (now) start)))))

                   (define lset= (@ (srfi srfi-1) lset=))

                   (display "sending all processes the TERM signal\n")

                   (if (null? omitted-pids)
                       (begin
                         ;; Easy: terminate all of them.
                         (kill -1 SIGTERM)
                         (sleep* #$grace-delay)
                         (kill -1 SIGKILL))
                       (begin
                         ;; Kill them all except OMITTED-PIDS.  XXX: We would
                         ;; like to (kill -1 SIGSTOP) to get a fixed list of
                         ;; processes, like 'killall5' does, but that seems
                         ;; unreliable.
                         (kill-except omitted-pids SIGTERM)
                         (sleep* #$grace-delay)
                         (kill-except omitted-pids SIGKILL)
                         (delete-file #$%do-not-kill-file)))

                   (let wait ()
                     ;; Reap children, if any, so that we don't end up with
                     ;; zombies and enter an infinite loop.
                     (let reap-children ()
                       (define result
                         (false-if-exception
                          (waitpid WAIT_ANY (if (null? omitted-pids)
                                                0
                                                WNOHANG))))

                       (when (and (pair? result)
                                  (not (zero? (car result))))
                         (reap-children)))

                     (let ((pids (processes)))
                       (unless (lset= = pids (cons 1 omitted-pids))
                         (format #t "waiting for process termination\
 (processes left: ~s)~%"
                                 pids)
                         (sleep* 2)
                         (wait))))

                   (display "all processes have been terminated\n")
                   #f))
         (respawn? #f))))

(define user-processes-service-type
  (service-type
   (name 'user-processes)
   (extensions (list (service-extension shepherd-root-service-type
                                        user-processes-shepherd-service)))
   (compose concatenate)
   (extend append)

   ;; The value is the list of Shepherd services 'user-processes' depends on.
   ;; Extensions can add new services to this list.
   (default-value '())

   (description "The @code{user-processes} service is responsible for
terminating all the processes so that the root file system can be re-mounted
read-only, just before rebooting/halting.  Processes still running after a few
seconds after @code{SIGTERM} has been sent are terminated with
@code{SIGKILL}.")))

;;; shepherd.scm ends here
fine-public font-fira-sans (package (name "font-fira-sans") (version "4.202") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/mozilla/Fira") (commit version))) (file-name (git-file-name name version)) (sha256 (base32 "116j26gdj5g1r124b4669372f7490vfjqw7apiwp2ggl0am5xd0w")))) (build-system font-build-system) (home-page "https://mozilla.github.io/Fira/") (synopsis "Mozilla's Fira Sans Font") (description "This is the typeface used by Mozilla in Firefox OS.") (license license:silofl1.1))) (define-public font-fira-go (package (name "font-fira-go") (version "1.000") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/bBoxType/FiraGO") (commit version))) (file-name (git-file-name name version)) (sha256 (base32 "10rcfg1fijv00yxv5n9l3lm0axhafa1irkg42zpmasd70flgg655")))) (build-system font-build-system) (home-page "https://github.com/bBoxType/FiraGO") (synopsis "Multilingual extension of the Fira Sans font family") (description "FiraGO is a multilingual extension of the Fira Sans font family. Based on the Fira Sans 4.3 glyph set, FiraGO adds support for the Arabic, Devanagari, Georgian, Hebrew and Thai scripts.") (license license:silofl1.1))) (define-public font-fira-code (package (name "font-fira-code") (version "5.2") (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/tonsky/FiraCode/releases/" "download/" version "/Fira_Code_v" version ".zip")) (sha256 (base32 "1zayrb6k0gd7xdvx7yx44dpip767q0bzhqwf4j6nf8nx02z746jj")))) (build-system font-build-system) (home-page "https://mozilla.github.io/Fira/") (synopsis "Monospaced font with programming ligatures") (description "Fira Code is an extension of the Fira Mono font containing a set of ligatures for common programming multi-character combinations. This is just a font rendering feature: underlying code remains ASCII-compatible. This helps to read and understand code faster. For some frequent sequences like .. or //, ligatures allow us to correct spacing.") (license license:silofl1.1))) (define-public font-awesome (package (name "font-awesome") ;; XXX The build scripts of version 5 are not freely licensed and ;; so we have to stick with version 4 for now: ;; (version "4.7.0") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/FortAwesome/Font-Awesome") (commit (string-append "v" version)))) (file-name (git-file-name name version)) (sha256 (base32 "0w30y26jp8nvxa3iiw7ayl6rkza1rz62msl9xw3srvxya1c77grc")))) (build-system font-build-system) (arguments '(#:phases (modify-phases %standard-phases (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (source (string-append (getcwd) "/fonts")) (fonts (string-append out "/share/fonts"))) (for-each (lambda (file) (install-file file (string-append fonts "/truetype"))) (find-files source "\\.(ttf|ttc)$")) (for-each (lambda (file) (install-file file (string-append fonts "/opentype"))) (find-files source "\\.(otf|otc)$")) #t)))))) (home-page "https://fontawesome.com/") (synopsis "Font that contains a rich iconset") (description "Font Awesome is a full suite of pictographic icons for easy scalable vector graphics.") (license license:silofl1.1))) (define-public font-tamzen (package (name "font-tamzen") (version "1.11.5") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/sunaku/tamzen-font") (commit (string-append "Tamzen-" version)))) (file-name (git-file-name name version)) (sha256 (base32 "00x5fipzqimglvshhqwycdhaqslbvn3rl06jnswhyxfvz16ymj7s")))) (build-system trivial-build-system) (arguments `(#:modules ((guix build utils)) #:builder (begin (use-modules (guix build utils)) (let* ((out (assoc-ref %outputs "out")) (font-dir (string-append out "/share/fonts/misc")) (psf-dir (string-append out "/share/kbd/consolefonts"))) (chdir (assoc-ref %build-inputs "source")) (mkdir-p font-dir) (mkdir-p psf-dir) (for-each (lambda (pcf) (install-file pcf font-dir)) (find-files "pcf" "\\.pcf$")) (for-each (lambda (psf) (install-file psf psf-dir)) (find-files "psf" "\\.psf$")) #t)))) (home-page "https://github.com/sunaku/tamzen-font") (synopsis "Monospaced bitmap font for console and X11") (description "Tamzen is a fork of the @code{Tamsyn} font. It is programmatically forked from @code{Tamsyn} version 1.11, backporting glyphs from older versions while deleting deliberately empty glyphs (which are marked as unimplemented) to allow secondary/fallback fonts to provide real glyphs at those codepoints. The @code{TamzenForPowerline} fonts provide additional @code{Powerline} symbols, which are programmatically injected with @code{bitmap-font-patcher} and later hand-tweaked with the gbdfed(1) editor: @enumerate @item all icons are expanded to occupy the maximum available space @item the branch of the fork icon ( U+E0A0) was made larger than the trunk @item for the newline icon ( U+E0A1), the @emph{N} was made larger at the bottom @item the keyhole in the padlock icon ( U+E0A2) was replaced with @emph{//} lines. @end enumerate\n") (license (license:non-copyleft "file://LICENSE")))) (define-public font-comic-neue (package (name "font-comic-neue") (version "2.51") (source (origin (method url-fetch/zipbomb) (uri (string-append "http://www.comicneue.com/comic-neue-" version ".zip")) (sha256 (base32 "0883542v915crz98v1ij6smgy40dg6gxwsid3j5nbmmqjf69kpal")))) (build-system font-build-system) (arguments `(#:phases (modify-phases %standard-phases ;; Delete Mac OS X specific files. If not deleted, these cause ;; several hidden files to be installed. (add-before 'install 'delete-macosx-files (lambda _ (delete-file-recursively "__MACOSX") #t)) (add-after 'install 'install-conf (lambda* (#:key outputs #:allow-other-keys) (let ((conf-dir (string-append (assoc-ref outputs "out") "/share/fontconfig/conf.avail"))) (mkdir-p conf-dir) (call-with-output-file (string-append conf-dir "/30-comic-neue.conf") (lambda (port) (format port " Comic Sans MS Comic Neue \n")))) #t))))) (home-page "http://www.comicneue.com/") (synopsis "Font that fixes the shortcomings of Comic Sans") (description "Comic Neue is a font that attempts to create a respectable casual typeface, by mimicking Comic Sans while fixing its most obvious shortcomings.") (license license:silofl1.1))) (define-public font-iosevka (package (name "font-iosevka") ;; When updating, also update the hash of the Iosevka variant(s) below. (version "4.0.3") (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/be5invis/Iosevka" "/releases/download/v" version "/ttc-iosevka-" version ".zip")) (sha256 (base32 "1xc45rs09aj899wz9ghyizq6ddbgxpkqq5bl1jc89hls5laf7qjb")))) (build-system font-build-system) (home-page "https://be5invis.github.io/Iosevka/") (synopsis "Coders' typeface, built from code") (description "Iosevka is a slender monospace sans-serif or slab-serif typeface inspired by Pragmata Pro, M+, and PF DIN Mono, designed to be the ideal font for programming. Iosevka is completely generated from its source code.") (license (list license:silofl1.1 ; build artifacts (i.e. the fonts) license:bsd-3)))) ; supporting code (define-public font-iosevka-slab (package (inherit font-iosevka) (name "font-iosevka-slab") (version (package-version font-iosevka)) (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/be5invis/Iosevka" "/releases/download/v" version "/ttc-iosevka-slab-" version ".zip")) (sha256 (base32 "0qpfzyi050zca0bwhb460nvcaarij4srhify0rb8sf9ygpzyvnjh")))))) (define-public font-iosevka-term (package (inherit font-iosevka) (name "font-iosevka-term") (version (package-version font-iosevka)) (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/be5invis/Iosevka" "/releases/download/v" version "/ttf-iosevka-term-" version ".zip")) (sha256 (base32 "092ygzv24wbi8cjjsmq0jkxdf4cm7wqlfj7jkn0cip7nlbyskl3h")))) (arguments `(#:phases (modify-phases %standard-phases (add-before 'install 'make-files-writable (lambda _ (for-each make-file-writable (find-files "." ".*")) #t))))))) (define-public font-iosevka-term-slab (package (inherit font-iosevka) (name "font-iosevka-term-slab") (version (package-version font-iosevka)) (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/be5invis/Iosevka/" "releases/download/v" version "/" "ttf-iosevka-term-slab-" version ".zip")) (sha256 (base32 "157kdxrxz981ympd2iww66v50vm2cxd7z98vvb36rii94hf30k7x")))) (arguments `(#:phases (modify-phases %standard-phases (add-before 'install 'make-files-writable (lambda _ (for-each make-file-writable (find-files "." ".*")) #t))))))) (define-public font-iosevka-aile (package (inherit font-iosevka) (name "font-iosevka-aile") (version (package-version font-iosevka)) (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/be5invis/Iosevka" "/releases/download/v" version "/ttc-iosevka-aile-" version ".zip")) (sha256 (base32 "0n52lfn7awc28a4f5yh4my8q4ikzza705kp69chfw9jm2xx79npc")))))) (define-public font-iosevka-curly (package (inherit font-iosevka) (name "font-iosevka-curly") (version (package-version font-iosevka)) (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/be5invis/Iosevka/" "releases/download/v" version "/" "ttc-iosevka-curly-" version ".zip")) (sha256 (base32 "0m51r0bc25khllq8nsfgsldhwfs7kzl8kqasivjlm14mpv5080fn")))))) (define-public font-iosevka-curly-slab (package (inherit font-iosevka) (name "font-iosevka-curly-slab") (version (package-version font-iosevka)) (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/be5invis/Iosevka/" "releases/download/v" version "/" "ttc-iosevka-curly-slab-" version ".zip")) (sha256 (base32 "0ffiz2kg43kc2dxv48sjji33ra3kc6sy8vlard93c601fqjmrjws")))))) (define-public font-iosevka-etoile (package (inherit font-iosevka) (name "font-iosevka-etoile") (version (package-version font-iosevka)) (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/be5invis/Iosevka" "/releases/download/v" version "/ttc-iosevka-etoile-" version ".zip")) (sha256 (base32 "1fj8g7sjp9idjh14iqk4wsz3rdarlmq7amcdsr0dznwyivx8a9wx")))))) (define-public font-iosevka-sparkle (package (inherit font-iosevka) (name "font-iosevka-sparkle") (version (package-version font-iosevka)) (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/be5invis/Iosevka" "/releases/download/v" version "/ttc-iosevka-sparkle-" version ".zip")) (sha256 (base32 "00dw894930xdikai8bcaimp0a3720diwi0r7ii52jwl4d70w53dx")))))) (define-public font-sarasa-gothic (package (name "font-sarasa-gothic") (version "0.12.7") (source (origin (method url-fetch) (uri (string-append "https://github.com/be5invis/Sarasa-Gothic" "/releases/download/v" version "/sarasa-gothic-ttc-" version ".7z")) (sha256 (base32 "09v65k00g8m953s6riz9xjzb2jgr6v5pdhcllalzzl7c1cn2xl3k")))) (build-system font-build-system) (arguments `(#:phases (modify-phases %standard-phases (replace 'unpack (lambda* (#:key source #:allow-other-keys) (mkdir "source") (chdir "source") (invoke "7z" "x" source)))))) (native-inputs `(("p7zip" ,p7zip))) (home-page "https://github.com/be5invis/Sarasa-Gothic") (license license:silofl1.1) (synopsis "Sarasa Gothic / 更纱黑体 / 更紗黑體 / 更紗ゴシック / 사라사 고딕") (description "Sarasa Gothic is a programming font based on Iosevka and Source Han Sans, most CJK characters are same height, and double width as ASCII characters."))) (define-public font-space-grotesk (package (name "font-space-grotesk") (version "2.0.0") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/floriankarsten/space-grotesk") (commit version))) (file-name (git-file-name name version)) (sha256 (base32 "1aiivn0rl7ydiyqvsr0fa2hx82h3br3x48w3100fcly23n0fdcby")))) (build-system font-build-system) ;; TODO: Package fontmake and gftools and build from source. (arguments `(#:phases (modify-phases %standard-phases (replace 'install-license-files (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (doc (string-append out "/share/doc/" ,name "-" ,version))) (install-file "OFL.txt" doc) #t)))))) (home-page "https://floriankarsten.github.io/space-grotesk/") (synopsis "Proportional variant of the fixed-width Space Mono family") (description "Space Grotesk is a proportional sans-serif typeface variant based on Colophon Foundry's fixed-width Space Mono family. It retains the monospace's idiosyncratic details while optimizing for improved readability at non-display sizes. Space Grotesk includes Latin Vietnamese, Pinyin, and all Western, Central, and South-Eastern European language support, as well as several OpenType features: old-style and tabular figures, superscript and subscript numerals, fractions, and stylistic alternates.") (license license:silofl1.1))) (define-public font-go (let ((commit "f03a046406d4d7fbfd4ed29f554da8f6114049fc") (revision "1")) (package (name "font-go") (version (string-append "20170330-" revision "." (string-take commit 7))) (source (origin (file-name (string-append "go-image-" version "-checkout")) (method git-fetch) (uri (git-reference (url "https://go.googlesource.com/image") (commit commit))) (sha256 (base32 "1aq6mnjayks55gd9ahavk6jfydlq5lm4xm0xk4pd5sqa74p5p74d")))) (build-system font-build-system) (arguments `(#:phases (modify-phases %standard-phases (add-before 'install 'chdir (lambda _ (chdir "font/gofont/ttfs") #t))))) (home-page "https://blog.golang.org/go-fonts") (synopsis "The Go font family") (description "The Go font family is a set of WGL4 TrueType fonts from the Bigelow & Holmes type foundry, released under the same license as the Go programming language. It includes a set of proportional, sans-serif fonts, and a set of monospace, slab-serif fonts.") (license license:bsd-3)))) (define-public font-google-material-design-icons (package (name "font-google-material-design-icons") (version "3.0.1") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/google/material-design-icons") (commit version))) (file-name (git-file-name name version)) (sha256 (base32 "17q5brcqyyc8gbjdgpv38p89s60cwxjlwy2ljnrvas5cj0s62np0")))) (build-system font-build-system) (home-page "https://google.github.io/material-design-icons") (synopsis "Icon font of Google Material Design icons") (description "Material design system icons are simple, modern, friendly, and sometimes quirky. Each icon is created using our design guidelines to depict in simple and minimal forms the universal concepts used commonly throughout a UI. Ensuring readability and clarity at both large and small sizes, these icons have been optimized for beautiful display on all common platforms and display resolutions.") (license license:asl2.0))) (define-public font-opendyslexic (package (name "font-opendyslexic") (version "0.91.12") (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/antijingoist/opendyslexic/" "releases/download/v" version "/opendyslexic-0.910.12-rc2-2019.10.17.zip")) (sha256 (base32 "11ml7v4iyf3hr0fbnkwz8afb8vi58wbcfnmn4gyvrwh9jk5pybdr")))) (build-system font-build-system) (native-inputs `(("unzip" ,unzip))) (home-page "https://opendyslexic.org/") (synopsis "Font for dyslexics and high readability") (description "OpenDyslexic is a font designed to help readability for some of the symptoms of dyslexia. Letters have heavy weighted bottoms to provide an indication of orientation to make it more difficult to confuse with other similar letters. Consistently weighted bottoms can also help reinforce the line of text. The unique shapes of each letter can help prevent flipping and swapping. The italic style for OpenDyslexic has been crafted to be used for emphasis while still being readable.") (license license:silofl1.1))) (define-public font-open-dyslexic (deprecated-package "font-open-dyslexic" font-opendyslexic)) (define-public font-openmoji (package (name "font-openmoji") (version "12.4.0") (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/hfg-gmuend/openmoji/" "releases/download/" version "/openmoji-font.zip")) (sha256 (base32 "0wvvg5vnc950h8v23wfgjyi7rv89mgm5hqq6viqv0bxcc3azglxb")))) (build-system font-build-system) (native-inputs `(("unzip" ,unzip))) (home-page "https://openmoji.org") (synopsis "Font for rendering emoji characters") (description "This package provides the OpenMoji font in both color and black variants.") (license license:cc-by-sa4.0))) (define-public font-dosis (package (name "font-dosis") (version "1.7") (source (origin (method url-fetch/zipbomb) (uri (string-append "https://web.archive.org/web/20180228233737/" "https://www.impallari.com/media/releases/dosis-" "v" version ".zip")) (sha256 (base32 "1qhci68f68mf87jd69vjf9qjq3wydgw1q7ivn3amjb65ls1s0c4s")))) (build-system font-build-system) (home-page (string-append "https://web.archive.org/web/20180228233737/" "https://www.impallari.com/dosis")) (synopsis "Very simple, rounded, sans serif family") (description "Dosis is a very simple, rounded, sans serif family. The lighter weights are minimalist. The bolder weights have more personality. The medium weight is nice and balanced. The overall result is a family that's clean and modern, and can express a wide range of voices & feelings. It comes in 7 incremental weights: ExtraLight, Light, Book, Medium, Semibold, Bold & ExtraBold") (license license:silofl1.1))) (define-public font-culmus (package (name "font-culmus") (version "0.133") (source (origin (method url-fetch) (uri (string-append "https://sourceforge.net/projects/" "culmus/files/culmus/" version "/culmus-src-" version ".tar.gz")) (sha256 (base32 "02akysgsqhi15cck54xcacm16q5raf4l7shgb8fnj7xr3c1pbfyp")))) (build-system font-build-system) (arguments `(#:phases (modify-phases %standard-phases (add-before 'install 'build (lambda _ (let ((compile (lambda (name ext) (invoke "fontforge" "-lang=ff" "-c" (string-append "Open('" name "');" "Generate('" (basename name "sfd") ext "')"))))) ;; This part based on the fonts shipped in the non-source package. (for-each (lambda (name) (compile name "ttf")) (find-files "." "^[^Nachlieli].*\\.sfd$")) (for-each (lambda (name) (compile name "otf")) (find-files "." "^Nachlieli.*\\.sfd$")) #t)))))) (native-inputs `(("fontforge" ,fontforge))) (home-page "http://culmus.sourceforge.net/") (synopsis "TrueType Hebrew Fonts for X11") (description "14 Hebrew trivial families. Contain ASCII glyphs from various sources. Those families provide a basic set of a serif (Frank Ruehl), sans serif (Nachlieli) and monospaced (Miriam Mono) trivials. Also included Miriam, Drugulin, Aharoni, David, Hadasim etc. Cantillation marks support is available in Keter YG.") (license license:gpl2))) ; consult the LICENSE file included (define-public font-lohit (package (name "font-lohit") (version "20140220") (source (origin (method url-fetch) (uri (string-append "https://releases.pagure.org/lohit/lohit-ttf-" version ".tar.gz")) (sha256 (base32 "1rmgr445hw1n851ywy28csfvswz1i6hnc8mzp88qw2xk9j4dn32d")))) (build-system font-build-system) (home-page "https://pagure.io/lohit") (synopsis "Lohit TrueType Indic fonts") (description "Lohit is a font family designed to cover Indic scripts. Lohit supports the Assamese, Bengali, Devanagari (Hindi, Kashmiri, Konkani, Maithili, Marathi, Nepali, Sindhi, Santali, Bodo, Dogri languages), Gujarati, Kannada, Malayalam, Manipuri, Oriya, Punjabi, Tamil and Telugu scripts.") (license license:silofl1.1))) (define-public font-blackfoundry-inria (package (name "font-blackfoundry-inria") (version "1.200") (home-page "https://github.com/BlackFoundry/InriaFonts") (source (origin (method git-fetch) (uri (git-reference (url home-page) (commit (string-append "v" version)))) (sha256 (base32 "06775y99lyh6hj5hzvrx56iybdck8a8xfqkipqd5c4cldg0a9hh8")) (file-name (string-append name "-" version "-checkout")))) ;; XXX: There are .ufo directories (the "source") so in theory we should ;; be able to rebuild TTF and OTF files with FontForge. Unfortunately a ;; command like: ;; ;; fontforge -lang=ff -c "Open('InriaSans-Regular.ufo'); Generate('foo.ttf');" ;; ;; segfaults in '_UFOLoadGlyph', which calls out to libpython. :-/ ;; In the meantime we ship the precompiled OTF and TTF files. (build-system font-build-system) (synopsis "Inria Sans and Inria Serif type family") (description "Inria Sans and Inria Serif are the two members of a type family designed for Inria, a public research institute in computer science and mathematics.") (license license:silofl1.1))) (define-public font-sil-gentium (package (name "font-sil-gentium") (version "5.000") (source (origin (method url-fetch) (uri (string-append "https://software.sil.org/downloads/r/gentium/GentiumPlus-" version ".zip")) (sha256 (base32 "0m7189870hha217n1vgpmf89mwggrxkh679ffi1lxpnjggqi2n9k")))) ;; Note: The zip file provides TTF files only, but the developer release, ;; which contains additional files, has a 'SOURCES.txt' file that says ;; that "the primary source files for the fonts are the fonts themselves". ;; Thus it looks like the TTF can be considered source. (build-system font-build-system) (synopsis "Serif font for the Cyrillic, Greek, and Latin alphabets") (description "Gentium is a typeface family designed to enable the diverse ethnic groups around the world who use the Latin, Cyrillic and Greek scripts to produce readable, high-quality publications. The font comes with regular and italics shapes. This package provides only TrueType files (TTF).") (home-page "https://software.sil.org/gentium/") (license license:silofl1.1))) (define-public font-sil-andika (package (name "font-sil-andika") (version "5.000") (source (origin (method url-fetch) (uri (string-append "https://software.sil.org/downloads/r/andika/Andika-" version ".zip")) (sha256 (base32 "01zm7p32gxfwmv7h3cfj2vx59846w2y6rxqy67grn2dyjh8pljv0")))) ;; As for Gentium (see above), the TTF files are considered source. (build-system font-build-system) (synopsis "Sans serif font designed especially for literacy use") (description "Andika SIL is a sans serif, Unicode-compliant font designed especially for literacy use, taking into account the needs of beginning readers. The focus is on clear, easy-to-perceive letterforms that will not be readily confused with one another. This package provides only TrueType files (TTF).") (home-page "https://software.sil.org/andika/") (license license:silofl1.1))) (define-public font-sil-charis (package (name "font-sil-charis") (version "5.000") (source (origin (method url-fetch) (uri (string-append "https://software.sil.org/downloads/r/charis/CharisSIL-" version ".zip")) (sha256 (base32 "1zcvw37f1a7gkml3yfm6hxh93844llm7xj4w52600qq3ndrm8gjy")))) ;; As for Gentium (see above), the TTF files are considered source. (build-system font-build-system) (synopsis "Serif font for the Cyrillic and Latin alphabets") (description "Charis SIL is a Unicode-based font family that supports the wide range of languages that use the Latin and Cyrillic scripts. It is specially designed to make long texts pleasant and easy to read, even in less than ideal reproduction and display environments. This package provides only TrueType files (TTF).") (home-page "https://software.sil.org/charis/") (license license:silofl1.1))) (define-public font-mononoki (package (name "font-mononoki") (version "1.2") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/madmalik/mononoki/") (commit version))) (sha256 (base32 "1rkzyxn30rn8qv2h2xz324j7q15hzg2lci8790a7cdl1dfgic4xi")) (file-name (git-file-name name version)))) (build-system font-build-system) (synopsis "Font for programming and code review") (description "Mononoki is a typeface by Matthias Tellen, created to enhance code formatting.") (home-page "https://madmalik.github.io/mononoki/") (license license:silofl1.1))) (define-public font-public-sans (package (name "font-public-sans") (version "1.008") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/uswds/public-sans") (commit (string-append "v" version)))) (file-name (git-file-name name version)) (sha256 (base32 "1qhyxbjv1rnydfpqzd18fbiyz75p4sabphy8yj07hyq0hidp5xsf")))) (build-system font-build-system) (home-page "https://public-sans.digital.gov/") (synopsis "Neutral typeface for interfaces, text, and headings") (description "Public Sans is a strong, neutral, sans-serif typeface for text or display based on Libre Franklin.") (license license:silofl1.1))) (define-public font-hermit (package (name "font-hermit") (version "2.0") (source (origin (method url-fetch/tarbomb) (uri (string-append "https://pcaro.es/d/otf-hermit-" version ".tar.gz")) (sha256 (base32 "09rmy3sbf1j1hr8zidighjgqc8kp0wsra115y27vrnlf10ml6jy0")))) (build-system font-build-system) (arguments `(#:tests? #f)) (home-page "https://pcaro.es/p/hermit/") (synopsis "Monospace font") (description "Hermit is a monospace font designed to be clear, pragmatic and very readable. Its creation has been focused on programming. Every glyph was carefully planned and calculated, according to defined principles and rules. For this reason, Hermit is coherent and regular. Symbols stand out from common text. Dots and commas are easily seen, and operators are clear even when not surrounded by spaces. Similar characters have been designed to be very distinguishable from each other.") (license license:silofl1.1))) (define-public font-dseg (package (name "font-dseg") (version "0.46") (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/keshikan/DSEG/" "releases/download/v" version "/fonts-DSEG_v" (string-concatenate (string-split version #\.)) ".zip")) (sha256 (base32 "13133kpa1ndsji9yq5ppkds5yq2y094qvrv2f83ah74p40sz9hm6")))) (build-system font-build-system) (arguments `(#:phases (modify-phases %standard-phases (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (font-dir (string-append out "/share/fonts")) (truetype-dir (string-append font-dir "/truetype"))) (with-directory-excursion (string-append "fonts-DSEG_v" (apply string-append (string-split ,version #\.))) (for-each (lambda (f) (install-file f truetype-dir)) (find-files "." "\\.ttf$")) #t))))))) (home-page "https://www.keshikan.net/fonts-e.html") (synopsis "DSEG: 7-segment and 14-segment fonts") (description "DSEG is a font family that imitates seven- and fourteen-segment LCD displays (7SEG, 14SEG). DSEG includes the roman alphabet and symbol glyphs. This package provides the TrueType fonts.") (license license:silofl1.1))) (define-public font-jetbrains-mono (package (name "font-jetbrains-mono") (version "2.221") (source (origin (method url-fetch) (uri (string-append "https://github.com/JetBrains/JetBrainsMono/releases/" "download/v" version "/JetBrainsMono-" version ".zip")) (sha256 (base32 "1acrgv2q9vxviirpi01xy67pkkswyssw4dn5pgyvrnjxr85cgjrg")))) (build-system font-build-system) (arguments `(#:phases (modify-phases %standard-phases (add-before 'install-license-files 'change-directory-to-archive-root ;; Find the license file outside of the default subdirectory. (lambda _ (chdir "..") #t)) (replace 'install-license-files (lambda* (#:key outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (doc (string-append out "/share/doc/" ,name "-" ,version))) (install-file "OFL.txt" doc) #t)))))) (home-page "https://www.jetbrains.com/lp/mono/") (synopsis "Mono typeface for developers") (description "JetBrains Mono is a font family dedicated to developers. JetBrains Mono’s typeface forms are simple and free from unnecessary details. Rendered in small sizes, the text looks crisper.") (license license:asl2.0))) (define-public font-juliamono (package (name "font-juliamono") (version "0.031") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/cormullion/juliamono") (commit (string-append "v" version)))) (file-name (git-file-name name version)) (sha256 (base32 "0pcz2qaw0g0gak4plvhgg3m76h4gamffa373r52dzx0qwn1i1cf1")))) (build-system font-build-system) (arguments `(#:phases (modify-phases %standard-phases (add-after 'unpack 'delete-website-folder ;; This folder contains other unrelated fonts. (lambda _ (delete-file-recursively "website") #t))))) (home-page "https://github.com/cormullion/juliamono") (synopsis "Monospaced font for programming") (description "JuliaMono is a monospaced font for scientific and technical computing, designed to work for programming in the Julia Programming Language and other text environments.") (license license:silofl1.1))) (define-public font-vazir (package (name "font-vazir") (version "22.1.0") (source (origin (method url-fetch/zipbomb) (uri (string-append "https://github.com/rastikerdar/vazir-font/" "releases/download/v" version "/vazir-font-v" version ".zip")) (sha256 (base32 "0w3gwb5q33x5llw7cfs8qhaxr4ssg6rsx4b9day3993zn24xq031")))) (build-system font-build-system) (home-page "https://rastikerdar.github.io/vazir-font/") (synopsis "Vazir Persian typeface") (description "Vazir is a beautiful and elegant Persian typeface originally based on DejaVu, and comes in six variants: Thin, Light, Normal, Medium, Bold, and Black. This package provides four versions of Vazir: @itemize @item @code{Vazir}: The main version; includes Latin glyphs from Roboto. @item @code{Vazir-FD}: Like @code{Vazir}, but (always) uses Farsi digit glyphs instead of Latin ones. @item @code{Vazir-WOL}: Like @code{Vazir}, but without Roboto's Latin glyphs. @item @code{Vazir-FD-WOL}: Combination of @code{Vazir-FD} and @code{Vazir-WOL}: always uses Farsi digits, and does not include Latin glyphs from Roboto. @end itemize\n") (license ;; See https://github.com/rastikerdar/vazir-font/blob/master/LICENSE for ;; details. (list license:public-domain ; the Vazir modifications to DejaVu ; and the DejaVu modifications to... (license:x11-style ; ...the Bitstream Vera typeface "file://LICENSE" "Bitstream Vera License") license:asl2.0)))) ; Latin glyphs from Roboto (define-public font-meera-inimai (package (name "font-meera-inimai") (version "2.0") (source (origin (method git-fetch) (uri (git-reference (url "https://gitlab.com/smc/meera-inimai") (commit "0f39cdd7dbf1b6d1bed7df85834d33789dce20a7"))) (file-name (git-file-name name version)) (sha256 (base32 "1x5mhrpx24imh0r4l83mkaiszxgwi1q4ppyyvq63h3ddwk20cwdg")))) (build-system gnu-build-system) (native-inputs `(("fontforge" ,fontforge) ("harfbuzz" ,harfbuzz "bin") ("python" ,python-minimal) ("python-fonttools" ,python-fonttools) ("python-google-brotli" ,python-google-brotli))) (arguments `(#:make-flags (list "PY=python3" (string-append "DESTDIR=" %output) "fontpath=/share/fonts/truetype") #:test-target "test" #:phases (modify-phases %standard-phases (delete 'configure)))) (home-page "https://gitlab.com/smc/meera-inimai") (synopsis "Meera Inimai Tamil font") (description "Meera Inimai is a Unicode font for the Tamil Script. Meera Inimai is a san-serif typeface. It is best used as a screen font for body text. It is also useful for body text of printed pamphlets or single page designs. Meera Inimai can be thought of as similar to Helvetica and its variation Arial. Tamil characters are inherently vertically-elliptical. The orthography of Roman glyphs of Meera Inimai are also based on this characteristic so that they sit smoothly with the Tamil glyphs.") (license license:silofl1.1))) (define-public font-ipa-mj-mincho (package (name "font-ipa-mj-mincho") (version "006.01") (source (origin (method url-fetch/zipbomb) (uri (string-append "https://mojikiban.ipa.go.jp/OSCDL/IPAmjMincho" "/ipamjm" (string-join (string-split version #\.) "") ".zip")) (sha256 (base32 "0s2vs9p7vd7ajnn6c2icli069sjwi4d45a39fczqpwwn507lwj9m")))) (build-system font-build-system) (arguments `(#:phases (modify-phases %standard-phases (add-after 'install 'install-doc (lambda* (#:key outputs #:allow-other-keys) (let ((doc-dir (string-append (assoc-ref outputs "out") "/share/doc/font-ipa-mj-mincho"))) (mkdir-p doc-dir) (copy-file "Readme.txt" (string-append doc-dir "/README")) (copy-file "IPA_Font_License_Agreement_v1.0.txt" (string-append doc-dir "/LICENSE")) #t)))))) (home-page "https://mojikiban.ipa.go.jp/1300.html") (synopsis "Japanese font from the Information-technology Promotion Agency") (description "MJM Mincho is a font that aims at, for example, allowing you to write people's name, or for formal business situations where it is necessary to have a detailed and proper character style.") (license license:ipa))) (define-public font-fontna-yasashisa-antique (package (name "font-fontna-yasashisa-antique") (version "0") (source (origin (method url-fetch) (uri (string-append "http://flop.sakura.ne.jp/font/fontna-op/" "YasashisaAntiqueFont.zip")) (sha256 (base32 "1hl2qk3lzmh9h2vv5647vhlslkn3vqbq9rqgp4wzybajafx8c6nj")))) (build-system font-build-system) (arguments `(#:phases (modify-phases %standard-phases ;; encoding issues cause many phases to fail (add-after 'unpack 'fix-encoding (lambda _ ;; This directory, TrueType(サポート外), is not properly encoded, ;; which makes rename-file fail. Instead, use shell globbing to ;; select and rename the directory. (invoke "sh" "-c" "mv TrueType* TrueType") #t))))) (native-inputs `(("bash" ,bash-minimal) ("coreutils" ,coreutils))) (home-page "http://www.fontna.com/blog/1122/") (synopsis "Mix font of gothic kanji and minchou kana") (description "Antique is a font that is popular to write manga bubbles, dictionary headwords and picture books. This font reduces the thickness differences in characters compared to other antique fonts.") (license (list license:ipa (license:non-copyleft "mplus-TESTFLIGHT-057/LICENSE_E"))))) (define-public font-mplus-testflight (package (name "font-mplus-testflight") (version "063a") (source (origin (method url-fetch) (uri (string-append "https://osdn.net/frs/redir.php?" "m=gigenet&f=mplus-fonts%2F62344%2Fmplus-TESTFLIGHT-" version ".tar.xz")) (file-name (string-append name "-" version ".tar.xz")) (sha256 (base32 "0yfx9i77638yrgclnwwl4af79ri3vifi1nslwi6mgzva9cxrgss4")))) (build-system font-build-system) (home-page "https://mplus-fonts.osdn.jp/index.html") (synopsis "Japanese font collection") (description "M+ is a collection of Japanese fonts with all Latin glyph sets, with Basic Latin, Latin-1 Supplement, Latin Extended-A, and IPA Extensions. In addition to European letters used in many Western European languages, it contains Japanese characters, including Kana glyphs and more than 5,300 Kanji glyphs, as well major international phonetic symbols, operators and special symbols.") (license (license:non-copyleft "file:///LICENSE_E")))) (define-public font-catamaran (let ((commit "7559b4906f9c9148fb22c6f89508c3053a78a296") (revision "1")) (package (name "font-catamaran") (version (git-version "0.0.0" revision commit)) (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/VanillaandCream/Catamaran-Tamil") (commit commit))) (file-name (git-file-name name version)) (sha256 (base32 "1wpp41l7j2kpgnyavhgxcc5wp852a4wqsnwravn39gp980s84yxw")))) (build-system font-build-system) (home-page "https://github.com/VanillaandCream/Catamaran-Tamil") (synopsis "9 weight Tamil and Latin type") (description "Catamaran is a 9 weight Tamil and Latin type. Catamaran is a stylish type with a polished yet relaxed feel. Its versatility makes it suitable for a wide range of uses.") (license license:silofl1.1)))) (define-public font-cozette (package (name "font-cozette") (version "1.9.3") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/slavfox/Cozette") (commit (string-append "v." version)))) (file-name (git-file-name name version)) (sha256 (base32 "0mb5ns6705piwgjw1g10czsakhyc1jnvxh342ixw8m5f1gf4595n")))) (build-system font-build-system) (arguments `(#:phases (modify-phases %standard-phases (add-before 'install 'build (lambda _ (invoke "python3" "build.py" "fonts")))))) (native-inputs `(("fontforge" ,fontforge) ("python" ,python) ("python-crayons" ,python-crayons) ("python-fonttools" ,python-fonttools) ("python-numpy" ,python-numpy) ("python-pillow" ,python-pillow))) (home-page "https://github.com/slavfox/Cozette") (synopsis "Bitmap programming font") (description "Cozette is a 6x13px (bounding box) bitmap font based on Dina and heavily inspired by Creep.") (license license:expat)))