From patchwork Thu Nov 9 16:26:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Philip McGrath X-Patchwork-Id: 56141 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 891DB27BBEA; Thu, 9 Nov 2023 16:28:47 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,SPF_HELO_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 6A8D627BBE2 for ; Thu, 9 Nov 2023 16:28:46 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r17tS-0008D1-9O; Thu, 09 Nov 2023 11:28:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r17tP-00088M-53 for guix-patches@gnu.org; Thu, 09 Nov 2023 11:28:31 -0500 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1r17tO-0006ay-Sn for guix-patches@gnu.org; Thu, 09 Nov 2023 11:28:30 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1r17tz-0004gr-KK; Thu, 09 Nov 2023 11:29:07 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#67019] [PATCH 16/16] gnu: Add katex. Resent-From: Philip McGrath Original-Sender: "Debbugs-submit" Resent-CC: philip@philipmcgrath.com, julien@lepiller.eu, pukkamustard@posteo.net, guix-patches@gnu.org Resent-Date: Thu, 09 Nov 2023 16:29:07 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 67019 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 67019@debbugs.gnu.org Cc: Philip McGrath , Philip McGrath , Julien Lepiller , pukkamustard X-Debbugs-Original-Xcc: Philip McGrath , Julien Lepiller , pukkamustard Received: via spool by 67019-submit@debbugs.gnu.org id=B67019.169954730117857 (code B ref 67019); Thu, 09 Nov 2023 16:29:07 +0000 Received: (at 67019) by debbugs.gnu.org; 9 Nov 2023 16:28:21 +0000 Received: from localhost ([127.0.0.1]:48545 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1r17tE-0004dr-Db for submit@debbugs.gnu.org; Thu, 09 Nov 2023 11:28:21 -0500 Received: from wout5-smtp.messagingengine.com ([64.147.123.21]:58689) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1r17tB-0004cl-0I for 67019@debbugs.gnu.org; Thu, 09 Nov 2023 11:28:18 -0500 Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailout.west.internal (Postfix) with ESMTP id 104B63200B59; Thu, 9 Nov 2023 11:27:31 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Thu, 09 Nov 2023 11:27:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= philipmcgrath.com; h=cc:cc:content-transfer-encoding :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm3; t=1699547251; x=1699633651; bh=cVOIUCojWI MibNt/4/ps5FcqYscpDwqoSyikZmtVKZU=; b=yylvLOPubwO1Tom6Oyoc3dDY8d qZiDIdL+yJfVtcNJR7Hvh8qPgqrP0PbpUp0foXrAD/DSJ8zyLP2yNi5iJBAM683i 8NXafUajOx4cOOhRsVvNgO23kXeSx4+b2BHo+41oe9rMDf7txetwKb4h7q3sachM u1C9RvQ5K5WXhFaxELCqyPjMk5xxluVN+xkbV7/q1uadkyYHX4cR54sJnAzae+B1 KGIXYcZCpQI2rwSIa0bBQkXLccJPRCYAT2EgP5tTeyPbIaEXAYPgLeoiEcWsq7KJ 34GaOGWqpRmNJrSZA6hqvSwIPgmBhwRFIFwaPUBDjo/fiD6OJYTRfMsvgGQw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t=1699547251; x= 1699633651; bh=cVOIUCojWIMibNt/4/ps5FcqYscpDwqoSyikZmtVKZU=; b=h fzIQz14Yr4wstXQsosICVXa7tKf3kIiixcAw2VGK/FxLDMUNrABBCU5i7KykOkM4 Ct+iqhg5/PMukjrsziHlLfjrLoCnq8S7Vlz3Zq6Ui0ZyqrxfN24XOuKpr9PbNNNy fOaC18nJoMtAHNRFRcNrl7/eQNnEiW0SRVIPrZEh/Ez8TzobW8nmbWWYGN+KfVM8 6ZkFQP0Dd0El52rj6i24hPPUYlh/QGEbmHubWOG7v9emPejduTHPrBwT5XiNZiSX dJf8vXvH1ntdno/Kgwa+Wmr6LoTvPeRzMWGHZZhH5A6oGzOJOhi1E8dKxCugqwNy bqQeJmYHKMxGHy3DrqUPA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedruddvuddgkeejucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvfevufffkffojghfggfgsedtke ertdertddtnecuhfhrohhmpefrhhhilhhiphcuofgtifhrrghthhcuoehphhhilhhiphes phhhihhlihhpmhgtghhrrghthhdrtghomheqnecuggftrfgrthhtvghrnhepleevkeffue dvgfeihefhgeefjeevueekudfhteffueffieekudehvdeivefgudejnecuffhomhgrihhn pehkrghtvgigrdhorhhgnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrg hilhhfrhhomhepphhhihhlihhpsehphhhilhhiphhmtghgrhgrthhhrdgtohhm X-ME-Proxy: Feedback-ID: i2b1146f3:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 9 Nov 2023 11:27:30 -0500 (EST) From: Philip McGrath Date: Thu, 9 Nov 2023 11:26:38 -0500 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * gnu/packages/javascript.scm (katex): New variable. --- gnu/packages/javascript.scm | 255 +++++++++++++++++++++++++++++++++++- 1 file changed, 253 insertions(+), 2 deletions(-) diff --git a/gnu/packages/javascript.scm b/gnu/packages/javascript.scm index ee7a48154c..76a51c22ac 100644 --- a/gnu/packages/javascript.scm +++ b/gnu/packages/javascript.scm @@ -32,6 +32,7 @@ (define-module (gnu packages javascript) #:use-module (gnu packages compression) #:use-module (gnu packages fontutils) #:use-module (gnu packages java) + #:use-module (gnu packages man) #:use-module (gnu packages node) #:use-module (gnu packages perl) #:use-module (gnu packages python) @@ -382,7 +383,7 @@ (define-public js-mathjax-for-r-mathjaxr (define-public font-katex (package (name "font-katex") - (version "0.16.4") + (version "0.16.9") (source (origin (method git-fetch) @@ -391,7 +392,7 @@ (define-public font-katex (commit (string-append "v" version)))) (sha256 (base32 - "0z6y2188lhfv0gk0hp4rm37g6fs99qb3ab2q3n9g76ga9dwxhw3s")) + "1aq8n9s4r15m1fdi4h58qxal4brkafm4xsw6rpz40wqi9454kkgn")) (snippet ;; unbundle generated files #~(begin @@ -446,6 +447,256 @@ (define-public font-katex (description "This package contains the fonts required for KaTeX.") (license license:expat))) +(define-public katex + (package + (inherit font-katex) + (name "katex") + (outputs '("out" "dist")) + (build-system node-build-system) + (native-inputs + (list esbuild + flow-remove-types + help2man + lessc)) + (inputs + (list font-katex + js-commander)) + (arguments + (list + #:tests? #f ; many more dependencies + #:modules + `((guix build node-build-system) + (ice-9 match) + (srfi srfi-1) + (srfi srfi-26) + (guix build utils)) + #:phases + #~(modify-phases %standard-phases + (add-before 'patch-dependencies 'move-sources + (lambda* (#:key inputs #:allow-other-keys) + ;; Our node-build-system doesn't properly respect the "files" + ;; entry in "package.json" to determine which files to install. + ;; This case is particularly egregious because the source + ;; repository also contains the source for the whole katex.org + ;; website. For now, manually do what "files" ought to do. + (mkdir "../guix-source") + (copy-recursively "src" "../guix-source/src") + (copy-recursively "contrib" "../guix-source/contrib") + (for-each (cut install-file <> "../guix-source") + '("README.md" + "LICENSE" + "package.json" + "katex.js" + "cli.js")) + (install-file + (search-input-file inputs "share/katex/fontMetricsData.js") + "../guix-source/src") + (chdir "../guix-source"))) + (add-after 'move-sources 'patch-package-json + (lambda args + (with-atomic-json-file-replacement "package.json" + (match-lambda + (('@ . alist) + (cons '@ + (filter-map + (match-lambda + (((or "devDependencies" "scripts") . _) + #f) + ;; ESBuild can't generate Universal Module Definitions, + ;; so keep our CJS separate from our browser builds: + (("files" . lst) + `("files" "guix-node-cjs/" ,@lst)) + (("main" . "dist/katex.js") + `("main" . "guix-node-cjs/katex.js")) + (("exports" '@ . alist) + `("exports" @ + ,@(map (match-lambda + (("./*" . "./*") + `("./*" . "./*")) + ((lhs '@ . alist) + `(,lhs @ + ,@(map (match-lambda + (("require" . ,str) + (cons + "require" + (string-append + "./guix-node-cjs/" + (substring str + (string-length + "./dist"))))) + (other + other)) + alist)))) + alist))) + (other + other)) + alist))))))) + (add-after 'patch-dependencies 'patch-sources + (lambda* (#:key inputs #:allow-other-keys) + (substitute* "src/SourceLocation.js" + ;; for some reason, the + prefix isn't handled + ;; by flow-remove-types + (("[+](lexer|start|end)" _ name) + name)) + (substitute* "src/fonts.less" + ;; what webpack would do + (("@font-folder: \"\\.\\./fonts\";" orig) + (string-append "@font-folder: \"fonts\"; // " orig))) + (define version + #$(package-version this-package)) + (substitute* "src/katex.less" + (("@version: \"\";" orig) + (string-append "@version: \"" version "\"; // " orig))) + (substitute* "katex.js" + (("version: __VERSION__," orig) + (string-append "version: \"" version "\", // " orig))))) + (add-after 'patch-sources 'erase-types + (lambda args + (invoke "flow-remove-types" + "--sourcemaps" + "--out-dir" "../erased/src/" + "src/") + (invoke "flow-remove-types" + "--sourcemaps" + "--out-dir" "../erased/" + "katex.js") + (invoke "flow-remove-types" + "--sourcemaps" + "--out-dir" "../erased/contrib/" + "contrib/"))) + (add-after 'erase-types 'build-js + (lambda args + (with-directory-excursion "../erased" + ;; ^ avoid "../erased" in generated code + (define (esbuild . args) + (apply invoke `("esbuild" + "--bundle" + "--log-limit=0" + "--platform=neutral" + ,@args))) + (esbuild "--outfile=../guix-source/dist/katex.mjs" + "--format=esm" + "katex.js") + ;; Workaround for different handling of ES6 default export + ;; when generating CJS: + (esbuild "--outfile=katex-cjs.js" + "--format=cjs" + "katex.js") + (with-output-to-file "katex-wrapper.js" + (lambda () + (display + "module.exports = require('./katex-cjs.js').default;\n"))) + (esbuild "--outfile=../guix-source/guix-node-cjs/katex.js" + "--format=cjs" + "katex-wrapper.js") + (esbuild "--outfile=../guix-source/dist/katex.js" + "--format=iife" + "--global-name=katex" + "katex-wrapper.js") + (esbuild "--outfile=../guix-source/dist/katex.min.js" + "--minify" + "--format=iife" + "--global-name=katex" + "katex-wrapper.js") + ;; Build extensions: + (for-each + (match-lambda + ((name export) + ;; The copy-tex extension doesn't actually import katex, + ;; but it's harmless to handle it the same way. + (with-directory-excursion (string-append "contrib/" name) + (esbuild (string-append "--outfile=../../../guix-source" + "/guix-node-cjs/contrib/" + name ".js") + "--format=cjs" + "--external:katex" + (string-append name ".js")) + (substitute* (string-append name ".js") + (("import katex from \"katex\";") + "import katex from \"../katex.mjs\";")) + (esbuild (string-append "--outfile=" name ".mjs") + "--format=esm" + "--external:../katex.mjs" + (string-append name ".js")) + (install-file (string-append name ".mjs") + "../../../guix-source/dist/contrib") + (substitute* (string-append name ".js") + (("import katex") + "// import katex")) + (for-each + (lambda (minify?) + (apply + esbuild + `(,(string-append "--outfile=../../.." + "/guix-source/dist/contrib/" + name + (if minify? ".min" "") + ".js") + "--format=iife" + ,@(if minify? + '("--minify") + '()) + ,@(if export + `("--global-name=guixTmp" + ,(string-append "--banner:js=const " + export + " = (() => {") + "--footer:js=return guixTmp.default;\n})();") + '()) + ,(string-append name ".js")))) + '(#t #f))))) + '(("auto-render" "renderMathInElement") + ("copy-tex" #f) + ("mathtex-script-type" #f) + ("mhchem" #f) + ("render-a11y-string" "renderA11yString")))))) + (add-after 'build-js 'build-css + (lambda args + (invoke "lessc" "src/katex.less" "dist/katex.css"))) + (add-after 'install 'generate-man-page + (lambda args + (invoke "help2man" + "-N" + "-n" "render TeX math to HTML and MathML" + "--output=katex.1" + (string-append #$output "/bin/katex")) + (install-file "katex.1" + (string-append #$output "/share/man/man1")))) + (add-after 'generate-man-page 'install-dist + (lambda* (#:key inputs #:allow-other-keys) + ;; The CSS, fonts, etc. needed for KaTeX, plus the optional + ;; bundled version of the JavaScript for dynamic use in the + ;; browser, are in the 'dist' directory of the Node module. + ;; Putting them in a separate output lets them be used without + ;; retaining a reference to Node and the cli utility. + ;; In Debian, 'dist' is a symlink to /usr/share/javascript/katex: + ;; do likewise to help tools that may need to find it. + (define up-dist-dir + (string-append #$output:dist "/share/javascript")) + (define dist-dir + (string-append up-dist-dir "/katex")) + (mkdir-p up-dist-dir) + (with-directory-excursion + (string-append #$output "/lib/node_modules/katex") + (rename-file "dist" dist-dir) + (symlink dist-dir "dist")) + (with-directory-excursion dist-dir + ;; Link the fonts to where the CSS expects them: + (symlink (search-input-directory inputs + "share/fonts/truetype/katex") + "fonts") + ;; We can't actually minify the CSS, but fake it for anything + ;; that may expect it. With Brotli compression, the difference + ;; is only about 300 bytes anyway. + (symlink "katex.css" "katex.min.css"))))))) + (synopsis "Fast math typesetting for the web") + (description "KaTeX renders TeX math notation to HTML and/or MathML. The +rendered output does not depend on JavaScript, so rendering can be done +entirely ahead-of-time using the @command{katex} command-line tool. When +desired, KaTeX can also be used as a JavaScript library in the browser to +render math dynamically, and it is designed to be fast, even on pages with +hundreds of mathematical expressions."))) + (define-public js-commander (package (name "js-commander")