code:
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2017 Arun Isaac <arunisaac@systemreboot.net>
;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2017, 2018 Tobias Geerinckx-Rice <me@tobias.gr>
;;; Copyright © 2017 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2018 Nicolas Goaziou <mail@nicolasgoaziou.fr>
;;;
;;; 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 packages javascript)
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (gnu packages)
  #:use-module (gnu packages base)
  #:use-module (gnu packages compression)
  #:use-module (gnu packages lisp)
  #:use-module (gnu packages readline)
  #:use-module (guix packages)
  #:use-module (guix download)
  #:use-module (guix git-download)
  #:use-module (guix build-system gnu)
  #:use-module (guix build-system trivial)
  #:use-module (guix build-system minify))

(define-public font-mathjax
  (package
    (name "font-mathjax")
    (version "2.7.2")
    (source
     (origin
       (method url-fetch)
       (uri (string-append
             "https://github.com/mathjax/MathJax/archive/"
             version ".tar.gz"))
       (file-name (string-append name "-" version ".tar.gz"))
       (sha256
        (base32
         "1r72di4pg4i6pfhcskkxqmf1158m81ki6a7lbw6nz4zh7xw23hy4"))))
    (build-system trivial-build-system)
    (arguments
     `(#:modules ((guix build utils))
       #:builder
       (begin
         (use-modules (guix build utils)
                      (ice-9 match))
         (set-path-environment-variable
          "PATH" '("bin") (map (match-lambda
                                 ((_ . input)
                                  input))
                               %build-inputs))
         (let ((install-directory (string-append %output "/share/fonts/mathjax")))
           (mkdir-p install-directory)
           (invoke "tar" "-C" install-directory "-xvf"
                   (assoc-ref %build-inputs "source")
                   ,(string-append "MathJax-" version "/fonts")
                   "--strip" "2")))))
    (native-inputs
     `(("gzip" ,gzip)
       ("tar" ,tar)))
    (home-page "https://www.mathjax.org/")
    (synopsis "Fonts for MathJax")
    (description "This package contains the fonts required for MathJax.")
    (license license:asl2.0)))

(define-public js-mathjax
  (package
    (inherit font-mathjax)
    (name "js-mathjax")
    (arguments
     `(#:modules ((guix build utils))
       #:builder
       (begin
         (use-modules (guix build utils)
                      (ice-9 match)
                      (ice-9 popen)
                      (ice-9 regex))
         (set-path-environment-variable
          "PATH" '("bin") (map (match-lambda
                                 ((_ . input)
                                  input))
                               %build-inputs))
         (set-path-environment-variable
          "GUIX_LOCPATH" '("lib/locale")
          (list (assoc-ref %build-inputs "glibc-utf8-locales")))
         (setenv "LANG" "en_US.UTF-8")
         (let ((install-directory (string-append %output "/share/javascript/mathjax")))
           (invoke "tar" "xvf" (assoc-ref %build-inputs "source")
                   ,(string-append "MathJax-" (package-version font-mathjax)
                                   "/unpacked")
                   "--strip" "2")
           (mkdir-p install-directory)
           (symlink (string-append (assoc-ref %build-inputs "font-mathjax")
                                   "/share/fonts/mathjax")
                    (string-append install-directory "/fonts"))

           (for-each
            (lambda (file)
              (let ((installed (string-append install-directory
                                              ;; remove prefix "."
                                              (string-drop file 1))))
                (format #t "~a -> ~a~%" file installed)
                (cond
                 ((string-match "\\.js$" file)
                  (mkdir-p (dirname installed))
                  (let ((minified (open-pipe* OPEN_READ "uglify-js" file)))
                    (call-with-output-file installed
                      (lambda (port)
                        (dump-port minified port)))))
                 (else
                  (install-file file (dirname installed))))))
            (find-files "."))

           #t))))
    (native-inputs
     `(("font-mathjax" ,font-mathjax)
       ("glibc-utf8-locales" ,glibc-utf8-locales)
       ("uglify-js" ,uglify-js)
       ,@(package-native-inputs font-mathjax)))
    (synopsis "JavaScript display engine for LaTeX, MathML, and AsciiMath")
    (description "MathJax is a JavaScript display engine for LaTeX, MathML,
and AsciiMath notation that works in all modern browsers.  It requires no
plugins or software to be installed on the browser.  So the page author can
write web documents that include mathematics and be confident that readers will
be able to view it naturally and easily.")))

(define-public js-respond
  (package
    (name "js-respond")
    (version "1.4.2")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://github.com/scottjehl/Respond/"
                                  "archive/" version ".tar.gz"))
              (file-name (string-append name "-" version ".tar.gz"))
              (sha256
               (base32
                "0ds1ya2a185jp93mdn07159c2x8zczwi960ykrawpp62bwk2n93d"))))
    (build-system trivial-build-system)
    (arguments
     `(#:modules ((guix build utils))
       #:builder
       (begin
         (use-modules (guix build utils)
                      (ice-9 match)
                      (ice-9 popen)
                      (srfi srfi-26))
         (set-path-environment-variable
          "PATH" '("bin") (map (match-lambda
                                 ((_ . input)
                                  input))
                               %build-inputs))
         (let ((install-directory (string-append %output
                                                 "/share/javascript/respond/")))
           (invoke "tar" "xvf"
                   (assoc-ref %build-inputs "source")
                   "--strip" "1")
           (mkdir-p install-directory)
           (let* ((file "src/respond.js")
                  (installed (string-append install-directory "respond.min.js")))
             (let ((minified (open-pipe* OPEN_READ "uglify-js" file)))
               (call-with-output-file installed
                 (cut dump-port minified <>)))))
         #t)))
    (home-page "https://github.com/scottjehl/Respond")
    (native-inputs
     `(("uglify-js" ,uglify-js)
       ("source" ,source)
       ("gzip" ,gzip)
       ("tar" ,tar)))
    (synopsis "Polyfill for min/max-width CSS3 Media Queries")
    (description "The goal of this script is to provide a fast and lightweight
script to enable responsive web designs in browsers that don't support CSS3
Media Queries.")
    (license license:expat)))

