From patchwork Thu Nov 16 19:15:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Philip McGrath X-Patchwork-Id: 56536 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 CDC4127BBE9; Thu, 16 Nov 2023 19:19:03 +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=unavailable 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 3071B27BBE2 for ; Thu, 16 Nov 2023 19:19:01 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r3hsO-0004Qy-Ui; Thu, 16 Nov 2023 14:18:08 -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 1r3hsM-0004OG-Lz for guix-patches@gnu.org; Thu, 16 Nov 2023 14:18:06 -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 1r3hsM-0004ii-CP for guix-patches@gnu.org; Thu, 16 Nov 2023 14:18:06 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1r3hsM-0003pb-3u for guix-patches@gnu.org; Thu, 16 Nov 2023 14:18:06 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#67019] [PATCH v2 16/16] gnu: Add katex. Resent-From: Philip McGrath Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 16 Nov 2023 19:18:06 +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 , Liliana Marie Prikler Received: via spool by 67019-submit@debbugs.gnu.org id=B67019.170016223314592 (code B ref 67019); Thu, 16 Nov 2023 19:18:06 +0000 Received: (at 67019) by debbugs.gnu.org; 16 Nov 2023 19:17:13 +0000 Received: from localhost ([127.0.0.1]:44609 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1r3hrU-0003nC-RO for submit@debbugs.gnu.org; Thu, 16 Nov 2023 14:17:13 -0500 Received: from out4-smtp.messagingengine.com ([66.111.4.28]:60411) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1r3hr6-0003iG-IV for 67019@debbugs.gnu.org; Thu, 16 Nov 2023 14:16:50 -0500 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id A72365C016D; Thu, 16 Nov 2023 14:16:48 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Thu, 16 Nov 2023 14:16:48 -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=fm1; t=1700162208; x=1700248608; bh=cVOIUCojWI MibNt/4/ps5FcqYscpDwqoSyikZmtVKZU=; b=HpF5x55eH/1qWFQcg5YY+ZyrU4 D+t9ZLKxD+ThHh+IysVxaCmioYKGrEb4sU+QByHuC/xYYo1Z4QpSIhcgTWuD7nHX nug5PZrX0HXlS8NKLuIgN9BtpDz+ORWOA26qqf21Z3z3s6MGTFchSdKAox3O99/p cmHd8TsgHZu2uFmL5p7UeMT6+W+B5/t604KYTG9n/vfTbDu5wQEKfEDlfKbpcc6C onBht1UrFA1UIfpyGUiB9Ke2IUaI9Vj/YLKlMByNfGiEi9Le+BTP1wpjhs0+bEOf Mkbu7ybPLYPTxLblBoGzgiNrzK/ORRmsdZeFGNgW5HerKbTv5TEXiS9PGfQw== 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=fm1; t=1700162208; x= 1700248608; bh=cVOIUCojWIMibNt/4/ps5FcqYscpDwqoSyikZmtVKZU=; b=x 0JA73z772mGB+5wPpmx/AcTBsS/VMnAJGDwwFejoodDaeOMIF6LeaaWd5N5qcKG3 5yY773seIVNei9VJXnyK1LtKfUY4y2tVy5r6U5YF0wQxXJU4DNtlBZAiNg+bI+s1 jnKtAkKTjX48ngkXTZwBdQoEvDuId6W01+ZF1T0NGmM0dEG7y4V5v9rZl+0phK/3 rzNh0+XMU235zGAlLiIAbCrS2C3wEVGQg3pjqP/iUkmRXfPlaJE3NOkwPhqP8c2u qJg4VCy2g90zTq9RtfKuw9+8SdvTMSlIxO8bli0/yc++LJDvbvP4NgHzHaWkQzw4 L7vdoyTqwnLlZUTn8z2LA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrudefkedguddvtdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefrhhhi lhhiphcuofgtifhrrghthhcuoehphhhilhhiphesphhhihhlihhpmhgtghhrrghthhdrtg homheqnecuggftrfgrthhtvghrnhepleevkeffuedvgfeihefhgeefjeevueekudfhteff ueffieekudehvdeivefgudejnecuffhomhgrihhnpehkrghtvgigrdhorhhgnecuvehluh hsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepphhhihhlihhpsehp hhhilhhiphhmtghgrhgrthhhrdgtohhm X-ME-Proxy: Feedback-ID: i2b1146f3:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 16 Nov 2023 14:16:47 -0500 (EST) From: Philip McGrath Date: Thu, 16 Nov 2023 14:15:54 -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")