diff options
| author | Ludovic Courtès <ludo@gnu.org> | 2022-01-18 22:20:12 +0100 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2022-01-18 22:51:08 +0100 |
| commit | 7eb883b7c284c78cc17093bfc4ef2d70e0acad83 (patch) | |
| tree | d6cb9d8b7879da6af715b03e5185584965e795d9 | |
| parent | ee16e4e8dac9fd14340cd96731e867134cd843fe (diff) | |
doc: Add a language menu in the HTML manual.
* doc/build.scm (stylized-html): New procedure.
(html-manual): Use it.
| -rw-r--r-- | doc/build.scm | 156 |
1 files changed, 153 insertions, 3 deletions
diff --git a/doc/build.scm b/doc/build.scm index 1057336c655..44c185e5f9d 100644 --- a/doc/build.scm +++ b/doc/build.scm | |||
| @@ -600,6 +600,154 @@ its <pre class=\"lisp\"> blocks (as produced by 'makeinfo --html')." | |||
| 600 | 600 | ||
| 601 | (computed-file name build)) | 601 | (computed-file name build)) |
| 602 | 602 | ||
| 603 | (define* (stylized-html source input | ||
| 604 | #:key | ||
| 605 | (languages %languages) | ||
| 606 | (manual %manual) | ||
| 607 | (manual-css-url "/static/base/css/manual.css")) | ||
| 608 | "Process all the HTML files in INPUT; add them MANUAL-CSS-URL as a <style> | ||
| 609 | link, and add a menu to choose among LANGUAGES. Use the Guix PO files found | ||
| 610 | in SOURCE." | ||
| 611 | (define build | ||
| 612 | (with-extensions (list guile-lib) | ||
| 613 | (with-imported-modules `((guix build utils) | ||
| 614 | ((localization) | ||
| 615 | => ,(localization-helper-module | ||
| 616 | source languages))) | ||
| 617 | #~(begin | ||
| 618 | (use-modules (htmlprag) | ||
| 619 | (localization) | ||
| 620 | (guix build utils) | ||
| 621 | (srfi srfi-1) | ||
| 622 | (ice-9 match) | ||
| 623 | (ice-9 threads)) | ||
| 624 | |||
| 625 | (define* (menu-dropdown #:key (label "Item") (url "#") (items '())) | ||
| 626 | ;; Return an SHTML <li> element representing a dropdown for the | ||
| 627 | ;; navbar. LABEL is the text of the dropdown menu, and ITEMS is | ||
| 628 | ;; the list of items in this menu. | ||
| 629 | (define id "visible-dropdown") | ||
| 630 | |||
| 631 | `(li | ||
| 632 | (@ (class "navbar-menu-item dropdown dropdown-btn")) | ||
| 633 | (input (@ (class "navbar-menu-hidden-input") | ||
| 634 | (type "radio") | ||
| 635 | (name "dropdown") | ||
| 636 | (id ,id))) | ||
| 637 | (label (@ (for ,id)) ,label) | ||
| 638 | (label (@ (for "all-dropdowns-hidden")) ,label) | ||
| 639 | (div | ||
| 640 | (@ (class "navbar-submenu") | ||
| 641 | (id "navbar-submenu")) | ||
| 642 | (div (@ (class "navbar-submenu-triangle")) | ||
| 643 | " ") | ||
| 644 | (ul ,@items)))) | ||
| 645 | |||
| 646 | (define (menu-item label url) | ||
| 647 | ;; Return an SHTML <li> element for a menu item with the given | ||
| 648 | ;; LABEL and URL. | ||
| 649 | `(li (a (@ (class "navbar-menu-item") | ||
| 650 | (href ,url)) | ||
| 651 | ,label))) | ||
| 652 | |||
| 653 | (define* (base-language-url code manual | ||
| 654 | #:key split-node?) | ||
| 655 | ;; Return the base URL of MANUAL for language CODE. | ||
| 656 | (if split-node? | ||
| 657 | (string-append "../../" code "/html_node") | ||
| 658 | (string-append "../" code "/" manual | ||
| 659 | (if (string=? code "en") | ||
| 660 | "" | ||
| 661 | (string-append "." code)) | ||
| 662 | ".html"))) | ||
| 663 | |||
| 664 | (define (language-menu-items file) | ||
| 665 | ;; Return the language menu items to be inserted in FILE. | ||
| 666 | (define split-node? | ||
| 667 | (string-contains file "/html_node/")) | ||
| 668 | |||
| 669 | (append | ||
| 670 | (map (lambda (code) | ||
| 671 | (menu-item (language-code->native-name code) | ||
| 672 | (base-language-url code #$manual | ||
| 673 | #:split-node? | ||
| 674 | split-node?))) | ||
| 675 | '#$%languages) | ||
| 676 | (list | ||
| 677 | (menu-item "⊕" | ||
| 678 | (if (string=? #$manual "guix-cookbook") | ||
| 679 | "https://translate.fedoraproject.org/projects/guix/documentation-cookbook/" | ||
| 680 | "https://translate.fedoraproject.org/projects/guix/documentation-manual/"))))) | ||
| 681 | |||
| 682 | (define (stylized-html sxml file) | ||
| 683 | ;; Return SXML, which was read from FILE, with additional | ||
| 684 | ;; styling. | ||
| 685 | (let loop ((sxml sxml)) | ||
| 686 | (match sxml | ||
| 687 | (('*TOP* decl body ...) | ||
| 688 | `(*TOP* ,decl ,@(map loop body))) | ||
| 689 | (('head elements ...) | ||
| 690 | ;; Add reference to our own manual CSS, which provides | ||
| 691 | ;; support for the language menu. | ||
| 692 | `(head ,@elements | ||
| 693 | (link (@ (rel "stylesheet") | ||
| 694 | (type "text/css") | ||
| 695 | (href #$manual-css-url))))) | ||
| 696 | (('body ('@ attributes ...) elements ...) | ||
| 697 | `(body (@ ,@attributes) | ||
| 698 | (nav (@ (class "navbar-menu")) | ||
| 699 | (ul | ||
| 700 | ;; TODO: Add "Contribute" menu, to report | ||
| 701 | ;; errors, etc. | ||
| 702 | ,(menu-dropdown #:label | ||
| 703 | `(img (@ (alt "Language") | ||
| 704 | (src "/static/base/img/language-picker.svg"))) | ||
| 705 | #:items | ||
| 706 | (language-menu-items file)))) | ||
| 707 | ,@elements)) | ||
| 708 | ((tag ('@ attributes ...) body ...) | ||
| 709 | `(,tag (@ ,@attributes) ,@(map loop body))) | ||
| 710 | ((tag body ...) | ||
| 711 | `(,tag ,@(map loop body))) | ||
| 712 | ((? string? str) | ||
| 713 | str)))) | ||
| 714 | |||
| 715 | (define (process-html file) | ||
| 716 | ;; Parse FILE and add links to translations. Install the result | ||
| 717 | ;; to #$output. | ||
| 718 | (format (current-error-port) "processing ~a...~%" file) | ||
| 719 | (let* ((shtml (parameterize ((%strict-tokenizer? #t)) | ||
| 720 | (call-with-input-file file html->shtml))) | ||
| 721 | (processed (stylized-html shtml file)) | ||
| 722 | (base (string-drop file (string-length #$input))) | ||
| 723 | (target (string-append #$output base))) | ||
| 724 | (mkdir-p (dirname target)) | ||
| 725 | (call-with-output-file target | ||
| 726 | (lambda (port) | ||
| 727 | (write-shtml-as-html processed port))))) | ||
| 728 | |||
| 729 | ;; Install a UTF-8 locale so we can process UTF-8 files. | ||
| 730 | (setenv "GUIX_LOCPATH" | ||
| 731 | #+(file-append glibc-utf8-locales "/lib/locale")) | ||
| 732 | (setlocale LC_ALL "en_US.utf8") | ||
| 733 | (setenv "LC_ALL" "en_US.utf8") | ||
| 734 | (setvbuf (current-error-port) 'line) | ||
| 735 | |||
| 736 | (n-par-for-each (parallel-job-count) | ||
| 737 | (lambda (file) | ||
| 738 | (if (string-suffix? ".html" file) | ||
| 739 | (process-html file) | ||
| 740 | ;; Copy FILE as is to #$output. | ||
| 741 | (let* ((base (string-drop file (string-length #$input))) | ||
| 742 | (target (string-append #$output base))) | ||
| 743 | (mkdir-p (dirname target)) | ||
| 744 | (if (eq? 'symlink (stat:type (lstat file))) | ||
| 745 | (symlink (readlink file) target) | ||
| 746 | (copy-file file target))))) | ||
| 747 | (find-files #$input)))))) | ||
| 748 | |||
| 749 | (computed-file "stylized-html-manual" build)) | ||
| 750 | |||
| 603 | (define* (html-manual source #:key (languages %languages) | 751 | (define* (html-manual source #:key (languages %languages) |
| 604 | (version "0.0") | 752 | (version "0.0") |
| 605 | (manual %manual) | 753 | (manual %manual) |
| @@ -690,9 +838,11 @@ makeinfo OPTIONS." | |||
| 690 | (filter (compose file-exists? language->texi-file-name) | 838 | (filter (compose file-exists? language->texi-file-name) |
| 691 | '#$languages))))) | 839 | '#$languages))))) |
| 692 | 840 | ||
| 693 | (let* ((name (string-append manual "-html-manual")) | 841 | (let* ((name (string-append manual "-html-manual")) |
| 694 | (manual (computed-file name build #:local-build? #f))) | 842 | (manual* (computed-file name build #:local-build? #f))) |
| 695 | (syntax-highlighted-html manual | 843 | (syntax-highlighted-html (stylized-html source manual* |
| 844 | #:languages languages | ||
| 845 | #:manual manual) | ||
| 696 | #:mono-node-indexes mono-node-indexes | 846 | #:mono-node-indexes mono-node-indexes |
| 697 | #:split-node-indexes split-node-indexes | 847 | #:split-node-indexes split-node-indexes |
| 698 | #:name (string-append name "-highlighted")))) | 848 | #:name (string-append name "-highlighted")))) |