(define-public js-html5shiv
  (package
    (name "js-html5shiv")
    (version "3.7.3")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://github.com/aFarkas/html5shiv/"
                                  "archive/" version ".tar.gz"))
              (file-name (string-append name "-" version ".tar.gz"))
              (sha256
               (base32
                "0inlbpxpqzdyi24lqagzf7l24zxg0y02xcpqs2h4npjscazzw7hg"))))
    (build-system minify-build-system)
    (home-page "https://github.com/aFarkas/html5shiv")
    (synopsis "Enable HTML5 sectioning elements in legacy browsers")
    (description "The HTML5 Shiv enables use of HTML5 sectioning elements in
legacy Internet Explorer and provides basic HTML5 styling for Internet
Explorer 6-9, Safari 4.x (and iPhone 3.x), and Firefox 3.x.")
    ;; From the file "MIT and GPL2 licenses.md":
    ;;
    ;;   This software is licensed under a dual license system (MIT or GPL
    ;;   version 2). This means you are free to choose with which of both
    ;;   licenses (MIT or GPL version 2) you want to use this library.
    (license (list license:expat license:gpl2))))

(define-public js-json2
  (let ((commit "031b1d9e6971bd4c433ca85e216cc853f5a867bd")
        (revision "1"))
    (package
      (name "js-json2")
      (version (string-append "2016-10-28." revision "-" (string-take commit 7)))
      (source (origin
                (method git-fetch)
                (uri (git-reference
                      (url "https://github.com/douglascrockford/JSON-js.git")
                      (commit commit)))
                (file-name (string-append name "-" version "-checkout"))
                (sha256
                 (base32
                  "1fvb6b2y5sd3sqdgcj683sdxcbxdii34q0ysc9wg0dq1sy81l11v"))))
      (build-system minify-build-system)
      (arguments
       `(#:javascript-files '("json2.js"
                              "json_parse.js"
                              "json_parse_state.js"
                              "cycle.js")))
      (home-page "https://github.com/douglascrockford/JSON-js")
      (synopsis "JSON encoders and decoders")
      (description "The files in this collection implement JSON
encoders/decoders in JavaScript.

@code{json2.js}: This file creates a JSON property in the global object, if
there isn't already one, setting its value to an object containing a stringify
method and a parse method.  The @code{parse} method uses the @code{eval}
method to do the parsing, guarding it with several regular expressions to
defend against accidental code execution hazards.  On current browsers, this
file does nothing, preferring the built-in JSON object.

@code{json_parse.js}: This file contains an alternative JSON @code{parse}
function that uses recursive descent instead of @code{eval}.

@code{json_parse_state.js}: This files contains an alternative JSON
@code{parse} function that uses a state machine instead of @code{eval}.

@code{cycle.js}: This file contains two functions, @code{JSON.decycle} and
@code{JSON.retrocycle}, which make it possible to encode cyclical structures
and DAGs in JSON, and to then recover them.  This is a capability that is not
provided by ES5.  @code{JSONPath} is used to represent the links.")
      (license license:public-domain))))

(define-public js-strftime
  (package
    (name "js-strftime")
    (version "0.10.0")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://github.com/samsonjs/strftime/"
                                  "archive/v" version ".tar.gz"))
              (file-name (string-append name "-" version ".tar.gz"))
              (sha256
               (base32
                "1iya43w7y26y2dp9l4d40bhjc4scb5a9mng5ng5c8hsqr82f1375"))))
    (build-system minify-build-system)
    (arguments
     `(#:javascript-files '("strftime.js")))
    (home-page "https://github.com/samsonjs/strftime")
    (synopsis "Implementation of strftime to JavaScript")
    (description "This is an implementation of the @code{strftime} procedure
for JavaScript.  It works in (at least) node.js and browsers.  It supports
localization and timezones.  Most standard specifiers from C are supported as
well as some other extensions from Ruby.")
    (license license:expat)))

(define-public js-highlight
  (package
    (name "js-highlight")
    (version "9.12.0")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://github.com/isagalaev/highlight.js/"
                                  "archive/" version ".tar.gz"))
              (file-name (string-append name "-" version ".tar.gz"))
              (sha256
               (base32
                "1jjn9mj7fwq4zpr6is438bscf03b3q8jkj0k5c3fc6pkmjnhw939"))))
    (build-system minify-build-system)
    (arguments
     `(#:javascript-files '("src/highlight.js")))
    (home-page "https://github.com/isagalaev/highlight.js")
    (synopsis "Syntax highlighting for JavaScript")
    (description "Highlight.js is a syntax highlighter written in JavaScript.
It works in the browser as well as on the server.  It works with pretty much
any markup, doesn’t depend on any framework and has automatic language
detection.")
    (license license:bsd-3)))

(define-public js-datatables
  (package
    (name "js-datatables")
    (version "1.10.15")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://datatables.net/releases/DataTables-"
                                  version ".zip"))
              (sha256
               (base32
                "1y9xqyqyz7x1ls3ska71pshl2hpiy3qnw1f7wygyslbhy4ssgf57"))))
    (build-system minify-build-system)
    (arguments
     `(#:javascript-files '("media/js/dataTables.bootstrap.js"
                            "media/js/jquery.dataTables.js")))
    (native-inputs
     `(("unzip" ,unzip)))
    (home-page "https://datatables.net")
    (synopsis "DataTables plug-in for jQuery")
    (description "DataTables is a table enhancing plug-in for the jQuery
Javascript library, adding sorting, paging and filtering abilities to plain
HTML tables with minimal effort.")
    (license license:expat)))

(define-public js-selectize
  (package
    (name "js-selectize")
    (version "0.12.4")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://github.com/selectize/selectize.js/"
                                  "archive/v" version ".tar.gz"))
              (file-name (string-append name "-" version ".tar.gz"))
              (sha256
               (base32
                "0756p49aaz34mw2dx8k1gxf210mngfrri25vkba0j7wihd2af8gn"))))
    (build-system minify-build-system)
    (arguments `(#:javascript-files '("src/selectize.js")))
    (home-page "http://selectize.github.io/selectize.js/")
    (synopsis "Hybrid widget between a textbox and <select> box")
    (description "Selectize is the hybrid of a textbox and @code{<select>}
box.  It's jQuery based and it has autocomplete and native-feeling keyboard
navigation; it is useful for tagging, contact lists, etc.")
    (license license:asl2.0)))

(define-public js-es5-shim
  (package
    (name "js-es5-shim")
    (version "4.5.9")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://github.com/es-shims/es5-shim/"
                                  "archive/v" version ".tar.gz"))
              (file-name (string-append name "-" version ".tar.gz"))
              (sha256
               (base32
                "0yfndyijz0ykddzprpvfjb2453gzpn528klmwycwbqc1bqd3m1hl"))))
    (build-system minify-build-system)
    (arguments `(#:javascript-files
                 '("es5-sham.js"
                   "es5-shim.js")))
    (home-page "https://github.com/es-shims/es5-shim")
    (synopsis "ECMAScript 5 compatibility shims for legacy JavaScript engines")
    (description "@code{es5-shim.js} patches a JavaScript context to contain
all ECMAScript 5 methods that can be faithfully emulated with a legacy
JavaScript engine.  @code{es5-sham.js} patches other ES5 methods as closely as
possible.  Many of these shams are intended only to allow code to be written
to ES5 without causing run-time errors in older engines.  In many cases, this
means that these shams cause many ES5 methods to silently fail.")
    (license license:expat)))

(define-public js-filesaver
  (package
    (name "js-filesaver")
    (version "1.3.8")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://github.com/eligrey/FileSaver.js/"
                                  "archive/" version ".tar.gz"))
              (file-name (string-append name "-" version))
              (sha256
               (base32
                "1rkhfqs5plaj628kzj7qgm5qahy4v7ihygifidqr6g6265mil97h"))))
    (build-system minify-build-system)
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (add-after 'unpack 'fix-uglification
           ;; Remove "export" keyword which prevents the file from being
           ;; uglified by uglify-js.  Moreover, that keyword is not present in
           ;; the minified version of the library some projects are using,
           ;; e.g.,
           ;; <https://github.com/jmoenig/Snap--Build-Your-Own-Blocks/blob/master/FileSaver.min.js>
           (lambda _
             (substitute* "src/FileSaver.js"
               (("export ") ""))
             #t)))))
    (home-page
     "https://eligrey.com/blog/saving-generated-files-on-the-client-side/")
    (synopsis "HTML5 saveAs() FileSaver implementation")
    (description "@file{FileSaver.js} implements the @code{saveAs()}
FileSaver interface in browsers that do not natively support it.

@file{FileSaver.js} is the solution to saving files on the
client-side, and is perfect for webapps that need to generate files,
or for saving sensitive information that shouldn't be sent to an
external server.")
    (license license:expat)))

(define-public mujs
  (package
    (name "mujs")
    (version "1.0.4")
    (source (origin
              (method git-fetch)
              (uri (git-reference
                    (url "https://git.ghostscript.com/mujs.git")
                    (commit version)))
              (file-name (string-append name "-" version "-checkout"))
              (sha256
               (base32
                "1ly0yybs66nk63517kg4dmdc7dbikhqqqf2r2kvccgzzvv6k0vs8"))))
    (build-system gnu-build-system)
    (arguments
     '(#:phases (modify-phases %standard-phases
                  (delete 'configure))  ; no configure
       #:make-flags (list (string-append "prefix=" (assoc-ref %outputs "out"))
                          (string-append "CC=gcc"))
       #:tests? #f))                    ; no tests
    (inputs
     `(("readline" ,readline)))
    (home-page "https://artifex.com/mujs/")
    (synopsis "JavaScript interpreter written in C")
    (description "MuJS is a lightweight Javascript interpreter designed for
embedding in other software to extend them with scripting capabilities.  MuJS
was designed with a focus on small size, correctness, and simplicity.  It is
written in portable C and implements ECMAScript as specified by ECMA-262.  The
interface for binding with native code is designed to be as simple as possible
to use, and is very similar to Lua.  There is no need to interact with byzantine
C++ template mechanisms, or worry about marking and unmarking garbage collection
roots, or wrestle with obscure build systems.")
    (license license:isc)))

license: mit


code:
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
;;; Copyright © 2017 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2017 Eric Bavier <bavier@member.fsf.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 packages jemalloc)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-26)
  #:use-module ((guix licenses) #:select (bsd-2))
  #:use-module (guix packages)
  #:use-module (guix download)
  #:use-module (guix utils)
  #:use-module (gnu packages)
  #:use-module (gnu packages perl)
  #:use-module (guix build-system gnu))

(define-public jemalloc
  (package
    (name "jemalloc")
    (version "5.0.1")
    (source (origin
              (method url-fetch)
              (uri (string-append
                    "https://github.com/jemalloc/jemalloc/releases/download/"
                    version "/jemalloc-" version ".tar.bz2"))
              (sha256
               (base32
                "1sf3lzgb0y8nnyzmp4zrca3sngdxw3kfh20sna9z03jv74fph528"))
              (patches (search-patches "jemalloc-arm-address-bits.patch"))))
    (build-system gnu-build-system)
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (add-after 'unpack 'delete-thp-test
           ;; This test does not check if transparent huge pages are supported
           ;; on the system before running the test.
           (lambda _
             (substitute* "Makefile.in"
               (("\\$\\(srcroot\\)test/unit/pages.c \\\\") "\\"))
             #t)))
       ,@(if (any (cute string-prefix? <> (or (%current-target-system)
                                              (%current-system)))
                 '("x64_64" "i686"))
           ;; Transparent huge pages are only enabled by default on Intel processors
           '()
           '(#:configure-flags (list "--disable-thp")))))
    (inputs `(("perl" ,perl)))
    (home-page "http://jemalloc.net/")
    (synopsis "General-purpose scalable concurrent malloc implementation")
    (description
     "This library providing a malloc(3) implementation that emphasizes
fragmentation avoidance and scalable concurrency support.")
    (license bsd-2)))

(define-public jemalloc-4.5.0
  (package
    (inherit jemalloc)
    (version "4.5.0")
    (source (origin
              (method url-fetch)
              (uri (string-append
                    "https://github.com/jemalloc/jemalloc/releases/download/"
                    version "/jemalloc-" version ".tar.bz2"))
              (sha256
               (base32
                "10373xhpc10pgmai9fkc1z0rs029qlcb3c0qfnvkbwdlcibdh2cl"))))
    (inputs '())))


code:
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014 Eric Bavier <address@hidden>
;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; 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 packages jrnl)
  #:use-module (guix packages)
  #:use-module (guix licenses)
  #:use-module (guix download)
  #:use-module (guix build-system python)
  #:use-module (gnu packages check)
  #:use-module (gnu packages python)
  #:use-module (gnu packages python-crypto)
  #:use-module (gnu packages time))

(define-public jrnl
  (package
    (name "jrnl")
    (version "1.9.7")
    (source
     (origin
      (method url-fetch)
      (uri (string-append "https://github.com/maebert/jrnl/archive/"
                          version ".tar.gz"))
      (file-name (string-append name "-" version ".tar.gz"))
      (sha256
       (base32
        "0mfq7hhw5np2dj9jlxpyyk2cg9i0xgz2brb894d928hczszy97bq"))))
    (build-system python-build-system)
    (native-inputs
     `(("behave" ,behave)))
    (inputs
     `(("python" ,python)
       ("python-keyring" ,python-keyring)
       ("python-pycrypto" ,python-pycrypto)
       ("python-pytz" ,python-pytz)
       ("python-tzlocal" ,python-tzlocal)
       ("python-six" ,python-six)
       ("python-dateutil" ,python-dateutil)
       ("python-parsedatetime" ,python-parsedatetime)))
    (home-page "http://maebert.github.io/jrnl/")
    (synopsis "Personal journal application")
    (description
     "Jrnl is a command line journal application that stores your journal in a
plain text file.  Optionally, your journal can be encrypted using 256-bit AES
encryption.")
    (license x11)))


code:
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015, 2016, 2017 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; 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 packages julia)
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (guix packages)
  #:use-module (guix download)
  #:use-module (guix utils)
  #:use-module (guix git-download)
  #:use-module (guix build-system gnu)
  #:use-module (gnu packages)
  #:use-module (gnu packages algebra)
  #:use-module (gnu packages base)
  #:use-module (gnu packages compression)
  #:use-module (gnu packages elf)
  #:use-module (gnu packages gcc)
  #:use-module (gnu packages llvm)
  #:use-module (gnu packages libevent)
  #:use-module (gnu packages libunwind)
  #:use-module (gnu packages maths)
  #:use-module (gnu packages multiprecision) ; mpfr
  #:use-module (gnu packages pcre)
  #:use-module (gnu packages perl)
  #:use-module (gnu packages pkg-config)
  #:use-module (gnu packages python)
  #:use-module (gnu packages textutils)
  #:use-module (gnu packages tls)
  #:use-module (gnu packages version-control)
  #:use-module (gnu packages wget)
  #:use-module (ice-9 match))

(define libuv-julia
  (let ((commit "52d72a52cc7ccd570929990f010ed16e2ec604c8")
        (revision "5"))
    (package (inherit libuv)
      (name "libuv-julia")
      (version (string-append "1.9.0-" revision "." (string-take commit 8)))
      (source (origin
                (method git-fetch)
                (uri (git-reference
                      (url "https://github.com/JuliaLang/libuv.git")
                      (commit commit)))
                (file-name (string-append name "-" version "-checkout"))
                (sha256
                 (base32
                  "1daxh6ci6q7znxxajr3bm16dd53ragm0d681wf4kzg542qnjq3lh"))))
      (build-system gnu-build-system)
      (arguments
       (substitute-keyword-arguments (package-arguments libuv)
         ((#:phases phases)
          `(modify-phases ,phases
             (delete 'autogen)))))
      (home-page "https://github.com/JuliaLang/libuv"))))

(define libunwind-for-julia
  (package
    (inherit libunwind)
    (version "1.1-julia2")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://s3.amazonaws.com/julialang/src/"
                                  "libunwind-" version ".tar.gz"))
              (sha256
               (base32
                "0499x7sg2v18a6cry6l8y713cgmic0adnjph8i0xr1db9p7n8qyv"))))))

(define-public julia
  (package
    (name "julia")
    (version "0.6.0")
    (source (origin
              (method url-fetch)
              (uri (string-append
                    "https://github.com/JuliaLang/julia/releases/download/v"
                    version "/julia-" version ".tar.gz"))
              (sha256
               (base32
                "0rd6lcc9sic10q1j3c6f9qr901i1c4554m93n2sz5b3mh37byqhw"))))
    (build-system gnu-build-system)
    (arguments
     `(#:test-target "test"
       #:modules ((ice-9 match)
                  (guix build gnu-build-system)
                  (guix build utils))

       ;; Do not strip binaries to keep support for full backtraces.
       ;; See https://github.com/JuliaLang/julia/issues/17831
       #:strip-binaries? #f

       ;; The DSOs use $ORIGIN to refer to each other, but (guix build
       ;; gremlin) doesn't support it yet, so skip this phase.
       #:validate-runpath? #f

       #:phases
       (modify-phases %standard-phases
         (delete 'configure)
         (add-after 'unpack 'prepare-deps
           (lambda* (#:key inputs #:allow-other-keys)
             (mkdir "deps/srccache")
             (copy-file (assoc-ref inputs "dsfmt")
                        "deps/srccache/dsfmt-2.2.3.tar.gz")
             (copy-file (assoc-ref inputs "objconv")
                        "deps/srccache/objconv.zip")
             (copy-file (assoc-ref inputs "suitesparse")
                        "deps/srccache/SuiteSparse-4.4.5.tar.gz")
             (copy-file (string-append (assoc-ref inputs "virtualenv")
                                       "/bin/virtualenv")
                        "julia-env")
             (copy-file (assoc-ref inputs "unicode-data")
                        "doc/UnicodeData.txt")
             #t))
         ;; FIXME: Building the documentation requires Julia packages that
         ;; would be downloaded from the Internet.  We should build them in a
         ;; separate build phase.
         (add-after 'unpack 'disable-documentation
           (lambda _
             (substitute* "Makefile"
               (("(install: .*) \\$\\(BUILDROOT\\)/doc/_build/html/en/index.html" _ line)
                (string-append line "\n"))
               (("src ui doc deps")
                "src ui deps"))
             #t))
         (add-before 'check 'set-home
           ;; Some tests require a home directory to be set.
           (lambda _ (setenv "HOME" "/tmp") #t))
         (add-after 'unpack 'hardcode-soname-map
          ;; ./src/runtime_ccall.cpp creates a map from library names to paths
          ;; using the output of "/sbin/ldconfig -p".  Since ldconfig is not
          ;; used in Guix, we patch runtime_ccall.cpp to contain a static map.
          (lambda* (#:key inputs #:allow-other-keys)
            (use-modules (ice-9 match))
            (substitute* "src/runtime_ccall.cpp"
              ;; Patch out invocations of '/sbin/ldconfig' to avoid getting
              ;; error messages about missing '/sbin/ldconfig' on GuixSD.
              (("popen\\(.*ldconfig.*\\);")
               "NULL;\n")

              ;; Populate 'sonameMap'.
              (("jl_read_sonames.*;")
               (string-join
                (map (match-lambda
                       ((input libname soname)
                        (string-append
                         "sonameMap[\"" libname "\"] = "
                         "\"" (assoc-ref inputs input) "/lib/" soname "\";")))
                     '(("libc"        "libc"           "libc.so.6")
                       ("pcre2"       "libpcre2-8"     "libpcre2-8.so")
                       ("mpfr"        "libmpfr"        "libmpfr.so")
                       ("openblas"    "libblas"        "libopenblas.so")
                       ("arpack-ng"   "libarpack"      "libarpack.so")
                       ("lapack"      "liblapack"      "liblapack.so")
                       ("libgit2"     "libgit2"        "libgit2.so")
                       ("gmp"         "libgmp"         "libgmp.so")
                       ("openlibm"    "libopenlibm"    "libopenlibm.so")
                       ("openspecfun" "libopenspecfun" "libopenspecfun.so")
                       ("fftw"        "libfftw3"       "libfftw3_threads.so")
                       ("fftwf"       "libfftw3f"      "libfftw3f_threads.so"))))))
            (substitute* "base/fft/FFTW.jl"
              (("const libfftw = Base.libfftw_name")
               (string-append "const libfftw = \""
                              (assoc-ref inputs "fftw") "/lib/libfftw3_threads.so"
                              "\""))
              (("const libfftwf = Base.libfftwf_name")
               (string-append "const libfftwf = \""
                              (assoc-ref inputs "fftwf") "/lib/libfftw3f_threads.so"
                              "\"")))
            (substitute* "base/math.jl"
              (("const libm = Base.libm_name")
               (string-append "const libm = \""
                              (assoc-ref inputs "openlibm")
                              "/lib/libopenlibm.so"
                              "\""))
              (("const openspecfun = \"libopenspecfun\"")
               (string-append "const openspecfun = \""
                              (assoc-ref inputs "openspecfun")
                              "/lib/libopenspecfun.so"
                              "\"")))
            (substitute* "base/pcre.jl"
              (("const PCRE_LIB = \"libpcre2-8\"")
               (string-append "const PCRE_LIB = \""
                              (assoc-ref inputs "pcre2")
                              "/lib/libpcre2-8.so" "\"")))
            #t))
         (add-before 'build 'fix-include-and-link-paths
          (lambda* (#:key inputs #:allow-other-keys)
            ;; LIBUTF8PROC is a linker flag, not a build target.  It is
            ;; included in the LIBFILES_* variable which is used as a
            ;; collection of build targets and a list of libraries to link
            ;; against.
            (substitute* "src/flisp/Makefile"
              (("\\$\\(BUILDDIR\\)/\\$\\(EXENAME\\): \\$\\(OBJS\\) \\$\\(LIBFILES_release\\)")
               "$(BUILDDIR)/$(EXENAME): $(OBJS) $(LLT_release)")
              (("\\$\\(BUILDDIR\\)/\\$\\(EXENAME\\)-debug: \\$\\(DOBJS\\) \\$\\(LIBFILES_debug\\)")
               "$(BUILDDIR)/$(EXENAME)-debug: $(DOBJS) $(LLT_debug)"))

            ;; The REPL must be linked with libuv.
            (substitute* "ui/Makefile"
              (("JLDFLAGS \\+= ")
               (string-append "JLDFLAGS += "
                              (assoc-ref %build-inputs "libuv")
                              "/lib/libuv.so ")))

            (substitute* "base/Makefile"
              (("\\$\\(build_includedir\\)/uv-errno.h")
               (string-append (assoc-ref inputs "libuv")
                              "/include/uv-errno.h")))
            #t))
         (add-before 'build 'replace-default-shell
          (lambda _
            (substitute* "base/client.jl"
              (("/bin/sh") (which "sh")))
            #t))
         (add-after 'unpack 'hardcode-paths
           (lambda _
             (substitute* "base/interactiveutil.jl"
               (("`which") (string-append "`" (which "which")))
               (("`wget")  (string-append "`" (which "wget"))))
             #t))
         (add-before 'check 'disable-broken-tests
           (lambda _
             ;; Adjust expected error messages to match what current libgit2
             ;; provides.
             (substitute* "test/libgit2.jl"
               (("Invalid Content-Type") "invalid Content-Type")
               (("Failed to resolve path") "failed to resolve path"))

             (substitute* "test/choosetests.jl"
               ;; These tests fail, probably because some of the input
               ;; binaries have been stripped and thus backtraces don't look
               ;; as expected.
               (("\"backtrace\",") "")
               (("\"compile\",") "")
               (("\"replutil\",") "")
               (("\"cmdlineargs\",") "")
               ;; FIXME: This test fails with the following error:
               ;; Error in testset file:
               ;; Test Failed
               ;;   Expression: download("ba\0d", "good")
               ;;     Expected: ArgumentError
               ;;       Thrown: Base.UVError
               (("\"file\",") ""))
             #t)))
       #:make-flags
       (list
        (string-append "prefix=" (assoc-ref %outputs "out"))

        ;; Passing the MARCH flag is necessary to build binary substitutes for
        ;; the supported architectures.
        ,(match (or (%current-target-system)
                    (%current-system))
           ("x86_64-linux" "MARCH=x86-64")
           ("i686-linux" "MARCH=pentium4")
           ("aarch64-linux" "MARCH=armv8-a")
           ;; Prevent errors when querying this package on unsupported
           ;; platforms, e.g. when running "guix package --search="
           (_ "MARCH=UNSUPPORTED"))

        "CONFIG_SHELL=bash"     ;needed to build bundled libraries
        "USE_SYSTEM_DSFMT=0"    ;not packaged for Guix and upstream has no
                                ;build system for a shared library.
        "USE_SYSTEM_LAPACK=1"
        "USE_SYSTEM_BLAS=1"
        "USE_BLAS64=0"          ;needed when USE_SYSTEM_BLAS=1

        "USE_SYSTEM_FFTW=1"
        "LIBFFTWNAME=libfftw3"
        "LIBFFTWFNAME=libfftw3f"

        ;; TODO: Suitesparse does not install shared libraries, so we cannot
        ;; use the suitesparse package.
        ;; "USE_SYSTEM_SUITESPARSE=1"
        ;; (string-append "SUITESPARSE_INC=-I "
        ;;                (assoc-ref %build-inputs "suitesparse")
        ;;                "/include")

        "USE_GPL_LIBS=1"        ;proudly
        "USE_SYSTEM_UTF8PROC=1"
        (string-append "UTF8PROC_INC="
                       (assoc-ref %build-inputs "utf8proc")
                       "/include")
        "USE_SYSTEM_LLVM=1"
        "USE_LLVM_SHLIB=0" ; FIXME: fails when set to 1

        "USE_SYSTEM_LIBUNWIND=1"
        "USE_SYSTEM_LIBUV=1"
        (string-append "LIBUV="
                       (assoc-ref %build-inputs "libuv")
                       "/lib/libuv.so")
        (string-append "LIBUV_INC="
                       (assoc-ref %build-inputs "libuv")
                       "/include")
        "USE_SYSTEM_PATCHELF=1"
        "USE_SYSTEM_PCRE=1"
        "USE_SYSTEM_OPENLIBM=1"
        "USE_SYSTEM_GMP=1"
        "USE_SYSTEM_MPFR=1"
        "USE_SYSTEM_ARPACK=1"
        "USE_SYSTEM_LIBGIT2=1"
        "USE_SYSTEM_OPENSPECFUN=1")))
    (inputs
     `(("llvm" ,llvm-3.9.1)

       ;; The bundled version is 3.3.0 so stick to that version.  With other
       ;; versions, we get test failures in 'linalg/arnoldi' as described in
       ;; <https://bugs.gnu.org/30282>.
       ("arpack-ng" ,arpack-ng-3.3.0)

       ("coreutils" ,coreutils) ;for bindings to "mkdir" and the like
       ("lapack" ,lapack)
       ("openblas" ,openblas) ;Julia does not build with Atlas
       ("libunwind" ,libunwind-for-julia)
       ("openlibm" ,openlibm)
       ("openspecfun" ,openspecfun)
       ("libgit2" ,libgit2)
       ("fftw" ,fftw)
       ("fftwf" ,fftwf)
       ("fortran" ,gfortran)
       ("libuv" ,libuv-julia)
       ("pcre2" ,pcre2)
       ("utf8proc" ,utf8proc)
       ("mpfr" ,mpfr)
       ("wget" ,wget)
       ("which" ,which)
       ("zlib" ,zlib)
       ("gmp" ,gmp)
       ("virtualenv" ,python2-virtualenv)
       ;; FIXME: The following inputs are downloaded from upstream to allow us
       ;; to use the lightweight Julia release tarball.  Ideally, these inputs
       ;; would eventually be replaced with proper Guix packages.

       ;; TODO: run "make -f contrib/repackage_system_suitesparse4.make" to copy static lib
       ("suitesparse"
        ,(origin
           (method url-fetch)
           (uri "http://faculty.cse.tamu.edu/davis/SuiteSparse/SuiteSparse-4.4.5.tar.gz")
           (sha256
            (base32
             "1jcbxb8jx5wlcixzf6n5dca2rcfx6mlcms1k2rl5gp67ay3bix43"))))
       ("objconv"
        ,(origin
           (method url-fetch)
           ;; No versioned URL, see <https://www.agner.org/optimize/> for updates.
           (uri "https://www.agner.org/optimize/objconv.zip")
           (file-name "objconv-2018-08-15.zip")
           (sha256
            (base32
             "09y4pwxfs6fl47cyingbf95i2rxx74wmycl9fd4ldcgvpx9bzdrx"))))
       ("dsfmt"
        ,(origin
           (method url-fetch)
           (uri (string-append
                 "http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/"
                 "SFMT/dSFMT-src-2.2.3.tar.gz"))
           (sha256
            (base32
             "03kaqbjbi6viz0n33dk5jlf6ayxqlsq4804n7kwkndiga9s4hd42"))))))
    (native-inputs
     `(("openssl" ,openssl)
       ("perl" ,perl)
       ("patchelf" ,patchelf)
       ("pkg-config" ,pkg-config)
       ("python" ,python-2)
       ("unicode-data"
        ,(origin
           (method url-fetch)
           (uri "http://www.unicode.org/Public/9.0.0/ucd/UnicodeData.txt")
           (sha256
            (base32
             "13zfannnr6sa6s27ggvcvzmh133ndi38pfyxsssvjmw2s8ac9pv8"))))))
    ;; Julia is not officially released for ARM and MIPS.
    ;; See https://github.com/JuliaLang/julia/issues/10639
    (supported-systems '("i686-linux" "x86_64-linux" "aarch64-linux"))
    (home-page "https://julialang.org/")
    (synopsis "High-performance dynamic language for technical computing")
    (description
     "Julia is a high-level, high-performance dynamic programming language for
technical computing, with syntax that is familiar to users of other technical
computing environments.  It provides a sophisticated compiler, distributed
parallel execution, numerical accuracy, and an extensive mathematical function
library.")
    (license license:expat)))