From: Graham Inggs Date: Tue, 22 Jan 2019 20:19:55 +0000 (+0000) Subject: Import julia_1.0.3+dfsg-4.debian.tar.xz X-Git-Tag: archive/raspbian/1.0.4+dfsg-1+rpi1~1^2~18^2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=93e743ffa35b5364c06ba4f0cc50c130df7b490f;p=julia.git Import julia_1.0.3+dfsg-4.debian.tar.xz [dgit import tarball julia 1.0.3+dfsg-4 julia_1.0.3+dfsg-4.debian.tar.xz] --- 93e743ffa35b5364c06ba4f0cc50c130df7b490f diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..7603a52 --- /dev/null +++ b/NEWS @@ -0,0 +1,14 @@ +julia (0.3.12-1) unstable; urgency=medium + + Starting with this release, the dynamic library loader only + considers files with a .so extension when given a library name + without an extension. With previous releases, the loader would + fall back to files with a .so.VERSION extension, which could + result in undefined behaviour when multiple versions of the + same library were installed. + + Before you install an external Julia package using Pkg.add() that + depends on a shared library, make sure to install the matching + lib*-dev package, which provides a symlink with a .so extension. + + -- Peter Colberg Tue, 10 Nov 2015 23:52:57 -0500 diff --git a/README.Debian b/README.Debian new file mode 100644 index 0000000..d068bd9 --- /dev/null +++ b/README.Debian @@ -0,0 +1,67 @@ +Starting Julia REPL +------------------- + + Simply type `julia' in a shell to launch an interactive Julia session. + + Full documentation and examples are available in the julia-doc package. + /usr/share/doc/julia/html/en/index.html + + An Emacs mode for editing Julia source files and managing interactive sessions + is available in the ess package. + + -- Sébastien Villemot , Wed, 16 Oct 2013 16:07:45 +0200 + + +Julia and Math Kernel Library (Intel-MKL) +----------------------------------------- + + There are two ways to switch the BLAS/LAPACK implementation to MKL. + 1. Switch the libblas.so.3 and liblapack.so.3 candidate with Debian's + alternatives system. + 2. Rebuild Julia against MKL. + + Alternatives System + ^^^^^^^^^^^^^^^^^^^ + + You can switch e.g. libblas.so.3-x86_64-linux-gnu with galternatives. + + $ sudo apt install galternatives + + When not using OpenBLAS, you might encounter the following warning, + but it doesn't harm: + + WARNING: Error during initialization of module LinearAlgebra: + ErrorException("could not load symbol "openblas_get_config": + /usr/bin/../lib/x86_64-linux-gnu/julia/libblas.so: undefined symbol: openblas_get_config") + + Rebuild against MKL + ^^^^^^^^^^^^^^^^^^^ + + To rebuild Julia against MKL, set the variable CUSTOM_MKL as 1 in + debian/rules, and rebuild the package. Please make sure that you + have intel-mkl installed before doing the custom build. + + Brief Instruction for doing custom build against MKL: + + 0. Fetch the source package of julia and enter the source tree. + + 1. Install the build dependencies and helper scripts + + $ sudo apt install devscripts + $ sudo apt build-dep julia + + 2. Modify debian/rules, setting CUSTOM_MKL to 1 . + + 3. Build, check, and install. + + $ debuild -j4 + $ debc + $ sudo debi + + Known Problems about MKL + ^^^^^^^^^^^^^^^^^^^^^^^^ + + 1. When MKL is installed in the build environment, this test failure + may appear: https://github.com/JuliaLang/julia/issues/23264 + + -- Mo Zhou Thu, 22 Sept 2018 09:00:00 +0000 diff --git a/changelog b/changelog new file mode 100644 index 0000000..d65aa78 --- /dev/null +++ b/changelog @@ -0,0 +1,1074 @@ +julia (1.0.3+dfsg-4) unstable; urgency=medium + + [ Mo Zhou ] + * Set JULIA_CPU_TARGET="pwr8" for ppc64el architecture + + [ Graham Inggs] + * Avoid baseline violation on armhf, thanks Adrian Bunk + (Closes: #919183) + * Build with GCC 8 on armhf again + + -- Graham Inggs Tue, 22 Jan 2019 20:19:55 +0000 + +julia (1.0.3+dfsg-3) unstable; urgency=medium + + * Switch to use embedded LLVM-6.0.0 with upstream patches. + + Embed llvm-6.0.0.src.tar.xz to debian/embedded. + + Register new tarball in source/include-binaries. + + Set USE_SYSTEM_LLVM=0 in rules. + + Add patch do-not-download-llvm.patch to redirect downloading. + + Add symlinks in debian/embedded to avoid "download" errors. + + Add cmake, python3 to B-D for the embedded LLVM. + + Update copyright for the embedded LLVM. + + Patch Makefile and update rules to amend installation. + + Install the embedded LLVM to Julia's private library directory. + + dh_makeshlibs: Don't track symbols for the private LLVM library. + - Drop B-D on Debian's LLVM 6.0 + - Remove makefile options for system LLVM. + * Remove the DESTDIR definition from make flags. This definition + screws up installtion of embedded LLVM. + * Add hack for embedded LLVM to let it install shlibs correctly. + * Refresh patches (quilt push -a --refresh). + * Skip more DNS tests for Sockets.jl module. + + -- Mo Zhou Thu, 17 Jan 2019 15:27:52 +0000 + +julia (1.0.3+dfsg-2) unstable; urgency=medium + + [ Graham Inggs ] + * Skip DNS tests which fail on Ubuntu autopkgtest infrastructure + + [ Mo Zhou ] + * Add d/gitlab-ci.yml for enabling Salsa CI pipeline. + * Delete the unused DEBIAN_FORCE_NONET env var from rules and autopkgtest. + * Update copyright for embedded .jl packages. + * Uscan: add dversionmangle option to append +dfsg postfix. + * Add headers for headless patches. + * Add patch (disabled by default) to append "@distro" to default LOAD_PATH. + * Bump Standards-Version to 4.3.0 (no change). + * Rollback embedded Documenter to 0.20.0, DocStringExtensions to 0.5.0 . + * Refresh the list of included-binaries. + * Bump B-D-I pygmentize to Py3 version. + + Append python3-pkg-resources to B-D-I to workaround #918401 + * Add repacksuffix option to uscan. + * Add openssl to B-D (more test coverage) and Recommends. + + -- Mo Zhou Sun, 13 Jan 2019 10:53:28 +0000 + +julia (1.0.3+dfsg-1) unstable; urgency=medium + + * Users who want to use MKL as Julia's BLAS/LAPACK backend should + rebuild this package after turning on the CUSTOM_MKL flag in d/rules. + I temporarily reverted the use of alternatives mechanism because the + code of stdlib/LinearAlgebra is not ready for such a feature. + + * DFSG: Exclude contrib/windows/7zS.sfx (Closes: #916957) + * Remove the aforementioned incremental patch since the + source tarball has been refreshed. + * Revert "Link libjulia.so.X against libblas.so.3 to take + advantage from alternatives." (Closes: #916991) + + -- Mo Zhou Fri, 21 Dec 2018 14:47:47 +0000 + +julia (1.0.3-2) unstable; urgency=medium + + * Cherry-pick incremental patch from upstream's force-pushed 1.0.3 tag. + + -- Mo Zhou Tue, 18 Dec 2018 06:25:16 +0000 + +julia (1.0.3-1) unstable; urgency=medium + + * New upstream version 1.0.3 + * Strip shared object libjulia.so.1 , whilst sys.so is still unstripped. + * Update embedded tarball for Pkg.jl . + * Refresh and update patches, including patches for embedded source. + * Refresh doc-silent.patch on new embedded source. + * Upgrade embedded DocStringExtensions.jl to v0.6.0 + * Upgrade embedded Documenter to v0.21.0 + * Remove embedded Compat.jl, not used by Documenter.jl anymore. + + -- Mo Zhou Mon, 17 Dec 2018 10:15:03 +0000 + +julia (1.0.2-1) unstable; urgency=medium + + * New upstream version 1.0.2 + * Remove test-precision.patch, merged upstream. + * Import Pkg.jl tarball to d/embedded directory. + Its sha512sum matches with the one provided by upstream. + + Register the Pkg.jl tarball in include-binaries. + + Patch makefile to avoid downloading Pkg.jl tarball. + * Remove LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING definition from rules. + * Refresh Patches. + + -- Mo Zhou Thu, 29 Nov 2018 06:50:23 +0000 + +julia (1.0.1-2) unstable; urgency=medium + + * Extend JULIA_CPU_TARGET to include optimized targets as well, + apart from the generic target. (Closes: #910784) + + -- Mo Zhou Sat, 13 Oct 2018 06:16:18 +0000 + +julia (1.0.1-1) unstable; urgency=medium + + * New upstream stable release 1.0.1 (Sept 2018) + * Remove hundreds of patches picked from WIP Julia 1.0.1 release. + * Elaborate on why debug info should not be stripped from sys.so in rules. + * Drop deps:openspecfun which is not used anymore since 0.7 release. + * Add CUSTOM_NATIVE variable in rules for custom builds. + * Drop test related patches, because they are not needed anymore: + - Drop test-add-envvar-for-skipping-network-tests.patch . + - Drop test-moredetail.patch, test-skip-ppc64el-spec.patch + - Drop test-remove-powermod.patch, test-aggressive-gc.patch . + + -- Mo Zhou Sun, 30 Sep 2018 15:22:20 +0000 + +julia (1.0.0-3) unstable; urgency=medium + + * Handle floating point precision issue during test. (test-precision.patch) + * Patch runtests.jl to let it print more detail. (test-moredetail.patch) + * Make Documenter.jl quiet. (pre-apply, doc-silent.patch) + * Autopkgtest: Skip network related tests for Ubuntu. + * Link libjulia.so.X against netlib LAPACK (libblas.so.3/liblapack.so.3) + in order to take advantage from alternatives system. (Closes: #905826) + * Shared object libjulia.so.X Depends on high performance BLAS/LAPACK + implementations when available, i.e. OpenBLAS | Atlas | Intel-MKL. + * Add 167 patches from work-in-progress Julia 1.0.1 release. + * Autopkgtest: Execute runtests.jl instead of calling Base.runtests() + * README.Debian: Julia's BLAS/LAPACK backend is switchable henceforth. + * Also remove the "net_on" guard in test/runtests.jl. + (update, test-add-envvar-for-skipping-network-tests.patch) + * Downgrade GCC version to 7 for armhf in order to circumvent FTBFS. + + -- Mo Zhou Sun, 23 Sep 2018 03:11:52 +0000 + +julia (1.0.0-2) unstable; urgency=medium + + * Run test on all architectures instead of only amd64 and i386, + but allow non-x86 tests to fail. (Closes: #906754) + * Binary package julia Suggests vim-julia. (Closes: #907050) + * Enable the build on s390x + - Disable libunwind on s390x (unsatisfiable dependency). + * shlibdeps.mk: don't link against libunwind on s390x architecture. + * Fix logic error in base/Makefile. (+ make-unwind-logic-error.patch) + * Skip some tests unconditionally or conditionally according to Sys.ARCH + * Skip "powermod" related tests on non-x86 architecture. + * Skip several tests specifically on i386. (+ test-skip-i386-spec.patch) + * Skip several tests on ppc64el. (+ test-skip-ppc64el-spec.patch) + * Add patch test-add-envvar-for-skipping-network-tests.patch. + + rules: Export DEBIAN_FORCE_NONET to skip network tests during build. + * Add patch test-aggressive-gc.patch: make garbage collection aggressive. + * Re-arrange patches and refresh them. + * Disable thumb instruction set for armhf by adding -marm to cflags. + * Bump Standards-Version to 4.2.1 (no change). + * rules: Don't install extra license files. + * Override false-positive lintian error: wrong-path-for-interpreter. + * Upload to unstable. + + -- Mo Zhou Fri, 14 Sep 2018 11:09:12 +0000 + +julia (1.0.0-1) experimental; urgency=medium + + * New upstream version 1.0.0 + * Bump SOVERSION from 0.7.0 to 1.0.0, update debian directory accordingly. + * Package libjulia1.0 Breaks and Replaces libjulia0.7 . + * Refresh symbols list for libjulia.so.1.0 . + * Update the embedded Documenter: + + Documenter.jl to v0.19.4 + + Compat.jl to v1.0.1 . + + DocStringExtensions.jl to v0.4.6 . + * Update debian/source/include-binaries accordingly. + * Update patch privacy-breach.patch and pre-apply the patch. + * Add patch doc-unicode-data-path.patch and update deb-make-doc.patch + to avoid UnicodeData.txt File-Not-Found during documentation build. + * Refresh debian/copyright. + * Also build the PDF documentation apart from the HTML doc. + + Add latex related Build-Depends-Indep packages for building PDF doc. + + Override dh_auto_build-indep to build both HTML and PDF document. + + Install the generated PDF doc doc/_build/pdf/en/TheJuliaLanguage.pdf + + Register the PDF documentation in doc-base. + * Remove source/local-options , not useful anymore. + * Update appstream.patch from upstream pull request #28020. + + -- Mo Zhou Thu, 16 Aug 2018 07:48:17 +0000 + +julia (0.7.0-2) unstable; urgency=medium + + [ Peter Colberg ] + * Drop Build-Depends on libfftw3-dev, Bindings to the FFTW library + have been removed from Base. (Closes: #905849) + + [ Mo Zhou ] + * Replace Sys.CPU_CORES with Sys.CPU_THREADS in test script. + * Add patch test-skip-sigint.patch to temporarily avoid a random + test failure in test/stress.jl, which sometimes fail to catch SIGINT. + + -- Mo Zhou Sun, 12 Aug 2018 01:00:36 +0000 + +julia (0.7.0-1) unstable; urgency=medium + + * New upstream version 0.7.0 + * Update embedded libuv tarball to ed3700c849289ed01fe04273a7bf865340b2bd7e. + * Refresh all the patches. + * Move privacy-breach.patch to quilt directory, and pre-apply the patch. + * Require libgit2-dev (>= 0.27.0~) as B-D. + * Bump Standards-Version to 4.2.0 (no change). + * Three new symbols for libjulia0.7 0.7.0 . + * Only traverse within debian directory when fixing shebang. (Avoid FTBFSx2) + * README.Debian: Add brief instructions for rebuilding Julia against MKL. + * Update file matching expressions in copyright. + * Require llvm-6.0-dev (>= 1:6.0.1-3) in the B-D field. + + -- Mo Zhou Thu, 09 Aug 2018 16:43:05 +0000 + +julia (0.7.0~beta2-1) experimental; urgency=medium + + * New upstream BETA version 0.7.0~beta2 + * Changes related to embedded sources: + + Embed newer libuv tarball which is specified by upstream. + - Remove the old libuv-d8ab1c6a33e77bf155facb54215dd8798e13825d.tar.gz + + Embed libwhich-81e9723c0273d78493dc8c8ed570f68d9ce7e89e.tar.gz + - Remove embedded arpack tarball and corresponding b-d. + * Update binary file registration in source/include-binaries . + * Updates related to patch stack: + * Refresh patches for 0.7.0~beta2 + + Add patch: do-not-download-libwhich.patch + + Update patch deb-make-doc.patch to fix document build failure. + + Update no-debug-version.patch to adapt to upstream Makefile change. + - Remove do-not-download-arpack.patch, not used anymore. + - Remove do-not-query-ldconfig.patch, due to upstream's commit: + github.com/JuliaLang/julia/commit/28f3c06f2d30dd1ae2c189cf8fb54d625ecc26ad + - Remove patch: unversioned-system-load-path.patch (not applied). + We don't need it anymore because it may result in confusing behaviour. + - Remove unused tests patch: test_libgit2.patch, unicode-test.patch, + test_replcompletions.patch. Nolonger needed since the tests don't fail. + * Control-related changes: + * Bump B-D llvm version to 6 (Closes: #873408) + * Bump SOVERSION, and update corresponding file names. + * Update .install files: install several new files. + * Update symbols control file. + * libjuila0.7 breaks and replaces libjulia0.6 . + * symbols: Mark jl_cpuidex as {amd64,i386}-only. + * Mark usr/share/doc/julia/html/* as not-installed to silent dh_missing. + * Build-related changes: + + Run dh_missing --list-missing during build. + + Suppress compiler warning by explicitly defining the following CXX flag: + -DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=0 + * JULIA_CPU_CORES is deprecated in favor of JULIA_CORE_THREADS. + * Fix shebang and mode bits during dh_fixperms: + 's@#!/usr/bin/env julia@#!/usr/bin/julia@g' + * Delete the deprecated make flag USE_SYSTEM_ARPACK. + * Policy-related changes: + + Update SOVERSION in lintian overrides + * julia-common: Override one more lintian Info: + package-contains-documentation-outside-usr-share-doc + * Miscellaneous changes: + - Delete comment from the watch file. + + Install an example config which tweaks the default prompt string. + * Update copyright for Julia 0.7.X and embedded sources. + * autopkgtest: Remove the arpack-sanity test, because arpack was split out + from Julia 0.7.X by upstream. + + -- Mo Zhou Mon, 23 Jul 2018 08:52:51 +0000 + +julia (0.6.4-2) unstable; urgency=medium + + * Let julia depend on libjulia0.6 (= ${binary:Version}) + * libjulia0.6 breaks julia (<< 0.5.0~) due to file overwrite. + This fixes stable->sid upgrade. (Closes: #903498) + * Remove unused patch version-git.patch since we have NO_GIT=1 in rules. + * Fill in patches' header with DEP-3 alike information. + + -- Mo Zhou Wed, 11 Jul 2018 09:23:52 +0000 + +julia (0.6.4-1) unstable; urgency=medium + + [ Mo Zhou ] + * New upstream version 0.6.4 + * Refresh patches after importing 0.6.4 . + * Replace the placeholder in watch file, which was left unchanged by mistake. + * Import embedded copy of libuv (checksum identical to upstream's). + libuv-d8ab1c6a33e77bf155facb54215dd8798e13825d.tar.gz + + Register the new embedded tarball in source/include-binary + * Refresh copyright for the tarball. + * Deprecate the get-orig-tarball target in rules. + * Split the autopkgtest test command into individual script. + * Replace the old do-not-download-libuv.patch patch with a new one. + * Patch: Let jldownload be verbose and download from file:// URI. + + debian/patches/jldownload-verbose-fakedownload.patch + * rules: Don't install any .gitignore file! + * rules: Update the TAGGED_RELEASE_BANNER to avoid confusion. + * Update the matching pattern in lintian overrides. + * Patch: disable unversioned-system-load-path.patch . + * Autopkgtest: One more script to test arpack sanity. + + [ Graham Inggs ] + * Disable unaligned access on armhf + * Enable ARM NEON extensions, since #842142 is fixed + + -- Mo Zhou Tue, 10 Jul 2018 16:08:48 +0000 + +julia (0.6.3-6) unstable; urgency=medium + + * Bump B-D on libutf8proc-dev to (>= 2.1.1) and enable + unicode/utf8proc test, since #902902 is fixed + * Drop libjulia0.6's explicit dependency on libgit2-26 + + -- Graham Inggs Mon, 09 Jul 2018 20:29:42 +0000 + +julia (0.6.3-5) unstable; urgency=medium + + * Switch B-D LLVM version from 3.9 -> 4.0 . + * Skip more tests in test/libgit2.jl to avoid FTBFS. + + -- Mo Zhou Mon, 09 Jul 2018 12:29:34 +0000 + +julia (0.6.3-4) unstable; urgency=medium + + * Don't strip sys.so and libjulia.so as suggested upstream. This fixes + several tests that fail during autopkgtest but didn't fail during build. + https://github.com/JuliaLang/julia/issues/23115#issuecomment-320715030 + * Override lintianE: libjulia0.6: unstripped-binary-or-object. + * Enable more tests from libgit2.jl and replcompletions.jl . + * Let libjulia0.6 depend on libgit2-27 (>= 0.27.0+dfsg.1-0.2) explicitly. + * Add missing symlinks to libmbedcrypto and libmbedx509 . + * Drop unneeded B-D libarpack2-dev, libjs-mathjax. + Drop libjs-underscore from julia-doc Depends. + * Revert "control: Stick to unicode-data version 11 to avoid surprise." + * Loosen libgit2 requirement to (>= 0.26.0+dfsg.1-1.1) . + * Explicitly Build-Depends on libmbedtls-dev. + * Upload to unstable. + + -- Mo Zhou Mon, 09 Jul 2018 09:08:35 +0000 + +julia (0.6.3-3) experimental; urgency=medium + + * rules: Wrap-and-sort the build flags. + * Fix a typo in shlibdeps.mk which could causes dh-link failure. + * Update shlibdeps.mk for libuv1 . + * rules: Comment that we cannot use the libuv1 provided in archive. + * Skip test "replcompletions" to avoid FTBFS. + See: https://github.com/JuliaLang/julia/issues/27958 + * Bump Standards-Version to 4.1.5 (no change). + * Add the missing B-D libcurl4-gnutls-dev | libcurl-dev . + + -- Mo Zhou Sat, 07 Jul 2018 08:39:35 +0000 + +julia (0.6.3-2) experimental; urgency=medium + + * Deal with symlinks for embedded julia documenter in more graceful way. + * Remove unused symlinks shipped in julia-doc . + * Install upstream NEWS, HISTORY, DISTRIBUTING, etc to julia. + * Merge debian/NOTES into debian/README.Debian + * Clean up old/unused parts in rules. + * Stick to unicode-data version 11 to avoid surprise. + * Update shlibdeps.mk according to upstream Make.inc . + * Move all private shared object files to package libjulia0.6 . + * Don't generate symbols for the private libarpack.so . + * Add a custom option to enable building Julia with MKL. + + -- Mo Zhou Fri, 06 Jul 2018 11:18:49 +0000 + +julia (0.6.3-1) experimental; urgency=medium + + [ Peter Colberg ] + * Update Vcs-* fields for move to salsa.debian.org + * New upstream version 0.6.0 + * Refresh patches + * Move manpages and examples back to julia package + * Add libjulia0.6 with runtime library + * Add libjulia-dev with runtime headers + * Build-Depends on llvm-3.9-dev + * Drop Build-Depends on python3-sphinx (Closes: #896622) + * Build-Depends on libgit2-dev (>= 0.23) + * Build-Depends on libutf8proc-dev (>= 2.1.0) + * Substitute deprecated parameters in autopkgtest command + * Update debian/copyright + * Drop embedded copy of Rmath from upstream tarball + * Drop embedded copy of juliadoc from upstream tarball + + [ Mo Zhou ] + * Add myself to Uploaders. + * Refresh patch after rebasing Peter's work to master (0.4.7-7). + * New upstream version 0.6.3 (Closes: #839668) + * Refresh existing patches based on Julia 0.6.3 . + * Household changes: + * Bump Standards-Version to 4.1.4 . + * Change Priority from extra to optional. (4.0.0 -> 4.0.1) + * Bump debhelper compat level to 11 . + * Remove --parallel option in favor of debhelper compat 11. + * Embed several convenient code copies to debian/embedded/ : + * These embedded Julia package copies are used to build Julia doc. + + Compat.jl-0.69.0 + + DocStringExtensions.jl-0.4.4 + + Documenter.jl-0.18.0 + * The embedded arpack source is used to avoid #902914. + + arpack-ng-3.3.0.tar.gz + * source: don't complain about binary files from embedded source. + * Patch upstream doc to avoid downloading anything. + + Build-Depends on unicode-data. (used during doc build) + + Prepare symlinks for embedded julia packages during dh_auto_configure. + + Patch upstream makefile to prevent it from downloading arpack source. + * Add upstream metadata including citation information. + * Upgrade watch file to uscan version 4. + * Move libjulia0.6 to libs section. + * Requires libgit2-dev >= 0.27.0+dfsg.1-0.5 for Build-Depends. + The specified version ships working TLS support. + * Add symbols control file for libjulia0.6 . + * rules: Don't use system Arpack. It causes "eigs(spdiagm(1:25))" failure. + * Patch upstream tester to skip utf8proc and libgit2 tests. + * Add missing Build-Depends for embedded arpack. + * Switch the default downloader dependency from wget to curl. + See https://github.com/JuliaLang/julia/issues/22783 . wget doesn't + throw the expected error, which would cause test failure. + * Patch embedded documenter code to prevent privacy-breach-generic . + + Replace google font css URL with customized css to avoid privacy breach. + + Use the "Incolsolata" font instead of "Roboto Mono". + + Document package depends on inconsolata font. + * Move AppStream xml file to new location /usr/share/metainfo . + * Patch upstream's outdated appstream xml file to prevent lintian Error. + * Update HTML documentation registration path in doc-base. + * Don't ship debug files e.g. libccalltest.so.debug . + * Don't trigger ldconfig for binary package "julia" because it ships libs + in private directory. This is accomplished by appending --no-scripts + option to dh_makeshlibs . An ldconfig trigger is manually added for + "libjulia0.6" package. + * Export HOME environt variable to really fix the mkdir permission issue. + * Mark symbol jl_cpuid as (amd64, i386)-only. + * Add NOTES to debian/ directory. (MKL is causing test failure) + * Note related to LLVM-4.0 : julia-0.6.3, built with llvm-4.0, is able to + pass the tests. However, llvm-3.9 is still preferred since upstream + sticks to llvm-3.9 . + * Update copyright for Julia 0.6.3 and embedded sources. + * Upload to experimental. + + -- Mo Zhou Thu, 05 Jul 2018 09:26:56 +0000 + +julia (0.4.7-7) unstable; urgency=medium + + * Add missing documentation option to fix build with Sphinx 1.5 + * Switch to debhelper 10 + * Use https in debian/control and debian/copyright + * Bump Standards-Version to 4.0.0 + * Drop override_dh_strip-arch, ddeb migration is complete + * Fix more Lintian warnings spelling-error-in-binary + * Mark all binary packages Multi-Arch: foreign + * Enable all hardening flags + + -- Graham Inggs Wed, 12 Jul 2017 14:50:13 +0200 + +julia (0.4.7-6) unstable; urgency=medium + + * Use openlibm instead of libm on mips, mips64el and mipsel + + -- Graham Inggs Wed, 25 Jan 2017 07:39:32 +0200 + +julia (0.4.7-5) unstable; urgency=medium + + * Use openlibm instead of libm on armhf and ppc64 + * Use openblas instead of blas and lapack on mips64el and ppc64 + * Update debian/copyright + * Do not override ARM options in Make.inc + * Do not print warning if unable to determine host CPU name + * Add src/*.dwo to debian/clean + * Explicitly set USE_SYSTEM_LIBM where needed + + -- Graham Inggs Mon, 23 Jan 2017 08:29:33 +0200 + +julia (0.4.7-4) unstable; urgency=medium + + * Use DEB_VENDOR inplace of lsb_release -si + + -- Peter Colberg Mon, 02 Jan 2017 22:28:51 -0500 + +julia (0.4.7-3) unstable; urgency=medium + + * Set TAGGED_RELEASE_BANNER to distribution and source package version + (Closes: #849815) + + -- Peter Colberg Sat, 31 Dec 2016 13:43:20 -0500 + +julia (0.4.7-2) unstable; urgency=medium + + * Ensure JULIA_CPU_CORES >= 2 to respawn test workers reaching memory limit + (Closes: #848506) + + -- Peter Colberg Tue, 20 Dec 2016 23:57:28 -0500 + +julia (0.4.7-1) unstable; urgency=medium + + * New upstream release + * Refresh patches + * Drop install-sh-exit-status.patch, applied upstream + * Drop verbose-build.patch since libuv is already built with V=1 + * Drop do-not-use-home-directory-in-tests.patch in favour of setting HOME + * Drop disable-download-test.patch since wget is not actually invoked + * Remove unused lintian override configure-generated-file-in-source + * Add debian/gbp.conf for pristine-tar + + -- Peter Colberg Sun, 18 Sep 2016 23:55:05 -0400 + +julia (0.4.6-1) unstable; urgency=medium + + [ Peter Colberg ] + * New upstream release + * Refresh patches + * Drop unneeded build dependency on libdouble-conversion-dev + * Bump Standards-Version to 3.9.8, no further changes + + [ Graham Inggs ] + * Use libopenlibm instead of libm on arm64 + * Fix inconsistent use of GNU_SOURCE in embedded libuv (Closes: #748573) + * Drop arm-rec_backtrace.patch, no longer needed since ARM ABI backport + + -- Peter Colberg Thu, 23 Jun 2016 22:20:54 -0400 + +julia (0.4.5-3) unstable; urgency=medium + + * Disable ARM NEON extensions. (Closes: #820220) + + -- Graham Inggs Sun, 17 Apr 2016 13:35:42 +0200 + +julia (0.4.5-2) unstable; urgency=medium + + * Make rec_backtrace() always return 0 on ARM and PPC64, + this avoids a FTBFS on armhf with recent GCC. + + -- Graham Inggs Thu, 07 Apr 2016 14:32:28 +0200 + +julia (0.4.5-1) unstable; urgency=medium + + * New upstream release. + * Refresh patches, new fix-spelling-error-in-binary.patch. + * Use libopenlibm instead of libm on powerpc and ppc64el. + + -- Graham Inggs Wed, 30 Mar 2016 17:56:56 +0200 + +julia (0.4.3-4) unstable; urgency=medium + + * Drop versioned build dependency on llvm-3.8-dev and + build dependencies on libllvm3.x (no longer needed). + * Upload to unstable. + + -- Graham Inggs Sun, 13 Mar 2016 11:06:39 +0200 + +julia (0.4.3-3) experimental; urgency=medium + + * Build depend on libllvm3.x as well (experimental). + + -- Graham Inggs Mon, 08 Feb 2016 13:06:53 +0200 + +julia (0.4.3-2) experimental; urgency=medium + + * Optionally build depend on llvm-3.8-dev (>= 1:3.8~+rc1). + * Add debian/clean to fix FTBFSx2. + * Migrate from julia-dbg to ddebs, bump debhelper build-dependency. + * Bump Standards-Version to 3.9.7, no further changes. + * Enable tests on i386 again. + * Improve generated debug info to fix FTBFS on i386 + (see upstream issue #13754). + + -- Graham Inggs Mon, 08 Feb 2016 10:02:00 +0200 + +julia (0.4.3-1) unstable; urgency=medium + + [ Graham Inggs ] + * Ensure pcre_h.jl and errno_h.jl are sorted reproducibly. + + [ Peter Colberg ] + * Imported Upstream version 0.4.3 + * Refresh patches. + * Drop patch fix-arm64-ftbfs.patch, no longer needed. + * Update Vcs-Git and Vcs-Browser fields. + * Fix lintian warning dh-exec-useless-usage. + * Fix lintian warning spelling-error-in-binary. + + -- Peter Colberg Thu, 14 Jan 2016 07:56:18 -0500 + +julia (0.4.2-3) unstable; urgency=medium + + * Fix FTBFS on arm64 (thanks to Edmund Grimley Evans). (Closes: #807701) + * Disable tests on i386 until perfomance issue with LLVM >= 3.4 + is resolved (see upstream issue #14191). + + -- Graham Inggs Sat, 12 Dec 2015 11:27:26 +0200 + +julia (0.4.2-2) unstable; urgency=medium + + * Set number of parallel workers for tests. + + Restart workers exceeding maximum resident memory size of 500 MiB. + * Drop build depends on llvm-3.8-dev to permit migration to testing. + (Closes: #803644) + + -- Peter Colberg Thu, 10 Dec 2015 06:50:01 -0500 + +julia (0.4.2-1) unstable; urgency=medium + + * Imported Upstream version 0.4.2 + * Refresh patches. + * Upload to unstable. (Closes: #803644) + + -- Peter Colberg Mon, 07 Dec 2015 06:49:01 -0500 + +julia (0.4.1-2) experimental; urgency=medium + + * Build depend on libpcre2-dev >= 10.20-3~ to fix FTBFS on ppc64el. + * Optionally build depend on llvm-3.8-dev to reduce performance regression. + * Optionally build depend on llvm-3.6-dev to ease backporting. + + -- Peter Colberg Wed, 02 Dec 2015 07:26:24 -0500 + +julia (0.4.1-1) experimental; urgency=medium + + * Imported Upstream version 0.4.1 + * Refresh patches. + * Update debian/copyright. + * Build depend on libsuitesparse-dev >= 1:4.4.5 + * Build depend on llvm-3.7-dev. + * Build depend on libpcre2-dev (thanks to Matthew Vernon). + * Disable libgit2 test to avoid dependency on libgit2. + * Disable download test to avoid dependency on curl or wget. + * Do not use home directory in tests. + * Fix backtrace test with MCJIT. + * Fix documentation spelling errors. + * Install examples to doc directory inplace of symlink. + + -- Peter Colberg Wed, 25 Nov 2015 08:00:20 -0500 + +julia (0.3.12-2) unstable; urgency=medium + + [ Peter Colberg ] + * Fix automated package testing with autopkgtest. + * Test REPL in dumb mode. + * Build depend on libopenlibm-dev (>= 0.4.1+dfsg-4~) to fix FTBFS on i386. + * Fix arch-all-only build with dpkg-buildpackage -A. + + [ Sébastien Villemot ] + * Remove myself from Uploaders. + + -- Graham Inggs Wed, 25 Nov 2015 10:46:18 +0200 + +julia (0.3.12-1) unstable; urgency=medium + + [ Peter Colberg ] + * Imported Upstream version 0.3.12 + * Add julia-common package with standard library and test suite. + * Remove embedded libraries: + + Build depend on libdsfmt-dev. + + Build depend on libutf8proc-dev. + * Generate version_git.jl from upstream commit. + * Build documentation using python3-sphinx. + * Fix potential privacy breach in documentation: + + Use libjs-modernizr package inplace of external link. + + Strip external link to Google Fonts API. + * Query SSE2 extension on i386 using x86 CPUID opcode. + * Do not query ldconfig for library sonames. + * Generate package dependencies for dynamically loaded libraries. + * Symlink dynamically loaded libraries to private library path. + * Add missing examples test for Base.runtests(). + * Fix hanging socket test for Base.runtests(). + * Enable parallel test. + + [ Graham Inggs ] + * Build in the multiarch lib directories as well, + so that patchelf is no longer required. (Closes: #799099) + * Build everywhere. (Closes: #802583) + + Use libopenlibm where available, libm elsewhere. + + Use libopenblas where available, libblas and liblapack elsewhere. + + Cherry-pick patches from upstream 0.4.0 for armhf and ppc64el. + + -- Graham Inggs Fri, 13 Nov 2015 15:56:34 +0200 + +julia (0.3.11-1) unstable; urgency=medium + + * Imported Upstream version 0.3.11 + * d/p/mcjit-llvm-ftbfs.patch: dropped, applied upstream. + + -- Sébastien Villemot Sun, 06 Sep 2015 18:51:09 +0200 + +julia (0.3.10-1) unstable; urgency=medium + + * Imported Upstream version 0.3.10 + * d/p/inject-ldflags.patch: drop patch, no longer needed. + * d/p/mcjit-llvm-ftbfs.patch: new patch, taken from upstream. + + -- Sébastien Villemot Fri, 17 Jul 2015 23:14:01 +0200 + +julia (0.3.9-1) unstable; urgency=medium + + * Imported Upstream version 0.3.9 + * repl-test.patch: new patch, prevents a test failure. + + -- Sébastien Villemot Sun, 21 Jun 2015 14:57:41 +0200 + +julia (0.3.8-1) unstable; urgency=medium + + * Imported Upstream version 0.3.8. + For the time being, manually embed juliadoc python package. + In the longer run, a separate Debian package should be created. + * sphinx-build.patch: new patch, needed for building doc without virtualenv. + * unicode-test.patch: new patch to workaround a test failure in unicode.jl. + * Set a hard dependency on OpenBLAS. (Closes: #778912) + * Ship tests in main package, so that they can be run on the compiled binary. + * Add autopkgtest (DEP8) support. + + -- Sébastien Villemot Mon, 25 May 2015 15:48:34 +0200 + +julia (0.3.5-1) experimental; urgency=low + + * Imported Upstream version 0.3.5. (Closes: #776069) + + -- Sébastien Villemot Fri, 13 Feb 2015 23:31:19 +0100 + +julia (0.3.2-1) unstable; urgency=medium + + * Imported Upstream version 0.3.2 + * Ship new desktop file, SVG icon and appdata file. + + -- Sébastien Villemot Wed, 22 Oct 2014 18:42:04 +0200 + +julia (0.3.1-1) unstable; urgency=medium + + * Imported Upstream version 0.3.1 + * Fix get-orig-source rule with respect to embedded utf8proc. + * No longer embed sphinx-rtd-theme. + + Add build-dependency on python-sphinx-rtd-theme. + + Drop patch embed-sphinx-rtd-theme.patch. + * Bump Standards-Version to 3.9.6, no changes needed. + * No longer try the "parallel" test at build time. + It always fails in chroots. + + -- Sébastien Villemot Wed, 24 Sep 2014 11:56:26 +0200 + +julia (0.3.0-1) unstable; urgency=medium + + * New upstream release. + - no longer breaks on PCRE upgrades. (Closes: #755576) + - command-line option "-p" works as expected. (Closes: #758783) + * Rewrite get-orig-source in d/rules. In particular no longer embed openlibm, + since it is now a separate package. + * debian/copyright: reflect upstream changes. + * New patches: + + do-not-download-utf8proc.patch + + inject-ldflags.patch + + install-sh-exit-status.patch + * Dropped patches: + + do-not-download-patchelf.patch (instead build depend on patchelf) + + fix-cpu-detection.patch + + ld-library-path-for-testing.patch + + make-4.0.patch + + no-git.patch (instead use "make -C base version_git.jl.phony") + + readline-6.3.patch (Julia no longer uses readline) + + sysconfdir-install.patch (instead use new make variable) + + use-sonames-with-dlopen.patch (not really needed, too difficult to + maintain) + * Ship the cached binary system image (sys.so). + * Compile with MARCH=x86-64 on amd64, and with MARCH=pentium4. In particular, + this means that SSE2 is now required on i386, because x87 FPU computing is + not supported by upstream and is buggy. Abort nicely if the CPU does have + SSE2, and by the way activate SSE2 in dSFMT (require-sse2-on-i386.patch). + As a consequence, drop the now unneeded testsuite-i386.patch. + * Bump to LLVM 3.5. (Closes: #753971) + * Add libopenblas-base to Recommends. Having it first in the BLAS + dependency alternative is not enough to ensure that it is installed by + default. + * Use OpenBLAS for both BLAS and LAPACK, since the Debian package now ships + both. + * Documentation package (julia-doc): + + use dh_sphinxdoc + + use packaged Mathjax instead of online version (with + use_packaged_mathjax.patch, symbolic links in d/julia-doc.links and + appropriate logic in d/rules) + + use packaged awesome font + + embed sphinx-rtd-theme, since the corresponding package has not yet been + accepted in sid (embed-sphinx-rtd-theme.patch) + + -- Sébastien Villemot Wed, 20 Aug 2014 10:51:46 +0000 + +julia (0.2.1+dfsg-3) unstable; urgency=medium + + * make-4.0.patch: fix FTBFS against make 4.0. + + -- Sébastien Villemot Wed, 07 May 2014 15:17:37 +0200 + +julia (0.2.1+dfsg-2) unstable; urgency=medium + + * readline-6.3.patch: new patch, fixes FTBFS against readline 6.3. + (Closes: #741824) + * Restrict supported archs to amd64 and i386, it never compiled elsewhere. + + -- Sébastien Villemot Sun, 16 Mar 2014 16:25:21 +0100 + +julia (0.2.1+dfsg-1) unstable; urgency=medium + + * New upstream release. + + -- Sébastien Villemot Sat, 15 Feb 2014 21:31:41 +0100 + +julia (0.2.0+dfsg-6) unstable; urgency=medium + + * Transition to libunwind8-dev. (Closes: #730464) + + -- Sébastien Villemot Sat, 01 Feb 2014 10:18:04 +0100 + +julia (0.2.0+dfsg-5) unstable; urgency=low + + * Transition to suitesparse 4.2.1. + + -- Sébastien Villemot Mon, 02 Dec 2013 18:38:37 +0100 + +julia (0.2.0+dfsg-4) unstable; urgency=low + + * Make the parallel.jl test non-fatal. + + -- Sébastien Villemot Sun, 24 Nov 2013 15:14:50 +0100 + +julia (0.2.0+dfsg-3) unstable; urgency=low + + * testsuite-i386.patch: loosen the numerical precision for yet another test. + + -- Sébastien Villemot Sun, 17 Nov 2013 19:32:52 +0100 + +julia (0.2.0+dfsg-2) unstable; urgency=low + + * testsuite-i386.patch: new patches, fixes FTBFS on i386. + + -- Sébastien Villemot Sun, 17 Nov 2013 17:51:13 +0100 + +julia (0.2.0+dfsg-1) unstable; urgency=low + + * New upstream release. + * debian/copyright: reflect upstream changes + * Update patches: + + remove patches applied upstream: + - suitesparse-3.4.patch + - testsuite-i386.patch + + remove fhs.patch, and replace it by the SYSCONFDIR build option. + + sysconfdir-install.patch: new patch to make the SYSCONFDIR option work + for us. + + refresh other patches. + * Bump Standards-Version to 3.9.5, no changes needed. + * Dependency of julia-dbg on julia is now versioned. + + -- Sébastien Villemot Sun, 17 Nov 2013 12:10:10 +0100 + +julia (0.2.0~rc2+dfsg-2) unstable; urgency=low + + * Use (older) suitesparse 3.4. + + d/control: downgrade (build-)dependencies + + use-sonames-with-dlopen.patch: update sonames + + suitesparse-3.4.patch: new patch + * Downgrade build-dependency to libunwind7-dev (was libunwind8-dev). + libunwind8-dev is unlikely to merge to testing soon. + * unversioned-system-load-path.patch: new patch. + Drops version number from system load path. Versioning unnecessary since + this path is managed by dpkg/apt. Moreover, it would make transitions to + higher versions needlessly complicated. + * testsuite-i386.patch: new patch, fixes testsuite crash on i386. + * Use canonical URL for Vcs-* fields + + -- Sébastien Villemot Sun, 03 Nov 2013 16:00:08 +0100 + +julia (0.2.0~rc2+dfsg-1) experimental; urgency=low + + * New upstream release candidate + * Link dynamically against LLVM, this seems to now work correctly + + -- Sébastien Villemot Sat, 26 Oct 2013 04:33:44 +0000 + +julia (0.2.0~rc1+dfsg-1) experimental; urgency=low + + * New upstream release candidate + * Removed patches: + + do-not-download-jquery.patch + + fix-version.patch + + no-webrepl.patch + + suitesparse-3.4.patch + + use-system-double-conversion.patch + + zlib-1.2.8.patch + * Added patches: + + fhs.patch + + no-debug-version.patch + + verbose-build.patch + * Ship upstream manpage + * Ship NEWS.md + * Build depend on llvm-3.3-dev + * Build depend on libsuitesparse-dev >= 1:4.2.1 + * Stop distributing PDF documentation, it currently does not build + * debian/copyright: reflect upstream changes + + -- Sébastien Villemot Wed, 16 Oct 2013 15:54:13 +0200 + +julia (0.1.2+dfsg-3) unstable; urgency=low + + * Bump the B-D on dpkg-dev. + Support for source:Package and source:Version fields was added in dpkg-dev + 1.16.2 (Closes: #706470) + * Add support for DEB_BUILD_OPTIONS=nocheck (Closes: #706472) + * Add julia-dbg package + * Fix FTBFS with zlib >= 1.2.8 (Closes: #707962) + - zlib-1.2.8.patch: new patch, fixes the gzip.jl test + - tighten B-D on zlib1g-dev to >= 1:1.2.8 + + -- Sébastien Villemot Wed, 15 May 2013 12:44:14 +0200 + +julia (0.1.2+dfsg-2) unstable; urgency=low + + * Statically link against LLVM. + With dynamic linking, strange bugs appear when the runtime library is not + the same than the one used for building. At this stage it is not clear + whether it is a Julia or LLVM bug. Reported as Julia issue #2494. + - use-shared-llvm.patch: remove patch + - add Built-Using field for julia binary package + - keep a dependency of julia on libllvm3.2, since strpack.jl dlopen's it + + -- Sébastien Villemot Wed, 03 Apr 2013 17:03:39 +0200 + +julia (0.1.2+dfsg-1) unstable; urgency=low + + * Imported Upstream version 0.1.2+dfsg. + Contains hotfix for package manager. + * debian/patches/fix-version.patch: new patch + * Refresh other patches + + -- Sébastien Villemot Thu, 07 Mar 2013 20:50:18 +0100 + +julia (0.1.1+dfsg-1) unstable; urgency=low + + * Imported Upstream version 0.1.1+dfsg + * debian/copyright: reflect upstream changes + * Refresh patches + * Disable tk-wrapper, since it is no longer built upstream + * Update README.debian + + -- Sébastien Villemot Thu, 07 Mar 2013 12:14:59 +0100 + +julia (0.1+dfsg-1) unstable; urgency=low + + * First upstream release! + * debian/copyright: document how to recreate orig tarball + * Add a debian/watch file + * d/rules, d/p/no-git-patch: adapt for numbered releases. + In particular, add a COMMITSHA file in the orig tarball containing the + SHA of the release tag. + * Promote zlib1g and libarpack2 to Depends + * Fix typo in manpage + + -- Sébastien Villemot Thu, 14 Feb 2013 12:00:05 +0100 + +julia (0.1~20130213.git4bc33bbc-1) unstable; urgency=low + + * New upstream release candidate. + Hopefully obviates the need of ugly hacks in libuv in order to build on + build daemons. + * Remove obsolete patches: + + bump-version-0.1.patch + + disable-final-uv-loop.patch + + revert-stdin-file-iostream.patch + * Refresh other patches + + -- Sébastien Villemot Wed, 13 Feb 2013 10:58:23 +0100 + +julia (0.1~20130212.gitf375d4bb-1) unstable; urgency=low + + * New upstream snapshot. + * no-git.patch: simplify and improve patch + * gsvddense_blasint.patch: remove patch, applied upstream + * New patches: + + bump-version-0.1.patch + + disable-final-uv-loop.patch + + revert-stdin-file-iostream.patch + * Refresh other patches + + -- Sébastien Villemot Tue, 12 Feb 2013 12:02:24 +0100 + +julia (0.1~20130211.git86fbe98d-1) unstable; urgency=low + + * New upstream snapshot. + * debian/control: + + add git to Recommends (for Julia package manager) + + remove dependencies on libglpk-dev (it moved to its own package) + + add explicit dependency on libgmp10 (there is no more a wrapper) + * fix-clean-rules.patch: remove patch, applied upstream + * gsvddense_blasint.patch: new patch + * Refresh other patches + + -- Sébastien Villemot Mon, 11 Feb 2013 03:51:26 +0100 + +julia (0.0.0+20130206.git32ff5759-1) unstable; urgency=low + + * New upstream snapshot. + * debian/copyright: reflect upstream changes + * debian/rules: update get-orig-source to reflect upstream changes + + Don't ship nginx + + Adapt for new configure-random target in deps/Makefile + * Enable build of Tk wrapper. + + debian/control: add build dependency on tk-dev + + debian/rules: add tk rule to build-arch + * debian/julia.install: install VERSION and COMMIT files + * no-webrepl.patch: new patch + * Refresh other patches + * Add source override for config.status file under deps/random/ + + -- Sébastien Villemot Wed, 06 Feb 2013 17:54:29 +0100 + +julia (0.0.0+20130107.gitd9656f41-2) unstable; urgency=low + + * fix-cpu-detection.patch: do not use -momit-leaf-frame-pointer on non-x86 + archs + * Upgrade to LLVM 3.2. + + debian/control: bump build-dependency + + debian/rules: use llvm-config-3.2 + + debian/patches/use-shared-llvm.patch + debian/patches/use-sonames-with-dlopen.patch: update patches + + -- Sébastien Villemot Sat, 19 Jan 2013 15:33:43 +0100 + +julia (0.0.0+20130107.gitd9656f41-1) unstable; urgency=low + + * New upstream snashot + * No longer try to rebuild helpdb.jl. + + debian/rules: remove helpdb.jl from build-arch rule + + debian/control: move back python-sphinx to Build-Depends-Indep + * debian/copyright: reflect upstream changes + * Add Build-Conflicts on libatlas3-base (makes linalg tests fail) + * debian/rules: replace obsolete USE_DEBIAN makeflag by a list of + USE_SYSTEM_* flags + * debian/rules: on non-x86 systems, use libm instead of openlibm + * dpkg-buildflags.patch: remove patch, applied upstream + * Refreshed other patches + + -- Sébastien Villemot Wed, 16 Jan 2013 12:29:42 +0100 + +julia (0.0.0+20121214.gitdced1f7-1) unstable; urgency=low + + * New upstream snapshot. + * debian/copyright: reflect upstream changes + * Embedded libuv no longer uses libc-ares and libev. + + debian/control: remove them from build-dependencies + + debian/rules: no longer strip them from upstream tarball + + use-system-{ev,c-ares}.patch: remove patches + * Remove other patches merged upstream or no longer necessary + + fhs-multiarch.patch + + linalg-test-tolerance.patch + + remove-rpath.patch + + verbose-build.patch + * New patches + + do-not-download-patchelf.patch + + ld-library-path-for-testing.patch + + dpkg-multiarch.patch + + libjulia-release-drop-soname.patch + * Refresh other patches + * debian/rules: + + compile with MULTIARCH_INSTALL=1 + + build helpdb.jl as part of the build-arch rule + + abort on failures in extra tests + * debian/control: move python-sphinx to Build-Depends (now used in build-arch) + + -- Sébastien Villemot Tue, 18 Dec 2012 14:42:23 +0100 + +julia (0.0.0+20121102.git63e93f2-1) unstable; urgency=low + + * Initial release. (Closes: #691912) + + -- Sébastien Villemot Fri, 02 Nov 2012 16:29:29 +0100 diff --git a/clean b/clean new file mode 100644 index 0000000..c29dd69 --- /dev/null +++ b/clean @@ -0,0 +1,7 @@ +deps/libuv/Makefile +deps/libuv/config.log +deps/libuv/config.status +deps/libuv/libtool +deps/libuv/libuv.pc +src/*.dwo +base/version_git.jl diff --git a/compat b/compat new file mode 100644 index 0000000..b4de394 --- /dev/null +++ b/compat @@ -0,0 +1 @@ +11 diff --git a/control b/control new file mode 100644 index 0000000..0523cb5 --- /dev/null +++ b/control @@ -0,0 +1,164 @@ +Source: julia +Section: science +Homepage: https://julialang.org +Priority: optional +Standards-Version: 4.3.0 +Vcs-Git: https://salsa.debian.org/julia-team/julia.git +Vcs-Browser: https://salsa.debian.org/julia-team/julia +Maintainer: Debian Julia Team +Uploaders: Peter Colberg , + Graham Inggs , + Mo Zhou , +Build-Depends: + cmake, python3, + curl, + debhelper (>= 11~), + dpkg-dev (>= 1.16.2~), + libblas-dev | libblas.so, + libcurl4-gnutls-dev | libcurl-dev, + libdsfmt-dev (>= 2.2.3), + libgit2-dev (>= 0.27.0~), + libgmp-dev, + liblapack-dev | liblapack.so, + libmbedtls-dev, + libmpfr-dev, + libopenblas-dev [amd64 arm64 armhf i386 kfreebsd-amd64 kfreebsd-i386 mips64el ppc64el s390x], + libopenlibm-dev (>= 0.4.1+dfsg-4~) [any-i386 any-amd64 arm64 armhf mips mips64el mipsel powerpc ppc64 ppc64el], + libpcre2-dev (>= 10.20-3~), + libsuitesparse-dev (>= 1:4.4.5), + libunwind8-dev [!s390x], + libutf8proc-dev (>= 2.1.1), + openssl, + unicode-data, +Build-Depends-Indep: + latexmk, + texlive, + texlive-extra-utils, + texlive-fonts-extra, + texlive-latex-base, + texlive-latex-extra, + texlive-latex-recommended, + texlive-luatex, + texlive-plain-generic, + python3-pygments, + python3-pkg-resources, + fonts-lato, + +Package: julia +Architecture: any +Multi-Arch: foreign +Pre-Depends: ${misc:Pre-Depends} +Depends: julia-common (= ${source:Version}), + libjulia1 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Replaces: julia-common (<< 0.5.0~) +Breaks: julia-common (<< 0.5.0~) +Suggests: ess (>= 12.09-1~), julia-doc, vim-julia, +Recommends: git, openssl, +Description: high-performance programming language for technical computing + 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. The library, mostly written in Julia itself, also integrates mature, + best-of-breed C and Fortran libraries for linear algebra, random number + generation, FFTs, and string processing. Julia programs are organized around + defining functions, and overloading them for different combinations of + argument types (which can also be user-defined). + . + This package provides a complete Julia installation (JIT compiler, standard + library, text-based user interface). + +Package: libjulia1 +Section: libs +Architecture: any +Pre-Depends: ${misc:Pre-Depends} +Replaces: julia (<< 0.5.0~), libjulia0.6, libjulia0.7 +Breaks: julia (<< 0.5.0~), libjulia0.6, libjulia0.7 +Depends: ${misc:Depends}, ${shlibs:Depends}, + libopenblas-base [amd64 arm64 armhf i386 kfreebsd-amd64 kfreebsd-i386 mips64el ppc64el s390x] + | libatlas3-base [amd64 arm64 armel armhf hurd-i386 i386 kfreebsd-amd64 kfreebsd-i386 mips mips64el mipsel ppc64el s390x] + | libmkl-rt [amd64 i386], + libopenblas-dev [amd64 arm64 armhf i386 kfreebsd-amd64 kfreebsd-i386 mips64el ppc64el s390x] + | libatlas-base-dev [amd64 arm64 armel armhf hurd-i386 i386 kfreebsd-amd64 kfreebsd-i386 mips mips64el mipsel ppc64el s390x] + | libmkl-dev [amd64 i386], +Description: high-performance programming language for technical computing (runtime library) + 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. The library, mostly written in Julia itself, also integrates mature, + best-of-breed C and Fortran libraries for linear algebra, random number + generation, FFTs, and string processing. Julia programs are organized around + defining functions, and overloading them for different combinations of + argument types (which can also be user-defined). + . + This package provides the Julia runtime library. + +Package: julia-common +Architecture: all +Multi-Arch: foreign +Depends: ${misc:Depends} +Replaces: julia (<< 0.4.1-1~) +Breaks: julia (<< 0.4.1-1~) +Recommends: julia +Description: high-performance programming language for technical computing (common files) + 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. The library, mostly written in Julia itself, also integrates mature, + best-of-breed C and Fortran libraries for linear algebra, random number + generation, FFTs, and string processing. Julia programs are organized around + defining functions, and overloading them for different combinations of + argument types (which can also be user-defined). + . + This package contains the Julia standard library and test suite. + +Package: libjulia-dev +Section: libdevel +Architecture: any +Depends: libjulia1 (= ${binary:Version}), ${misc:Depends} +Description: high-performance programming language for technical computing (development) + 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. The library, mostly written in Julia itself, also integrates mature, + best-of-breed C and Fortran libraries for linear algebra, random number + generation, FFTs, and string processing. Julia programs are organized around + defining functions, and overloading them for different combinations of + argument types (which can also be user-defined). + . + This package provides the Julia runtime headers. + +Package: julia-doc +Architecture: all +Multi-Arch: foreign +Section: doc +Depends: ${misc:Depends}, + fonts-font-awesome, + fonts-inconsolata, + libjs-jquery, + libjs-jquery-ui, + libjs-mathjax, + libjs-highlight.js, + libjs-requirejs, + libjs-lodash, + node-normalize.css, + node-highlight.js, +Suggests: julia +Description: high-performance programming language for technical computing (documentation) + 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. The library, mostly written in Julia itself, also integrates mature, + best-of-breed C and Fortran libraries for linear algebra, random number + generation, FFTs, and string processing. Julia programs are organized around + defining functions, and overloading them for different combinations of + argument types (which can also be user-defined). + . + This package contains the Julia manual, which describes the language and its + standard library. It also contains example Julia programs. diff --git a/copyright b/copyright new file mode 100644 index 0000000..cb4e5d0 --- /dev/null +++ b/copyright @@ -0,0 +1,775 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: Julia +Source: https://julialang.org +Files-Excluded: + contrib/windows/7zS.sfx + +Files: * +Copyright: 2009-2016 Jeff Bezanson, Stefan Karpinski, Viral B. Shah + and other contributors: https://github.com/JuliaLang/julia/contributors +License: Expat + +Files: base/grisu/bignum.jl + base/grisu/bignums.jl + base/grisu/fastfixed.jl + base/grisu/fastprecision.jl + base/grisu/fastshortest.jl + base/grisu/float.jl +Copyright: 2006-2014, the V8 project authors. +License: BSD-3-clause + +Files: base/special/exp.jl + base/special/hyperbolic.jl + base/special/rem_pio2.jl + base/special/trig.jl +Copyright: 1993, 2004, Sun Microsystems, Inc. + 2009-2016 Jeff Bezanson, Stefan Karpinski, Viral B. Shah + and other contributors: https://github.com/JuliaLang/julia/contributors +License: Expat + +Files: stdlib/REPL/src/TerminalMenus/* +Copyright: 2017 Nick Paul +License: Expat + +Files: stdlib/SHA/* +Copyright: 2014 Elliot Saba +License: Expat + +Files: contrib/julia.appdata.xml +Copyright: 2014, Paul Lange +License: CC-BY-SA-3.0 + +Files: src/abi_llvm.cpp + src/abi_ppc64le.cpp + src/abi_win32.cpp + src/abi_win64.cpp + src/abi_x86.cpp + src/abi_x86_64.cpp +Copyright: 2007-2012, LDC Team. +License: BSD-3-clause + +Files: src/support/END.h + src/support/ENTRY.amd64.h + src/support/ENTRY.i387.h + src/support/_longjmp.win32.S + src/support/_setjmp.win32.S +Copyright: 1990, The Regents of the University of California. / William Jolitz +License: BSD-3-clause + +Files: src/support/MurmurHash3.c + src/support/MurmurHash3.h +Copyright: none +License: public-domain-murmurhash + MurmurHash3 was written by Austin Appleby, and is placed in the public + domain. The author hereby disclaims copyright to this source code. + +Files: src/support/asprintf.c +Copyright: 1997 Todd C. Miller + 2004 Darren Tucker +License: ISC + +Files: src/flisp/flisp.c + src/flisp/system.lsp +Copyright: 2009 Jeff Bezanson +License: BSD-3-clause + +Files: src/support/dirname.c +Copyright: 2012, 2013 MinGW.org project +License: Expat + +Files: src/getopt.c + src/getopt.h +Copyright: 2005-2014, Rich Felker, et al. +License: Expat + +Files: src/support/strptime.c +Copyright: 1997-1998, 2005, 2008, The NetBSD Foundation, Inc. +License: BSD-2-clause + +Files: src/disasm.cpp +Copyright: 2009-2016 Jeff Bezanson, Stefan Karpinski, Viral B. Shah +License: Expat +Comment: Original code comes from The LLVM Compiler Infrastructure. + Modified by Julia developers. + +Files: src/support/strtod.c +Copyright: 2009-2016 Jeff Bezanson, Stefan Karpinski, Viral B. Shah +License: Expat +Comment: Portions derived from the Python function _PyOS_ascii_strtod + Copyright 2001-2014 Python Software Foundation + +Files: src/crc32c.c +Copyright: 2013, Mark Adler +License: Zlib + +Files: src/support/tzfile.h +Copyright: NONE +License: public-domain-tzfile + This file is in the public domain, + so clarified as of 1996-06-05 by Arthur David Olson. + +Files: deps/gfortblas.c +Copyright: 2013 JuliaLang Project / Jameson Nash +License: Expat + +Files: deps/valgrind/valgrind.h +Copyright: 2000-2013, Julian Seward. +License: BSD-3-clause + +Files: deps/patches/llvm-D31524-sovers_4.0.patch +Copyright: 2017 Rebecca N. Palmer + 2017 Lisandro Damían Nicanor Pérez Meyer + 2017 Sylvestre Ledru +License: U-OF-I-BSD-LIKE +Comment: License copied from Sylvestre Ledru 's + copyright file from llvm-toolchain-4.0 source. + +Files: debian/* +Copyright: 2012-2015 Sébastien Villemot + 2015-2017 Graham Inggs + 2015-2017 Peter Colberg + 2018 Mo Zhou +License: Expat + +Files: debian/embedded/Pkg* +Copyright: 2017 Stefan Karpinski + 2017 SimonDanisch + 2016 Art Wild +License: Expat + +Files: debian/embedded/DocStringExtensions.jl*/* +Copyright: 2016 Michael Hatherly +License: Expat + +Files: debian/embedded/Documenter.jl*/* +Copyright: 2016 Michael Hatherly +License: Expat +Comment: + Files: debian/embedded/Documenter.jl*/assets/html/search.js + Copyright: Steven Levithan + License: Expat + +# Just a tiny library written for Julia. Maybe no need to package separately. +Files: debian/embedded/libwhich-81e9723c0273d78493dc8c8ed570f68d9ce7e89e.tar.gz +Copyright: 2017 Jameson Nash +License: Expat + +Files: debian/embedded/llvm* +Copyright: 2003-2017 University of Illinois at Urbana-Champaign. +License: U-OF-I-BSD-LIKE + +Files: debian/embedded/libuv-ed3700c849289ed01fe04273a7bf865340b2bd7e.tar.gz +Copyright: Joyent, Inc. and other Node contributors + 2013 Ben Noordhuis + StrongLoop, Inc. +License: Expat +Comment: Copyright for files contained in this tarball + Files: docs/src/sphinx-plugins/manpage.py + Copyright: 2013, Dariusz Dwornikowski. + License: Apache-2.0 + . + Files: config.guess + config.sub + Copyright: 1992-2014, Free Software Foundation, Inc. + License: GPL-3+ + . + Files: include/pthread-fixes.h + src/unix/pthread-fixes.c + Copyright: 2012, Google Inc. + 2013, Sony Mobile Communications AB + License: BSD-3-clause + . + Files: Makefile.am + Makefile.mingw + autogen.sh + checksparse.sh + configure.ac + src/heap-inl.h + src/queue.h + src/unix/atomic-ops.h + src/unix/spinlock.h + test/test-loop-configure.c + test/test-pipe-set-non-blocking.c + Copyright: 2013-2015, Ben Noordhuis + License: ISC + . + Files: samples/socks5-proxy/Makefile + samples/socks5-proxy/build.gyp + samples/socks5-proxy/client.c + samples/socks5-proxy/defs.h + samples/socks5-proxy/main.c + samples/socks5-proxy/s5.c + samples/socks5-proxy/s5.h + samples/socks5-proxy/server.c + samples/socks5-proxy/util.c + Copyright: StrongLoop, Inc. + License: Expat + . + Files: test/test-pipe-connect-multiple.c + test/test-pipe-connect-prepare.c + test/test-pipe-pending-instances.c + test/test-tcp-create-socket-early.c + test/test-udp-create-socket-early.c + Copyright: 2015 Saúl Ibarra Corretgé . + License: Expat + . + Files: ar-lib + compile + depcomp + ltmain.sh + missing + Copyright: 1996-2014, Free Software Foundation, Inc. + License: GPL-2+ + . + Files: m4/ltoptions.m4 + m4/ltsugar.m4 + m4/lt~obsolete.m4 + Copyright: 2004-2015, Free Software Foundation, Inc. + License: FSFULLR + . + Files: src/inet.c + Copyright: 2004 Internet Systems Consortium, Inc. ("ISC") + 1996-1999 Internet Software Consortium + License: ISC + . + Files: include/stdint-msvc2008.h + Copyright: 2006-2008 Alexander Chemeris + License: BSD-3-clause + . + Files: samples/socks5-proxy/getopt.c + Copyright: 1987, 1993, 1994 The Regents of the University of California / NetBSD + License: BSD-3-clause + . + Files: include/tree.h + Copyright: 2002 Niels Provos + License: BSD-2-clause + . + Files: include/android-ifaddrs.h + src/unix/android-ifaddrs.c + Copyright: 1995, 1999 Berkeley Software Design, Inc. + 2013 Kenneth MacKay + 2014 Emergya (Cloud4all, FP7/2007-2013 grant agreement n° 289016) + License: BSD-2-clause + +License: Expat + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +License: BSD-2-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + . + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the author nor the names of any contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License: ISC + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + . + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +License: FSFUL + This configure script is free software; the Free Software Foundation + gives unlimited permission to copy, distribute and modify it. + +License: FSFULLR + This file is free software; the Free Software Foundation gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + +License: CC-BY-SA-3.0 + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL + SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT + RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" + BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION + PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. + . + License + . + THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE + COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY + COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS + AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + . + BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO + BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE + CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED + HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. + . + 1. Definitions + "Adaptation" means a work based upon the Work, or upon the Work and + other pre-existing works, such as a translation, adaptation, derivative + work, arrangement of music or other alterations of a literary or + artistic work, or phonogram or performance and includes cinematographic + adaptations or any other form in which the Work may be recast, + transformed, or adapted including in any form recognizably derived from + the original, except that a work that constitutes a Collection will not + be considered an Adaptation for the purpose of this License. For the + avoidance of doubt, where the Work is a musical work, performance or + phonogram, the synchronization of the Work in timed-relation with a + moving image ("synching") will be considered an Adaptation for the + purpose of this License. + "Collection" means a collection of literary or artistic works, such as + encyclopedias and anthologies, or performances, phonograms or + broadcasts, or other works or subject matter other than works listed in + Section 1(f) below, which, by reason of the selection and arrangement of + their contents, constitute intellectual creations, in which the Work is + included in its entirety in unmodified form along with one or more other + contributions, each constituting separate and independent works in + themselves, which together are assembled into a collective whole. A work + that constitutes a Collection will not be considered an Adaptation (as + defined below) for the purposes of this License. + "Creative Commons Compatible License" means a license that is listed at + http://creativecommons.org/compatiblelicenses that has been approved by + Creative Commons as being essentially equivalent to this License, + including, at a minimum, because that license: (i) contains terms that + have the same purpose, meaning and effect as the License Elements of + this License; and, (ii) explicitly permits the relicensing of + adaptations of works made available under that license under this + License or a Creative Commons jurisdiction license with the same License + Elements as this License. + "Distribute" means to make available to the public the original and + copies of the Work or Adaptation, as appropriate, through sale or other + transfer of ownership. + "License Elements" means the following high-level license attributes as + selected by Licensor and indicated in the title of this License: + Attribution, ShareAlike. + "Licensor" means the individual, individuals, entity or entities that + offer(s) the Work under the terms of this License. + "Original Author" means, in the case of a literary or artistic work, the + individual, individuals, entity or entities who created the Work or if + no individual or entity can be identified, the publisher; and in + addition (i) in the case of a performance the actors, singers, + musicians, dancers, and other persons who act, sing, deliver, declaim, + play in, interpret or otherwise perform literary or artistic works or + expressions of folklore; (ii) in the case of a phonogram the producer + being the person or legal entity who first fixes the sounds of a + performance or other sounds; and, (iii) in the case of broadcasts, the + organization that transmits the broadcast. + "Work" means the literary and/or artistic work offered under the terms + of this License including without limitation any production in the + literary, scientific and artistic domain, whatever may be the mode or + form of its expression including digital form, such as a book, pamphlet + and other writing; a lecture, address, sermon or other work of the same + nature; a dramatic or dramatico-musical work; a choreographic work or + entertainment in dumb show; a musical composition with or without words; + a cinematographic work to which are assimilated works expressed by a + process analogous to cinematography; a work of drawing, painting, + architecture, sculpture, engraving or lithography; a photographic work + to which are assimilated works expressed by a process analogous to + photography; a work of applied art; an illustration, map, plan, sketch + or three-dimensional work relative to geography, topography, + architecture or science; a performance; a broadcast; a phonogram; a + compilation of data to the extent it is protected as a copyrightable + work; or a work performed by a variety or circus performer to the extent + it is not otherwise considered a literary or artistic work. + "You" means an individual or entity exercising rights under this License + who has not previously violated the terms of this License with respect + to the Work, or who has received express permission from the Licensor to + exercise rights under this License despite a previous violation. + "Publicly Perform" means to perform public recitations of the Work and + to communicate to the public those public recitations, by any means or + process, including by wire or wireless means or public digital + performances; to make available to the public Works in such a way that + members of the public may access these Works from a place and at a place + individually chosen by them; to perform the Work to the public by any + means or process and the communication to the public of the performances + of the Work, including by public digital performance; to broadcast and + rebroadcast the Work by any means including signs, sounds or images. + "Reproduce" means to make copies of the Work by any means including + without limitation by sound or visual recordings and the right of + fixation and reproducing fixations of the Work, including storage of a + protected performance or phonogram in digital form or other electronic + medium. + . + 2. Fair Dealing Rights. Nothing in this License is intended to reduce, + limit, or restrict any uses free from copyright or rights arising from + limitations or exceptions that are provided for in connection with the + copyright protection under copyright law or other applicable laws. + . + 3. License Grant. Subject to the terms and conditions of this License, + Licensor hereby grants You a worldwide, royalty-free, non-exclusive, + perpetual (for the duration of the applicable copyright) license to + exercise the rights in the Work as stated below: + . + to Reproduce the Work, to incorporate the Work into one or more + Collections, and to Reproduce the Work as incorporated in the + Collections; + to create and Reproduce Adaptations provided that any such Adaptation, + including any translation in any medium, takes reasonable steps to + clearly label, demarcate or otherwise identify that changes were made to + the original Work. For example, a translation could be marked "The + original work was translated from English to Spanish," or a modification + could indicate "The original work has been modified."; + to Distribute and Publicly Perform the Work including as incorporated in + Collections; and, + to Distribute and Publicly Perform Adaptations. + . + For the avoidance of doubt: + Non-waivable Compulsory License Schemes. In those jurisdictions in + which the right to collect royalties through any statutory or + compulsory licensing scheme cannot be waived, the Licensor reserves + the exclusive right to collect such royalties for any exercise by + You of the rights granted under this License; + Waivable Compulsory License Schemes. In those jurisdictions in which + the right to collect royalties through any statutory or compulsory + licensing scheme can be waived, the Licensor waives the exclusive + right to collect such royalties for any exercise by You of the + rights granted under this License; and, + Voluntary License Schemes. The Licensor waives the right to collect + royalties, whether individually or, in the event that the Licensor + is a member of a collecting society that administers voluntary + licensing schemes, via that society, from any exercise by You of the + rights granted under this License. + . + The above rights may be exercised in all media and formats whether now + known or hereafter devised. The above rights include the right to make such + modifications as are technically necessary to exercise the rights in other + media and formats. Subject to Section 8(f), all rights not expressly + granted by Licensor are hereby reserved. + . + 4. Restrictions. The license granted in Section 3 above is expressly made + subject to and limited by the following restrictions: + . + You may Distribute or Publicly Perform the Work only under the terms of + this License. You must include a copy of, or the Uniform Resource + Identifier (URI) for, this License with every copy of the Work You + Distribute or Publicly Perform. You may not offer or impose any terms on + the Work that restrict the terms of this License or the ability of the + recipient of the Work to exercise the rights granted to that recipient + under the terms of the License. You may not sublicense the Work. You + must keep intact all notices that refer to this License and to the + disclaimer of warranties with every copy of the Work You Distribute or + Publicly Perform. When You Distribute or Publicly Perform the Work, You + may not impose any effective technological measures on the Work that + restrict the ability of a recipient of the Work from You to exercise the + rights granted to that recipient under the terms of the License. This + Section 4(a) applies to the Work as incorporated in a Collection, but + this does not require the Collection apart from the Work itself to be + made subject to the terms of this License. If You create a Collection, + upon notice from any Licensor You must, to the extent practicable, + remove from the Collection any credit as required by Section 4(c), as + requested. If You create an Adaptation, upon notice from any Licensor + You must, to the extent practicable, remove from the Adaptation any + credit as required by Section 4(c), as requested. + You may Distribute or Publicly Perform an Adaptation only under the + terms of: (i) this License; (ii) a later version of this License with + the same License Elements as this License; (iii) a Creative Commons + jurisdiction license (either this or a later license version) that + contains the same License Elements as this License (e.g., + Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible + License. If you license the Adaptation under one of the licenses + mentioned in (iv), you must comply with the terms of that license. If + you license the Adaptation under the terms of any of the licenses + mentioned in (i), (ii) or (iii) (the "Applicable License"), you must + comply with the terms of the Applicable License generally and the + following provisions: (I) You must include a copy of, or the URI for, + the Applicable License with every copy of each Adaptation You Distribute + or Publicly Perform; (II) You may not offer or impose any terms on the + Adaptation that restrict the terms of the Applicable License or the + ability of the recipient of the Adaptation to exercise the rights + granted to that recipient under the terms of the Applicable License; + (III) You must keep intact all notices that refer to the Applicable + License and to the disclaimer of warranties with every copy of the Work + as included in the Adaptation You Distribute or Publicly Perform; (IV) + when You Distribute or Publicly Perform the Adaptation, You may not + impose any effective technological measures on the Adaptation that + restrict the ability of a recipient of the Adaptation from You to + exercise the rights granted to that recipient under the terms of the + Applicable License. This Section 4(b) applies to the Adaptation as + incorporated in a Collection, but this does not require the Collection + apart from the Adaptation itself to be made subject to the terms of the + Applicable License. + If You Distribute, or Publicly Perform the Work or any Adaptations or + Collections, You must, unless a request has been made pursuant to + Section 4(a), keep intact all copyright notices for the Work and + provide, reasonable to the medium or means You are utilizing: (i) the + name of the Original Author (or pseudonym, if applicable) if supplied, + and/or if the Original Author and/or Licensor designate another party or + parties (e.g., a sponsor institute, publishing entity, journal) for + attribution ("Attribution Parties") in Licensor's copyright notice, + terms of service or by other reasonable means, the name of such party or + parties; (ii) the title of the Work if supplied; (iii) to the extent + reasonably practicable, the URI, if any, that Licensor specifies to be + associated with the Work, unless such URI does not refer to the + copyright notice or licensing information for the Work; and (iv) , + consistent with Ssection 3(b), in the case of an Adaptation, a credit + identifying the use of the Work in the Adaptation (e.g., "French + translation of the Work by Original Author," or "Screenplay based on + original Work by Original Author"). The credit required by this Section + 4(c) may be implemented in any reasonable manner; provided, however, + that in the case of a Adaptation or Collection, at a minimum such credit + will appear, if a credit for all contributing authors of the Adaptation + or Collection appears, then as part of these credits and in a manner at + least as prominent as the credits for the other contributing authors. + For the avoidance of doubt, You may only use the credit required by this + Section for the purpose of attribution in the manner set out above and, + by exercising Your rights under this License, You may not implicitly or + explicitly assert or imply any connection with, sponsorship or + endorsement by the Original Author, Licensor and/or Attribution Parties, + as appropriate, of You or Your use of the Work, without the separate, + express prior written permission of the Original Author, Licensor and/or + Attribution Parties. + Except as otherwise agreed in writing by the Licensor or as may be + otherwise permitted by applicable law, if You Reproduce, Distribute or + Publicly Perform the Work either by itself or as part of any Adaptations + or Collections, You must not distort, mutilate, modify or take other + derogatory action in relation to the Work which would be prejudicial to + the Original Author's honor or reputation. Licensor agrees that in those + jurisdictions (e.g. Japan), in which any exercise of the right granted + in Section 3(b) of this License (the right to make Adaptations) would be + deemed to be a distortion, mutilation, modification or other derogatory + action prejudicial to the Original Author's honor and reputation, the + Licensor will waive or not assert, as appropriate, this Section, to the + fullest extent permitted by the applicable national law, to enable You + to reasonably exercise Your right under Section 3(b) of this License + (right to make Adaptations) but not otherwise. + . + 5. Representations, Warranties and Disclaimer + . + UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR + OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY + KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, + INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, + FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT + OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER + OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF + IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. + . + 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE + LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY + SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING + OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + . + 7. Termination + . + This License and the rights granted hereunder will terminate + automatically upon any breach by You of the terms of this License. + Individuals or entities who have received Adaptations or Collections + from You under this License, however, will not have their licenses + terminated provided such individuals or entities remain in full + compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will + survive any termination of this License. + Subject to the above terms and conditions, the license granted here is + perpetual (for the duration of the applicable copyright in the Work). + Notwithstanding the above, Licensor reserves the right to release the + Work under different license terms or to stop distributing the Work at + any time; provided, however that any such election will not serve to + withdraw this License (or any other license that has been, or is + required to be, granted under the terms of this License), and this + License will continue in full force and effect unless terminated as + stated above. + . + 8. Miscellaneous + . + Each time You Distribute or Publicly Perform the Work or a Collection, + the Licensor offers to the recipient a license to the Work on the same + terms and conditions as the license granted to You under this License. + Each time You Distribute or Publicly Perform an Adaptation, Licensor + offers to the recipient a license to the original Work on the same terms + and conditions as the license granted to You under this License. + If any provision of this License is invalid or unenforceable under + applicable law, it shall not affect the validity or enforceability of + the remainder of the terms of this License, and without further action + by the parties to this agreement, such provision shall be reformed to + the minimum extent necessary to make such provision valid and + enforceable. + No term or provision of this License shall be deemed waived and no + breach consented to unless such waiver or consent shall be in writing + and signed by the party to be charged with such waiver or consent. + This License constitutes the entire agreement between the parties with + respect to the Work licensed here. There are no understandings, + agreements or representations with respect to the Work not specified + here. Licensor shall not be bound by any additional provisions that may + appear in any communication from You. This License may not be modified + without the mutual written agreement of the Licensor and You. + The rights granted under, and the subject matter referenced, in this + License were drafted utilizing the terminology of the Berne Convention + for the Protection of Literary and Artistic Works (as amended on + September 28, 1979), the Rome Convention of 1961, the WIPO Copyright + Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and + the Universal Copyright Convention (as revised on July 24, 1971). These + rights and subject matter take effect in the relevant jurisdiction in + which the License terms are sought to be enforced according to the + corresponding provisions of the implementation of those treaty + provisions in the applicable national law. If the standard suite of + rights granted under applicable copyright law includes additional rights + not granted under this License, such additional rights are deemed to be + included in the License; this License is not intended to restrict the + license of any rights under applicable law. + +License: Apache-2.0 + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + . + http://www.apache.org/licenses/LICENSE-2.0 + . + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + . + On Debian systems, the complete text of the Apache version 2.0 license + can be found in "/usr/share/common-licenses/Apache-2.0". + +License: GPL-2+ + This package 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 2 of the License, or + (at your option) any later version. + . + This package 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 this program. If not, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". + +License: GPL-3+ + This program 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. + . + This package 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 this program. If not, see . + . + On Debian systems, the complete text of the GNU General + Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". + +License: Zlib + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + . + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + . + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +License: U-OF-I-BSD-LIKE + ============================================================================== + LLVM Release License + ============================================================================== + University of Illinois/NCSA + Open Source License + . + Copyright (c) 2003-2017 University of Illinois at Urbana-Champaign. + All rights reserved. + . + Developed by: + . + LLVM Team + . + University of Illinois at Urbana-Champaign + . + http://llvm.org + . + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal with + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + . + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + . + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + . + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE + SOFTWARE. diff --git a/embedded/6.0 b/embedded/6.0 new file mode 120000 index 0000000..945c9b4 --- /dev/null +++ b/embedded/6.0 @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/embedded/6.0.0 b/embedded/6.0.0 new file mode 120000 index 0000000..945c9b4 --- /dev/null +++ b/embedded/6.0.0 @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/embedded/93b6d6de857dc88e665d2c64397852ab9701ba24 b/embedded/93b6d6de857dc88e665d2c64397852ab9701ba24 new file mode 100644 index 0000000..9a1a272 Binary files /dev/null and b/embedded/93b6d6de857dc88e665d2c64397852ab9701ba24 differ diff --git a/embedded/DocStringExtensions b/embedded/DocStringExtensions new file mode 120000 index 0000000..3e4c57c --- /dev/null +++ b/embedded/DocStringExtensions @@ -0,0 +1 @@ +DocStringExtensions.jl-0.5.0 \ No newline at end of file diff --git a/embedded/DocStringExtensions.jl-0.5.0/.codecov.yml b/embedded/DocStringExtensions.jl-0.5.0/.codecov.yml new file mode 100644 index 0000000..69cb760 --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/.codecov.yml @@ -0,0 +1 @@ +comment: false diff --git a/embedded/DocStringExtensions.jl-0.5.0/.travis.yml b/embedded/DocStringExtensions.jl-0.5.0/.travis.yml new file mode 100644 index 0000000..c95f675 --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/.travis.yml @@ -0,0 +1,28 @@ +language: julia + +os: + - linux + - osx + +sudo: false + +julia: + - 0.7 + - 1.0 + - nightly + +notifications: + email: false + +after_success: + - julia test/coverage.jl + +jobs: + include: + - stage: "Deploy docs" + julia: 1.0 + os: linux + script: + - julia -e 'using Pkg; Pkg.add([PackageSpec("Documenter"), PackageSpec(path=pwd())])' + - julia docs/make.jl + after_success: skip diff --git a/embedded/DocStringExtensions.jl-0.5.0/LICENSE.md b/embedded/DocStringExtensions.jl-0.5.0/LICENSE.md new file mode 100644 index 0000000..14fb2fa --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/LICENSE.md @@ -0,0 +1,22 @@ +The DocStringExtensions.jl package is licensed under the MIT "Expat" License: + +> Copyright (c) 2016: Michael Hatherly. +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in all +> copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +> SOFTWARE. +> diff --git a/embedded/DocStringExtensions.jl-0.5.0/README.md b/embedded/DocStringExtensions.jl-0.5.0/README.md new file mode 100644 index 0000000..658e7ab --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/README.md @@ -0,0 +1,49 @@ +# DocStringExtensions + +*Extensions for Julia's docsystem.* + +| **Documentation** | **Build Status** | +|:-------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------:| +| [![][docs-stable-img]][docs-stable-url] [![][docs-latest-img]][docs-latest-url] | [![][travis-img]][travis-url] [![][appveyor-img]][appveyor-url] [![][codecov-img]][codecov-url] | + +## Installation + +The package can be added using the Julia package manager. From the Julia REPL, type `]` +to enter the Pkg REPL mode and run + +``` +pkg> add DocStringExtensions +``` + +## Documentation + +- [**STABLE**][docs-stable-url] — **most recently tagged version of the documentation.** +- [**LATEST**][docs-latest-url] — *in-development version of the documentation.* + +## Project Status + +The package is tested and developed against Julia `0.7` and `1.0` on Linux, OS X, and Windows, +but there are versions of the package that works on older versions of Julia. + +## Contributing and Questions + +Contributions are very welcome, as are feature requests and suggestions. Please open an [issue][issues-url] if you encounter any problems. If you have a question then feel free to ask for help in the [Gitter chat room][gitter-url]. + +[gitter-url]: https://gitter.im/juliadocs/users + +[docs-latest-img]: https://img.shields.io/badge/docs-latest-blue.svg +[docs-latest-url]: https://juliadocs.github.io/DocStringExtensions.jl/latest + +[docs-stable-img]: https://img.shields.io/badge/docs-stable-blue.svg +[docs-stable-url]: https://juliadocs.github.io/DocStringExtensions.jl/stable + +[travis-img]: https://travis-ci.org/JuliaDocs/DocStringExtensions.jl.svg?branch=master +[travis-url]: https://travis-ci.org/JuliaDocs/DocStringExtensions.jl + +[appveyor-img]: https://ci.appveyor.com/api/projects/status/7bixd69chxps91wx/branch/master?svg=true +[appveyor-url]: https://ci.appveyor.com/project/JuliaDocs/docstringextensions-jl/branch/master + +[codecov-img]: https://codecov.io/gh/JuliaDocs/DocStringExtensions.jl/branch/master/graph/badge.svg +[codecov-url]: https://codecov.io/gh/JuliaDocs/DocStringExtensions.jl + +[issues-url]: https://github.com/JuliaDocs/DocStringExtensions.jl/issues diff --git a/embedded/DocStringExtensions.jl-0.5.0/REQUIRE b/embedded/DocStringExtensions.jl-0.5.0/REQUIRE new file mode 100644 index 0000000..859ad46 --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/REQUIRE @@ -0,0 +1 @@ +julia 0.7 diff --git a/embedded/DocStringExtensions.jl-0.5.0/appveyor.yml b/embedded/DocStringExtensions.jl-0.5.0/appveyor.yml new file mode 100644 index 0000000..c2588f1 --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/appveyor.yml @@ -0,0 +1,43 @@ +environment: + matrix: + - julia_version: 0.7 + - julia_version: 1 + - julia_version: nightly + +platform: + - x86 # 32-bit + - x64 # 64-bit + +# # Uncomment the following lines to allow failures on nightly julia +# # (tests will run but not make your overall status red) +# matrix: +# allow_failures: +# - julia_version: nightly + +branches: + only: + - master + - /release-.*/ + +notifications: + - provider: Email + on_build_success: false + on_build_failure: false + on_build_status_changed: false + +install: + - ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1")) + +build_script: + - echo "%JL_BUILD_SCRIPT%" + - C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%" + +test_script: + - echo "%JL_TEST_SCRIPT%" + - C:\julia\bin\julia -e "%JL_TEST_SCRIPT%" + +# # Uncomment to support code coverage upload. Should only be enabled for packages +# # which would have coverage gaps without running on Windows +# on_success: +# - echo "%JL_CODECOV_SCRIPT%" +# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%" diff --git a/embedded/DocStringExtensions.jl-0.5.0/docs/make.jl b/embedded/DocStringExtensions.jl-0.5.0/docs/make.jl new file mode 100644 index 0000000..41bc078 --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/docs/make.jl @@ -0,0 +1,18 @@ +using Documenter, DocStringExtensions + +makedocs( + sitename = "DocStringExtensions.jl", + modules = [DocStringExtensions], + format = :html, + clean = false, + pages = Any["Home" => "index.md"], +) + +deploydocs( + target = "build", + deps = nothing, + make = nothing, + repo = "github.com/JuliaDocs/DocStringExtensions.jl.git", + julia = "1.0", +) + diff --git a/embedded/DocStringExtensions.jl-0.5.0/docs/src/assets/logo.png b/embedded/DocStringExtensions.jl-0.5.0/docs/src/assets/logo.png new file mode 100644 index 0000000..3c0c8a1 Binary files /dev/null and b/embedded/DocStringExtensions.jl-0.5.0/docs/src/assets/logo.png differ diff --git a/embedded/DocStringExtensions.jl-0.5.0/docs/src/index.md b/embedded/DocStringExtensions.jl-0.5.0/docs/src/index.md new file mode 100644 index 0000000..b87fdce --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/docs/src/index.md @@ -0,0 +1,19 @@ +# DocStringExtensions + +```@docs +DocStringExtensions +``` + +## Index + +```@index +Modules = [DocStringExtensions] +``` + +## Reference + +```@autodocs +Modules = [DocStringExtensions] +Order = [:constant, :function, :macro, :type] +``` + diff --git a/embedded/DocStringExtensions.jl-0.5.0/src/DocStringExtensions.jl b/embedded/DocStringExtensions.jl-0.5.0/src/DocStringExtensions.jl new file mode 100644 index 0000000..9cc96d7 --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/src/DocStringExtensions.jl @@ -0,0 +1,110 @@ +__precompile__(true) + +""" +*Extensions for the Julia docsystem.* + +# Introduction + +This package provides a collection of useful extensions for Julia's built-in docsystem. +These are features that are still regarded as "experimental" and not yet mature enough to be +considered for inclusion in `Base`, or that have sufficiently niche use cases that including +them with the default Julia installation is not seen as valuable enough at this time. + +Currently `DocStringExtensions.jl` exports a collection of so-called "abbreviations", which +can be used to add useful automatically generated information to docstrings. These include +information such as: + + * simplified method signatures; + * documentation for the individual fields of composite types; + * import and export lists for modules; + * and source-linked lists of methods applicable to a particular docstring. + +Users are most welcome to suggest additional abbreviation ideas, or implement and submit +them themselves. Julia's strong support for program introspection makes this a reasonably +straight forward process. + +Details of the currently available abbreviations can be viewed in their individual +docstrings listed below in the "Exports" section. + +# Examples + +In simple terms an abbreviation can be used by simply interpolating it into a suitable +docstring. For example: + +```julia +using DocStringExtensions + +\""" +A short summary of `func`... + +\$(SIGNATURES) + +where `x` and `y` should both be positive. + +# Details + +Some details about `func`... +\""" +func(x, y) = x + y +``` + +`\$(SIGNATURES)` will be replaced in the above docstring with + +````markdown +# Signatures + +```julia +func(x, y) +``` +```` + +The resulting generated content can be viewed via Julia's `?` mode or, if `Documenter.jl` is +set up, the generated external documentation. + +The advantage of using [`SIGNATURES`](@ref) (and other abbreviations) is that docstrings are +less likely to become out-of-sync with the surrounding code. Note though that references to +the argument names `x` and `y` that have been manually embedded within the docstring are, of +course, not updated automatically. + +# Exports +$(EXPORTS) + +# Imports +$(IMPORTS) + +""" +module DocStringExtensions + +# Exports. + +export @template, FIELDS, EXPORTS, METHODLIST, IMPORTS, SIGNATURES, TYPEDEF, DOCSTRING, FUNCTIONNAME + +# Includes. + +include("utilities.jl") +include("abbreviations.jl") +include("templates.jl") + +# +# Bootstrap abbreviations. +# +# Within the package itself we would like to be able to use the abbreviations that have been +# implemented. To do this we need to delay evaluation of the interpolated abbreviations +# until they have all been defined. We use `Symbol`s in place of the actual constants, such +# as `METHODLIST` which is written as `:METHODLIST` instead. +# +# The docstring for the module itself, defined at the start of the file, does not need to +# use `Symbol`s since with the way `@doc` works the module docstring gets inserted at the +# end of the module definition and so has all the definitions already defined. +# +let λ = s -> isa(s, Symbol) ? getfield(DocStringExtensions, s) : s + for (binding, multidoc) in Docs.meta(DocStringExtensions) + for (typesig, docstr) in multidoc.docs + docstr.text = Core.svec(map(λ, docstr.text)...) + end + end +end + +__init__() = (hook!(template_hook); nothing) + +end # module diff --git a/embedded/DocStringExtensions.jl-0.5.0/src/abbreviations.jl b/embedded/DocStringExtensions.jl-0.5.0/src/abbreviations.jl new file mode 100644 index 0000000..b669aa6 --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/src/abbreviations.jl @@ -0,0 +1,467 @@ + +# +# Abstract Interface. +# + +""" +Abbreviation objects are used to automatically generate context-dependent markdown content +within documentation strings. Objects of this type interpolated into docstrings will be +expanded automatically before parsing the text to markdown. + +$(:FIELDS) +""" +abstract type Abbreviation end + +""" +$(:SIGNATURES) + +Expand the [`Abbreviation`](@ref) `abbr` in the context of the `DocStr` `doc` and write +the resulting markdown-formatted text to the `IOBuffer` `buf`. +""" +format(abbr, buf, doc) = error("`format` not implemented for `$typeof(abbr)`.") + +# Only extend `formatdoc` once with our abstract type. Within the package use a different +# `format` function instead to keep things decoupled from `Base` as much as possible. +Docs.formatdoc(buf::IOBuffer, doc::Docs.DocStr, part::Abbreviation) = format(part, buf, doc) + + +# +# Implementations. +# + + +# +# `TypeFields` +# + +""" +The singleton type for [`FIELDS`](@ref) abbreviations. + +$(:FIELDS) +""" +struct TypeFields <: Abbreviation end + +""" +An [`Abbreviation`](@ref) to include the names of the fields of a type as well as any +documentation that may be attached to the fields. + +# Examples + +The generated markdown text should look similar to to following example where a +type has three fields (`x`, `y`, and `z`) and the last two have documentation +attached. + +```markdown + + - `x` + + - `y` + + Unlike the `x` field this field has been documented. + + - `z` + + Another documented field. +``` +""" +const FIELDS = TypeFields() + +function format(::TypeFields, buf, doc) + local docs = get(doc.data, :fields, Dict()) + local binding = doc.data[:binding] + local object = Docs.resolve(binding) + # On 0.7 fieldnames() on an abstract type throws an error. We then explicitly return + # an empty vector to be consistent with the behaviour on v0.6. + local fields = isabstracttype(object) ? Symbol[] : fieldnames(object) + if !isempty(fields) + println(buf) + for field in fields + print(buf, " - `", field, "`\n") + # Print the field docs if they exist and aren't a `doc"..."` docstring. + if haskey(docs, field) && isa(docs[field], AbstractString) + println(buf) + for line in split(docs[field], "\n") + println(buf, isempty(line) ? "" : " ", rstrip(line)) + end + end + println(buf) + end + println(buf) + end + return nothing +end + + +# +# `ModuleExports` +# + +""" +The singleton type for [`EXPORTS`](@ref) abbreviations. + +$(:FIELDS) +""" +struct ModuleExports <: Abbreviation end + +""" +An [`Abbreviation`](@ref) to include all the exported names of a module is a sorted list of +`Documenter.jl`-style `@ref` links. + +!!! note + + The names are sorted alphabetically and ignore leading `@` characters so that macros are + *not* sorted before other names. + +# Examples + +The markdown text generated by the `EXPORTS` abbreviation looks similar to the following: + +```markdown + + - [`bar`](@ref) + - [`@baz`](@ref) + - [`foo`](@ref) + +``` +""" +const EXPORTS = ModuleExports() + +function format(::ModuleExports, buf, doc) + local binding = doc.data[:binding] + local object = Docs.resolve(binding) + local exports = names(object) + if !isempty(exports) + println(buf) + # Sorting ignores the `@` in macro names and sorts them in with others. + for sym in sort(exports, by = s -> lstrip(string(s), '@')) + # Skip the module itself, since that's always exported. + sym === nameof(object) && continue + # We print linked names using Documenter.jl cross-reference syntax + # for ease of integration with that package. + println(buf, " - [`", sym, "`](@ref)") + end + println(buf) + end + return nothing +end + + +# +# `ModuleImports` +# + +""" +The singleton type for [`IMPORTS`](@ref) abbreviations. + +$(:FIELDS) +""" +struct ModuleImports <: Abbreviation end + +""" +An [`Abbreviation`](@ref) to include all the imported modules in a sorted list. + +# Examples + +The markdown text generated by the `IMPORTS` abbreviation looks similar to the following: + +```markdown + + - `Foo` + - `Bar` + - `Baz` + +``` +""" +const IMPORTS = ModuleImports() + +function format(::ModuleImports, buf, doc) + local binding = doc.data[:binding] + local object = Docs.resolve(binding) + local imports = unique(ccall(:jl_module_usings, Any, (Any,), object)) + if !isempty(imports) + println(buf) + for mod in sort(imports, by = string) + println(buf, " - `", mod, "`") + end + println(buf) + end +end + + +# +# `MethodList` +# + +""" +The singleton type for [`METHODLIST`](@ref) abbreviations. + +$(:FIELDS) +""" +struct MethodList <: Abbreviation end + +""" +An [`Abbreviation`](@ref) for including a list of all the methods that match a documented +`Method`, `Function`, or `DataType` within the current module. + +# Examples + +The generated markdown text will look similar to the following example where a function +`f` defines two different methods (one that takes a number, and the other a string): + +````markdown +```julia +f(num) +``` + +defined at [`:`](). + +```julia +f(str) +``` + +defined at [`:`](). +```` +""" +const METHODLIST = MethodList() + +function format(::MethodList, buf, doc) + local binding = doc.data[:binding] + local typesig = doc.data[:typesig] + local modname = doc.data[:module] + local func = Docs.resolve(binding) + local groups = methodgroups(func, typesig, modname; exact = false) + if !isempty(groups) + println(buf) + for group in groups + println(buf, "```julia") + for method in group + printmethod(buf, binding, func, method) + println(buf) + end + println(buf, "```\n") + if !isempty(group) + local method = group[1] + local file = string(method.file) + local line = method.line + local path = cleanpath(file) + local URL = url(method) + isempty(URL) || println(buf, "defined at [`$path:$line`]($URL).") + end + println(buf) + end + println(buf) + end + return nothing +end + + +# +# `MethodSignatures` +# + +""" +The singleton type for [`SIGNATURES`](@ref) abbreviations. + +$(:FIELDS) +""" +struct MethodSignatures <: Abbreviation end + +""" +An [`Abbreviation`](@ref) for including a simplified representation of all the method +signatures that match the given docstring. See [`printmethod`](@ref) for details on +the simplifications that are applied. + +# Examples + +The generated markdown text will look similar to the following example where a function `f` +defines method taking two positional arguments, `x` and `y`, and two keywords, `a` and the `b`. + +````markdown +```julia +f(x, y; a, b...) +``` +```` +""" +const SIGNATURES = MethodSignatures() + +function format(::MethodSignatures, buf, doc) + local binding = doc.data[:binding] + local typesig = doc.data[:typesig] + local modname = doc.data[:module] + local func = Docs.resolve(binding) + local groups = methodgroups(func, typesig, modname) + if !isempty(groups) + println(buf) + println(buf, "```julia") + for group in groups + for method in group + printmethod(buf, binding, func, method) + println(buf) + end + end + println(buf, "\n```\n") + end +end + +# +# `FunctionName` +# + +""" +The singleton type for [`FUNCTIONNAME`](@ref) abbreviations. + +$(:FIELDS) +""" +struct FunctionName <: Abbreviation end + +""" +An [`Abbreviation`](@ref) for including the function name matching the method of +the docstring. + +# Usage + +This is mostly useful for not repeating the function name in docstrings where +the user wants to retain full control of the argument list, or the latter does +not exist (eg generic functions). + +Note that the generated docstring snippet is not quoted, use indentation or +explicit quoting. + +# Example + +```julia +\""" + \$(FUNCTIONNAME)(d, θ) + +Calculate the logdensity `d` at `θ`. + +Users should define their own methods for `$(FUNCTIONNAME)`. +\""" +function logdensity end +``` +""" +const FUNCTIONNAME = FunctionName() + +format(::FunctionName, buf, doc) = print(buf, doc.data[:binding].var) + +# +# `TypeSignature` +# + +""" +The singleton type for [`TYPEDEF`](@ref) abbreviations. +""" +struct TypeDefinition <: Abbreviation end + +""" +An [`Abbreviation`](@ref) for including a summary of the signature of a type definition. +Some of the following information may be included in the output: + + * whether the object is an `abstract` type or a `bitstype`; + * mutability (either `type` or `struct` is printed); + * the unqualified name of the type; + * any type parameters; + * the supertype of the type if it is not `Any`. + +# Examples + +The generated output for a type definition such as: + +```julia +\""" +\$(TYPEDEF) +\""" +struct MyType{S, T <: Integer} <: AbstractArray + # ... +end +``` + +will look similar to the following: + +````markdown +```julia +struct MyType{S, T<:Integer} <: AbstractArray +``` +```` + +!!! note + + No information about the fields of the type is printed. Use the [`FIELDS`](@ref) + abbreviation to include information about the fields of a type. +""" +const TYPEDEF = TypeDefinition() + +function print_supertype(buf, object) + super = supertype(object) + super != Any && print(buf, " <: ", super) +end + +function print_params(buf, object) + if !isempty(object.parameters) + print(buf, "{") + join(buf, object.parameters, ", ") + print(buf, "}") + end +end + +function print_primitive_type(buf, object) + print(buf, "primitive type ", object.name.name) + print_supertype(buf, object) + print(buf, " ", sizeof(object) * 8) + println(buf) +end + +function print_abstract_type(buf, object) + print(buf, "abstract type ", object.name.name) + print_supertype(buf, object) + println(buf) +end + +function print_mutable_struct_or_struct(buf, object) + object.mutable && print(buf, "mutable ") + print(buf, "struct ", object.name.name) + print_params(buf, object) + print_supertype(buf, object) + println(buf) +end + +@static if VERSION < v"0.7.0" + isprimitivetype(x) = isbitstype(x) +end + +function format(::TypeDefinition, buf, doc) + local binding = doc.data[:binding] + local object = gettype(Docs.resolve(binding)) + if isa(object, DataType) + println(buf, "\n```julia") + if isprimitivetype(object) + print_primitive_type(buf, object) + elseif isabstracttype(object) + print_abstract_type(buf, object) + else + print_mutable_struct_or_struct(buf, object) + end + println(buf, "```\n") + end +end + +# +# `DocStringTemplate` +# + +""" +The singleton type for [`DOCSTRING`](@ref) abbreviations. +""" +struct DocStringTemplate <: Abbreviation end + +""" +An [`Abbreviation`](@ref) used in [`@template`](@ref) definitions to represent the location +of the docstring body that should be spliced into a template. + +!!! warning + + This abbreviation must only ever be used in template strings; never normal docstrings. +""" +const DOCSTRING = DocStringTemplate() + +# NOTE: no `format` needed for this 'mock' abbreviation. diff --git a/embedded/DocStringExtensions.jl-0.5.0/src/templates.jl b/embedded/DocStringExtensions.jl-0.5.0/src/templates.jl new file mode 100644 index 0000000..77bdc7b --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/src/templates.jl @@ -0,0 +1,151 @@ +const expander = Core.atdoc +const setter! = Core.atdoc! + +""" +$(:SIGNATURES) + +Set the docstring expander function to first call `func` before calling the default expander. + +To remove a hook that has been applied using this method call [`hook!()`](@ref). +""" +hook!(func) = setter!((args...) -> expander(func(args...)...)) + +""" +$(:SIGNATURES) + +Reset the docstring expander to only call the default expander function. This clears any +'hook' that has been set using [`hook!(func)`](@ref). +""" +hook!() = setter!(expander) + +""" +$(:SIGNATURES) + +Defines a docstring template that will be applied to all docstrings in a module that match +the specified category or tuple of categories. + +# Examples + +```julia +@template DEFAULT = + \""" + \$(SIGNATURES) + \$(DOCSTRING) + \""" +``` + +`DEFAULT` is the default template that is applied to a docstring if no other template +definitions match the documented expression. The `DOCSTRING` abbreviation is used to mark +the location in the template where the actual docstring body will be spliced into each +docstring. + +```julia +@template (FUNCTIONS, METHODS, MACROS) = + \""" + \$(SIGNATURES) + \$(DOCSTRING) + \$(METHODLIST) + \""" +``` + +A tuple of categories can be specified when a docstring template should be used for several +different categories. + +```julia +@template MODULES = ModName +``` + +The template definition above will define a template for module docstrings based on the +template for modules found in module `ModName`. + +!!! note + + Supported categories are `DEFAULT`, `FUNCTIONS`, `METHODS`, `MACROS`, `TYPES`, + `MODULES`, and `CONSTANTS`. + +""" +macro template(ex) + # JuliaLang/julia#22064 introduced the __module__ variable and deprecated current_module() + @static if VERSION >= v"0.7.0-DEV.484" + template(__source__, __module__, ex) + else + template(LineNumberNode(0), current_module(), ex) + end +end + +const TEMP_SYM = gensym("templates") + +function template(src::LineNumberNode, mod::Module, ex::Expr) + Meta.isexpr(ex, :(=), 2) || error("invalid `@template` syntax.") + template(src, mod, ex.args[1], ex.args[2]) +end + +function template(source::LineNumberNode, mod::Module, tuple::Expr, docstr::Union{Symbol, Expr}) + Meta.isexpr(tuple, :tuple) || error("invalid `@template` syntax on LHS.") + isdefined(mod, TEMP_SYM) || Core.eval(mod, :(const $(TEMP_SYM) = $(Dict{Symbol, Vector}()))) + local block = Expr(:block) + for category in tuple.args + local key = Meta.quot(category) + local vec = Meta.isexpr(docstr, :string) ? + Expr(:vect, docstr.args...) : :($(docstr).$(TEMP_SYM)[$(key)]) + push!(block.args, :($(TEMP_SYM)[$(key)] = $(vec))) + end + push!(block.args, nothing) + return esc(block) +end + +function template(src::LineNumberNode, mod::Module, sym::Symbol, docstr::Union{Symbol, Expr}) + template(src, mod, Expr(:tuple, sym), docstr) +end + +# The signature for the atdocs() calls changed in v0.7 +# On v0.6 and below it seems it was assumed to be (docstr::String, expr::Expr), but on v0.7 +# it is (source::LineNumberNode, mod::Module, docstr::String, expr::Expr) +function template_hook(source::LineNumberNode, mod::Module, docstr, expr::Expr) + local docex = interp_string(docstr) + if isdefined(mod, TEMP_SYM) && Meta.isexpr(docex, :string) + local templates = getfield(mod, TEMP_SYM) + local template = get_template(templates, expression_type(expr)) + local out = Expr(:string) + for t in template + t == DOCSTRING ? append!(out.args, docex.args) : push!(out.args, t) + end + return (source, mod, out, expr) + else + return (source, mod, docstr, expr) + end +end + +function template_hook(docstr, expr::Expr) + source, mod, docstr, expr::Expr = template_hook(LineNumberNode(0), current_module(), docstr, expr) + docstr, expr +end + +template_hook(args...) = args + +interp_string(str::AbstractString) = Expr(:string, str) +interp_string(other) = other + +get_template(t::Dict, k::Symbol) = haskey(t, k) ? t[k] : get(t, :DEFAULT, Any[DOCSTRING]) + +function expression_type(ex::Expr) + # Expression heads changed in JuliaLang/julia/pull/23157 to match the new keyword syntax. + if VERSION < v"0.7.0-DEV.1263" && Meta.isexpr(ex, [:type, :bitstype]) + :TYPES + elseif Meta.isexpr(ex, :module) + :MODULES + elseif Meta.isexpr(ex, [:struct, :abstract, :typealias, :primitive]) + :TYPES + elseif Meta.isexpr(ex, :macro) + :MACROS + elseif Meta.isexpr(ex, [:function, :(=)]) && Meta.isexpr(ex.args[1], :call) || (Meta.isexpr(ex.args[1], :where) && Meta.isexpr(ex.args[1].args[1], :call)) + :METHODS + elseif Meta.isexpr(ex, :function) + :FUNCTIONS + elseif Meta.isexpr(ex, [:const, :(=)]) + :CONSTANTS + else + :DEFAULT + end +end +expression_type(other) = :DEFAULT diff --git a/embedded/DocStringExtensions.jl-0.5.0/src/utilities.jl b/embedded/DocStringExtensions.jl-0.5.0/src/utilities.jl new file mode 100644 index 0000000..947e2a8 --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/src/utilities.jl @@ -0,0 +1,342 @@ + +# +# Utilities. +# + +# +# Method grouping. +# + +""" +$(:SIGNATURES) + +Group all methods of function `func` with type signatures `typesig` in module `modname`. +Keyword argument `exact = true` matches signatures "exactly" with `==` rather than `<:`. + +# Examples + +```julia +groups = methodgroups(f, Union{Tuple{Any}, Tuple{Any, Integer}}, Main; exact = false) +``` +""" +function methodgroups(func, typesig, modname; exact = true) + # Group methods by file and line number. + local methods = getmethods(func, typesig) + local groups = groupby(Tuple{Symbol, Int}, Vector{Method}, methods) do m + (m.file, m.line), m + end + + # Filter out methods from other modules and with non-matching signatures. + local typesigs = alltypesigs(typesig) + local results = Vector{Method}[] + for (key, group) in groups + filter!(group) do m + local ismod = m.module == modname + exact ? (ismod && Base.rewrap_unionall(Base.tuple_type_tail(m.sig), m.sig) in typesigs) : ismod + end + isempty(group) || push!(results, group) + end + + # Sort the groups by file and line. + sort!(results, lt = comparemethods, by = first) + + return results +end + +""" +$(:SIGNATURES) + +Compare methods `a` and `b` by file and line number. +""" +function comparemethods(a::Method, b::Method) + comp = a.file < b.file ? -1 : a.file > b.file ? 1 : 0 + comp == 0 ? a.line < b.line : comp < 0 +end + +if isdefined(Base, :UnionAll) + uniontypes(T) = uniontypes!(Any[], T) + function uniontypes!(out, T) + if isa(T, Union) + push!(out, T.a) + uniontypes!(out, T.b) + else + push!(out, T) + end + return out + end + gettype(T::UnionAll) = gettype(T.body) +else + uniontypes(T) = collect(T.types) +end +gettype(other) = other + +""" +$(:SIGNATURES) + +A helper method for [`getmethods`](@ref) that collects methods in `results`. +""" +function getmethods!(results, f, sig) + if sig == Union{} + append!(results, methods(f)) + elseif isa(sig, Union) + for each in uniontypes(sig) + getmethods!(results, f, each) + end + elseif isa(sig, UnionAll) + getmethods!(results, f, Base.unwrap_unionall(sig)) + else + append!(results, methods(f, sig)) + end + return results +end +""" +$(:SIGNATURES) + +Collect and return all methods of function `f` matching signature `sig`. + +This is similar to `methods(f, sig)`, but handles type signatures found in `DocStr` objects +more consistently that `methods`. +""" +getmethods(f, sig) = unique(getmethods!(Method[], f, sig)) + + +""" +$(:SIGNATURES) + +Is the type `t` a `bitstype`? +""" +isbitstype(@nospecialize(t)) = isconcretetype(t) && sizeof(t) > 0 && isbits(t) + +""" +$(:SIGNATURES) + +Is the type `t` an `abstract` type? +""" +isabstracttype(@nospecialize(t)) = isa(t, DataType) && getfield(t, :abstract) + + +""" +$(:SIGNATURES) + +Returns a `Vector` of the `Tuple` types contained in `sig`. +""" +function alltypesigs(sig)::Vector{Any} + if sig == Union{} + Any[] + elseif isa(sig, Union) + uniontypes(sig) + elseif isa(sig, UnionAll) + Base.rewrap_unionall.(uniontypes(Base.unwrap_unionall(sig)), sig) + else + Any[sig] + end +end + +""" +$(:SIGNATURES) + +A helper method for [`groupby`](@ref) that uses a pre-allocated `groups` `Dict`. +""" +function groupby!(f, groups, data) + for each in data + key, value = f(each) + push!(get!(groups, key, []), value) + end + return sort!(collect(groups), by = first) +end + +""" +$(:SIGNATURES) + +Group `data` using function `f` where key type is specified by `K` and group type by `V`. + +The function `f` takes a single argument, an element of `data`, and should return a 2-tuple +of `(computed_key, element)`. See the example below for details. + +# Examples + +```julia +groupby(Int, Vector{Int}, collect(1:10)) do num + mod(num, 3), num +end +``` +""" +groupby(f, K, V, data) = groupby!(f, Dict{K, V}(), data) + +""" +$(:SIGNATURES) + +Remove the `Pkg.dir` part of a file `path` if it exists. +""" +function cleanpath(path::AbstractString) + for depot in DEPOT_PATH + pkgdir = joinpath(depot, "") + startswith(path, pkgdir) && return first(split(path, pkgdir, keepempty=false)) + end + return path +end + +""" +$(:SIGNATURES) + +Parse all docstrings defined within a module `mod`. +""" +function parsedocs(mod::Module) + for (binding, multidoc) in Docs.meta(mod) + for (typesig, docstr) in multidoc.docs + Docs.parsedoc(docstr) + end + end +end + + +""" +$(:SIGNATURES) + +Print a simplified representation of a method signature to `buffer`. Some of these +simplifications include: + + * no `TypeVar`s; + * no types; + * no keyword default values; + * `?` printed where `#unused#` arguments are found. + +# Examples + +```julia +f(x; a = 1, b...) = x +sig = printmethod(Docs.Binding(Main, :f), f, first(methods(f))) +``` +""" +function printmethod(buffer::IOBuffer, binding::Docs.Binding, func, method::Method) + # TODO: print qualified? + print(buffer, binding.var) + print(buffer, "(") + join(buffer, arguments(method), ", ") + local kws = keywords(func, method) + if !isempty(kws) + print(buffer, "; ") + join(buffer, kws, ", ") + end + print(buffer, ")") + return buffer +end + +printmethod(b, f, m) = String(take!(printmethod(IOBuffer(), b, f, m))) + +get_method_source(m::Method) = Base.uncompressed_ast(m) +nargs(m::Method) = m.nargs + + +""" +$(:SIGNATURES) + +Returns the list of keywords for a particular method `m` of a function `func`. + +# Examples + +```julia +f(x; a = 1, b...) = x +kws = keywords(f, first(methods(f))) +``` +""" +function keywords(func, m::Method) + local table = methods(func).mt + # table is a MethodTable object. For some reason, the :kwsorter field is not always + # defined. An undefined kwsorter seems to imply that there are no methods in the + # MethodTable with keyword arguments. + if isdefined(table, :kwsorter) + # Fetching method keywords stolen from base/replutil.jl:572-576 (commit 3b45cdc9aab0): + local kwargs = Base.kwarg_decl(m, typeof(table.kwsorter)) + if isa(kwargs, Vector) && length(kwargs) > 0 + filter!(arg -> !occursin("#", string(arg)), kwargs) + # Keywords *may* not be sorted correctly. We move the vararg one to the end. + local index = findfirst(arg -> endswith(string(arg), "..."), kwargs) + if index != nothing + kwargs[index], kwargs[end] = kwargs[end], kwargs[index] + end + return kwargs + end + end + return Symbol[] +end + + +""" +$(:SIGNATURES) + +Returns the list of arguments for a particular method `m`. + +# Examples + +```julia +f(x; a = 1, b...) = x +args = arguments(first(methods(f))) +``` +""" +function arguments(m::Method) + local template = get_method_source(m) + if isdefined(template, :slotnames) + local args = map(template.slotnames[1:nargs(m)]) do arg + arg === Symbol("#unused#") ? "?" : arg + end + return filter(arg -> arg !== Symbol("#self#"), args) + end + return Symbol[] +end + +# +# Source URLs. +# +# Based on code from https://github.com/JuliaLang/julia/blob/master/base/methodshow.jl. +# +# Customised to handle URLs on travis since the directory is not a Git repo and we must +# instead rely on `TRAVIS_REPO_SLUG` to get the remote repo. +# + +""" +$(:SIGNATURES) + +Get the URL (file and line number) where a method `m` is defined. + +Note that this is based on the implementation of `Base.url`, but handles URLs correctly +on TravisCI as well. +""" +url(m::Method) = url(m.module, string(m.file), m.line) + +import LibGit2 + +function url(mod::Module, file::AbstractString, line::Integer) + file = Sys.iswindows() ? replace(file, '\\' => '/') : file + if Base.inbase(mod) && !isabspath(file) + local base = "https://github.com/JuliaLang/julia/tree" + if isempty(Base.GIT_VERSION_INFO.commit) + return "$base/v$VERSION/base/$file#L$line" + else + local commit = Base.GIT_VERSION_INFO.commit + return "$base/$commit/base/$file#L$line" + end + else + if isfile(file) + local d = dirname(file) + return LibGit2.with(LibGit2.GitRepoExt(d)) do repo + LibGit2.with(LibGit2.GitConfig(repo)) do cfg + local u = LibGit2.get(cfg, "remote.origin.url", "") + local m = match(LibGit2.GITHUB_REGEX, u) + u = m === nothing ? get(ENV, "TRAVIS_REPO_SLUG", "") : m.captures[1] + local commit = string(LibGit2.head_oid(repo)) + local root = LibGit2.path(repo) + if startswith(file, root) || startswith(realpath(file), root) + local base = "https://github.com/$u/tree" + local filename = file[(length(root) + 1):end] + return "$base/$commit/$filename#L$line" + else + return "" + end + end + end + else + return "" + end + end +end diff --git a/embedded/DocStringExtensions.jl-0.5.0/test/coverage.jl b/embedded/DocStringExtensions.jl-0.5.0/test/coverage.jl new file mode 100644 index 0000000..818ef3a --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/test/coverage.jl @@ -0,0 +1,10 @@ +# Only run coverage from linux nightly build on travis. +get(ENV, "TRAVIS_OS_NAME", "") == "linux" || exit() +get(ENV, "TRAVIS_JULIA_VERSION", "") == "nightly" || exit() +using Pkg +Pkg.add("Coverage") +using Coverage + +cd(joinpath(dirname(@__FILE__), "..")) do + Codecov.submit(Codecov.process_folder()) +end diff --git a/embedded/DocStringExtensions.jl-0.5.0/test/runtests.jl b/embedded/DocStringExtensions.jl-0.5.0/test/runtests.jl new file mode 100644 index 0000000..047a880 --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/test/runtests.jl @@ -0,0 +1,5 @@ +using DocStringExtensions +using Test +import Markdown + +include("tests.jl") diff --git a/embedded/DocStringExtensions.jl-0.5.0/test/templates.jl b/embedded/DocStringExtensions.jl-0.5.0/test/templates.jl new file mode 100644 index 0000000..1e9de96 --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/test/templates.jl @@ -0,0 +1,98 @@ +module TemplateTests + +using DocStringExtensions + +@template DEFAULT = + """ + (DEFAULT) + + $(DOCSTRING) + """ + +@template TYPES = + """ + (TYPES) + + $(TYPEDEF) + + $(DOCSTRING) + """ + +@template (METHODS, MACROS) = + """ + (METHODS, MACROS) + + $(SIGNATURES) + + $(DOCSTRING) + + $(METHODLIST) + """ + +"constant `K`" +const K = 1 + +"mutable struct `T`" +mutable struct T end + +"method `f`" +f(x) = x + +"method `g`" +g(::Type{T}) where {T} = T # Issue 32 + +"macro `@m`" +macro m(x) end + +module InnerModule + + import ..TemplateTests + + using DocStringExtensions + + @template DEFAULT = TemplateTests + + @template METHODS = TemplateTests + + @template MACROS = + """ + (MACROS) + + $(DOCSTRING) + + $(SIGNATURES) + """ + + "constant `K`" + const K = 1 + + "mutable struct `T`" + mutable struct T end + + "method `f`" + f(x) = x + + "macro `@m`" + macro m(x) end +end + +module OtherModule + + import ..TemplateTests + + using DocStringExtensions + + @template TYPES = TemplateTests + @template MACROS = TemplateTests.InnerModule + + "mutable struct `T`" + mutable struct T end + + "macro `@m`" + macro m(x) end + + "method `f`" + f(x) = x +end + +end diff --git a/embedded/DocStringExtensions.jl-0.5.0/test/tests.jl b/embedded/DocStringExtensions.jl-0.5.0/test/tests.jl new file mode 100644 index 0000000..dd93ef7 --- /dev/null +++ b/embedded/DocStringExtensions.jl-0.5.0/test/tests.jl @@ -0,0 +1,415 @@ +const DSE = DocStringExtensions + +include("templates.jl") + +module M + +export f + +f(x) = x + +g(x = 1, y = 2, z = 3; kwargs...) = x + +const A{T} = Union{Vector{T}, Matrix{T}} + +h_1(x::A) = x +h_2(x::A{Int}) = x +h_3(x::A{T}) where {T} = x + +i_1(x; y = x) = x * y +i_2(x::Int; y = x) = x * y +i_3(x::T; y = x) where {T} = x * y +i_4(x; y::T = zero(T), z::U = zero(U)) where {T, U} = x + y + z + +j_1(x, y) = x * y # two arguments, no keyword arguments +j_1(x; y = x) = x * y # one argument, one keyword argument + +mutable struct T + a + b + c +end + +struct K + K(; a = 1) = new() +end + + +abstract type AbstractType <: Integer end + +struct CustomType{S, T <: Integer} <: Integer +end + +primitive type BitType8 8 end + +primitive type BitType32 <: Real 32 end + +end + +@testset "DocStringExtensions" begin + @testset "Base assumptions" begin + # The package heavily relies on type and docsystem-related methods and types from + # Base, which are generally undocumented and their behaviour might change at any + # time. This set of tests is tests and documents the assumptions the package makes + # about them. + # + # The testset is not comprehensive -- i.e. DocStringExtensions makes use of + # undocumented features that are not tested here. Should you come across anything + # like that, please add a test here. + # + + # Getting keyword arguments of a method. + # + # Used in src/utilities.jl for the keywords() function. + # + # The methodology is based on a snippet in Base at base/replutil.jl:572-576 + # (commit 3b45cdc9aab0). It uses the undocumented Base.kwarg_decl() function. + @test isdefined(Base, :kwarg_decl) + # Its signature is kwarg_decl(m::Method, kwtype::DataType). The second argument + # should be the type of the kwsorter from the corresponding MethodTable. + @test isa(methods(M.j_1), Base.MethodList) + @test isdefined(methods(M.j_1), :mt) + local mt = methods(M.j_1).mt + @test isa(mt, Core.MethodTable) + @test isdefined(mt, :kwsorter) + # .kwsorter is not always defined -- namely, it seems when none of the methods + # have keyword arguments: + @test isdefined(methods(M.f).mt, :kwsorter) === false + # M.j_1 has two methods. Fetch the single argument one.. + local m = which(M.j_1, (Any,)) + @test isa(m, Method) + # .. which should have a single keyword argument, :y + # Base.kwarg_decl returns a Vector{Any} of the keyword arguments. + local kwargs = Base.kwarg_decl(m, typeof(mt.kwsorter)) + @test isa(kwargs, Vector{Any}) + @test kwargs == [:y] + # Base.kwarg_decl will return a Tuple{} for some reason when called on a method + # that does not have any arguments + m = which(M.j_1, (Any,Any)) # fetch the no-keyword method + @test Base.kwarg_decl(m, typeof(methods(M.j_1).mt.kwsorter)) == Tuple{}() + end + @testset "format" begin + # Setup. + doc = Docs.DocStr(Core.svec(), nothing, Dict()) + buf = IOBuffer() + + # Errors. + @test_throws ErrorException DSE.format(nothing, buf, doc) + + @testset "imports & exports" begin + # Module imports. + doc.data = Dict( + :binding => Docs.Binding(Main, :M), + :typesig => Union{}, + ) + DSE.format(IMPORTS, buf, doc) + str = String(take!(buf)) + @test occursin("\n - `Base`\n", str) + @test occursin("\n - `Core`\n", str) + + # Module exports. + DSE.format(EXPORTS, buf, doc) + str = String(take!(buf)) + @test occursin("\n - [`f`](@ref)\n", str) + end + + @testset "type fields" begin + doc.data = Dict( + :binding => Docs.Binding(M, :T), + :fields => Dict( + :a => "one", + :b => "two", + ), + ) + DSE.format(FIELDS, buf, doc) + str = String(take!(buf)) + @test occursin(" - `a`", str) + @test occursin(" - `b`", str) + @test occursin(" - `c`", str) + @test occursin("one", str) + @test occursin("two", str) + end + + @testset "method lists" begin + doc.data = Dict( + :binding => Docs.Binding(M, :f), + :typesig => Tuple{Any}, + :module => M, + ) + DSE.format(METHODLIST, buf, doc) + str = String(take!(buf)) + @test occursin("```julia", str) + @test occursin("f(x)", str) + @test occursin(joinpath("test", "tests.jl"), str) + end + + @testset "method signatures" begin + doc.data = Dict( + :binding => Docs.Binding(M, :f), + :typesig => Tuple{Any}, + :module => M, + ) + DSE.format(SIGNATURES, buf, doc) + str = String(take!(buf)) + @test occursin("\n```julia\n", str) + @test occursin("\nf(x)\n", str) + @test occursin("\n```\n", str) + + doc.data = Dict( + :binding => Docs.Binding(M, :g), + :typesig => Union{Tuple{}, Tuple{Any}}, + :module => M, + ) + DSE.format(SIGNATURES, buf, doc) + str = String(take!(buf)) + @test occursin("\n```julia\n", str) + @test occursin("\ng()\n", str) + @test occursin("\ng(x)\n", str) + @test occursin("\n```\n", str) + + doc.data = Dict( + :binding => Docs.Binding(M, :g), + :typesig => Union{Tuple{}, Tuple{Any}, Tuple{Any, Any}, Tuple{Any, Any, Any}}, + :module => M, + ) + DSE.format(SIGNATURES, buf, doc) + str = String(take!(buf)) + @test occursin("\n```julia\n", str) + @test occursin("\ng()\n", str) + @test occursin("\ng(x)\n", str) + @test occursin("\ng(x, y)\n", str) + @test occursin("\ng(x, y, z; kwargs...)\n", str) + @test occursin("\n```\n", str) + end + + @testset "function names" begin + doc.data = Dict( + :binding => Docs.Binding(M, :f), + :typesig => Tuple{Any}, + :module => M, + ) + DSE.format(FUNCTIONNAME, buf, doc) + str = String(take!(buf)) + @test str == "f" + end + + @testset "type definitions" begin + doc.data = Dict( + :binding => Docs.Binding(M, :AbstractType), + :typesig => Union{}, + :module => M, + ) + DSE.format(TYPEDEF, buf, doc) + str = String(take!(buf)) + @test str == "\n```julia\nabstract type AbstractType <: Integer\n```\n\n" + + doc.data = Dict( + :binding => Docs.Binding(M, :CustomType), + :typesig => Union{}, + :module => M, + ) + DSE.format(TYPEDEF, buf, doc) + str = String(take!(buf)) + @test str == "\n```julia\nstruct CustomType{S, T<:Integer} <: Integer\n```\n\n" + + doc.data = Dict( + :binding => Docs.Binding(M, :BitType8), + :typesig => Union{}, + :module => M, + ) + DSE.format(TYPEDEF, buf, doc) + str = String(take!(buf)) + @test str == "\n```julia\nprimitive type BitType8 8\n```\n\n" + + doc.data = Dict( + :binding => Docs.Binding(M, :BitType32), + :typesig => Union{}, + :module => M, + ) + DSE.format(TYPEDEF, buf, doc) + str = String(take!(buf)) + @test str == "\n```julia\nprimitive type BitType32 <: Real 32\n```\n\n" + end + end + @testset "templates" begin + let fmt = expr -> Markdown.plain(eval(:(@doc $expr))) + @test occursin("(DEFAULT)", fmt(:(TemplateTests.K))) + @test occursin("(TYPES)", fmt(:(TemplateTests.T))) + @test occursin("(METHODS, MACROS)", fmt(:(TemplateTests.f))) + @test occursin("(METHODS, MACROS)", fmt(:(TemplateTests.g))) + @test occursin("(METHODS, MACROS)", fmt(:(TemplateTests.@m))) + + @test occursin("(DEFAULT)", fmt(:(TemplateTests.InnerModule.K))) + @test occursin("(DEFAULT)", fmt(:(TemplateTests.InnerModule.T))) + @test occursin("(METHODS, MACROS)", fmt(:(TemplateTests.InnerModule.f))) + @test occursin("(MACROS)", fmt(:(TemplateTests.InnerModule.@m))) + + @test occursin("(TYPES)", fmt(:(TemplateTests.OtherModule.T))) + @test occursin("(MACROS)", fmt(:(TemplateTests.OtherModule.@m))) + @test fmt(:(TemplateTests.OtherModule.f)) == "method `f`\n" + end + end + @testset "utilities" begin + @testset "keywords" begin + @test DSE.keywords(M.T, first(methods(M.T))) == Symbol[] + @test DSE.keywords(M.K, first(methods(M.K))) == [:a] + @test DSE.keywords(M.f, first(methods(M.f))) == Symbol[] + let f = (() -> ()), + m = first(methods(f)) + @test DSE.keywords(f, m) == Symbol[] + end + let f = ((a) -> ()), + m = first(methods(f)) + @test DSE.keywords(f, m) == Symbol[] + end + let f = ((; a = 1) -> ()), + m = first(methods(f)) + @test DSE.keywords(f, m) == [:a] + end + let f = ((; a = 1, b = 2) -> ()), + m = first(methods(f)) + @test DSE.keywords(f, m) == [:a, :b] + end + let f = ((; a...) -> ()), + m = first(methods(f)) + @test DSE.keywords(f, m) == [Symbol("a...")] + end + # Tests for #42 + let f = M.i_1, m = first(methods(f)) + @test DSE.keywords(f, m) == [:y] + end + let f = M.i_2, m = first(methods(f)) + @test DSE.keywords(f, m) == [:y] + end + let f = M.i_3, m = first(methods(f)) + @test DSE.keywords(f, m) == [:y] + end + let f = M.i_4, m = first(methods(f)) + @test DSE.keywords(f, m) == [:y, :z] + end + end + @testset "arguments" begin + @test DSE.arguments(first(methods(M.T))) == [:a, :b, :c] + @test DSE.arguments(first(methods(M.K))) == Symbol[] + @test DSE.arguments(first(methods(M.f))) == [:x] + let m = first(methods(() -> ())) + @test DSE.arguments(m) == Symbol[] + end + let m = first(methods((a) -> ())) + @test DSE.arguments(m) == [:a] + end + let m = first(methods((; a = 1) -> ())) + @test DSE.arguments(m) == Symbol[] + end + let m = first(methods((x; a = 1, b = 2) -> ())) + @test DSE.arguments(m) == Symbol[:x] + end + let m = first(methods((; a...) -> ())) + @test DSE.arguments(m) == Symbol[] + end + end + @testset "printmethod" begin + let b = Docs.Binding(M, :T), + f = M.T, + m = first(methods(f)) + @test DSE.printmethod(b, f, m) == "T(a, b, c)" + end + let b = Docs.Binding(M, :K), + f = M.K, + m = first(methods(f)) + @test DSE.printmethod(b, f, m) == "K(; a)" + end + let b = Docs.Binding(M, :f), + f = M.f, + m = first(methods(f)) + @test DSE.printmethod(b, f, m) == "f(x)" + end + let b = Docs.Binding(Main, :f), + f = () -> (), + m = first(methods(f)) + @test DSE.printmethod(b, f, m) == "f()" + end + let b = Docs.Binding(Main, :f), + f = (a) -> (), + m = first(methods(f)) + @test DSE.printmethod(b, f, m) == "f(a)" + end + let b = Docs.Binding(Main, :f), + f = (; a = 1) -> (), + m = first(methods(f)) + @test DSE.printmethod(b, f, m) == "f(; a)" + end + let b = Docs.Binding(Main, :f), + f = (; a = 1, b = 2) -> (), + m = first(methods(f)) + # Keywords are not ordered, so check for both combinations. + @test DSE.printmethod(b, f, m) in ("f(; a, b)", "f(; b, a)") + end + let b = Docs.Binding(Main, :f), + f = (; a...) -> (), + m = first(methods(f)) + @test DSE.printmethod(b, f, m) == "f(; a...)" + end + let b = Docs.Binding(Main, :f), + f = (; a = 1, b = 2, c...) -> (), + m = first(methods(f)) + # Keywords are not ordered, so check for both combinations. + @test DSE.printmethod(b, f, m) in ("f(; a, b, c...)", "f(; b, a, c...)") + end + end + @testset "getmethods" begin + @test length(DSE.getmethods(M.f, Union{})) == 1 + @test length(DSE.getmethods(M.f, Tuple{})) == 0 + @test length(DSE.getmethods(M.f, Union{Tuple{}, Tuple{Any}})) == 1 + @test length(DSE.getmethods(M.h_3, Tuple{M.A{Int}})) == 1 + @test length(DSE.getmethods(M.h_3, Tuple{Vector{Int}})) == 1 + @test length(DSE.getmethods(M.h_3, Tuple{Array{Int, 3}})) == 0 + end + @testset "methodgroups" begin + @test length(DSE.methodgroups(M.f, Tuple{Any}, M)) == 1 + @test length(DSE.methodgroups(M.f, Tuple{Any}, M)[1]) == 1 + @test length(DSE.methodgroups(M.h_1, Tuple{M.A}, M)) == 1 + @test length(DSE.methodgroups(M.h_1, Tuple{M.A}, M)[1]) == 1 + @test length(DSE.methodgroups(M.h_2, Tuple{M.A{Int}}, M)) == 1 + @test length(DSE.methodgroups(M.h_2, Tuple{M.A{Int}}, M)[1]) == 1 + @test length(DSE.methodgroups(M.h_3, Tuple{M.A}, M)[1]) == 1 + end + @testset "alltypesigs" begin + @test DSE.alltypesigs(Union{}) == Any[] + @test DSE.alltypesigs(Union{Tuple{}}) == Any[Tuple{}] + @test DSE.alltypesigs(Tuple{}) == Any[Tuple{}] + + # TODO: Clean me up + T = Type{T} where {T} + @test DSE.alltypesigs(T) == + Base.rewrap_unionall.(DSE.uniontypes(Base.unwrap_unionall(T)), T) + end + @testset "groupby" begin + let groups = DSE.groupby(Int, Vector{Int}, collect(1:10)) do each + mod(each, 3), each + end + @test groups == Pair{Int, Vector{Int}}[ + 0 => [3, 6, 9], + 1 => [1, 4, 7, 10], + 2 => [2, 5, 8], + ] + end + end + @testset "url" begin + @test !isempty(DSE.url(first(methods(sin)))) + @test !isempty(DSE.url(first(methods(DSE.parsedocs)))) + @test !isempty(DSE.url(first(methods(M.f)))) + @test !isempty(DSE.url(first(methods(M.K)))) + end + @testset "comparemethods" begin + let f = first(methods(M.f)), + g = first(methods(M.g)) + @test !DSE.comparemethods(f, f) + @test DSE.comparemethods(f, g) + @test !DSE.comparemethods(g, f) + end + end + end +end + +DSE.parsedocs(DSE) diff --git a/embedded/DocStringExtensions.source b/embedded/DocStringExtensions.source new file mode 100644 index 0000000..d39ab66 --- /dev/null +++ b/embedded/DocStringExtensions.source @@ -0,0 +1 @@ +https://github.com/JuliaDocs/DocStringExtensions.jl/releases diff --git a/embedded/Documenter b/embedded/Documenter new file mode 120000 index 0000000..569ca84 --- /dev/null +++ b/embedded/Documenter @@ -0,0 +1 @@ +Documenter.jl-0.20.0 \ No newline at end of file diff --git a/embedded/Documenter.jl-0.20.0/.codecov.yml b/embedded/Documenter.jl-0.20.0/.codecov.yml new file mode 100644 index 0000000..69cb760 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/.codecov.yml @@ -0,0 +1 @@ +comment: false diff --git a/embedded/Documenter.jl-0.20.0/.travis.yml b/embedded/Documenter.jl-0.20.0/.travis.yml new file mode 100644 index 0000000..ba33e69 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/.travis.yml @@ -0,0 +1,27 @@ +language: julia + +os: + - linux + - osx + +julia: + - 0.7 + - 1.0 + - nightly + +notifications: + email: false + +after_success: + - julia --project=coverage/ -e 'using Pkg; Pkg.instantiate()' + - julia --project=coverage/ coverage/coverage.jl + +jobs: + include: + - stage: "Documentation" + julia: 1.0 + os: linux + script: + - julia --project=docs/ -e 'using Pkg; Pkg.instantiate(); Pkg.develop(PackageSpec(path=pwd()))' + - julia --project=docs/ docs/make.jl + after_success: skip diff --git a/embedded/Documenter.jl-0.20.0/CHANGELOG.md b/embedded/Documenter.jl-0.20.0/CHANGELOG.md new file mode 100644 index 0000000..fe40576 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/CHANGELOG.md @@ -0,0 +1,121 @@ +# Documenter.jl changelog + +## Version `v0.20.0` + +* Documenter v0.20 requires at least Julia v0.7. ([#795][github-795]) + +* ![BREAKING][badge-breaking] Documentation deployment via the `deploydocs` function has changed considerably. + + - The user-facing directories (URLs) of different versions and what gets displayed in the version selector have changed. By default, Documenter now creates the `stable/` directory (as before) and a directory for every minor version (`vX.Y/`). The `release-X.Y` directories are no longer created. ([#706][github-706], [#813][github-813], [#817][github-817]) + + Technically, Documenter now deploys actual files only to `dev/` and `vX.Y.Z/` directories. The directories (URLs) that change from version to version (e.g. `latest/`, `vX.Y`) are implemented as symlinks on the `gh-pages` branch. + + The version selector will only display `vX.Y/`, `stable/` and `dev/` directories by default. This behavior can be customized with the `versions` keyword of `deploydocs`. + + - Documentation from the development branch (e.g. `master`) now deploys to `dev/` by default (instead of `latest/`). This can be customized with the `devurl` keyword. ([#802][github-802]) + + - The `latest` keyword to `deploydocs` has been deprecated and renamed to `devbranch`. ([#802][github-802]) + + - The `julia` and `osname` keywords to `deploydocs` are now deprecated. ([#816][github-816]) + + - The default values of the `target`, `deps` and `make` keywords to `deploydocs` have been changed. See the default format change below for more information. ([#826][github-826]) + + **For upgrading:** + + - If you are using the `latest` keyword, then just use `devbranch` with the same value instead. + + - Update links that point to `latest/` to point to `dev/` instead (e.g. in the README). + + - Remove any links to the `release-X.Y` branches and remove the directories from your `gh-pages` branch. + + - The operating system and Julia version should be specified in the Travis build stage configuration (via `julia:` and `os:` options, see "Hosting Documentation" in the manual for more details) or by checking the `TRAVIS_JULIA_VERSION` and `TRAVIS_OS_NAME` environment variables in `make.jl` yourself. + +* ![BREAKING][badge-breaking] `makedocs` will now build Documenter's native HTML output by default and `deploydocs`' defaults now assume the HTML output. ([#826][github-826]) + + - The default value of the `format` keyword of `makedocs` has been changed to `:html`. + + - The default value of the `target` keyword to `deploydocs` has been changed to `"build"`. + + - The default value of the `make` and `deps` keywords to `deploydocs` have been changed to `nothing`. + + **For upgrading:** If you are relying on the Markdown/MkDocs output, you now need to: + + - In `makedocs`, explicitly set `format = :markdown` + + - In `deploydocs`, explicitly set + + ```julia + target = "site" + deps = Deps.pip("pygments", "mkdocs") + make = () -> run(`mkdocs build`) + ``` + + - Explicitly import `DocumenterMarkdown` in `make.jl`. See the `MarkdownWriter` deprecation below. + + If you already specify any of the changed keywords, then you do not need to make any changes to those keywords you already set. + + However, if you are setting any of the values to the new defaults (e.g. when you are already using the HTML output), you may now rely on the new defaults. + +* ![Deprecation][badge-deprecation] The Markdown/MkDocs (`format = :markdown`) and PDF/LaTeX (`format = :latex`) outputs now require an external package to be loaded ([DocumenterMarkdown](https://github.com/JuliaDocs/DocumenterMarkdown.jl) and [DocumenterLaTeX](https://github.com/JuliaDocs/DocumenterLaTeX.jl), respectively). ([#833][github-833]) + + **For upgrading:** Make sure that the respective extra package is installed and then just add `using DocumenterMarkdown` or `using DocumenterLaTeX` to `make.jl`. + +* ![BREAKING][badge-breaking] "Pretty URLs" are enabled by default now for the HTML output. The default value of the `html_prettyurls` has been changed to `true`. + + For a page `foo/page.md` Documenter now generates `foo/page/index.html`, instead of `foo/page.html`. + On GitHub pages deployments it means that your URLs look like `foo/page/` instead of `foo/page.html`. + + For local builds you should explicitly set `html_prettyurls = false`. + + **For upgrading:** If you wish to retain the old behavior, set `html_prettyurls = false` in `makedocs`. If you already set `html_prettyurls`, you do not need to change anything. + +* ![BREAKING][badge-breaking] The `Travis.genkeys` and `Documenter.generate` functions have been moved to a separate [DocumenterTools.jl package](https://github.com/JuliaDocs/DocumenterTools.jl). ([#789][github-789]) + +* ![Enhancement][badge-enhancement] If Documenter is not able to determine which Git hosting service is being used to host the source, the "Edit on XXX" links become "Edit source" with a generic icon. ([#804][github-804]) + +* ![Enhancement][badge-enhancement] The at-blocks now support `MIME"text/html"` rendering of objects (e.g. for interactive plots). I.e. if a type has `show(io, ::MIME"text/html", x)` defined, Documenter now uses that when rendering the objects in the document. ([#764][github-764]) + +* ![Enhancement][badge-enhancement] Enhancements to the sidebar. When loading a page, the sidebar will jump to the current page now. Also, the scrollbar in WebKit-based browsers look less intrusive now. ([#792][github-792], [#854][github-854], [#863][github-863]) + +* ![Enhancement][badge-enhancement] Minor style enhancements to admonitions. ([#841][github-841]) + +* ![Bugfix][badge-bugfix] The at-blocks that execute code can now handle `include` statements. ([#793][github-793], [#794][github-794]) + +* ![Bugfix][badge-bugfix] At-docs blocks no longer give an error when containing empty lines. ([#823][github-823], [#824][github-824]) + +[github-706]: https://github.com/JuliaDocs/Documenter.jl/pull/706 +[github-764]: https://github.com/JuliaDocs/Documenter.jl/pull/764 +[github-789]: https://github.com/JuliaDocs/Documenter.jl/pull/789 +[github-792]: https://github.com/JuliaDocs/Documenter.jl/pull/792 +[github-793]: https://github.com/JuliaDocs/Documenter.jl/pull/793 +[github-794]: https://github.com/JuliaDocs/Documenter.jl/pull/794 +[github-795]: https://github.com/JuliaDocs/Documenter.jl/pull/795 +[github-802]: https://github.com/JuliaDocs/Documenter.jl/pull/802 +[github-804]: https://github.com/JuliaDocs/Documenter.jl/pull/804 +[github-813]: https://github.com/JuliaDocs/Documenter.jl/pull/813 +[github-816]: https://github.com/JuliaDocs/Documenter.jl/pull/816 +[github-817]: https://github.com/JuliaDocs/Documenter.jl/pull/817 +[github-823]: https://github.com/JuliaDocs/Documenter.jl/pull/823 +[github-824]: https://github.com/JuliaDocs/Documenter.jl/pull/824 +[github-826]: https://github.com/JuliaDocs/Documenter.jl/pull/826 +[github-833]: https://github.com/JuliaDocs/Documenter.jl/pull/833 +[github-841]: https://github.com/JuliaDocs/Documenter.jl/pull/841 +[github-854]: https://github.com/JuliaDocs/Documenter.jl/pull/854 +[github-863]: https://github.com/JuliaDocs/Documenter.jl/pull/863 + + +[badge-breaking]: https://img.shields.io/badge/BREAKING-red.svg +[badge-deprecation]: https://img.shields.io/badge/deprecation-orange.svg +[badge-feature]: https://img.shields.io/badge/feature-green.svg +[badge-enhancement]: https://img.shields.io/badge/enhancement-blue.svg +[badge-bugfix]: https://img.shields.io/badge/bugfix-purple.svg + + diff --git a/embedded/Documenter.jl-0.20.0/LICENSE.md b/embedded/Documenter.jl-0.20.0/LICENSE.md new file mode 100644 index 0000000..1a2af49 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/LICENSE.md @@ -0,0 +1,22 @@ +The Documenter.jl package is licensed under the MIT "Expat" License: + +> Copyright (c) 2016: Michael Hatherly. +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in all +> copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +> SOFTWARE. +> diff --git a/embedded/Documenter.jl-0.20.0/README.md b/embedded/Documenter.jl-0.20.0/README.md new file mode 100644 index 0000000..72a2d18 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/README.md @@ -0,0 +1,62 @@ + +# Documenter + +*A documentation generator for Julia.* + +| **Documentation** | **Build Status** | +|:-------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------:| +| [![][docs-stable-img]][docs-stable-url] [![][docs-dev-img]][docs-dev-url] | [![][travis-img]][travis-url] [![][appveyor-img]][appveyor-url] [![][codecov-img]][codecov-url] | + + +## Installation + +The package can be installed with the Julia package manager. +From the Julia REPL, type `]` to enter the Pkg REPL mode and run: + +``` +pkg> add Documenter +``` + +Or, equivalently, via the `Pkg` API: + +```julia +julia> import Pkg; Pkg.add("Documenter") +``` + +## Documentation + +- [**STABLE**][docs-stable-url] — **documentation of the most recently tagged version.** +- [**DEVEL**][docs-dev-url] — *documentation of the in-development version.* + +## Project Status + +The package is tested against Julia `0.7`, `1.0` and the nightly builds of the Julia `master` branch on Linux, macOS, and Windows. + +Support for Julia `0.4`, `0.5` and `0.6` has been dropped in the latest version, but older versions of Documenter may still work (Documenter versions `0.8`, `0.11` and `0.19`, respectively). + +## Questions and Contributions + +Usage questions can be posted on the [Julia Discourse forum][discourse-tag-url] under the `documenter` tag, in the #documentation channel of the [Julia Slack](https://julialang.org/community/) and/or in the [JuliaDocs Gitter chat room][gitter-url]. + +Contributions are very welcome, as are feature requests and suggestions. Please open an [issue][issues-url] if you encounter any problems. The [contributing page][contrib-url] has a few guidelines that should be followed when opening pull requests and contributing code. + +[contrib-url]: https://juliadocs.github.io/Documenter.jl/latest/man/contributing/ +[discourse-tag-url]: https://discourse.julialang.org/tags/documenter +[gitter-url]: https://gitter.im/juliadocs/users + +[docs-dev-img]: https://img.shields.io/badge/docs-dev-blue.svg +[docs-dev-url]: https://juliadocs.github.io/Documenter.jl/latest + +[docs-stable-img]: https://img.shields.io/badge/docs-stable-blue.svg +[docs-stable-url]: https://juliadocs.github.io/Documenter.jl/stable + +[travis-img]: https://travis-ci.org/JuliaDocs/Documenter.jl.svg?branch=master +[travis-url]: https://travis-ci.org/JuliaDocs/Documenter.jl + +[appveyor-img]: https://ci.appveyor.com/api/projects/status/xx7nimfpnl1r4gx0?svg=true +[appveyor-url]: https://ci.appveyor.com/project/JuliaDocs/documenter-jl + +[codecov-img]: https://codecov.io/gh/JuliaDocs/Documenter.jl/branch/master/graph/badge.svg +[codecov-url]: https://codecov.io/gh/JuliaDocs/Documenter.jl + +[issues-url]: https://github.com/JuliaDocs/Documenter.jl/issues diff --git a/embedded/Documenter.jl-0.20.0/REQUIRE b/embedded/Documenter.jl-0.20.0/REQUIRE new file mode 100644 index 0000000..4e2a4a0 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/REQUIRE @@ -0,0 +1,2 @@ +julia 0.7 +DocStringExtensions 0.2 diff --git a/embedded/Documenter.jl-0.20.0/appveyor.yml b/embedded/Documenter.jl-0.20.0/appveyor.yml new file mode 100644 index 0000000..c3acffe --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/appveyor.yml @@ -0,0 +1,37 @@ +environment: + matrix: + - julia_version: 0.7 + - julia_version: 1.0 + - julia_version: latest + +platform: + - x86 # 32-bit + - x64 # 64-bit + +## uncomment the following lines to allow failures on nightly julia +## (tests will run but not make your overall status red) +#matrix: +# allow_failures: +# - julia_version: latest + +branches: + only: + - master + - /release-.*/ + +notifications: + - provider: Email + on_build_success: false + on_build_failure: false + on_build_status_changed: false + +install: + - ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1")) + +build_script: + - echo "%JL_BUILD_SCRIPT%" + - C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%" + +test_script: + - echo "%JL_TEST_SCRIPT%" + - C:\julia\bin\julia -e "%JL_TEST_SCRIPT%" diff --git a/embedded/Documenter.jl-0.20.0/assets/html/arrow.svg b/embedded/Documenter.jl-0.20.0/assets/html/arrow.svg new file mode 100644 index 0000000..ee2798d --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/assets/html/arrow.svg @@ -0,0 +1,63 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/embedded/Documenter.jl-0.20.0/assets/html/documenter.css b/embedded/Documenter.jl-0.20.0/assets/html/documenter.css new file mode 100644 index 0000000..b6c9e1d --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/assets/html/documenter.css @@ -0,0 +1,601 @@ +/* + * The default CSS style for Documenter.jl generated sites + * + * Heavily inspired by the Julia Sphinx theme + * https://github.com/JuliaLang/JuliaDoc + * which extends the sphinx_rtd_theme + * https://github.com/snide/sphinx_rtd_theme + * + * Part of Documenter.jl + * https://github.com/JuliaDocs/Documenter.jl + * + * License: MIT + */ + +/* fonts */ +body, input { + font-family: 'Lato', 'Helvetica Neue', Arial, sans-serif; + font-size: 16px; + color: #222; + text-rendering: optimizeLegibility; +} + +pre, code, kbd { + font-family: Inconsolata, Monaco, courier, monospace; + font-size: 0.90em; +} + +pre code { + font-size: 1em; +} + +a { + color: #2980b9; + text-decoration: none; +} + +a:hover { + color: #3091d1; +} + +a:visited { + color: #9b59b6; +} + +body { + line-height: 1.5; +} + +h1 { + font-size: 1.75em; +} + +/* Unless the

the is very first thing on the page (i.e. the second element + * in the
, * after the
, we add some additional styling to it + * to make it stand out a bit more. This way we get a reasonable fallback if CSS3 + * selectors are not supported in the browser. + */ +article > h1:not(:nth-child(2)) { + margin: 2.5em 0 0; + padding-bottom: 0.30em; + border-bottom: 1px solid #e5e5e5; +} +h2 { + font-size: 1.50em; + margin: 2.3em 0 0; + padding-bottom: 0.25em; + border-bottom: 1px solid #e5e5e5; +} +h3 { + font-size: 1.25em; + margin: 2.0em 0 0; +} +h4 { font-size: 1.15em; } +h5 { font-size: 1.10em; } +h6 { font-size: 1em; } + +h4, h5, h6 { + margin-top: 1.5em; + margin-bottom: 1em; +} + +img { + max-width: 100%; +} + +table { + border-collapse: collapse; + margin: 1em 0; +} + +th, td { + border: 1px solid #e1e4e5; + padding: 0.5em 1em; +} + +th { + border-bottom-width: 2px; +} + +tr:nth-child(even) { + background-color: #f3f6f6; +} + +hr { + border: 0; + border-top: 1px solid #e5e5e5; +} + +/* Inline code and code blocks */ + +code { + padding: 0.1em; + background-color: rgba(0,0,0,.04); + border-radius: 3px; +} + +pre { + background-color: #f5f5f5; + border: 1px solid #dddddd; + border-radius: 3px; + padding: 0.5em; + overflow: auto; +} + +pre code { + padding: 0; + background-color: initial; +} + +kbd { + font-size: 0.70em; + display: inline-block; + padding: 0.1em 0.5em 0.4em 0.5em; + line-height: 1.0em; + color: #444d56; + vertical-align: middle; + background-color: #fafbfc; + border: solid 1px #c6cbd1; + border-bottom-color: #959da5; + border-radius: 3px; + box-shadow: inset 0 -1px 0 #959da5; +} + +/* Headers in admonitions and docstrings */ +.admonition h1, +article section.docstring h1 { + font-size: 1.25em; +} + +.admonition h2, +article section.docstring h2 { + font-size: 1.10em; +} + +.admonition h3, +.admonition h4, +.admonition h5, +.admonition h6, +article section.docstring h3, +article section.docstring h4, +article section.docstring h5, +article section.docstring h6 { + font-size: 1em; +} + +/* Navigation */ +nav.toc { + position: fixed; + top: 0; + left: 0; + bottom: 0; + width: 20em; + display: flex; + flex-flow: column nowrap; + overflow-y: auto; + padding: 1em 0 0 0; + background-color: #fcfcfc; + box-shadow: inset -14px 0px 5px -12px rgb(210,210,210); +} + +nav.toc .logo { + margin: 0 auto; + display: block; + max-height: 6em; + max-width: 18em; +} + +nav.toc h1 { + text-align: center; + margin-top: .57em; + margin-bottom: 0; +} + +nav.toc select { + display: block; + height: 2em; + flex-shrink: 0; + padding: 0 1.6em 0 1em; + min-width: 7em; + max-width: 90%; + max-width: calc(100% - 5em); + margin: 0 auto; + font-size: .83em; + border: 1px solid #c9c9c9; + border-radius: 1em; + + /* TODO: doesn't seem to be centered on Safari */ + text-align: center; + text-align-last: center; + + appearance: none; + -moz-appearance: none; + -webkit-appearance: none; + + background: white url("arrow.svg"); + background-size: 1.155em; + background-repeat: no-repeat; + background-position: right; +} + +nav.toc select:hover { + border: 1px solid #a0a0a0; +} + +nav.toc select option { + text-align: center; +} + +nav.toc input { + display: block; + height: 2em; + width: 90%; + width: calc(100% - 5em); + margin: 1.2em auto; + padding: 0 1em; + border: 1px solid #c9c9c9; + border-radius: 1em; + font-size: .83em; +} + +nav.toc > ul * { + margin: 0; +} + +nav.toc > ul { + min-height: 2em; + overflow-y: auto; + margin: 0; +} + +nav.toc > ul > li:last-child { + padding-bottom: 1em; +} + +nav.toc ul { + color: #404040; + padding: 0; + list-style: none; +} + +nav.toc ul .toctext { + color: inherit; + display: block; +} + +nav.toc ul a:hover { + color: #fcfcfc; + background-color: #4e4a4a; +} + +nav.toc ul.internal a { + color: inherit; + display: block; +} + +nav.toc ul.internal a:hover { + background-color: #d6d6d6; +} + +nav.toc ul.internal { + background-color: #e3e3e3; + box-shadow: inset -14px 0px 5px -12px rgb(210,210,210); + list-style: none; +} + +nav.toc ul.internal li.toplevel { + border-top: 1px solid #909090; + font-weight: bold; +} + +nav.toc ul.internal li.toplevel:first-child { + border-top: none; +} + +nav.toc .toctext { + padding-top: 0.3em; + padding-bottom: 0.3em; + padding-right: 1em; +} + +nav.toc ul .toctext { + padding-left: 1em; +} + +nav.toc ul ul .toctext { + padding-left: 2em; +} + +nav.toc ul ul ul .toctext { + padding-left: 3em; +} + +nav.toc li.current > .toctext { + border-top: 1px solid #c9c9c9; + border-bottom: 1px solid #c9c9c9; + color: #404040; + font-weight: bold; + background-color: white; +} + +nav.toc ul::-webkit-scrollbar { + width: .4em; + background: none; +} + +nav.toc ul::-webkit-scrollbar-thumb { + border-radius: 5px; + background: #c9c9c9; +} + +nav.toc ul::-webkit-scrollbar-thumb:hover { + border-radius: 5px; + background: #aaaaaa; +} + +article { + margin-left: 20em; + min-width: 20em; + max-width: 48em; + padding: 2em; +} + +article > header {} + +article > header div#topbar { + display: none; +} + +article > header nav ul { + display: inline-block; + list-style: none; + margin: 0; + padding: 0; +} + +article > header nav li { + display: inline-block; + padding-right: 0.2em; +} + +article > header nav li:before { + content: "»"; + padding-right: 0.2em; +} + +article > header .edit-page { + float: right; +} + +article > footer {} + +article > footer a.prev { + float: left; +} +article > footer a.next { + float: right; +} + +article > footer a .direction:after { + content: ": "; +} + +article hr { + margin: 1em 0; +} + +article section.docstring { + border: 1px solid #ddd; + margin: 0.5em 0; + padding: 0.5em; + border-radius: 3px; +} + +article section.docstring .docstring-header { + margin-bottom: 1em; +} + +article section.docstring .docstring-binding { + color: #333; + font-weight: bold; +} + +article section.docstring .docstring-category { + font-style: italic; +} + +article section.docstring a.source-link { + display: block; + font-weight: bold; +} + +.nav-anchor, +.nav-anchor:hover, +.nav-anchor:visited { + color: #333; +} + +/* + * Admonitions + * + * Colors (title, body) + * warning: #f0b37e #ffedcc (orange) + * note: #6ab0de #e7f2fa (blue) + * tip: #1abc9c #dbfaf4 (green) +*/ +.admonition { + border-radius: 3px; + background-color: #eeeeee; + margin: 1em 0; +} + +.admonition-title { + border-radius: 3px 3px 0 0; + background-color: #9b9b9b; + padding: 0.15em 0.5em; +} + +.admonition-text { + padding: 0.5em; +} + +.admonition-text > :first-child { + margin-top: 0; +} + +.admonition-text > :last-child { + margin-bottom: 0; +} + +.admonition > .admonition-title:before { + font-family: "FontAwesome"; + margin-right: 5px; + content: "\f06a"; +} + +.admonition.warning > .admonition-title { + background-color: #f0b37e; +} + +.admonition.warning { + background-color: #ffedcc; +} + +.admonition.note > .admonition-title { + background-color: #6ab0de; +} + +.admonition.note { + background-color: #e7f2fa; +} + +.admonition.tip > .admonition-title { + background-color: #1abc9c; +} + +.admonition.tip { + background-color: #dbfaf4; +} + + +/* footnotes */ +.footnote { + padding-left: 0.8em; + border-left: 2px solid #ccc; +} + +/* Search page */ +#search-results .category { + font-size: smaller; +} + +/* Overriding the block style of highligh.js. + * We have to override the padding and the background-color, since we style this + * part ourselves. Specifically, we style the
 surrounding the , while
+ * highlight.js applies the .hljs style directly to the  tag.
+ */
+.hljs {
+    background-color: transparent;
+    padding: 0;
+}
+
+@media only screen and (max-width: 768px) {
+    nav.toc {
+        position: fixed;
+        width: 16em;
+        left: -16em;
+        -webkit-overflow-scrolling: touch;
+        -webkit-transition-property: left; /* Safari */
+        -webkit-transition-duration: 0.3s; /* Safari */
+        transition-property: left;
+        transition-duration: 0.3s;
+        -webkit-transition-timing-function: ease-out; /* Safari */
+        transition-timing-function: ease-out;
+        z-index: 2;
+        box-shadow: 5px 0px 5px 0px rgb(210,210,210);
+    }
+
+    nav.toc.show {
+        left: 0;
+    }
+
+    article {
+        margin-left: 0;
+        padding: 3em 0.9em 0 0.9em; /* top right bottom left */
+        overflow-wrap: break-word;
+    }
+
+    article > header {
+        position: fixed;
+        left: 0;
+        z-index: 1;
+    }
+
+    article > header nav, hr {
+        display: none;
+    }
+
+    article > header div#topbar {
+        display: block; /* is mobile */
+        position: fixed;
+        width: 100%;
+        height: 1.5em;
+        padding-top: 1em;
+        padding-bottom: 1em;
+        background-color: #fcfcfc;
+        box-shadow: 0 1px 3px rgba(0,0,0,.26);
+        top: 0;
+        -webkit-transition-property: top; /* Safari */
+        -webkit-transition-duration: 0.3s; /* Safari */
+        transition-property: top;
+        transition-duration: 0.3s;
+    }
+
+    article > header div#topbar.headroom--unpinned.headroom--not-top.headroom--not-bottom {
+        top: -4em;
+        -webkit-transition-property: top; /* Safari */
+        -webkit-transition-duration: 0.7s; /* Safari */
+        transition-property: top;
+        transition-duration: 0.7s;
+    }
+
+    article > header div#topbar span {
+        width: 80%;
+        height: 1.5em;
+        margin-top: -0.1em;
+        margin-left: 0.9em;
+        font-size: 1.2em;
+        overflow: hidden;
+    }
+
+    article > header div#topbar a.fa-bars {
+        float: right;
+        padding: 0.6em;
+        margin-top: -0.6em;
+        margin-right: 0.3em;
+        font-size: 1.5em;
+    }
+
+    article > header div#topbar a.fa-bars:visited {
+        color: #3091d1;
+    }
+
+    article table {
+        overflow-x: auto;
+        display: block;
+    }
+
+    article div.MathJax_Display {
+        overflow: scroll;
+    }
+
+    article span.MathJax {
+        overflow: hidden;
+    }
+}
+
+@media only screen and (max-width: 320px) {
+    body {
+        font-size: 15px;
+    }
+}
diff --git a/embedded/Documenter.jl-0.20.0/assets/html/documenter.js b/embedded/Documenter.jl-0.20.0/assets/html/documenter.js
new file mode 100644
index 0000000..661e7e5
--- /dev/null
+++ b/embedded/Documenter.jl-0.20.0/assets/html/documenter.js
@@ -0,0 +1,133 @@
+/*
+ * Part of Documenter.jl
+ *     https://github.com/JuliaDocs/Documenter.jl
+ *
+ * License: MIT
+ */
+
+requirejs.config({
+    paths: {
+        'jquery': 'file:///usr/share/javascript/jquery/jquery.min.js',
+        'jqueryui': 'file:///usr/share/javascript/jquery-ui/jquery-ui.min.js',
+		//'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.9.3/headroom.min',
+		'headroom': 'http://localhost',
+        'mathjax': 'file:///usr/share/javascript/mathjax/MathJax.js?config=TeX-AMS_HTML',
+        'highlight': 'file:///usr/lib/nodejs/highlight.js/highlight.js',
+        'highlight-julia': 'file:////usr/lib/nodejs/highlight.js/languages/julia.js',
+        'highlight-julia-repl': 'file:////usr/lib/nodejs/highlight.js/languages/julia-repl.js',
+    },
+    shim: {
+        'mathjax' : {
+            exports: "MathJax"
+        },
+        'highlight-julia': ['highlight'],
+        'highlight-julia-repl': ['highlight'],
+    }
+});
+
+// Load MathJax
+require(['mathjax'], function(MathJax) {
+    MathJax.Hub.Config({
+      "tex2jax": {
+        inlineMath: [['$','$'], ['\\(','\\)']],
+        processEscapes: true
+      }
+    });
+    MathJax.Hub.Config({
+      config: ["MMLorHTML.js"],
+      jax: [
+        "input/TeX",
+        "output/HTML-CSS",
+        "output/NativeMML"
+      ],
+      extensions: [
+        "MathMenu.js",
+        "MathZoom.js",
+        "TeX/AMSmath.js",
+        "TeX/AMSsymbols.js",
+        "TeX/autobold.js",
+        "TeX/autoload-all.js"
+      ]
+    });
+    MathJax.Hub.Config({
+      TeX: { equationNumbers: { autoNumber: "AMS" } }
+    });
+})
+
+require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($, hljs) {
+    $(document).ready(function() {
+        hljs.initHighlighting();
+    })
+
+})
+
+// update the version selector with info from the siteinfo.js and ../versions.js files
+require(['jquery'], function($) {
+    $(document).ready(function() {
+        var version_selector = $("#version-selector");
+
+        // add the current version to the selector based on siteinfo.js, but only if the selector is empty
+        if (typeof DOCUMENTER_CURRENT_VERSION !== 'undefined' && $('#version-selector > option').length == 0) {
+            var option = $("");
+            version_selector.append(option);
+        }
+
+        if (typeof DOC_VERSIONS !== 'undefined') {
+            var existing_versions = $('#version-selector > option');
+            var existing_versions_texts = existing_versions.map(function(i,x){return x.text});
+            DOC_VERSIONS.forEach(function(each) {
+                var version_url = documenterBaseURL + "/../" + each;
+                var existing_id = $.inArray(each, existing_versions_texts);
+                // if not already in the version selector, add it as a new option,
+                // otherwise update the old option with the URL and enable it
+                if (existing_id == -1) {
+                    var option = $("");
+                    version_selector.append(option);
+                } else {
+                    var option = existing_versions[existing_id];
+                    option.value = version_url;
+                    option.disabled = false;
+                }
+            });
+        }
+
+        // only show the version selector if the selector has been populated
+        if ($('#version-selector > option').length > 0) {
+            version_selector.css("visibility", "visible");
+        }
+
+        // Scroll the navigation bar to the currently selected menu item
+        $("nav.toc > ul").get(0).scrollTop = $(".current").get(0).offsetTop - $("nav.toc > ul").get(0).offsetTop;
+    })
+
+})
+
+// mobile
+require(['jquery', 'headroom'], function($, Headroom) {
+    $(document).ready(function() {
+        var navtoc = $("nav.toc");
+        $("nav.toc li.current a.toctext").click(function() {
+            navtoc.toggleClass('show');
+        });
+        $("article > header div#topbar a.fa-bars").click(function(ev) {
+            ev.preventDefault();
+            navtoc.toggleClass('show');
+            if (navtoc.hasClass('show')) {
+                var title = $("article > header div#topbar span").text();
+                $("nav.toc ul li a:contains('" + title + "')").focus();
+            }
+        });
+        $("article#docs").bind('click', function(ev) {
+            if ($(ev.target).is('div#topbar a.fa-bars')) {
+                return;
+            }
+            if (navtoc.hasClass('show')) {
+                navtoc.removeClass('show');
+            }
+        });
+        if ($("article > header div#topbar").css('display') == 'block') {
+            var headroom = new Headroom(document.querySelector("article > header div#topbar"), {"tolerance": {"up": 10, "down": 10}});
+            headroom.init();
+        }
+    })
+})
diff --git a/embedded/Documenter.jl-0.20.0/assets/html/search.js b/embedded/Documenter.jl-0.20.0/assets/html/search.js
new file mode 100644
index 0000000..f99b378
--- /dev/null
+++ b/embedded/Documenter.jl-0.20.0/assets/html/search.js
@@ -0,0 +1,250 @@
+/*
+ * Part of Documenter.jl
+ *     https://github.com/JuliaDocs/Documenter.jl
+ *
+ * License: MIT
+ */
+
+// parseUri 1.2.2
+// (c) Steven Levithan 
+// MIT License
+function parseUri (str) {
+	var	o   = parseUri.options,
+		m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
+		uri = {},
+		i   = 14;
+
+	while (i--) uri[o.key[i]] = m[i] || "";
+
+	uri[o.q.name] = {};
+	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+		if ($1) uri[o.q.name][$1] = $2;
+	});
+
+	return uri;
+};
+parseUri.options = {
+	strictMode: false,
+	key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
+	q:   {
+		name:   "queryKey",
+		parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+	},
+	parser: {
+		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+		loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+	}
+};
+
+requirejs.config({
+    paths: {
+        'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min',
+        'lunr': 'https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.1/lunr.min',
+        'lodash': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min',
+    }
+});
+
+var currentScript = document.currentScript;
+
+require(["jquery", "lunr", "lodash"], function($, lunr, _) {
+    $("#search-form").submit(function(e) {
+        e.preventDefault()
+    })
+
+    // list below is the lunr 2.1.3 list minus the intersect with names(Base)
+    // (all, any, get, in, is, which) and (do, else, for, let, where, while, with)
+    // ideally we'd just filter the original list but it's not available as a variable
+    lunr.stopWordFilter = lunr.generateStopWordFilter([
+        'a',
+        'able',
+        'about',
+        'across',
+        'after',
+        'almost',
+        'also',
+        'am',
+        'among',
+        'an',
+        'and',
+        'are',
+        'as',
+        'at',
+        'be',
+        'because',
+        'been',
+        'but',
+        'by',
+        'can',
+        'cannot',
+        'could',
+        'dear',
+        'did',
+        'does',
+        'either',
+        'ever',
+        'every',
+        'from',
+        'got',
+        'had',
+        'has',
+        'have',
+        'he',
+        'her',
+        'hers',
+        'him',
+        'his',
+        'how',
+        'however',
+        'i',
+        'if',
+        'into',
+        'it',
+        'its',
+        'just',
+        'least',
+        'like',
+        'likely',
+        'may',
+        'me',
+        'might',
+        'most',
+        'must',
+        'my',
+        'neither',
+        'no',
+        'nor',
+        'not',
+        'of',
+        'off',
+        'often',
+        'on',
+        'only',
+        'or',
+        'other',
+        'our',
+        'own',
+        'rather',
+        'said',
+        'say',
+        'says',
+        'she',
+        'should',
+        'since',
+        'so',
+        'some',
+        'than',
+        'that',
+        'the',
+        'their',
+        'them',
+        'then',
+        'there',
+        'these',
+        'they',
+        'this',
+        'tis',
+        'to',
+        'too',
+        'twas',
+        'us',
+        'wants',
+        'was',
+        'we',
+        'were',
+        'what',
+        'when',
+        'who',
+        'whom',
+        'why',
+        'will',
+        'would',
+        'yet',
+        'you',
+        'your'
+        ])
+
+    // add . as a separator, because otherwise "title": "Documenter.Anchors.add!"
+    // would not find anything if searching for "add!", only for the entire qualification
+    lunr.tokenizer.separator = /[\s\-\.]+/
+
+    // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names
+    lunr.trimmer = function (token) {
+        return token.update(function (s) {
+            return s.replace(/^[^a-zA-Z0-9@!]+/, '').replace(/[^a-zA-Z0-9@!]+$/, '')
+        })
+    }
+
+    lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'juliaStopWordFilter')
+    lunr.Pipeline.registerFunction(lunr.trimmer, 'juliaTrimmer')
+
+    var index = lunr(function () {
+        this.ref('location')
+        this.field('title')
+        this.field('text')
+        documenterSearchIndex['docs'].forEach(function(e) {
+            this.add(e)
+        }, this)
+    })
+    var store = {}
+
+    documenterSearchIndex['docs'].forEach(function(e) {
+        store[e.location] = {title: e.title, category: e.category}
+    })
+
+    $(function(){
+        function update_search(querystring) {
+            tokens = lunr.tokenizer(querystring)
+            results = index.query(function (q) {
+                tokens.forEach(function (t) {
+                    q.term(t.toString(), {
+                        fields: ["title"],
+                        boost: 100,
+                        usePipeline: false,
+                        editDistance: 0,
+                        wildcard: lunr.Query.wildcard.NONE
+                    })
+                    q.term(t.toString(), {
+                        fields: ["title"],
+                        boost: 10,
+                        usePipeline: false,
+                        editDistance: 2,
+                        wildcard: lunr.Query.wildcard.NONE
+                    })
+                    q.term(t.toString(), {
+                        fields: ["text"],
+                        boost: 1,
+                        usePipeline: true,
+                        editDistance: 0,
+                        wildcard: lunr.Query.wildcard.NONE
+                    })
+                })
+            })
+            $('#search-info').text("Number of results: " + results.length)
+            $('#search-results').empty()
+            results.forEach(function(result) {
+                data = store[result.ref]
+                link = $('')
+                link.text(data.title)
+                link.attr('href', documenterBaseURL+'/'+result.ref)
+                cat = $('('+data.category+')')
+                li = $('
  • ').append(link).append(" ").append(cat) + $('#search-results').append(li) + }) + } + + function update_search_box() { + querystring = $('#search-query').val() + update_search(querystring) + } + + $('#search-query').keyup(_.debounce(update_search_box, 250)) + $('#search-query').change(update_search_box) + + search_query_uri = parseUri(window.location).queryKey["q"] + if(search_query_uri !== undefined) { + search_query = decodeURIComponent(search_query_uri.replace(/\+/g, '%20')) + $("#search-query").val(search_query) + } + update_search_box(); + }) +}) diff --git a/embedded/Documenter.jl-0.20.0/assets/html/style.css b/embedded/Documenter.jl-0.20.0/assets/html/style.css new file mode 100644 index 0000000..e69de29 diff --git a/embedded/Documenter.jl-0.20.0/assets/latex/documenter.sty b/embedded/Documenter.jl-0.20.0/assets/latex/documenter.sty new file mode 100644 index 0000000..ad71724 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/assets/latex/documenter.sty @@ -0,0 +1,77 @@ +% font settings +\usepackage{fontspec, newunicodechar, polyglossia} + +\setsansfont{Lato}[Scale=MatchLowercase, Ligatures=TeX] +\setmonofont{Roboto Mono}[Scale=MatchLowercase] +\renewcommand{\familydefault}{\sfdefault} +% + +% colours +\usepackage{xcolor} + +\definecolor{light-blue}{HTML}{6b85dd} +\definecolor{dark-blue}{HTML}{4266d5} +\definecolor{light-red}{HTML}{d66661} +\definecolor{dark-red}{HTML}{c93d39} +\definecolor{light-green}{HTML}{6bab5b} +\definecolor{dark-green}{HTML}{3b972e} +\definecolor{light-purple}{HTML}{aa7dc0} +\definecolor{dark-purple}{HTML}{945bb0} +% + +% maths +\usepackage{amsmath, amssymb} +% + +% listings +\usepackage{listings, minted} + +\lstset{ + basicstyle = \small\ttfamily, + breaklines = true, + columns = fullflexible, + frame = leftline, + keepspaces = true, + showstringspaces = false, + xleftmargin = 3pt, +} + +\setminted{ + breaklines = true, + fontsize = \small, + frame = leftline, +} +% + +% tables +\usepackage{tabulary} +% + +% hyperref +\usepackage{hyperref} +\hypersetup{ + pdfpagelabels, + bookmarks, + hyperindex, + unicode = true, + linkcolor = dark-blue, + urlcolor = dark-purple, + colorlinks = true, +} +% + +% table of contents +\maxtocdepth{subsection} +% + +% paragraphs +\setlength{\parindent}{0pt} +\nonzeroparskip +% + +% adjust margins +\setulmarginsandblock{1.5in}{1in}{*} +\setlrmarginsandblock{1.5in}{1in}{*} +\setheaderspaces{1in}{*}{*} +\checkandfixthelayout +% diff --git a/embedded/Documenter.jl-0.20.0/assets/mkdocs/Documenter.css b/embedded/Documenter.jl-0.20.0/assets/mkdocs/Documenter.css new file mode 100644 index 0000000..f7ae84a --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/assets/mkdocs/Documenter.css @@ -0,0 +1,18 @@ +div.wy-menu-vertical ul.current li.toctree-l3 a { + font-weight: bold; +} + +a.documenter-source { + float: right; +} + +.documenter-methodtable pre { + margin-left: 0px; + margin-right: 0px; + margin-top: 0px; + padding: 0px; +} + +.documenter-methodtable pre.documenter-inline { + display: inline; +} diff --git a/embedded/Documenter.jl-0.20.0/assets/mkdocs/mathjaxhelper.js b/embedded/Documenter.jl-0.20.0/assets/mkdocs/mathjaxhelper.js new file mode 100644 index 0000000..3561b10 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/assets/mkdocs/mathjaxhelper.js @@ -0,0 +1,25 @@ +MathJax.Hub.Config({ + "tex2jax": { + inlineMath: [['$','$'], ['\\(','\\)']], + processEscapes: true + } +}); +MathJax.Hub.Config({ + config: ["MMLorHTML.js"], + jax: [ + "input/TeX", + "output/HTML-CSS", + "output/NativeMML" + ], + extensions: [ + "MathMenu.js", + "MathZoom.js", + "TeX/AMSmath.js", + "TeX/AMSsymbols.js", + "TeX/autobold.js", + "TeX/autoload-all.js" + ] +}); +MathJax.Hub.Config({ + TeX: { equationNumbers: { autoNumber: "AMS" } } +}); diff --git a/embedded/Documenter.jl-0.20.0/coverage/Project.toml b/embedded/Documenter.jl-0.20.0/coverage/Project.toml new file mode 100644 index 0000000..4fbdc47 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/coverage/Project.toml @@ -0,0 +1,2 @@ +[deps] +Coverage = "a2441757-f6aa-5fb2-8edb-039e3f45d037" diff --git a/embedded/Documenter.jl-0.20.0/coverage/coverage.jl b/embedded/Documenter.jl-0.20.0/coverage/coverage.jl new file mode 100644 index 0000000..c15a01c --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/coverage/coverage.jl @@ -0,0 +1,9 @@ +# Only run coverage from linux nightly build on travis. +get(ENV, "TRAVIS_OS_NAME", "") == "linux" || exit() +get(ENV, "TRAVIS_JULIA_VERSION", "") == "nightly" || exit() + +using Coverage + +cd(joinpath(dirname(@__FILE__), "..")) do + Codecov.submit(Codecov.process_folder()) +end diff --git a/embedded/Documenter.jl-0.20.0/docs/Manifest.toml b/embedded/Documenter.jl-0.20.0/docs/Manifest.toml new file mode 100644 index 0000000..849bca9 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/Manifest.toml @@ -0,0 +1,81 @@ +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.5.0" + +[[DocumenterTools]] +deps = ["Base64", "DocStringExtensions", "LibGit2"] +git-tree-sha1 = "519f8026e8f719ec018b70cfb394ae3756b427b1" +repo-rev = "master" +repo-url = "https://github.com/JuliaDocs/DocumenterTools.jl" +uuid = "46bb7b6e-9a58-11e8-21f8-9f2f45a0fcba" +version = "0.0.0" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/embedded/Documenter.jl-0.20.0/docs/Project.toml b/embedded/Documenter.jl-0.20.0/docs/Project.toml new file mode 100644 index 0000000..359718f --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/Project.toml @@ -0,0 +1,2 @@ +[deps] +DocumenterTools = "46bb7b6e-9a58-11e8-21f8-9f2f45a0fcba" diff --git a/embedded/Documenter.jl-0.20.0/docs/make.jl b/embedded/Documenter.jl-0.20.0/docs/make.jl new file mode 100644 index 0000000..7ca2870 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/make.jl @@ -0,0 +1,56 @@ +using Documenter, DocumenterTools + +makedocs( + modules = [Documenter, DocumenterTools], + clean = false, + assets = ["assets/favicon.ico"], + sitename = "Documenter.jl", + authors = "Michael Hatherly, Morten Piibeleht, and contributors.", + analytics = "UA-89508993-1", + linkcheck = !("skiplinks" in ARGS), + pages = [ + "Home" => "index.md", + "Manual" => Any[ + "Guide" => "man/guide.md", + "man/examples.md", + "man/syntax.md", + "man/doctests.md", + "man/latex.md", + hide("man/hosting.md", [ + "man/hosting/walkthrough.md" + ]), + "man/other-formats.md", + ], + "Library" => Any[ + "Public" => "lib/public.md", + hide("Internals" => "lib/internals.md", Any[ + "lib/internals/anchors.md", + "lib/internals/builder.md", + "lib/internals/cross-references.md", + "lib/internals/docchecks.md", + "lib/internals/docsystem.md", + "lib/internals/doctests.md", + "lib/internals/documenter.md", + "lib/internals/documentertools.md", + "lib/internals/documents.md", + "lib/internals/dom.md", + "lib/internals/expanders.md", + "lib/internals/formats.md", + "lib/internals/mdflatten.md", + "lib/internals/selectors.md", + "lib/internals/textdiff.md", + "lib/internals/utilities.md", + "lib/internals/writers.md", + ]) + ], + "contributing.md", + ], + # Use clean URLs, unless built as a "local" build + html_prettyurls = !("local" in ARGS), + html_canonical = "https://juliadocs.github.io/Documenter.jl/stable/", +) + +deploydocs( + repo = "github.com/JuliaDocs/Documenter.jl.git", + target = "build", +) diff --git a/embedded/Documenter.jl-0.20.0/docs/src/assets/favicon.ico b/embedded/Documenter.jl-0.20.0/docs/src/assets/favicon.ico new file mode 100644 index 0000000..d793195 Binary files /dev/null and b/embedded/Documenter.jl-0.20.0/docs/src/assets/favicon.ico differ diff --git a/embedded/Documenter.jl-0.20.0/docs/src/assets/logo.png b/embedded/Documenter.jl-0.20.0/docs/src/assets/logo.png new file mode 100644 index 0000000..3c0c8a1 Binary files /dev/null and b/embedded/Documenter.jl-0.20.0/docs/src/assets/logo.png differ diff --git a/embedded/Documenter.jl-0.20.0/docs/src/contributing.md b/embedded/Documenter.jl-0.20.0/docs/src/contributing.md new file mode 100644 index 0000000..51f7432 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/contributing.md @@ -0,0 +1,59 @@ +# Contributing + +This page details the some of the guidelines that should be followed when contributing to this package. + + +## Branches + +From `Documenter` version `0.3` onwards `release-*` branches are used for tagged minor versions of this package. This follows the same approach used in the main Julia repository, albeit on a much more modest scale. + +Please open pull requests against the `master` branch rather than any of the `release-*` branches whenever possible. + +### Backports + +Bug fixes are backported to the `release-*` branches using `git cherry-pick -x` by a JuliaDocs member and will become available in point releases of that particular minor version of the package. + +Feel free to nominate commits that should be backported by opening an issue. Requests for new point releases to be tagged in `METADATA.jl` can also be made in the same way. + +### `release-*` branches + + * Each new minor version `x.y.0` gets a branch called `release-x.y` (a [protected branch](https://help.github.com/articles/about-protected-branches/)). + * New versions are usually tagged only from the `release-x.y` branches. + * For patch releases, changes get backported to the `release-x.y` branch via a single PR with the standard name "Backports for x.y.z" and label ["Type: Backport"](https://github.com/JuliaDocs/Documenter.jl/pulls?q=label%3A%22Type%3A+Backport%22). The PR message links to all the PRs that are providing commits to the backport. The PR gets merged as a merge commit (i.e. not squashed). + * The old `release-*` branches may be removed once they have outlived their usefulness. + * Patch version [milestones](https://github.com/JuliaDocs/Documenter.jl/milestones) are used to keep track of which PRs get backported etc. + + +## Style Guide + +Follow the style of the surrounding text when making changes. When adding new features please try to stick to the following points whenever applicable. + +### Julia + + * 4-space indentation; + * modules spanning entire files should not be indented, but modules that have surrounding code should; + * no blank lines at the start or end of files; + * do not manually align syntax such as `=` or `::` over adjacent lines; + * use `function ... end` when a method definition contains more than one toplevel expression; + * related short-form method definitions don't need a new line between them; + * unrelated or long-form method definitions must have a blank line separating each one; + * surround all binary operators with whitespace except for `::`, `^`, and `:`; + * files containing a single `module ... end` must be named after the module; + * method arguments should be ordered based on the amount of usage within the method body; + * methods extended from other modules must follow their inherited argument order, not the above rule; + * explicit `return` should be preferred except in short-form method definitions; + * avoid dense expressions where possible e.g. prefer nested `if`s over complex nested `?`s; + * include a trailing `,` in vectors, tuples, or method calls that span several lines; + * do not use multiline comments (`#=` and `=#`); + * wrap long lines as near to 92 characters as possible, this includes docstrings; + * follow the standard naming conventions used in `Base`. + +### Markdown + + * Use unbalanced `#` headers, i.e. no `#` on the right hand side of the header text; + * include a single blank line between toplevel blocks; + * unordered lists must use `*` bullets with two preceding spaces; + * do *not* hard wrap lines; + * use emphasis (`*`) and bold (`**`) sparingly; + * always use fenced code blocks instead of indented blocks; + * follow the conventions outlined in the Julia documentation page on documentation. diff --git a/embedded/Documenter.jl-0.20.0/docs/src/index.md b/embedded/Documenter.jl-0.20.0/docs/src/index.md new file mode 100644 index 0000000..8a5b50c --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/index.md @@ -0,0 +1,57 @@ +# Documenter.jl + +*A documentation generator for Julia.* + +A package for building documentation from docstrings and markdown files. + +!!! note + + Please read through the + [Documentation](https://docs.julialang.org/en/latest/manual/documentation/) section + of the main Julia manual if this is your first time using Julia's documentation system. + Once you've read through how to write documentation for your code then come back here. + +## Package Features + +- Write all your documentation in [Markdown](https://en.wikipedia.org/wiki/Markdown). +- Minimal configuration. +- Supports Julia `0.7` and `1.0`. +- Doctests Julia code blocks. +- Cross references for docs and section headers. +- [``\LaTeX`` syntax](@ref latex_syntax) support. +- Checks for missing docstrings and incorrect cross references. +- Generates tables of contents and docstring indexes. +- Automatically builds and deploys docs from Travis to GitHub Pages. + +The [Package Guide](@ref) provides a tutorial explaining how to get started using Documenter. + +Some examples of packages using Documenter can be found on the [Examples](@ref) page. + +See the [Index](@ref main-index) for the complete list of documented functions and types. + +## Manual Outline + +```@contents +Pages = [ + "man/guide.md", + "man/examples.md", + "man/syntax.md", + "man/doctests.md", + "man/hosting.md", + "man/latex.md", + "man/contributing.md", +] +Depth = 1 +``` + +## Library Outline + +```@contents +Pages = ["lib/public.md", "lib/internals.md"] +``` + +### [Index](@id main-index) + +```@index +Pages = ["lib/public.md"] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals.md new file mode 100644 index 0000000..b78ce0e --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals.md @@ -0,0 +1,17 @@ +# Internal Documentation + +This page lists all the documented internals of the `Documenter` module and submodules. + +## Contents + +```@contents +Pages = [joinpath("internals", f) for f in readdir("internals")] +``` + +## Index + +A list of all internal documentation sorted by module. + +```@index +Pages = [joinpath("internals", f) for f in readdir("internals")] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/anchors.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/anchors.md new file mode 100644 index 0000000..9d8fa23 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/anchors.md @@ -0,0 +1,5 @@ +# Anchors + +```@autodocs +Modules = [Documenter.Anchors] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/builder.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/builder.md new file mode 100644 index 0000000..366b6cd --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/builder.md @@ -0,0 +1,5 @@ +# Builder + +```@autodocs +Modules = [Documenter.Builder] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/cross-references.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/cross-references.md new file mode 100644 index 0000000..4a05a0e --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/cross-references.md @@ -0,0 +1,5 @@ +# CrossReferences + +```@autodocs +Modules = [Documenter.CrossReferences] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/docchecks.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/docchecks.md new file mode 100644 index 0000000..229bd18 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/docchecks.md @@ -0,0 +1,5 @@ +# DocChecks + +```@autodocs +Modules = [Documenter.DocChecks] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/docsystem.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/docsystem.md new file mode 100644 index 0000000..39f1be3 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/docsystem.md @@ -0,0 +1,5 @@ +# DocSystem + +```@autodocs +Modules = [Documenter.DocSystem] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/doctests.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/doctests.md new file mode 100644 index 0000000..d2ef53d --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/doctests.md @@ -0,0 +1,5 @@ +# DocTests + +```@autodocs +Modules = [Documenter.DocTests] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/documenter.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/documenter.md new file mode 100644 index 0000000..de28117 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/documenter.md @@ -0,0 +1,6 @@ +# Documenter + +```@docs +Documenter.gitrm_copy +Documenter.git_push +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/documentertools.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/documentertools.md new file mode 100644 index 0000000..ba3966f --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/documentertools.md @@ -0,0 +1,11 @@ +# DocumenterTools + +```@docs +DocumenterTools.package_devpath +``` + +## Generator + +```@autodocs +Modules = [DocumenterTools.Generator] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/documents.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/documents.md new file mode 100644 index 0000000..4589b71 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/documents.md @@ -0,0 +1,5 @@ +# Documents + +```@autodocs +Modules = [Documenter.Documents] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/dom.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/dom.md new file mode 100644 index 0000000..ce03071 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/dom.md @@ -0,0 +1,5 @@ +# DOM + +```@autodocs +Modules = [Documenter.Utilities.DOM] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/expanders.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/expanders.md new file mode 100644 index 0000000..605a98b --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/expanders.md @@ -0,0 +1,5 @@ +# Expanders + +```@autodocs +Modules = [Documenter.Expanders] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/formats.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/formats.md new file mode 100644 index 0000000..baaedd5 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/formats.md @@ -0,0 +1,5 @@ +# Formats + +```@autodocs +Modules = [Documenter.Formats] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/mdflatten.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/mdflatten.md new file mode 100644 index 0000000..cc46364 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/mdflatten.md @@ -0,0 +1,5 @@ +# MDFlatten + +```@autodocs +Modules = [Documenter.Utilities.MDFlatten] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/selectors.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/selectors.md new file mode 100644 index 0000000..56e4fea --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/selectors.md @@ -0,0 +1,5 @@ +# Selectors + +```@autodocs +Modules = [Documenter.Selectors] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/textdiff.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/textdiff.md new file mode 100644 index 0000000..2c6b6fd --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/textdiff.md @@ -0,0 +1,5 @@ +# TextDiff + +```@autodocs +Modules = [Documenter.Utilities.TextDiff] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/utilities.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/utilities.md new file mode 100644 index 0000000..cc94038 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/utilities.md @@ -0,0 +1,5 @@ +# Utilities + +```@autodocs +Modules = [Documenter.Utilities] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/writers.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/writers.md new file mode 100644 index 0000000..3333376 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/internals/writers.md @@ -0,0 +1,10 @@ +# Writers + +```@autodocs +Modules = [ + Documenter.Writers, + Documenter.Writers.MarkdownWriter, + Documenter.Writers.HTMLWriter, + Documenter.Writers.LaTeXWriter, +] +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/lib/public.md b/embedded/Documenter.jl-0.20.0/docs/src/lib/public.md new file mode 100644 index 0000000..f0ebbd3 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/lib/public.md @@ -0,0 +1,36 @@ +# Public Documentation + +Documentation for `Documenter.jl`'s public interface. + +See [Internal Documentation](@ref) for internal package docs covering all submodules. + +## Contents + +```@contents +Pages = ["public.md"] +``` + +## Index + +```@index +Pages = ["public.md"] +``` + +## Public Interface + +```@docs +Documenter +makedocs +hide +deploydocs +Deps +Deps.pip +``` + +## DocumenterTools + +```@docs +DocumenterTools.generate +DocumenterTools.Travis.genkeys +DocumenterTools.Travis +``` diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/doctests.md b/embedded/Documenter.jl-0.20.0/docs/src/man/doctests.md new file mode 100644 index 0000000..aacc188 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/man/doctests.md @@ -0,0 +1,310 @@ +# Doctests + +Documenter will, by default, try to run `jldoctest` code blocks that it finds in the generated +documentation. This can help to avoid documentation examples from becoming outdated, +incorrect, or misleading. It's recommended that as many of a package's examples be runnable +by Documenter's doctest. + +This section of the manual outlines how to go about enabling doctests for code blocks in +your package's documentation. + +## "Script" Examples + +The first, of two, types of doctests is the "script" code block. To make Documenter detect +this kind of code block the following format must be used: + +````markdown +```jldoctest +a = 1 +b = 2 +a + b + +# output + +3 +``` +```` + +The code block's "language" must be `jldoctest` and must include a line containing the text `# +output`. The text before this line is the contents of the script which is run. The text that +appears after `# output` is the textual representation that would be shown in the Julia REPL +if the script had been `include`d. + +The actual output produced by running the "script" is compared to the expected result and +any difference will result in [`makedocs`](@ref) throwing an error and terminating. + +Note that the amount of whitespace appearing above and below the `# output` line is not +significant and can be increased or decreased if desired. + +It is possible to suppress the output from the doctest by setting the `output` keyword +argument to `false`, for example + +````markdown +```jldoctest; output = false +a = 1 +b = 2 +a + b + +# output + +3 +``` +```` + +Note that the output of the script will still be compared to the expected result, +i.e. what is `# output` section, but the `# output` section will be suppressed in +the rendered documentation. + +## REPL Examples + +The other kind of doctest is a simulated Julia REPL session. The following format is +detected by Documenter as a REPL doctest: + +````markdown +```jldoctest +julia> a = 1 +1 + +julia> b = 2; + +julia> c = 3; # comment + +julia> a + b + c +6 +``` +```` + +As with script doctests, the code block must have it's language set to `jldoctest`. When a code +block contains one or more `julia> ` at the start of a line then it is assumed to be a REPL +doctest. Semi-colons, `;`, at the end of a line works in the same way as in the Julia REPL +and will suppress the output, although the line is still evaluated. + +Note that not all features of the REPL are supported such as shell and help modes. + +## Exceptions + +Doctests can also test for thrown exceptions and their stacktraces. Comparing of the actual +and expected results is done by checking whether the expected result matches the start of +the actual result. Hence, both of the following errors will match the actual result. + +````markdown +```jldoctest +julia> div(1, 0) +ERROR: DivideError: integer division error + in div(::Int64, ::Int64) at ./int.jl:115 + +julia> div(1, 0) +ERROR: DivideError: integer division error +``` +```` + +If instead the first `div(1, 0)` error was written as + +````markdown +```jldoctest +julia> div(1, 0) +ERROR: DivideError: integer division error + in div(::Int64, ::Int64) at ./int.jl:114 +``` +```` + +where line `115` is replaced with `114` then the doctest will fail. + +In the second `div(1, 0)`, where no stacktrace is shown, it may appear to the reader that +it is expected that no stacktrace will actually be displayed when they attempt to try to +recreate the error themselves. To indicate to readers that the output result is truncated +and does not display the entire (or any of) the stacktrace you may write `[...]` at the +line where checking should stop, i.e. + +````markdown +```jldoctest +julia> div(1, 0) +ERROR: DivideError: integer division error +[...] +``` +```` + +## Preserving Definitions Between Blocks + +Every doctest block is evaluated inside its own `module`. This means that definitions +(types, variables, functions etc.) from a block can *not* be used in the next block. +For example: + +````markdown +```jldoctest +julia> foo = 42 +42 +``` +```` + +The variable `foo` will not be defined in the next block: + +````markdown +```jldoctest +julia> println(foo) +ERROR: UndefVarError: foo not defined +``` +```` + +To preserve definitions it is possible to label blocks in order to collect several blocks +into the same module. All blocks with the same label (in the same file) will be evaluated +in the same module, and hence share scope. This can be useful if the same definitions are +used in more than one block, with for example text, or other doctest blocks, in between. +Example: + +````markdown +```jldoctest mylabel +julia> foo = 42 +42 +``` +```` + +Now, since the block below has the same label as the block above, the variable `foo` can +be used: + +````markdown +```jldoctest mylabel +julia> println(foo) +42 +``` +```` + +!!! note + + Labeled doctest blocks does not need to be consecutive (as in the example above) to be + included in the same module. They can be interspaced with unlabeled blocks or blocks + with another label. + +## Setup Code + +Doctests may require some setup code that must be evaluated prior to that of the actual +example, but that should not be displayed in the final documentation. For this purpose a +`@meta` block containing a `DocTestSetup = ...` value can be used. In the example below, +the function `foo` is defined inside a `@meta` block. This block will be evaluated at +the start of the following doctest blocks: + +````markdown +```@meta +DocTestSetup = quote + function foo(x) + return x^2 + end +end +``` + +```jldoctest +julia> foo(2) +4 +``` + +```@meta +DocTestSetup = nothing +``` +```` + +The `DocTestSetup = nothing` is not strictly necessary, but good practice nonetheless to +help avoid unintentional definitions in following doctest blocks. + +Another option is to use the `setup` keyword argument, which is convenient for short definitions, +and for setups needed in inline docstrings. + +````markdown +```jldoctest; setup = :(foo(x) = x^2) +julia> foo(2) +4 +``` +```` + +!!! note + + The `DocTestSetup` and the `setup` values are **re-evaluated** at the start of *each* doctest block + and no state is shared between any code blocks. + To preserve definitions see [Preserving Definitions Between Blocks](@ref). + +## Filtering Doctests + +A part of the output of a doctest might be non-deterministic, e.g. pointer addresses and timings. +It is therefore possible to filter a doctest so that the deterministic part can still be tested. + +A filter takes the form of a regular expression. +In a doctest, each match in the expected output and the actual output is removed before the two outputs are compared. +Filters are added globally, i.e. applied to all doctests in the documentation, by passing a list of regular expressions to +`makedocs` with the keyword `doctestfilters`. + +For more fine grained control it is possible to define filters in `@meta` blocks by assigning them +to the `DocTestFilters` variable, either as a single regular expression (`DocTestFilters = [r"foo"]`) +or as a vector of several regex (`DocTestFilters = [r"foo", r"bar"]`). + +An example is given below where some of the non-deterministic output from `@time` is filtered. + +````markdown +```@meta +DocTestFilters = r"[0-9\.]+ seconds \(.*\)" +``` + +```jldoctest +julia> @time [1,2,3,4] + 0.000003 seconds (5 allocations: 272 bytes) +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` + +```@meta +DocTestFilters = nothing +``` +```` + +The `DocTestFilters = nothing` is not strictly necessary, but good practice nonetheless to +help avoid unintentional filtering in following doctest blocks. + +Another option is to use the `filter` keyword argument. This defines a doctest-local filter +which is only active for the specific doctest. Note that such filters are not shared between +named doctests either. It is possible to define a filter by a single regex (filter = r"foo") +or as a list of regex (filter = [r"foo", r"bar"]). Example: + +````markdown +```jldoctest; filter = r"[0-9\.]+ seconds \(.*\)" +julia> @time [1,2,3,4] + 0.000003 seconds (5 allocations: 272 bytes) +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```` + +!!! note + + The global filters, filters defined in `@meta` blocks, and filters defined with the `filter` + keyword argument are all applied to each doctest. + +## Fixing Outdated Doctests + +To fix outdated doctests, the `doctest` flag to [`makedocs`](@ref) can be set to +`doctest = :fix`. This will run the doctests, and overwrite the old results with +the new output. + +!!! note + + The `:fix` option currently only works for LF line endings (`'\n'`) + +!!! note + + It is recommended to `git commit` any code changes before running the doctest fixing. + That way it is simple to restore to the previous state if the fixing goes wrong. + +!!! note + + There are some corner cases where the fixing algorithm may replace the wrong code snippet. + It is therefore recommended to manually inspect the result of the fixing before committing. + + +## Skipping Doctests + +Doctesting can be disabled by setting the [`makedocs`](@ref) keyword `doctest = false`. +This should only be done when initially laying out the structure of a package's +documentation, after which it's encouraged to always run doctests when building docs. diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/examples.md b/embedded/Documenter.jl-0.20.0/docs/src/man/examples.md new file mode 100644 index 0000000..7319cb8 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/man/examples.md @@ -0,0 +1,67 @@ +# Examples + +Sometimes the best way to learn how to use a new package is to look for +examples of what others have already built with it. + +The following packages use Documenter to build their documentation and so +should give a good overview of what this package is currently able to do. + +!!! note + + Packages are listed alphabetically. If you have a package that uses Documenter then + please open a PR that adds it to the appropriate list below; a simple way to do so + is to navigate to + https://github.com/JuliaDocs/Documenter.jl/edit/master/docs/src/man/examples.md. + + The `make.jl` file for all listed packages will be tested to check for potential + regressions prior to tagging new Documenter releases whenever possible. + +## Registered + +Packages that have tagged versions available in `METADATA.jl`. + +- [Augmentor.jl](https://evizero.github.io/Augmentor.jl/) +- [BanditOpt.jl](https://v-i-s-h.github.io/BanditOpt.jl/latest/) +- [BeaData.jl](https://stephenbnicar.github.io/BeaData.jl/latest/) +- [Bio.jl](https://biojulia.net/Bio.jl/latest/) +- [ControlSystems.jl](http://juliacontrol.github.io/ControlSystems.jl/latest/) +- [Currencies.jl](https://juliafinance.github.io/Currencies.jl/latest/) +- [DiscretePredictors.jl](https://github.com/v-i-s-h/DiscretePredictors.jl) +- [Documenter.jl](https://juliadocs.github.io/Documenter.jl/latest/) +- [EvolvingGraphs.jl](https://etymoio.github.io/EvolvingGraphs.jl/latest/) +- [ExtractMacro.jl](https://carlobaldassi.github.io/ExtractMacro.jl/latest/) +- [EzXML.jl](https://bicycle1885.github.io/EzXML.jl/latest/) +- [FourierFlows.jl](https://FourierFlows.github.io/FourierFlows.jl/latest/) +- [Gadfly.jl](http://gadflyjl.org/stable/) +- [GeoStats.jl](http://juliohm.github.io/GeoStats.jl/latest/) +- [Highlights.jl](https://juliadocs.github.io/Highlights.jl/latest/) +- [IntervalConstraintProgramming.jl](https://juliaintervals.github.io/IntervalConstraintProgramming.jl/latest/) +- [Luxor.jl](https://juliagraphics.github.io/Luxor.jl/stable/) +- [MergedMethods.jl](https://michaelhatherly.github.io/MergedMethods.jl/latest/) +- [Mimi.jl](http://anthofflab.berkeley.edu/Mimi.jl/stable/) +- [NumericSuffixes.jl](https://michaelhatherly.github.io/NumericSuffixes.jl/latest/) +- [OhMyREPL.jl](https://github.com/KristofferC/OhMyREPL.jl) +- [OnlineStats.jl](http://joshday.github.io/OnlineStats.jl/latest/) +- [POMDPs.jl](http://juliapomdp.github.io/POMDPs.jl/latest/) +- [PhyloNetworks.jl](http://crsl4.github.io/PhyloNetworks.jl/latest/) +- [PrivateModules.jl](https://michaelhatherly.github.io/PrivateModules.jl/latest/) +- [Query.jl](http://www.queryverse.org/Query.jl/stable/) +- [TaylorSeries.jl](http://www.juliadiff.org/TaylorSeries.jl/latest/) +- [Weave.jl](http://weavejl.mpastell.com/stable/) + +## Documentation repositories + +Some projects or organizations maintain dedicated documentation repositories that are +separate from specific packages. + +- [DifferentialEquations.jl](http://docs.juliadiffeq.org/latest/) +- [JuliaDocs landing page](https://juliadocs.github.io/latest/) +- [JuliaMusic](https://juliamusic.github.io/JuliaMusic_documentation.jl/latest/) +- [Plots.jl](https://docs.juliaplots.org/latest/) + +## Unregistered + +Packages that are not available in `METADATA.jl` and may be works-in-progress. +Please do take that into consideration when browsing this list. + +- [AnonymousTypes.jl](https://michaelhatherly.github.io/AnonymousTypes.jl/latest/) diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/guide.md b/embedded/Documenter.jl-0.20.0/docs/src/man/guide.md new file mode 100644 index 0000000..322d91b --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/man/guide.md @@ -0,0 +1,327 @@ +# Package Guide + +Documenter is designed to do one thing -- combine markdown files and inline docstrings from +Julia's docsystem into a single inter-linked document. What follows is a step-by-step guide +to creating a simple document. + + +## Installation + +Documenter can be installed using the Julia package manager. +From the Julia REPL, type `]` to enter the Pkg REPL mode and run + +``` +pkg> add Documenter +``` + + +## Setting up the Folder Structure + +!!! note + The function [`DocumenterTools.generate`](@ref) from the `DocumenterTools` package + can generate the basic structure that Documenter expects. + +Firstly, we need a Julia module to document. This could be a package generated via +`PkgDev.generate` or a single `.jl` script accessible via Julia's `LOAD_PATH`. For this +guide we'll be using a package called `Example.jl` that has the following directory layout: + +``` +Example/ + src/ + Example.jl + ... +``` + +Note that the `...` just represent unimportant files and folders. + +We must decide on a location where we'd like to store the documentation for this package. +It's recommended to use a folder named `docs/` in the toplevel of the package, like so + +``` +Example/ + docs/ + ... + src/ + Example.jl + ... +``` + +Inside the `docs/` folder we need to add two things. A source folder which will contain the +markdown files that will be used to build the finished document and a Julia script that will +be used to control the build process. The following names are recommended + +``` +docs/ + src/ + make.jl +``` + + +## Building an Empty Document + +With our `docs/` directory now setup we're going to build our first document. It'll just be +a single empty file at the moment, but we'll be adding to it later on. + +Add the following to your `make.jl` file + +```julia +using Documenter, Example + +makedocs(sitename="My Documentation") +``` + +This assumes you've installed Documenter as discussed in [Installation](@ref) and that your +`Example.jl` package can be found by Julia. + +!!! note + + If your source directory is not accessible through Julia's LOAD_PATH, you might wish to + add the following line at the top of make.jl + + ```julia + push!(LOAD_PATH,"../src/") + ``` + +Now add an `index.md` file to the `src/` directory. The name has no particular significance +though and you may name it whatever you like. We'll stick to `index.md` for this guide. + +Leave the newly added file empty and then run the following command from the `docs/` directory + +```sh +$ julia make.jl +``` + +Note that `$` just represents the prompt character. You don't need to type that. + +If you'd like to see the output from this command in color use + +```sh +$ julia --color=yes make.jl +``` + +When you run that you should see the following output + +``` +Documenter: setting up build directory. +Documenter: expanding markdown templates. +Documenter: building cross-references. +Documenter: running document checks. + > checking for missing docstrings. + > running doctests. + > checking footnote links. +Documenter: populating indices. +Documenter: rendering document. +``` + +The `docs/` folder should contain a new directory -- called `build/`. It's structure should +look like the following + +``` +build/ + assets/ + arrow.svg + documenter.css + documenter.js + search.js + index.html + search.html + search_index.js +``` + +!!! warning + + **Never** `git commit` the contents of `build` (or any other content generated by + Documenter) to your repository's `master` branch. Always commit generated files to the + `gh-pages` branch of your repository. This helps to avoid including unnecessary changes + for anyone reviewing commits that happen to include documentation changes. + + See the [Hosting Documentation](@ref) section for details regarding how you should go + about setting this up correctly. + +At this point `build/index.html` should be an empty page since `src/index.md` is empty. You +can try adding some text to `src/index.md` and re-running the `make.jl` file to see the +changes. + + +## Adding Some Docstrings + +Next we'll splice a docstring defined in the `Example` module into the `index.md` file. To +do this first document a function in that module: + +```julia +module Example + +export func + +""" + func(x) + +Returns double the number `x` plus `1`. +""" +func(x) = 2x + 1 + +end +``` + +Then in the `src/index.md` file add the following + +````markdown +# Example.jl Documentation + +```@docs +func(x) +``` +```` + +When we next run `make.jl` the docstring for `Example.func(x)` should appear in place of +the `@docs` block in `build/index.md`. Note that *more than one* object can be referenced +inside a `@docs` block -- just place each one on a separate line. + +Note that a `@docs` block is evaluated in the `Main` module. This means that each object +listed in the block must be visible there. The module can be changed to something else on +a per-page basis with a `@meta` block as in the following + +````markdown +# Example.jl Documentation + +```@meta +CurrentModule = Example +``` + +```@docs +func(x) +``` +```` + +### Filtering included docstrings + +In some cases you may want to include a docstring for a `Method` that extends a +`Function` from a different module -- such as `Base`. In the following example we extend +`Base.length` with a new definition for the struct `T` and also add a docstring: + +```julia +struct T + # ... +end + +""" +Custom `length` docs for `T`. +""" +Base.length(::T) = 1 +``` + +When trying to include this docstring with + +````markdown +```@docs +length +``` +```` + +all the docs for `length` will be included -- even those from other modules. There are two +ways to solve this problem. Either include the type in the signature with + +````markdown +```@docs +length(::T) +``` +```` + +or declare the specific modules that [`makedocs`](@ref) should include with + +```julia +makedocs( + # options + modules = [MyModule] +) +``` + + +## Cross Referencing + +It may be necessary to refer to a particular docstring or section of your document from +elsewhere in the document. To do this we can make use of Documenter's cross-referencing +syntax which looks pretty similar to normal markdown link syntax. Replace the contents of +`src/index.md` with the following + +````markdown +# Example.jl Documentation + +```@docs +func(x) +``` + +- link to [Example.jl Documentation](@ref) +- link to [`func(x)`](@ref) +```` + +So we just have to replace each link's url with `@ref` and write the name of the thing we'd +link to cross-reference. For document headers it's just plain text that matches the name of +the header and for docstrings enclose the object in backticks. + +This also works across different pages in the same way. Note that these sections and +docstrings must be unique within a document. + + +## Navigation + +Documenter can auto-generate tables of contents and docstring indexes for your document with +the following syntax. We'll illustrate these features using our `index.md` file from the +previous sections. Add the following to that file + +````markdown +# Example.jl Documentation + +```@contents +``` + +## Functions + +```@docs +func(x) +``` + +## Index + +```@index +``` +```` + +The `@contents` block will generate a nested list of links to all the section headers in +the document. By default it will gather all the level 1 and 2 headers from every page in the +document, but this can be adjusted using `Pages` and `Depth` settings as in the following + +````markdown +```@contents +Pages = ["foo.md", "bar.md"] +Depth = 3 +``` +```` + +The `@index` block will generate a flat list of links to all the docs that that have been +spliced into the document using `@docs` blocks. As with the `@contents` block the pages to +be included can be set with a `Pages = [...]` line. Since the list is not nested `Depth` is +not supported for `@index`. + + +## Pages in the Sidebar + +By default all the pages (`.md` files) in your source directory get added to the sidebar, +sorted by their filenames. However, in most cases you want to use the `pages` argument to +[`makedocs`](@ref) to control how the sidebar looks like. The basic usage is as follows: + +```julia +makedocs( + ..., + pages = [ + "page.md", + "Page title" => "page2.md", + "Subsection" => [ + ... + ] + ] +) +``` + +Using the `pages` argument you can organize your pages into subsections and hide some pages +from the sidebar with the help of the [`hide`](@ref) functions. diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/hosting.md b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting.md new file mode 100644 index 0000000..1787afc --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting.md @@ -0,0 +1,262 @@ +# Hosting Documentation + +After going through the [Package Guide](@ref) and [Doctests](@ref) page you will need to +host the generated documentation somewhere for potential users to read. This guide will +describe how to setup automatic updates for your package docs using the Travis build service +and GitHub Pages. This is the same approach used by this package to host its own docs -- +the docs you're currently reading. + +!!! note + + Following this guide should be the *final* step you take after you are comfortable with + the syntax and build process used by `Documenter.jl`. It is recommended that you only + proceed with the steps outlined here once you have successfully managed to build your + documentation locally with Documenter. + + This guide assumes that you already have [GitHub](https://github.com/) and + [Travis](https://travis-ci.com/) accounts setup. If not then go set those up first and + then return here. + + +## Overview + +Once set up correctly, the following will happen each time you push new updates to your +package repository: + +- Travis buildbots will start up and run your package tests in a "Test" stage. +- After the Test stage completes, a single bot will run a new "Documentation" stage, which + will build the documentation. +- If the documentation is built successfully, the bot will attempt to push the generated + HTML pages back to GitHub. + +Note that the hosted documentation does not update when you make pull requests; you see +updates only when you merge to `master` or push new tags. + +The following sections outline how to enable this for your own package. + + +## SSH Deploy Keys + +Deploy keys provide push access to a *single* repository, to allow secure deployment of +generated documentation from Travis to GitHub. The SSH keys can be generated with the +`Travis.genkeys` from the [DocumenterTools](https://github.com/JuliaDocs/DocumenterTools.jl) +package. + +!!! note + + You will need several command line programs (`which`, `git` and `ssh-keygen`) to be + installed for the following steps to work. If DocumenterTools fails, please see the the + [SSH Deploy Keys Walkthrough](@ref) section for instruction on how to generate the keys + manually (including in Windows). + + +Install and load DocumenterTools with + +``` +pkg> add DocumenterTools +``` +```julia-repl +julia> using DocumenterTools +``` + +Then call the [`Travis.genkeys`](@ref) function as follows: + +```julia-repl +julia> using MyPackage +julia> Travis.genkeys(MyPackage) +``` + +where `MyPackage` is the name of the package you would like to create deploy keys for. The +output will look similar to the text below: + +``` +INFO: add the public key below to https://github.com/USER/REPO/settings/keys + with read/write access: + +[SSH PUBLIC KEY HERE] + +INFO: add a secure environment variable named 'DOCUMENTER_KEY' to + https://travis-ci.org/USER/REPO/settings with value: + +[LONG BASE64 ENCODED PRIVATE KEY] +``` + +Follow the instructions that are printed out, namely: + + 1. Add the public ssh key to your settings page for the GitHub repository that you are + setting up by following the `.../settings/key` link provided. Click on **`Add deploy + key`**, enter the name **`documenter`** as the title, and copy the public key into the + **`Key`** field. Check **`Allow write access`** to allow Documenter to commit the + generated documentation to the repo. + + 2. Next add the long private key to the Travis settings page using the provided link. Again + note that you should include **no whitespace** when copying the key. In the **`Environment + Variables`** section add a key with the name `DOCUMENTER_KEY` and the value that was printed + out. **Do not** set the variable to be displayed in the build log. Then click **`Add`**. + + !!! warning "Security warning" + + To reiterate: make sure that the "Display value in build log" option is **OFF** for + the variable, so that it does not get printed when the tests run. This + base64-encoded string contains the *unencrypted* private key that gives full write + access to your repository, so it must be kept safe. Also, make sure that you never + expose this variable in your tests, nor merge any code that does. You can read more + about Travis environment variables in [Travis User Documentation](https://docs.travis-ci.com/user/environment-variables/#Defining-Variables-in-Repository-Settings). + +!!! note + + There are more explicit instructions for adding the keys to GitHub and Travis in the + [SSH Deploy Keys Walkthrough](@ref) section of the manual. + +## `.travis.yml` Configuration + +To tell Travis that we want a new build stage we can add the following to the `.travis.yml` +file: + +```yaml +jobs: + include: + - stage: "Documentation" + julia: 1.0 + os: linux + script: + - julia --project=docs/ -e 'using Pkg; Pkg.instantiate(); + Pkg.develop(PackageSpec(path=pwd()))' + - julia --project=docs/ docs/make.jl + after_success: skip +``` + +where the `julia:` and `os:` entries decide the worker from which the docs are built and +deployed. In the example above we will thus build and deploy the documentation from a linux +worker running Julia 1.0. For more information on how to setup a build stage, see the Travis +manual for [Build Stages](https://docs.travis-ci.com/user/build-stages). + +The three lines in the `script:` section do the following: + + 1. Instantiate the doc-building environment (i.e. `docs/Project.toml`, see below). + 2. Install your package in the doc-build environment. + 3. Run the docs/make.jl script, which builds and deploys the documentation. + +The doc-build environment `docs/Project.toml` includes Documenter and other doc-build +dependencies your package might have. If Documenter is the only dependency, then the +`Project.toml` should include the following: + +```toml +[deps] +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" + +[compat] +Documenter = "~0.20" +``` + +Note that it is recommended that you have a `[compat]` section, like the one above, in your +`Project.toml` file, which would restrict Documenter's version that gets installed when the +build runs. This is to make sure that your builds do not start failing suddenly due to a new +major release of Documenter, which may include breaking changes. However, it also means that +you will not get updates to Documenter automatically, and hence need to upgrade Documenter's +major version yourself. + + +## The `deploydocs` Function + +At the moment your `docs/make.jl` file probably only contains + +```julia +using Documenter, PACKAGE_NAME + +makedocs() +``` + +We'll need to add an additional function call to this file after [`makedocs`](@ref) which +would perform the deployment of the docs to the `gh-pages` branch. +Add the following at the end of the file: + +```julia +deploydocs( + repo = "github.com/USER_NAME/PACKAGE_NAME.jl.git", +) +``` + +where `USER_NAME` and `PACKAGE_NAME` must be set to the appropriate names. +Note that `repo` should not specify any protocol, i.e. it should not begin with `https://` +or `git@`. + +See the [`deploydocs`](@ref) function documentation for more details. + + + +## `.gitignore` + +Add the following to your package's `.gitignore` file + +``` +docs/build/ +``` + +These are needed to avoid committing generated content to your repository. + +## `gh-pages` Branch + +By default, Documenter pushes documentation to the `gh-pages` branch. If the branch does not +exist it will be created automatically by [`deploydocs`](@ref). If does exist then +Documenter simply adds an additional commit with the built documentation. You should be +aware that Documenter may overwrite existing content without warning. + +If you wish to create the `gh-pages` branch manually the that can be done following +[these instructions](https://coderwall.com/p/0n3soa/create-a-disconnected-git-branch). + +## Documentation Versions + +The documentation is deployed as follows: + +- Documentation built for a tag `vX.Y.Z` will be stored in a folder `vX.Y.Z`. + +- Documentation built from the `devbranch` branch (`master` by default) is stored a folder + determined by the `devurl` keyword to [`deploydocs`](@ref) (`dev` by default). + +Which versions that will show up in the version selector is determined by the +`versions` argument to [`deploydocs`](@ref). + +Unless a custom domain is being used, the pages are found at: + +``` +https://USER_NAME.github.io/PACKAGE_NAME.jl/vX.Y.Z +https://USER_NAME.github.io/PACKAGE_NAME.jl/dev +``` + +By default Documenter will create a link called `stable` that points to the latest release + +``` +https://USER_NAME.github.io/PACKAGE_NAME.jl/stable +``` + +It is recommended to use this link, rather then the versioned links, since it will be updated +with new releases. + +Once your documentation has been pushed to the `gh-pages` branch you should add links to +your `README.md` pointing to the `stable` (and perhaps `dev`) documentation URLs. It is common +practice to make use of "badges" similar to those used for Travis and AppVeyor build +statuses or code coverage. Adding the following to your package `README.md` should be all +that is necessary: + +```markdown +[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://USER_NAME.github.io/PACKAGE_NAME.jl/stable) +[![](https://img.shields.io/badge/docs-dev-blue.svg)](https://USER_NAME.github.io/PACKAGE_NAME.jl/dev) +``` + +`PACKAGE_NAME` and `USER_NAME` should be replaced with their appropriate values. The colour +and text of the image can be changed by altering `docs-stable-blue` as described on +[shields.io](https://shields.io), though it is recommended that package authors follow this +standard to make it easier for potential users to find documentation links across multiple +package README files. + +--- + +**Final Remarks** + +That should be all that is needed to enable automatic documentation building. Pushing new +commits to your `master` branch should trigger doc builds. **Note that other branches do not +trigger these builds and neither do pull requests by potential contributors.** + +If you would like to see a more complete example of how this process is setup then take a +look at this package's repository for some inspiration. diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/github-add-deploy-key.png b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/github-add-deploy-key.png new file mode 100644 index 0000000..f927c02 Binary files /dev/null and b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/github-add-deploy-key.png differ diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/puttygen-export-private-key.png b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/puttygen-export-private-key.png new file mode 100644 index 0000000..5e7fbe7 Binary files /dev/null and b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/puttygen-export-private-key.png differ diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/puttygen-generated.png b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/puttygen-generated.png new file mode 100644 index 0000000..112da3f Binary files /dev/null and b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/puttygen-generated.png differ diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/puttygen.png b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/puttygen.png new file mode 100644 index 0000000..d2fb3eb Binary files /dev/null and b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/puttygen.png differ diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/travis-variables.png b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/travis-variables.png new file mode 100644 index 0000000..2511626 Binary files /dev/null and b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/travis-variables.png differ diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/walkthrough.md b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/walkthrough.md new file mode 100644 index 0000000..d1e4871 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/walkthrough.md @@ -0,0 +1,165 @@ +# SSH Deploy Keys Walkthrough + +If the instructions in [SSH Deploy Keys](@ref) did not work for you (for example, +`ssh-keygen` is not installed), don't worry! This walkthrough will guide you through the +process. There are three main steps: + +1. [Generating an SSH Key](@ref) +2. [Adding the Public Key to GitHub](@ref) +3. [Adding the Private Key to Travis](@ref) + +## Generating an SSH Key + +The first step is to generate an SSH key. An SSH key is made up of two components: a +*public* key, which can be shared publicly, and a *private* key, which you should ensure is +**never** shared publicly. + +The public key usually looks something like this + +``` +ssh-rsa [base64-encoded-key] [optional-comment] +``` + +And the private key usually look something like this + +``` +-----BEGIN RSA PRIVATE KEY----- + ... base64-encoded key over several lines ... +-----END RSA PRIVATE KEY----- +``` + +### If you have `ssh-keygen` installed + +If you have `ssh-keygen` installed, but `Travis.genkeys()` didn't work, you can generate an +SSH key as follows. First, generate a key using `ssh-keygen` and save it to the file +`privatekey`: + +```julia +shell> ssh-keygen -N "" -f privatekey +``` + +Next, we need to encode the private key in Base64. Run the following command: + +```julia +julia> read("privatekey", String) |> base64encode |> println +``` + +Copy and paste the output somewhere. This is your *private key* and is required for the step +[Adding the Private Key to Travis](@ref). + +Now we need to get the public key. Run the following command: + +```julia +julia> read("privatekey.pub", String) |> println +``` + +Copy and paste the output somewhere. This is your *public key* and is required for the step +[Adding the Public Key to GitHub](@ref). + +### If you do not have `ssh-keygen` + +If you're using Windows, you probably don't have `ssh-keygen` installed. Instead, we're +going to use a program called PuTTY. The first step in the process to generate a new SSH key +is to download PuTTY: + +* Download and install [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/) + +PuTTY is actually a collection of a few different programs. We need to use PuTTYgen. Open +it, and you should get a window that looks like: + +![](puttygen.png) + +Now we need to generate a key. + +* Click the "Generate" button, then follow the instructions and move the mouse around to + create randomness. + +Once you've moved the mouse enough, the window should look like: + +![](puttygen-generated.png) + +Now we need to save the public key somewhere. + +* Copy the text in the box titled "Public key for pasting into OpenSSH authorized_keys file" + and paste it somewhere for later. This is your *public key* and is required for the step + [Adding the Public Key to GitHub](@ref) + +Finally, we need to save the private key somewhere. + +* Click the "Conversions" tab, and then click "Export OpenSSH key". Save that file + somewhere. That file is your *private key* and is required for the [Adding the Private Key + to Travis](@ref) step. + + ![](puttygen-export-private-key.png) + + !!! note + + Don't save your key via the "Save private key" button as this will save the key in the + wrong format. + +If you made it this far, congratulations! You now have the private and public keys needed to +set up automatic deployment of your documentation. The next steps are to add the keys to +GitHub and Travis. + + +## Adding the Public Key to GitHub + +In this section, we explain how to upload a public SSH key to GitHub. By this point, you +should have generated a public key and saved it to a file. If you haven't done this, go read +[Generating an SSH Key](@ref). + +Go to `https://github.com/[YOUR_USER_NAME]/[YOUR_REPO_NAME]/settings/keys` and click "Add +deploy key". You should get to a page that looks like: + +![](github-add-deploy-key.png) + +Now we need to fill in three pieces of information. + +1. Have "Title" be e.g. "Documenter". +2. Copy and paste the *public key* that we generated in the [Generating an SSH Key](@ref) + step into the "Key" field. +3. Make sure that the "Allow write access" box is checked. + +Once you're done, click "Add key". Congratulations! You've added the public key +to GitHub. The next step is to add the private key to Travis. + + +## Adding the Private Key to Travis + +In this section, we explain how to upload a private SSH key to Travis. By this point, you +should have generated a private key and saved it to a file. If you haven't done this, go +read [Generating an SSH Key](@ref). + +First, we need to Base64 encode the private key. Open Julia, and run the command + +```julia +julia> read("path/to/private/key", String) |> Documenter.base64encode |> println +``` + +Copy the resulting output. + +Next, go to `https://travis-ci.org/[YOUR_USER_NAME]/[YOUR_REPO_NAME]/settings`. Scroll down +to the "Environment Variables" section. It should look like this: + +![](travis-variables.png) + +Now, add a new environment variable called `DOCUMENTER_KEY`, and set its value to the output +from the Julia command above (make sure to remove the surrounding quotes). + +Finally, check that the "Display value in build log" is switched off and then click "Add". +Congratulations! You've added the private key to Travis. + +!!! warning "Security warning" + + To reiterate: make sure that the "Display value in build log" option is **OFF** for + the variable, so that it does not get printed when the tests run. This + base64-encoded string contains the *unencrypted* private key that gives full write + access to your repository, so it must be kept safe. Also, make sure that you never + expose this variable in your tests, nor merge any code that does. You can read more + about Travis environment variables in [Travis User Documentation](https://docs.travis-ci.com/user/environment-variables/#Defining-Variables-in-Repository-Settings). + +--- + +**Final Remarks** + +You should now be able to continue on with the [Hosting Documentation](@ref). diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/latex.md b/embedded/Documenter.jl-0.20.0/docs/src/man/latex.md new file mode 100644 index 0000000..c9f040a --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/man/latex.md @@ -0,0 +1,83 @@ +# [``\LaTeX`` Syntax](@id latex_syntax) + +The following section describes how to add equations written using ``\LaTeX`` to your +documentation. + +## Escaping Characters in Docstrings + +Since some characters used in ``\LaTeX`` syntax are treated differently in docstrings they +need to be escaped using a `\` character as in the following example: + +```julia +""" +Here's some inline maths: \$\\sqrt[n]{1 + x + x^2 + \\ldots}\$. + +Here's an equation: + +\$\\frac{n!}{k!(n - k)!} = \\binom{n}{k}\$ + +This is the binomial coefficient. +""" +func(x) = # ... +``` + +To avoid needing to escape the special characters the `doc""` string macro can be used: + +```julia +doc""" +Here's some inline maths: $\sqrt[n]{1 + x + x^2 + \ldots}$. + +Here's an equation: + +$\frac{n!}{k!(n - k)!} = \binom{n}{k}$ + +This is the binomial coefficient. +""" +func(x) = # ... +``` + +A related issue is how to add dollar signs to a docstring. They need to be +double-escaped as follows: +```julia +""" +The cost was \\\$1. +""" +``` + +## Inline Equations + +```markdown +Here's some inline maths: ``\sqrt[n]{1 + x + x^2 + \ldots}``. +``` + +which will be displayed as + +--- + +Here's some inline maths: ``\sqrt[n]{1 + x + x^2 + \ldots}``. + +--- + +## Display Equations + +````markdown +Here's an equation: + +```math +\frac{n!}{k!(n - k)!} = \binom{n}{k} +``` + +This is the binomial coefficient. +```` + +which will be displayed as + +--- + +Here's an equation: + +```math +\frac{n!}{k!(n - k)!} = \binom{n}{k} +``` + +This is the binomial coefficient. diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/other-formats.md b/embedded/Documenter.jl-0.20.0/docs/src/man/other-formats.md new file mode 100644 index 0000000..7745c4a --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/man/other-formats.md @@ -0,0 +1,169 @@ +# Other Output Formats + +In addition to the default native HTML output, plugin packages enable Documenter to generate +output in other formats. Once the corresponding package is loaded, the output format can be +specified using the `format` option in [`makedocs`](@ref). + + +## Markdown & MkDocs + +Markdown output requires the [`DocumenterMarkdown`](https://github.com/JuliaDocs/DocumenterMarkdown.jl) +package to be available and loaded. +For Travis setups, add the package to the `docs/Project.toml` environment as a dependency. +You also need to import the package in `make.jl`: + +``` +using DocumenterMarkdown +``` + +When `DocumenterMarkdown` is loaded, you can specify `format = :markdown` in [`makedocs`](@ref). +Documenter will then output a set of Markdown files to the `build` directory that can then +further be processed with [MkDocs](https://www.mkdocs.org/) into HTML pages. + +MkDocs, of course, is not the only option you have -- any markdown to HTML converter should +work fine with some amount of setting up. + +!!! note + + Markdown output used to be the default option (i.e. when leaving the `format` option + unspecified). The default now is the HTML output. + +### The MkDocs `mkdocs.yml` file + +A MkDocs build is controlled by the `mkdocs.yml` configuration file. Add the file with the +following content to the `docs/` directory: + +```yaml +site_name: PACKAGE_NAME.jl +repo_url: https://github.com/USER_NAME/PACKAGE_NAME.jl +site_description: Description... +site_author: USER_NAME + +theme: readthedocs + +extra_css: + - assets/Documenter.css + +extra_javascript: + - https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_HTML + - assets/mathjaxhelper.js + +markdown_extensions: + - extra + - tables + - fenced_code + - mdx_math + +docs_dir: 'build' + +pages: + - Home: index.md +``` + +If you have run Documenter and it has generated a `build/` directory, you can now try running +`mkdocs build` -- this should now generate the `site/` directory. +You should also add the `docs/site/` directory into your `.gitignore` file, which should now +look like: + +``` +docs/build/ +docs/site/ +``` + +This is only a basic skeleton. Read through the MkDocs documentation if you would like to +know more about the available settings. + + +### Deployment with MkDocs + +To deploy MkDocs on Travis, you also need to provide additional keyword arguments to +[`deploydocs`](@ref). Your [`deploydocs`](@ref) call should look something like + +```julia +deploydocs( + repo = "github.com/USER_NAME/PACKAGE_NAME.jl.git", + deps = Deps.pip("mkdocs", "pygments", "python-markdown-math"), + make = () -> run(`mkdocs build`) + target = "site" +) +``` + +* `deps` serves to provide the required Python dependencies to build the documentation +* `make` specifies the function that calls `mkdocs` to perform the second build step +* `target`, which specified which files get copied to `gh-pages`, needs to point to the + `site/` directory + +In the example above we include the dependencies [mkdocs](https://www.mkdocs.org) +and [`python-markdown-math`](https://github.com/mitya57/python-markdown-math). +The former makes sure that MkDocs is installed to deploy the documentation, +and the latter provides the `mdx_math` markdown extension to exploit MathJax +rendering of latex equations in markdown. Other dependencies should be +included here. + + +### ``\LaTeX``: MkDocs and MathJax + +To get MkDocs to display ``\LaTeX`` equations correctly we need to update several of this +configuration files described in the [Package Guide](@ref). + +`docs/make.jl` should add the `python-markdown-math` dependency to allow for equations to +be rendered correctly. + +```julia +# ... + +deploydocs( + deps = Deps.pip("pygments", "mkdocs", "python-markdown-math"), + # ... +) +``` + +This package should also be installed locally so that you can preview the generated +documentation prior to pushing new commits to a repository. + +```sh +$ pip install python-markdown-math +``` + +The `docs/mkdocs.yml` file must add the `python-markdown-math` extension, called `mdx_math`, +as well as two MathJax JavaScript files: + +```yaml +# ... +markdown_extensions: + - mdx_math + # ... + +extra_javascript: + - https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_HTML + - assets/mathjaxhelper.js +# ... +``` + +**Final Remarks** + +Following this guide and adding the necessary changes to the configuration files should +enable properly rendered mathematical equations within your documentation both locally and +when built and deployed using the Travis built service. + + +## PDF Output via LaTeX + +LaTeX/PDF output requires the [`DocumenterLaTeX`](https://github.com/JuliaDocs/DocumenterLaTeX.jl) +package to be available and loaded in `make.jl` with + +``` +using DocumenterLaTeX +``` + +When `DocumenterLaTeX` is loaded, you can set `format = :latex` in [`makedocs`](@ref), +and Documenter will generate a PDF version of the documentation using LaTeX. + +* You need `pdflatex` command to be installed and available to Documenter. +* You need the [minted](https://ctan.org/pkg/minted) LaTeX package and its backend source + highlighter [Pygments](http://pygments.org/) installed. +* You need the [Lato](http://www.latofonts.com/lato-free-fonts/) and + [Roboto Mono](https://fonts.google.com/specimen/Roboto+Mono) fonts installed. + +You should also specify the `sitename` and `authors` keywords for `makedocs` when using the +LaTeX output. diff --git a/embedded/Documenter.jl-0.20.0/docs/src/man/syntax.md b/embedded/Documenter.jl-0.20.0/docs/src/man/syntax.md new file mode 100644 index 0000000..e1f28fd --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/docs/src/man/syntax.md @@ -0,0 +1,559 @@ +# Syntax + +This section of the manual describes the syntax used by Documenter to build documentation. + +```@contents +Pages = ["syntax.md"] +``` + +## `@docs` block + +Splice one or more docstrings into a document in place of the code block, i.e. + +````markdown +```@docs +Documenter +makedocs +deploydocs +``` +```` + +This block type is evaluated within the `CurrentModule` module if defined, otherwise within +`Main`, and so each object listed in the block should be visible from that +module. Undefined objects will raise warnings during documentation generation and cause the +code block to be rendered in the final document unchanged. + +Objects may not be listed more than once within the document. When duplicate objects are +detected an error will be raised and the build process will be terminated. + +To ensure that all docstrings from a module are included in the final document the `modules` +keyword for [`makedocs`](@ref) can be set to the desired module or modules, i.e. + +```julia +makedocs( + modules = [Documenter], +) +``` + +which will cause any unlisted docstrings to raise warnings when [`makedocs`](@ref) is +called. If `modules` is not defined then no warnings are printed, even if a document has +missing docstrings. + +## `@autodocs` block + +Automatically splices all docstrings from the provided modules in place of the code block. +This is equivalent to manually adding all the docstrings in a `@docs` block. + +````markdown +```@autodocs +Modules = [Foo, Bar] +Order = [:function, :type] +``` +```` + +The above `@autodocs` block adds all the docstrings found in modules `Foo` and `Bar` that +refer to functions or types to the document. + +Each module is added in order and so all docs from `Foo` will appear before those of `Bar`. +Possible values for the `Order` vector are + +- `:module` +- `:constant` +- `:type` +- `:function` +- `:macro` + +If no `Order` is provided then the order listed above is used. + +When a potential docstring is found in one of the listed modules, but does not match any +value from `Order` then it will be omitted from the document. Hence `Order` acts as a basic +filter as well as sorter. + +In addition to `Order`, a `Pages` vector may be included in `@autodocs` to filter docstrings +based on the source file in which they are defined: + +````markdown +```@autodocs +Modules = [Foo] +Pages = ["a.jl", "b.jl"] +``` +```` + +In the above example docstrings from module `Foo` found in source files that end in `a.jl` +and `b.jl` are included. The page order provided by `Pages` is also used to sort the +docstrings. Note that page matching is done using the end of the provided strings and so +`a.jl` will be matched by *any* source file that ends in `a.jl`, i.e. `src/a.jl` or +`src/foo/a.jl`. + +To include only the exported names from the modules listed in `Modules` use `Private = false`. +In a similar way `Public = false` can be used to only show the unexported names. By +default both of these are set to `true` so that all names will be shown. + +````markdown +Functions exported from `Foo`: + +```@autodocs +Modules = [Foo] +Private = false +Order = [:function] +``` + +Private types in module `Foo`: + +```@autodocs +Modules = [Foo] +Public = false +Order = [:type] +``` +```` + +!!! note + + When more complex sorting and filtering is needed then use `@docs` to define it + explicitly. + +## `@ref` link + +Used in markdown links as the URL to tell Documenter to generate a cross-reference +automatically. The text part of the link can be a docstring, header name, or GitHub PR/Issue +number. + +````markdown +# Syntax + +... [`makedocs`](@ref) ... + +# Functions + +```@docs +makedocs +``` + +... [Syntax](@ref) ... + +... [#42](@ref) ... +```` + +Plain text in the "text" part of a link will either cross-reference a header, or, when it is +a number preceded by a `#`, a GitHub issue/pull request. Text wrapped in backticks will +cross-reference a docstring from a `@docs` block. + +`@ref`s may refer to docstrings or headers on different pages as well as the current page +using the same syntax. + +Note that depending on what the `CurrentModule` is set to, a docstring `@ref` may need to +be prefixed by the module which defines it. + +### Duplicate Headers + +In some cases a document may contain multiple headers with the same name, but on different +pages or of different levels. To allow `@ref` to cross-reference a duplicate header it must +be given a name as in the following example + +```markdown +# [Header](@id my_custom_header_name) + +... + +## Header + +... [Custom Header](@ref my_custom_header_name) ... +``` + +The link that wraps the named header is removed in the final document. The text for a named +`@ref ...` does not need to match the header that it references. Named `@ref ...`s may refer +to headers on different pages in the same way as unnamed ones do. + +Duplicate docstring references do not occur since splicing the same docstring into a +document more than once is disallowed. + +### Named doc `@ref`s + +Docstring `@ref`s can also be "named" in a similar way to headers as shown in the +[Duplicate Headers](@ref) section above. For example + +```julia +module Mod + +""" +Both of the following references point to `g` found in module `Main.Other`: + + * [`Main.Other.g`](@ref) + * [`g`](@ref Main.Other.g) + +""" +f(args...) = # ... + +end +``` + +This can be useful to avoid having to write fully qualified names for references that +are not imported into the current module, or when the text displayed in the link is +used to add additional meaning to the surrounding text, such as + +```markdown +Use [`for i = 1:10 ...`](@ref for) to loop over all the numbers from 1 to 10. +``` + +!!! note + + Named doc `@ref`s should be used sparingly since writing unqualified names may, in some + cases, make it difficult to tell *which* function is being referred to in a particular + docstring if there happen to be several modules that provide definitions with the same + name. + +## `@meta` block + +This block type is used to define metadata key/value pairs that can be used elsewhere in the +page. Currently recognised keys: +- `CurrentModule`: module where Documenter evaluates, for example, [`@docs`-block](@ref) + and [`@ref`-link](@ref)s. +- `DocTestSetup`: code to be evaluated before a doctest, see the [Setup Code](@ref) + section under [Doctests](@ref). +- `DocTestFilters`: filters to deal with, for example, unpredictable output from doctests, + see the [Filtering Doctests](@ref) section under [Doctests](@ref). +- `EditURL`: link to where the page can be edited. This defaults to the `.md` page itself, + but if the source is something else (for example if the `.md` page is generated as part of + the doc build) this can be set, either as a local link, or an absolute url. + +Example: + +````markdown +```@meta +CurrentModule = FooBar +DocTestSetup = quote + using MyPackage +end +DocTestFilters = [r"Stacktrace:[\s\S]+"] +EditURL = "link/to/source/file" +``` +```` + +Note that `@meta` blocks are always evaluated in `Main`. + +## `@index` block + +Generates a list of links to docstrings that have been spliced into a document. Valid +settings are `Pages`, `Modules`, and `Order`. For example: + +````markdown +```@index +Pages = ["foo.md"] +Modules = [Foo, Bar] +Order = [:function, :type] +``` +```` + +When `Pages` or `Modules` are not provided then all pages or modules are included. `Order` +defaults to + +```julia +[:module, :constant, :type, :function, :macro] +``` + +if not specified. `Order` and `Modules` behave the same way as in [`@autodocs` block](@ref)s +and filter out docstrings that do not match one of the modules or categories specified. + +Note that the values assigned to `Pages`, `Modules`, and `Order` may be any valid Julia code +and thus can be something more complex that an array literal if required, i.e. + +````markdown +```@index +Pages = map(file -> joinpath("man", file), readdir("man")) +``` +```` + +It should be noted though that in this case `Pages` may not be sorted in the order that is +expected by the user. Try to stick to array literals as much as possible. + +## `@contents` block + +Generates a nested list of links to document sections. Valid settings are `Pages` and `Depth`. + +````markdown +```@contents +Pages = ["foo.md"] +Depth = 5 +``` +```` + +As with `@index` if `Pages` is not provided then all pages are included. The default +`Depth` value is `2`. + +## `@example` block + +Evaluates the code block and inserts the result into the final document along with the +original source code. + +````markdown +```@example +a = 1 +b = 2 +a + b +``` +```` + +The above `@example` block will splice the following into the final document + +````markdown +```julia +a = 1 +b = 2 +a + b +``` + +``` +3 +``` +```` + +Leading and trailing newlines are removed from the rendered code blocks. Trailing whitespace +on each line is also removed. + +**Hiding Source Code** + +Code blocks may have some content that does not need to be displayed in the final document. +`# hide` comments can be appended to lines that should not be rendered, i.e. + +````markdown +```@example +import Random # hide +Random.seed!(1) # hide +A = rand(3, 3) +b = [1, 2, 3] +A \ b +``` +```` + +Note that appending `# hide` to every line in an `@example` block will result in the block +being hidden in the rendered document. The results block will still be rendered though. +`@setup` blocks are a convenient shorthand for hiding an entire block, including the output. + +**`stdout` and `stderr`** + +The Julia output streams are redirected to the results block when evaluating `@example` +blocks in the same way as when running doctest code blocks. + +**`nothing` Results** + +When the `@example` block evaluates to `nothing` then the second block is not displayed. +Only the source code block will be shown in the rendered document. Note that if any output +from either `stdout` or `stderr` is captured then the results block will be displayed even +if `nothing` is returned. + +**Named `@example` Blocks** + +By default `@example` blocks are run in their own anonymous `Module`s to avoid side-effects +between blocks. To share the same module between different blocks on a page the `@example` +can be named with the following syntax + +````markdown +```@example 1 +a = 1 +``` + +```@example 1 +println(a) +``` +```` + +The name can be any text, not just integers as in the example above, i.e. `@example foo`. + +Named `@example` blocks can be useful when generating documentation that requires +intermediate explanation or multimedia such as plots as illustrated in the following example + +````markdown +First we define some functions + +```@example 1 +using PyPlot # hide +f(x) = sin(2x) + 1 +g(x) = cos(x) - x +``` + +and then we plot `f` over the interval from ``-π`` to ``π`` + +```@example 1 +x = linspace(-π, π) +plot(x, f(x), color = "red") +savefig("f-plot.svg"); nothing # hide +``` + +![](f-plot.svg) + +and then we do the same with `g` + +```@example 1 +plot(x, g(x), color = "blue") +savefig("g-plot.svg"); nothing # hide +``` + +![](g-plot.svg) +```` + +Note that `@example` blocks are evaluated within the directory of `build` where the file +will be rendered . This means than in the above example `savefig` will output the `.svg` +files into that directory. This allows the images to be easily referenced without needing to +worry about relative paths. + +`@example` blocks automatically define `ans` which, as in the Julia REPL, is bound to the +value of the last evaluated expression. This can be useful in situations such as the +following one where where binding the object returned by `plot` to a named variable would +look out of place in the final rendered documentation: + +````markdown +```@example +using Gadfly # hide +plot([sin, x -> 2sin(x) + x], -2π, 2π) +draw(SVG("plot.svg", 6inch, 4inch), ans); nothing # hide +``` + +![](plot.svg) +```` + +**Delayed Execution of `@example` Blocks** + +`@example` blocks accept a keyword argument `continued` which can be set to `true` or `false` +(defaults to `false`). When `continued = true` the execution of the code is delayed until the +next `continued = false` `@example`-block. This is needed for example when the expression in +a block is not complete. Example: + +````markdown +```@example half-loop; continued = true +for i in 1:3 + j = i^2 +``` +Some text explaining what we should do with `j` +```@example half-loop + println(j) +end +``` +```` + +Here the first block is not complete -- the loop is missing the `end`. Thus, by setting +`continued = true` here we delay the evaluation of the first block, until we reach the +second block. A block with `continued = true` does not have any output. + +## `@repl` block + +These are similar to `@example` blocks, but adds a `julia> ` prompt before each toplevel +expression. `;` and `# hide` syntax may be used in `@repl` blocks in the same way as in the +Julia REPL and `@example` blocks. + +````markdown +```@repl +a = 1 +b = 2 +a + b +``` +```` + +will generate + +````markdown +```julia +julia> a = 1 +1 + +julia> b = 2 +2 + +julia> a + b +3 +``` +```` + +Named `@repl ` blocks behave in the same way as named `@example ` blocks. + +## `@setup ` block + +These are similar to `@example` blocks, but both the input and output are hidden from the +final document. This can be convenient if there are several lines of setup code that need to be +hidden. + +!!! note + + Unlike `@example` and `@repl` blocks, `@setup` requires a `` attribute to associate it + with downstream `@example ` and `@repl ` blocks. + +````markdown +```@setup abc +using RDatasets +using DataFrames +iris = dataset("datasets", "iris") +``` + +```@example abc +println(iris) +``` +```` + + +## `@eval` block + +Evaluates the contents of the block and inserts the resulting value into the final document. + +In the following example we use the PyPlot package to generate a plot and display it in the +final document. + +````markdown +```@eval +using PyPlot + +x = linspace(-π, π) +y = sin(x) + +plot(x, y, color = "red") +savefig("plot.svg") + +nothing +``` + +![](plot.svg) +```` + +Note that each `@eval` block evaluates its contents within a separate module. When +evaluating each block the present working directory, `pwd`, is set to the directory in +`build` where the file will be written to. + +Also, instead of returning `nothing` in the example above we could have returned a new +`Markdown.MD` object through `Markdown.parse`. This can be more appropriate when the +filename is not known until evaluation of the block itself. + +!!! note + + In most cases `@example` is preferred over `@eval`. Just like in normal Julia code where + `eval` should be only be considered as a last resort, `@eval` should be treated in the + same way. + + +## `@raw ` block + +Allows code to be inserted into the final document verbatim. E.g. to insert custom HTML or +LaTeX code into the output. + +The `format` argument is mandatory and Documenter uses it to determine whether a particular +block should be copied over to the output or not. Currently supported formats are `html` +and `latex`, used by the respective writers. A `@raw` block whose `format` is not +recognized is usually ignored, so it is possible to have a raw block for each output format +without the blocks being duplicated in the output. + +The following example shows how SVG code with custom styling can be included into documents +using the `@raw` block. + +````markdown +```@raw html + + + +``` +```` + +It will show up as follows, with code having been copied over verbatim to the HTML file. + +```@raw html + + + (SVG) + +``` diff --git a/embedded/Documenter.jl-0.20.0/src/Anchors.jl b/embedded/Documenter.jl-0.20.0/src/Anchors.jl new file mode 100644 index 0000000..c1f7115 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Anchors.jl @@ -0,0 +1,127 @@ +""" +Defines the [`Anchor`](@ref) and [`AnchorMap`](@ref) types. + +`Anchor`s and `AnchorMap`s are used to represent links between objects within a document. +""" +module Anchors + +using DocStringExtensions + +# Types. +# ------ + +""" +Stores an arbitrary object called `.object` and it's location within a document. + +**Fields** + +- `object` -- the stored object. +- `order` -- ordering of `object` within the entire document. +- `file` -- the destination file, in `build`, where the object will be written to. +- `id` -- the generated "slug" identifying the object. +- `nth` -- integer that unique-ifies anchors with the same `id`. +""" +mutable struct Anchor + object :: Any + order :: Int + file :: String + id :: String + nth :: Int + Anchor(object) = new(object, 0, "", "", 1) +end + +""" +Tree structure representating anchors in a document and their relationships with eachother. + +**Object Hierarchy** + + id -> file -> anchors + +Each `id` maps to a `file` which in turn maps to a vector of `Anchor` objects. +""" +mutable struct AnchorMap + map :: Dict{String, Dict{String, Vector{Anchor}}} + count :: Int + AnchorMap() = new(Dict(), 0) +end + +# Add anchor. +# ----------- + +""" +$(SIGNATURES) + +Adds a new [`Anchor`](@ref) to the [`AnchorMap`](@ref) for a given `id` and `file`. + +Either an actual [`Anchor`](@ref) object may be provided or any other object which is +automatically wrapped in an [`Anchor`](@ref) before being added to the [`AnchorMap`](@ref). +""" +function add!(m::AnchorMap, anchor::Anchor, id, file) + filemap = get!(m.map, id, Dict{String, Vector{Anchor}}()) + anchors = get!(filemap, file, Anchor[]) + push!(anchors, anchor) + anchor.order = m.count += 1 + anchor.file = file + anchor.id = id + anchor.nth = length(anchors) + anchor +end +add!(m::AnchorMap, object, id, file) = add!(m, Anchor(object), id, file) + +# Anchor existance. +# ----------------- + +""" +$(SIGNATURES) + +Does the given `id` exist within the [`AnchorMap`](@ref)? A `file` and integer `n` may also +be provided to narrow the search for existance. +""" +exists(m::AnchorMap, id, file, n) = exists(m, id, file) && 1 ≤ n ≤ length(m.map[id][file]) +exists(m::AnchorMap, id, file) = exists(m, id) && haskey(m.map[id], file) +exists(m::AnchorMap, id) = haskey(m.map, id) + +# Anchor uniqueness. +# ------------------ + +""" +$(SIGNATURES) + +Is the `id` unique within the given [`AnchorMap`](@ref)? May also specify the `file`. +""" +function isunique(m::AnchorMap, id) + exists(m, id) && + length(m.map[id]) === 1 && + isunique(m, id, first(first(m.map[id]))) +end +function isunique(m::AnchorMap, id, file) + exists(m, id, file) && + length(m.map[id][file]) === 1 +end + +# Get anchor. +# ----------- + +""" +$(SIGNATURES) + +Returns the [`Anchor`](@ref) object matching `id`. `file` and `n` may also be provided. An +`Anchor` is returned, or `nothing` in case of no match. +""" +function anchor(m::AnchorMap, id) + isunique(m, id) ? + anchor(m, id, first(first(m.map[id])), 1) : + nothing +end +function anchor(m::AnchorMap, id, file) + isunique(m, id, file) ? + anchor(m, id, file, 1) : + nothing +end +function anchor(m::AnchorMap, id, file, n) + exists(m, id, file, n) ? + m.map[id][file][n] : + nothing +end + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Builder.jl b/embedded/Documenter.jl-0.20.0/src/Builder.jl new file mode 100644 index 0000000..616c68d --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Builder.jl @@ -0,0 +1,213 @@ +""" +Defines the `Documenter.jl` build "pipeline" named [`DocumentPipeline`](@ref). + +Each stage of the pipeline performs an action on a [`Documents.Document`](@ref) object. +These actions may involve creating directory structures, expanding templates, running +doctests, etc. +""" +module Builder + +import ..Documenter: + Anchors, + Documents, + Documenter, + Utilities + +import .Utilities: Selectors + +using DocStringExtensions + +# Document Pipeline. +# ------------------ + +""" +The default document processing "pipeline", which consists of the following actions: + +- [`SetupBuildDirectory`](@ref) +- [`ExpandTemplates`](@ref) +- [`CrossReferences`](@ref) +- [`CheckDocument`](@ref) +- [`Populate`](@ref) +- [`RenderDocument`](@ref) + +""" +abstract type DocumentPipeline <: Selectors.AbstractSelector end + +""" +Creates the correct directory layout within the `build` folder and parses markdown files. +""" +abstract type SetupBuildDirectory <: DocumentPipeline end + +""" +Executes a sequence of actions on each node of the parsed markdown files in turn. +""" +abstract type ExpandTemplates <: DocumentPipeline end + +""" +Finds and sets URLs for each `@ref` link in the document to the correct destinations. +""" +abstract type CrossReferences <: DocumentPipeline end + +""" +Checks that all documented objects are included in the document and runs doctests on all +valid Julia code blocks. +""" +abstract type CheckDocument <: DocumentPipeline end + +""" +Populates the `ContentsNode`s and `IndexNode`s with links. +""" +abstract type Populate <: DocumentPipeline end + +""" +Writes the document tree to the `build` directory. +""" +abstract type RenderDocument <: DocumentPipeline end + +Selectors.order(::Type{SetupBuildDirectory}) = 1.0 +Selectors.order(::Type{ExpandTemplates}) = 2.0 +Selectors.order(::Type{CrossReferences}) = 3.0 +Selectors.order(::Type{CheckDocument}) = 4.0 +Selectors.order(::Type{Populate}) = 5.0 +Selectors.order(::Type{RenderDocument}) = 6.0 + +Selectors.matcher(::Type{T}, doc::Documents.Document) where {T <: DocumentPipeline} = true + +Selectors.strict(::Type{T}) where {T <: DocumentPipeline} = false + +function Selectors.runner(::Type{SetupBuildDirectory}, doc::Documents.Document) + Utilities.log(doc, "setting up build directory.") + + # Frequently used fields. + build = doc.user.build + source = doc.user.source + + # The .user.source directory must exist. + isdir(source) || error("source directory '$(abspath(source))' is missing.") + + # We create the .user.build directory. + # If .user.clean is set, we first clean the existing directory. + doc.user.clean && isdir(build) && rm(build; recursive = true) + isdir(build) || mkpath(build) + + # We'll walk over all the files in the .user.source directory. + # The directory structure is copied over to .user.build. All files, with + # the exception of markdown files (identified by the extension) are copied + # over as well, since they're assumed to be images, data files etc. + # Markdown files, however, get added to the document and also stored into + # `mdpages`, to be used later. + mdpages = String[] + for (root, dirs, files) in walkdir(source) + for dir in dirs + d = normpath(joinpath(build, relpath(root, source), dir)) + isdir(d) || mkdir(d) + end + for file in files + src = normpath(joinpath(root, file)) + dst = normpath(joinpath(build, relpath(root, source), file)) + if endswith(file, ".md") + push!(mdpages, Utilities.srcpath(source, root, file)) + Documents.addpage!(doc, src, dst) + else + cp(src, dst; force = true) + end + end + end + + # If the user hasn't specified the page list, then we'll just default to a + # flat list of all the markdown files we found, sorted by the filesystem + # path (it will group them by subdirectory, among others). + userpages = isempty(doc.user.pages) ? sort(mdpages) : doc.user.pages + + # Populating the .navtree and .navlist. + # We need the for loop because we can't assign to the fields of the immutable + # doc.internal. + for navnode in walk_navpages(userpages, nothing, doc) + push!(doc.internal.navtree, navnode) + end + + # Finally we populate the .next and .prev fields of the navnodes that point + # to actual pages. + local prev::Union{Documents.NavNode, Nothing} = nothing + for navnode in doc.internal.navlist + navnode.prev = prev + if prev !== nothing + prev.next = navnode + end + prev = navnode + end +end + +""" +$(SIGNATURES) + +Recursively walks through the [`Documents.Document`](@ref)'s `.user.pages` field, +generating [`Documents.NavNode`](@ref)s and related data structures in the +process. + +This implementation is the de facto specification for the `.user.pages` field. +""" +function walk_navpages(visible, title, src, children, parent, doc) + # parent can also be nothing (for top-level elements) + parent_visible = (parent === nothing) || parent.visible + if src !== nothing + src = normpath(src) + src in keys(doc.internal.pages) || error("'$src' is not an existing page!") + end + nn = Documents.NavNode(src, title, parent) + (src === nothing) || push!(doc.internal.navlist, nn) + nn.visible = parent_visible && visible + nn.children = walk_navpages(children, nn, doc) + nn +end + +function walk_navpages(hps::Tuple, parent, doc) + @assert length(hps) == 4 + walk_navpages(hps..., parent, doc) +end + +walk_navpages(title::String, children::Vector, parent, doc) = walk_navpages(true, title, nothing, children, parent, doc) +walk_navpages(title::String, page, parent, doc) = walk_navpages(true, title, page, [], parent, doc) + +walk_navpages(p::Pair, parent, doc) = walk_navpages(p.first, p.second, parent, doc) +walk_navpages(ps::Vector, parent, doc) = [walk_navpages(p, parent, doc)::Documents.NavNode for p in ps] +walk_navpages(src::String, parent, doc) = walk_navpages(true, nothing, src, [], parent, doc) + + +function Selectors.runner(::Type{ExpandTemplates}, doc::Documents.Document) + Utilities.log(doc, "expanding markdown templates.") + Documenter.Expanders.expand(doc) +end + +function Selectors.runner(::Type{CrossReferences}, doc::Documents.Document) + Utilities.log(doc, "building cross-references.") + Documenter.CrossReferences.crossref(doc) +end + +function Selectors.runner(::Type{CheckDocument}, doc::Documents.Document) + Utilities.log(doc, "running document checks.") + Documenter.DocChecks.missingdocs(doc) + Documenter.DocTests.doctest(doc) + Documenter.DocChecks.footnotes(doc) + Documenter.DocChecks.linkcheck(doc) +end + +function Selectors.runner(::Type{Populate}, doc::Documents.Document) + Utilities.log("populating indices.") + Documents.doctest_replace!(doc) + Documents.populate!(doc) +end + +function Selectors.runner(::Type{RenderDocument}, doc::Documents.Document) + count = length(doc.internal.errors) + if doc.user.strict && count > 0 + error("`makedocs` encountered $(count > 1 ? "errors" : "an error"). Terminating build") + else + Utilities.log(doc, "rendering document.") + Documenter.Writers.render(doc) + end +end + +Selectors.runner(::Type{DocumentPipeline}, doc::Documents.Document) = nothing + +end diff --git a/embedded/Documenter.jl-0.20.0/src/CrossReferences.jl b/embedded/Documenter.jl-0.20.0/src/CrossReferences.jl new file mode 100644 index 0000000..c22edbb --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/CrossReferences.jl @@ -0,0 +1,227 @@ +""" +Provides the [`crossref`](@ref) function used to automatically calculate link URLs. +""" +module CrossReferences + +import ..Documenter: + Anchors, + Builder, + Documents, + Expanders, + Formats, + Documenter, + Utilities + +using DocStringExtensions +import Markdown + +""" +$(SIGNATURES) + +Traverses a [`Documents.Document`](@ref) and replaces links containg `@ref` URLs with +their real URLs. +""" +function crossref(doc::Documents.Document) + for (src, page) in doc.internal.pages + empty!(page.globals.meta) + for element in page.elements + crossref(page.mapping[element], page, doc) + end + end +end + +function crossref(elem, page, doc) + Documents.walk(page.globals.meta, elem) do link + xref(link, page.globals.meta, page, doc) + end +end + +# Dispatch to `namedxref` / `docsxref`. +# ------------------------------------- + +const NAMED_XREF = r"^@ref (.+)$" + +function xref(link::Markdown.Link, meta, page, doc) + link.url == "@ref" ? basicxref(link, meta, page, doc) : + occursin(NAMED_XREF, link.url) ? namedxref(link, meta, page, doc) : nothing + return false # Stop `walk`ing down this `link` element. +end +xref(other, meta, page, doc) = true # Continue to `walk` through element `other`. + +function basicxref(link::Markdown.Link, meta, page, doc) + if length(link.text) === 1 && isa(link.text[1], Markdown.Code) + docsxref(link, link.text[1].code, meta, page, doc) + elseif isa(link.text, Vector) + # No `name` was provided, since given a `@ref`, so slugify the `.text` instead. + text = strip(sprint(Markdown.plain, Markdown.Paragraph(link.text))) + if occursin(r"#[0-9]+", text) + issue_xref(link, lstrip(text, '#'), meta, page, doc) + else + name = Utilities.slugify(text) + namedxref(link, name, meta, page, doc) + end + end +end + +# Cross referencing headers. +# -------------------------- + +function namedxref(link::Markdown.Link, meta, page, doc) + # Extract the `name` from the `(@ref ...)`. + slug = match(NAMED_XREF, link.url)[1] + if isempty(slug) + text = sprint(Markdown.plaininline, link) + push!(doc.internal.errors, :cross_references) + Utilities.warn(page.source, "'$text' missing a name after '#'.") + else + if Anchors.exists(doc.internal.headers, slug) + namedxref(link, slug, meta, page, doc) + elseif length(link.text) === 1 && isa(link.text[1], Markdown.Code) + docsxref(link, slug, meta, page, doc) + else + namedxref(link, slug, meta, page, doc) + end + end +end + +function namedxref(link::Markdown.Link, slug, meta, page, doc) + headers = doc.internal.headers + # Add the link to list of local uncheck links. + doc.internal.locallinks[link] = link.url + # Error checking: `slug` should exist and be unique. + # TODO: handle non-unique slugs. + if Anchors.exists(headers, slug) + if Anchors.isunique(headers, slug) + # Replace the `@ref` url with a path to the referenced header. + anchor = Anchors.anchor(headers, slug) + path = relpath(anchor.file, dirname(page.build)) + link.url = string(path, '#', slug, '-', anchor.nth) + else + push!(doc.internal.errors, :cross_references) + Utilities.warn(page.source, "'$slug' is not unique.") + end + else + push!(doc.internal.errors, :cross_references) + Utilities.warn(page.source, "Reference for '$slug' could not be found.") + end +end + +# Cross referencing docstrings. +# ----------------------------- + +function docsxref(link::Markdown.Link, code, meta, page, doc) + # Add the link to list of local uncheck links. + doc.internal.locallinks[link] = link.url + # Parse the link text and find current module. + keyword = Symbol(strip(code)) + local ex + if haskey(Docs.keywords, keyword) + ex = QuoteNode(keyword) + else + try + ex = Meta.parse(code) + catch err + !isa(err, Meta.ParseError) && rethrow(err) + push!(doc.internal.errors, :cross_references) + Utilities.warn(page.source, "Unable to parse the reference '[`$code`](@ref)'.") + return + end + end + mod = get(meta, :CurrentModule, Main) + + # Find binding and type signature associated with the link. + local binding + try + binding = Documenter.DocSystem.binding(mod, ex) + catch err + push!(doc.internal.errors, :cross_references) + Utilities.warn(page.source, "Unable to get the binding for '[`$code`](@ref)'.", err, ex, mod) + return + end + + local typesig + try + typesig = Core.eval(mod, Documenter.DocSystem.signature(ex, rstrip(code))) + catch err + push!(doc.internal.errors, :cross_references) + Utilities.warn(page.source, "Unable to evaluate the type signature for '[`$code`](@ref)'.", err, ex, mod) + return + end + + # Try to find a valid object that we can cross-reference. + object = find_object(doc, binding, typesig) + if object !== nothing + # Replace the `@ref` url with a path to the referenced docs. + docsnode = doc.internal.objects[object] + path = relpath(docsnode.page.build, dirname(page.build)) + slug = Utilities.slugify(object) + link.url = string(path, '#', slug) + else + push!(doc.internal.errors, :cross_references) + Utilities.warn(page.source, "No doc found for reference '[`$code`](@ref)'.") + end +end + +""" +$(SIGNATURES) + +Find the included `Object` in the `doc` matching `binding` and `typesig`. The matching +heuristic isn't too picky about what matches and will only fail when no `Binding`s matching +`binding` have been included. +""" +function find_object(doc::Documents.Document, binding, typesig) + object = Utilities.Object(binding, typesig) + if haskey(doc.internal.objects, object) + # Exact object matching the requested one. + return object + else + objects = get(doc.internal.bindings, binding, Utilities.Object[]) + if isempty(objects) + # No bindings match the requested object == FAILED. + return nothing + elseif length(objects) == 1 + # Only one possible choice. Use it even if the signature doesn't match. + return objects[1] + else + candidate = find_object(binding, typesig) + if candidate in objects + # We've found an actual match out of the possible choices! Use it. + return candidate + else + # No match in the possible choices. Use the one that was first included. + return objects[1] + end + end + end +end +function find_object(binding, typesig) + if Documenter.DocSystem.defined(binding) + local λ = Documenter.DocSystem.resolve(binding) + return find_object(λ, binding, typesig) + else + return Utilities.Object(binding, typesig) + end +end +function find_object(λ::Union{Function, DataType}, binding, typesig) + if hasmethod(λ, typesig) + signature = getsig(λ, typesig) + return Utilities.Object(binding, signature) + else + return Utilities.Object(binding, typesig) + end +end +find_object(::Union{Function, DataType}, binding, ::Union{Union,Type{Union{}}}) = Utilities.Object(binding, Union{}) +find_object(other, binding, typesig) = Utilities.Object(binding, typesig) + +getsig(λ::Union{Function, DataType}, typesig) = Base.tuple_type_tail(which(λ, typesig).sig) + + +# Issues/PRs cross referencing. +# ----------------------------- + +function issue_xref(link::Markdown.Link, num, meta, page, doc) + link.url = isempty(doc.internal.remote) ? link.url : + "https://github.com/$(doc.internal.remote)/issues/$num" +end + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Deps.jl b/embedded/Documenter.jl-0.20.0/src/Deps.jl new file mode 100644 index 0000000..1dd1302 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Deps.jl @@ -0,0 +1,52 @@ +""" +Exported module that provides build and deploy dependencies and related functions. + +Currently only [`pip`](@ref) is implemented. +""" +module Deps + +export pip + +using DocStringExtensions + +""" +$(SIGNATURES) + +Installs (as non-root user) all python packages listed in `deps`. + +# Examples + +```julia +using Documenter + +makedocs( + # ... +) + +deploydocs( + deps = Deps.pip("pygments", "mkdocs", "mkdocs-material"), + # ... +) +``` +""" +function pip(deps...) + for dep in deps + run(`pip install --user $(dep)`) + end +end + + +function localbin() + Sys.islinux() ? joinpath(homedir(), ".local", "bin") : + Sys.isapple() ? joinpath(homedir(), "Library", "Python", "2.7", "bin") : "" +end + +function updatepath!(p = localbin()) + if occursin(p, ENV["PATH"]) + ENV["PATH"] + else + ENV["PATH"] = "$p:$(ENV["PATH"])" + end +end + +end diff --git a/embedded/Documenter.jl-0.20.0/src/DocChecks.jl b/embedded/Documenter.jl-0.20.0/src/DocChecks.jl new file mode 100644 index 0000000..0dae52f --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/DocChecks.jl @@ -0,0 +1,224 @@ +""" +Provides the [`missingdocs`](@ref), [`footnotes`](@ref) and [`linkcheck`](@ref) functions +for checking docs. +""" +module DocChecks + +import ..Documenter: + Documenter, + Documents, + Utilities + +using DocStringExtensions +import Markdown + +# Missing docstrings. +# ------------------- + +""" +$(SIGNATURES) + +Checks that a [`Documents.Document`](@ref) contains all available docstrings that are +defined in the `modules` keyword passed to [`Documenter.makedocs`](@ref). + +Prints out the name of each object that has not had its docs spliced into the document. +""" +function missingdocs(doc::Documents.Document) + doc.user.checkdocs === :none && return + println(" > checking for missing docstrings.") + bindings = allbindings(doc.user.checkdocs, doc.user.modules) + for object in keys(doc.internal.objects) + if haskey(bindings, object.binding) + signatures = bindings[object.binding] + if object.signature ≡ Union{} || length(signatures) ≡ 1 + delete!(bindings, object.binding) + elseif object.signature in signatures + delete!(signatures, object.signature) + end + end + end + n = reduce(+, map(length, values(bindings)), init=0) + if n > 0 + b = IOBuffer() + println(b, "$n docstring$(n ≡ 1 ? "" : "s") potentially missing:\n") + for (binding, signatures) in bindings + for sig in signatures + println(b, " $binding", sig ≡ Union{} ? "" : " :: $sig") + end + end + push!(doc.internal.errors, :missing_docs) + Utilities.warn(String(take!(b))) + end +end + +function allbindings(checkdocs::Symbol, mods) + out = Dict{Utilities.Binding, Set{Type}}() + for m in mods + allbindings(checkdocs, m, out) + end + out +end + +function allbindings(checkdocs::Symbol, mod::Module, out = Dict{Utilities.Binding, Set{Type}}()) + for (obj, doc) in meta(mod) + isa(obj, IdDict{Any,Any}) && continue + name = nameof(obj) + isexported = Base.isexported(mod, name) + if checkdocs === :all || (isexported && checkdocs === :exports) + out[Utilities.Binding(mod, name)] = Set(sigs(doc)) + end + end + out +end + +meta(m) = Docs.meta(m) + +nameof(b::Base.Docs.Binding) = b.var +nameof(x) = Base.nameof(x) + +sigs(x::Base.Docs.MultiDoc) = x.order +sigs(::Any) = Type[Union{}] + + +# Footnote checks. +# ---------------- +""" +$(SIGNATURES) + +Checks footnote links in a [`Documents.Document`](@ref). +""" +function footnotes(doc::Documents.Document) + println(" > checking footnote links.") + # A mapping of footnote ids to a tuple counter of how many footnote references and + # footnote bodies have been found. + # + # For all ids the final result should be `(N, 1)` where `N > 1`, i.e. one or more + # footnote references and a single footnote body. + footnotes = Dict{Documents.Page, Dict{String, Tuple{Int, Int}}}() + for (src, page) in doc.internal.pages + empty!(page.globals.meta) + orphans = Dict{String, Tuple{Int, Int}}() + for element in page.elements + Documents.walk(page.globals.meta, page.mapping[element]) do block + footnote(block, orphans) + end + end + footnotes[page] = orphans + end + for (page, orphans) in footnotes + for (id, (ids, bodies)) in orphans + # Multiple footnote bodies. + if bodies > 1 + push!(doc.internal.errors, :footnote) + Utilities.warn(page.source, "Footnote '$id' has $bodies bodies.") + end + # No footnote references for an id. + if ids === 0 + push!(doc.internal.errors, :footnote) + Utilities.warn(page.source, "Unused footnote named '$id'.") + end + # No footnote bodies for an id. + if bodies === 0 + push!(doc.internal.errors, :footnote) + Utilities.warn(page.source, "No footnotes found for '$id'.") + end + end + end +end + +function footnote(fn::Markdown.Footnote, orphans::Dict) + ids, bodies = get(orphans, fn.id, (0, 0)) + if fn.text === nothing + # Footnote references: syntax `[^1]`. + orphans[fn.id] = (ids + 1, bodies) + return false # No more footnotes inside footnote references. + else + # Footnote body: syntax `[^1]:`. + orphans[fn.id] = (ids, bodies + 1) + return true # Might be footnotes inside footnote bodies. + end +end + +footnote(other, orphans::Dict) = true + +# Link Checks. +# ------------ + +hascurl() = (try; success(`curl --version`); catch err; false; end) + +""" +$(SIGNATURES) + +Checks external links using curl. +""" +function linkcheck(doc::Documents.Document) + if doc.user.linkcheck + if hascurl() + println(" > checking external URLs:") + for (src, page) in doc.internal.pages + println(" - ", src) + for element in page.elements + Documents.walk(page.globals.meta, page.mapping[element]) do block + linkcheck(block, doc) + end + end + end + else + push!(doc.internal.errors, :linkcheck) + Utilities.warn("linkcheck requires `curl`.") + end + end + return nothing +end + +function linkcheck(link::Markdown.Link, doc::Documents.Document) + INDENT = " "^6 + + # first, make sure we're not supposed to ignore this link + for r in doc.user.linkcheck_ignore + if linkcheck_ismatch(r, link.url) + printstyled(INDENT, "--- ", link.url, "\n", color=:normal) + return false + end + end + + if !haskey(doc.internal.locallinks, link) + local result + try + result = read(`curl -sI $(link.url) --max-time 10`, String) + catch err + push!(doc.internal.errors, :linkcheck) + Utilities.warn("`curl -sI $(link.url)` failed:\n\n$(err)") + return false + end + local STATUS_REGEX = r"^HTTP/(1.1|2) (\d+) (.+)$"m + if occursin(STATUS_REGEX, result) + status = parse(Int, match(STATUS_REGEX, result).captures[2]) + if status < 300 + printstyled(INDENT, "$(status) ", link.url, "\n", color=:green) + elseif status < 400 + LOCATION_REGEX = r"^Location: (.+)$"m + if occursin(LOCATION_REGEX, result) + location = strip(match(LOCATION_REGEX, result).captures[1]) + printstyled(INDENT, "$(status) ", link.url, "\n", color=:yellow) + printstyled(INDENT, " -> ", location, "\n\n", color=:yellow) + else + printstyled(INDENT, "$(status) ", link.url, "\n", color=:yellow) + end + else + push!(doc.internal.errors, :linkcheck) + printstyled(INDENT, "$(status) ", link.url, "\n", color=:red) + end + else + push!(doc.internal.errors, :linkcheck) + Utilities.warn("invalid result returned by `curl -sI $(link.url)`:\n\n$(result)") + end + end + return false +end +linkcheck(other, doc::Documents.Document) = true + +linkcheck_ismatch(r::String, url) = (url == r) +linkcheck_ismatch(r::Regex, url) = occursin(r, url) + +end diff --git a/embedded/Documenter.jl-0.20.0/src/DocSystem.jl b/embedded/Documenter.jl-0.20.0/src/DocSystem.jl new file mode 100644 index 0000000..d1a4240 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/DocSystem.jl @@ -0,0 +1,270 @@ +""" +Provides a consistent interface to retreiving `DocStr` objects from the Julia +docsystem in both `0.4` and `0.5`. +""" +module DocSystem + +using DocStringExtensions +import Markdown +import Base.Docs: MultiDoc, parsedoc, formatdoc, DocStr + +## Bindings ## + +""" +Converts an object to a `Base.Docs.Binding` object. + +$(SIGNATURES) + +Supported inputs are: + +- `Binding` +- `DataType` +- `Function` +- `Module` +- `Symbol` + +Note that unsupported objects will throw an `ArgumentError`. +""" +binding(any::Any) = throw(ArgumentError("cannot convert `$(repr(any))` to a `Binding`.")) + +# +# The simple definitions. +# +binding(b::Docs.Binding) = binding(b.mod, b.var) +binding(d::DataType) = binding(d.name.module, d.name.name) +binding(m::Module) = binding(m, nameof(m)) +binding(s::Symbol) = binding(Main, s) +binding(f::Function) = binding(typeof(f).name.module, typeof(f).name.mt.name) + +# +# We need a lookup table for `IntrinsicFunction`s since they do not track their +# own name and defining module. +# +# Note that `IntrinsicFunction` is exported from `Base` in `0.4`, but not in `0.5`. +# +let INTRINSICS = Dict(map(s -> getfield(Core.Intrinsics, s) => s, names(Core.Intrinsics, all=true))) + global binding(i::Core.IntrinsicFunction) = binding(Core.Intrinsics, INTRINSICS[i]::Symbol) +end + +# +# Normalise the parent module. +# +# This is done within the `Binding` constructor on `0.5`, but not on `0.4`. +# +function binding(m::Module, v::Symbol) + m = nameof(m) === v ? parentmodule(m) : m + Docs.Binding(m, v) +end + +# +# Pseudo-eval of `Expr`s to find their equivalent `Binding`. +# +binding(m::Module, x::Expr) = + Meta.isexpr(x, :.) ? binding(getmod(m, x.args[1]), x.args[2].value) : + Meta.isexpr(x, [:call, :macrocall, :curly]) ? binding(m, x.args[1]) : + Meta.isexpr(x, :where) ? binding(m, x.args[1].args[1]) : + error("`binding` cannot understand expression `$x`.") + +# Helper methods for the above `binding` method. +getmod(m::Module, x::Expr) = getfield(getmod(m, x.args[1]), x.args[2].value) +getmod(m::Module, s::Symbol) = getfield(m, s) + +binding(m::Module, q::QuoteNode) = binding(Main, q.value) + +binding(m::Module, λ::Any) = binding(λ) + +## Signatures. ## + +function signature(x, str::AbstractString) + ts = Base.Docs.signature(x) + (Meta.isexpr(x, :macrocall, 2) && !endswith(strip(str), "()")) ? :(Union{}) : ts +end + +## Docstring containers. ## + + +""" +Construct a `MultiDoc` object from the provided argument. + +Valid inputs are: + +- `Markdown.MD` +- `Docs.FuncDoc` +- `Docs.TypeDoc` + +""" +function multidoc end + +function multidoc(markdown::Markdown.MD) + md = MultiDoc() + sig = Union{} + push!(md.order, sig) + md.docs[sig] = docstr(markdown) + md +end + + + +""" +$(SIGNATURES) + +Construct a `DocStr` object from a `Markdown.MD` object. + +The optional keyword arguments are used to add new data to the `DocStr`'s +`.data` dictionary. +""" +function docstr(md::Markdown.MD; kws...) + data = Dict{Symbol, Any}( + :path => md.meta[:path], + :module => md.meta[:module], + :linenumber => 0, + ) + doc = DocStr(Core.svec(), md, data) + for (key, value) in kws + doc.data[key] = value + end + doc +end +docstr(other) = other + + +## Formatting `DocStr`s. ## + + + + +## Converting docstring caches. ## + +""" +$(SIGNATURES) + +Converts a `0.4`-style docstring cache into a `0.5` one. + +The original docstring cache is not modified. +""" +function convertmeta(meta::IdDict{Any,Any}) + if !haskey(CACHED, meta) + docs = IdDict{Any,Any}() + for (k, v) in meta + if !isa(k, Union{Number, AbstractString, IdDict{Any,Any}}) + docs[binding(k)] = multidoc(v) + end + end + CACHED[meta] = docs + end + CACHED[meta]::IdDict{Any,Any} +end +const CACHED = IdDict{Any,Any}() + + +## Get docs from modules. + +""" +$(SIGNATURES) + +Find all `DocStr` objects that match the provided arguments: + +- `binding`: the name of the object. +- `typesig`: the signature of the object. Default: `Union{}`. +- `compare`: how to compare signatures? Exact (`==`) or subtypes (`<:`). Default: `<:`. +- `modules`: which modules to search through. Default: *all modules*. +- `aliases`: check aliases of `binding` when nothing is found. Default: `true`. + +Returns a `Vector{DocStr}` ordered by definition order in `0.5` and by +`type_morespecific` in `0.4`. +""" +function getdocs( + binding::Docs.Binding, + typesig::Type = Union{}; + compare = (==), + modules = Docs.modules, + aliases = true, + ) + # Fall back to searching all modules if user provides no modules. + modules = isempty(modules) ? Docs.modules : modules + # Keywords are special-cased within the docsystem. Handle those first. + iskeyword(binding) && return [docstr(Base.Docs.keywords[binding.var])] + # Handle all the other possible bindings. + results = DocStr[] + for mod in modules + meta = getmeta(mod) + if haskey(meta, binding) + multidoc = meta[binding]::MultiDoc + for signature in multidoc.order + if compare(typesig, signature) + doc = multidoc.docs[signature] + doc.data[:binding] = binding + doc.data[:typesig] = signature + push!(results, doc) + end + end + end + end + if compare == (==) + # Exact matching of signatures: + # + # When we get a single match from using `==` as the comparision then we just return + # that one result. + # + # Otherwise we fallback to comparing signatures using `<:` to match, hopefully, a + # wider range of possible docstrings. + if length(results) == 1 + results + else + getdocs(binding, typesig; compare = (<:), modules = modules, aliases = aliases) + end + else + # When nothing is found we check whether the `binding` is an alias of some other + # `Binding`. If so then we redo the search using that `Binding` instead. + if aliases && isempty(results) && (b = aliasof(binding)) != binding + getdocs(b, typesig; compare = compare, modules = modules) + else + results + end + end +end + +""" +$(SIGNATURES) + +Accepts objects of any type and tries to convert them to `Binding`s before +searching for the `Binding` in the docsystem. + +Note that when conversion fails this method returns an empty `Vector{DocStr}`. +""" +function getdocs(object::Any, typesig::Type = Union{}; kws...) + binding = aliasof(object, object) + binding === object ? DocStr[] : getdocs(binding, typesig; kws...) +end + +# +# Helper methods used by the `getdocs` function above. +# + +getmeta(m::Module) = Docs.meta(m) + +import Base.Docs: aliasof, resolve, defined + + +aliasof(s::Symbol, b) = binding(s) + +iskeyword(b::Docs.Binding) = b.mod === Main && haskey(Base.Docs.keywords, b.var) +ismacro(b::Docs.Binding) = startswith(string(b.var), '@') + + +function category(b::Docs.Binding) + if iskeyword(b) + :keyword + elseif ismacro(b) + :macro + else + category(resolve(b)) + end +end +category(::Function) = :function +category(::DataType) = :type +category(x::UnionAll) = category(Base.unwrap_unionall(x)) +category(::Module) = :module +category(::Any) = :constant + +end diff --git a/embedded/Documenter.jl-0.20.0/src/DocTests.jl b/embedded/Documenter.jl-0.20.0/src/DocTests.jl new file mode 100644 index 0000000..c978d38 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/DocTests.jl @@ -0,0 +1,455 @@ +""" +Provides the [`doctest`](@ref) function that makes sure that the `jldoctest` code blocks +in the documents and docstrings run and are up to date. +""" +module DocTests +using DocStringExtensions + +import ..Documenter: + Documenter, + Documents, + Expanders, + Utilities + +import Markdown, REPL + +# Julia code block testing. +# ------------------------- + +# escape characters that has a meaning in regex +regex_escape(str) = sprint(escape_string, str, "\\^\$.|?*+()[{") + +# helper to display linerange for error printing +function find_codeblock_in_file(code, file) + content = read(Base.find_source_file(file), String) + content = replace(content, "\r\n" => "\n") + # make a regex of the code that matches leading whitespace + rcode = "\\h*" * replace(regex_escape(code), "\\n" => "\\n\\h*") + blockidx = findfirst(Regex(rcode), content) + if blockidx !== nothing + startline = countlines(IOBuffer(content[1:prevind(content, first(blockidx))])) + endline = startline + countlines(IOBuffer(code)) + 1 # +1 to include the closing ``` + return ":$(startline)-$(endline)" + else + return "" + end +end + +""" +$(SIGNATURES) + +Traverses the document tree and tries to run each Julia code block encountered. Will abort +the document generation when an error is thrown. Use `doctest = false` keyword in +[`Documenter.makedocs`](@ref) to disable doctesting. +""" +function doctest(doc::Documents.Document) + if doc.user.doctest === :fix || doc.user.doctest + println(" > running doctests.") + for (src, page) in doc.internal.pages + empty!(page.globals.meta) + for element in page.elements + page.globals.meta[:CurrentFile] = page.source + Documents.walk(page.globals.meta, page.mapping[element]) do block + doctest(block, page.globals.meta, doc, page) + end + end + end + else + Utilities.warn("Skipped doctesting.") + end +end + +function doctest(block::Markdown.Code, meta::Dict, doc::Documents.Document, page) + lang = block.language + if startswith(lang, "jldoctest") + # Define new module or reuse an old one from this page if we have a named doctest. + name = match(r"jldoctest[ ]?(.*)$", split(lang, ';', limit = 2)[1])[1] + sym = isempty(name) ? gensym("doctest-") : Symbol("doctest-", name) + sandbox = get!(() -> Expanders.get_new_sandbox(sym), page.globals.meta, sym) + + # Normalise line endings. + block.code = replace(block.code, "\r\n" => "\n") + + # parse keyword arguments to doctest + d = Dict() + idx = findfirst(c -> c == ';', lang) + if idx !== nothing + kwargs = Meta.parse("($(lang[nextind(lang, idx):end]),)") + for kwarg in kwargs.args + if !(isa(kwarg, Expr) && kwarg.head === :(=) && isa(kwarg.args[1], Symbol)) + file = meta[:CurrentFile] + lines = find_codeblock_in_file(block.code, file) + Utilities.warn( + """ + Invalid syntax for doctest keyword arguments in $(file)$(lines) + Use ```jldoctest name; key1 = value1, key2 = value2 + + ```$(lang) + $(block.code) + ``` + """ + ) + return false + end + d[kwarg.args[1]] = Core.eval(sandbox, kwarg.args[2]) + end + end + meta[:LocalDocTestArguments] = d + + for expr in [get(meta, :DocTestSetup, []); get(meta[:LocalDocTestArguments], :setup, [])] + Meta.isexpr(expr, :block) && (expr.head = :toplevel) + try + Core.eval(sandbox, expr) + catch e + push!(doc.internal.errors, :doctest) + @error("could not evaluate expression from doctest setup.", + expression = expr, exception = e) + return false + end + end + if occursin(r"^julia> "m, block.code) + eval_repl(block, sandbox, meta, doc, page) + elseif occursin(r"^# output$"m, block.code) + eval_script(block, sandbox, meta, doc, page) + else + push!(doc.internal.errors, :doctest) + file = meta[:CurrentFile] + lines = find_codeblock_in_file(block.code, file) + Utilities.warn( + """ + Invalid doctest block in $(file)$(lines) + Requires `julia> ` or `# output` + + ```$(lang) + $(block.code) + ``` + """ + ) + end + delete!(meta, :LocalDocTestArguments) + end + false +end +doctest(block, meta::Dict, doc::Documents.Document, page) = true + +function doctest(block::Markdown.MD, meta::Dict, doc::Documents.Document, page) + haskey(block.meta, :path) && (meta[:CurrentFile] = block.meta[:path]) + return true +end + +# Doctest evaluation. + +mutable struct Result + block :: Markdown.Code # The entire code block that is being tested. + input :: String # Part of `block.code` representing the current input. + output :: String # Part of `block.code` representing the current expected output. + file :: String # File in which the doctest is written. Either `.md` or `.jl`. + value :: Any # The value returned when evaluating `input`. + hide :: Bool # Semi-colon suppressing the output? + stdout :: IOBuffer # Redirected stdout/stderr gets sent here. + bt :: Vector # Backtrace when an error is thrown. + + function Result(block, input, output, file) + new(block, input, rstrip(output, '\n'), file, nothing, false, IOBuffer()) + end +end + +function eval_repl(block, sandbox, meta::Dict, doc::Documents.Document, page) + for (input, output) in repl_splitter(block.code) + result = Result(block, input, output, meta[:CurrentFile]) + for (ex, str) in Utilities.parseblock(input, doc, page; keywords = false) + # Input containing a semi-colon gets suppressed in the final output. + result.hide = REPL.ends_with_semicolon(str) + (value, success, backtrace, text) = Utilities.withoutput() do + disable_color() do + Core.eval(sandbox, ex) + end + end + result.value = value + print(result.stdout, text) + if success + # Redefine the magic `ans` binding available in the REPL. + __ans__!(sandbox, result.value) + else + result.bt = backtrace + end + end + checkresult(sandbox, result, meta, doc) + end +end + +function __ans__!(m::Module, value) + isdefined(m, :__ans__!) || Core.eval(m, :(__ans__!(value) = global ans = value)) + return Core.eval(m, Expr(:call, () -> m.__ans__!(value))) +end + +function eval_script(block, sandbox, meta::Dict, doc::Documents.Document, page) + # TODO: decide whether to keep `# output` syntax for this. It's a bit ugly. + # Maybe use double blank lines, i.e. + # + # + # to mark `input`/`output` separation. + input, output = split(block.code, "# output\n", limit = 2) + input = rstrip(input, '\n') + output = lstrip(output, '\n') + result = Result(block, input, output, meta[:CurrentFile]) + for (ex, str) in Utilities.parseblock(input, doc, page; keywords = false) + (value, success, backtrace, text) = Utilities.withoutput() do + Core.eval(sandbox, ex) + end + result.value = value + print(result.stdout, text) + if !success + result.bt = backtrace + break + end + end + checkresult(sandbox, result, meta, doc) +end + +function filter_doctests(strings::NTuple{2, AbstractString}, + doc::Documents.Document, meta::Dict) + meta_block_filters = get(meta, :DocTestFilters, []) + meta_block_filters == nothing && meta_block_filters == [] + doctest_local_filters = get(meta[:LocalDocTestArguments], :filter, []) + for r in [doc.user.doctestfilters; meta_block_filters; doctest_local_filters] + if all(occursin.((r,), strings)) + strings = replace.(strings, (r => "",)) + end + end + return strings +end + +# Regex used here to replace gensym'd module names could probably use improvements. +function checkresult(sandbox::Module, result::Result, meta::Dict, doc::Documents.Document) + sandbox_name = nameof(sandbox) + mod_regex = Regex("(Main\\.)?(Symbol\\(\"$(sandbox_name)\"\\)|$(sandbox_name))[,.]") + mod_regex_nodot = Regex(("(Main\\.)?$(sandbox_name)")) + outio = IOContext(result.stdout, :module => sandbox) + if isdefined(result, :bt) # An error was thrown and we have a backtrace. + # To avoid dealing with path/line number issues in backtraces we use `[...]` to + # mark ignored output from an error message. Only the text prior to it is used to + # test for doctest success/failure. + head = replace(split(result.output, "\n[...]"; limit = 2)[1], mod_regex => "") + head = replace(head, mod_regex_nodot => "Main") + str = replace(error_to_string(outio, result.value, result.bt), mod_regex => "") + str = replace(str, mod_regex_nodot => "Main") + + str, head = filter_doctests((str, head), doc, meta) + # Since checking for the prefix of an error won't catch the empty case we need + # to check that manually with `isempty`. + if isempty(head) || !startswith(str, head) + if doc.user.doctest === :fix + fix_doctest(result, str, doc) + else + report(result, str, doc) + end + end + else + value = result.hide ? nothing : result.value # `;` hides output. + output = replace(rstrip(sanitise(IOBuffer(result.output))), mod_regex => "") + str = replace(result_to_string(outio, value), mod_regex => "") + # Replace a standalone module name with `Main`. + str = rstrip(replace(str, mod_regex_nodot => "Main")) + filteredstr, filteredoutput = filter_doctests((str, output), doc, meta) + if filteredstr != filteredoutput + if doc.user.doctest === :fix + fix_doctest(result, str, doc) + else + report(result, str, doc) + end + end + end + return nothing +end + +# Display doctesting results. + +function result_to_string(buf, value) + dis = text_display(buf) + value === nothing || disable_color() do + Core.eval(Main, Expr(:call, display, dis, QuoteNode(value))) + end + sanitise(buf) +end + +text_display(buf) = TextDisplay(IOContext(buf, :limit => true)) + +funcsym() = CAN_INLINE[] ? :disable_color : :eval + +function error_to_string(buf, er, bt) + fs = funcsym() + # Remove unimportant backtrace info. + index = findlast(ptr -> Base.ip_matches_func(ptr, fs), bt) + # Print a REPL-like error message. + disable_color() do + print(buf, "ERROR: ") + Base.invokelatest(showerror, buf, er, index === nothing ? bt : bt[1:(index - 1)]) + end + sanitise(buf) +end + +# Strip trailing whitespace and remove terminal colors. +function sanitise(buffer) + out = IOBuffer() + for line in eachline(seekstart(Base.unwrapcontext(buffer)[1])) + println(out, rstrip(line)) + end + remove_term_colors(rstrip(String(take!(out)), '\n')) +end + +import .Utilities.TextDiff + +function report(result::Result, str, doc::Documents.Document) + iob = IOBuffer() + ioc = IOContext(iob, :color => Base.have_color) + println(ioc, "=====[Test Error]", "="^30) + println(ioc) + printstyled(ioc, "> Location: ", result.file, color=:cyan) + printstyled(ioc, find_codeblock_in_file(result.block.code, result.file), color=:cyan) + printstyled(ioc, "\n\n> Code block:\n", color=:cyan) + println(ioc, "\n```$(result.block.language)") + println(ioc, result.block.code) + println(ioc, "```") + if !isempty(result.input) + printstyled(ioc, "\n> Subexpression:\n", color=:cyan) + print_indented(ioc, result.input; indent = 4) + end + warning = Base.have_color ? "" : " (REQUIRES COLOR)" + printstyled(ioc, "\n> Output Diff", warning, ":\n\n", color=:cyan) + diff = TextDiff.Diff{TextDiff.Words}(result.output, rstrip(str)) + Utilities.TextDiff.showdiff(ioc, diff) + println(ioc, "\n\n", "=====[End Error]=", "="^30) + push!(doc.internal.errors, :doctest) + printstyled(String(take!(iob)), color=:normal) +end + +function print_indented(buffer::IO, str::AbstractString; indent = 4) + println(buffer) + for line in split(str, '\n') + println(buffer, " "^indent, line) + end +end + +function fix_doctest(result::Result, str, doc::Documents.Document) + code = result.block.code + filename = Base.find_source_file(result.file) + # read the file containing the code block + content = read(filename, String) + # output stream + io = IOBuffer(sizehint = sizeof(content)) + # first look for the entire code block + # make a regex of the code that matches leading whitespace + rcode = "(\\h*)" * replace(regex_escape(code), "\\n" => "\\n\\h*") + r = Regex(rcode) + codeidx = findfirst(r, content) + if codeidx === nothing + Utilities.warn("Could not find code block in source file") + return + end + # use the capture group to identify indentation + indent = match(r, content).captures[1] + # write everything up until the code block + write(io, content[1:prevind(content, first(codeidx))]) + # next look for the particular input string in the given code block + # make a regex of the input that matches leading whitespace (for multiline input) + rinput = "\\h*" * replace(regex_escape(result.input), "\\n" => "\\n\\h*") + r = Regex(rinput) + inputidx = findfirst(r, code) + if inputidx === nothing + Utilities.warn("Could not find input line in code block") + return + end + # construct the new code-snippet (without indent) + # first part: everything up until the last index of the input string + newcode = code[1:last(inputidx)] + isempty(result.output) && (newcode *= '\n') # issue #772 + # second part: the rest, with the old output replaced with the new one + newcode *= replace(code[nextind(code, last(inputidx)):end], result.output => str, count = 1) + # replace internal code block with the non-indented new code, needed if we come back + # looking to replace output in the same code block later + result.block.code = newcode + # write the new code snippet to the stream, with indent + newcode = replace(newcode, r"^(.+)$"m => Base.SubstitutionString(indent * "\\1")) + write(io, newcode) + # write rest of the file + write(io, content[nextind(content, last(codeidx)):end]) + # write to file + write(filename, seekstart(io)) + return +end + +# Remove terminal colors. + +const TERM_COLOR_REGEX = r"\e\[[0-9;]*m" +remove_term_colors(s) = replace(s, TERM_COLOR_REGEX => "") + +# REPL doctest splitter. + +const PROMPT_REGEX = r"^julia> (.*)$" +const SOURCE_REGEX = r"^ (.*)$" +const ANON_FUNC_DECLARATION = r"#[0-9]+ \(generic function with [0-9]+ method(s)?\)" + +function repl_splitter(code) + lines = split(string(code, "\n"), '\n') + input = String[] + output = String[] + buffer = IOBuffer() + while !isempty(lines) + line = popfirst!(lines) + # REPL code blocks may contain leading lines with comments. Drop them. + # TODO: handle multiline comments? + # ANON_FUNC_DECLARATION deals with `x->x` -> `#1 (generic function ....)` on 0.7 + # TODO: Remove this special case and just disallow lines with comments? + startswith(line, '#') && !occursin(ANON_FUNC_DECLARATION, line) && continue + prompt = match(PROMPT_REGEX, line) + if prompt === nothing + source = match(SOURCE_REGEX, line) + if source === nothing + savebuffer!(input, buffer) + println(buffer, line) + takeuntil!(PROMPT_REGEX, buffer, lines) + else + println(buffer, source[1]) + end + else + savebuffer!(output, buffer) + println(buffer, prompt[1]) + end + end + savebuffer!(output, buffer) + zip(input, output) +end + +function savebuffer!(out, buf) + n = bytesavailable(seekstart(buf)) + n > 0 ? push!(out, rstrip(String(take!(buf)))) : out +end + +function takeuntil!(r, buf, lines) + while !isempty(lines) + line = lines[1] + if !occursin(r, line) + println(buf, popfirst!(lines)) + else + break + end + end +end + +function disable_color(func) + color = Base.have_color + try + @eval Base have_color = false + func() + finally + @eval Base have_color = $color + end +end + +const CAN_INLINE = Ref(true) +function __init__() + CAN_INLINE[] = Base.JLOptions().can_inline == 0 ? false : true +end + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Documenter.jl b/embedded/Documenter.jl-0.20.0/src/Documenter.jl new file mode 100644 index 0000000..39cdde2 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Documenter.jl @@ -0,0 +1,642 @@ +""" +Main module for `Documenter.jl` -- a documentation generation package for Julia. + +Two functions are exported from this module for public use: + +- [`makedocs`](@ref). Generates documentation from docstrings and templated markdown files. +- [`deploydocs`](@ref). Deploys generated documentation from *Travis-CI* to *GitHub Pages*. + +# Exports + +$(EXPORTS) + +""" +module Documenter + +using DocStringExtensions +import Base64: base64decode +import Pkg + +# Submodules +# ---------- + +include("Utilities/Utilities.jl") +include("DocSystem.jl") +include("Formats.jl") +include("Anchors.jl") +include("Documents.jl") +include("Builder.jl") +include("Expanders.jl") +include("CrossReferences.jl") +include("DocTests.jl") +include("DocChecks.jl") +include("Writers/Writers.jl") +include("Deps.jl") + +import .Utilities: Selectors + + +# User Interface. +# --------------- + +export Deps, makedocs, deploydocs, hide + +""" + makedocs( + root = "", + source = "src", + build = "build", + clean = true, + doctest = true, + modules = Module[], + repo = "", + ) + +Combines markdown files and inline docstrings into an interlinked document. +In most cases [`makedocs`](@ref) should be run from a `make.jl` file: + +```julia +using Documenter +makedocs( + # keywords... +) +``` + +which is then run from the command line with: + +```sh +\$ julia make.jl +``` + +The folder structure that [`makedocs`](@ref) expects looks like: + + docs/ + build/ + src/ + make.jl + +# Keywords + +**`root`** is the directory from which `makedocs` should run. When run from a `make.jl` file +this keyword does not need to be set. It is, for the most part, needed when repeatedly +running `makedocs` from the Julia REPL like so: + + julia> makedocs(root = Pkg.dir("MyPackage", "docs")) + +**`source`** is the directory, relative to `root`, where the markdown source files are read +from. By convention this folder is called `src`. Note that any non-markdown files stored +in `source` are copied over to the build directory when [`makedocs`](@ref) is run. + +**`build`** is the directory, relative to `root`, into which generated files and folders are +written when [`makedocs`](@ref) is run. The name of the build directory is, by convention, +called `build`, though, like with `source`, users are free to change this to anything else +to better suit their project needs. + +**`clean`** tells [`makedocs`](@ref) whether to remove all the content from the `build` +folder prior to generating new content from `source`. By default this is set to `true`. + +**`doctest`** instructs [`makedocs`](@ref) on whether to try to test Julia code blocks +that are encountered in the generated document. By default this keyword is set to `true`. +Doctesting should only ever be disabled when initially setting up a newly developed package +where the developer is just trying to get their package and documentation structure correct. +After that, it's encouraged to always make sure that documentation examples are runnable and +produce the expected results. See the [Doctests](@ref) manual section for details about +running doctests. + +**`modules`** specifies a vector of modules that should be documented in `source`. If any +inline docstrings from those modules are seen to be missing from the generated content then +a warning will be printed during execution of [`makedocs`](@ref). By default no modules are +passed to `modules` and so no warnings will appear. This setting can be used as an indicator +of the "coverage" of the generated documentation. +For example Documenter's `make.jl` file contains: + +```julia +makedocs( + modules = [Documenter], + # ... +) +``` + +and so any docstring from the module `Documenter` that is not spliced into the generated +documentation in `build` will raise a warning. + +**`repo`** specifies a template for the "link to source" feature. If you are +using GitHub, this is automatically generated from the remote. If you are using +a different host, you can use this option to tell Documenter how URLs should be +generated. The following placeholders will be replaced with the respective +value of the generated link: + + - `{commit}` Git branch or tag name, or commit hash + - `{path}` Path to the file in the repository + - `{line}` Line (or range of lines) in the source file + +For example if you are using GitLab.com, you could use + +```julia +makedocs(repo = \"https://gitlab.com/user/project/blob/{commit}{path}#{line}\") +``` + +# Experimental keywords + +In addition to standard arguments there is a set of non-finalized experimental keyword +arguments. The behaviour of these may change or they may be removed without deprecation +when a minor version changes (i.e. except in patch releases). + +**`checkdocs`** instructs [`makedocs`](@ref) to check whether all names within the modules +defined in the `modules` keyword that have a docstring attached have the docstring also +listed in the manual (e.g. there's a `@docs` blocks with that docstring). Possible values +are `:all` (check all names) and `:exports` (check only exported names). The default value +is `:none`, in which case no checks are performed. If `strict` is also enabled then the +build will fail if any missing docstrings are encountered. + +**`linkcheck`** -- if set to `true` [`makedocs`](@ref) uses `curl` to check the status codes +of external-pointing links, to make sure that they are up-to-date. The links and their +status codes are printed to the standard output. If `strict` is also enabled then the build +will fail if there are any broken (400+ status code) links. Default: `false`. + +**`linkcheck_ignore`** allows certain URLs to be ignored in `linkcheck`. The values should +be a list of strings (which get matched exactly) or `Regex` objects. By default nothing is +ignored. + +**`strict`** -- [`makedocs`](@ref) fails the build right before rendering if it encountered +any errors with the document in the previous build phases. + +## Output formats + +**`format`** allows the output format to be specified. Possible values are `:html` (default), +`:latex` and `:markdown`. + +Documenter is designed to support multiple output formats. By default it is creates a set of +HTML files, but the output format can be controlled with the `format` keyword. The different +output formats may require additional keywords to be specified. The keywords for the default +HTML output are documented at the [`Writers.HTMLWriter`](@ref) module. + +Documenter also has (experimental) support for Markdown and LaTeX / PDF outputs. See the +[Other Output Formats](@ref) for more information. + +!!! warning + + The Markdown and LaTeX output formats will be moved to a separate package in future + versions of Documenter. Automatic documentation deployments should not rely on it unless + they fix Documenter to a minor version. + +# See Also + +A guide detailing how to document a package using Documenter's [`makedocs`](@ref) is provided +in the [setup guide in the manual](@ref Package-Guide). +""" +function makedocs(; debug = false, args...) + document = Documents.Document(; args...) + cd(document.user.root) do + Selectors.dispatch(Builder.DocumentPipeline, document) + end + debug ? document : nothing +end + +""" +$(SIGNATURES) + +Allows a page to be hidden in the navigation menu. It will only show up if it happens to be +the current page. The hidden page will still be present in the linear page list that can be +accessed via the previous and next page links. The title of the hidden page can be overriden +using the `=>` operator as usual. + +# Usage + +```julia +makedocs( + ..., + pages = [ + ..., + hide("page1.md"), + hide("Title" => "page2.md") + ] +) +``` +""" +hide(page::Pair) = (false, page.first, page.second, []) +hide(page::AbstractString) = (false, nothing, page, []) + +""" +$(SIGNATURES) + +Allows a subsection of pages to be hidden from the navigation menu. `root` will be linked +to in the navigation menu, with the title determined as usual. `children` should be a list +of pages (note that it **can not** be hierarchical). + +# Usage + +```julia +makedocs( + ..., + pages = [ + ..., + hide("Hidden section" => "hidden_index.md", [ + "hidden1.md", + "Hidden 2" => "hidden2.md" + ]), + hide("hidden_index.md", [...]) + ] +) +``` +""" +hide(root::Pair, children) = (true, root.first, root.second, map(hide, children)) +hide(root::AbstractString, children) = (true, nothing, root, map(hide, children)) + +""" + deploydocs( + root = "", + target = "build", + repo = "", + branch = "gh-pages", + deps = nothing | , + make = nothing | , + devbranch = "master", + devurl = "dev", + versions = ["stable" => "v^", "v#.#", devurl => devurl] + ) + +Converts markdown files generated by [`makedocs`](@ref) to HTML and pushes them to `repo`. +This function should be called from within a package's `docs/make.jl` file after the call to +[`makedocs`](@ref), like so + +```julia +using Documenter, PACKAGE_NAME +makedocs( + # options... +) +deploydocs( + repo = "github.com/..." +) +``` + +When building the docs for a tag (i.e. a release) the documentation is deployed to +a directory with the tag name (i.e. `vX.Y.Z`) and to the `stable` directory. +Otherwise the docs are deployed to the directory determined by the `devurl` argument. + +# Required keyword arguments + +**`repo`** is the remote repository where generated HTML content should be pushed to. Do not +specify any protocol - "https://" or "git@" should not be present. This keyword *must* +be set and will throw an error when left undefined. For example this package uses the +following `repo` value: + +```julia +repo = "github.com/JuliaDocs/Documenter.jl.git" +``` + +# Optional keyword arguments + +**`root`** has the same purpose as the `root` keyword for [`makedocs`](@ref). + +**`target`** is the directory, relative to `root`, where generated content that should be +deployed to `gh-pages` is written to. written to. It should generally be the same as +[`makedocs`](@ref)'s `build` and defaults to `"build"`. + +**`branch`** is the branch where the generated documentation is pushed. If the branch does +not exist, a new orphaned branch is created automatically. It defaults to `"gh-pages"`. + +**`deps`** is the function used to install any additional dependencies needed to build the +documentation. By default nothing is installed. + +It can be used e.g. for a Markdown build. The following example installed the `pygments` and +`mkdocs` Python packages using the [`Deps.pip`](@ref) function: + +```julia +deps = Deps.pip("pygments", "mkdocs") +``` + +**`make`** is the function used to specify an additonal build phase. By default, nothing gets +executed. + +**`devbranch`** is the branch that "tracks" the in-development version of the generated +documentation. By default this value is set to `"master"`. + +**`devurl`** the folder that in-development version of the docs will be deployed. +Defaults to `"dev"`. + +**`versions`** determines content and order of the resulting version selector in +the generated html. The following entries are valied in the `versions` vector: + - `"v#"`: includes links to the latest documentation for each major release cycle + (i.e. `v2.0`, `v1.1`). + - `"v#.#"`: includes links to the latest documentation for each minor release cycle + (i.e. `v2.0`, `v1.1`, `v1.0`, `v0.1`). + - `"v#.#.#"`: includes links to all released versions. + - `"v^"`: includes a link to the docs for the maximum version + (i.e. a link `vX.Y` pointing to `vX.Y.Z` for highest `X`, `Y`, `Z`, respectively). + - A pair, e.g. `"first" => "second"`, which will put `"first"` in the selector, + and generate a url from which `"second"` can be accessed. + The second argument can be `"v^"`, to point to the maximum version docs + (as in e.g. `"stable" => "v^"`). + +# See Also + +The [Hosting Documentation](@ref) section of the manual provides a step-by-step guide to +using the [`deploydocs`](@ref) function to automatically generate docs and push them to +GitHub. +""" +function deploydocs(; + root = Utilities.currentdir(), + target = "build", + dirname = "", + + repo = error("no 'repo' keyword provided."), + branch = "gh-pages", + latest::Union{String,Nothing} = nothing, # deprecated + + osname::Union{String,Nothing} = nothing, # deprecated + julia::Union{String,Nothing} = nothing, # deprecated + + deps = nothing, + make = nothing, + + devbranch = "master", + devurl = "dev", + versions = ["stable" => "v^", "v#.#", devurl => devurl] + ) + # deprecation of latest kwarg (renamed to devbranch) + if latest !== nothing + Base.depwarn("The `latest` keyword argument has been renamed to `devbranch`.", :deploydocs) + devbranch = latest + @info("setting `devbranch` to `$(devbranch)`.") + end + # deprecation/removal of `julia` and `osname` kwargs + if julia !== nothing + Base.depwarn("the `julia` keyword argument to `Documenter.deploydocs` is " * + "removed. Use Travis Build Stages for determining from where to deploy instead. " * + "See the section about Hosting in the Documenter manual for more details.", :deploydocs) + @info("skipping docs deployment.") + return + end + if osname !== nothing + Base.depwarn("the `osname` keyword argument to `Documenter.deploydocs` is " * + "removed. Use Travis Build Stages for determining from where to deploy instead. " * + "See the section about Hosting in the Documenter manual for more details.", :deploydocs) + @info("skipping docs deployment.") + return + end + + # Get environment variables. + documenter_key = get(ENV, "DOCUMENTER_KEY", "") + travis_branch = get(ENV, "TRAVIS_BRANCH", "") + travis_pull_request = get(ENV, "TRAVIS_PULL_REQUEST", "") + travis_repo_slug = get(ENV, "TRAVIS_REPO_SLUG", "") + travis_tag = get(ENV, "TRAVIS_TAG", "") + + + # Other variables. + sha = cd(root) do + # We'll make sure we run the git commands in the source directory (root), in case + # the working directory has been changed (e.g. if the makedocs' build argument is + # outside root). + try + readchomp(`git rev-parse --short HEAD`) + catch + # git rev-parse will throw an error and return code 128 if it is not being + # run in a git repository, which will make run/readchomp throw an exception. + # We'll assume that if readchomp fails it is due to this and set the sha + # variable accordingly. + "(not-git-repo)" + end + end + + # Sanity checks + if !isempty(travis_repo_slug) && !occursin(travis_repo_slug, repo) + @warn("repo $repo does not match $travis_repo_slug") + end + + # When should a deploy be attempted? + should_deploy = + occursin(travis_repo_slug, repo) && + travis_pull_request == "false" && + ( + travis_branch == devbranch || + travis_tag != "" + ) + + # check that the tag is valid + if should_deploy && !isempty(travis_tag) && !occursin(Base.VERSION_REGEX, travis_tag) + @warn("tag `$(travis_tag)` is not a valid VersionNumber") + should_deploy = false + end + + # check DOCUMENTER_KEY only if the branch, Julia version etc. check out + if should_deploy && isempty(documenter_key) + @warn(""" + DOCUMENTER_KEY environment variable missing, unable to deploy. + Note that in Documenter v0.9.0 old deprecated authentication methods were removed. + DOCUMENTER_KEY is now the only option. See the documentation for more information.""") + should_deploy = false + end + + if get(ENV, "DOCUMENTER_DEBUG", "") == "true" + Utilities.debug("TRAVIS_REPO_SLUG = \"$travis_repo_slug\"") + Utilities.debug(" should occur in \"$repo\" (kwarg: repo)") + Utilities.debug("TRAVIS_PULL_REQUEST = \"$travis_pull_request\"") + Utilities.debug(" deploying if equal to \"false\"") + Utilities.debug("TRAVIS_BRANCH = \"$travis_branch\"") + Utilities.debug("TRAVIS_TAG = \"$travis_tag\"") + Utilities.debug(" deploying if branch equal to \"$devbranch\" (kwarg: devbranch) or tag is set") + Utilities.debug("git commit SHA = $sha") + Utilities.debug("DOCUMENTER_KEY exists = $(!isempty(documenter_key))") + Utilities.debug("should_deploy = $should_deploy") + end + + if should_deploy + # Add local bin path if needed. + Deps.updatepath!() + # Install dependencies when applicable. + if deps !== nothing + Utilities.log("installing dependencies.") + deps() + end + # Change to the root directory and try to deploy the docs. + cd(root) do + Utilities.log("setting up target directory.") + isdir(target) || mkpath(target) + # Run extra build steps defined in `make` if required. + if make !== nothing + Utilities.log("running extra build steps.") + make() + end + Utilities.log("pushing new documentation to remote: $repo:$branch.") + mktempdir() do temp + git_push( + root, temp, repo; + branch=branch, dirname=dirname, target=target, + tag=travis_tag, key=documenter_key, sha=sha, + devurl = devurl, versions = versions, + ) + end + end + else + Utilities.log("skipping docs deployment.") + if get(ENV, "DOCUMENTER_DEBUG", "") != "true" + Utilities.log("You can set DOCUMENTER_DEBUG to \"true\" in Travis to see more information.") + end + end +end + +""" + git_push( + root, tmp, repo; + branch="gh-pages", dirname="", target="site", tag="", key="", sha="", devurl="dev" + ) + +Handles pushing changes to the remote documentation branch. +When `tag` is empty the docs are deployed to the `devurl` directory, +and when building docs for a tag they are deployed to a `vX.Y.Z` directory. +""" +function git_push( + root, temp, repo; + branch="gh-pages", dirname="", target="site", tag="", key="", sha="", devurl="dev", + versions + ) + dirname = isempty(dirname) ? temp : joinpath(temp, dirname) + isdir(dirname) || mkpath(dirname) + + keyfile = abspath(joinpath(root, ".documenter")) + target_dir = abspath(target) + + # The upstream URL to which we push new content and the ssh decryption commands. + upstream = "git@$(replace(repo, "github.com/" => "github.com:"))" + + write(keyfile, String(base64decode(key))) + chmod(keyfile, 0o600) + + try + # Use a custom SSH config file to avoid overwriting the default user config. + withfile(joinpath(homedir(), ".ssh", "config"), + """ + Host github.com + StrictHostKeyChecking no + HostName github.com + IdentityFile $keyfile + """ + ) do + cd(temp) do + # Setup git. + run(`git init`) + run(`git config user.name "autodocs"`) + run(`git config user.email "autodocs"`) + + # Fetch from remote and checkout the branch. + run(`git remote add upstream $upstream`) + run(`git fetch upstream`) + + try + run(`git checkout -b $branch upstream/$branch`) + catch e + Utilities.log("Checking out $branch failed with error: $e") + Utilities.log("Creating a new local $branch branch.") + run(`git checkout --orphan $branch`) + run(`git commit --allow-empty -m "Initial empty commit for docs"`) + end + + # Copy docs to `devurl`, or `stable`, ``, and `` directories. + if isempty(tag) + devurl_dir = joinpath(dirname, devurl) + gitrm_copy(target_dir, devurl_dir) + Writers.HTMLWriter.generate_siteinfo_file(devurl_dir, devurl) + # symlink "latest" to devurl to preserve links (remove in some future release) + if devurl != "latest" + rm(joinpath(dirname, "latest"); recursive = true, force = true) + @warn(string("creating symlink from `latest` to `$(devurl)` for backwards ", + "compatibility with old links. In future Documenter versions this symlink ", + "will not be created. Please update any links that point to `latest`.")) + cd(dirname) do; rm_and_add_symlink(devurl, "latest"); end + end + else + tagged_dir = joinpath(dirname, tag) + gitrm_copy(target_dir, tagged_dir) + Writers.HTMLWriter.generate_siteinfo_file(tagged_dir, tag) + end + + # Expand the users `versions` vector + entries, symlinks = Writers.HTMLWriter.expand_versions(dirname, versions) + + # Create the versions.js file containing a list of `entries`. + # This must always happen after the folder copying. + Writers.HTMLWriter.generate_version_file(joinpath(dirname, "versions.js"), entries) + + # generate the symlinks, make sure we don't overwrite devurl + cd(dirname) do + for kv in symlinks + i = findfirst(x -> x.first == devurl, symlinks) + if i === nothing + rm_and_add_symlink(kv.second, kv.first) + else + throw(ArgumentError(string("link `$(kv)` cannot overwrite ", + "`devurl = $(devurl)` with the same name."))) + end + end + end + + # Add, commit, and push the docs to the remote. + run(`git add -A .`) + if !success(`git diff --cached --exit-code`) + run(`git commit -m "build based on $sha"`) + run(`git push -q upstream HEAD:$branch`) + else + Utilities.log("New docs identical to the old -- not committing nor pushing.") + end + end + end + finally + # Remove the unencrypted private key. + isfile(keyfile) && rm(keyfile) + end +end + +function rm_and_add_symlink(target, link) + if ispath(link) + @warn "removing `$(link)` and linking `$(link)` to `$(target)`." + rm(link; force = true, recursive = true) + end + symlink(target, link) +end + +""" + gitrm_copy(src, dst) + +Uses `git rm -r` to remove `dst` and then copies `src` to `dst`. Assumes that the working +directory is within the git repository of `dst` is when the function is called. + +This is to get around [#507](https://github.com/JuliaDocs/Documenter.jl/issues/507) on +filesystems that are case-insensitive (e.g. on OS X, Windows). Without doing a `git rm` +first, `git add -A` will not detect case changes in filenames. +""" +function gitrm_copy(src, dst) + # --ignore-unmatch so that we wouldn't get errors if dst does not exist + run(`git rm -rf --ignore-unmatch $(dst)`) + cp(src, dst; force=true) +end + +function withfile(func, file::AbstractString, contents::AbstractString) + hasfile = isfile(file) + original = hasfile ? read(file, String) : "" + open(file, "w") do stream + print(stream, contents) + flush(stream) # Make sure file is written before continuing. + end + try + func() + finally + if hasfile + open(file, "w") do stream + print(stream, original) + end + else + rm(file) + end + end +end + +function getenv(regex::Regex) + for (key, value) in ENV + occursin(regex, key) && return value + end + error("could not find key/iv pair.") +end + +end # module diff --git a/embedded/Documenter.jl-0.20.0/src/Documents.jl b/embedded/Documenter.jl-0.20.0/src/Documents.jl new file mode 100644 index 0000000..a5e4448 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Documents.jl @@ -0,0 +1,489 @@ +""" +Defines [`Document`](@ref) and its supporting types + +- [`Page`](@ref) +- [`User`](@ref) +- [`Internal`](@ref) +- [`Globals`](@ref) + +""" +module Documents + +import ..Documenter: + Anchors, + Formats, + Utilities + +using DocStringExtensions +import Markdown +using Unicode + +# Pages. +# ------ + +""" +[`Page`](@ref)-local values such as current module that are shared between nodes in a page. +""" +mutable struct Globals + mod :: Module + meta :: Dict{Symbol, Any} +end +Globals() = Globals(Main, Dict()) + +""" +Represents a single markdown file. +""" +struct Page + source :: String + build :: String + """ + Ordered list of raw toplevel markdown nodes from the parsed page contents. This vector + should be considered immutable. + """ + elements :: Vector + """ + Each element in `.elements` maps to an "expanded" element. This may be itself if the + element does not need expanding or some other object, such as a `DocsNode` in the case + of `@docs` code blocks. + """ + mapping :: IdDict{Any,Any} + globals :: Globals +end +function Page(source::AbstractString, build::AbstractString) + elements = Markdown.parse(read(source, String)).content + Page(source, build, elements, IdDict{Any,Any}(), Globals()) +end + +# Document Nodes. +# --------------- + +## IndexNode. + +struct IndexNode + pages :: Vector{String} # Which pages to include in the index? Set by user. + modules :: Vector{Module} # Which modules to include? Set by user. + order :: Vector{Symbol} # What order should docs be listed in? Set by user. + build :: String # Path to the file where this index will appear. + source :: String # Path to the file where this index was written. + elements :: Vector # (object, doc, page, mod, cat)-tuple for constructing links. + + function IndexNode(; + # TODO: Fix difference between uppercase and lowercase naming of keys. + # Perhaps deprecate the uppercase versions? Same with `ContentsNode`. + Pages = [], + Modules = [], + Order = [:module, :constant, :type, :function, :macro], + build = error("missing value for `build` in `IndexNode`."), + source = error("missing value for `source` in `IndexNode`."), + others... + ) + new(Pages, Modules, Order, build, source, []) + end +end + +## ContentsNode. + +struct ContentsNode + pages :: Vector{String} # Which pages should be included in contents? Set by user. + depth :: Int # Down to which level should headers be displayed? Set by user. + build :: String # Same as for `IndexNode`s. + source :: String # Same as for `IndexNode`s. + elements :: Vector # (order, page, anchor)-tuple for constructing links. + + function ContentsNode(; + Pages = [], + Depth = 2, + build = error("missing value for `build` in `ContentsNode`."), + source = error("missing value for `source` in `ContentsNode`."), + others... + ) + new(Pages, Depth, build, source, []) + end +end + +## Other nodes + +struct MetaNode + dict :: Dict{Symbol, Any} +end + +struct MethodNode + method :: Method + visible :: Bool +end + +struct DocsNode + docstr :: Any + anchor :: Anchors.Anchor + object :: Utilities.Object + page :: Documents.Page +end + +struct DocsNodes + nodes :: Vector{DocsNode} +end + +struct EvalNode + code :: Markdown.Code + result :: Any +end + +struct RawHTML + code::String +end + +struct RawNode + name::Symbol + text::String +end + +# Navigation +# ---------------------- + +""" +Element in the navigation tree of a document, containing navigation references +to other page, reference to the [`Page`](@ref) object etc. +""" +mutable struct NavNode + """ + `nothing` if the `NavNode` is a non-page node of the navigation tree, otherwise + the string should be a valid key in `doc.internal.pages` + """ + page :: Union{String, Nothing} + """ + If not `nothing`, specifies the text that should be displayed in navigation + links etc. instead of the automatically determined text. + """ + title_override :: Union{String, Nothing} + parent :: Union{NavNode, Nothing} + children :: Vector{NavNode} + visible :: Bool + prev :: Union{NavNode, Nothing} + next :: Union{NavNode, Nothing} +end +NavNode(page, title_override, parent) = NavNode(page, title_override, parent, [], true, nothing, nothing) + +""" +Constructs a list of the ancestors of the `navnode` (inclding the `navnode` itself), +ordered so that the root of the navigation tree is the first and `navnode` itself +is the last item. +""" +navpath(navnode::NavNode) = navnode.parent === nothing ? [navnode] : + push!(navpath(navnode.parent), navnode) + + +# Inner Document Fields. +# ---------------------- + +""" +User-specified values used to control the generation process. +""" +struct User + root :: String # An absolute path to the root directory of the document. + source :: String # Parent directory is `.root`. Where files are read from. + build :: String # Parent directory is also `.root`. Where files are written to. + format :: Vector{Symbol} # What format to render the final document with? + clean :: Bool # Empty the `build` directory before starting a new build? + doctest :: Union{Bool,Symbol} # Run doctests? + linkcheck::Bool # Check external links.. + linkcheck_ignore::Vector{Union{String,Regex}} # ..and then ignore (some of) them. + checkdocs::Symbol # Check objects missing from `@docs` blocks. `:none`, `:exports`, or `:all`. + doctestfilters::Vector{Regex} # Filtering for doctests + strict::Bool # Throw an exception when any warnings are encountered. + modules :: Set{Module} # Which modules to check for missing docs? + pages :: Vector{Any} # Ordering of document pages specified by the user. + assets :: Vector{String} + repo :: String # Template for URL to source code repo + sitename:: String + authors :: String + analytics::String + version :: String # version string used in the version selector by default + html_prettyurls :: Bool # Use pretty URLs in the HTML build? + html_disable_git :: Bool # Don't call git when exporting HTML + html_edit_branch :: Union{String, Nothing} # Change how the "Edit on GitHub" links are handled + html_canonical :: Union{String, Nothing} # Set a canonical url, if desired (https://en.wikipedia.org/wiki/Canonical_link_element) +end + +""" +Private state used to control the generation process. +""" +struct Internal + assets :: String # Path where asset files will be copied to. + remote :: String # The remote repo on github where this package is hosted. + pages :: Dict{String, Page} # Markdown files only. + navtree :: Vector{NavNode} # A vector of top-level navigation items. + navlist :: Vector{NavNode} # An ordered list of `NavNode`s that point to actual pages + headers :: Anchors.AnchorMap # See `modules/Anchors.jl`. Tracks `Markdown.Header` objects. + docs :: Anchors.AnchorMap # See `modules/Anchors.jl`. Tracks `@docs` docstrings. + bindings:: IdDict{Any,Any} # Tracks insertion order of object per-binding. + objects :: IdDict{Any,Any} # Tracks which `Utilities.Objects` are included in the `Document`. + contentsnodes :: Vector{ContentsNode} + indexnodes :: Vector{IndexNode} + locallinks :: Dict{Markdown.Link, String} + errors::Set{Symbol} +end + +# Document. +# --------- + +""" +Represents an entire document. +""" +struct Document + user :: User # Set by the user via `makedocs`. + internal :: Internal # Computed values. +end + +function Document(; + root :: AbstractString = Utilities.currentdir(), + source :: AbstractString = "src", + build :: AbstractString = "build", + format :: Any = :html, + clean :: Bool = true, + doctest :: Union{Bool,Symbol} = true, + linkcheck:: Bool = false, + linkcheck_ignore :: Vector = [], + checkdocs::Symbol = :all, + doctestfilters::Vector{Regex}= Regex[], + strict::Bool = false, + modules :: Utilities.ModVec = Module[], + pages :: Vector = Any[], + assets :: Vector = String[], + repo :: AbstractString = "", + sitename :: AbstractString = "", + authors :: AbstractString = "", + analytics :: AbstractString = "", + version :: AbstractString = "", + html_prettyurls :: Bool = true, + html_disable_git :: Bool = false, + html_edit_branch :: Union{String, Nothing} = "master", + html_canonical :: Union{String, Nothing} = nothing, + others... + ) + Utilities.check_kwargs(others) + + fmt = Formats.fmt(format) + @assert !isempty(fmt) "No formats provided." + + if version == "git-commit" + version = "git:$(Utilities.get_commit_short(root))" + end + + user = User( + root, + source, + build, + fmt, + clean, + doctest, + linkcheck, + linkcheck_ignore, + checkdocs, + doctestfilters, + strict, + Utilities.submodules(modules), + pages, + assets, + repo, + sitename, + authors, + analytics, + version, + html_prettyurls, + html_disable_git, + html_edit_branch, + html_canonical, + ) + internal = Internal( + Utilities.assetsdir(), + Utilities.getremote(root), + Dict{String, Page}(), + [], + [], + Anchors.AnchorMap(), + Anchors.AnchorMap(), + IdDict{Any,Any}(), + IdDict{Any,Any}(), + [], + [], + Dict{Markdown.Link, String}(), + Set{Symbol}(), + ) + Document(user, internal) +end + +## Methods + +function addpage!(doc::Document, src::AbstractString, dst::AbstractString) + page = Page(src, dst) + # page's identifier is the path relative to the `doc.user.source` directory + name = normpath(relpath(src, doc.user.source)) + doc.internal.pages[name] = page +end + +""" +$(SIGNATURES) + +Populates the `ContentsNode`s and `IndexNode`s of the `document` with links. + +This can only be done after all the blocks have been expanded (and nodes constructed), +because the items have to exist before we can gather the links to those items. +""" +function populate!(document::Document) + for node in document.internal.contentsnodes + populate!(node, document) + end + for node in document.internal.indexnodes + populate!(node, document) + end +end + +function populate!(index::IndexNode, document::Document) + # Filtering valid index links. + for (object, doc) in document.internal.objects + page = relpath(doc.page.build, dirname(index.build)) + mod = object.binding.mod + # Include *all* signatures, whether they are `Union{}` or not. + cat = Symbol(lowercase(Utilities.doccat(object.binding, Union{}))) + if _isvalid(page, index.pages) && _isvalid(mod, index.modules) && _isvalid(cat, index.order) + push!(index.elements, (object, doc, page, mod, cat)) + end + end + # Sorting index links. + pagesmap = precedence(index.pages) + modulesmap = precedence(index.modules) + ordermap = precedence(index.order) + comparison = function(a, b) + (x = _compare(pagesmap, 3, a, b)) == 0 || return x < 0 # page + (x = _compare(modulesmap, 4, a, b)) == 0 || return x < 0 # module + (x = _compare(ordermap, 5, a, b)) == 0 || return x < 0 # category + string(a[1].binding) < string(b[1].binding) # object name + end + sort!(index.elements, lt = comparison) + return index +end + +function populate!(contents::ContentsNode, document::Document) + # Filtering valid contents links. + for (id, filedict) in document.internal.headers.map + for (file, anchors) in filedict + for anchor in anchors + page = relpath(anchor.file, dirname(contents.build)) + if _isvalid(page, contents.pages) && Utilities.header_level(anchor.object) ≤ contents.depth + push!(contents.elements, (anchor.order, page, anchor)) + end + end + end + end + # Sorting contents links. + pagesmap = precedence(contents.pages) + comparison = function(a, b) + (x = _compare(pagesmap, 2, a, b)) == 0 || return x < 0 # page + a[1] < b[1] # anchor order + end + sort!(contents.elements, lt = comparison) + return contents +end + +# some replacements for jldoctest blocks +function doctest_replace!(doc::Documents.Document) + for (src, page) in doc.internal.pages + empty!(page.globals.meta) + for element in page.elements + page.globals.meta[:CurrentFile] = page.source + walk(page.globals.meta, page.mapping[element]) do block + doctest_replace!(block) + end + end + end +end +function doctest_replace!(block::Markdown.Code) + startswith(block.language, "jldoctest") || return false + # suppress output for `#output`-style doctests with `output=false` kwarg + if occursin(r"^# output$"m, block.code) && occursin(r";.*output\h*=\h*false", block.language) + input = first(split(block.code, "# output\n", limit = 2)) + block.code = rstrip(input) + end + # correct the language field + block.language = occursin(r"^julia> "m, block.code) ? "julia-repl" : "julia" + return false +end +doctest_replace!(block) = true + +## Utilities. + +function buildnode(T::Type, block, doc, page) + mod = get(page.globals.meta, :CurrentModule, Main) + dict = Dict{Symbol, Any}(:source => page.source, :build => page.build) + for (ex, str) in Utilities.parseblock(block.code, doc, page) + if Utilities.isassign(ex) + cd(dirname(page.source)) do + dict[ex.args[1]] = Core.eval(mod, ex.args[2]) + end + end + end + T(; dict...) +end + +function _compare(col, ind, a, b) + x, y = a[ind], b[ind] + haskey(col, x) && haskey(col, y) ? _compare(col[x], col[y]) : 0 +end +_compare(a, b) = a < b ? -1 : a == b ? 0 : 1 +_isvalid(x, xs) = isempty(xs) || x in xs +precedence(vec) = Dict(zip(vec, 1:length(vec))) + +############################################## +# walk (previously in the Walkers submodule) # +############################################## +""" +$(SIGNATURES) + +Calls `f` on `element` and any of its child elements. `meta` is a `Dict` containing metadata +such as current module. +""" +walk(f, meta, element) = (f(element); nothing) + +# Change to the docstring's defining module if it has one. Change back afterwards. +function walk(f, meta, block::Markdown.MD) + tmp = get(meta, :CurrentModule, nothing) + mod = get(block.meta, :module, nothing) + mod ≡ nothing || (meta[:CurrentModule] = mod) + f(block) && walk(f, meta, block.content) + tmp ≡ nothing ? delete!(meta, :CurrentModule) : (meta[:CurrentModule] = tmp) + nothing +end + +function walk(f, meta, block::Vector) + for each in block + walk(f, meta, each) + end +end + +const MDContentElements = Union{ + Markdown.BlockQuote, + Markdown.Paragraph, + Markdown.MD, +} +walk(f, meta, block::MDContentElements) = f(block) ? walk(f, meta, block.content) : nothing + +const MDTextElements = Union{ + Markdown.Bold, + Markdown.Header, + Markdown.Italic, +} +walk(f, meta, block::MDTextElements) = f(block) ? walk(f, meta, block.text) : nothing +walk(f, meta, block::Markdown.Footnote) = f(block) ? walk(f, meta, block.text) : nothing +walk(f, meta, block::Markdown.Admonition) = f(block) ? walk(f, meta, block.content) : nothing +walk(f, meta, block::Markdown.Image) = f(block) ? walk(f, meta, block.alt) : nothing +walk(f, meta, block::Markdown.Table) = f(block) ? walk(f, meta, block.rows) : nothing +walk(f, meta, block::Markdown.List) = f(block) ? walk(f, meta, block.items) : nothing +walk(f, meta, block::Markdown.Link) = f(block) ? walk(f, meta, block.text) : nothing +walk(f, meta, block::RawHTML) = nothing +walk(f, meta, block::DocsNodes) = walk(f, meta, block.nodes) +walk(f, meta, block::DocsNode) = walk(f, meta, block.docstr) +walk(f, meta, block::EvalNode) = walk(f, meta, block.result) +walk(f, meta, block::MetaNode) = (merge!(meta, block.dict); nothing) +walk(f, meta, block::Anchors.Anchor) = walk(f, meta, block.object) + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Expanders.jl b/embedded/Documenter.jl-0.20.0/src/Expanders.jl new file mode 100644 index 0000000..81e0abb --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Expanders.jl @@ -0,0 +1,645 @@ +""" +Defines node "expanders" that transform nodes from the parsed markdown files. +""" +module Expanders + +import ..Documenter: + Anchors, + Builder, + Documents, + Formats, + Documenter, + Utilities + +import .Documents: + MethodNode, + DocsNode, + DocsNodes, + EvalNode, + MetaNode + +import .Utilities: Selectors + +import Markdown, REPL +import Base64: stringmime + + +function expand(doc::Documents.Document) + for (src, page) in doc.internal.pages + empty!(page.globals.meta) + for element in page.elements + Selectors.dispatch(ExpanderPipeline, element, page, doc) + end + pagecheck(page) + end +end + +# run some checks after expanding the page +function pagecheck(page) + # make sure there is no "continued code" lingering around + if haskey(page.globals.meta, :ContinuedCode) && !isempty(page.globals.meta[:ContinuedCode]) + Utilities.warn(page.source, "Code from a continued @example block unused.") + end +end + + +# Expander Pipeline. +# ------------------ + +""" +The default node expander "pipeline", which consists of the following expanders: + +- [`TrackHeaders`](@ref) +- [`MetaBlocks`](@ref) +- [`DocsBlocks`](@ref) +- [`AutoDocsBlocks`](@ref) +- [`EvalBlocks`](@ref) +- [`IndexBlocks`](@ref) +- [`ContentsBlocks`](@ref) +- [`ExampleBlocks`](@ref) +- [`SetupBlocks`](@ref) +- [`REPLBlocks`](@ref) + +""" +abstract type ExpanderPipeline <: Selectors.AbstractSelector end + +""" +Tracks all `Markdown.Header` nodes found in the parsed markdown files and stores an +[`Anchors.Anchor`](@ref) object for each one. +""" +abstract type TrackHeaders <: ExpanderPipeline end + +""" +Parses each code block where the language is `@meta` and evaluates the key/value pairs found +within the block, i.e. + +````markdown +```@meta +CurrentModule = Documenter +DocTestSetup = quote + using Documenter +end +``` +```` +""" +abstract type MetaBlocks <: ExpanderPipeline end + +""" +Parses each code block where the language is `@docs` and evaluates the expressions found +within the block. Replaces the block with the docstrings associated with each expression. + +````markdown +```@docs +Documenter +makedocs +deploydocs +``` +```` +""" +abstract type DocsBlocks <: ExpanderPipeline end + +""" +Parses each code block where the language is `@autodocs` and replaces it with all the +docstrings that match the provided key/value pairs `Modules = ...` and `Order = ...`. + +````markdown +```@autodocs +Modules = [Foo, Bar] +Order = [:function, :type] +``` +```` +""" +abstract type AutoDocsBlocks <: ExpanderPipeline end + +""" +Parses each code block where the language is `@eval` and evaluates it's content. Replaces +the block with the value resulting from the evaluation. This can be useful for inserting +generated content into a document such as plots. + +````markdown +```@eval +using PyPlot +x = linspace(-π, π) +y = sin(x) +plot(x, y, color = "red") +savefig("plot.svg") +Markdown.parse("![Plot](plot.svg)") +``` +```` +""" +abstract type EvalBlocks <: ExpanderPipeline end + +abstract type RawBlocks <: ExpanderPipeline end + +""" +Parses each code block where the language is `@index` and replaces it with an index of all +docstrings spliced into the document. The pages that are included can be set using a +key/value pair `Pages = [...]` such as + +````markdown +```@index +Pages = ["foo.md", "bar.md"] +``` +```` +""" +abstract type IndexBlocks <: ExpanderPipeline end + +""" +Parses each code block where the language is `@contents` and replaces it with a nested list +of all `Header` nodes in the generated document. The pages and depth of the list can be set +using `Pages = [...]` and `Depth = N` where `N` is and integer. + +````markdown +```@contents +Pages = ["foo.md", "bar.md"] +Depth = 1 +``` +```` +The default `Depth` value is `2`. +""" +abstract type ContentsBlocks <: ExpanderPipeline end + +""" +Parses each code block where the language is `@example` and evaluates the parsed Julia code +found within. The resulting value is then inserted into the final document after the source +code. + +````markdown +```@example +a = 1 +b = 2 +a + b +``` +```` +""" +abstract type ExampleBlocks <: ExpanderPipeline end + +""" +Similar to the [`ExampleBlocks`](@ref) expander, but inserts a Julia REPL prompt before each +toplevel expression in the final document. +""" +abstract type REPLBlocks <: ExpanderPipeline end + +""" +Similar to the [`ExampleBlocks`](@ref) expander, but hides all output in the final document. +""" +abstract type SetupBlocks <: ExpanderPipeline end + +Selectors.order(::Type{TrackHeaders}) = 1.0 +Selectors.order(::Type{MetaBlocks}) = 2.0 +Selectors.order(::Type{DocsBlocks}) = 3.0 +Selectors.order(::Type{AutoDocsBlocks}) = 4.0 +Selectors.order(::Type{EvalBlocks}) = 5.0 +Selectors.order(::Type{IndexBlocks}) = 6.0 +Selectors.order(::Type{ContentsBlocks}) = 7.0 +Selectors.order(::Type{ExampleBlocks}) = 8.0 +Selectors.order(::Type{REPLBlocks}) = 9.0 +Selectors.order(::Type{SetupBlocks}) = 10.0 +Selectors.order(::Type{RawBlocks}) = 11.0 + +Selectors.matcher(::Type{TrackHeaders}, node, page, doc) = isa(node, Markdown.Header) +Selectors.matcher(::Type{MetaBlocks}, node, page, doc) = iscode(node, "@meta") +Selectors.matcher(::Type{DocsBlocks}, node, page, doc) = iscode(node, "@docs") +Selectors.matcher(::Type{AutoDocsBlocks}, node, page, doc) = iscode(node, "@autodocs") +Selectors.matcher(::Type{EvalBlocks}, node, page, doc) = iscode(node, "@eval") +Selectors.matcher(::Type{IndexBlocks}, node, page, doc) = iscode(node, "@index") +Selectors.matcher(::Type{ContentsBlocks}, node, page, doc) = iscode(node, "@contents") +Selectors.matcher(::Type{ExampleBlocks}, node, page, doc) = iscode(node, r"^@example") +Selectors.matcher(::Type{REPLBlocks}, node, page, doc) = iscode(node, r"^@repl") +Selectors.matcher(::Type{SetupBlocks}, node, page, doc) = iscode(node, r"^@setup") +Selectors.matcher(::Type{RawBlocks}, node, page, doc) = iscode(node, r"^@raw") + +# Default Expander. + +Selectors.runner(::Type{ExpanderPipeline}, x, page, doc) = page.mapping[x] = x + +# Track Headers. +# -------------- + +function Selectors.runner(::Type{TrackHeaders}, header, page, doc) + # Get the header slug. + text = + if namedheader(header) + url = header.text[1].url + header.text = header.text[1].text + match(NAMEDHEADER_REGEX, url)[1] + else + sprint(Markdown.plain, Markdown.Paragraph(header.text)) + end + slug = Utilities.slugify(text) + # Add the header to the document's header map. + anchor = Anchors.add!(doc.internal.headers, header, slug, page.build) + # Map the header element to the generated anchor and the current anchor count. + page.mapping[header] = anchor +end + +# @meta +# ----- + +function Selectors.runner(::Type{MetaBlocks}, x, page, doc) + meta = page.globals.meta + for (ex, str) in Utilities.parseblock(x.code, doc, page) + if Utilities.isassign(ex) + try + meta[ex.args[1]] = Core.eval(Main, ex.args[2]) + catch err + push!(doc.internal.errors, :meta_block) + Utilities.warn(doc, page, "Failed to evaluate `$(strip(str))` in `@meta` block.", err) + end + end + end + page.mapping[x] = MetaNode(copy(meta)) +end + +# @docs +# ----- + +function Selectors.runner(::Type{DocsBlocks}, x, page, doc) + failed = false + nodes = DocsNode[] + curmod = get(page.globals.meta, :CurrentModule, Main) + for (ex, str) in Utilities.parseblock(x.code, doc, page) + binding = try + Documenter.DocSystem.binding(curmod, ex) + catch err + push!(doc.internal.errors, :docs_block) + Utilities.warn(page.source, "Unable to get the binding for '$(strip(str))'.", err, ex, curmod) + failed = true + continue + end + # Undefined `Bindings` get discarded. + if !Documenter.DocSystem.iskeyword(binding) && !Documenter.DocSystem.defined(binding) + push!(doc.internal.errors, :docs_block) + Utilities.warn(page.source, "Undefined binding '$(binding)'.") + failed = true + continue + end + typesig = Core.eval(curmod, Documenter.DocSystem.signature(ex, str)) + + object = Utilities.Object(binding, typesig) + # We can't include the same object more than once in a document. + if haskey(doc.internal.objects, object) + push!(doc.internal.errors, :docs_block) + Utilities.warn(page.source, "Duplicate docs found for '$(strip(str))'.") + failed = true + continue + end + + # Find the docs matching `binding` and `typesig`. Only search within the provided modules. + docs = Documenter.DocSystem.getdocs(binding, typesig; modules = doc.user.modules) + + # Include only docstrings from user-provided modules if provided. + if !isempty(doc.user.modules) + filter!(d -> d.data[:module] in doc.user.modules, docs) + end + + # Check that we aren't printing an empty docs list. Skip block when empty. + if isempty(docs) + push!(doc.internal.errors, :docs_block) + Utilities.warn(page.source, "No docs found for '$(strip(str))'.") + failed = true + continue + end + + # Concatenate found docstrings into a single `MD` object. + docstr = Markdown.MD(map(Documenter.DocSystem.parsedoc, docs)) + docstr.meta[:results] = docs + + # Generate a unique name to be used in anchors and links for the docstring. + slug = Utilities.slugify(object) + anchor = Anchors.add!(doc.internal.docs, object, slug, page.build) + docsnode = DocsNode(docstr, anchor, object, page) + + # Track the order of insertion of objects per-binding. + push!(get!(doc.internal.bindings, binding, Utilities.Object[]), object) + + doc.internal.objects[object] = docsnode + push!(nodes, docsnode) + end + # When a `@docs` block fails we need to remove the `.language` since some markdown + # parsers have trouble rendering it correctly. + page.mapping[x] = failed ? (x.language = ""; x) : DocsNodes(nodes) +end + +# @autodocs +# --------- + +const AUTODOCS_DEFAULT_ORDER = [:module, :constant, :type, :function, :macro] + +function Selectors.runner(::Type{AutoDocsBlocks}, x, page, doc) + curmod = get(page.globals.meta, :CurrentModule, Main) + fields = Dict{Symbol, Any}() + for (ex, str) in Utilities.parseblock(x.code, doc, page) + if Utilities.isassign(ex) + try + fields[ex.args[1]] = Core.eval(curmod, ex.args[2]) + catch err + push!(doc.internal.errors, :autodocs_block) + Utilities.warn(doc, page, "Failed to evaluate `$(strip(str))` in `@autodocs` block.", err) + end + end + end + if haskey(fields, :Modules) + # Gather and filter docstrings. + modules = fields[:Modules] + order = get(fields, :Order, AUTODOCS_DEFAULT_ORDER) + pages = map(normpath, get(fields, :Pages, [])) + public = get(fields, :Public, true) + private = get(fields, :Private, true) + results = [] + for mod in modules + for (binding, multidoc) in Documenter.DocSystem.getmeta(mod) + # Which bindings should be included? + isexported = Base.isexported(mod, binding.var) + included = (isexported && public) || (!isexported && private) + # What category does the binding belong to? + category = Documenter.DocSystem.category(binding) + if category in order && included + for (typesig, docstr) in multidoc.docs + path = normpath(docstr.data[:path]) + object = Utilities.Object(binding, typesig) + if isempty(pages) + push!(results, (mod, path, category, object, isexported, docstr)) + else + for p in pages + if endswith(path, p) + push!(results, (mod, p, category, object, isexported, docstr)) + break + end + end + end + end + end + end + end + + # Sort docstrings. + modulemap = Documents.precedence(modules) + pagesmap = Documents.precedence(pages) + ordermap = Documents.precedence(order) + comparison = function (a, b) + local t + (t = Documents._compare(modulemap, 1, a, b)) == 0 || return t < 0 # module + a[5] == b[5] || return a[5] > b[5] # exported bindings before unexported ones. + (t = Documents._compare(pagesmap, 2, a, b)) == 0 || return t < 0 # page + (t = Documents._compare(ordermap, 3, a, b)) == 0 || return t < 0 # category + string(a[4]) < string(b[4]) # name + end + sort!(results; lt = comparison) + + # Finalise docstrings. + nodes = DocsNode[] + for (mod, path, category, object, isexported, docstr) in results + if haskey(doc.internal.objects, object) + push!(doc.internal.errors, :autodocs_block) + Utilities.warn(page.source, "Duplicate docs found for '$(object.binding)'.") + continue + end + markdown = Markdown.MD(Documenter.DocSystem.parsedoc(docstr)) + markdown.meta[:results] = [docstr] + slug = Utilities.slugify(object) + anchor = Anchors.add!(doc.internal.docs, object, slug, page.build) + docsnode = DocsNode(markdown, anchor, object, page) + + # Track the order of insertion of objects per-binding. + push!(get!(doc.internal.bindings, object.binding, Utilities.Object[]), object) + + doc.internal.objects[object] = docsnode + push!(nodes, docsnode) + end + page.mapping[x] = DocsNodes(nodes) + else + push!(doc.internal.errors, :autodocs_block) + Utilities.warn(page.source, "'@autodocs' missing 'Modules = ...'.") + page.mapping[x] = x + end +end + +# @eval +# ----- + +function Selectors.runner(::Type{EvalBlocks}, x, page, doc) + sandbox = Module(:EvalBlockSandbox) + cd(dirname(page.build)) do + result = nothing + for (ex, str) in Utilities.parseblock(x.code, doc, page) + try + result = Core.eval(sandbox, ex) + catch err + push!(doc.internal.errors, :eval_block) + Utilities.warn(doc, page, "Failed to evaluate `@eval` block.", err) + end + end + page.mapping[x] = EvalNode(x, result) + end +end + +# @index +# ------ + +function Selectors.runner(::Type{IndexBlocks}, x, page, doc) + node = Documents.buildnode(Documents.IndexNode, x, doc, page) + push!(doc.internal.indexnodes, node) + page.mapping[x] = node +end + +# @contents +# --------- + +function Selectors.runner(::Type{ContentsBlocks}, x, page, doc) + node = Documents.buildnode(Documents.ContentsNode, x, doc, page) + push!(doc.internal.contentsnodes, node) + page.mapping[x] = node +end + +# @example +# -------- + +function Selectors.runner(::Type{ExampleBlocks}, x, page, doc) + # The sandboxed module -- either a new one or a cached one from this page. + name = match(r"^@example[ ]?(.*)$", first(split(x.language, ';', limit = 2)))[1] + sym = isempty(name) ? gensym("ex-") : Symbol("ex-", name) + mod = get!(() -> get_new_sandbox(sym), page.globals.meta, sym) + + # "parse" keyword arguments to example (we only need to look for continued = true) + continued = occursin(r"continued\s*=\s*true", x.language) + + # Evaluate the code block. We redirect stdout/stderr to `buffer`. + result, buffer = nothing, IOBuffer() + if !continued # run the code + # check if there is any code wating + if haskey(page.globals.meta, :ContinuedCode) && haskey(page.globals.meta[:ContinuedCode], sym) + code = page.globals.meta[:ContinuedCode][sym] * '\n' * x.code + delete!(page.globals.meta[:ContinuedCode], sym) + else + code = x.code + end + for (ex, str) in Utilities.parseblock(code, doc, page) + (value, success, backtrace, text) = Utilities.withoutput() do + cd(dirname(page.build)) do + Core.eval(mod, Expr(:(=), :ans, ex)) + end + end + result = value + print(buffer, text) + if !success + push!(doc.internal.errors, :example_block) + Utilities.warn(page.source, "failed to run code block.\n\n$(value)") + page.mapping[x] = x + return + end + end + else # store the continued code + CC = get!(page.globals.meta, :ContinuedCode, Dict()) + CC[sym] = get(CC, sym, "") * '\n' * x.code + end + # Splice the input and output into the document. + content = [] + input = droplines(x.code) + + # Special-case support for displaying SVG and PNG graphics. TODO: make this more general. + output = if showable(MIME"text/html"(), result) + Documents.RawHTML(Base.invokelatest(stringmime, MIME"text/html"(), result)) + elseif showable(MIME"image/svg+xml"(), result) + Documents.RawHTML(Base.invokelatest(stringmime, MIME"image/svg+xml"(), result)) + elseif showable(MIME"image/png"(), result) + Documents.RawHTML(string("")) + elseif showable(MIME"image/webp"(), result) + Documents.RawHTML(string("")) + elseif showable(MIME"image/gif"(), result) + Documents.RawHTML(string("")) + elseif showable(MIME"image/jpeg"(), result) + Documents.RawHTML(string("")) + else + Markdown.Code(Documenter.DocTests.result_to_string(buffer, result)) + end + + # Only add content when there's actually something to add. + isempty(input) || push!(content, Markdown.Code("julia", input)) + isempty(output.code) || push!(content, output) + # ... and finally map the original code block to the newly generated ones. + page.mapping[x] = Markdown.MD(content) +end + +# @repl +# ----- + +function Selectors.runner(::Type{REPLBlocks}, x, page, doc) + matched = match(r"^@repl[ ]?(.*)$", x.language) + matched === nothing && error("invalid '@repl' syntax: $(x.language)") + name = matched[1] + sym = isempty(name) ? gensym("ex-") : Symbol("ex-", name) + mod = get!(() -> get_new_sandbox(sym), page.globals.meta, sym) + code = split(x.code, '\n'; limit = 2)[end] + result, out = nothing, IOBuffer() + for (ex, str) in Utilities.parseblock(x.code, doc, page) + buffer = IOBuffer() + input = droplines(str) + (value, success, backtrace, text) = Utilities.withoutput() do + cd(dirname(page.build)) do + Core.eval(mod, :(ans = $(Core.eval(mod, ex)))) + end + end + result = value + output = if success + hide = REPL.ends_with_semicolon(input) + Documenter.DocTests.result_to_string(buffer, hide ? nothing : value) + else + Documenter.DocTests.error_to_string(buffer, value, []) + end + isempty(input) || println(out, prepend_prompt(input)) + print(out, text) + if isempty(input) || isempty(output) + println(out) + else + println(out, output, "\n") + end + end + page.mapping[x] = Markdown.Code("julia-repl", rstrip(String(take!(out)))) +end + +# @setup +# ------ + +function Selectors.runner(::Type{SetupBlocks}, x, page, doc) + matched = match(r"^@setup[ ](.+)$", x.language) + matched === nothing && error("invalid '@setup ' syntax: $(x.language)") + # The sandboxed module -- either a new one or a cached one from this page. + name = matched[1] + sym = isempty(name) ? gensym("ex-") : Symbol("ex-", name) + mod = get!(page.globals.meta, sym, Module(sym))::Module + + # Evaluate whole @setup block at once instead of piecewise + page.mapping[x] = + try + cd(dirname(page.build)) do + include_string(mod, x.code) + end + Markdown.MD([]) + catch err + push!(doc.internal.errors, :setup_block) + Utilities.warn(page.source, "failed to run `@setup` block.\n\n$(err)") + x + end + # ... and finally map the original code block to the newly generated ones. + page.mapping[x] = Markdown.MD([]) +end + +# @raw +# ---- + +function Selectors.runner(::Type{RawBlocks}, x, page, doc) + m = match(r"@raw[ ](.+)$", x.language) + m === nothing && error("invalid '@raw ' syntax: $(x.language)") + page.mapping[x] = Documents.RawNode(Symbol(m[1]), x.code) +end + +# Utilities. +# ---------- + +iscode(x::Markdown.Code, r::Regex) = occursin(r, x.language) +iscode(x::Markdown.Code, lang) = x.language == lang +iscode(x, lang) = false + +const NAMEDHEADER_REGEX = r"^@id (.+)$" + +function namedheader(h::Markdown.Header) + if isa(h.text, Vector) && length(h.text) === 1 && isa(h.text[1], Markdown.Link) + url = h.text[1].url + occursin(NAMEDHEADER_REGEX, url) + else + false + end +end + +# Remove any `# hide` lines, leading/trailing blank lines, and trailing whitespace. +function droplines(code; skip = 0) + buffer = IOBuffer() + for line in split(code, '\n')[(skip + 1):end] + occursin(r"^(.*)#\s*hide$", line) && continue + println(buffer, rstrip(line)) + end + strip(String(take!(buffer)), '\n') +end + +function prepend_prompt(input) + prompt = "julia> " + padding = " "^length(prompt) + out = IOBuffer() + for (n, line) in enumerate(split(input, '\n')) + line = rstrip(line) + println(out, n == 1 ? prompt : padding, line) + end + rstrip(String(take!(out))) +end + +function get_new_sandbox(name::Symbol) + m = Module(name) + # eval(expr) is available in the REPL (i.e. Main) so we emulate that for the sandbox + Core.eval(m, :(eval(x) = Core.eval($m, x))) + # modules created with Module() does not have include defined + Core.eval(m, :(include(x) = Base.include($m, x))) + return m +end + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Formats.jl b/embedded/Documenter.jl-0.20.0/src/Formats.jl new file mode 100644 index 0000000..2de63fd --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Formats.jl @@ -0,0 +1,62 @@ +""" +Filetypes used to decide which rendering methods in [`Documenter.Writers`](@ref) are called. + +The only supported format is currently `Markdown`. +""" +module Formats + +import ..Documenter + +using DocStringExtensions + +""" +Represents the output format. Possible values are `Markdown`, `LaTeX`, and `HTML`. +""" +@enum( + Format, + Markdown, + LaTeX, + HTML, +) + +""" +$(SIGNATURES) + +Converts a [`Format`](@ref) value to a `MIME` type. +""" +function mimetype(f::Symbol) + f ≡ :markdown ? MIME"text/plain"() : + f ≡ :latex ? MIME"text/latex"() : + f ≡ :html ? MIME"text/html"() : + error("unexpected format.") +end + +function extension(f::Symbol, file) + path, _ = splitext(file) + string(path, extension(f)) +end + +function extension(f::Symbol) + f ≡ :markdown ? ".md" : + f ≡ :latex ? ".tex" : + f ≡ :html ? ".html" : + error("unexpected format.") +end + +# `fmt` -- convert a format spec to a vector of symbols. +const DEPRECATION_MAPPING = Dict( + Markdown => :markdown, + LaTeX => :latex, + HTML => :html, +) +function _fmt(f::Format) + s = DEPRECATION_MAPPING[f] + Base.depwarn("`$(f)` is deprecated use `:$(s)` for `format = ...`.", :fmt) + return s +end +fmt(f::Format) = [_fmt(f)] +fmt(v::Vector{Format}) = map(_fmt, v) +fmt(s::Symbol) = [s] +fmt(v::Vector{Symbol}) = v + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Utilities/DOM.jl b/embedded/Documenter.jl-0.20.0/src/Utilities/DOM.jl new file mode 100644 index 0000000..d26cfd1 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Utilities/DOM.jl @@ -0,0 +1,315 @@ +""" +Provides a domain specific language for representing HTML documents. + +# Examples + +```julia +using Documenter.Utilities.DOM + +# `DOM` does not export any HTML tags. Define the ones we actually need. +@tags div p em strong ul li + +div( + p("This ", em("is"), " a ", strong("paragraph."), + p("And this is ", strong("another"), " one"), + ul( + li("and"), + li("an"), + li("unordered"), + li("list") + ) +) +``` + +*Notes* + +All the arguments passed to a node are flattened into a single vector rather +than preserving any nested structure. This means that passing two vectors of +nodes to a `div` will result in a `div` node with a single vector of children +(the concatenation of the two vectors) rather than two vector children. The +only arguments that are not flattened are nested nodes. + +String arguments are automatically converted into text nodes. Text nodes do not +have any children or attributes and when displayed the string is escaped using +[`escapehtml`](@ref). + +# Attributes + +As well as plain nodes shown in the previous example, nodes can have attributes +added to them using the following syntax. + +```julia +div[".my-class"]( + img[:src => "foo.jpg"], + input[\"#my-id\", :disabled] +) +``` + +In the above example we add a `class = "my-class"` attribute to the `div` node, +a `src = "foo.jpg"` to the `img`, and `id = "my-id" disabled` attributes to the +`input` node. + +The following syntax is supported within `[...]`: + +```julia +tag[\"#id\"] +tag[".class"] +tag[\".class#id\"] +tag[:disabled] +tag[:src => "foo.jpg"] +# ... or any combination of the above arguments. +``` + +# Internal Representation + +The [`@tags`](@ref) macro defines named [`Tag`](@ref) objects as follows + +```julia +@tags div p em strong +``` + +expands to + +```julia +const div, p, em, strong = Tag(:div), Tag(:p), Tag(:em), Tag(:strong) +``` + +These [`Tag`](@ref) objects are lightweight representations of empty HTML +elements without any attributes and cannot be used to represent a complete +document. To create an actual tree of HTML elements that can be rendered we +need to add some attributes and/or child elements using `getindex` or `call` +syntax. Applying either to a [`Tag`](@ref) object will construct a new +[`Node`](@ref) object. + +```julia +tag(...) # No attributes. +tag[...] # No children. +tag[...](...) # Has both attributes and children. +``` + +All three of the above syntaxes return a new [`Node`](@ref) object. Printing of +`Node` objects is defined using the standard Julia display functions, so only +needs a call to `print` to print out a valid HTML document with all nessesary +text escaped. +""" +module DOM + +import ..Utilities + +tostr(p::Pair) = p + +export @tags + +# +# The following sets are based on: +# +# - https://developer.mozilla.org/en/docs/Web/HTML/Block-level_elements +# - https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements +# - https://developer.mozilla.org/en-US/docs/Glossary/empty_element +# +const BLOCK_ELEMENTS = Set([ + :address, :article, :aside, :blockquote, :canvas, :dd, :div, :dl, + :fieldset, :figcaption, :figure, :footer, :form, :h1, :h2, :h3, :h4, :h5, + :h6, :header, :hgroup, :hr, :li, :main, :nav, :noscript, :ol, :output, :p, + :pre, :section, :table, :tfoot, :ul, :video, +]) +const INLINE_ELEMENTS = Set([ + :a, :abbr, :acronym, :b, :bdo, :big, :br, :button, :cite, :code, :dfn, :em, + :i, :img, :input, :kbd, :label, :map, :object, :q, :samp, :script, :select, + :small, :span, :strong, :sub, :sup, :textarea, :time, :tt, :var, +]) +const VOID_ELEMENTS = Set([ + :area, :base, :br, :col, :command, :embed, :hr, :img, :input, :keygen, + :link, :meta, :param, :source, :track, :wbr, +]) +const ALL_ELEMENTS = union(BLOCK_ELEMENTS, INLINE_ELEMENTS, VOID_ELEMENTS) + +# +# Empty string as a constant to make equality checks slightly cheaper. +# +const EMPTY_STRING = "" +const TEXT = Symbol(EMPTY_STRING) + +""" +Represents a empty and attribute-less HTML element. + +Use [`@tags`](@ref) to define instances of this type rather than manually +creating them via `Tag(:tagname)`. +""" +struct Tag + name :: Symbol +end + +Base.show(io::IO, t::Tag) = print(io, "<", t.name, ">") + +""" +Define a collection of [`Tag`](@ref) objects and bind them to constants +with the same names. + +# Examples + +Defined globally within a module: + +```julia +@tags div ul li +``` + +Defined within the scope of a function to avoid cluttering the global namespace: + +```julia +function template(args...) + @tags div ul li + # ... +end +``` +""" +macro tags(args...) esc(tags(args)) end +tags(s) = :(($(s...),) = $(map(Tag, s))) + +const Attributes = Vector{Pair{Symbol, String}} + +""" +Represents an element within an HTML document including any textual content, +children `Node`s, and attributes. + +This type should not be constructed directly, but instead via `(...)` and +`[...]` applied to a [`Tag`](@ref) or another [`Node`](@ref) object. +""" +struct Node + name :: Symbol + text :: String + attributes :: Attributes + nodes :: Vector{Node} + + Node(name::Symbol, attr::Attributes, data::Vector{Node}) = new(name, EMPTY_STRING, attr, data) + Node(text::AbstractString) = new(TEXT, text) +end + +# +# Syntax for defining `Node` objects from `Tag`s and other `Node` objects. +# +(t::Tag)(args...) = Node(t.name, Attributes(), data(args)) +(n::Node)(args...) = Node(n.name, n.attributes, data(args)) +Base.getindex(t::Tag, args...) = Node(t.name, attr(args), Node[]) +Base.getindex(n::Node, args...) = Node(n.name, attr(args), n.nodes) + +# +# Helper methods for the above `Node` "pseudo-constructors". +# +data(args) = flatten!(nodes!, Node[], args) +attr(args) = flatten!(attributes!, Attributes(), args) + +# +# Types that must not be flattened when constructing a `Node`'s child vector. +# +const Atom = Union{AbstractString, Node, Pair, Symbol} + +""" +# Signatures + +```julia +flatten!(f!, out, x::Atom) +flatten!(f!, out, xs) +``` + +Flatten the contents the third argument into the second after applying the +function `f!` to the element. +""" +flatten!(f!, out, x::Atom) = f!(out, x) +flatten!(f!, out, xs) = (for x in xs; flatten!(f!, out, x); end; out) + +# +# Helper methods for handling flattening children elements in `Node` construction. +# +nodes!(out, s::AbstractString) = push!(out, Node(s)) +nodes!(out, n::Node) = push!(out, n) + +# +# Helper methods for handling flattening in construction of attribute vectors. +# +function attributes!(out, s::AbstractString) + class, id = IOBuffer(), IOBuffer() + for x in eachmatch(r"[#|\.]([\w\-]+)", s) + print(startswith(x.match, '.') ? class : id, x.captures[1], ' ') + end + position(class) === 0 || push!(out, tostr(:class => rstrip(String(take!(class))))) + position(id) === 0 || push!(out, tostr(:id => rstrip(String(take!(id))))) + return out +end +attributes!(out, s::Symbol) = push!(out, tostr(s => "")) +attributes!(out, p::Pair) = push!(out, tostr(p)) + +function Base.show(io::IO, n::Node) + if n.name === Symbol("#RAW#") + print(io, n.nodes[1].text) + elseif n.name === TEXT + print(io, escapehtml(n.text)) + else + print(io, '<', n.name) + for (name, value) in n.attributes + print(io, ' ', name) + isempty(value) || print(io, '=', repr(escapehtml(value))) + end + if n.name in VOID_ELEMENTS + print(io, "/>") + else + print(io, '>') + if n.name === :script || n.name === :style + isempty(n.nodes) || print(io, n.nodes[1].text) + else + for each in n.nodes + show(io, each) + end + end + print(io, "') + end + end +end + +Base.show(io::IO, ::MIME"text/html", n::Node) = print(io, n) + +""" +Escape characters in the provided string. This converts the following characters: + +- `<` to `<` +- `>` to `>` +- `&` to `&` +- `'` to `'` +- `\"` to `"` + +When no escaping is needed then the same object is returned, otherwise a new +string is constructed with the characters escaped. The returned object should +always be treated as an immutable copy and compared using `==` rather than `===`. +""" +function escapehtml(text::AbstractString) + if occursin(r"[<>&'\"]", text) + buffer = IOBuffer() + for char in text + char === '<' ? write(buffer, "<") : + char === '>' ? write(buffer, ">") : + char === '&' ? write(buffer, "&") : + char === '\'' ? write(buffer, "'") : + char === '"' ? write(buffer, """) : write(buffer, char) + end + String(take!(buffer)) + else + text + end +end + +""" +A HTML node that wraps around the root node of the document and adds a DOCTYPE +to it. +""" +mutable struct HTMLDocument + doctype :: String + root :: Node +end +HTMLDocument(root) = HTMLDocument("html", root) + +function Base.show(io::IO, doc::HTMLDocument) + println(io, "") + println(io, doc.root) +end + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Utilities/MDFlatten.jl b/embedded/Documenter.jl-0.20.0/src/Utilities/MDFlatten.jl new file mode 100644 index 0000000..33cfb13 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Utilities/MDFlatten.jl @@ -0,0 +1,94 @@ +""" +Provides the [`mdflatten`](@ref) function that can "flatten" Markdown objects into +a string, with formatting etc. stripped. + +Note that the tests in `test/mdflatten.jl` should be considered to be the spec +for the output (number of newlines, indents, formatting, etc.). +""" +module MDFlatten + +export mdflatten + +import ..Utilities + +import Markdown: + MD, BlockQuote, Bold, Code, Header, HorizontalRule, + Image, Italic, LaTeX, LineBreak, Link, List, Paragraph, Table, + Footnote, Admonition + +""" +Convert a Markdown object to a `String` of only text (i.e. not formatting info). + +It drop most of the extra information (e.g. language of a code block, URLs) +and formatting (e.g. emphasis, headers). This "flattened" representation can +then be used as input for search engines. +""" +function mdflatten(md) + io = IOBuffer() + mdflatten(io, md) + String(take!(io)) +end + +mdflatten(io, md) = mdflatten(io, md, md) +mdflatten(io, md::MD, parent) = mdflatten(io, md.content, md) +mdflatten(io, vec::Vector, parent) = map(x -> mdflatten(io, x, parent), vec) +function mdflatten(io, vec::Vector, parent::MD) + # this special case separates top level blocks with newlines + for md in vec + mdflatten(io, md, parent) + print(io, "\n\n") + end +end + +# Block level MD nodes +mdflatten(io, h::Header{N}, parent) where {N} = mdflatten(io, h.text, h) +mdflatten(io, p::Paragraph, parent) = mdflatten(io, p.content, p) +mdflatten(io, bq::BlockQuote, parent) = mdflatten(io, bq.content, bq) +mdflatten(io, ::HorizontalRule, parent) = nothing +function mdflatten(io, list::List, parent) + for (idx, li) in enumerate(list.items) + for (jdx, x) in enumerate(li) + mdflatten(io, x, list) + jdx == length(li) || print(io, '\n') + end + idx == length(list.items) || print(io, '\n') + end +end +function mdflatten(io, t::Table, parent) + for (idx, row) = enumerate(t.rows) + for (jdx, x) in enumerate(row) + mdflatten(io, x, t) + jdx == length(row) || print(io, ' ') + end + idx == length(t.rows) || print(io, '\n') + end +end + +# Inline nodes +mdflatten(io, text::AbstractString, parent) = print(io, text) +mdflatten(io, link::Link, parent) = mdflatten(io, link.text, link) +mdflatten(io, b::Bold, parent) = mdflatten(io, b.text, b) +mdflatten(io, i::Italic, parent) = mdflatten(io, i.text, i) +mdflatten(io, i::Image, parent) = print(io, "(Image: $(i.alt))") +mdflatten(io, m::LaTeX, parent) = print(io, replace(m.formula, r"[^()+\-*^=\w\s]" => "")) +mdflatten(io, ::LineBreak, parent) = print(io, '\n') + +# Is both inline and block +mdflatten(io, c::Code, parent) = print(io, c.code) + +# Special (inline) "node" -- due to JuliaMark's interpolations +mdflatten(io, expr::Union{Symbol,Expr}, parent) = print(io, expr) + +mdflatten(io, f::Footnote, parent) = footnote(io, f.id, f.text, f) +footnote(io, id, text::Nothing, parent) = print(io, "[$id]") +function footnote(io, id, text, parent) + print(io, "[$id]: ") + mdflatten(io, text, parent) +end + +function mdflatten(io, a::Admonition, parent) + println(io, "$(a.category): $(a.title)") + mdflatten(io, a.content, a) +end + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Utilities/Selectors.jl b/embedded/Documenter.jl-0.20.0/src/Utilities/Selectors.jl new file mode 100644 index 0000000..7ac79bf --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Utilities/Selectors.jl @@ -0,0 +1,174 @@ +""" +An extensible code selection interface. + +The `Selectors` module provides an extensible way to write code that has to dispatch on +different predicates without hardcoding the control flow into a single chain of `if` +statements. + +In the following example a selector for a simple condition is implemented and the generated +selector code is described: + +```julia +abstract type MySelector <: Selectors.AbstractSelector end + +# The different cases we want to test. +abstract type One <: MySelector end +abstract type NotOne <: MySelector end + +# The order in which to test the cases. +Selectors.order(::Type{One}) = 0.0 +Selectors.order(::Type{NotOne}) = 1.0 + +# The predicate to test against. +Selectors.matcher(::Type{One}, x) = x === 1 +Selectors.matcher(::Type{NotOne}, x) = x !== 1 + +# What to do when a test is successful. +Selectors.runner(::Type{One}, x) = println("found one") +Selectors.runner(::Type{NotOne}, x) = println("not found") + +# Test our selector with some numbers. +for i in 0:5 + Selectors.dispatch(MySelector, i) +end +``` + +`Selectors.dispatch(Selector, i)` will behave equivalent to the following: + +```julia +function dispatch(::Type{MySelector}, i::Int) + if matcher(One, i) + runner(One, i) + elseif matcher(NotOne, i) + runner(NotOne, i) + end +end +``` + +and further to + +```julia +function dispatch(::Type{MySelector}, i::Int) + if i === 1 + println("found one") + elseif i !== 1 + println("not found") + end +end +``` + +The module provides the following interface for creating selectors: + +- [`order`](@ref) +- [`matcher`](@ref) +- [`runner`](@ref) +- [`strict`](@ref) +- [`disable`](@ref) +- [`dispatch`](@ref) + +""" +module Selectors + +import InteractiveUtils: subtypes + +""" +Root selector type. Each user-defined selector must subtype from this, i.e. + +```julia +abstract type MySelector <: Selectors.AbstractSelector end + +abstract type First <: MySelector end +abstract type Second <: MySelector end +``` +""" +abstract type AbstractSelector end + +""" +Define the precedence of each case in a selector, i.e. + +```julia +Selectors.order(::Type{First}) = 1.0 +Selectors.order(::Type{Second}) = 2.0 +``` + +Note that the return type must be `Float64`. Defining multiple case types to have the same +order will result in undefined behaviour. +""" +function order end + +""" +Define the matching test for each case in a selector, i.e. + +```julia +Selectors.matcher(::Type{First}, x) = x == 1 +Selectors.matcher(::Type{Second}, x) = true +``` + +Note that the return type must be `Bool`. + +To match against multiple cases use the [`Selectors.strict`](@ref) function. +""" +function matcher end + +""" +Define the code that will run when a particular [`Selectors.matcher`](@ref) test returns +`true`, i.e. + +```julia +Selectors.runner(::Type{First}, x) = println("`x` is equal to `1`.") +Selectors.runner(::Type{Second}, x) = println("`x` is not equal to `1`.") +``` +""" +function runner end + +""" +Define whether a selector case will "fallthrough" or not when successfully matched against. +By default matching is strict and does not fallthrough to subsequent selector cases. + +```julia +# Adding a debugging selector case. +abstract type Debug <: MySelector end + +# Insert prior to all other cases. +Selectors.order(::Type{Debug}) = 0.0 + +# Fallthrough to the next case on success. +Selectors.strict(::Type{Debug}) = false + +# We always match, regardless of the value of `x`. +Selectors.matcher(::Type{Debug}, x) = true + +# Print some debugging info. +Selectors.runner(::Type{Debug}, x) = @show x +``` +""" +strict(::Type{T}) where {T <: AbstractSelector} = true + +""" +Disable a particular case in a selector so that it is never used. + +```julia +Selectors.disable(::Type{Debug}) = true +``` +""" +disable(::Type{T}) where {T <: AbstractSelector} = false + +""" +Call `Selectors.runner(T, args...)` where `T` is a subtype of +`MySelector` for which `matcher(T, args...)` is `true`. + +```julia +Selectors.dispatch(MySelector, args...) +``` +""" +function dispatch(::Type{T}, x...) where T <: AbstractSelector + for t in (sort(subtypes(T); by = order)) + if !disable(t) && matcher(t, x...) + runner(t, x...) + strict(t) && return + end + end + runner(T, x...) +end + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Utilities/TextDiff.jl b/embedded/Documenter.jl-0.20.0/src/Utilities/TextDiff.jl new file mode 100644 index 0000000..125d4db --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Utilities/TextDiff.jl @@ -0,0 +1,101 @@ +module TextDiff + +using DocStringExtensions + +# Utilities. + +function lcs(old_tokens::Vector, new_tokens::Vector) + m = length(old_tokens) + n = length(new_tokens) + weights = zeros(Int, m + 1, n + 1) + for i = 2:(m + 1), j = 2:(n + 1) + weights[i, j] = old_tokens[i - 1] == new_tokens[j - 1] ? + weights[i - 1, j - 1] + 1 : max(weights[i, j - 1], weights[i - 1, j]) + end + return weights +end + +function makediff(weights::Matrix, old_tokens::Vector, new_tokens::Vector) + m = length(old_tokens) + n = length(new_tokens) + diff = Vector{Pair{Symbol, SubString{String}}}() + makediff!(diff, weights, old_tokens, new_tokens, m + 1, n + 1) + return diff +end + +function makediff!(out, weights, X, Y, i, j) + if i > 1 && j > 1 && X[i - 1] == Y[j - 1] + makediff!(out, weights, X, Y, i - 1, j - 1) + push!(out, :normal => X[i - 1]) + else + if j > 1 && (i == 1 || weights[i, j - 1] >= weights[i - 1, j]) + makediff!(out, weights, X, Y, i, j - 1) + push!(out, :green => Y[j - 1]) + elseif i > 1 && (j == 1 || weights[i, j - 1] < weights[i - 1, j]) + makediff!(out, weights, X, Y, i - 1, j) + push!(out, :red => X[i - 1]) + end + end + return out +end + +""" +$(SIGNATURES) + +Splits `text` at `regex` matches, returning an array of substrings. The parts of the string +that match the regular expression are also included at the ends of the returned strings. +""" +function splitby(reg::Regex, text::AbstractString) + out = SubString{String}[] + token_first = 1 + for each in eachmatch(reg, text) + token_last = each.offset + lastindex(each.match) - 1 + push!(out, SubString(text, token_first, token_last)) + token_first = nextind(text, token_last) + end + laststr = SubString(text, token_first) + isempty(laststr) || push!(out, laststr) + return out +end + +# Diff Type. + +struct Lines end +struct Words end + +splitter(::Type{Lines}) = r"\n" +splitter(::Type{Words}) = r"\s+" + +struct Diff{T} + old_tokens::Vector{SubString{String}} + new_tokens::Vector{SubString{String}} + weights::Matrix{Int} + diff::Vector{Pair{Symbol, SubString{String}}} + + function Diff{T}(old_text::AbstractString, new_text::AbstractString) where T + reg = splitter(T) + old_tokens = splitby(reg, old_text) + new_tokens = splitby(reg, new_text) + weights = lcs(old_tokens, new_tokens) + diff = makediff(weights, old_tokens, new_tokens) + return new{T}(old_tokens, new_tokens, weights, diff) + end +end + +# Display. + +prefix(::Diff{Lines}, s::Symbol) = s === :green ? "+ " : s === :red ? "- " : " " +prefix(::Diff{Words}, ::Symbol) = "" + +function showdiff(io::IO, diff::Diff) + for (color, text) in diff.diff + printstyled(io, prefix(diff, color), text, color=color) + end +end + +function Base.show(io::IO, diff::Diff) + printstyled(io, color=:normal) # Reset colors. + showdiff(io, diff) +end + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Utilities/Utilities.jl b/embedded/Documenter.jl-0.20.0/src/Utilities/Utilities.jl new file mode 100644 index 0000000..c81bdf9 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Utilities/Utilities.jl @@ -0,0 +1,633 @@ +""" +Provides a collection of utility functions and types that are used in other submodules. +""" +module Utilities + +using Base.Meta +import Base: isdeprecated, Docs.Binding +using DocStringExtensions +import Markdown, LibGit2 +import Base64: stringmime + +# Logging output. + +const __log__ = Ref(true) +""" + logging(flag::Bool) + +Enable or disable logging output for [`log`](@ref) and [`warn`](@ref). +""" +logging(flag::Bool) = __log__[] = flag + +""" +Format and print a message to the user. +""" +log(msg) = __log__[] ? printstyled(stdout, "Documenter: ", msg, "\n", color=:magenta) : nothing + +# Print logging output to the "real" stdout. +function log(doc, msg) + __log__[] && printstyled(stdout, "Documenter: ", msg, "\n", color=:magenta) + return nothing +end + +debug(msg) = printstyled(" ?? ", msg, "\n", color=:green) + +""" + warn(file, msg) + warn(msg) + +Format and print a warning message to the user. Passing a `file` will include the filename +where the warning was raised. +""" +function warn(file, msg) + if __log__[] + msg = string(" !! ", msg, " [", file, "]\n") + printstyled(stdout, msg, color=:red) + else + nothing + end +end +warn(msg) = __log__[] ? printstyled(stdout, " !! ", msg, "\n", color=:red) : nothing + +function warn(file, msg, err, ex, mod) + if __log__[] + warn(file, msg) + printstyled(stdout, "\nERROR: $err\n\nexpression '$(repr(ex))' in module '$mod'\n\n", color=:red) + else + nothing + end +end + +function warn(doc, page, msg, err) + file = page.source + printstyled(stdout, " !! Warning in $(file):\n\n$(msg)\n\nERROR: $(err)\n\n", color=:red) +end + +# Directory paths. + +""" +Returns the current directory. +""" +function currentdir() + d = Base.source_dir() + d === nothing ? pwd() : d +end + +""" +Returns the path to the Documenter `assets` directory. +""" +assetsdir() = normpath(joinpath(dirname(@__FILE__), "..", "..", "assets")) + +cleandir(d::AbstractString) = (isdir(d) && rm(d, recursive = true); mkdir(d)) + +""" +Find the path of a file relative to the `source` directory. `root` is the path +to the directory containing the file `file`. + +It is meant to be used with `walkdir(source)`. +""" +srcpath(source, root, file) = normpath(joinpath(relpath(root, source), file)) + +# Slugify text. + +""" +Slugify a string into a suitable URL. +""" +function slugify(s::AbstractString) + s = replace(s, r"\s+" => "-") + s = replace(s, r"^\d+" => "") + s = replace(s, r"&" => "-and-") + s = replace(s, r"[^\p{L}\p{P}\d\-]+" => "") + s = strip(replace(s, r"\-\-+" => "-"), '-') +end +slugify(object) = string(object) # Non-string slugifying doesn't do anything. + +# Parse code blocks. + +""" +Returns a vector of parsed expressions and their corresponding raw strings. + +Returns a `Vector` of tuples `(expr, code)`, where `expr` is the corresponding expression +(e.g. a `Expr` or `Symbol` object) and `code` is the string of code the expression was +parsed from. + +The keyword argument `skip = N` drops the leading `N` lines from the input string. +""" +function parseblock(code::AbstractString, doc, page; skip = 0, keywords = true) + # Drop `skip` leading lines from the code block. Needed for deprecated `{docs}` syntax. + code = string(code, '\n') + code = last(split(code, '\n', limit = skip + 1)) + endofstr = lastindex(code) + results = [] + cursor = 1 + while cursor < endofstr + # Check for keywords first since they will throw parse errors if we `parse` them. + line = match(r"^(.*)\r?\n"m, SubString(code, cursor)).match + keyword = Symbol(strip(line)) + (ex, ncursor) = + # TODO: On 0.7 Symbol("") is in Docs.keywords, remove that check when dropping 0.6 + if keywords && (haskey(Docs.keywords, keyword) || keyword == Symbol("")) + (QuoteNode(keyword), cursor + lastindex(line)) + else + try + Meta.parse(code, cursor) + catch err + push!(doc.internal.errors, :parse_error) + Utilities.warn(doc, page, "Failed to parse expression.", err) + break + end + end + str = SubString(code, cursor, prevind(code, ncursor)) + if !isempty(strip(str)) + push!(results, (ex, str)) + end + cursor = ncursor + end + results +end +isassign(x) = isexpr(x, :(=), 2) && isa(x.args[1], Symbol) + +# Checking arguments. + +""" +Prints a formatted warning to the user listing unrecognised keyword arguments. +""" +function check_kwargs(kws) + isempty(kws) && return + out = IOBuffer() + println(out, "Unknown keywords:\n") + for (k, v) in kws + println(out, " ", k, " = ", v) + end + warn(String(take!(out))) +end + +# Finding submodules. + +const ModVec = Union{Module, Vector{Module}} + +""" +Returns the set of submodules of a given root module/s. +""" +function submodules(modules::Vector{Module}) + out = Set{Module}() + for each in modules + submodules(each, out) + end + out +end +function submodules(root::Module, seen = Set{Module}()) + push!(seen, root) + for name in names(root, all=true) + if Base.isidentifier(name) && isdefined(root, name) && !isdeprecated(root, name) + object = getfield(root, name) + if isa(object, Module) && !(object in seen) && parentmodule(object::Module) == root + submodules(object, seen) + end + end + end + return seen +end + + + +## objects +## ======= + + + +""" +Represents an object stored in the docsystem by its binding and signature. +""" +struct Object + binding :: Binding + signature :: Type + + function Object(b::Binding, signature::Type) + m = nameof(b.mod) === b.var ? parentmodule(b.mod) : b.mod + new(Binding(m, b.var), signature) + end +end + +function splitexpr(x::Expr) + isexpr(x, :macrocall) ? splitexpr(x.args[1]) : + isexpr(x, :.) ? (x.args[1], x.args[2]) : + error("Invalid @var syntax `$x`.") +end +splitexpr(s::Symbol) = :(Main), quot(s) +splitexpr(other) = error("Invalid @var syntax `$other`.") + +""" + object(ex, str) + +Returns a expression that, when evaluated, returns an [`Object`](@ref) representing `ex`. +""" +function object(ex::Union{Symbol, Expr}, str::AbstractString) + binding = Expr(:call, Binding, splitexpr(Docs.namify(ex))...) + signature = Base.Docs.signature(ex) + isexpr(ex, :macrocall, 2) && !endswith(str, "()") && (signature = :(Union{})) + Expr(:call, Object, binding, signature) +end + +function object(qn::QuoteNode, str::AbstractString) + if haskey(Base.Docs.keywords, qn.value) + binding = Expr(:call, Binding, Main, qn) + Expr(:call, Object, binding, Union{}) + else + error("'$(qn.value)' is not a documented keyword.") + end +end + +function Base.print(io::IO, obj::Object) + print(io, obj.binding) + print_signature(io, obj.signature) +end +print_signature(io::IO, signature::Union{Union, Type{Union{}}}) = nothing +print_signature(io::IO, signature) = print(io, '-', signature) + +## docs +## ==== + +""" + docs(ex, str) + +Returns an expression that, when evaluated, returns the docstrings associated with `ex`. +""" +function docs end + +# Macro representation changed between 0.4 and 0.5. +function docs(ex::Union{Symbol, Expr}, str::AbstractString) + isexpr(ex, :macrocall, 2) && !endswith(rstrip(str), "()") && (ex = quot(ex)) + :(Base.Docs.@doc $ex) +end +docs(qn::QuoteNode, str::AbstractString) = :(Base.Docs.@doc $(qn.value)) + +""" +Returns the category name of the provided [`Object`](@ref). +""" +doccat(obj::Object) = startswith(string(obj.binding.var), '@') ? + "Macro" : doccat(obj.binding, obj.signature) + +function doccat(b::Binding, ::Union{Union, Type{Union{}}}) + if b.mod === Main && haskey(Base.Docs.keywords, b.var) + "Keyword" + elseif startswith(string(b.var), '@') + "Macro" + else + doccat(getfield(b.mod, b.var)) + end +end + +doccat(b::Binding, ::Type) = "Method" + +doccat(::Function) = "Function" +doccat(::DataType) = "Type" +doccat(x::UnionAll) = doccat(Base.unwrap_unionall(x)) +doccat(::Module) = "Module" +doccat(::Any) = "Constant" + +""" + filterdocs(doc, modules) + +Remove docstrings from the markdown object, `doc`, that are not from one of `modules`. +""" +function filterdocs(doc::Markdown.MD, modules::Set{Module}) + if isempty(modules) + # When no modules are specified in `makedocs` then don't filter anything. + doc + else + if haskey(doc.meta, :module) + doc.meta[:module] ∈ modules ? doc : nothing + else + if haskey(doc.meta, :results) + out = [] + results = [] + for (each, result) in zip(doc.content, doc.meta[:results]) + r = filterdocs(each, modules) + if r !== nothing + push!(out, r) + push!(results, result) + end + end + if isempty(out) + nothing + else + md = Markdown.MD(out) + md.meta[:results] = results + md + end + else + out = [] + for each in doc.content + r = filterdocs(each, modules) + r === nothing || push!(out, r) + end + isempty(out) ? nothing : Markdown.MD(out) + end + end + end +end +# Non-markdown docs won't have a `.meta` field so always just accept those. +filterdocs(other, modules::Set{Module}) = other + +""" +Does the given docstring represent actual documentation or a no docs error message? +""" +nodocs(x) = occursin("No documentation found.", stringmime("text/plain", x)) +nodocs(::Nothing) = false + +header_level(::Markdown.Header{N}) where {N} = N + +""" + repo_root(file; dbdir=".git") + +Tries to determine the root directory of the repository containing `file`. If the file is +not in a repository, the function returns `nothing`. + +The `dbdir` keyword argument specifies the name of the directory we are searching for to +determine if this is a repostory or not. If there is a file called `dbdir`, then it's +contents is checked under the assumption that it is a Git worktree. +""" +function repo_root(file; dbdir=".git") + parent_dir, parent_dir_last = dirname(abspath(file)), "" + while parent_dir != parent_dir_last + dbdir_path = joinpath(parent_dir, dbdir) + isdir(dbdir_path) && return parent_dir + # Let's see if this is a worktree checkout + if isfile(dbdir_path) + contents = chomp(read(dbdir_path, String)) + if startswith(contents, "gitdir: ") + if isdir(contents[9:end]) + return parent_dir + end + end + end + parent_dir, parent_dir_last = dirname(parent_dir), parent_dir + end + return nothing +end + +""" + $(SIGNATURES) + +Returns the path of `file`, relative to the root of the Git repository, or `nothing` if the +file is not in a Git repository. +""" +function relpath_from_repo_root(file) + cd(dirname(file)) do + root = repo_root(file) + root !== nothing && startswith(file, root) ? relpath(file, root) : nothing + end +end + +function repo_commit(file) + cd(dirname(file)) do + readchomp(`git rev-parse HEAD`) + end +end + +function url(repo, file; commit=nothing) + file = realpath(abspath(file)) + remote = getremote(dirname(file)) + isempty(repo) && (repo = "https://github.com/$remote/blob/{commit}{path}") + path = relpath_from_repo_root(file) + if path === nothing + nothing + else + repo = replace(repo, "{commit}" => commit === nothing ? repo_commit(file) : commit) + # Note: replacing any backslashes in path (e.g. if building the docs on Windows) + repo = replace(repo, "{path}" => string("/", replace(path, '\\' => '/'))) + repo = replace(repo, "{line}" => "") + repo + end +end + +url(remote, repo, doc) = url(remote, repo, doc.data[:module], doc.data[:path], linerange(doc)) + +function url(remote, repo, mod, file, linerange) + file === nothing && return nothing # needed on julia v0.6, see #689 + remote = getremote(dirname(file)) + isabspath(file) && isempty(remote) && isempty(repo) && return nothing + + # make sure we get the true path, as otherwise we will get different paths when we compute `root` below + if isfile(file) + file = realpath(abspath(file)) + end + + # Format the line range. + line = format_line(linerange, LineRangeFormatting(repo_host_from_url(repo))) + # Macro-generated methods such as those produced by `@deprecate` list their file as + # `deprecated.jl` since that is where the macro is defined. Use that to help + # determine the correct URL. + if inbase(mod) || !isabspath(file) + file = replace(file, '\\' => '/') + base = "https://github.com/JuliaLang/julia/blob" + dest = "base/$file#$line" + if isempty(Base.GIT_VERSION_INFO.commit) + "$base/v$VERSION/$dest" + else + commit = Base.GIT_VERSION_INFO.commit + "$base/$commit/$dest" + end + else + path = relpath_from_repo_root(file) + if isempty(repo) + repo = "https://github.com/$remote/blob/{commit}{path}#{line}" + end + if path === nothing + nothing + else + repo = replace(repo, "{commit}" => repo_commit(file)) + # Note: replacing any backslashes in path (e.g. if building the docs on Windows) + repo = replace(repo, "{path}" => string("/", replace(path, '\\' => '/'))) + repo = replace(repo, "{line}" => line) + repo + end + end +end + +function getremote(dir::AbstractString) + remote = + try + cd(() -> readchomp(`git config --get remote.origin.url`), dir) + catch err + "" + end + m = match(LibGit2.GITHUB_REGEX, remote) + if m === nothing + travis = get(ENV, "TRAVIS_REPO_SLUG", "") + isempty(travis) ? "" : travis + else + m[1] + end +end + +""" +$(SIGNATURES) + +Returns the first 5 characters of the current git commit hash of the directory `dir`. +""" +function get_commit_short(dir) + commit = cd(dir) do + readchomp(`git rev-parse HEAD`) + end + (length(commit) > 5) ? commit[1:5] : commit +end + +function inbase(m::Module) + if m ≡ Base + true + else + parent = parentmodule(m) + parent ≡ m ? false : inbase(parent) + end +end + +# Repository hosts +# RepoUnknown denotes that the repository type could not be determined automatically +@enum RepoHost RepoGithub RepoBitbucket RepoGitlab RepoUnknown + +# Repository host from repository url +# i.e. "https://github.com/something" => RepoGithub +# "https://bitbucket.org/xxx" => RepoBitbucket +# If no match, returns RepoUnknown +function repo_host_from_url(repoURL::String) + if occursin("bitbucket", repoURL) + return RepoBitbucket + elseif occursin("github", repoURL) || isempty(repoURL) + return RepoGithub + elseif occursin("gitlab", repoURL) + return RepoGitlab + else + return RepoUnknown + end +end + +# Find line numbers. +# ------------------ + +linerange(doc) = linerange(doc.text, doc.data[:linenumber]) + +function linerange(text, from) + lines = sum([isodd(n) ? newlines(s) : 0 for (n, s) in enumerate(text)]) + return lines > 0 ? (from:(from + lines + 1)) : (from:from) +end + +struct LineRangeFormatting + prefix::String + separator::String + + function LineRangeFormatting(host::RepoHost) + if host == RepoBitbucket + new("", ":") + elseif host == RepoGitlab + new("L", "-") + else + # default is github-style + new("L", "-L") + end + end +end + +function format_line(range::AbstractRange, format::LineRangeFormatting) + if length(range) <= 1 + string(format.prefix, first(range)) + else + string(format.prefix, first(range), format.separator, last(range)) + end +end + +newlines(s::AbstractString) = count(c -> c === '\n', s) +newlines(other) = 0 + + +# Output redirection. +# ------------------- +using Logging + +""" +Call a function and capture all `stdout` and `stderr` output. + + withoutput(f) --> (result, success, backtrace, output) + +where + + * `result` is the value returned from calling function `f`. + * `success` signals whether `f` has thrown an error, in which case `result` stores the + `Exception` that was raised. + * `backtrace` a `Vector{Ptr{Cvoid}}` produced by `catch_backtrace()` if an error is thrown. + * `output` is the combined output of `stdout` and `stderr` during execution of `f`. + +""" +function withoutput(f) + # Save the default output streams. + default_stdout = stdout + default_stderr = stderr + + # Redirect both the `stdout` and `stderr` streams to a single `Pipe` object. + pipe = Pipe() + Base.link_pipe!(pipe; reader_supports_async = true, writer_supports_async = true) + redirect_stdout(pipe.in) + redirect_stderr(pipe.in) + # Also redirect logging stream to the same pipe + logger = ConsoleLogger(pipe.in) + + # Bytes written to the `pipe` are captured in `output` and converted to a `String`. + output = UInt8[] + + # Run the function `f`, capturing all output that it might have generated. + # Success signals whether the function `f` did or did not throw an exception. + result, success, backtrace = with_logger(logger) do + try + f(), true, Vector{Ptr{Cvoid}}() + catch err + # InterruptException should never happen during normal doc-testing + # and not being able to abort the doc-build is annoying (#687). + isa(err, InterruptException) && rethrow(err) + + err, false, catch_backtrace() + finally + # Force at least a single write to `pipe`, otherwise `readavailable` blocks. + println() + # Restore the original output streams. + redirect_stdout(default_stdout) + redirect_stderr(default_stderr) + # NOTE: `close` must always be called *after* `readavailable`. + append!(output, readavailable(pipe)) + close(pipe) + end + end + return result, success, backtrace, chomp(String(output)) +end + + +""" + issubmodule(sub, mod) + +Checks whether `sub` is a submodule of `mod`. A module is also considered to be +its own submodule. + +E.g. `A.B.C` is a submodule of `A`, `A.B` and `A.B.C`, but it is not a submodule +of `D`, `A.D` nor `A.B.C.D`. +""" +function issubmodule(sub, mod) + if (sub === Main) && (mod !== Main) + return false + end + (sub === mod) || issubmodule(parentmodule(sub), mod) +end + +""" + isabsurl(url) + +Checks whether `url` is an absolute URL (as opposed to a relative one). +""" +isabsurl(url) = occursin(ABSURL_REGEX, url) +const ABSURL_REGEX = r"^[[:alpha:]+-.]+://" + +include("DOM.jl") +include("MDFlatten.jl") +include("TextDiff.jl") +include("Selectors.jl") + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Writers/HTMLWriter.jl b/embedded/Documenter.jl-0.20.0/src/Writers/HTMLWriter.jl new file mode 100644 index 0000000..d87aeac --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Writers/HTMLWriter.jl @@ -0,0 +1,1143 @@ +""" +A module for rendering `Document` objects to HTML. + +# Keywords + +[`HTMLWriter`](@ref) uses the following additional keyword arguments that can be passed to +[`Documenter.makedocs`](@ref): `assets`, `sitename`, `analytics`, `authors`, `pages`, +`version`, `html_prettyurls`, `html_disable_git`. + +**`sitename`** is the site's title displayed in the title bar and at the top of the +*navigation menu. This argument is mandatory for [`HTMLWriter`](@ref). + +**`pages`** defines the hierarchy of the navigation menu. + +**`assets`** can be used to include additional assets (JS, CSS, ICO etc. files). See below +for more information. + +# Experimental keywords + +**`analytics`** can be used specify the Google Analytics tracking ID. + +**`version`** specifies the version string of the current version which will be the +selected option in the version selector. If this is left empty (default) the version +selector will be hidden. The special value `git-commit` sets the value in the output to +`git:{commit}`, where `{commit}` is the first few characters of the current commit hash. + +**`html_prettyurls`** (default `true`) -- allows disabling the pretty URLs feature, which +generates an output directory structre that hides the `.html` suffixes from the URLs (e.g. +by default `src/foo.md` becomes `src/foo/index.html`). This does not work when browsing +documentation in local files since browsers do not resolve `foo/` to `foo/index.html` +for local files. If `html_prettyurls = false`, then Documenter generate `src/foo.html` +instead and sets up the internal links accordingly, suitable for local documentation builds. + +**`html_disable_git`** can be used to disable calls to `git` when the document is not +in a Git-controlled repository. Without setting this to `true`, Documenter will throw +an error and exit if any of the Git commands fail. The calls to Git are mainly used to +gather information about the current commit hash and file paths, necessary for constructing +the links to the remote repository. + +**`html_edit_branch`** specifies which branch, tag or commit the "Edit on GitHub" links +point to. It defaults to `master`. If it set to `nothing`, the current commit will be used. + +**`html_canonical`** specifies the canonical URL for your documentation. We recommend +you set this to the base url of your stable documentation, e.g. `https://juliadocs.github.io/Documenter.jl/stable`. +This allows search engines to know which version to send their users to. [See +wikipedia for more information](https://en.wikipedia.org/wiki/Canonical_link_element). +Default is `nothing`, in which case no canonical link is set. + +# Page outline + +The [`HTMLWriter`](@ref) makes use of the page outline that is determined by the +headings. It is assumed that if the very first block of a page is a level 1 heading, +then it is intended as the page title. This has two consequences: + +1. It is then used to automatically determine the page title in the navigation menu + and in the `` tag, unless specified in the `.pages` option. +2. If the first heading is interpreted as being the page title, it is not displayed + in the navigation sidebar. + +# Default and custom assets + +Documenter copies all files under the source directory (e.g. `/docs/src/`) over +to the compiled site. It also copies a set of default assets from `/assets/html/` +to the site's `assets/` directory, unless the user already had a file with the +same name, in which case the user's files overrides the Documenter's file. +This could, in principle, be used for customizing the site's style and scripting. + +The HTML output also links certain custom assets to the generated HTML documents, +specfically a logo and additional javascript files. +The asset files that should be linked must be placed in `assets/`, under the source +directory (e.g `/docs/src/assets`) and must be on the top level (i.e. files in +the subdirectories of `assets/` are not linked). + +For the **logo**, Documenter checks for the existence of `assets/logo.png`. +If that's present, it gets displayed in the navigation bar. + +Additional JS, ICO, and CSS assets can be included in the generated pages using the +`assets` keyword for `makedocs`. `assets` must be a `Vector{String}` and will include +each listed asset in the `<head>` of every page in the order in which they are listed. +The type of the asset (i.e. whether it is going to be included with a `<script>` or a +`<link>` tag) is determined by the file's extension -- either `.js`, `.ico`, or `.css`. +Adding an ICO asset is primarilly useful for setting a custom `favicon`. +""" +module HTMLWriter + +import Markdown + +import ...Documenter: + Anchors, + Builder, + Documents, + Expanders, + Formats, + Documenter, + Utilities, + Writers + +import ...Utilities.DOM: DOM, Tag, @tags +using ...Utilities.MDFlatten + +const requirejs_cdn = "file:///usr/share/javascript/requirejs/require.min.js" +const normalize_css = "file:///usr/share/javascript/normalize.css/normalize.min.css" +const google_fonts = "file:///usr/share/doc/julia-doc/fontface.css" +const fontawesome_css = "file:///usr/share/fonts-font-awesome/css/font-awesome.min.css" +const highlightjs_css = "file:///usr/share/javascript/highlight.js/styles/default.css" + + +""" +[`HTMLWriter`](@ref)-specific globals that are passed to [`domify`](@ref) and +other recursive functions. +""" +mutable struct HTMLContext + doc :: Documents.Document + logo :: String + scripts :: Vector{String} + documenter_js :: String + search_js :: String + search_index :: IOBuffer + search_index_js :: String + search_navnode :: Documents.NavNode + local_assets :: Vector{String} +end +HTMLContext(doc) = HTMLContext(doc, "", [], "", "", IOBuffer(), "", Documents.NavNode("search", "Search", nothing), []) + +""" +Returns a page (as a [`Documents.Page`](@ref) object) using the [`HTMLContext`](@ref). +""" +getpage(ctx, path) = ctx.doc.internal.pages[path] +getpage(ctx, navnode::Documents.NavNode) = getpage(ctx, navnode.page) + + +function render(doc::Documents.Document) + !isempty(doc.user.sitename) || error("HTML output requires `sitename`.") + + ctx = HTMLContext(doc) + ctx.search_index_js = "search_index.js" + + copy_asset("arrow.svg", doc) + + let logo = joinpath("assets", "logo.png") + if isfile(joinpath(doc.user.build, logo)) + ctx.logo = logo + end + end + + ctx.documenter_js = copy_asset("documenter.js", doc) + ctx.search_js = copy_asset("search.js", doc) + + push!(ctx.local_assets, copy_asset("documenter.css", doc)) + append!(ctx.local_assets, doc.user.assets) + + for navnode in doc.internal.navlist + render_page(ctx, navnode) + end + + render_search(ctx) + + open(joinpath(doc.user.build, ctx.search_index_js), "w") do io + println(io, "var documenterSearchIndex = {\"docs\": [\n") + write(io, String(take!(ctx.search_index))) + println(io, "]}") + end +end + +""" +Copies an asset from Documenters `assets/html/` directory to `doc.user.build`. +Returns the path of the copied asset relative to `.build`. +""" +function copy_asset(file, doc) + src = joinpath(Utilities.assetsdir(), "html", file) + alt_src = joinpath(doc.user.source, "assets", file) + dst = joinpath(doc.user.build, "assets", file) + isfile(src) || error("Asset '$file' not found at $(abspath(src))") + + # Since user's alternative assets are already copied over in a previous build + # step and they should override documenter's original assets, we only actually + # perform the copy if <source>/assets/<file> does not exist. Note that checking + # the existence of <build>/assets/<file> is not sufficient since the <build> + # directory might be dirty from a previous build. + if isfile(alt_src) + Utilities.warn("Not copying '$src', provided by the user.") + else + ispath(dirname(dst)) || mkpath(dirname(dst)) + ispath(dst) && Utilities.warn("Overwriting '$dst'.") + cp(src, dst, force=true) + end + assetpath = normpath(joinpath("assets", file)) + # Replace any backslashes in links, if building the docs on Windows + return replace(assetpath, '\\' => '/') +end + +# Page +# ------------------------------------------------------------------------------ + +""" +Constructs and writes the page referred to by the `navnode` to `.build`. +""" +function render_page(ctx, navnode) + @tags html body + + page = getpage(ctx, navnode) + + head = render_head(ctx, navnode) + navmenu = render_navmenu(ctx, navnode) + article = render_article(ctx, navnode) + + htmldoc = DOM.HTMLDocument( + html[:lang=>"en"]( + head, + body(navmenu, article) + ) + ) + + open_output(ctx, navnode) do io + print(io, htmldoc) + end +end + +function render_head(ctx, navnode) + @tags head meta link script title + src = get_url(ctx, navnode) + + page_title = "$(mdflatten(pagetitle(ctx, navnode))) · $(ctx.doc.user.sitename)" + css_links = [ + normalize_css, + google_fonts, + fontawesome_css, + highlightjs_css, + ] + head( + meta[:charset=>"UTF-8"], + meta[:name => "viewport", :content => "width=device-width, initial-scale=1.0"], + title(page_title), + + analytics_script(ctx.doc.user.analytics), + + canonical_link_element(ctx.doc.user.html_canonical, src), + + # Stylesheets. + map(css_links) do each + link[:href => each, :rel => "stylesheet", :type => "text/css"] + end, + + script("documenterBaseURL=\"$(relhref(src, "."))\""), + script[ + :src => requirejs_cdn, + Symbol("data-main") => relhref(src, ctx.documenter_js) + ], + + script[:src => relhref(src, "siteinfo.js")], + script[:src => relhref(src, "../versions.js")], + + # Custom user-provided assets. + asset_links(src, ctx.local_assets) + ) +end + +function asset_links(src::AbstractString, assets::Vector) + @tags link script + links = DOM.Node[] + for each in assets + ext = splitext(each)[end] + url = relhref(src, each) + node = + ext == ".ico" ? link[:href => url, :rel => "icon", :type => "image/x-icon"] : + ext == ".css" ? link[:href => url, :rel => "stylesheet", :type => "text/css"] : + ext == ".js" ? script[:src => url] : continue # Skip non-js/css files. + push!(links, node) + end + return links +end + +analytics_script(tracking_id::AbstractString) = + isempty(tracking_id) ? Tag(Symbol("#RAW#"))("") : Tag(:script)( + """ + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); + + ga('create', '$(tracking_id)', 'auto'); + ga('send', 'pageview'); + """ + ) + +function canonical_link_element(canonical_link, src) + @tags link + if canonical_link === nothing + return Tag(Symbol("#RAW#"))("") + else + canonical_link_stripped = rstrip(canonical_link, '/') + href = "$canonical_link_stripped/$src" + return link[:rel => "canonical", :href => href] + end +end + +## Search page +# ------------ + +function render_search(ctx) + @tags article body h1 header hr html li nav p span ul script + + src = get_url(ctx, ctx.search_navnode) + + head = render_head(ctx, ctx.search_navnode) + navmenu = render_navmenu(ctx, ctx.search_navnode) + article = article( + header( + nav(ul(li("Search"))), + hr(), + render_topbar(ctx, ctx.search_navnode), + ), + h1("Search"), + p["#search-info"]("Number of results: ", span["#search-results-number"]("loading...")), + ul["#search-results"] + ) + + htmldoc = DOM.HTMLDocument( + html[:lang=>"en"]( + head, + body(navmenu, article), + script[:src => relhref(src, ctx.search_index_js)], + script[:src => relhref(src, ctx.search_js)], + ) + ) + open_output(ctx, ctx.search_navnode) do io + print(io, htmldoc) + end +end + +# Navigation menu +# ------------------------------------------------------------------------------ + +function render_navmenu(ctx, navnode) + @tags a form h1 img input nav div select option + + src = get_url(ctx, navnode) + + navmenu = nav[".toc"] + if !isempty(ctx.logo) + push!(navmenu.nodes, + a[:href => relhref(src, "index.html")]( + img[ + ".logo", + :src => relhref(src, ctx.logo), + :alt => "$(ctx.doc.user.sitename) logo" + ] + ) + ) + end + push!(navmenu.nodes, h1(ctx.doc.user.sitename)) + let version_selector = select["#version-selector", :onChange => "window.location.href=this.value"]() + if isempty(ctx.doc.user.version) + push!(version_selector.attributes, :style => "visibility: hidden") + else + push!(version_selector.nodes, + option[ + :value => "#", + :selected => "selected", + ](ctx.doc.user.version) + ) + end + push!(navmenu.nodes, version_selector) + end + push!(navmenu.nodes, + form[".search#search-form", :action => navhref(ctx, ctx.search_navnode, navnode)]( + input[ + "#search-query", + :name => "q", + :type => "text", + :placeholder => "Search docs", + ], + ) + ) + push!(navmenu.nodes, navitem(ctx, navnode)) + navmenu +end + +""" +[`navitem`](@ref) returns the lists and list items of the navigation menu. +It gets called recursively to construct the whole tree. + +It always returns a [`DOM.Node`](@ref). If there's nothing to display (e.g. the node is set +to be invisible), it returns an empty text node (`DOM.Node("")`). +""" +navitem(ctx, current) = navitem(ctx, current, ctx.doc.internal.navtree) +function navitem(ctx, current, nns::Vector) + nodes = map(nn -> navitem(ctx, current, nn), nns) + filter!(node -> node.name !== DOM.TEXT, nodes) + isempty(nodes) ? DOM.Node("") : DOM.Tag(:ul)(nodes) +end +function navitem(ctx, current, nn::Documents.NavNode) + @tags ul li span a + + # We'll do the children first, primarily to determine if this node has any that are + # visible. If it does not and it itself is not visible (including current), then + # we'll hide this one as well, returning an empty string Node. + children = navitem(ctx, current, nn.children) + if nn !== current && !nn.visible && children.name === DOM.TEXT + return DOM.Node("") + end + + # construct this item + title = mdconvert(pagetitle(ctx, nn); droplinks=true) + link = if nn.page === nothing + span[".toctext"](title) + else + a[".toctext", :href => navhref(ctx, nn, current)](title) + end + item = (nn === current) ? li[".current"](link) : li(link) + + # add the subsections (2nd level headings) from the page + if (nn === current) && current.page !== nothing + subs = collect_subsections(ctx.doc.internal.pages[current.page]) + internal_links = map(subs) do s + istoplevel, anchor, text = s + _li = istoplevel ? li[".toplevel"] : li[] + _li(a[".toctext", :href => anchor](mdconvert(text; droplinks=true))) + end + push!(item.nodes, ul[".internal"](internal_links)) + end + + # add the visible subsections, if any, as a single list + (children.name === DOM.TEXT) || push!(item.nodes, children) + + item +end + + +# Article (page contents) +# ------------------------------------------------------------------------------ + +function render_article(ctx, navnode) + @tags article header footer nav ul li hr span a + + header_links = map(Documents.navpath(navnode)) do nn + title = mdconvert(pagetitle(ctx, nn); droplinks=true) + nn.page === nothing ? li(title) : li(a[:href => navhref(ctx, nn, navnode)](title)) + end + + topnav = nav(ul(header_links)) + + # Set the logo and name for the "Edit on.." button. + host_type = Utilities.repo_host_from_url(ctx.doc.user.repo) + if host_type == Utilities.RepoGitlab + host = "GitLab" + logo = "\uf296" + elseif host_type == Utilities.RepoGithub + host = "GitHub" + logo = "\uf09b" + elseif host_type == Utilities.RepoBitbucket + host = "BitBucket" + logo = "\uf171" + else + host = "" + logo = "\uf15c" + end + hoststring = isempty(host) ? " source" : " on $(host)" + + if !ctx.doc.user.html_disable_git + pageurl = get(getpage(ctx, navnode).globals.meta, :EditURL, getpage(ctx, navnode).source) + if Utilities.isabsurl(pageurl) + url = pageurl + else + if !(pageurl == getpage(ctx, navnode).source) + # need to set users path relative the page itself + pageurl = joinpath(first(splitdir(getpage(ctx, navnode).source)), pageurl) + end + url = Utilities.url(ctx.doc.user.repo, pageurl, commit=ctx.doc.user.html_edit_branch) + end + if url !== nothing + edit_verb = (ctx.doc.user.html_edit_branch === nothing) ? "View" : "Edit" + push!(topnav.nodes, a[".edit-page", :href => url](span[".fa"](logo), " $(edit_verb)$hoststring")) + end + end + art_header = header(topnav, hr(), render_topbar(ctx, navnode)) + + # build the footer with nav links + art_footer = footer(hr()) + if navnode.prev !== nothing + direction = span[".direction"]("Previous") + title = span[".title"](mdconvert(pagetitle(ctx, navnode.prev); droplinks=true)) + link = a[".previous", :href => navhref(ctx, navnode.prev, navnode)](direction, title) + push!(art_footer.nodes, link) + end + + if navnode.next !== nothing + direction = span[".direction"]("Next") + title = span[".title"](mdconvert(pagetitle(ctx, navnode.next); droplinks=true)) + link = a[".next", :href => navhref(ctx, navnode.next, navnode)](direction, title) + push!(art_footer.nodes, link) + end + + pagenodes = domify(ctx, navnode) + article["#docs"](art_header, pagenodes, art_footer) +end + +function render_topbar(ctx, navnode) + @tags a div span + page_title = string(mdflatten(pagetitle(ctx, navnode))) + return div["#topbar"](span(page_title), a[".fa .fa-bars", :href => "#"]) +end + +# expand the versions argument from the user +# and return entries and needed symlinks +function expand_versions(dir, versions) + # output: entries and symlinks + entries = String[] + symlinks = Pair{String,String}[] + + # read folders and filter out symlinks + available_folders = readdir(dir) + cd(() -> filter!(!islink, available_folders), dir) + + # filter and sort release folders + vnum(x) = VersionNumber(x) + version_folders = [x for x in available_folders if occursin(Base.VERSION_REGEX, x)] + sort!(version_folders, lt = (x, y) -> vnum(x) < vnum(y), rev = true) + release_folders = filter(x -> (v = vnum(x); v.prerelease == () && v.build == ()), version_folders) + # pre_release_folders = filter(x -> (v = vnum(x); v.prerelease != () || v.build != ()), version_folders) + major_folders = filter!(x -> (v = vnum(x); v.major != 0), + unique(x -> (v = vnum(x); v.major), release_folders)) + minor_folders = filter!(x -> (v = vnum(x); !(v.major == 0 && v.minor == 0)), + unique(x -> (v = vnum(x); (v.major, v.minor)), release_folders)) + patch_folders = unique(x -> (v = vnum(x); (v.major, v.minor, v.patch)), release_folders) + + filter!(x -> vnum(x) !== 0, major_folders) + + # populate output + for entry in versions + if entry == "v#" # one doc per major release + for x in major_folders + vstr = "v$(vnum(x).major).$(vnum(x).minor)" + push!(entries, vstr) + push!(symlinks, vstr => x) + end + elseif entry == "v#.#" # one doc per minor release + for x in minor_folders + vstr = "v$(vnum(x).major).$(vnum(x).minor)" + push!(entries, vstr) + push!(symlinks, vstr => x) + end + elseif entry == "v#.#.#" # one doc per patch release + for x in patch_folders + vstr = "v$(vnum(x).major).$(vnum(x).minor).$(vnum(x).patch)" + push!(entries, vstr) + push!(symlinks, vstr => x) + end + elseif entry == "v^" || (entry isa Pair && entry.second == "v^") + if !isempty(release_folders) + x = first(release_folders) + vstr = isa(entry, Pair) ? entry.first : "v$(vnum(x).major).$(vnum(x).minor)" + push!(entries, vstr) + push!(symlinks, vstr => x) + end + elseif entry isa Pair + k, v = entry + i = findfirst(==(v), available_folders) + if i === nothing + @info("no match for `versions` entry `$(repr(entry))`") + else + push!(entries, k) + push!(symlinks, k => v) + end + else + @info("no match for `versions` entry `$(repr(entry))`") + end + end + unique!(entries) # remove any duplicates + + # generate remaining symlinks + foreach(x -> push!(symlinks, "v$(vnum(x).major)" => x), major_folders) + foreach(x -> push!(symlinks, "v$(vnum(x).major).$(vnum(x).minor)" => x), minor_folders) + foreach(x -> push!(symlinks, "v$(vnum(x).major).$(vnum(x).minor).$(vnum(x).patch)" => x), patch_folders) + filter!(x -> x.first != x.second, unique!(symlinks)) + + # assert that none of the links point to another link + for link in symlinks + i = findfirst(x -> link.first == x.second, symlinks) + if i !== nothing + throw(ArgumentError("link `$(link)` incompatible with link `$(symlinks[i])`.")) + end + end + + return entries, symlinks +end + +# write version file +function generate_version_file(versionfile::AbstractString, entries) + open(versionfile, "w") do buf + println(buf, "var DOC_VERSIONS = [") + for folder in entries + println(buf, " \"", folder, "\",") + end + println(buf, "];") + end +end + +function generate_siteinfo_file(dir::AbstractString, version::AbstractString) + open(joinpath(dir, "siteinfo.js"), "w") do buf + println(buf, "var DOCUMENTER_CURRENT_VERSION = \"$(version)\";") + end +end + +## domify(...) +# ------------ + +""" +Converts recursively a [`Documents.Page`](@ref), `Markdown` or Documenter +`*Node` objects into HTML DOM. +""" +function domify(ctx, navnode) + page = getpage(ctx, navnode) + sib = SearchIndexBuffer(ctx, navnode) + ret = map(page.elements) do elem + search_append(sib, elem) + domify(ctx, navnode, page.mapping[elem]) + end + search_flush(sib) + ret +end + +mutable struct SearchIndexBuffer + ctx :: HTMLContext + src :: String + page :: Documents.Page + loc :: String + category :: Symbol + title :: String + page_title :: String + buffer :: IOBuffer + function SearchIndexBuffer(ctx, navnode) + page_title = mdflatten(pagetitle(ctx, navnode)) + new( + ctx, + pretty_url(ctx, get_url(ctx, navnode.page)), + getpage(ctx, navnode), + "", + :page, + page_title, + page_title, + IOBuffer() + ) + end +end + +function search_append(sib, node::Markdown.Header) + search_flush(sib) + sib.category = :section + sib.title = mdflatten(node) + a = sib.page.mapping[node] + sib.loc = "$(a.id)-$(a.nth)" +end + +search_append(sib, node) = mdflatten(sib.buffer, node) + +function search_flush(sib) + # Replace any backslashes in links, if building the docs on Windows + src = replace(sib.src, '\\' => '/') + ref = "$(src)#$(sib.loc)" + text = String(take!(sib.buffer)) + println(sib.ctx.search_index, """ + { + "location": "$(jsescape(ref))", + "page": "$(jsescape(sib.page_title))", + "title": "$(jsescape(sib.title))", + "category": "$(jsescape(lowercase(string(sib.category))))", + "text": "$(jsescape(text))" + }, + """) +end + +""" +Replaces some of the characters in the string with escape sequences so that the strings +would be valid JS string literals, as per the +[ECMAScript® 2017 standard](https://www.ecma-international.org/ecma-262/8.0/index.html#sec-literals-string-literals). + +Note that it always escapes both potential `"` and `'` closing quotes. +""" +function jsescape(s) + b = IOBuffer() + # From the ECMAScript® 2017 standard: + # + # > All code points may appear literally in a string literal except for the closing + # > quote code points, U+005C (REVERSE SOLIDUS), U+000D (CARRIAGE RETURN), U+2028 (LINE + # > SEPARATOR), U+2029 (PARAGRAPH SEPARATOR), and U+000A (LINE FEED). + # + # https://www.ecma-international.org/ecma-262/8.0/index.html#sec-literals-string-literals + for c in s + if c === '\u000a' # LINE FEED, i.e. \n + write(b, "\\n") + elseif c === '\u000d' # CARRIAGE RETURN, i.e. \r + write(b, "\\r") + elseif c === '\u005c' # REVERSE SOLIDUS, i.e. \ + write(b, "\\\\") + elseif c === '\u0022' # QUOTATION MARK, i.e. " + write(b, "\\\"") + elseif c === '\u0027' # APOSTROPHE, i.e. ' + write(b, "\\'") + elseif c === '\u2028' # LINE SEPARATOR + write(b, "\\u2028") + elseif c === '\u2029' # PARAGRAPH SEPARATOR + write(b, "\\u2029") + else + write(b, c) + end + end + String(take!(b)) +end + +function domify(ctx, navnode, node) + fixlinks!(ctx, navnode, node) + mdconvert(node, Markdown.MD()) +end + +function domify(ctx, navnode, anchor::Anchors.Anchor) + @tags a + aid = "$(anchor.id)-$(anchor.nth)" + if isa(anchor.object, Markdown.Header) + h = anchor.object + fixlinks!(ctx, navnode, h) + DOM.Tag(Symbol("h$(Utilities.header_level(h))"))( + a[".nav-anchor", :id => aid, :href => "#$aid"](mdconvert(h.text, h)) + ) + else + a[".nav-anchor", :id => aid, :href => "#$aid"](domify(ctx, navnode, anchor.object)) + end +end + + +struct ListBuilder + es::Vector +end +ListBuilder() = ListBuilder([]) + +import Base: push! +function push!(lb::ListBuilder, level, node) + @assert level >= 1 + if level == 1 + push!(lb.es, node) + else + if isempty(lb.es) || typeof(last(lb.es)) !== ListBuilder + push!(lb.es, ListBuilder()) + end + push!(last(lb.es), level-1, node) + end +end + +function domify(lb::ListBuilder) + @tags ul li + ul(map(e -> isa(e, ListBuilder) ? domify(e) : li(e), lb.es)) +end + +function domify(ctx, navnode, contents::Documents.ContentsNode) + @tags a + navnode_dir = dirname(navnode.page) + navnode_url = get_url(ctx, navnode) + lb = ListBuilder() + for (count, path, anchor) in contents.elements + path = joinpath(navnode_dir, path) # links in ContentsNodes are relative to current page + path = pretty_url(ctx, relhref(navnode_url, get_url(ctx, path))) + header = anchor.object + url = string(path, '#', anchor.id, '-', anchor.nth) + node = a[:href=>url](mdconvert(header.text; droplinks=true)) + level = Utilities.header_level(header) + push!(lb, level, node) + end + domify(lb) +end + +function domify(ctx, navnode, index::Documents.IndexNode) + @tags a code li ul + navnode_dir = dirname(navnode.page) + navnode_url = get_url(ctx, navnode) + lis = map(index.elements) do el + object, doc, path, mod, cat = el + path = joinpath(navnode_dir, path) # links in IndexNodes are relative to current page + path = pretty_url(ctx, relhref(navnode_url, get_url(ctx, path))) + url = string(path, "#", Utilities.slugify(object)) + li(a[:href=>url](code("$(object.binding)"))) + end + ul(lis) +end + +function domify(ctx, navnode, docs::Documents.DocsNodes) + [domify(ctx, navnode, node) for node in docs.nodes] +end + +function domify(ctx, navnode, node::Documents.DocsNode) + @tags a code div section span + + # push to search index + sib = SearchIndexBuffer(ctx, navnode) + sib.loc = node.anchor.id + sib.title = string(node.object.binding) + sib.category = Symbol(Utilities.doccat(node.object)) + mdflatten(sib.buffer, node.docstr) + search_flush(sib) + + section[".docstring"]( + div[".docstring-header"]( + a[".docstring-binding", :id=>node.anchor.id, :href=>"#$(node.anchor.id)"](code("$(node.object.binding)")), + " — ", # — + span[".docstring-category"]("$(Utilities.doccat(node.object))"), + "." + ), + domify_doc(ctx, navnode, node.docstr) + ) +end + +function domify_doc(ctx, navnode, md::Markdown.MD) + @tags a + if haskey(md.meta, :results) + # The `:results` field contains a vector of `Docs.DocStr` objects associated with + # each markdown object. The `DocStr` contains data such as file and line info that + # we need for generating correct source links. + map(zip(md.content, md.meta[:results])) do md + markdown, result = md + ret = Any[domify(ctx, navnode, Writers.MarkdownWriter.dropheaders(markdown))] + # When a source link is available then print the link. + if !ctx.doc.user.html_disable_git + url = Utilities.url(ctx.doc.internal.remote, ctx.doc.user.repo, result) + if url !== nothing + push!(ret, a[".source-link", :target=>"_blank", :href=>url]("source")) + end + end + ret + end + else + # Docstrings with no `:results` metadata won't contain source locations so we don't + # try to print them out. Just print the basic docstring. + domify(ctx, navnode, Writers.MarkdownWriter.dropheaders(md)) + end +end + +function domify(ctx, navnode, node::Documents.EvalNode) + node.result === nothing ? DOM.Node[] : domify(ctx, navnode, node.result) +end + +# nothing to show for MetaNodes, so we just return an empty list +domify(ctx, navnode, node::Documents.MetaNode) = DOM.Node[] + +function domify(ctx, navnode, raw::Documents.RawNode) + raw.name === :html ? Tag(Symbol("#RAW#"))(raw.text) : DOM.Node[] +end + + +# Utilities +# ------------------------------------------------------------------------------ + +""" +Opens the output file of the `navnode` in write node. If necessary, the path to the output +file is created before opening the file. +""" +function open_output(f, ctx, navnode) + path = joinpath(ctx.doc.user.build, get_url(ctx, navnode)) + isdir(dirname(path)) || mkpath(dirname(path)) + open(f, path, "w") +end + +""" +Get the relative hyperlink between two [`Documents.NavNode`](@ref)s. Assumes that both +[`Documents.NavNode`](@ref)s have an associated [`Documents.Page`](@ref) (i.e. `.page` +is not `nothing`). +""" +navhref(ctx, to, from) = pretty_url(ctx, relhref(get_url(ctx, from), get_url(ctx, to))) + +""" +Calculates a relative HTML link from one path to another. +""" +function relhref(from, to) + pagedir = dirname(from) + # The regex separator replacement is necessary since otherwise building the docs on + # Windows will result in paths that have `//` separators which break asset inclusion. + replace(relpath(to, isempty(pagedir) ? "." : pagedir), r"[/\\]+" => "/") +end + +""" +Returns the full path corresponding to a path of a `.md` page file. The the input and output +paths are assumed to be relative to `src/`. +""" +function get_url(ctx, path::AbstractString) + if ctx.doc.user.html_prettyurls + d = if basename(path) == "index.md" + dirname(path) + else + first(splitext(path)) + end + isempty(d) ? "index.html" : "$d/index.html" + else + Formats.extension(:html, path) + end +end + +""" +Returns the full path of a [`Documents.NavNode`](@ref) relative to `src/`. +""" +get_url(ctx, navnode::Documents.NavNode) = get_url(ctx, navnode.page) + +""" +If `html_prettyurls` is enabled, returns a "pretty" version of the `path` which can then be +used in links in the resulting HTML file. +""" +function pretty_url(ctx, path::AbstractString) + if ctx.doc.user.html_prettyurls + dir, file = splitdir(path) + if file == "index.html" + return length(dir) == 0 ? "" : "$(dir)/" + end + end + return path +end + +""" +Tries to guess the page title by looking at the `<h1>` headers and returns the +header contents of the first `<h1>` on a page (or `nothing` if the algorithm +was unable to find any `<h1>` headers). +""" +function pagetitle(page::Documents.Page) + title = nothing + for element in page.elements + if isa(element, Markdown.Header{1}) + title = element.text + break + end + end + title +end + +function pagetitle(ctx, navnode::Documents.NavNode) + if navnode.title_override !== nothing + # parse title_override as markdown + md = Markdown.parse(navnode.title_override) + # Markdown.parse results in a paragraph so we need to strip that + if !(length(md.content) === 1 && isa(first(md.content), Markdown.Paragraph)) + error("Bad Markdown provided for page title: '$(navnode.title_override)'") + end + return first(md.content).content + end + + if navnode.page !== nothing + title = pagetitle(getpage(ctx, navnode)) + title === nothing || return title + end + + "-" +end + +""" +Returns an ordered list of tuples, `(toplevel, anchor, text)`, corresponding to level 1 and 2 +headings on the `page`. Note that if the first header on the `page` is a level 1 header then +it is not included -- it is assumed to be the page title and so does not need to be included +in the navigation menu twice. +""" +function collect_subsections(page::Documents.Page) + sections = [] + title_found = false + for element in page.elements + if isa(element, Markdown.Header) && Utilities.header_level(element) < 3 + toplevel = Utilities.header_level(element) === 1 + # Don't include the first header if it is `h1`. + if toplevel && isempty(sections) && !title_found + title_found = true + continue + end + anchor = page.mapping[element] + push!(sections, (toplevel, "#$(anchor.id)-$(anchor.nth)", element.text)) + end + end + return sections +end + + +# mdconvert +# ------------------------------------------------------------------------------ + +const md_block_nodes = [Markdown.MD, Markdown.BlockQuote] +push!(md_block_nodes, Markdown.List) +push!(md_block_nodes, Markdown.Admonition) + +""" +[`MDBlockContext`](@ref) is a union of all the Markdown nodes whose children should +be blocks. It can be used to dispatch on all the block-context nodes at once. +""" +const MDBlockContext = Union{md_block_nodes...} + +""" +Convert a markdown object to a `DOM.Node` object. + +The `parent` argument is passed to allow for context-dependant conversions. +""" +mdconvert(md; kwargs...) = mdconvert(md, md; kwargs...) + +mdconvert(text::AbstractString, parent; kwargs...) = DOM.Node(text) + +mdconvert(vec::Vector, parent; kwargs...) = [mdconvert(x, parent; kwargs...) for x in vec] + +mdconvert(md::Markdown.MD, parent; kwargs...) = Tag(:div)(mdconvert(md.content, md; kwargs...)) + +mdconvert(b::Markdown.BlockQuote, parent; kwargs...) = Tag(:blockquote)(mdconvert(b.content, b; kwargs...)) + +mdconvert(b::Markdown.Bold, parent; kwargs...) = Tag(:strong)(mdconvert(b.text, parent; kwargs...)) + +function mdconvert(c::Markdown.Code, parent::MDBlockContext; kwargs...) + @tags pre code + language = isempty(c.language) ? "none" : c.language + pre(code[".language-$(language)"](c.code)) +end +mdconvert(c::Markdown.Code, parent; kwargs...) = Tag(:code)(c.code) + +mdconvert(h::Markdown.Header{N}, parent; kwargs...) where {N} = DOM.Tag(Symbol("h$N"))(mdconvert(h.text, h; kwargs...)) + +mdconvert(::Markdown.HorizontalRule, parent; kwargs...) = Tag(:hr)() + +mdconvert(i::Markdown.Image, parent; kwargs...) = Tag(:img)[:src => i.url, :alt => i.alt] + +mdconvert(i::Markdown.Italic, parent; kwargs...) = Tag(:em)(mdconvert(i.text, i; kwargs...)) + +mdconvert(m::Markdown.LaTeX, ::MDBlockContext; kwargs...) = Tag(:div)(string("\\[", m.formula, "\\]")) +mdconvert(m::Markdown.LaTeX, parent; kwargs...) = Tag(:span)(string('$', m.formula, '$')) + +mdconvert(::Markdown.LineBreak, parent; kwargs...) = Tag(:br)() + +function mdconvert(link::Markdown.Link, parent; droplinks=false, kwargs...) + link_text = mdconvert(link.text, link; droplinks=droplinks, kwargs...) + droplinks ? link_text : Tag(:a)[:href => link.url](link_text) +end + +mdconvert(list::Markdown.List, parent; kwargs...) = (Markdown.isordered(list) ? Tag(:ol) : Tag(:ul))(map(Tag(:li), mdconvert(list.items, list; kwargs...))) + +mdconvert(paragraph::Markdown.Paragraph, parent; kwargs...) = Tag(:p)(mdconvert(paragraph.content, paragraph; kwargs...)) + +# For compatibility with versions before Markdown.List got the `loose field, Julia PR #26598 +const list_has_loose_field = :loose in fieldnames(Markdown.List) +function mdconvert(paragraph::Markdown.Paragraph, parent::Markdown.List; kwargs...) + content = mdconvert(paragraph.content, paragraph; kwargs...) + return (list_has_loose_field && !parent.loose) ? content : Tag(:p)(content) +end + +mdconvert(t::Markdown.Table, parent; kwargs...) = Tag(:table)( + Tag(:tr)(map(x -> Tag(:th)(mdconvert(x, t; kwargs...)), t.rows[1])), + map(x -> Tag(:tr)(map(y -> Tag(:td)(mdconvert(y, x; kwargs...)), x)), t.rows[2:end]) +) + +mdconvert(expr::Union{Expr,Symbol}, parent; kwargs...) = string(expr) + +mdconvert(f::Markdown.Footnote, parent; kwargs...) = footnote(f.id, f.text, parent; kwargs...) +footnote(id, text::Nothing, parent; kwargs...) = Tag(:a)[:href => "#footnote-$(id)"]("[$id]") +function footnote(id, text, parent; kwargs...) + Tag(:div)[".footnote#footnote-$(id)"]( + Tag(:a)[:href => "#footnote-$(id)"](Tag(:strong)("[$id]")), + mdconvert(text, parent; kwargs...), + ) +end + +function mdconvert(a::Markdown.Admonition, parent; kwargs...) + @tags div + div[".admonition.$(a.category)"]( + div[".admonition-title"](a.title), + div[".admonition-text"](mdconvert(a.content, a; kwargs...)) + ) +end + +mdconvert(html::Documents.RawHTML, parent; kwargs...) = Tag(Symbol("#RAW#"))(html.code) + + +# fixlinks! +# ------------------------------------------------------------------------------ + +""" +Replaces URLs in `Markdown.Link` elements (if they point to a local `.md` page) with the +actual URLs. +""" +function fixlinks!(ctx, navnode, link::Markdown.Link) + fixlinks!(ctx, navnode, link.text) + Utilities.isabsurl(link.url) && return + + # links starting with a # are references within the same file -- there's nothing to fix + # for such links + startswith(link.url, '#') && return + + s = split(link.url, "#", limit = 2) + if Sys.iswindows() && ':' in first(s) + Utilities.warn("Invalid local link: colons not allowed in paths on Windows\n '$(link.url)' in $(navnode.page)") + return + end + path = normpath(joinpath(dirname(navnode.page), first(s))) + + if endswith(path, ".md") && path in keys(ctx.doc.internal.pages) + # make sure that links to different valid pages are correct + path = pretty_url(ctx, relhref(get_url(ctx, navnode), get_url(ctx, path))) + elseif isfile(joinpath(ctx.doc.user.build, path)) + # update links to other files that are present in build/ (e.g. either user + # provided files or generated by code examples) + path = relhref(get_url(ctx, navnode), path) + else + Utilities.warn("Invalid local link: unresolved path\n '$(link.url)' in $(navnode.page)") + end + + # Replace any backslashes in links, if building the docs on Windows + path = replace(path, '\\' => '/') + link.url = (length(s) > 1) ? "$path#$(last(s))" : String(path) +end + +function fixlinks!(ctx, navnode, img::Markdown.Image) + Utilities.isabsurl(img.url) && return + + if Sys.iswindows() && ':' in img.url + Utilities.warn("Invalid local image: colons not allowed in paths on Windows\n '$(img.url)' in $(navnode.page)") + return + end + + path = joinpath(dirname(navnode.page), img.url) + if isfile(joinpath(ctx.doc.user.build, path)) + path = relhref(get_url(ctx, navnode), path) + # Replace any backslashes in links, if building the docs on Windows + img.url = replace(path, '\\' => '/') + else + Utilities.warn("Invalid local image: unresolved path\n '$(img.url)' in `$(navnode.page)`") + end +end + +fixlinks!(ctx, navnode, md::Markdown.MD) = fixlinks!(ctx, navnode, md.content) +function fixlinks!(ctx, navnode, a::Markdown.Admonition) + fixlinks!(ctx, navnode, a.title) + fixlinks!(ctx, navnode, a.content) +end +fixlinks!(ctx, navnode, b::Markdown.BlockQuote) = fixlinks!(ctx, navnode, b.content) +fixlinks!(ctx, navnode, b::Markdown.Bold) = fixlinks!(ctx, navnode, b.text) +fixlinks!(ctx, navnode, f::Markdown.Footnote) = fixlinks!(ctx, navnode, f.text) +fixlinks!(ctx, navnode, h::Markdown.Header) = fixlinks!(ctx, navnode, h.text) +fixlinks!(ctx, navnode, i::Markdown.Italic) = fixlinks!(ctx, navnode, i.text) +fixlinks!(ctx, navnode, list::Markdown.List) = fixlinks!(ctx, navnode, list.items) +fixlinks!(ctx, navnode, p::Markdown.Paragraph) = fixlinks!(ctx, navnode, p.content) +fixlinks!(ctx, navnode, t::Markdown.Table) = fixlinks!(ctx, navnode, t.rows) + +fixlinks!(ctx, navnode, mds::Vector) = map(md -> fixlinks!(ctx, navnode, md), mds) +fixlinks!(ctx, navnode, md) = nothing + +# TODO: do some regex-magic in raw HTML blocks? Currently ignored. +#fixlinks!(ctx, navnode, md::Documents.RawHTML) = ... + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Writers/LaTeXWriter.jl b/embedded/Documenter.jl-0.20.0/src/Writers/LaTeXWriter.jl new file mode 100644 index 0000000..51ce92e --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Writers/LaTeXWriter.jl @@ -0,0 +1,540 @@ +""" +A module for rendering `Document` objects to LaTeX and PDF. + +# Keywords + +[`LaTeXWriter`](@ref) uses the following additional keyword arguments that can be passed to +[`Documenter.makedocs`](@ref): `authors`, `sitename`. + +**`sitename`** is the site's title displayed in the title bar and at the top of the +navigation menu. It goes into the `\\title` LaTeX command. + +**`authors`** can be used to specify the authors of. It goes into the `\\author` LaTeX command. + +""" +module LaTeXWriter + +import ...Documenter: + Anchors, + Builder, + Documents, + Expanders, + Formats, + Documenter, + Utilities, + Writers + +import Markdown + +mutable struct Context{I <: IO} <: IO + io::I + in_header::Bool + footnotes::Dict{String, Int} + depth::Int + filename::String # currently active source file +end +Context(io) = Context{typeof(io)}(io, false, Dict(), 1, "") + +_print(c::Context, args...) = Base.print(c.io, args...) +_println(c::Context, args...) = Base.println(c.io, args...) + + +const STYLE = joinpath(dirname(@__FILE__), "..", "..", "assets", "latex", "documenter.sty") + +hastex() = (try; success(`latexmk -version`); catch; false; end) + +const DOCUMENT_STRUCTURE = ( + "part", + "chapter", + "section", + "subsection", + "subsubsection", + "paragraph", + "subparagraph", +) + +function render(doc::Documents.Document) + mktempdir() do path + cp(joinpath(doc.user.root, doc.user.build), joinpath(path, "build")) + cd(joinpath(path, "build")) do + file = replace("$(doc.user.sitename).tex", " " => "") + open(file, "w") do io + context = Context(io) + writeheader(context, doc) + for (title, filename, depth) in files(doc.user.pages) + context.filename = filename + empty!(context.footnotes) + if 1 <= depth <= length(DOCUMENT_STRUCTURE) + header_type = DOCUMENT_STRUCTURE[depth] + header_text = "\n\\$(header_type){$(title)}\n" + if isempty(filename) + _println(context, header_text) + else + path = normpath(filename) + page = doc.internal.pages[path] + if get(page.globals.meta, :IgnorePage, :none) !== :latex + context.depth = depth + (isempty(title) ? 0 : 1) + context.depth > depth && _println(context, header_text) + latex(context, page, doc) + end + end + end + end + writefooter(context, doc) + end + cp(STYLE, "documenter.sty") + if hastex() + outdir = joinpath(doc.user.root, doc.user.build) + pdf = replace("$(doc.user.sitename).pdf", " " => "") + try + run(`latexmk -silent -f -interaction=nonstopmode -view=none -lualatex -shell-escape $file`) + catch err + Utilities.warn("failed to compile. Check generated LaTeX file.") + cp(file, joinpath(outdir, file); force = true) + end + cp(pdf, joinpath(outdir, pdf); force = true) + else + Utilities.warn("`latexmk` and `lualatex` required for PDF generation.") + end + end + end +end + +function writeheader(io::IO, doc::Documents.Document) + custom = joinpath(doc.user.root, doc.user.source, "assets", "custom.sty") + isfile(custom) ? cp(custom, "custom.sty"; force = true) : touch("custom.sty") + preamble = + """ + \\documentclass{memoir} + + \\usepackage{./documenter} + \\usepackage{./custom} + + \\title{$(doc.user.sitename)} + \\author{$(doc.user.authors)} + + \\begin{document} + + \\frontmatter + \\maketitle + \\tableofcontents + + \\mainmatter + + """ + _println(io, preamble) +end + +function writefooter(io::IO, doc::Documents.Document) + _println(io, "\n\\end{document}") +end + +function latex(io::IO, page::Documents.Page, doc::Documents.Document) + for element in page.elements + latex(io, page.mapping[element], page, doc) + end +end + +function latex(io::IO, vec::Vector, page, doc) + for each in vec + latex(io, each, page, doc) + end +end + +function latex(io::IO, anchor::Anchors.Anchor, page, doc) + id = string(hash(string(anchor.id, "-", anchor.nth))) + _println(io, "\n\\hypertarget{", id, "}{}\n") + latex(io, anchor.object, page, doc) +end + + +## Documentation Nodes. + +function latex(io::IO, node::Documents.DocsNodes, page, doc) + for node in node.nodes + latex(io, node, page, doc) + end +end + +function latex(io::IO, node::Documents.DocsNode, page, doc) + id = string(hash(string(node.anchor.id))) + # Docstring header based on the name of the binding and it's category. + _println(io, "\\hypertarget{", id, "}{} ") + _print(io, "\\hyperlink{", id, "}{\\texttt{") + latexesc(io, string(node.object.binding)) + _print(io, "}} ") + _println(io, " -- {", Utilities.doccat(node.object), ".}\n") + # # Body. May contain several concatenated docstrings. + _println(io, "\\begin{adjustwidth}{2em}{0pt}") + latexdoc(io, node.docstr, page, doc) + _println(io, "\n\\end{adjustwidth}") +end + +function latexdoc(io::IO, md::Markdown.MD, page, doc) + if haskey(md.meta, :results) + # The `:results` field contains a vector of `Docs.DocStr` objects associated with + # each markdown object. The `DocStr` contains data such as file and line info that + # we need for generating correct scurce links. + for (markdown, result) in zip(md.content, md.meta[:results]) + latex(io, Writers.MarkdownWriter.dropheaders(markdown), page, doc) + # When a source link is available then print the link. + url = Utilities.url(doc.internal.remote, doc.user.repo, result) + if url !== nothing + link = "\\href{$url}{\\texttt{source}}" + _println(io, "\n", link, "\n") + end + end + else + # Docstrings with no `:results` metadata won't contain source locations so we don't + # try to print them out. Just print the basic docstring. + render(io, mime, dropheaders(md), page, doc) + end +end + +function latexdoc(io::IO, other, page, doc) + # TODO: properly support non-markdown docstrings at some point. + latex(io, other, page, doc) +end + + +## Index, Contents, and Eval Nodes. + +function latex(io::IO, index::Documents.IndexNode, page, doc) + _println(io, "\\begin{itemize}") + for (object, _, page, mod, cat) in index.elements + id = string(hash(string(Utilities.slugify(object)))) + text = string(object.binding) + _print(io, "\\item \\hyperlink{") + _print(io, id, "}{\\texttt{") + latexesc(io, text) + _println(io, "}}") + end + _println(io, "\\end{itemize}\n") +end + +function latex(io::IO, contents::Documents.ContentsNode, page, doc) + depth = 1 + needs_end = false + _println(io, "\\begin{itemize}") + for (count, path, anchor) in contents.elements + header = anchor.object + level = Utilities.header_level(header) + id = string(hash(string(anchor.id, "-", anchor.nth))) + level < depth && _println(io, "\\end{itemize}") + level > depth && (_println(io, "\\begin{itemize}"); needs_end = true) + _print(io, "\\item \\hyperlink{", id, "}{") + latexinline(io, header.text) + _println(io, "}") + depth = level + end + needs_end && _println(io, "\\end{itemize}") + _println(io, "\\end{itemize}") + _println(io) +end + +function latex(io::IO, node::Documents.EvalNode, page, doc) + node.result === nothing ? nothing : latex(io, node.result, page, doc) +end + + +## Basic Nodes. AKA: any other content that hasn't been handled yet. + +latex(io::IO, str::AbstractString, page, doc) = _print(io, str) + +function latex(io::IO, other, page, doc) + _println(io) + latex(io, other) + _println(io) +end + +latex(io::IO, md::Markdown.MD) = latex(io, md.content) + +function latex(io::IO, content::Vector) + for c in content + latex(io, c) + end +end + +function latex(io::IO, h::Markdown.Header{N}) where N + tag = DOCUMENT_STRUCTURE[min(io.depth + N - 1, length(DOCUMENT_STRUCTURE))] + _print(io, "\\", tag, "{") + io.in_header = true + latexinline(io, h.text) + io.in_header = false + _println(io, "}\n") +end + +# Whitelisted lexers. +const LEXER = Set([ + "julia", + "jlcon", +]) + +function latex(io::IO, code::Markdown.Code) + language = isempty(code.language) ? "none" : code.language + # the julia-repl is called "jlcon" in Pygments + language = (language == "julia-repl") ? "jlcon" : language + if language in LEXER + _print(io, "\n\\begin{minted}") + _println(io, "{", language, "}") + _println(io, code.code) + _println(io, "\\end{minted}\n") + else + _println(io, "\n\\begin{lstlisting}") + _println(io, code.code) + _println(io, "\\end{lstlisting}\n") + end +end + +function latexinline(io::IO, code::Markdown.Code) + _print(io, "\\texttt{") + latexesc(io, code.code) + _print(io, "}") +end + +function latex(io::IO, md::Markdown.Paragraph) + for md in md.content + latexinline(io, md) + end + _println(io, "\n") +end + +function latex(io::IO, md::Markdown.BlockQuote) + wrapblock(io, "quote") do + latex(io, md.content) + end +end + +function latex(io::IO, md::Markdown.Admonition) + wrapblock(io, "quote") do + wrapinline(io, "textbf") do + _print(io, md.title) + end + _println(io, "\n") + latex(io, md.content) + end +end + +function latex(io::IO, f::Markdown.Footnote) + id = get(io.footnotes, f.id, 1) + _print(io, "\\footnotetext[", id, "]{") + latex(io, f.text) + _println(io, "}") +end + +function latex(io::IO, md::Markdown.List) + # `\begin{itemize}` is used here for both ordered and unordered lists since providing + # custom starting numbers for enumerated lists is simpler to do by manually assigning + # each number to `\item` ourselves rather than using `\setcounter{enumi}{<start>}`. + # + # For an ordered list starting at 5 the following will be generated: + # + # \begin{itemize} + # \item[5. ] ... + # \item[6. ] ... + # ... + # \end{itemize} + # + pad = ndigits(md.ordered + length(md.items)) + 2 + fmt = n -> (Markdown.isordered(md) ? "[$(rpad("$(n + md.ordered - 1).", pad))]" : "") + wrapblock(io, "itemize") do + for (n, item) in enumerate(md.items) + _print(io, "\\item$(fmt(n)) ") + latex(io, item) + n < length(md.items) && _println(io) + end + end +end + + +function latex(io::IO, hr::Markdown.HorizontalRule) + _println(io, "{\\rule{\\textwidth}{1pt}}") +end + +# This (equation*, split) math env seems to be the only way to correctly +# render all the equations in the Julia manual. +function latex(io::IO, math::Markdown.LaTeX) + _print(io, "\\begin{equation*}\n\\begin{split}") + _print(io, math.formula) + _println(io, "\\end{split}\\end{equation*}") +end + +function latex(io::IO, md::Markdown.Table) + _println(io, "\n\\begin{table}[h]") + _print(io, "\n\\begin{tabulary}{\\linewidth}") + _println(io, "{|", uppercase(join(md.align, '|')), "|}") + for (i, row) in enumerate(md.rows) + i === 1 && _println(io, "\\hline") + for (j, cell) in enumerate(row) + j === 1 || _print(io, " & ") + latexinline(io, cell) + end + _println(io, " \\\\") + _println(io, "\\hline") + end + _println(io, "\\end{tabulary}\n") + _println(io, "\\end{table}\n") +end + +function latex(io::IO, raw::Documents.RawNode) + raw.name === :latex ? _println(io, "\n", raw.text, "\n") : nothing +end + +# Inline Elements. + +function latexinline(io::IO, md::Vector) + for c in md + latexinline(io, c) + end +end + +function latexinline(io::IO, md::AbstractString) + latexesc(io, md) +end + +function latexinline(io::IO, md::Markdown.Bold) + wrapinline(io, "textbf") do + latexinline(io, md.text) + end +end + +function latexinline(io::IO, md::Markdown.Italic) + wrapinline(io, "emph") do + latexinline(io, md.text) + end +end + +function latexinline(io::IO, md::Markdown.Image) + wrapblock(io, "figure") do + _println(io, "\\centering") + url = if Utilities.isabsurl(md.url) + Utilities.warn("Images with absolute URLs not supported in LaTeX output.\n in $(io.filename)\n url: $(md.url)") + # We nevertheless output an \includegraphics with the URL. The LaTeX build will + # then give an error, indicating to the user that something wrong. Only the + # warning would be drowned by all the output from LaTeX. + md.url + elseif startswith(md.url, '/') + # URLs starting with a / are assumed to be relative to the document's root + normpath(lstrip(md.url, '/')) + else + normpath(joinpath(dirname(io.filename), md.url)) + end + wrapinline(io, "includegraphics") do + _print(io, url) + end + _println(io) + wrapinline(io, "caption") do + latexinline(io, md.alt) + end + _println(io) + end +end + +function latexinline(io::IO, f::Markdown.Footnote) + id = get!(io.footnotes, f.id, length(io.footnotes) + 1) + _print(io, "\\footnotemark[", id, "]") +end + +function latexinline(io::IO, md::Markdown.Link) + if io.in_header + latexinline(io, md.text) + else + if occursin(".md#", md.url) + file, target = split(md.url, ".md#"; limit = 2) + id = string(hash(target)) + wrapinline(io, "hyperlink") do + _print(io, id) + end + _print(io, "{") + latexinline(io, md.text) + _print(io, "}") + else + wrapinline(io, "href") do + latexesc(io, md.url) + end + _print(io, "{") + latexinline(io, md.text) + _print(io, "}") + end + end +end + +function latexinline(io, math::Markdown.LaTeX) + # Handle MathJax and TeX inconsistency since the first wants `\LaTeX` wrapped + # in math delims, whereas actual TeX fails when that is done. + math.formula == "\\LaTeX" ? _print(io, math.formula) : _print(io, "\\(", math.formula, "\\)") +end + +function latexinline(io, hr::Markdown.HorizontalRule) + _println(io, "\\rule{\\textwidth}{1pt}}") +end + + +# Metadata Nodes get dropped from the final output for every format but are needed throughout +# rest of the build and so we just leave them in place and print a blank line in their place. +latex(io::IO, node::Documents.MetaNode, page, doc) = _println(io, "\n") + +# Utilities. + +const _latexescape_chars = Dict{Char, AbstractString}( + '~' => "{\\textasciitilde}", + '^' => "{\\textasciicircum}", + '\\' => "{\\textbackslash}", + '\'' => "{\\textquotesingle}", + '"' => "{\\textquotedbl}", + '_' => "{\\_}", +) +for ch in "&%\$#_{}" + _latexescape_chars[ch] = "\\$ch" +end + +function latexesc(io, s::AbstractString) + for ch in s + _print(io, get(_latexescape_chars, ch, ch)) + end +end + +latexesc(s) = sprint(latexesc, s) + +function wrapblock(f, io, env) + _println(io, "\\begin{", env, "}") + f() + _println(io, "\\end{", env, "}") +end + +function wrapinline(f, io, cmd) + _print(io, "\\", cmd, "{") + f() + _print(io, "}") +end + + +function files!(out::Vector, v::Vector, depth) + for each in v + files!(out, each, depth + 1) + end + return out +end + +# Tuples come from `hide(page)` with either +# (visible, nothing, page, children) or +# (visible, page.first, pages.second, children) +function files!(out::Vector, v::Tuple, depth) + files!(out, v[2] == nothing ? v[3] : v[2] => v[3], depth) + files!(out, v[4], depth) +end + +files!(out, s::AbstractString, depth) = push!(out, ("", s, depth)) + +function files!(out, p::Pair{S, T}, depth) where {S <: AbstractString, T <: AbstractString} + push!(out, (p.first, p.second, depth)) +end + +function files!(out, p::Pair{S, V}, depth) where {S <: AbstractString, V} + push!(out, (p.first, "", depth)) + files!(out, p.second, depth) +end + +files(v::Vector) = files!(Tuple{String, String, Int}[], v, 0) + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Writers/MarkdownWriter.jl b/embedded/Documenter.jl-0.20.0/src/Writers/MarkdownWriter.jl new file mode 100644 index 0000000..054fc98 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Writers/MarkdownWriter.jl @@ -0,0 +1,167 @@ +""" +A module for rendering `Document` objects to markdown. +""" +module MarkdownWriter + +import ...Documenter: + Anchors, + Builder, + Documents, + Expanders, + Formats, + Documenter, + Utilities + +import Markdown + +function render(doc::Documents.Document) + copy_assets(doc) + mime = Formats.mimetype(:markdown) + for (src, page) in doc.internal.pages + open(Formats.extension(:markdown, page.build), "w") do io + for elem in page.elements + node = page.mapping[elem] + render(io, mime, node, page, doc) + end + end + end +end + +function copy_assets(doc::Documents.Document) + Utilities.log(doc, "copying assets to build directory.") + assets = joinpath(doc.internal.assets, "mkdocs") + if isdir(assets) + builddir = joinpath(doc.user.build, "assets") + isdir(builddir) || mkdir(builddir) + for each in readdir(assets) + src = joinpath(assets, each) + dst = joinpath(builddir, each) + ispath(dst) && Utilities.warn("Overwriting '$dst'.") + cp(src, dst; force = true) + end + else + error("assets directory '$(abspath(assets))' is missing.") + end +end + +function render(io::IO, mime::MIME"text/plain", vec::Vector, page, doc) + for each in vec + render(io, mime, each, page, doc) + end +end + +function render(io::IO, mime::MIME"text/plain", anchor::Anchors.Anchor, page, doc) + println(io, "\n<a id='", anchor.id, "-", anchor.nth, "'></a>") + render(io, mime, anchor.object, page, doc) +end + + +## Documentation Nodes. + +function render(io::IO, mime::MIME"text/plain", node::Documents.DocsNodes, page, doc) + for node in node.nodes + render(io, mime, node, page, doc) + end +end + +function render(io::IO, mime::MIME"text/plain", node::Documents.DocsNode, page, doc) + # Docstring header based on the name of the binding and it's category. + anchor = "<a id='$(node.anchor.id)' href='#$(node.anchor.id)'>#</a>" + header = "**`$(node.object.binding)`** — *$(Utilities.doccat(node.object))*." + println(io, anchor, "\n", header, "\n\n") + # Body. May contain several concatenated docstrings. + renderdoc(io, mime, node.docstr, page, doc) +end + +function renderdoc(io::IO, mime::MIME"text/plain", md::Markdown.MD, page, doc) + if haskey(md.meta, :results) + # The `:results` field contains a vector of `Docs.DocStr` objects associated with + # each markdown object. The `DocStr` contains data such as file and line info that + # we need for generating correct source links. + for (markdown, result) in zip(md.content, md.meta[:results]) + render(io, mime, dropheaders(markdown), page, doc) + # When a source link is available then print the link. + url = Utilities.url(doc.internal.remote, doc.user.repo, result) + if url !== nothing + link = "<a target='_blank' href='$url' class='documenter-source'>source</a><br>" + println(io, "\n", link, "\n") + end + end + else + # Docstrings with no `:results` metadata won't contain source locations so we don't + # try to print them out. Just print the basic docstring. + render(io, mime, dropheaders(md), page, doc) + end +end + +function renderdoc(io::IO, mime::MIME"text/plain", other, page, doc) + # TODO: properly support non-markdown docstrings at some point. + render(io, mime, other, page, doc) +end + + +## Index, Contents, and Eval Nodes. + +function render(io::IO, ::MIME"text/plain", index::Documents.IndexNode, page, doc) + for (object, _, page, mod, cat) in index.elements + page = Formats.extension(:markdown, page) + url = string(page, "#", Utilities.slugify(object)) + println(io, "- [`", object.binding, "`](", url, ")") + end + println(io) +end + +function render(io::IO, ::MIME"text/plain", contents::Documents.ContentsNode, page, doc) + for (count, path, anchor) in contents.elements + path = Formats.extension(:markdown, path) + header = anchor.object + url = string(path, '#', anchor.id, '-', anchor.nth) + link = Markdown.Link(header.text, url) + level = Utilities.header_level(header) + print(io, " "^(level - 1), "- ") + Markdown.plaininline(io, link) + println(io) + end + println(io) +end + +function render(io::IO, mime::MIME"text/plain", node::Documents.EvalNode, page, doc) + node.result === nothing ? nothing : render(io, mime, node.result, page, doc) +end + + +## Basic Nodes. AKA: any other content that hasn't been handled yet. + +function render(io::IO, ::MIME"text/plain", other, page, doc) + println(io) + Markdown.plain(io, other) + println(io) +end + +render(io::IO, ::MIME"text/plain", str::AbstractString, page, doc) = print(io, str) + +# Metadata Nodes get dropped from the final output for every format but are needed throughout +# rest of the build and so we just leave them in place and print a blank line in their place. +render(io::IO, ::MIME"text/plain", node::Documents.MetaNode, page, doc) = println(io, "\n") + +function render(io::IO, ::MIME"text/plain", raw::Documents.RawNode, page, doc) + raw.name === :html ? println(io, "\n", raw.text, "\n") : nothing +end + + +## Markdown Utilities. + +# Remove all header nodes from a markdown object and replace them with bold font. +# Only for use in `text/plain` output, since we'll use some css to make these less obtrusive +# in the HTML rendering instead of using this hack. +function dropheaders(md::Markdown.MD) + out = Markdown.MD() + out.meta = md.meta + out.content = map(dropheaders, md.content) + out +end +dropheaders(h::Markdown.Header) = Markdown.Paragraph([Markdown.Bold(h.text)]) +dropheaders(v::Vector) = map(dropheaders, v) +dropheaders(other) = other + +end diff --git a/embedded/Documenter.jl-0.20.0/src/Writers/Writers.jl b/embedded/Documenter.jl-0.20.0/src/Writers/Writers.jl new file mode 100644 index 0000000..37b518c --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/src/Writers/Writers.jl @@ -0,0 +1,132 @@ +""" +A module that provides several renderers for `Document` objects. The supported +formats are currently: + + * `:markdown` -- the default format. + * `:html` -- generates a complete HTML site with navigation and search included. + * `:latex` -- generates a PDF using LuaLaTeX. + +""" +module Writers + +import ..Documenter: + Anchors, + Builder, + Documents, + Expanders, + Formats, + Documenter, + Utilities + +import .Utilities: Selectors + +# +# Format selector definitions. +# + +abstract type FormatSelector <: Selectors.AbstractSelector end + +abstract type MarkdownFormat <: FormatSelector end +abstract type LaTeXFormat <: FormatSelector end +abstract type HTMLFormat <: FormatSelector end + +Selectors.order(::Type{MarkdownFormat}) = 1.0 +Selectors.order(::Type{LaTeXFormat}) = 2.0 +Selectors.order(::Type{HTMLFormat}) = 3.0 + +Selectors.matcher(::Type{MarkdownFormat}, fmt, _) = fmt === :markdown +Selectors.matcher(::Type{LaTeXFormat}, fmt, _) = fmt === :latex +Selectors.matcher(::Type{HTMLFormat}, fmt, _) = fmt === :html + +Selectors.runner(::Type{MarkdownFormat}, _, doc) = MarkdownWriter.render(doc) +Selectors.runner(::Type{LaTeXFormat}, _, doc) = LaTeXWriter.render(doc) +Selectors.runner(::Type{HTMLFormat}, _, doc) = HTMLWriter.render(doc) + +""" +Writes a [`Documents.Document`](@ref) object to `.user.build` directory in +the formats specified in the `.user.format` vector. + +Adding additional formats requires adding new `Selector` definitions as follows: + +```julia +abstract type CustomFormat <: FormatSelector end + +Selectors.order(::Type{CustomFormat}) = 4.0 # or a higher number. +Selectors.matcher(::Type{CustomFormat}, fmt, _) = fmt === :custom +Selectors.runner(::Type{CustomFormat}, _, doc) = CustomWriter.render(doc) + +# Definition of `CustomWriter` module below... +``` +""" +function render(doc::Documents.Document) + # Render each format. Additional formats must define an `order`, `matcher`, `runner`, as + # well as their own rendering methods in a separate module. + for each in doc.user.format + if each === :markdown && !backends_enabled[:markdown] + @warn """Deprecated format value :markdown + + The Markdown/MkDocs backend must now be imported from a separate package. + Add DocumenterMarkdown to your documentation dependencies and add + + using DocumenterMarkdown + + to your make.jl script. + + Built-in support for format=:markdown will be removed completely in a future + Documenter version, causing builds to fail completely. + + See the Output Backends section in the manual for more information. + """ + elseif each === :latex && !backends_enabled[:latex] + @warn """Deprecated format value :markdown + + The LaTeX/PDF backend must now be imported from a separate package. + Add DocumenterLaTeX to your documentation dependencies and add + + using DocumenterLaTeX + + to your make.jl script. + + Built-in support for format=:latex will be removed completely in a future + Documenter version, causing builds to fail completely. + + See the Output Backends section in the manual for more information. + """ + end + Selectors.dispatch(FormatSelector, each, doc) + end + # Revert all local links to their original URLs. + for (link, url) in doc.internal.locallinks + link.url = url + end +end + +include("MarkdownWriter.jl") +include("HTMLWriter.jl") +include("LaTeXWriter.jl") + +# This is hack to enable shell packages that would behave as in the supplementary Writer +# modules have been moved out of Documenter. +# +# External packages DocumenterMarkdown and DocumenterLaTeX can use the enable_backend +# function to mark that a certain backend is loaded in backends_enabled. That is used to +# determine whether a deprecation warning should be printed in the render method above. +# +# enable_backend() is not part of the API and will be removed as soon as LaTeXWriter and +# MarkdownWriter are actually moved out into a separate module (TODO). +backends_enabled = Dict( + :markdown => false, + :latex => false +) + +function enable_backend(backend::Symbol) + global backends_enabled + if backend in keys(backends_enabled) + backends_enabled[backend] = true + else + @error "Unknown backend. Expected one of:" keys(backends_enabled) + throw(ArgumentError("Unknown backend $backend.")) + end +end + +end diff --git a/embedded/Documenter.jl-0.20.0/test/docsystem.jl b/embedded/Documenter.jl-0.20.0/test/docsystem.jl new file mode 100644 index 0000000..a71ab86 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/docsystem.jl @@ -0,0 +1,80 @@ +module DocSystemTests + +using Test + +import Documenter: Documenter, DocSystem + +const alias_of_getdocs = DocSystem.getdocs # NOTE: won't get docstrings if in a @testset + +@testset "DocSystem" begin + ## Bindings. + @test_throws ArgumentError DocSystem.binding(9000) + let b = Docs.Binding(@__MODULE__, :DocSystem) + @test DocSystem.binding(b) == b + end + let b = DocSystem.binding(Documenter.Documents.Document) + @test b.mod === Documenter.Documents + @test b.var === :Document + end + let b = DocSystem.binding(Documenter) + @test b.mod === (Documenter) + @test b.var === :Documenter + end + let b = DocSystem.binding(:Main) + # @test b.mod === Main + @test b.var === :Main + end + let b = DocSystem.binding(DocSystem.binding) + @test b.mod === DocSystem + @test b.var === :binding + end + let b = DocSystem.binding(Documenter, :Documenter) + @test b.mod === (Documenter) + @test b.var === :Documenter + end + + ## `MultiDoc` object. + @test isdefined(DocSystem, :MultiDoc) + @test (fieldnames(DocSystem.MultiDoc)...,) == (:order, :docs) + + ## `DocStr` object. + @test isdefined(DocSystem, :DocStr) + @test (fieldnames(DocSystem.DocStr)...,) == (:text, :object, :data) + ## `getdocs`. + let b = DocSystem.binding(DocSystem, :getdocs), + d_0 = DocSystem.getdocs(b, Tuple{}), + d_1 = DocSystem.getdocs(b), + d_2 = DocSystem.getdocs(b, Union{Tuple{Any}, Tuple{Any, Type}}; compare = (==)), + d_3 = DocSystem.getdocs(b; modules = Module[Main]), + d_4 = DocSystem.getdocs(DocSystem.binding(@__MODULE__, :alias_of_getdocs)), + d_5 = DocSystem.getdocs(DocSystem.binding(@__MODULE__, :alias_of_getdocs); aliases = false) + + @test length(d_0) == 0 + @test length(d_1) == 2 + @test length(d_2) == 1 + @test length(d_3) == 0 + @test length(d_4) == 2 + @test length(d_5) == 0 + + @test d_1[1].data[:binding] == b + @test d_1[2].data[:binding] == b + @test d_1[1].data[:typesig] == Union{Tuple{Docs.Binding}, Tuple{Docs.Binding, Type}} + @test d_1[2].data[:typesig] == Union{Tuple{Any}, Tuple{Any, Type}} + @test d_1[1].data[:module] == DocSystem + @test d_1[2].data[:module] == DocSystem + + @test d_2[1].data[:binding] == b + @test d_2[1].data[:typesig] == Union{Tuple{Any}, Tuple{Any, Type}} + @test d_2[1].data[:module] == DocSystem + + @test d_1 == d_4 + @test d_1 != d_5 + end + + ## `UnionAll` + let b = DocSystem.binding(@__MODULE__, Meta.parse("f(x::T) where T")) + @test b.var == :f + end +end + +end diff --git a/embedded/Documenter.jl-0.20.0/test/doctests/broken.jl b/embedded/Documenter.jl-0.20.0/test/doctests/broken.jl new file mode 100644 index 0000000..9d4e264 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/doctests/broken.jl @@ -0,0 +1,100 @@ +module Foo +""" +```jldoctest +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 + +julia> Int64[1, 2, 3, 4] +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```jldoctest +julia> Int64[1, 2, 3, 4] +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 + +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```jldoctest +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 + +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```jldoctest +julia> begin + Int64[1, 2, 3, 4] * 2 + end +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```jldoctest +Int64[1, 2, 3, 4] * 2 + +# output + +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```jldoctest; filter = r"foo" +julia> println(" foobar") + foobaz +``` +```jldoctest +julia> 1 + 2 + +julia> 3 + 4 +``` +""" +foo() = 1 + + """ + ```jldoctest + julia> begin + Int64[1, 2, 3, 4] * 2 + end + 4-element Array{Int64,1}: + 1 + 2 + 3 + 4 + ``` + ```jldoctest + julia> println(); println("foo") + + bar + ``` + """ + foo(x) = 1 + +end # module diff --git a/embedded/Documenter.jl-0.20.0/test/doctests/broken.md b/embedded/Documenter.jl-0.20.0/test/doctests/broken.md new file mode 100644 index 0000000..aa0ee7d --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/doctests/broken.md @@ -0,0 +1,79 @@ +```@docs +DocTestsTest.Foo.foo +``` + +```jldoctest +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 + +julia> Int64[1, 2, 3, 4] +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```jldoctest +julia> Int64[1, 2, 3, 4] +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 + +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```jldoctest +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 + +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```jldoctest +julia> begin + Int64[1, 2, 3, 4] * 2 + end +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```jldoctest +Int64[1, 2, 3, 4] * 2 + +# output + +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```jldoctest; filter = r"foo" +julia> println(" foobar") + foobaz +``` +```jldoctest +julia> 1 + 2 + +julia> 3 + 4 +``` \ No newline at end of file diff --git a/embedded/Documenter.jl-0.20.0/test/doctests/doctests.jl b/embedded/Documenter.jl-0.20.0/test/doctests/doctests.jl new file mode 100644 index 0000000..af883e2 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/doctests/doctests.jl @@ -0,0 +1,26 @@ +module DocTestsTest +using Documenter, Test + +println("="^50) +@info("Testing `doctest = :fix`") +mktempdir(@__DIR__) do dir + srcdir = mktempdir(dir) + builddir = mktempdir(dir) + cp(joinpath(@__DIR__, "broken.md"), joinpath(srcdir, "index.md")) + cp(joinpath(@__DIR__, "broken.jl"), joinpath(srcdir, "src.jl")) + include(joinpath(srcdir, "src.jl")) + @eval using .Foo + # fix up + makedocs(sitename="-", modules = [Foo], source = srcdir, build = builddir, doctest = :fix) + # test that strict = true works + makedocs(sitename="-", modules = [Foo], source = srcdir, build = builddir, strict = true) + # also test that we obtain the expected output + @test read(joinpath(srcdir, "index.md"), String) == + read(joinpath(@__DIR__, "fixed.md"), String) + @test read(joinpath(srcdir, "src.jl"), String) == + read(joinpath(@__DIR__, "fixed.jl"), String) +end +@info("Done testing `doctest = :fix`") +println("="^50) + +end # module diff --git a/embedded/Documenter.jl-0.20.0/test/doctests/fixed.jl b/embedded/Documenter.jl-0.20.0/test/doctests/fixed.jl new file mode 100644 index 0000000..c6852bf --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/doctests/fixed.jl @@ -0,0 +1,102 @@ +module Foo +""" +```jldoctest +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 2 + 4 + 6 + 8 + +julia> Int64[1, 2, 3, 4] +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```jldoctest +julia> Int64[1, 2, 3, 4] +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 + +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 2 + 4 + 6 + 8 +``` +```jldoctest +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 2 + 4 + 6 + 8 + +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 2 + 4 + 6 + 8 +``` +```jldoctest +julia> begin + Int64[1, 2, 3, 4] * 2 + end +4-element Array{Int64,1}: + 2 + 4 + 6 + 8 +``` +```jldoctest +Int64[1, 2, 3, 4] * 2 + +# output + +4-element Array{Int64,1}: + 2 + 4 + 6 + 8 +``` +```jldoctest; filter = r"foo" +julia> println(" foobar") + foobar +``` +```jldoctest +julia> 1 + 2 +3 + +julia> 3 + 4 +7 +``` +""" +foo() = 1 + + """ + ```jldoctest + julia> begin + Int64[1, 2, 3, 4] * 2 + end + 4-element Array{Int64,1}: + 2 + 4 + 6 + 8 + ``` + ```jldoctest + julia> println(); println("foo") + + foo + ``` + """ + foo(x) = 1 + +end # module diff --git a/embedded/Documenter.jl-0.20.0/test/doctests/fixed.md b/embedded/Documenter.jl-0.20.0/test/doctests/fixed.md new file mode 100644 index 0000000..c7a87e8 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/doctests/fixed.md @@ -0,0 +1,81 @@ +```@docs +DocTestsTest.Foo.foo +``` + +```jldoctest +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 2 + 4 + 6 + 8 + +julia> Int64[1, 2, 3, 4] +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 +``` +```jldoctest +julia> Int64[1, 2, 3, 4] +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 + +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 2 + 4 + 6 + 8 +``` +```jldoctest +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 2 + 4 + 6 + 8 + +julia> Int64[1, 2, 3, 4] * 2 +4-element Array{Int64,1}: + 2 + 4 + 6 + 8 +``` +```jldoctest +julia> begin + Int64[1, 2, 3, 4] * 2 + end +4-element Array{Int64,1}: + 2 + 4 + 6 + 8 +``` +```jldoctest +Int64[1, 2, 3, 4] * 2 + +# output + +4-element Array{Int64,1}: + 2 + 4 + 6 + 8 +``` +```jldoctest; filter = r"foo" +julia> println(" foobar") + foobar +``` +```jldoctest +julia> 1 + 2 +3 + +julia> 3 + 4 +7 +``` \ No newline at end of file diff --git a/embedded/Documenter.jl-0.20.0/test/dom.jl b/embedded/Documenter.jl-0.20.0/test/dom.jl new file mode 100644 index 0000000..c855f4d --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/dom.jl @@ -0,0 +1,92 @@ +module DOMTests + +using Test + +import Documenter.Utilities.DOM: DOM, @tags, HTMLDocument + +@tags div ul li p + +@testset "DOM" begin + for tag in (:div, :ul, :li, :p) + TAG = @eval $tag + @test isa(TAG, DOM.Tag) + @test TAG.name === tag + end + + @test div().name === :div + @test div().text == "" + @test isempty(div().nodes) + @test isempty(div().attributes) + + @test div("...").name === :div + @test div("...").text == "" + @test length(div("...").nodes) === 1 + @test div("...").nodes[1].text == "..." + @test div("...").nodes[1].name === Symbol("") + @test isempty(div("...").attributes) + + @test div[".class"]("...").name === :div + @test div[".class"]("...").text == "" + @test length(div[".class"]("...").nodes) === 1 + @test div[".class"]("...").nodes[1].text == "..." + @test div[".class"]("...").nodes[1].name === Symbol("") + @test length(div[".class"]("...").attributes) === 1 + @test div[".class"]("...").attributes[1] == (:class => "class") + @test div[:attribute].attributes[1] == (:attribute => "") + @test div[:attribute => "value"].attributes[1] == (:attribute => "value") + + let d = div(ul(map(li, [string(n) for n = 1:10]))) + @test d.name === :div + @test d.text == "" + @test isempty(d.attributes) + @test length(d.nodes) === 1 + let u = d.nodes[1] + @test u.name === :ul + @test u.text == "" + @test isempty(u.attributes) + @test length(u.nodes) === 10 + for n = 1:10 + let v = u.nodes[n] + @test v.name === :li + @test v.text == "" + @test isempty(v.attributes) + @test length(v.nodes) === 1 + @test v.nodes[1].name === Symbol("") + @test v.nodes[1].text == string(n) + @test !isdefined(v.nodes[1], :attributes) + @test !isdefined(v.nodes[1], :nodes) + end + end + end + end + + @tags script style img + + @test string(div(p("one"), p("two"))) == "<div><p>one</p><p>two</p></div>" + @test string(div[:key => "value"]) == "<div key=\"value\"></div>" + @test string(p(" < > & ' \" ")) == "<p> < > & ' " </p>" + @test string(img[:src => "source"]) == "<img src=\"source\"/>" + @test string(img[:none]) == "<img none/>" + @test string(script(" < > & ' \" ")) == "<script> < > & ' \" </script>" + @test string(style(" < > & ' \" ")) == "<style> < > & ' \" </style>" + @test string(script) == "<script>" + + function locally_defined() + @tags button + @test try + x = button + true + catch err + false + end + end + @test !isdefined(@__MODULE__, :button) + locally_defined() + @test !isdefined(@__MODULE__, :button) + + # HTMLDocument + @test string(HTMLDocument(div())) == "<!DOCTYPE html>\n<div></div>\n" + @test string(HTMLDocument("custom doctype", div())) == "<!DOCTYPE custom doctype>\n<div></div>\n" +end + +end diff --git a/embedded/Documenter.jl-0.20.0/test/errors/make.jl b/embedded/Documenter.jl-0.20.0/test/errors/make.jl new file mode 100644 index 0000000..74e8bf9 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/errors/make.jl @@ -0,0 +1,21 @@ +module ErrorsModule + +""" +```jldoctest +julia> a = 1 +2 + +``` + +```jldoctest +``` +""" +func(x) = x + +end + +using Documenter + +makedocs(sitename="-", modules = [ErrorsModule]) + +@test_throws ErrorException makedocs(modules = [ErrorsModule], strict = true) diff --git a/embedded/Documenter.jl-0.20.0/test/errors/src/index.md b/embedded/Documenter.jl-0.20.0/test/errors/src/index.md new file mode 100644 index 0000000..71fb398 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/errors/src/index.md @@ -0,0 +1,99 @@ + +```@docs +missing_doc +``` + +```@docs +parse error +``` + +```@meta +CurrentModule = NonExistantModule +``` + +```@autodocs +Modules = [NonExistantModule] +``` + +```@eval +NonExistantModule +``` + +```@docs +# comment in a @docs block +``` + +[`foo(x::Foo)`](@ref) creates an [`UndefVarError`](@ref) when `eval`d +for the type signature, since `Foo` is not defined. + +Numeric literals don't have bindings: [`1`](@ref). Nor [`"strings"`](@ref). +[`:symbols`] do, however. + +Some syntax errors in references will fail with an `ParseError`: [`foo+*bar`](@ref). +Others, like [`foo(x`](@ref) will give an `:incomplete` expression. + +This is the footnote [^1]. And [^another] [^another]. + +[^1]: one + + [^nested]: a nested footnote + +[^another_one]: + + Things! [^1]. [^2]. + +[^nested] + +[^nested]: + + Duplicate [^1] nested footnote. + +```@docs +ErrorsModule.func +``` + +```jldoctest +julia> b = 1 +2 + +julia> x + +julia> x +ERROR: UndefVarError: x not defined + +julia> x +``` + +```jldoctest; setup +julia> 1+1 +2 +``` +```jldoctest invalidkwarg1; setup +julia> 1+1 +2 +``` +```jldoctest; setup == 1 +julia> 1+1 +2 +``` +```jldoctest invalidkwarg2; setup == 1 +julia> 1+1 +2 +``` + +```jldoctest; output = false +foo(a, b) = a * b +foo(2, 3) + +# output + +1 +``` +```jldoctest; output = true +foo(a, b) = a * b +foo(2, 3) + +# output + +1 +``` diff --git a/embedded/Documenter.jl-0.20.0/test/examples/images/logo.gif b/embedded/Documenter.jl-0.20.0/test/examples/images/logo.gif new file mode 100644 index 0000000..bbf8f6d Binary files /dev/null and b/embedded/Documenter.jl-0.20.0/test/examples/images/logo.gif differ diff --git a/embedded/Documenter.jl-0.20.0/test/examples/images/logo.jpg b/embedded/Documenter.jl-0.20.0/test/examples/images/logo.jpg new file mode 100644 index 0000000..8ffac37 Binary files /dev/null and b/embedded/Documenter.jl-0.20.0/test/examples/images/logo.jpg differ diff --git a/embedded/Documenter.jl-0.20.0/test/examples/images/logo.png b/embedded/Documenter.jl-0.20.0/test/examples/images/logo.png new file mode 100644 index 0000000..3c0c8a1 Binary files /dev/null and b/embedded/Documenter.jl-0.20.0/test/examples/images/logo.png differ diff --git a/embedded/Documenter.jl-0.20.0/test/examples/images/logo.webp b/embedded/Documenter.jl-0.20.0/test/examples/images/logo.webp new file mode 100644 index 0000000..5bfa5c5 Binary files /dev/null and b/embedded/Documenter.jl-0.20.0/test/examples/images/logo.webp differ diff --git a/embedded/Documenter.jl-0.20.0/test/examples/make.jl b/embedded/Documenter.jl-0.20.0/test/examples/make.jl new file mode 100644 index 0000000..f061624 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/make.jl @@ -0,0 +1,147 @@ +# Defines the modules referred to in the example docs (under src/) and then builds them. +# It can be called separately to build the examples/, or as part of the test suite. +# +# It defines a set of variables (`examples_*`) that can be used in the tests. +# The `examples_root` should be used to check whether this file has already been included +# or not and should be kept unique. +isdefined(@__MODULE__, :examples_root) && error("examples_root is already defined\n$(@__FILE__) included multiple times?") + +# The `Mod` and `AutoDocs` modules are assumed to exists in the Main module. +(@__MODULE__) === Main || error("$(@__FILE__) must be included into Main.") + +# Modules `Mod` and `AutoDocs` +module Mod + """ + func(x) + + [`T`](@ref) + """ + func(x) = x + + """ + T + + [`func(x)`](@ref) + """ + mutable struct T end +end + +"`AutoDocs` module." +module AutoDocs + module Pages + include("pages/a.jl") + include("pages/b.jl") + include("pages/c.jl") + include("pages/d.jl") + include("pages/e.jl") + end + + "Function `f`." + f(x) = x + + "Constant `K`." + const K = 1 + + "Type `T`." + mutable struct T end + + "Macro `@m`." + macro m() end + + "Module `A`." + module A + "Function `A.f`." + f(x) = x + + "Constant `A.K`." + const K = 1 + + "Type `B.T`." + mutable struct T end + + "Macro `B.@m`." + macro m() end + end + + "Module `B`." + module B + "Function `B.f`." + f(x) = x + + "Constant `B.K`." + const K = 1 + + "Type `B.T`." + mutable struct T end + + "Macro `B.@m`." + macro m() end + end +end + +# Build example docs +using Documenter + +const examples_root = dirname(@__FILE__) + +@info("Building mock package docs: MarkdownWriter") +examples_markdown_doc = makedocs( + format = :markdown, + debug = true, + root = examples_root, + build = "builds/markdown", + doctest = false, +) + + +htmlbuild_pages = Any[ + "**Home**" => "index.md", + "Manual" => [ + "man/tutorial.md", + ], + hide("hidden.md"), + "Library" => [ + "lib/functions.md", + "lib/autodocs.md", + ], + hide("Hidden Pages" => "hidden/index.md", Any[ + "Page X" => "hidden/x.md", + "hidden/y.md", + "hidden/z.md", + ]) +] + +@info("Building mock package docs: HTMLWriter / local build") +examples_html_local_doc = makedocs( + debug = true, + root = examples_root, + build = "builds/html-local", + html_prettyurls = false, + doctestfilters = [r"Ptr{0x[0-9]+}"], + assets = ["assets/custom.css"], + sitename = "Documenter example", + pages = htmlbuild_pages, + + linkcheck = true, + linkcheck_ignore = [r"(x|y).md", "z.md", r":func:.*"], + + html_edit_branch = nothing, +) + +# Build with pretty URLs and canonical links +@info("Building mock package docs: HTMLWriter / deployment build") +examples_html_deploy_doc = makedocs( + debug = true, + root = examples_root, + build = "builds/html-deploy", + html_prettyurls = true, + html_canonical = "https://example.com/stable", + doctestfilters = [r"Ptr{0x[0-9]+}"], + assets = [ + "assets/favicon.ico", + "assets/custom.css" + ], + sitename = "Documenter example", + pages = htmlbuild_pages, + doctest = false, +) diff --git a/embedded/Documenter.jl-0.20.0/test/examples/mkdocs.yml b/embedded/Documenter.jl-0.20.0/test/examples/mkdocs.yml new file mode 100644 index 0000000..087f324 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/mkdocs.yml @@ -0,0 +1,34 @@ +site_name: Documenter.jl +repo_url: https://github.com/JuliaDocs/Documenter.jl +site_description: Julia package documentation generator. +site_author: Michael Hatherly + +theme: material + +extra: + palette: + primary: 'indigo' + accent: 'blue' + +extra_css: + - assets/Documenter.css + +markdown_extensions: + - codehilite + - extra + - tables + - fenced_code + +extra_javascript: + - https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_HTML + - assets/mathjaxhelper.js + +docs_dir: 'build' + +pages: +- Home: index.md +- Manual: + - Tutorial: man/tutorial.md +- Library: + - Functions: lib/functions.md + - AutoDocs: lib/autodocs.md diff --git a/embedded/Documenter.jl-0.20.0/test/examples/pages/a.jl b/embedded/Documenter.jl-0.20.0/test/examples/pages/a.jl new file mode 100644 index 0000000..4f06c5f --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/pages/a.jl @@ -0,0 +1,22 @@ + +""" +`f` from page `a.jl`. + +Links: + +- [`ccall`](@ref) +- [`while`](@ref) +- [`@time(x)`](@ref) +- [`T(x)`](@ref) +- [`T(x, y)`](@ref) +- [`f(::Integer)`](@ref) +- [`f(::Any)`](@ref) +- [`f(::Any, ::Any)`](@ref) +- [`f(x, y, z)`](@ref) + +[^footnote]: + + Footnote contents. [^footnote] + +""" +f(x) = x diff --git a/embedded/Documenter.jl-0.20.0/test/examples/pages/b.jl b/embedded/Documenter.jl-0.20.0/test/examples/pages/b.jl new file mode 100644 index 0000000..fa67e31 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/pages/b.jl @@ -0,0 +1,17 @@ + +""" +`f` from page `b.jl`. + +Links: + +- [`ccall`](@ref) +- [`while`](@ref) +- [`@time`](@ref) +- [`T`](@ref) +- [`f`](@ref) +- [`f(::Any)`](@ref) +- [`f(::Any, ::Any)`](@ref) +- [`f(::Any, ::Any, ::Any)`](@ref) + +""" +f(x, y) = x + y diff --git a/embedded/Documenter.jl-0.20.0/test/examples/pages/c.jl b/embedded/Documenter.jl-0.20.0/test/examples/pages/c.jl new file mode 100644 index 0000000..8398bd0 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/pages/c.jl @@ -0,0 +1,17 @@ + +""" +`f` from page `c.jl`. + +Links: + +- [`ccall`](@ref) +- [`while`](@ref) +- [`@time`](@ref) +- [`T`](@ref) +- [`f`](@ref) +- [`f(::Any)`](@ref) +- [`f(::Any, ::Any)`](@ref) +- [`f(::Any, ::Any, ::Any)`](@ref) + +""" +f(x, y, z) = x + y + z diff --git a/embedded/Documenter.jl-0.20.0/test/examples/pages/d.jl b/embedded/Documenter.jl-0.20.0/test/examples/pages/d.jl new file mode 100644 index 0000000..626b85d --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/pages/d.jl @@ -0,0 +1,57 @@ + +""" +`T` from page `d.jl`. + +Links: + +- [`ccall`](@ref) +- [`while`](@ref) +- [`@time`](@ref) +- [`T`](@ref) +- [`f`](@ref) +- [`f(x)`](@ref) +- [`f(x, y)`](@ref) +- [`f(::Any, ::Any, ::Any)`](@ref) + +""" +mutable struct T end + + +""" +`T` from page `d.jl`. + +Links: + +- [`ccall`](@ref) +- [`while`](@ref) +- [`@time`](@ref) +- [`T(x)`](@ref) +- [`T(x, y)`](@ref) +- [`T(x, y, z)`](@ref) +- [`f`](@ref) +- [`f(x)`](@ref) +- [`f(x, y)`](@ref) +- [`f(::Any, ::Any, ::Any)`](@ref) + +""" +T(x) = T() + +""" +`T` from page `d.jl`. + +Links: + +- [`ccall`](@ref) +- [`while`](@ref) +- [`@time`](@ref) +- [`T()`](@ref) +- [`T(x)`](@ref) +- [`T(x, y)`](@ref) +- [`T(x, y, z)`](@ref) +- [`f`](@ref) +- [`f(x)`](@ref) +- [`f(x, y)`](@ref) +- [`f(::Any, ::Any, ::Any)`](@ref) + +""" +T(x, y) = T() diff --git a/embedded/Documenter.jl-0.20.0/test/examples/pages/e.jl b/embedded/Documenter.jl-0.20.0/test/examples/pages/e.jl new file mode 100644 index 0000000..f5f0c2c --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/pages/e.jl @@ -0,0 +1,35 @@ +module E + +export f_1, f_2, f_3 + +"f_1" +f_1(x) = x + +"f_2" +f_2(x) = x + +"f_3" +f_3(x) = x + + +"g_1" +g_1(x) = x + +"g_2" +g_2(x) = x + +"g_3" +g_3(x) = x + +export T_1 + +"T_1" +mutable struct T_1 end + +"T_2" +mutable struct T_2 end + +"T_3" +struct T_3{T} end + +end diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/assets/custom.css b/embedded/Documenter.jl-0.20.0/test/examples/src/assets/custom.css new file mode 100644 index 0000000..4502c59 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/assets/custom.css @@ -0,0 +1,5 @@ +/* custom.css */ + +center.raw-html-block { + color: red; +} diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/assets/custom.js b/embedded/Documenter.jl-0.20.0/test/examples/src/assets/custom.js new file mode 100644 index 0000000..d465f83 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/assets/custom.js @@ -0,0 +1 @@ +// custom javascript diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/assets/favicon.ico b/embedded/Documenter.jl-0.20.0/test/examples/src/assets/favicon.ico new file mode 100644 index 0000000..d793195 Binary files /dev/null and b/embedded/Documenter.jl-0.20.0/test/examples/src/assets/favicon.ico differ diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/assets/search.js b/embedded/Documenter.jl-0.20.0/test/examples/src/assets/search.js new file mode 100644 index 0000000..4ef34f3 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/assets/search.js @@ -0,0 +1 @@ +// overrides Documenter's search.js diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/hidden.md b/embedded/Documenter.jl-0.20.0/test/examples/src/hidden.md new file mode 100644 index 0000000..1ffb11c --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/hidden.md @@ -0,0 +1,3 @@ +# Hidden (toplevel) + +## Section diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/hidden/index.md b/embedded/Documenter.jl-0.20.0/test/examples/src/hidden/index.md new file mode 100644 index 0000000..ebab4b2 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/hidden/index.md @@ -0,0 +1,15 @@ +# Hidden pages + +Pages can be hidden with the [`hide`](@ref) function. + +## List of hidden pages + +- [Hidden page 1](x.md) +- [Hidden page 2](y.md) +- [Hidden page 3](z.md) + +## Docs for `hide` + +```@docs +hide +``` diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/hidden/x.md b/embedded/Documenter.jl-0.20.0/test/examples/src/hidden/x.md new file mode 100644 index 0000000..8d5e6a6 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/hidden/x.md @@ -0,0 +1,4 @@ +# Hidden 1 + +## First heading +## Second heading diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/hidden/y.md b/embedded/Documenter.jl-0.20.0/test/examples/src/hidden/y.md new file mode 100644 index 0000000..918e723 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/hidden/y.md @@ -0,0 +1 @@ +# Hidden 2 diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/hidden/z.md b/embedded/Documenter.jl-0.20.0/test/examples/src/hidden/z.md new file mode 100644 index 0000000..922f3d8 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/hidden/z.md @@ -0,0 +1 @@ +# Hidden 3 diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/index.md b/embedded/Documenter.jl-0.20.0/test/examples/src/index.md new file mode 100644 index 0000000..a944153 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/index.md @@ -0,0 +1,447 @@ +# Documentation + +## Index Page + +```@contents +Pages = ["index.md"] +Depth = 5 +``` + +## Functions Contents + +```@contents +Pages = ["lib/functions.md"] +Depth = 3 +``` + +## Tutorial Contents + +```@contents +Pages = ["man/tutorial.md"] +``` + +## Index + +```@index +``` + +### Embedded `@ref` links headers: [`ccall`](@ref) + +[#60](@ref) [#61](@ref) + +```@repl +zeros(5, 5) +zeros(50, 50) +``` + +```@meta +DocTestSetup = quote + using Base + x = -3:0.01:3 + y = -4:0.02:5 + z = [Float64((xi^2 + yi^2)) for xi in x, yi in y] +end +``` + +```jldoctest +julia> [1.0, 2.0, 3.0] +3-element Array{Float64,1}: + 1.0 + 2.0 + 3.0 + +``` + +```jldoctest +julia> println(" "^5) + +julia> "\nfoo\n\nbar\n\n\nbaz" +"\nfoo\n\nbar\n\n\nbaz" + +julia> println(ans) + +foo + +bar + + +baz +``` + + * `one` two three + * four `five` six + + * ``` + one + ``` + +## Raw Blocks + +```@raw html +<center class="raw-html-block"> + <strong>CENTER</strong> +</center> +``` + +```@raw latex +\begin{verbatim} +``` + +```@raw latex +\end{verbatim} +``` + +# Symbols in doctests + +```jldoctest +julia> a = :undefined +:undefined + +julia> a +:undefined +``` + +# Named doctests + +```jldoctest test-one +julia> a = 1 +1 +``` + +```jldoctest test-one +julia> a + 1 +2 +``` + +# Filtered doctests + +## Global + +```jldoctest +julia> print("Ptr{0x123456}") +Ptr{0x654321} +``` + +## Local +```@meta +DocTestFilters = [r"foo[a-z]+"] +``` + +```jldoctest +julia> print("foobar") +foobuu +``` + +```@meta +DocTestFilters = [r"foo[a-z]+", r"[0-9]+"] +``` + +```jldoctest +julia> print("foobar123") +foobuu456 +``` + +```@meta +DocTestFilters = r"foo[a-z]+" +``` + +```jldoctest +julia> print("foobar") +foobuu +``` + +```@meta +DocTestFilters = [] +``` + +## Errors + +```@meta +DocTestFilters = [r"Stacktrace:\n \[1\][\s\S]+"] +``` + +```jldoctest +julia> error() +ERROR: +Stacktrace: + [1] error() at ./thisfiledoesnotexist.jl:123456789 +``` + + +```jldoctest +julia> error() +ERROR: +Stacktrace: +[...] +``` + +```@meta +DocTestFilters = [] +``` + +# Doctest keyword arguments + +```jldoctest; setup = :(f(x) = x^2; g(x) = x) +julia> f(2) +4 + +julia> g(2) +2 +``` +```jldoctest +julia> f(2) +ERROR: UndefVarError: f not defined +``` + +```jldoctest PR650; setup = :(f(x) = x^2; g(x) = x) +julia> f(2) +4 + +julia> g(2) +2 +``` +```jldoctest PR650 +julia> f(2) +4 + +julia> g(2) +2 +``` + +```jldoctest; filter = [r"foo[a-z]+"] +julia> print("foobar") +foobuu +``` + +```jldoctest; filter = [r"foo[a-z]+", r"[0-9]+"] +julia> print("foobar123") +foobuu456 +``` + +```jldoctest; filter = r"foo[a-z]+" +julia> print("foobar") +foobuu +``` + +```jldoctest; filter = r"foo[a-z]+", setup = :(f() = print("foobar")) +julia> f() +foobuu +``` + +```jldoctest; output = false +foo(a, b) = a * b +foo(2, 3) + +# output + +6 +``` + + +# Sanitise module names + +```jldoctest +julia> struct T end + +julia> t = T() +T() + +julia> fullname(@__MODULE__) +(:Main,) + +julia> fullname(Base.Broadcast) +(:Base, :Broadcast) + +julia> @__MODULE__ +Main +``` + +# Issue398 + +```@meta +DocTestSetup = quote + module Issue398 + + struct TestType{T} end + + function _show end + Base.show(io::IO, t::TestType) = _show(io, t) + + macro define_show_and_make_object(x, y) + z = Expr(:quote, x) + esc(quote + $(Issue398)._show(io::IO, t::$(Issue398).TestType{$z}) = print(io, $y) + const $x = $(Issue398).TestType{$z}() + end) + end + + export @define_show_and_make_object + + end # module + + using .Issue398 +end +``` + +```jldoctest +julia> @define_show_and_make_object q "abcd" +abcd +``` + +```@meta +DocTestSetup = nothing +``` + +# Issue653 + +```jldoctest +julia> struct MyException <: Exception + msg::AbstractString + end + +julia> function Base.showerror(io::IO, err::MyException) + print(io, "MyException: ") + print(io, err.msg) + end + +julia> err = MyException("test exception") +MyException("test exception") + +julia> sprint(showerror, err) +"MyException: test exception" + +julia> throw(MyException("test exception")) +ERROR: MyException: test exception +``` + +# Issue418 + +```jldoctest +julia> f(x::Float64) = x +f (generic function with 1 method) + +julia> f("") +ERROR: MethodError: no method matching f(::String) +Closest candidates are: + f(!Matched::Float64) at none:1 +``` + + +```jldoctest +julia> a = 1 +1 + +julia> b = 2 +2 + +julia> ex = :(a + b) +:(a + b) + +julia> eval(ex) +3 +``` + +```@repl +ex = :(1 + 5) +eval(ex) +``` + +```@example +ex = :(1 + 5) +eval(ex) +``` + +# Issue #793 +```jldoctest +julia> write("issue793.jl", "\"Hello!\""); + +julia> include("issue793.jl") +"Hello!" + +julia> rm("issue793.jl"); +``` +```@repl +write("issue793.jl", "\"Hello!\"") +include("issue793.jl") +rm("issue793.jl") +``` +```@example +write("issue793.jl", "\"Hello!\"") +r = include("issue793.jl") +rm("issue793.jl") +r +``` + + +```jldoctest +julia> a = 1 +1 + +julia> ans +1 +``` + +# Issue513 + +```jldoctest named +julia> a = 1 +1 + +julia> ans +1 +``` + +# Filtering of `Main.` + +```jldoctest +julia> struct Point end; + +julia> println(Point) +Point + +julia> sqrt(100) +10.0 + +julia> sqrt = 4 +ERROR: cannot assign variable Base.sqrt from module Main +``` + +```jldoctest +julia> g(x::Float64, y) = 2x + y +g (generic function with 1 method) + +julia> g(x, y::Float64) = x + 2y +g (generic function with 2 methods) + +julia> g(2.0, 3) +7.0 + +julia> g(2, 3.0) +8.0 + +julia> g(2.0, 3.0) +ERROR: MethodError: g(::Float64, ::Float64) is ambiguous. Candidates: + g(x, y::Float64) in Main at none:1 + g(x::Float64, y) in Main at none:1 +Possible fix, define + g(::Float64, ::Float64) +``` + +# Anonymous function declaration + +```jldoc +julia> x->x # ignore error on 0.7 +#1 (generic function with 1 method) +``` + +# Assigning symbols example + +```@example +r = :a +``` + +# Bad links (Windows) + +* [Colons not allowed on Windows -- `some:path`](some:path) +* [No "drive" -- `:path`](:path) +* [Absolute Windows paths -- `X:\some\path`](X:\some\path) diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/lib/autodocs.md b/embedded/Documenter.jl-0.20.0/test/examples/src/lib/autodocs.md new file mode 100644 index 0000000..48149dd --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/lib/autodocs.md @@ -0,0 +1,52 @@ +# `@autodocs` tests + +```@meta +CurrentModule = Main +``` + +## Public + +Should include docs for + + * [`AutoDocs.Pages.E.f_1`](@ref) + * [`AutoDocs.Pages.E.f_2`](@ref) + * [`AutoDocs.Pages.E.f_3`](@ref) + +in that order. + +```@autodocs +Modules = [AutoDocs.Pages.E] +Private = false +Order = [:function] +``` + +## Private + +Should include docs for + + * [`AutoDocs.Pages.E.g_1`](@ref) + * [`AutoDocs.Pages.E.g_2`](@ref) + * [`AutoDocs.Pages.E.g_3`](@ref) + +in that order. + +```@autodocs +Modules = [AutoDocs.Pages.E] +Public = false +Order = [:function] +``` + +## Ordering of Public and Private + +Should include docs for + + * [`AutoDocs.Pages.E.T_1`](@ref) + * [`AutoDocs.Pages.E.T_2`](@ref) + +in that order. + +```@autodocs +Modules = [AutoDocs.Pages.E] +Order = [:type] +``` + diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/lib/crlf.md b/embedded/Documenter.jl-0.20.0/test/examples/src/lib/crlf.md new file mode 100644 index 0000000..62cdc0d --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/lib/crlf.md @@ -0,0 +1,13 @@ +!!! warning + + This file contains windows line endings. Do not edit. + +```jldoctest +a = 1 +b = 2 +a + b + +# output + +3 +``` diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/lib/functions.md b/embedded/Documenter.jl-0.20.0/test/examples/src/lib/functions.md new file mode 100644 index 0000000..9f9256a --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/lib/functions.md @@ -0,0 +1,209 @@ + +```@meta +CurrentModule = Main.Mod +``` + +# Function Index + +```@index +Pages = ["lib/functions.md"] +``` + +# Functions + +[`ccall`](@ref), [`func(x)`](@ref), [`T`](@ref), [`for`](@ref), and [`while`](@ref). + +```@docs +func(x) +T +ccall +for +while +@time +@assert +``` + +# Foo + +```@example +@show pwd() +a = 1 +``` + +... + +```@example +@isdefined a +``` + +```@example 1 +f(x) = 2x +g(x) = 3x +nothing # hide +``` + +```@example 2 +x, y = 1, 2 +println(x, y) +``` + +```@example 3 +struct T end +t = T() +``` + +```@example hide-all-the-things +a = 1#hide +b = 2# hide +c = 3# hide +d = 4 #hide +e = 5 # hide +f = 6 # hide +a + b + c + d + e + f +``` + +## Foo + +```@example 3 +@isdefined T +@show @isdefined t # hide +@show typeof(T) +typeof(t) # hide +``` + +```@example 2 +x + y +``` + +```@example 1 +f(2), g(2) +``` + +### Foo + +```@example 2 +x - y +``` + +```@example 1 +f(1), g(1) +``` + +```@example 3 +using InteractiveUtils +@which T() +``` + +```@example continued-code +A = 1 +``` +```@example continued-code; continued = true +for i in 1:3 +``` +```@example +A = 2 +``` +```@example continued-code; continued = true + println(A + i) +``` +```@example continued-code +end +``` +```@example continued-code +A + 1 +``` + +#### Foo + +```@example +a = 1 +b = ans +@assert a === b +``` + +```@repl +using Random # hide +Random.seed!(1) # hide +nothing +rand() +a = 1 +println(a) +b = 2 +a + b +struct T + x :: Int + y :: Vector +end +x = T(1, [1]) +x.y +x.x +``` + +```@repl 1 +d = 1 +``` + +```@repl 1 +println(d) +``` + +Test setup function + +```@setup testsetup +w = 5 +``` + +```@example testsetup +@assert w === 5 +``` + +```@repl testsetup +@assert w === 5 +``` + +# Autodocs + +```@meta +CurrentModule = Main +``` + +## AutoDocs Module + +```@autodocs +Modules = [AutoDocs] +``` + +## Functions, Modules, and Macros + +```@autodocs +Modules = [AutoDocs.A, AutoDocs.B] +Order = [:function, :module, :macro] +``` + +## Constants and Types + +```@autodocs +Modules = [AutoDocs.A, AutoDocs.B] +Order = [:constant, :type] +``` + +## Autodocs by Page + +```@autodocs +Modules = [AutoDocs.Pages] +Pages = ["a.jl", "b.jl"] +``` + +```@autodocs +Modules = [AutoDocs.Pages] +Pages = ["c.jl", "d.jl"] +``` + +A footnote reference [^footnote]. + +# Named docstring `@ref`s + + * a normal docstring `@ref` link: [`AutoDocs.Pages.f`](@ref); + * a named docstring `@ref` link: [`f`](@ref AutoDocs.Pages.f); + * and a link with custom text: [`@time 1 + 2`](@ref @time); + * some invalid syntax: [`for i = 1:10; ...`](@ref for). diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/man/data.csv b/embedded/Documenter.jl-0.20.0/test/examples/src/man/data.csv new file mode 100644 index 0000000..0584e1d --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/man/data.csv @@ -0,0 +1,2 @@ +csv,data,file +1,2,3 diff --git a/embedded/Documenter.jl-0.20.0/test/examples/src/man/tutorial.md b/embedded/Documenter.jl-0.20.0/test/examples/src/man/tutorial.md new file mode 100644 index 0000000..935ef30 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/src/man/tutorial.md @@ -0,0 +1,338 @@ +# Tutorial + +[Documentation](@ref) + +[Index](@ref) + +[Functions](@ref) + +[`Main.Mod.func(x)`](@ref) + +[`Main.Mod.T`](@ref) + +```jldoctest +julia> using Base.Meta # `nothing` shouldn't be displayed. + +julia> Meta +Base.Meta + +julia> a = 1 +1 + +julia> b = 2; + +julia> a + b +3 +``` + +```jldoctest +a = 1 +b = 2 +a + b + +# output + +3 +``` + +```@meta +DocTestSetup = + quote + using Documenter + using Random + Random.seed!(1) + end +``` + +```jldoctest +a = 1 +b = 2 +a / b + +# output + +0.5 +``` + +```jldoctest +julia> a = 1; + +julia> b = 2 +2 + +julia> a / b +0.5 +``` + +```@eval +import Markdown +code = string(sprint(Base.banner), "julia>") +Markdown.Code(code) +``` + +```jldoctest +julia> # First definition. + function f(x, y) + x + y + end + # + # Second definition. + # + struct T + x + end + +julia> @isdefined(f), @isdefined(T) # Check for both definitions. +(true, true) + +julia> import Base + +julia> using Base.Meta + +julia> r = isexpr(:(using Base.Meta), :using); # Discarded result. + +julia> !r +false +``` + +```jldoctest +julia> for i = 1:5 + println(i) + end +1 +2 +3 +4 +5 + +julia> println("Printing with semi-comma ending."); +Printing with semi-comma ending. + +julia> div(1, 0) +ERROR: DivideError: integer division error +[...] + +julia> println("a"); # Semi-colons *not* on the last expression shouldn't suppress output. + println(1) # ... + 2 # ... +a +1 +2 + +julia> println("a"); # Semi-colons *not* on the last expression shouldn't suppress output. + println(1) # ... + 2; # Only those in the last expression. +a +1 +``` + +```jldoctest +a = 1 +b = 2; # Semi-colons don't affect script doctests. + +# output + +2 +``` + +```@repl 1 +f(x) = (sleep(x); x) +@time f(0.1); +``` + +```@repl 1 +f(0.01) +div(1, 0) +``` + +Make sure that stdout is in the right place (#484): + +```@repl 1 +println("---") === nothing +versioninfo() +``` + +```@eval +1 + 2 +nothing +``` + +## Including images with `MIME` + +If `show(io, ::MIME, x)` is overloaded for a particular type then `@example` blocks can show the SVG, HTML/JS/CSS, PNG, JPEG, GIF or WebP image as appropriate in the output. + +Assuming the following type and method live in the `InlineSVG` module + +```julia +struct SVG + code :: String +end +Base.show(io, ::MIME"image/svg+xml", svg::SVG) = write(io, svg.code) +``` + +.. then we we can invoke and show them with an `@example` block: + +```@setup inlinesvg +module InlineSVG +export SVG +mutable struct SVG + code :: String +end +Base.show(io, ::MIME"image/svg+xml", svg::SVG) = write(io, svg.code) +end # module +``` + +```@example inlinesvg +using .InlineSVG +SVG(""" +<svg width="82" height="76"> + <g style="stroke-width: 3"> + <circle cx="20" cy="56" r="16" style="stroke: #cb3c33; fill: #d5635c" /> + <circle cx="41" cy="20" r="16" style="stroke: #389826; fill: #60ad51" /> + <circle cx="62" cy="56" r="16" style="stroke: #9558b2; fill: #aa79c1" /> + </g> +</svg> +""") +``` + +_Note: we can't define the `show` method in the `@example` block due to the world age +counter in Julia 0.6 (Documenter's `makedocs` is not aware of any of the new method +definitions happening in `eval`s)._ + +We can also show SVG images with interactivity via the `text/html` MIME to display output that combines HTML, JS and CSS. Assume the following type and method live in the `InlineHTML` modeul + +```julia +struct HTML + code::String +end +Base.show(io, ::MIME"text/html", html::HTML) = write(io, read(html.code)) +``` + +.. then we can invoke and show them with an `@example` block (try mousing over the circles to see the applied style): + +```@setup inlinehtml +module InlineHTML +mutable struct HTML + code::String +end +Base.show(io, ::MIME"text/html", html::HTML) = write(io, html.code) +end # module +``` + +```@example inlinehtml +using .InlineHTML +InlineHTML.HTML(""" +<script> + function showStyle(e) { + document.querySelector("#inline-html-style").innerHTML = e.getAttribute('style'); + } +</script> +<svg width="100%" height="76"> + <g style="stroke-width: 3"> + <circle cx="20" cy="56" r="16" style="stroke: #cb3c33; fill: #d5635c" onmouseover="showStyle(this)"/> + <circle cx="41" cy="20" r="16" style="stroke: #389826; fill: #60ad51" onmouseover="showStyle(this)"/> + <circle cx="62" cy="56" r="16" style="stroke: #9558b2; fill: #aa79c1" onmouseover="showStyle(this)"/> + <text id="inline-html-style" x="90", y="20"></text> + </g> +</svg> +""") +``` + +The same mechanism also works for PNG files. Assuming again the following +type and method live in the `InlinePNG` module + +```julia +struct PNG + filename::String +end +Base.show(io, ::MIME"image/png", png::PNG) = write(io, read(png.filename)) +``` + +.. then we can invoke and show them with an `@example` block: + +```@setup inlinepng +module InlinePNG +export PNG +mutable struct PNG + filename::String +end +Base.show(io, ::MIME"image/png", png::PNG) = write(io, read(png.filename)) +end # module +``` + +```@example inlinepng +using Documenter +using .InlinePNG +PNG(joinpath(dirname(pathof(Documenter)), "..", "test", "examples", "images", "logo.png")) +``` + + +.. and JPEG, GIF and WebP files: + +```@setup inlinewebpgifjpeg +module InlineWEBPGIFJPEG +export WEBP, GIF, JPEG +mutable struct WEBP + filename :: String +end +Base.show(io, ::MIME"image/webp", image::WEBP) = write(io, read(image.filename)) +mutable struct GIF + filename :: String +end +Base.show(io, ::MIME"image/gif", image::GIF) = write(io, read(image.filename)) +mutable struct JPEG + filename :: String +end +Base.show(io, ::MIME"image/jpeg", image::JPEG) = write(io, read(image.filename)) +end # module +``` + +```@example inlinewebpgifjpeg +using Documenter +using .InlineWEBPGIFJPEG +WEBP(joinpath(dirname(pathof(Documenter)), "..", "test", "examples", "images", "logo.webp")) +``` + +```@example inlinewebpgifjpeg +GIF(joinpath(dirname(pathof(Documenter)), "..", "test", "examples", "images", "logo.gif")) +``` + +```@example inlinewebpgifjpeg +JPEG(joinpath(dirname(pathof(Documenter)), "..", "test", "examples", "images", "logo.jpg")) +``` + +## Interacting with external files + +You can also write output files and then refer to them in the document: + +```@example +open("julia.svg", "w") do io + write(io, """ + <svg width="82" height="76" xmlns="http://www.w3.org/2000/svg"> + <g style="stroke-width: 3"> + <circle cx="20" cy="56" r="16" style="stroke: #cb3c33; fill: #d5635c" /> + <circle cx="41" cy="20" r="16" style="stroke: #389826; fill: #60ad51" /> + <circle cx="62" cy="56" r="16" style="stroke: #9558b2; fill: #aa79c1" /> + </g> + </svg> + """) +end +``` + +![Julia circles](julia.svg) + +Dowload [`data.csv`](data.csv). + + +## [Links](../index.md) in headers + +... are dropped in the navigation links. + + +## Embedding raw HTML + +Below is a nicely rendered version of `^D`: + +```@raw html +<kbd>Ctrl</kbd> + <kbd>D</kbd> +``` diff --git a/embedded/Documenter.jl-0.20.0/test/examples/tests.jl b/embedded/Documenter.jl-0.20.0/test/examples/tests.jl new file mode 100644 index 0000000..446190b --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/examples/tests.jl @@ -0,0 +1,93 @@ +using Test + +# When the file is run separately we need to include make.jl which actually builds +# the docs and defines a few modules that are referred to in the docs. The make.jl +# has to be expected in the context of the Main module. +if (@__MODULE__) === Main && !@isdefined examples_root + include("make.jl") +elseif (@__MODULE__) !== Main && isdefined(Main, :examples_root) + using Documenter + const examples_root = Main.examples_root +elseif (@__MODULE__) !== Main && !isdefined(Main, :examples_root) + error("examples/make.jl has not been loaded into Main.") +end + +@testset "Examples" begin + @testset "Markdown" begin + doc = Main.examples_markdown_doc + + @test isa(doc, Documenter.Documents.Document) + + let build_dir = joinpath(examples_root, "builds", "markdown"), + source_dir = joinpath(examples_root, "src") + + @test isdir(build_dir) + @test isdir(joinpath(build_dir, "assets")) + @test isdir(joinpath(build_dir, "lib")) + @test isdir(joinpath(build_dir, "man")) + + @test isfile(joinpath(build_dir, "index.md")) + @test isfile(joinpath(build_dir, "assets", "mathjaxhelper.js")) + @test isfile(joinpath(build_dir, "assets", "Documenter.css")) + @test isfile(joinpath(build_dir, "assets", "custom.css")) + @test isfile(joinpath(build_dir, "assets", "custom.js")) + @test isfile(joinpath(build_dir, "lib", "functions.md")) + @test isfile(joinpath(build_dir, "man", "tutorial.md")) + @test isfile(joinpath(build_dir, "man", "data.csv")) + @test isfile(joinpath(build_dir, "man", "julia.svg")) + + @test (==)( + read(joinpath(source_dir, "man", "data.csv"), String), + read(joinpath(build_dir, "man", "data.csv"), String), + ) + end + + @test doc.user.root == examples_root + @test doc.user.source == "src" + @test doc.user.build == "builds/markdown" + @test doc.user.clean == true + @test doc.user.format == [:markdown] + + @test realpath(doc.internal.assets) == realpath(joinpath(dirname(@__FILE__), "..", "..", "assets")) + + @test length(doc.internal.pages) == 10 + + let headers = doc.internal.headers + @test Documenter.Anchors.exists(headers, "Documentation") + @test Documenter.Anchors.exists(headers, "Documentation") + @test Documenter.Anchors.exists(headers, "Index-Page") + @test Documenter.Anchors.exists(headers, "Functions-Contents") + @test Documenter.Anchors.exists(headers, "Tutorial-Contents") + @test Documenter.Anchors.exists(headers, "Index") + @test Documenter.Anchors.exists(headers, "Tutorial") + @test Documenter.Anchors.exists(headers, "Function-Index") + @test Documenter.Anchors.exists(headers, "Functions") + @test Documenter.Anchors.isunique(headers, "Functions") + @test Documenter.Anchors.isunique(headers, "Functions", joinpath("builds", "markdown", "lib", "functions.md")) + let name = "Foo", path = joinpath("builds", "markdown", "lib", "functions.md") + @test Documenter.Anchors.exists(headers, name, path) + @test !Documenter.Anchors.isunique(headers, name) + @test !Documenter.Anchors.isunique(headers, name, path) + @test length(headers.map[name][path]) == 4 + end + end + + @test length(doc.internal.objects) == 38 + end + + @testset "HTML: local" begin + doc = Main.examples_html_local_doc + + @test isa(doc, Documenter.Documents.Document) + + # TODO: test the HTML build + end + + @testset "HTML: deploy" begin + doc = Main.examples_html_deploy_doc + + @test isa(doc, Documenter.Documents.Document) + + # TODO: test the HTML build with pretty URLs + end +end diff --git a/embedded/Documenter.jl-0.20.0/test/formats/latex.jl b/embedded/Documenter.jl-0.20.0/test/formats/latex.jl new file mode 100644 index 0000000..cdfb6eb --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/formats/latex.jl @@ -0,0 +1,59 @@ +module LaTeXFormatTests + +using Test + +using Documenter + +# Documenter package docs +@info("Building Documenter's docs with LaTeX.") +const Documenter_root = normpath(joinpath(dirname(@__FILE__), "..", "..", "docs")) +doc = makedocs( + debug = true, + root = Documenter_root, + modules = [Documenter], + clean = false, + format = :latex, + sitename = "Documenter.jl", + authors = "Michael Hatherly, Morten Piibeleht, and contributors.", + pages = [ + "Home" => "index.md", + "Manual" => Any[ + "Guide" => "man/guide.md", + "man/examples.md", + "man/syntax.md", + "man/doctests.md", + "man/latex.md", + "man/hosting.md", + "man/other-formats.md", + ], + "Library" => Any[ + "Public" => "lib/public.md", + hide("Internals" => "lib/internals.md", Any[ + "lib/internals/anchors.md", + "lib/internals/builder.md", + "lib/internals/cross-references.md", + "lib/internals/docchecks.md", + "lib/internals/docsystem.md", + "lib/internals/doctests.md", + "lib/internals/documenter.md", + "lib/internals/documentertools.md", + "lib/internals/documents.md", + "lib/internals/dom.md", + "lib/internals/expanders.md", + "lib/internals/formats.md", + "lib/internals/mdflatten.md", + "lib/internals/selectors.md", + "lib/internals/textdiff.md", + "lib/internals/utilities.md", + "lib/internals/writers.md", + ]) + ], + "contributing.md", + ] +) + +@testset "LaTeX" begin + @test isa(doc, Documenter.Documents.Document) +end + +end diff --git a/embedded/Documenter.jl-0.20.0/test/formats/markdown.jl b/embedded/Documenter.jl-0.20.0/test/formats/markdown.jl new file mode 100644 index 0000000..6933c63 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/formats/markdown.jl @@ -0,0 +1,41 @@ +module MarkdownFormatTests + +using Test +using Random + +using Documenter + +# Documenter package docs +@info("Building Documenter's docs with Markdown.") +const Documenter_root = normpath(joinpath(@__DIR__, "..", "..", "docs")) +build_dir_relpath = relpath(joinpath(@__DIR__, "builds/markdown"), Documenter_root) +doc = makedocs( + format = :markdown, + debug = true, + root = Documenter_root, + modules = Documenter, + build = build_dir_relpath, +) + +@testset "Markdown" begin + @test isa(doc, Documenter.Documents.Document) + + let build_dir = joinpath(Documenter_root, build_dir_relpath), + source_dir = joinpath(Documenter_root, "src") + @test isdir(build_dir) + @test isdir(joinpath(build_dir, "assets")) + @test isdir(joinpath(build_dir, "lib")) + @test isdir(joinpath(build_dir, "man")) + + @test isfile(joinpath(build_dir, "index.md")) + @test isfile(joinpath(build_dir, "assets", "mathjaxhelper.js")) + @test isfile(joinpath(build_dir, "assets", "Documenter.css")) + end + + @test doc.user.root == Documenter_root + @test doc.user.source == "src" + @test doc.user.build == build_dir_relpath + @test doc.user.clean == true +end + +end diff --git a/embedded/Documenter.jl-0.20.0/test/htmlwriter.jl b/embedded/Documenter.jl-0.20.0/test/htmlwriter.jl new file mode 100644 index 0000000..abc58aa --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/htmlwriter.jl @@ -0,0 +1,89 @@ +module HTMLWriterTests + +using Test + +import Documenter.Writers.HTMLWriter: jsescape, generate_version_file, expand_versions + +function verify_version_file(versionfile, entries) + @test isfile(versionfile) + content = read(versionfile, String) + idx = 1 + for entry in entries + i = findnext(entry, content, idx) + @test i !== nothing + idx = last(i) + end +end + +@testset "HTMLWriter" begin + @test jsescape("abc123") == "abc123" + @test jsescape("▶αβγ") == "▶αβγ" + @test jsescape("") == "" + + @test jsescape("a\nb") == "a\\nb" + @test jsescape("\r\n") == "\\r\\n" + @test jsescape("\\") == "\\\\" + + @test jsescape("\"'") == "\\\"\\'" + + # Ref: #639 + @test jsescape("\u2028") == "\\u2028" + @test jsescape("\u2029") == "\\u2029" + @test jsescape("policy to
 delete.") == "policy to\\u2028 delete." + + mktempdir() do tmpdir + versionfile = joinpath(tmpdir, "versions.js") + versions = ["stable", "dev", + "2.1.1", "v2.1.0", "v2.0.1", "v2.0.0", + "1.1.1", "v1.1.0", "v1.0.1", "v1.0.0", + "0.1.1", "v0.1.0"] # note no `v` on first ones + cd(tmpdir) do + for version in versions + mkdir(version) + end + end + + # expanding versions + versions = ["stable" => "v^", "v#.#", "dev" => "dev"] # default to makedocs + entries, symlinks = expand_versions(tmpdir, versions) + @test entries == ["stable", "v2.1", "v2.0", "v1.1", "v1.0", "v0.1", "dev"] + @test symlinks == ["stable"=>"2.1.1", "v2.1"=>"2.1.1", "v2.0"=>"v2.0.1", + "v1.1"=>"1.1.1", "v1.0"=>"v1.0.1", "v0.1"=>"0.1.1", + "v2"=>"2.1.1", "v1"=>"1.1.1", "v2.1.1"=>"2.1.1", + "v1.1.1"=>"1.1.1", "v0.1.1"=>"0.1.1"] + generate_version_file(versionfile, entries) + verify_version_file(versionfile, entries) + + versions = ["v#"] + entries, symlinks = expand_versions(tmpdir, versions) + @test entries == ["v2.1", "v1.1"] + @test symlinks == ["v2.1"=>"2.1.1", "v1.1"=>"1.1.1", "v2"=>"2.1.1", "v1"=>"1.1.1", + "v2.0"=>"v2.0.1", "v1.0"=>"v1.0.1", "v0.1"=>"0.1.1", + "v2.1.1"=>"2.1.1", "v1.1.1"=>"1.1.1", "v0.1.1"=>"0.1.1"] + generate_version_file(versionfile, entries) + verify_version_file(versionfile, entries) + + versions = ["v#.#.#"] + entries, symlinks = expand_versions(tmpdir, versions) + @test entries == ["v2.1.1", "v2.1.0", "v2.0.1", "v2.0.0", "v1.1.1", "v1.1.0", + "v1.0.1", "v1.0.0", "v0.1.1", "v0.1.0"] + @test symlinks == ["v2.1.1"=>"2.1.1", "v1.1.1"=>"1.1.1", "v0.1.1"=>"0.1.1", + "v2"=>"2.1.1", "v1"=>"1.1.1", "v2.1"=>"2.1.1", + "v2.0"=>"v2.0.1", "v1.1"=>"1.1.1", "v1.0"=>"v1.0.1", "v0.1"=>"0.1.1"] + generate_version_file(versionfile, entries) + verify_version_file(versionfile, entries) + + versions = ["v^", "devel" => "dev", "foobar", "foo" => "bar"] + entries, symlinks = expand_versions(tmpdir, versions) + @test entries == ["v2.1", "devel"] + @test ("v2.1" => "2.1.1") in symlinks + @test ("devel" => "dev") in symlinks + generate_version_file(versionfile, entries) + verify_version_file(versionfile, entries) + + versions = ["stable" => "v^", "dev" => "stable"] + @test_throws ArgumentError expand_versions(tmpdir, versions) + end +end + +end diff --git a/embedded/Documenter.jl-0.20.0/test/mdflatten.jl b/embedded/Documenter.jl-0.20.0/test/mdflatten.jl new file mode 100644 index 0000000..0f78ee4 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/mdflatten.jl @@ -0,0 +1,68 @@ +module MDFlattenTests + +using Test + +import Markdown +using Documenter.Utilities.MDFlatten + +@testset "MDFlatten" begin + @test mdflatten(Markdown.Paragraph("...")) == "..." + @test mdflatten(Markdown.Header{1}("...")) == "..." + + # a simple test for blocks in top-level (each gets two newline appended to it) + @test mdflatten(Markdown.parse("# Test\nTest")) == "Test\n\nTest\n\n" + block_md = Markdown.parse(""" + # MDFlatten test + + + ^^^ Ignoring extra whitespace. + + ```markdown + code + is forwarded as **is** + ``` + """) + block_text = """ + MDFlatten test + + ^^^ Ignoring extra whitespace. + + code + is forwarded as **is** + + """ + @test mdflatten(block_md) == block_text + + # blocks + @test mdflatten(Markdown.parse("> Test\n> Test\n\n> Test")) == "Test Test\n\nTest\n\n" + @test mdflatten(Markdown.parse("HRs\n\n---\n\nto whitespace")) == "HRs\n\n\n\nto whitespace\n\n" + @test mdflatten(Markdown.parse("HRs\n\n---\n\nto whitespace")) == "HRs\n\n\n\nto whitespace\n\n" + @test mdflatten(Markdown.parse("HRs\n\n---\n\nto whitespace")) == "HRs\n\n\n\nto whitespace\n\n" + + # test some inline blocks + @test mdflatten(Markdown.parse("`code` *em* normal **strong**")) == "code em normal strong\n\n" + @test mdflatten(Markdown.parse("[link text *parsed*](link/itself/ignored)")) == "link text parsed\n\n" + @test mdflatten(Markdown.parse("- a\n- b\n- c")) == "a\nb\nc\n\n" + @test mdflatten(Markdown.parse("A | B\n---|---\naa|bb\ncc | dd")) == "A B\naa bb\ncc dd\n\n" + + # Math + @test mdflatten(Markdown.parse("\$e=mc^2\$")) == "e=mc^2\n\n" + # backticks and blocks for math only in 0.5, i.e. these fail on 0.4 + @test mdflatten(Markdown.parse("``e=mc^2``")) == "e=mc^2\n\n" + @test mdflatten(Markdown.parse("```math\n\\(m+n)(m-n)\nx=3\\sin(x)\n```")) == "(m+n)(m-n)\nx=3sin(x)\n\n" + + # symbols in markdown + @test mdflatten(Markdown.parse("A \$B C")) == "A B C\n\n" + + # linebreaks + @test mdflatten(Markdown.parse("A\\\nB")) == "A\nB\n\n" + + # footnotes + @test mdflatten(Markdown.parse("[^name]")) == "[name]\n\n" + @test mdflatten(Markdown.parse("[^name]:**Strong** text.")) == "[name]: Strong text.\n\n" + + # admonitions + @test mdflatten(Markdown.parse("!!! note \"Admonition Title\"\n Test")) == "note: Admonition Title\nTest\n\n" +end + +end diff --git a/embedded/Documenter.jl-0.20.0/test/missingdocs/make.jl b/embedded/Documenter.jl-0.20.0/test/missingdocs/make.jl new file mode 100644 index 0000000..edf748d --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/missingdocs/make.jl @@ -0,0 +1,22 @@ +module MissingDocs + export f + + "exported" + f(x) = x + + "unexported" + g(x) = x +end + +using Documenter + +for sym in [:none, :exports] + makedocs( + root = dirname(@__FILE__), + source = joinpath("src", string(sym)), + build = joinpath("build", string(sym)), + modules = MissingDocs, + checkdocs = sym, + sitename = "MissingDocs Checks", + ) +end diff --git a/embedded/Documenter.jl-0.20.0/test/missingdocs/src/exports/index.md b/embedded/Documenter.jl-0.20.0/test/missingdocs/src/exports/index.md new file mode 100644 index 0000000..7746104 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/missingdocs/src/exports/index.md @@ -0,0 +1,5 @@ +# MissingDocs Exports + +```@docs +Main.MissingDocs.f +``` diff --git a/embedded/Documenter.jl-0.20.0/test/missingdocs/src/none/index.md b/embedded/Documenter.jl-0.20.0/test/missingdocs/src/none/index.md new file mode 100644 index 0000000..9b7ae05 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/missingdocs/src/none/index.md @@ -0,0 +1,4 @@ +# MissingDocs None + +```@docs +``` diff --git a/embedded/Documenter.jl-0.20.0/test/navnode.jl b/embedded/Documenter.jl-0.20.0/test/navnode.jl new file mode 100644 index 0000000..6716e90 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/navnode.jl @@ -0,0 +1,60 @@ +module NavNodeTests + +using Test + +import Documenter: Documents, Builder +import Documenter.Documents: NavNode + +mutable struct FakeDocumentInternal + pages :: Dict{String, Nothing} + navlist :: Vector{NavNode} + FakeDocumentInternal() = new(Dict(), []) +end +mutable struct FakeDocument + internal :: FakeDocumentInternal + FakeDocument() = new(FakeDocumentInternal()) +end + +@testset "NavNode" begin + @test fieldtype(FakeDocumentInternal, :navlist) == fieldtype(Documents.Internal, :navlist) + + pages = [ + "page1.md", + "Page2" => "page2.md", + "Section" => [ + "page3.md", + "Page4" => "page4.md", + "Subsection" => [ + "page5.md", + ], + ], + "page6.md", + ] + doc = FakeDocument() + doc.internal.pages = Dict(map(i -> "page$i.md" => nothing, 1:8)) + navtree = Builder.walk_navpages(pages, nothing, doc) + navlist = doc.internal.navlist + + @test length(navlist) == 6 + for (i,navnode) in enumerate(navlist) + @test navnode.page == "page$i.md" + end + + @test isa(navtree, Vector{NavNode}) + @test length(navtree) == 4 + @test navtree[1] === navlist[1] + @test navtree[2] === navlist[2] + @test navtree[4] === navlist[6] + + section = navtree[3] + @test section.title_override == "Section" + @test section.page === nothing + @test length(section.children) == 3 + + navpath = Documents.navpath(navlist[5]) + @test length(navpath) == 3 + @test navpath[1] === section + @test navpath[3] === navlist[5] +end + +end diff --git a/embedded/Documenter.jl-0.20.0/test/nongit/docs/make.jl b/embedded/Documenter.jl-0.20.0/test/nongit/docs/make.jl new file mode 100644 index 0000000..81f0f9e --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/nongit/docs/make.jl @@ -0,0 +1,8 @@ +using Documenter + +makedocs( + debug = true, + doctestfilters = [r"Ptr{0x[0-9]+}"], + sitename = "Documenter example", + pages = ["index.md"], +) diff --git a/embedded/Documenter.jl-0.20.0/test/nongit/docs/src/index.md b/embedded/Documenter.jl-0.20.0/test/nongit/docs/src/index.md new file mode 100644 index 0000000..3d93078 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/nongit/docs/src/index.md @@ -0,0 +1,3 @@ +# Test + +.... diff --git a/embedded/Documenter.jl-0.20.0/test/nongit/tests.jl b/embedded/Documenter.jl-0.20.0/test/nongit/tests.jl new file mode 100644 index 0000000..fbb3bf8 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/nongit/tests.jl @@ -0,0 +1,7 @@ +mktempdir() do tmpdir + @info("Buiding 'nongit' in $tmpdir") + cp(joinpath(@__DIR__, "docs"), joinpath(tmpdir, "docs")) + include(joinpath(tmpdir, "docs/make.jl")) + # Copy the build/ directory back so that it would be possible to inspect the output. + cp(joinpath(tmpdir, "docs/build"), joinpath(@__DIR__, "build"); force=true) +end diff --git a/embedded/Documenter.jl-0.20.0/test/runtests.jl b/embedded/Documenter.jl-0.20.0/test/runtests.jl new file mode 100644 index 0000000..482c81b --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/runtests.jl @@ -0,0 +1,67 @@ +using Test + +# Build the example docs +include("examples/make.jl") + +# Test missing docs +include("missingdocs/make.jl") + +# Primary @testset + +# Error reporting. +println("="^50) +@info("The following errors are expected output.") +include(joinpath("errors", "make.jl")) +@info("END of expected error output.") +println("="^50) + +@testset "Documenter" begin + # Unit tests for module internals. + include("utilities.jl") + + # NavNode tests. + include("navnode.jl") + + # DocSystem unit tests. + include("docsystem.jl") + + # DocTest unit tests. + include("doctests/doctests.jl") + + # DOM Tests. + include("dom.jl") + + # MDFlatten tests. + include("mdflatten.jl") + + # HTMLWriter + include("htmlwriter.jl") + + # Mock package docs. + include("examples/tests.jl") + + # Documenter package docs with other formats. + include("formats/markdown.jl") + include("formats/latex.jl") + + # A simple build outside of a Git repository + include("nongit/tests.jl") +end + +# Additional tests + +## `Markdown.MD` to `DOM.Node` conversion tests. +module MarkdownToNode + import Documenter.DocSystem + import Documenter.Writers.HTMLWriter: mdconvert + + # Exhaustive Conversion from Markdown to Nodes. + for mod in Base.Docs.modules + for (binding, multidoc) in DocSystem.getmeta(mod) + for (typesig, docstr) in multidoc.docs + md = DocSystem.parsedoc(docstr) + string(mdconvert(md)) + end + end + end +end diff --git a/embedded/Documenter.jl-0.20.0/test/utilities.jl b/embedded/Documenter.jl-0.20.0/test/utilities.jl new file mode 100644 index 0000000..c00c547 --- /dev/null +++ b/embedded/Documenter.jl-0.20.0/test/utilities.jl @@ -0,0 +1,223 @@ +module UtilitiesTests + +using Test +import Base64: stringmime + +import Documenter + +module UnitTests + module SubModule end + + # Does `submodules` collect *all* the submodules? + module A + module B + module C + module D end + end + end + end + + mutable struct T end + mutable struct S{T} end + + "Documenter unit tests." + Base.length(::T) = 1 + + f(x) = x + + const pi = 3.0 +end + +module OuterModule +module InnerModule +import ..OuterModule +export OuterModule +end +end + +module ExternalModule end +module ModuleWithAliases +using ..ExternalModule +Y = ExternalModule +module A + module B + const X = Main + end +end +end + +@testset "Utilities" begin + let doc = @doc(length) + a = Documenter.Utilities.filterdocs(doc, Set{Module}()) + b = Documenter.Utilities.filterdocs(doc, Set{Module}([UnitTests])) + c = Documenter.Utilities.filterdocs(doc, Set{Module}([Base])) + d = Documenter.Utilities.filterdocs(doc, Set{Module}([UtilitiesTests])) + + @test a !== nothing + @test a === doc + @test b !== nothing + @test occursin("Documenter unit tests.", stringmime("text/plain", b)) + @test c !== nothing + @test !occursin("Documenter unit tests.", stringmime("text/plain", c)) + @test d === nothing + end + + # Documenter.Utilities.issubmodule + @test Documenter.Utilities.issubmodule(Main, Main) === true + @test Documenter.Utilities.issubmodule(UnitTests, UnitTests) === true + @test Documenter.Utilities.issubmodule(UnitTests.SubModule, Main) === true + @test Documenter.Utilities.issubmodule(UnitTests.SubModule, UnitTests) === true + @test Documenter.Utilities.issubmodule(UnitTests.SubModule, Base) === false + @test Documenter.Utilities.issubmodule(UnitTests, UnitTests.SubModule) === false + + @test UnitTests.A in Documenter.Utilities.submodules(UnitTests.A) + @test UnitTests.A.B in Documenter.Utilities.submodules(UnitTests.A) + @test UnitTests.A.B.C in Documenter.Utilities.submodules(UnitTests.A) + @test UnitTests.A.B.C.D in Documenter.Utilities.submodules(UnitTests.A) + @test OuterModule in Documenter.Utilities.submodules(OuterModule) + @test OuterModule.InnerModule in Documenter.Utilities.submodules(OuterModule) + @test length(Documenter.Utilities.submodules(OuterModule)) == 2 + @test Documenter.Utilities.submodules(ModuleWithAliases) == Set([ModuleWithAliases, ModuleWithAliases.A, ModuleWithAliases.A.B]) + + @test Documenter.Utilities.isabsurl("file.md") === false + @test Documenter.Utilities.isabsurl("../file.md") === false + @test Documenter.Utilities.isabsurl(".") === false + @test Documenter.Utilities.isabsurl("https://example.org/file.md") === true + @test Documenter.Utilities.isabsurl("http://example.org") === true + @test Documenter.Utilities.isabsurl("ftp://user:pw@example.org") === true + @test Documenter.Utilities.isabsurl("/fs/absolute/path") === false + + @test Documenter.Utilities.doccat(UnitTests) == "Module" + @test Documenter.Utilities.doccat(UnitTests.T) == "Type" + @test Documenter.Utilities.doccat(UnitTests.S) == "Type" + @test Documenter.Utilities.doccat(UnitTests.f) == "Function" + @test Documenter.Utilities.doccat(UnitTests.pi) == "Constant" + + # repo type + @test Documenter.Utilities.repo_host_from_url("https://bitbucket.org/somerepo") == Documenter.Utilities.RepoBitbucket + @test Documenter.Utilities.repo_host_from_url("https://www.bitbucket.org/somerepo") == Documenter.Utilities.RepoBitbucket + @test Documenter.Utilities.repo_host_from_url("http://bitbucket.org/somethingelse") == Documenter.Utilities.RepoBitbucket + @test Documenter.Utilities.repo_host_from_url("http://github.com/Whatever") == Documenter.Utilities.RepoGithub + @test Documenter.Utilities.repo_host_from_url("https://github.com/Whatever") == Documenter.Utilities.RepoGithub + @test Documenter.Utilities.repo_host_from_url("https://www.github.com/Whatever") == Documenter.Utilities.RepoGithub + @test Documenter.Utilities.repo_host_from_url("https://gitlab.com/Whatever") == Documenter.Utilities.RepoGitlab + + # line range + let formatting = Documenter.Utilities.LineRangeFormatting(Documenter.Utilities.RepoGithub) + @test Documenter.Utilities.format_line(1:1, formatting) == "L1" + @test Documenter.Utilities.format_line(123:123, formatting) == "L123" + @test Documenter.Utilities.format_line(2:5, formatting) == "L2-L5" + @test Documenter.Utilities.format_line(100:9999, formatting) == "L100-L9999" + end + + let formatting = Documenter.Utilities.LineRangeFormatting(Documenter.Utilities.RepoGitlab) + @test Documenter.Utilities.format_line(1:1, formatting) == "L1" + @test Documenter.Utilities.format_line(123:123, formatting) == "L123" + @test Documenter.Utilities.format_line(2:5, formatting) == "L2-5" + @test Documenter.Utilities.format_line(100:9999, formatting) == "L100-9999" + end + + let formatting = Documenter.Utilities.LineRangeFormatting(Documenter.Utilities.RepoBitbucket) + @test Documenter.Utilities.format_line(1:1, formatting) == "1" + @test Documenter.Utilities.format_line(123:123, formatting) == "123" + @test Documenter.Utilities.format_line(2:5, formatting) == "2:5" + @test Documenter.Utilities.format_line(100:9999, formatting) == "100:9999" + end + + # URL building + filepath = string(first(methods(Documenter.Utilities.url)).file) + Sys.iswindows() && (filepath = replace(filepath, "/" => "\\")) # work around JuliaLang/julia#26424 + let expected_filepath = "/src/Utilities/Utilities.jl" + Sys.iswindows() && (expected_filepath = replace(expected_filepath, "/" => "\\")) + @test endswith(filepath, expected_filepath) + @show filepath expected_filepath + end + + mktempdir() do path + cd(path) do + # Create a simple mock repo in a temporary directory with a single file. + @test success(`git init`) + @test success(`git config user.email "tester@example.com"`) + @test success(`git config user.name "Test Committer"`) + @test success(`git remote add origin git@github.com:JuliaDocs/Documenter.jl.git`) + mkpath("src") + filepath = abspath(joinpath("src", "SourceFile.jl")) + write(filepath, "X") + @test success(`git add -A`) + @test success(`git commit -m"Initial commit."`) + + # Run tests + commit = Documenter.Utilities.repo_commit(filepath) + + @test Documenter.Utilities.url("//blob/{commit}{path}#{line}", filepath) == "//blob/$(commit)/src/SourceFile.jl#" + @test Documenter.Utilities.url(nothing, "//blob/{commit}{path}#{line}", Documenter.Utilities, filepath, 10:20) == "//blob/$(commit)/src/SourceFile.jl#L10-L20" + + # repo_root & relpath_from_repo_root + @test Documenter.Utilities.repo_root(filepath) == dirname(abspath(joinpath(dirname(filepath), ".."))) # abspath() keeps trailing /, hence dirname() + @test Documenter.Utilities.repo_root(filepath; dbdir=".svn") == nothing + @test Documenter.Utilities.relpath_from_repo_root(filepath) == joinpath("src", "SourceFile.jl") + # We assume that a temporary file is not in a repo + @test Documenter.Utilities.repo_root(tempname()) == nothing + @test Documenter.Utilities.relpath_from_repo_root(tempname()) == nothing + end + end + + import Documenter.Documents: Document, Page, Globals + let page = Page("source", "build", [], IdDict{Any,Any}(), Globals()), doc = Document() + code = """ + x += 3 + γγγ_γγγ + γγγ + """ + exprs = Documenter.Utilities.parseblock(code, doc, page) + + @test isa(exprs, Vector) + @test length(exprs) === 3 + + @test isa(exprs[1][1], Expr) + @test exprs[1][1].head === :+= + @test exprs[1][2] == "x += 3\n" + + @test exprs[2][2] == "γγγ_γγγ\n" + + @test exprs[3][1] === :γγγ + @test exprs[3][2] == "γγγ\n" + end + + @testset "TextDiff" begin + import Documenter.Utilities.TextDiff: splitby + @test splitby(r"\s+", "X Y Z") == ["X ", "Y ", "Z"] + @test splitby(r"[~]", "X~Y~Z") == ["X~", "Y~", "Z"] + @test splitby(r"[▶]", "X▶Y▶Z") == ["X▶", "Y▶", "Z"] + @test splitby(r"[▶]+", "X▶▶Y▶Z▶") == ["X▶▶", "Y▶", "Z▶"] + @test splitby(r"[▶]+", "▶▶Y▶Z▶") == ["▶▶", "Y▶", "Z▶"] + @test splitby(r"[▶]+", "Ω▶▶Y▶Z▶") == ["Ω▶▶", "Y▶", "Z▶"] + @test splitby(r"[▶]+", "Ω▶▶Y▶Z▶κ") == ["Ω▶▶", "Y▶", "Z▶", "κ"] + end + + @static if isdefined(Base, :with_logger) + @testset "withoutput" begin + _, _, _, output = Documenter.Utilities.withoutput() do + println("println") + @info "@info" + f() = (Base.depwarn("depwarn", :f); nothing) + f() + end + @test startswith(output, "println\n[ Info: @info\n┌ Warning: depwarn\n") + end + end + + @testset "issues #749, #790, #823" begin + let parse(x) = Documenter.Utilities.parseblock(x, nothing, nothing) + for LE in ("\r\n", "\n") + l1, l2 = parse("x = Int[]$(LE)$(LE)push!(x, 1)$(LE)") + @test l1[1] == :(x = Int[]) + @test l1[2] == "x = Int[]$(LE)" + @test l2[1] == :(push!(x, 1)) + @test l2[2] == "push!(x, 1)$(LE)" + end + end + end +end + +end diff --git a/embedded/Documenter.source b/embedded/Documenter.source new file mode 100644 index 0000000..f090c7d --- /dev/null +++ b/embedded/Documenter.source @@ -0,0 +1 @@ +https://github.com/JuliaDocs/Documenter.jl/releases diff --git a/embedded/Pkg.source b/embedded/Pkg.source new file mode 100644 index 0000000..727ccc0 --- /dev/null +++ b/embedded/Pkg.source @@ -0,0 +1 @@ +https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/93b6d6de857dc88e665d2c64397852ab9701ba24 diff --git a/embedded/libuv-ed3700c849289ed01fe04273a7bf865340b2bd7e.tar.gz b/embedded/libuv-ed3700c849289ed01fe04273a7bf865340b2bd7e.tar.gz new file mode 100644 index 0000000..8fcad94 Binary files /dev/null and b/embedded/libuv-ed3700c849289ed01fe04273a7bf865340b2bd7e.tar.gz differ diff --git a/embedded/libuv.source b/embedded/libuv.source new file mode 100644 index 0000000..36f4754 --- /dev/null +++ b/embedded/libuv.source @@ -0,0 +1 @@ +https://api.github.com/repos/JuliaLang/libuv/tarball/d8ab1c6a33e77bf155facb54215dd8798e13825d diff --git a/embedded/libwhich-81e9723c0273d78493dc8c8ed570f68d9ce7e89e.tar.gz b/embedded/libwhich-81e9723c0273d78493dc8c8ed570f68d9ce7e89e.tar.gz new file mode 100644 index 0000000..4471b7f Binary files /dev/null and b/embedded/libwhich-81e9723c0273d78493dc8c8ed570f68d9ce7e89e.tar.gz differ diff --git a/embedded/libwhich.source b/embedded/libwhich.source new file mode 100644 index 0000000..a53a330 --- /dev/null +++ b/embedded/libwhich.source @@ -0,0 +1 @@ +https://api.github.com/repos/vtjnash/libwhich/tarball/81e9723c0273d78493dc8c8ed570f68d9ce7e89e diff --git a/embedded/llvm-6.0.0.src.tar.xz b/embedded/llvm-6.0.0.src.tar.xz new file mode 100644 index 0000000..47e342f Binary files /dev/null and b/embedded/llvm-6.0.0.src.tar.xz differ diff --git a/embedded/llvm-6.0.src.tar.xz b/embedded/llvm-6.0.src.tar.xz new file mode 120000 index 0000000..a19c373 --- /dev/null +++ b/embedded/llvm-6.0.src.tar.xz @@ -0,0 +1 @@ +llvm-6.0.0.src.tar.xz \ No newline at end of file diff --git a/fontface.css b/fontface.css new file mode 100644 index 0000000..e6f942d --- /dev/null +++ b/fontface.css @@ -0,0 +1,19 @@ +/* This file is provided by Debian as an replacement to + * https://fonts.googleapis.com/css?family=Lato|Roboto+Mono + * MIT License, 2018, Mo Zhou <cdluminate@gmail.com> + */ +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 400; + src: local('Lato Regular'), + local('Lato-Regular'), + url(file:///usr/share/fonts/truetype/lato/Lato-Regular.ttf) format('truetype'); +} +@font-face { + font-family: 'Inconsolata'; + font-style: normal; + font-weight: 400; + src: local('Inconsolata'), + url(file:///usr/share/fonts/truetype/inconsolata/Inconsolata.otf) format('opentype'); +} diff --git a/gbp.conf b/gbp.conf new file mode 100644 index 0000000..cec628c --- /dev/null +++ b/gbp.conf @@ -0,0 +1,2 @@ +[DEFAULT] +pristine-tar = True diff --git a/gitlab-ci.yml b/gitlab-ci.yml new file mode 100644 index 0000000..b7dc52a --- /dev/null +++ b/gitlab-ci.yml @@ -0,0 +1,16 @@ +include: https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml + +build: + extends: .build-unstable + +reprotest: + extends: .test-reprotest + +lintian: + extends: .test-lintian + +autopkgtest: + extends: .test-autopkgtest + +piuparts: + extends: .test-piuparts diff --git a/julia-common.install b/julia-common.install new file mode 100644 index 0000000..abfdfcb --- /dev/null +++ b/julia-common.install @@ -0,0 +1,6 @@ +etc/julia/ +usr/share/julia/base +usr/share/julia/test +usr/share/julia/stdlib +usr/share/julia/julia-config.jl +usr/share/julia/build_sysimg.jl diff --git a/julia-common.lintian-overrides b/julia-common.lintian-overrides new file mode 100644 index 0000000..5b6385d --- /dev/null +++ b/julia-common.lintian-overrides @@ -0,0 +1,4 @@ +# Docs are deliberately put there. +julia-common: package-contains-documentation-outside-usr-share-doc usr/share/julia/stdlib/* +# This is false-positive +julia-common: wrong-path-for-interpreter diff --git a/julia-doc.doc-base b/julia-doc.doc-base new file mode 100644 index 0000000..fa68631 --- /dev/null +++ b/julia-doc.doc-base @@ -0,0 +1,8 @@ +Document: julia-manual +Title: Julia Language Manual +Abstract: Describes the Julia language and its standard library +Section: Programming + +Format: HTML +Index: /usr/share/doc/julia/html/en/index.html +Files: /usr/share/doc/julia/html/* diff --git a/julia-doc.doc-base.pdf b/julia-doc.doc-base.pdf new file mode 100644 index 0000000..ede9b5d --- /dev/null +++ b/julia-doc.doc-base.pdf @@ -0,0 +1,7 @@ +Document: julia-manual-pdf +Title: Julia Language Manual +Abstract: Describes the Julia language and its standard library +Section: Programming + +Format: PDF +Files: /usr/share/doc/julia/TheJuliaLanguage.pdf.gz diff --git a/julia-doc.docs b/julia-doc.docs new file mode 100644 index 0000000..84c60ce --- /dev/null +++ b/julia-doc.docs @@ -0,0 +1,2 @@ +doc/_build/html +doc/_build/pdf/en/TheJuliaLanguage.pdf diff --git a/julia-doc.install b/julia-doc.install new file mode 100644 index 0000000..71ced2c --- /dev/null +++ b/julia-doc.install @@ -0,0 +1 @@ +debian/fontface.css usr/share/doc/julia-doc/ diff --git a/julia.docs b/julia.docs new file mode 100644 index 0000000..a67add3 --- /dev/null +++ b/julia.docs @@ -0,0 +1,9 @@ +README.md +CONTRIBUTING.md +DISTRIBUTING.md +HISTORY.md +NEWS.md +README.arm.md +README.md +README.windows.md +VERSION diff --git a/julia.examples b/julia.examples new file mode 100644 index 0000000..9b68fb5 --- /dev/null +++ b/julia.examples @@ -0,0 +1 @@ +debian/prompt.example.jl diff --git a/julia.install b/julia.install new file mode 100644 index 0000000..e9d188b --- /dev/null +++ b/julia.install @@ -0,0 +1,6 @@ +usr/bin/julia +usr/share/appdata/julia.appdata.xml usr/share/metainfo/ +usr/share/applications/julia.desktop +usr/share/icons/hicolor/scalable/apps/julia.svg +usr/share/julia/base/build_h.jl +usr/share/julia/base.cache diff --git a/julia.manpages b/julia.manpages new file mode 100644 index 0000000..3904480 --- /dev/null +++ b/julia.manpages @@ -0,0 +1 @@ +debian/tmp/usr/share/man/man1/julia.1 diff --git a/libjulia-dev.install b/libjulia-dev.install new file mode 100644 index 0000000..ab27977 --- /dev/null +++ b/libjulia-dev.install @@ -0,0 +1,2 @@ +usr/include/julia +usr/lib/*/libjulia.so diff --git a/libjulia1.install b/libjulia1.install new file mode 100644 index 0000000..8c0e6ef --- /dev/null +++ b/libjulia1.install @@ -0,0 +1,2 @@ +usr/lib/*/libjulia.so.* +usr/lib/*/julia diff --git a/libjulia1.lintian-overrides b/libjulia1.lintian-overrides new file mode 100644 index 0000000..309899e --- /dev/null +++ b/libjulia1.lintian-overrides @@ -0,0 +1,4 @@ +# Deliberately keeping debug info https://github.com/JuliaLang/julia/issues/23115#issuecomment-320715030 +libjulia1: unstripped-binary-or-object usr/lib/*/julia/sys.so +# Deliberately keeping debug info https://github.com/JuliaLang/julia/issues/23115#issuecomment-320715030 +libjulia1: unstripped-binary-or-object usr/lib/*/libjulia.so.* diff --git a/libjulia1.symbols b/libjulia1.symbols new file mode 100644 index 0000000..32f9351 --- /dev/null +++ b/libjulia1.symbols @@ -0,0 +1,1233 @@ +libjulia.so.1 libjulia1 #MINVER# + LLVMExtraAddInternalizePassWithExportList@Base 0.7.0~beta2 + LLVMExtraAddMVVMReflectPass@Base 0.7.0~beta2 + LLVMExtraAddPass@Base 0.7.0~beta2 + LLVMExtraAddTargetLibraryInfoByTiple@Base 0.7.0~beta2 + LLVMExtraCreateBasicBlockPass@Base 0.7.0~beta2 + LLVMExtraCreateFunctionPass@Base 0.7.0~beta2 + LLVMExtraCreateModulePass@Base 0.7.0~beta2 + LLVMExtraGetDebugMDVersion@Base 0.7.0~beta2 + LLVMExtraGetSourceLocation@Base 0.7.0~beta2 + LLVMExtraGetValueContext@Base 0.7.0~beta2 + LLVMExtraInitializeAllAsmParsers@Base 0.7.0~beta2 + LLVMExtraInitializeAllAsmPrinters@Base 0.7.0~beta2 + LLVMExtraInitializeAllDisassemblers@Base 0.7.0~beta2 + LLVMExtraInitializeAllTargetInfos@Base 0.7.0~beta2 + LLVMExtraInitializeAllTargetMCs@Base 0.7.0~beta2 + LLVMExtraInitializeAllTargets@Base 0.7.0~beta2 + LLVMExtraInitializeNativeAsmParser@Base 0.7.0~beta2 + LLVMExtraInitializeNativeAsmPrinter@Base 0.7.0~beta2 + LLVMExtraInitializeNativeDisassembler@Base 0.7.0~beta2 + LLVMExtraInitializeNativeTarget@Base 0.7.0~beta2 + __stack_chk_guard@Base 0.6.3 + bitvector_get@Base 0.6.3 + bitvector_new@Base 0.6.3 + bitvector_resize@Base 0.6.3 + bitvector_set@Base 0.6.3 + int32hash@Base 0.6.3 + int64hash@Base 0.6.3 + int64to32hash@Base 0.6.3 + ios_bufmode@Base 0.6.3 + ios_close@Base 0.6.3 + ios_copy@Base 0.6.3 + ios_copyall@Base 0.6.3 + ios_copyuntil@Base 0.6.3 + ios_eof@Base 0.6.3 + ios_eof_blocking@Base 0.6.3 + ios_fd@Base 0.6.3 + ios_file@Base 0.6.3 + ios_flush@Base 0.6.3 + ios_get_readable@Base 0.6.3 + ios_get_writable@Base 0.6.3 + ios_getc@Base 0.6.3 + ios_getutf8@Base 0.6.3 + ios_isopen@Base 0.6.3 + ios_mem@Base 0.6.3 + ios_mkstemp@Base 0.6.3 + ios_nchomp@Base 0.6.3 + ios_peekc@Base 0.6.3 + ios_peekutf8@Base 0.6.3 + ios_pos@Base 0.6.3 + ios_printf@Base 0.6.3 + ios_purge@Base 0.6.3 + ios_putc@Base 0.6.3 + ios_pututf8@Base 0.6.3 + ios_read@Base 0.6.3 + ios_readall@Base 0.6.3 + ios_readline@Base 0.6.3 + ios_readprep@Base 0.6.3 + ios_seek@Base 0.6.3 + ios_seek_end@Base 0.6.3 + ios_set_readonly@Base 0.6.3 + ios_setbuf@Base 0.6.3 + ios_skip@Base 0.6.3 + ios_stderr@Base 0.6.3 + ios_stdin@Base 0.6.3 + ios_stdout@Base 0.6.3 + ios_take_buffer@Base 0.6.3 + ios_trunc@Base 0.6.3 + ios_vprintf@Base 0.6.3 + ios_write@Base 0.6.3 + ios_write_direct@Base 0.6.3 + jl_@Base 0.6.3 + jl_LLVMContext@Base 0.6.3 + jl_LLVMCreateDisasm@Base 0.6.3 + jl_LLVMDisasmInstruction@Base 0.6.3 + jl_LLVMFlipSign@Base 0.6.3 + jl_LLVMSMod@Base 0.6.3 + jl_RTLD_DEFAULT_handle@Base 0.6.3 + jl_SC_CLK_TCK@Base 0.6.3 + jl_abs_float@Base 0.6.3 + jl_abs_float_withtype@Base 0.6.3 + jl_abstractarray_type@Base 0.6.3 + jl_abstractslot_type@Base 0.6.3 + jl_abstractstring_type@Base 0.6.3 + jl_add_float@Base 0.6.3 + jl_add_int@Base 0.6.3 + jl_add_optimization_passes@Base 0.7.0~beta2 + jl_add_ptr@Base 0.7.0~beta2 + jl_add_standard_imports@Base 0.6.3 + jl_alignment@Base 0.6.3 + jl_alloc_array_1d@Base 0.6.3 + jl_alloc_array_2d@Base 0.6.3 + jl_alloc_array_3d@Base 0.6.3 + jl_alloc_string@Base 0.6.3 + jl_alloc_svec@Base 0.6.3 + jl_alloc_svec_uninit@Base 0.6.3 + jl_alloc_vec_any@Base 0.6.3 + jl_an_empty_vec_any@Base 0.6.3 + jl_and_int@Base 0.6.3 + jl_any_type@Base 0.6.3 + jl_anytuple_type@Base 0.6.3 + jl_anytuple_type_type@Base 0.6.3 + jl_apply_2va@Base 0.6.3 + jl_apply_array_type@Base 0.6.3 + jl_apply_generic@Base 0.6.3 + jl_apply_tuple_type@Base 0.6.3 + jl_apply_tuple_type_v@Base 0.6.3 + jl_apply_type1@Base 0.6.3 + jl_apply_type2@Base 0.6.3 + jl_apply_type@Base 0.6.3 + jl_apply_with_saved_exception_state@Base 0.6.3 + jl_argument_datatype@Base 0.7.0~beta2 + jl_argumenterror_type@Base 0.6.3 + jl_array_any_type@Base 0.6.3 + jl_array_cconvert_cstring@Base 0.6.3 + jl_array_copy@Base 0.6.3 + jl_array_data_owner@Base 0.6.3 + jl_array_del_at@Base 0.6.3 + jl_array_del_beg@Base 0.6.3 + jl_array_del_end@Base 0.6.3 + jl_array_eltype@Base 0.6.3 + jl_array_grow_at@Base 0.6.3 + jl_array_grow_beg@Base 0.6.3 + jl_array_grow_end@Base 0.6.3 + jl_array_int32_type@Base 0.7.0~beta2 + jl_array_isassigned@Base 0.6.3 + jl_array_ptr@Base 0.6.3 + jl_array_ptr_1d_append@Base 0.6.3 + jl_array_ptr_1d_push@Base 0.6.3 + jl_array_ptr_copy@Base 0.6.3 + jl_array_rank@Base 0.6.3 + jl_array_size@Base 0.6.3 + jl_array_sizehint@Base 0.6.3 + jl_array_store_unboxed@Base 0.7.0~beta2 + jl_array_symbol_type@Base 0.6.3 + jl_array_to_string@Base 0.6.3 + jl_array_type@Base 0.6.3 + jl_array_typename@Base 0.6.3 + jl_array_typetagdata@Base 0.7.0 + jl_array_uint8_type@Base 0.6.3 + jl_arraylen@Base 0.6.3 + jl_arrayref@Base 0.6.3 + jl_arrayset@Base 0.6.3 + jl_arrayunset@Base 0.6.3 + jl_ashr_int@Base 0.6.3 + jl_ast_flag_inferred@Base 0.6.3 + jl_ast_flag_inlineable@Base 0.6.3 + jl_ast_flag_pure@Base 0.6.3 + jl_astaggedvalue@Base 0.6.3 + jl_atexit_hook@Base 0.6.3 + jl_backtrace_from_here@Base 0.6.3 + jl_base_module@Base 0.6.3 + jl_base_relative_to@Base 0.6.3 + jl_binding_owner@Base 0.7.0~beta2 + jl_binding_resolved_p@Base 0.6.3 + jl_bitcast@Base 0.6.3 + jl_bool_type@Base 0.6.3 + jl_bottom_type@Base 0.6.3 + jl_boundp@Base 0.6.3 + jl_bounds_error@Base 0.6.3 + jl_bounds_error_int@Base 0.6.3 + jl_bounds_error_ints@Base 0.6.3 + jl_bounds_error_tuple_int@Base 0.6.3 + jl_bounds_error_unboxed_int@Base 0.6.3 + jl_bounds_error_v@Base 0.6.3 + jl_boundserror_type@Base 0.6.3 + jl_box_bool@Base 0.6.3 + jl_box_char@Base 0.6.3 + jl_box_float32@Base 0.6.3 + jl_box_float64@Base 0.6.3 + jl_box_int16@Base 0.6.3 + jl_box_int32@Base 0.6.3 + jl_box_int64@Base 0.6.3 + jl_box_int8@Base 0.6.3 + jl_box_slotnumber@Base 0.6.3 + jl_box_ssavalue@Base 0.6.3 + jl_box_uint16@Base 0.6.3 + jl_box_uint32@Base 0.6.3 + jl_box_uint64@Base 0.6.3 + jl_box_uint8@Base 0.6.3 + jl_box_voidpointer@Base 0.6.3 + jl_breakpoint@Base 0.6.3 + jl_bswap_int@Base 0.6.3 + jl_builtin_type@Base 0.6.3 + jl_call0@Base 0.6.3 + jl_call1@Base 0.6.3 + jl_call2@Base 0.6.3 + jl_call3@Base 0.6.3 + jl_call@Base 0.6.3 + jl_calloc@Base 0.6.3 + jl_capture_interp_frame@Base 0.7.0~beta2 + jl_ceil_llvm@Base 0.6.3 + jl_ceil_llvm_withtype@Base 0.6.3 + jl_cglobal@Base 0.6.3 + jl_cglobal_auto@Base 0.6.3 + jl_char_type@Base 0.6.3 + jl_checked_assignment@Base 0.6.3 + jl_checked_sadd_int@Base 0.6.3 + jl_checked_sdiv_int@Base 0.6.3 + jl_checked_smul_int@Base 0.6.3 + jl_checked_srem_int@Base 0.6.3 + jl_checked_ssub_int@Base 0.6.3 + jl_checked_uadd_int@Base 0.6.3 + jl_checked_udiv_int@Base 0.6.3 + jl_checked_umul_int@Base 0.6.3 + jl_checked_urem_int@Base 0.6.3 + jl_checked_usub_int@Base 0.6.3 + jl_clear_malloc_data@Base 0.6.3 + jl_clock_now@Base 0.6.3 + jl_close_uv@Base 0.6.3 + jl_code_for_staged@Base 0.6.3 + jl_code_info_type@Base 0.6.3 + jl_compile_hint@Base 0.6.3 + jl_compress_ast@Base 0.6.3 + jl_connect_raw@Base 0.6.3 + jl_copy_ast@Base 0.6.3 + jl_copy_code_info@Base 0.6.3 + jl_copysign_float@Base 0.6.3 + jl_core_module@Base 0.6.3 + jl_cpu_pause@Base 0.6.3 + jl_cpu_threads@Base 0.7.0~beta2 + jl_cpu_wake@Base 0.6.3 + (arch=amd64 i386)jl_cpuid@Base 0.6.3 + (arch=amd64 i386)jl_cpuidex@Base 0.7.0~beta2 + jl_crc32c@Base 0.6.3 + jl_crc32c_sw@Base 0.7.0~beta2 + jl_create_system_image@Base 0.6.3 + jl_cstr_to_string@Base 0.6.3 + jl_ctlz_int@Base 0.6.3 + jl_ctpop_int@Base 0.6.3 + jl_cttz_int@Base 0.6.3 + jl_datatype_type@Base 0.6.3 + jl_declare_constant@Base 0.6.3 + jl_default_cgparams@Base 0.6.3 + jl_defines_or_exports_p@Base 0.6.3 + jl_densearray_type@Base 0.6.3 + jl_deprecate_binding@Base 0.6.3 + jl_div_float@Base 0.6.3 + jl_diverror_exception@Base 0.6.3 + jl_dl_handle@Base 0.6.3 + jl_dlclose@Base 0.6.3 + jl_dlopen@Base 0.6.3 + jl_dlsym@Base 0.6.3 + jl_dlsym_e@Base 0.6.3 + jl_domain_exception@Base 0.6.3 + jl_dump_compiles@Base 0.6.3 + jl_dump_fptr_asm@Base 0.7.0~beta2 + jl_dump_function_asm@Base 0.6.3 + jl_dump_function_ir@Base 0.6.3 + jl_dump_host_cpu@Base 0.7.0~beta2 + jl_egal@Base 0.6.3 + jl_emptysvec@Base 0.6.3 + jl_emptytuple@Base 0.6.3 + jl_emptytuple_type@Base 0.6.3 + jl_enter_handler@Base 0.6.3 + jl_environ@Base 0.6.3 + jl_eof_error@Base 0.6.3 + jl_eq_float@Base 0.6.3 + jl_eq_int@Base 0.6.3 + jl_eqtable_get@Base 0.6.3 + jl_eqtable_nextind@Base 0.6.3 + jl_eqtable_pop@Base 0.6.3 + jl_eqtable_put@Base 0.6.3 + jl_errno@Base 0.6.3 + jl_error@Base 0.6.3 + jl_errorexception_type@Base 0.6.3 + jl_errorf@Base 0.6.3 + jl_eval_string@Base 0.6.3 + jl_exception_clear@Base 0.6.3 + jl_exception_occurred@Base 0.6.3 + jl_exceptionf@Base 0.6.3 + jl_exe_handle@Base 0.6.3 + jl_exit@Base 0.6.3 + jl_exit_on_sigint@Base 0.6.3 + jl_expand@Base 0.6.3 + jl_expand_stmt@Base 0.7.0~beta2 + jl_expr_type@Base 0.6.3 + jl_extern_c@Base 0.6.3 + jl_f__apply@Base 0.6.3 + jl_f__apply_latest@Base 0.6.3 + jl_f__apply_pure@Base 0.6.3 + jl_f__expr@Base 0.6.3 + jl_f_applicable@Base 0.6.3 + jl_f_apply_type@Base 0.6.3 + jl_f_arrayref@Base 0.6.3 + jl_f_arrayset@Base 0.6.3 + jl_f_arraysize@Base 0.6.3 + jl_f_fieldtype@Base 0.6.3 + jl_f_getfield@Base 0.6.3 + jl_f_ifelse@Base 0.7.0~beta2 + jl_f_intrinsic_call@Base 0.6.3 + jl_f_invoke@Base 0.6.3 + jl_f_invoke_kwsorter@Base 0.6.3 + jl_f_is@Base 0.6.3 + jl_f_isa@Base 0.6.3 + jl_f_isdefined@Base 0.6.3 + jl_f_issubtype@Base 0.6.3 + jl_f_new_module@Base 0.6.3 + jl_f_nfields@Base 0.6.3 + jl_f_setfield@Base 0.6.3 + jl_f_sizeof@Base 0.6.3 + jl_f_svec@Base 0.6.3 + jl_f_throw@Base 0.6.3 + jl_f_tuple@Base 0.6.3 + jl_f_typeassert@Base 0.6.3 + jl_f_typeof@Base 0.6.3 + jl_false@Base 0.6.3 + jl_field_index@Base 0.6.3 + jl_field_isdefined@Base 0.6.3 + jl_filename@Base 0.6.3 + jl_fill_argnames@Base 0.6.3 + jl_finalize@Base 0.6.3 + jl_finalize_th@Base 0.6.3 + jl_find_free_typevars@Base 0.6.3 + jl_first_argument_datatype@Base 0.6.3 + jl_flipsign_int@Base 0.6.3 + jl_float16_type@Base 0.6.3 + jl_float32_type@Base 0.6.3 + jl_float64_type@Base 0.6.3 + jl_floatingpoint_type@Base 0.6.3 + jl_floor_llvm@Base 0.6.3 + jl_floor_llvm_withtype@Base 0.6.3 + jl_flush_cstdio@Base 0.6.3 + jl_fma_float@Base 0.6.3 + jl_forceclose_uv@Base 0.6.3 + jl_fpext@Base 0.6.3 + jl_fpiseq@Base 0.6.3 + jl_fpislt@Base 0.6.3 + jl_fptosi@Base 0.6.3 + jl_fptoui@Base 0.6.3 + jl_fptr_args@Base 0.7.0~beta2 + jl_fptr_const_return@Base 0.7.0~beta2 + jl_fptr_interpret_call@Base 0.7.0~beta2 + jl_fptr_sparam@Base 0.7.0~beta2 + jl_fptr_trampoline@Base 0.7.0~beta2 + jl_fptrunc@Base 0.6.3 + jl_free@Base 0.6.3 + jl_fs_chmod@Base 0.6.3 + jl_fs_chown@Base 0.6.3 + jl_fs_close@Base 0.6.3 + jl_fs_read@Base 0.6.3 + jl_fs_read_byte@Base 0.6.3 + jl_fs_rename@Base 0.6.3 + jl_fs_sendfile@Base 0.6.3 + jl_fs_symlink@Base 0.6.3 + jl_fs_unlink@Base 0.6.3 + jl_fs_write@Base 0.6.3 + jl_fstat@Base 0.6.3 + jl_ftruncate@Base 0.6.3 + jl_function_ptr@Base 0.6.3 + jl_function_ptr_by_llvm_name@Base 0.6.3 + jl_function_type@Base 0.6.3 + jl_gc_add_finalizer@Base 0.6.3 + jl_gc_add_finalizer_th@Base 0.6.3 + jl_gc_add_ptr_finalizer@Base 0.6.3 + jl_gc_alloc@Base 0.6.3 + jl_gc_alloc_0w@Base 0.6.3 + jl_gc_alloc_1w@Base 0.6.3 + jl_gc_alloc_2w@Base 0.6.3 + jl_gc_alloc_3w@Base 0.6.3 + jl_gc_allocobj@Base 0.6.3 + jl_gc_big_alloc@Base 0.6.3 + jl_gc_collect@Base 0.6.3 + jl_gc_counted_calloc@Base 0.6.3 + jl_gc_counted_free@Base 0.6.3 + jl_gc_counted_free_with_size@Base 0.7.0~beta2 + jl_gc_counted_malloc@Base 0.6.3 + jl_gc_counted_realloc_with_old_size@Base 0.6.3 + jl_gc_diff_total_bytes@Base 0.6.3 + jl_gc_enable@Base 0.6.3 + jl_gc_enable_finalizers@Base 0.6.3 + jl_gc_find_taggedvalue_pool@Base 0.6.3 + jl_gc_is_enabled@Base 0.6.3 + jl_gc_managed_malloc@Base 0.6.3 + jl_gc_managed_realloc@Base 0.6.3 + jl_gc_new_weakref@Base 0.6.3 + jl_gc_new_weakref_th@Base 0.6.3 + jl_gc_num@Base 0.6.3 + jl_gc_pool_alloc@Base 0.6.3 + jl_gc_queue_root@Base 0.6.3 + jl_gc_safe_enter@Base 0.6.3 + jl_gc_safe_leave@Base 0.6.3 + jl_gc_safepoint@Base 0.6.3 + jl_gc_total_bytes@Base 0.6.3 + jl_gc_total_hrtime@Base 0.6.3 + jl_gc_unsafe_enter@Base 0.6.3 + jl_gc_unsafe_leave@Base 0.6.3 + jl_gc_use@Base 0.7.0~beta2 + jl_gdblookup@Base 0.6.3 + jl_generating_output@Base 0.6.3 + jl_generic_function_def@Base 0.6.3 + jl_gensym@Base 0.6.3 + jl_get_ARCH@Base 0.6.3 + jl_get_JIT@Base 0.6.3 + jl_get_LLVM_VERSION@Base 0.6.3 + jl_get_UNAME@Base 0.6.3 + jl_get_backtrace@Base 0.6.3 + jl_get_binding@Base 0.6.3 + jl_get_binding_for_method_def@Base 0.6.3 + jl_get_binding_or_error@Base 0.6.3 + jl_get_binding_wr@Base 0.6.3 + jl_get_cfunction_trampoline@Base 0.7.0~beta2 + jl_get_cpu_name@Base 0.6.3 + jl_get_current_task@Base 0.6.3 + jl_get_default_sysimg_path@Base 0.6.3 + jl_get_dobj_data@Base 0.6.3 + jl_get_fenv_consts@Base 0.6.3 + jl_get_field@Base 0.6.3 + jl_get_field_offset@Base 0.6.3 + jl_get_global@Base 0.6.3 + jl_get_image_file@Base 0.6.3 + jl_get_invoke_lambda@Base 0.6.3 + jl_get_julia_bin@Base 0.6.3 + jl_get_julia_bindir@Base 0.7.0~beta2 + jl_get_keyword_sorter@Base 0.6.3 + jl_get_kwsorter@Base 0.6.3 + jl_get_llvm_fptr@Base 0.6.3 + jl_get_llvmf_decl@Base 0.6.3 + jl_get_llvmf_defn@Base 0.6.3 + jl_get_module_of_binding@Base 0.6.3 + jl_get_nth_field@Base 0.6.3 + jl_get_nth_field_checked@Base 0.6.3 + jl_get_nth_field_noalloc@Base 0.7.0~beta2 + jl_get_ptls_states@Base 0.6.3 + jl_get_root_symbol@Base 0.6.3 + jl_get_section_start@Base 0.6.3 + jl_get_size@Base 0.6.3 + jl_get_spec_lambda@Base 0.6.3 + jl_get_tls_world_age@Base 0.6.3 + jl_get_world_counter@Base 0.6.3 + jl_get_zero_subnormals@Base 0.6.3 + jl_getaddrinfo@Base 0.6.3 + jl_getallocationgranularity@Base 0.6.3 + jl_getnameinfo6@Base 0.7.0~beta2 + jl_getnameinfo@Base 0.7.0~beta2 + jl_getpagesize@Base 0.6.3 + jl_getpid@Base 0.6.3 + jl_gettimeofday@Base 0.6.3 + jl_getutf8@Base 0.6.3 + jl_gf_invoke_lookup@Base 0.6.3 + jl_git_branch@Base 0.6.3 + jl_git_commit@Base 0.6.3 + jl_global_event_loop@Base 0.6.3 + jl_globalref_type@Base 0.6.3 + jl_gotonode_type@Base 0.6.3 + jl_has_call_ambiguities@Base 0.6.3 + jl_has_empty_intersection@Base 0.6.3 + jl_has_free_typevars@Base 0.6.3 + jl_has_so_reuseport@Base 0.7.0~beta2 + jl_has_typevar@Base 0.6.3 + jl_has_typevar_from_unionall@Base 0.6.3 + jl_hrtime@Base 0.6.3 + jl_id_char@Base 0.6.3 + jl_id_start_char@Base 0.6.3 + jl_idtable_rehash@Base 0.6.3 + jl_incomplete_sym@Base 0.6.3 + jl_infer_thunk@Base 0.7.0~beta2 + jl_init__threading@Base 0.7.0~beta2 + jl_init_restored_modules@Base 0.7.0 + jl_init_with_image__threading@Base 0.7.0~beta2 + jl_initerror_type@Base 0.6.3 + jl_install_sigint_handler@Base 0.6.3 + jl_instantiate_type_in_env@Base 0.6.3 + jl_instantiate_unionall@Base 0.6.3 + jl_int16_type@Base 0.6.3 + jl_int32_type@Base 0.6.3 + jl_int64_type@Base 0.6.3 + jl_int8_type@Base 0.6.3 + jl_internal_main_module@Base 0.6.3 + jl_interrupt_exception@Base 0.6.3 + jl_intersect_types@Base 0.6.3 + jl_intrinsic_name@Base 0.6.3 + jl_intrinsic_type@Base 0.6.3 + jl_invoke@Base 0.6.3 + jl_invoke_api@Base 0.7.0~beta2 + jl_ios_fd@Base 0.6.3 + jl_ios_get_nbyte_int@Base 0.6.3 + jl_is_binding_deprecated@Base 0.6.3 + jl_is_call_ambiguous@Base 0.7.0~beta2 + jl_is_char_signed@Base 0.6.3 + jl_is_const@Base 0.6.3 + jl_is_debugbuild@Base 0.6.3 + jl_is_enter_interpreter_frame@Base 0.7.0~beta2 + jl_is_identifier@Base 0.7.0~beta2 + jl_is_imported@Base 0.6.3 + jl_is_in_pure_context@Base 0.6.3 + jl_is_initialized@Base 0.6.3 + jl_is_interpreter_frame@Base 0.7.0~beta2 + jl_is_memdebug@Base 0.6.3 + jl_is_not_broken_subtype@Base 0.7.0~beta2 + jl_is_operator@Base 0.6.3 + jl_is_task_started@Base 0.6.3 + jl_is_unary_and_binary_operator@Base 0.7.0~beta2 + jl_is_unary_operator@Base 0.7.0~beta2 + jl_isa@Base 0.6.3 + jl_isa_compileable_sig@Base 0.7.0~beta2 + jl_islayout_inline@Base 0.7.0~beta2 + jl_istopmod@Base 0.6.3 + jl_le_float@Base 0.6.3 + jl_lineinfonode_type@Base 0.7.0~beta2 + jl_lineno@Base 0.6.3 + jl_linenumbernode_type@Base 0.6.3 + jl_lisp_prompt@Base 0.6.3 + jl_load@Base 0.6.3 + jl_load_@Base 0.6.3 + jl_load_and_lookup@Base 0.6.3 + jl_load_dynamic_library@Base 0.6.3 + jl_load_dynamic_library_e@Base 0.6.3 + jl_load_file_string@Base 0.6.3 + jl_loaderror_type@Base 0.6.3 + jl_lookup_code_address@Base 0.6.3 + jl_lseek@Base 0.6.3 + jl_lshr_int@Base 0.6.3 + jl_lstat@Base 0.6.3 + jl_lt_float@Base 0.6.3 + jl_macroexpand1@Base 0.7.0~beta2 + jl_macroexpand@Base 0.6.3 + jl_main_module@Base 0.6.3 + jl_malloc@Base 0.6.3 + jl_matching_methods@Base 0.6.3 + jl_maxrss@Base 0.6.3 + jl_memory_exception@Base 0.6.3 + jl_method_def@Base 0.6.3 + jl_method_exists@Base 0.6.3 + jl_method_instance_add_backedge@Base 0.6.3 + jl_method_instance_type@Base 0.6.3 + jl_method_table_add_backedge@Base 0.6.3 + jl_method_table_disable@Base 0.7.0~beta2 + jl_method_table_insert@Base 0.6.3 + jl_method_type@Base 0.6.3 + jl_methoderror_type@Base 0.6.3 + jl_methtable_lookup@Base 0.6.3 + jl_methtable_type@Base 0.6.3 + jl_mmap@Base 0.6.3 + jl_module_build_id@Base 0.7.0~beta2 + jl_module_export@Base 0.6.3 + jl_module_exports_p@Base 0.6.3 + jl_module_globalref@Base 0.6.3 + jl_module_import@Base 0.6.3 + jl_module_name@Base 0.6.3 + jl_module_names@Base 0.6.3 + jl_module_parent@Base 0.6.3 + jl_module_type@Base 0.6.3 + jl_module_use@Base 0.6.3 + jl_module_using@Base 0.6.3 + jl_module_usings@Base 0.6.3 + jl_module_uuid@Base 0.6.3 + jl_mul_float@Base 0.6.3 + jl_mul_int@Base 0.6.3 + jl_muladd_float@Base 0.6.3 + jl_n_threads@Base 0.6.3 + jl_namedtuple_type@Base 0.7.0~beta2 + jl_namedtuple_typename@Base 0.7.0~beta2 + jl_native_alignment@Base 0.6.3 + jl_nb_available@Base 0.6.3 + jl_ne_float@Base 0.6.3 + jl_ne_int@Base 0.6.3 + jl_neg_float@Base 0.6.3 + jl_neg_float_withtype@Base 0.6.3 + jl_neg_int@Base 0.6.3 + jl_new_array@Base 0.6.3 + jl_new_bits@Base 0.6.3 + jl_new_code_info_uninit@Base 0.6.3 + jl_new_datatype@Base 0.6.3 + jl_new_main_module@Base 0.6.3 + jl_new_method_instance_uninit@Base 0.6.3 + jl_new_method_table@Base 0.6.3 + jl_new_method_uninit@Base 0.6.3 + jl_new_module@Base 0.6.3 + jl_new_primitivetype@Base 0.6.3 + jl_new_struct@Base 0.6.3 + jl_new_struct_uninit@Base 0.6.3 + jl_new_structv@Base 0.6.3 + jl_new_task@Base 0.6.3 + jl_new_typename_in@Base 0.6.3 + jl_new_typevar@Base 0.6.3 + jl_newvarnode_type@Base 0.6.3 + jl_next_from_addrinfo@Base 0.6.3 + jl_no_exc_handler@Base 0.6.3 + jl_not_int@Base 0.6.3 + jl_nothing@Base 0.6.3 + jl_number_type@Base 0.6.3 + jl_object_id@Base 0.6.3 + jl_op_suffix_char@Base 0.7.0~beta2 + jl_operator_precedence@Base 0.6.3 + jl_options@Base 0.6.3 + jl_or_int@Base 0.6.3 + jl_overflow_exception@Base 0.6.3 + jl_parse_input_line@Base 0.6.3 + jl_parse_opts@Base 0.6.3 + jl_parse_string@Base 0.6.3 + jl_pathname_for_handle@Base 0.6.3 + jl_pchar_to_array@Base 0.6.3 + jl_pchar_to_string@Base 0.6.3 + jl_phicnode_type@Base 0.7.0~beta2 + jl_phinode_type@Base 0.7.0~beta2 + jl_pinode_type@Base 0.7.0~beta2 + jl_pipe_open@Base 0.7.0~beta2 + jl_pointer_type@Base 0.6.3 + jl_pointer_typename@Base 0.6.3 + jl_pointerref@Base 0.6.3 + jl_pointerset@Base 0.6.3 + jl_pop_handler@Base 0.6.3 + jl_preload_sysimg_so@Base 0.6.3 + jl_prepend_cwd@Base 0.7.0~beta2 + jl_printf@Base 0.6.3 + jl_process_events@Base 0.6.3 + jl_profile_clear_data@Base 0.6.3 + jl_profile_delay_nsec@Base 0.6.3 + jl_profile_get_data@Base 0.6.3 + jl_profile_init@Base 0.6.3 + jl_profile_is_running@Base 0.6.3 + jl_profile_len_data@Base 0.6.3 + jl_profile_maxlen_data@Base 0.6.3 + jl_profile_start_timer@Base 0.6.3 + jl_profile_stop_timer@Base 0.6.3 + jl_ptr_to_array@Base 0.6.3 + jl_ptr_to_array_1d@Base 0.6.3 + jl_ptrarrayref@Base 0.7.0~beta2 + jl_pwrite@Base 0.6.3 + jl_queue_work@Base 0.6.3 + jl_quotenode_type@Base 0.6.3 + jl_raise_debugger@Base 0.6.3 + jl_read_verify_header@Base 0.6.3 + jl_readonlymemory_exception@Base 0.6.3 + jl_readuntil@Base 0.6.3 + jl_realloc@Base 0.6.3 + jl_ref_type@Base 0.6.3 + jl_register_linfo_tracer@Base 0.6.3 + jl_register_method_tracer@Base 0.6.3 + jl_register_newmeth_tracer@Base 0.6.3 + jl_rem_float@Base 0.6.3 + jl_repl_raise_sigtstp@Base 0.7.0~beta2 + jl_reshape_array@Base 0.6.3 + jl_restore_incremental@Base 0.6.3 + jl_restore_incremental_from_buf@Base 0.6.3 + jl_restore_system_image@Base 0.6.3 + jl_restore_system_image_data@Base 0.6.3 + jl_rethrow@Base 0.6.3 + jl_rethrow_other@Base 0.6.3 + jl_rint_llvm@Base 0.6.3 + jl_rint_llvm_withtype@Base 0.6.3 + jl_run_event_loop@Base 0.6.3 + jl_run_once@Base 0.6.3 + jl_running_on_valgrind@Base 0.6.3 + jl_safe_printf@Base 0.6.3 + jl_save_incremental@Base 0.6.3 + jl_save_system_image@Base 0.6.3 + jl_sdiv_int@Base 0.6.3 + jl_set_ARGS@Base 0.6.3 + jl_set_const@Base 0.6.3 + jl_set_errno@Base 0.6.3 + jl_set_global@Base 0.6.3 + jl_set_istopmod@Base 0.6.3 + jl_set_method_inferred@Base 0.6.3 + jl_set_module_nospecialize@Base 0.7.0 + jl_set_module_uuid@Base 0.7.0~beta2 + jl_set_nth_field@Base 0.6.3 + jl_set_ptls_states_getter@Base 0.6.3 + jl_set_sysimg_so@Base 0.6.3 + jl_set_typeinf_func@Base 0.6.3 + jl_set_zero_subnormals@Base 0.6.3 + jl_sext_int@Base 0.6.3 + jl_shl_int@Base 0.6.3 + jl_sigatomic_begin@Base 0.6.3 + jl_sigatomic_end@Base 0.6.3 + jl_signal_pending@Base 0.6.3 + jl_signed_type@Base 0.6.3 + jl_simplevector_type@Base 0.6.3 + jl_sitofp@Base 0.6.3 + jl_sizeof_ios_t@Base 0.6.3 + jl_sizeof_jl_options@Base 0.7.0~beta2 + jl_sizeof_mode_t@Base 0.6.3 + jl_sizeof_off_t@Base 0.6.3 + jl_sizeof_stat@Base 0.6.3 + jl_sizeof_uv_fs_t@Base 0.6.3 + jl_sizeof_uv_mutex@Base 0.6.3 + jl_sle_int@Base 0.6.3 + jl_slotnumber_type@Base 0.6.3 + jl_slt_int@Base 0.6.3 + jl_smod_int@Base 0.6.3 + jl_sockaddr_from_addrinfo@Base 0.6.3 + jl_sockaddr_host4@Base 0.6.3 + jl_sockaddr_host6@Base 0.6.3 + jl_sockaddr_in_is_ip4@Base 0.6.3 + jl_sockaddr_in_is_ip6@Base 0.6.3 + jl_sockaddr_is_ip4@Base 0.6.3 + jl_sockaddr_is_ip6@Base 0.6.3 + jl_sockaddr_set_port@Base 0.6.3 + jl_spawn@Base 0.6.3 + jl_specializations_get_linfo@Base 0.6.3 + jl_specializations_lookup@Base 0.6.3 + jl_sqrt_llvm@Base 0.6.3 + jl_sqrt_llvm_withtype@Base 0.6.3 + jl_srem_int@Base 0.6.3 + jl_ssavalue_type@Base 0.6.3 + jl_stackovf_exception@Base 0.6.3 + jl_stat@Base 0.6.3 + jl_stat_blksize@Base 0.6.3 + jl_stat_blocks@Base 0.6.3 + jl_stat_ctime@Base 0.6.3 + jl_stat_dev@Base 0.6.3 + jl_stat_gid@Base 0.6.3 + jl_stat_ino@Base 0.6.3 + jl_stat_mode@Base 0.6.3 + jl_stat_mtime@Base 0.6.3 + jl_stat_nlink@Base 0.6.3 + jl_stat_rdev@Base 0.6.3 + jl_stat_size@Base 0.6.3 + jl_stat_uid@Base 0.6.3 + jl_static_show@Base 0.6.3 + jl_static_show_func_sig@Base 0.6.3 + jl_stderr_obj@Base 0.6.3 + jl_stderr_stream@Base 0.6.3 + jl_stdin_stream@Base 0.6.3 + jl_stdout_obj@Base 0.6.3 + jl_stdout_stream@Base 0.6.3 + jl_string_ptr@Base 0.6.3 + jl_string_to_array@Base 0.6.3 + jl_string_type@Base 0.6.3 + jl_strtod_c@Base 0.6.3 + jl_strtof_c@Base 0.6.3 + jl_sub_float@Base 0.6.3 + jl_sub_int@Base 0.6.3 + jl_sub_ptr@Base 0.7.0~beta2 + jl_substrtod@Base 0.6.3 + jl_substrtof@Base 0.6.3 + jl_subtype@Base 0.6.3 + jl_subtype_env@Base 0.6.3 + jl_subtype_env_size@Base 0.6.3 + jl_svec1@Base 0.6.3 + jl_svec2@Base 0.6.3 + jl_svec@Base 0.6.3 + jl_svec_copy@Base 0.6.3 + jl_svec_fill@Base 0.6.3 + jl_switchto@Base 0.6.3 + jl_sym_type@Base 0.6.3 + jl_symbol@Base 0.6.3 + jl_symbol_lookup@Base 0.6.3 + jl_symbol_n@Base 0.6.3 + jl_symbol_name@Base 0.6.3 + jl_symbol_type@Base 0.6.3 + jl_tagged_gensym@Base 0.6.3 + jl_take_buffer@Base 0.6.3 + jl_task_type@Base 0.6.3 + jl_tcp4_connect@Base 0.6.3 + jl_tcp6_connect@Base 0.6.3 + jl_tcp_bind6@Base 0.6.3 + jl_tcp_bind@Base 0.6.3 + jl_tcp_getpeername@Base 0.6.3 + jl_tcp_getsockname@Base 0.6.3 + jl_tcp_quickack@Base 0.6.3 + jl_tcp_reuseport@Base 0.6.3 + jl_threadid@Base 0.6.3 + jl_threading_enabled@Base 0.6.3 + jl_threading_profile@Base 0.6.3 + jl_threading_run@Base 0.6.3 + jl_throw@Base 0.6.3 + jl_too_few_args@Base 0.6.3 + jl_too_many_args@Base 0.6.3 + jl_top_module@Base 0.6.3 + jl_toplevel_eval@Base 0.6.3 + jl_toplevel_eval_in@Base 0.6.3 + jl_trace_linfo@Base 0.6.3 + jl_trace_method@Base 0.6.3 + jl_true@Base 0.6.3 + jl_trunc_int@Base 0.6.3 + jl_trunc_llvm@Base 0.6.3 + jl_trunc_llvm_withtype@Base 0.6.3 + jl_try_substrtod@Base 0.6.3 + jl_try_substrtof@Base 0.6.3 + jl_tty_set_mode@Base 0.6.3 + jl_tuple_typename@Base 0.6.3 + jl_tupletype_fill@Base 0.6.3 + jl_tvar_type@Base 0.6.3 + jl_type_error@Base 0.6.3 + jl_type_error_new_expr@Base 0.7.0~beta2 + jl_type_error_rt@Base 0.6.3 + jl_type_intersection@Base 0.6.3 + jl_type_intersection_with_env@Base 0.7.0~beta2 + jl_type_morespecific@Base 0.6.3 + jl_type_morespecific_no_subtype@Base 0.6.3 + jl_type_type@Base 0.6.3 + jl_type_typename@Base 0.6.3 + jl_type_union@Base 0.6.3 + jl_type_unionall@Base 0.6.3 + jl_typeassert@Base 0.6.3 + jl_typedslot_type@Base 0.6.3 + jl_typeerror_type@Base 0.6.3 + jl_typeinf_begin@Base 0.6.3 + jl_typeinf_end@Base 0.6.3 + jl_typemap_entry_type@Base 0.6.3 + jl_typemap_level_type@Base 0.6.3 + jl_typemax_uint@Base 0.7.0~beta2 + jl_typename_str@Base 0.6.3 + jl_typename_type@Base 0.6.3 + jl_typeof@Base 0.6.3 + jl_typeof_str@Base 0.6.3 + jl_typeofbottom_type@Base 0.6.3 + jl_types_equal@Base 0.6.3 + jl_typetype_type@Base 0.6.3 + jl_udiv_int@Base 0.6.3 + jl_udp_bind6@Base 0.6.3 + jl_udp_bind@Base 0.6.3 + jl_udp_send6@Base 0.6.3 + jl_udp_send@Base 0.6.3 + jl_uint16_type@Base 0.6.3 + jl_uint32_type@Base 0.6.3 + jl_uint64_type@Base 0.6.3 + jl_uint8_type@Base 0.6.3 + jl_uitofp@Base 0.6.3 + jl_ule_int@Base 0.6.3 + jl_ult_int@Base 0.6.3 + jl_unbox_bool@Base 0.6.3 + jl_unbox_float32@Base 0.6.3 + jl_unbox_float64@Base 0.6.3 + jl_unbox_int16@Base 0.6.3 + jl_unbox_int32@Base 0.6.3 + jl_unbox_int64@Base 0.6.3 + jl_unbox_int8@Base 0.6.3 + jl_unbox_uint16@Base 0.6.3 + jl_unbox_uint32@Base 0.6.3 + jl_unbox_uint64@Base 0.6.3 + jl_unbox_uint8@Base 0.6.3 + jl_unbox_voidpointer@Base 0.6.3 + jl_uncompress_ast@Base 0.6.3 + jl_undefined_var_error@Base 0.6.3 + jl_undefref_exception@Base 0.6.3 + jl_undefvarerror_type@Base 0.6.3 + jl_unionall_type@Base 0.6.3 + jl_uniontype_type@Base 0.6.3 + jl_untrace_linfo@Base 0.6.3 + jl_untrace_method@Base 0.6.3 + jl_upsilonnode_type@Base 0.7.0~beta2 + jl_urem_int@Base 0.6.3 + jl_uv_associate_julia_struct@Base 0.6.3 + jl_uv_buf_base@Base 0.6.3 + jl_uv_buf_len@Base 0.6.3 + jl_uv_buf_set_base@Base 0.6.3 + jl_uv_buf_set_len@Base 0.6.3 + jl_uv_connect_handle@Base 0.6.3 + jl_uv_disassociate_julia_struct@Base 0.6.3 + jl_uv_file_handle@Base 0.6.3 + jl_uv_fs_req_cleanup@Base 0.6.3 + jl_uv_fs_result@Base 0.6.3 + jl_uv_fs_t_ptr@Base 0.6.3 + jl_uv_handle@Base 0.6.3 + jl_uv_handle_data@Base 0.6.3 + jl_uv_handle_type@Base 0.6.3 + jl_uv_interface_address_is_internal@Base 0.6.3 + jl_uv_interface_address_sockaddr@Base 0.6.3 + jl_uv_interface_addresses@Base 0.6.3 + jl_uv_process_data@Base 0.6.3 + jl_uv_putb@Base 0.6.3 + jl_uv_putc@Base 0.6.3 + jl_uv_puts@Base 0.6.3 + jl_uv_req_data@Base 0.6.3 + jl_uv_req_set_data@Base 0.6.3 + jl_uv_sizeof_interface_address@Base 0.6.3 + jl_uv_stderr@Base 0.6.3 + jl_uv_stdin@Base 0.6.3 + jl_uv_stdout@Base 0.6.3 + jl_uv_unix_fd_is_watched@Base 0.6.3 + jl_uv_write@Base 0.6.3 + jl_uv_write_handle@Base 0.6.3 + jl_uv_writecb@Base 0.6.3 + jl_value_ptr@Base 0.6.3 + jl_valueof@Base 0.6.3 + jl_vararg_type@Base 0.6.3 + jl_vararg_typename@Base 0.6.3 + jl_vecelement_typename@Base 0.6.3 + jl_ver_is_release@Base 0.6.3 + jl_ver_major@Base 0.6.3 + jl_ver_minor@Base 0.6.3 + jl_ver_patch@Base 0.6.3 + jl_ver_string@Base 0.6.3 + jl_void_type@Base 0.6.3 + jl_voidpointer_type@Base 0.6.3 + jl_vprintf@Base 0.6.3 + jl_weakref_type@Base 0.6.3 + jl_world_counter@Base 0.6.3 + jl_xor_int@Base 0.6.3 + jl_yield@Base 0.6.3 + jl_zext_int@Base 0.6.3 + jlbacktrace@Base 0.6.3 + julia_init__threading@Base 0.7.0~beta2 + julia_type_to_llvm@Base 0.6.3 + libsupport_init@Base 0.6.3 + memhash32@Base 0.6.3 + memhash32_seed@Base 0.6.3 + memhash@Base 0.6.3 + memhash_seed@Base 0.6.3 + u8_charnum@Base 0.6.3 + u8_isvalid@Base 0.6.3 + u8_offset@Base 0.6.3 + u8_strwidth@Base 0.6.3 + uv__accept4@Base 0.7.0~beta2 + uv__accept@Base 0.7.0~beta2 + uv__async_close@Base 0.7.0~beta2 + uv__async_stop@Base 0.7.0~beta2 + uv__calloc@Base 0.7.0~beta2 + uv__check_close@Base 0.7.0~beta2 + uv__cloexec_fcntl@Base 0.7.0~beta2 + uv__cloexec_ioctl@Base 0.7.0~beta2 + uv__close@Base 0.7.0~beta2 + uv__close_nocheckstdio@Base 0.7.0~beta2 + uv__count_bufs@Base 0.7.0~beta2 + uv__dup2_cloexec@Base 0.7.0~beta2 + uv__dup3@Base 0.7.0~beta2 + uv__dup@Base 0.7.0~beta2 + uv__epoll_create1@Base 0.7.0~beta2 + uv__epoll_create@Base 0.7.0~beta2 + uv__epoll_ctl@Base 0.7.0~beta2 + uv__epoll_pwait@Base 0.7.0~beta2 + uv__epoll_wait@Base 0.7.0~beta2 + uv__eventfd2@Base 0.7.0~beta2 + uv__eventfd@Base 0.7.0~beta2 + uv__free@Base 0.7.0~beta2 + uv__fs_event_close@Base 0.7.0~beta2 + uv__fs_poll_close@Base 0.7.0~beta2 + uv__fs_scandir_cleanup@Base 0.7.0~beta2 + uv__getaddrinfo_translate_error@Base 0.7.0~beta2 + uv__getiovmax@Base 0.7.0~beta2 + uv__getpwuid_r@Base 0.7.0~beta2 + uv__handle_type@Base 0.7.0~beta2 + uv__hrtime@Base 0.7.0~beta2 + uv__idle_close@Base 0.7.0~beta2 + uv__inotify_add_watch@Base 0.7.0~beta2 + uv__inotify_init1@Base 0.7.0~beta2 + uv__inotify_init@Base 0.7.0~beta2 + uv__inotify_rm_watch@Base 0.7.0~beta2 + uv__io_active@Base 0.7.0~beta2 + uv__io_check_fd@Base 0.7.0~beta2 + uv__io_close@Base 0.7.0~beta2 + uv__io_feed@Base 0.7.0~beta2 + uv__io_init@Base 0.7.0~beta2 + uv__io_poll@Base 0.7.0~beta2 + uv__io_start@Base 0.7.0~beta2 + uv__io_stop@Base 0.7.0~beta2 + uv__loop_close@Base 0.7.0~beta2 + uv__loop_configure@Base 0.7.0~beta2 + uv__make_close_pending@Base 0.7.0~beta2 + uv__make_pipe@Base 0.7.0~beta2 + uv__malloc@Base 0.7.0~beta2 + uv__next_timeout@Base 0.7.0~beta2 + uv__nonblock_fcntl@Base 0.7.0~beta2 + uv__nonblock_ioctl@Base 0.7.0~beta2 + uv__open_cloexec@Base 0.7.0~beta2 + uv__open_file@Base 0.7.0~beta2 + uv__pipe2@Base 0.7.0~beta2 + uv__pipe_close@Base 0.7.0~beta2 + uv__platform_invalidate_fd@Base 0.7.0~beta2 + uv__platform_loop_delete@Base 0.7.0~beta2 + uv__platform_loop_init@Base 0.7.0~beta2 + uv__poll_close@Base 0.7.0~beta2 + uv__preadv@Base 0.7.0~beta2 + uv__prepare_close@Base 0.7.0~beta2 + uv__process_close@Base 0.7.0~beta2 + uv__pwritev@Base 0.7.0~beta2 + uv__realloc@Base 0.7.0~beta2 + uv__recvmmsg@Base 0.7.0~beta2 + uv__recvmsg@Base 0.7.0~beta2 + uv__run_check@Base 0.7.0~beta2 + uv__run_idle@Base 0.7.0~beta2 + uv__run_prepare@Base 0.7.0~beta2 + uv__run_timers@Base 0.7.0~beta2 + uv__sendmmsg@Base 0.7.0~beta2 + uv__server_io@Base 0.7.0~beta2 + uv__set_process_title@Base 0.7.0~beta2 + uv__signal_close@Base 0.7.0~beta2 + uv__signal_global_once_init@Base 0.7.0~beta2 + uv__signal_loop_cleanup@Base 0.7.0~beta2 + uv__socket@Base 0.7.0~beta2 + uv__socket_sockopt@Base 0.7.0~beta2 + uv__strdup@Base 0.7.0~beta2 + uv__stream_close@Base 0.7.0~beta2 + uv__stream_destroy@Base 0.7.0~beta2 + uv__stream_flush_write_queue@Base 0.7.0~beta2 + uv__stream_init@Base 0.7.0~beta2 + uv__stream_open@Base 0.7.0~beta2 + uv__strndup@Base 0.7.0~beta2 + uv__tcp_bind@Base 0.7.0~beta2 + uv__tcp_close@Base 0.7.0~beta2 + uv__tcp_connect@Base 0.7.0~beta2 + uv__tcp_keepalive@Base 0.7.0~beta2 + uv__tcp_nodelay@Base 0.7.0~beta2 + uv__timer_close@Base 0.7.0~beta2 + uv__udp_bind@Base 0.7.0~beta2 + uv__udp_close@Base 0.7.0~beta2 + uv__udp_finish_close@Base 0.7.0~beta2 + uv__udp_recv_start@Base 0.7.0~beta2 + uv__udp_recv_stop@Base 0.7.0~beta2 + uv__udp_send@Base 0.7.0~beta2 + uv__udp_try_send@Base 0.7.0~beta2 + uv__utimesat@Base 0.7.0~beta2 + uv__work_done@Base 0.7.0~beta2 + uv__work_submit@Base 0.7.0~beta2 + uv_accept@Base 0.6.3 + uv_async_init@Base 0.6.3 + uv_async_send@Base 0.6.3 + uv_backend_fd@Base 0.6.3 + uv_backend_timeout@Base 0.6.3 + uv_barrier_destroy@Base 0.6.3 + uv_barrier_init@Base 0.6.3 + uv_barrier_wait@Base 0.6.3 + uv_buf_init@Base 0.6.3 + uv_cancel@Base 0.6.3 + uv_chdir@Base 0.6.3 + uv_check_init@Base 0.6.3 + uv_check_start@Base 0.6.3 + uv_check_stop@Base 0.6.3 + uv_close@Base 0.6.3 + uv_cond_broadcast@Base 0.6.3 + uv_cond_destroy@Base 0.6.3 + uv_cond_init@Base 0.6.3 + uv_cond_signal@Base 0.6.3 + uv_cond_timedwait@Base 0.6.3 + uv_cond_wait@Base 0.6.3 + uv_cpu_info@Base 0.6.3 + uv_cpumask_size@Base 0.7.0~beta2 + uv_cwd@Base 0.6.3 + uv_default_loop@Base 0.6.3 + uv_disable_stdio_inheritance@Base 0.6.3 + uv_dlclose@Base 0.6.3 + uv_dlerror@Base 0.6.3 + uv_dlopen@Base 0.6.3 + uv_dlsym@Base 0.6.3 + uv_err_name@Base 0.6.3 + uv_exepath@Base 0.6.3 + uv_fileno@Base 0.6.3 + uv_free_cpu_info@Base 0.6.3 + uv_free_interface_addresses@Base 0.6.3 + uv_freeaddrinfo@Base 0.6.3 + uv_fs_access@Base 0.6.3 + uv_fs_chmod@Base 0.6.3 + uv_fs_chown@Base 0.6.3 + uv_fs_close@Base 0.6.3 + uv_fs_event_getpath@Base 0.6.3 + uv_fs_event_init@Base 0.6.3 + uv_fs_event_start@Base 0.6.3 + uv_fs_event_stop@Base 0.6.3 + uv_fs_fchmod@Base 0.6.3 + uv_fs_fchown@Base 0.6.3 + uv_fs_fdatasync@Base 0.6.3 + uv_fs_fstat@Base 0.6.3 + uv_fs_fsync@Base 0.6.3 + uv_fs_ftruncate@Base 0.6.3 + uv_fs_futime@Base 0.6.3 + uv_fs_link@Base 0.6.3 + uv_fs_lstat@Base 0.6.3 + uv_fs_mkdir@Base 0.6.3 + uv_fs_mkdtemp@Base 0.6.3 + uv_fs_open@Base 0.6.3 + uv_fs_poll_getpath@Base 0.6.3 + uv_fs_poll_init@Base 0.6.3 + uv_fs_poll_start@Base 0.6.3 + uv_fs_poll_stop@Base 0.6.3 + uv_fs_read@Base 0.6.3 + uv_fs_readlink@Base 0.6.3 + uv_fs_realpath@Base 0.6.3 + uv_fs_rename@Base 0.6.3 + uv_fs_req_cleanup@Base 0.6.3 + uv_fs_rmdir@Base 0.6.3 + uv_fs_scandir@Base 0.6.3 + uv_fs_scandir_next@Base 0.6.3 + uv_fs_sendfile@Base 0.6.3 + uv_fs_stat@Base 0.6.3 + uv_fs_symlink@Base 0.6.3 + uv_fs_unlink@Base 0.6.3 + uv_fs_utime@Base 0.6.3 + uv_fs_write@Base 0.6.3 + uv_get_free_memory@Base 0.6.3 + uv_get_process_title@Base 0.6.3 + uv_get_total_memory@Base 0.6.3 + uv_getaddrinfo@Base 0.6.3 + uv_getnameinfo@Base 0.6.3 + uv_getrusage@Base 0.6.3 + uv_guess_handle@Base 0.6.3 + uv_handle_size@Base 0.6.3 + uv_has_ref@Base 0.6.3 + uv_hrtime@Base 0.6.3 + uv_idle_init@Base 0.6.3 + uv_idle_start@Base 0.6.3 + uv_idle_stop@Base 0.6.3 + uv_inet_ntop@Base 0.6.3 + uv_inet_pton@Base 0.6.3 + uv_interface_addresses@Base 0.6.3 + uv_ip4_addr@Base 0.6.3 + uv_ip4_name@Base 0.6.3 + uv_ip6_addr@Base 0.6.3 + uv_ip6_name@Base 0.6.3 + uv_is_active@Base 0.6.3 + uv_is_closing@Base 0.6.3 + uv_is_readable@Base 0.6.3 + uv_is_writable@Base 0.6.3 + uv_key_create@Base 0.6.3 + uv_key_delete@Base 0.6.3 + uv_key_get@Base 0.6.3 + uv_key_set@Base 0.6.3 + uv_kill@Base 0.6.3 + uv_listen@Base 0.6.3 + uv_loadavg@Base 0.6.3 + uv_loop_alive@Base 0.6.3 + uv_loop_close@Base 0.6.3 + uv_loop_configure@Base 0.6.3 + uv_loop_delete@Base 0.6.3 + uv_loop_init@Base 0.6.3 + uv_loop_new@Base 0.6.3 + uv_loop_size@Base 0.6.3 + uv_mutex_destroy@Base 0.6.3 + uv_mutex_init@Base 0.6.3 + uv_mutex_lock@Base 0.6.3 + uv_mutex_trylock@Base 0.6.3 + uv_mutex_unlock@Base 0.6.3 + uv_now@Base 0.6.3 + uv_once@Base 0.6.3 + uv_os_free_passwd@Base 0.6.3 + uv_os_get_passwd@Base 0.6.3 + uv_os_getenv@Base 0.7.0~beta2 + uv_os_gethostname@Base 0.7.0~beta2 + uv_os_homedir@Base 0.6.3 + uv_os_setenv@Base 0.7.0~beta2 + uv_os_tmpdir@Base 0.6.3 + uv_os_unsetenv@Base 0.7.0~beta2 + uv_pipe@Base 0.7.0~beta2 + uv_pipe_bind@Base 0.6.3 + uv_pipe_connect@Base 0.6.3 + uv_pipe_getpeername@Base 0.6.3 + uv_pipe_getsockname@Base 0.6.3 + uv_pipe_init@Base 0.6.3 + uv_pipe_listen@Base 0.7.0~beta2 + uv_pipe_open@Base 0.6.3 + uv_pipe_pending_count@Base 0.6.3 + uv_pipe_pending_instances@Base 0.6.3 + uv_pipe_pending_type@Base 0.6.3 + uv_poll_init@Base 0.6.3 + uv_poll_start@Base 0.6.3 + uv_poll_stop@Base 0.6.3 + uv_prepare_init@Base 0.6.3 + uv_prepare_start@Base 0.6.3 + uv_prepare_stop@Base 0.6.3 + uv_print_active_handles@Base 0.6.3 + uv_print_all_handles@Base 0.6.3 + uv_process_kill@Base 0.6.3 + uv_queue_work@Base 0.6.3 + uv_read_start@Base 0.6.3 + uv_read_stop@Base 0.6.3 + uv_recv_buffer_size@Base 0.6.3 + uv_ref@Base 0.6.3 + uv_replace_allocator@Base 0.6.3 + uv_req_size@Base 0.6.3 + uv_resident_set_memory@Base 0.6.3 + uv_run@Base 0.6.3 + uv_rwlock_destroy@Base 0.6.3 + uv_rwlock_init@Base 0.6.3 + uv_rwlock_rdlock@Base 0.6.3 + uv_rwlock_rdunlock@Base 0.6.3 + uv_rwlock_tryrdlock@Base 0.6.3 + uv_rwlock_trywrlock@Base 0.6.3 + uv_rwlock_wrlock@Base 0.6.3 + uv_rwlock_wrunlock@Base 0.6.3 + uv_sem_destroy@Base 0.6.3 + uv_sem_init@Base 0.6.3 + uv_sem_post@Base 0.6.3 + uv_sem_trywait@Base 0.6.3 + uv_sem_wait@Base 0.6.3 + uv_send_buffer_size@Base 0.6.3 + uv_set_process_title@Base 0.6.3 + uv_setup_args@Base 0.6.3 + uv_shutdown@Base 0.6.3 + uv_signal_init@Base 0.6.3 + uv_signal_start@Base 0.6.3 + uv_signal_start_oneshot@Base 0.7.0~beta2 + uv_signal_stop@Base 0.6.3 + uv_socketpair@Base 0.7.0~beta2 + uv_spawn@Base 0.6.3 + uv_stop@Base 0.6.3 + uv_stream_set_blocking@Base 0.6.3 + uv_strerror@Base 0.6.3 + uv_tcp_bind@Base 0.6.3 + uv_tcp_connect@Base 0.6.3 + uv_tcp_getpeername@Base 0.6.3 + uv_tcp_getsockname@Base 0.6.3 + uv_tcp_init@Base 0.6.3 + uv_tcp_init_ex@Base 0.6.3 + uv_tcp_keepalive@Base 0.6.3 + uv_tcp_listen@Base 0.7.0~beta2 + uv_tcp_nodelay@Base 0.6.3 + uv_tcp_open@Base 0.6.3 + uv_tcp_simultaneous_accepts@Base 0.6.3 + uv_thread_create@Base 0.6.3 + uv_thread_detach@Base 0.6.3 + uv_thread_equal@Base 0.6.3 + uv_thread_getaffinity@Base 0.6.3 + uv_thread_join@Base 0.6.3 + uv_thread_self@Base 0.6.3 + uv_thread_setaffinity@Base 0.6.3 + uv_timer_again@Base 0.6.3 + uv_timer_get_repeat@Base 0.6.3 + uv_timer_init@Base 0.6.3 + uv_timer_set_repeat@Base 0.6.3 + uv_timer_start@Base 0.6.3 + uv_timer_stop@Base 0.6.3 + uv_translate_sys_error@Base 0.7.0~beta2 + uv_try_write@Base 0.6.3 + uv_try_write_cb@Base 0.7.0~beta2 + uv_tty_get_winsize@Base 0.6.3 + uv_tty_init@Base 0.6.3 + uv_tty_reset_mode@Base 0.6.3 + uv_tty_set_mode@Base 0.6.3 + uv_udp_bind@Base 0.6.3 + uv_udp_getsockname@Base 0.6.3 + uv_udp_init@Base 0.6.3 + uv_udp_init_ex@Base 0.6.3 + uv_udp_open@Base 0.6.3 + uv_udp_recv_start@Base 0.6.3 + uv_udp_recv_stop@Base 0.6.3 + uv_udp_send@Base 0.6.3 + uv_udp_set_broadcast@Base 0.6.3 + uv_udp_set_membership@Base 0.6.3 + uv_udp_set_multicast_interface@Base 0.6.3 + uv_udp_set_multicast_loop@Base 0.6.3 + uv_udp_set_multicast_ttl@Base 0.6.3 + uv_udp_set_ttl@Base 0.6.3 + uv_udp_try_send@Base 0.6.3 + uv_unref@Base 0.6.3 + uv_update_time@Base 0.6.3 + uv_uptime@Base 0.6.3 + uv_version@Base 0.6.3 + uv_version_string@Base 0.6.3 + uv_walk@Base 0.6.3 + uv_write2@Base 0.6.3 + uv_write@Base 0.6.3 diff --git a/libjulia1.triggers b/libjulia1.triggers new file mode 100644 index 0000000..dd86603 --- /dev/null +++ b/libjulia1.triggers @@ -0,0 +1 @@ +activate-noawait ldconfig diff --git a/not-installed b/not-installed new file mode 100644 index 0000000..e799388 --- /dev/null +++ b/not-installed @@ -0,0 +1 @@ +usr/share/doc/julia/html/* diff --git a/patches/appstream.patch b/patches/appstream.patch new file mode 100644 index 0000000..3055270 --- /dev/null +++ b/patches/appstream.patch @@ -0,0 +1,41 @@ +Description: lintian error due to ancient version of metadata format +Reference: https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html +Created-by: Mo Zhou +Last-Update: 2018-08-16 +Forwarded: [Merged] https://github.com/JuliaLang/julia/pull/28020 + +Index: julia/contrib/julia.appdata.xml +=================================================================== +--- julia.orig/contrib/julia.appdata.xml ++++ julia/contrib/julia.appdata.xml +@@ -1,9 +1,15 @@ + <?xml version="1.0" encoding="UTF-8"?> + <!-- Copyright 2014 Paul Lange <palango@gmx.de> --> +-<application> +- <id type="desktop">julia.desktop</id> ++<component> ++ <id>org.julialang.julia</id> ++ <name>Julia</name> ++ <launchable type="desktop-id">julia.desktop</launchable> + <metadata_license>CC-BY-SA-3.0</metadata_license> + <project_license>MIT and LGPL-2.1+ and GPL-2.0+</project_license> ++ <summary>High-performance programming language for technical computing</summary> ++ <provides> ++ <binary>julia</binary> ++ </provides> + <description> + <p> + Julia is a high-level, high-performance dynamic programming language for +@@ -21,8 +27,9 @@ + </p> + </description> + <screenshots> +- <screenshot type="default">https://julialang.org/images/julia-gnome.png</screenshot> ++ <screenshot type="default"> ++ <image>https://julialang.org/images/julia-gnome.png</image> ++ </screenshot> + </screenshots> + <url type="homepage">https://julialang.org/</url> +- <updatecontact>julia-dev@googlegroups.com</updatecontact> +-</application> ++</component> diff --git a/patches/default-load-path-distro.patch b/patches/default-load-path-distro.patch new file mode 100644 index 0000000..612bba4 --- /dev/null +++ b/patches/default-load-path-distro.patch @@ -0,0 +1,26 @@ +Description: enable distro julia packages so that they are immediately importable after install +See: https://github.com/cdluminate/DistroHelper.jl + https://github.com/JuliaLang/julia/issues/30528 +Author: Mo Zhou + +diff --git a/base/initdefs.jl b/base/initdefs.jl +index f95c22b4..e63d395b 100644 +--- a/base/initdefs.jl ++++ b/base/initdefs.jl +@@ -61,6 +61,7 @@ end + # entries starting with `@` are named environments: + # - the first three `#`s in a named environment are replaced with version numbers + # - `@stdlib` is a special name for the standard library and expands to its path ++# - `@distro` is a special name for distributions' vendored julia packages + + # if you want a current env setup, use direnv and + # have your .envrc do something like this: +@@ -70,7 +71,7 @@ end + # this will inherit an existing JULIA_LOAD_PATH value or if there is none, leave + # a trailing empty entry in JULIA_LOAD_PATH which will be replaced with defaults. + +-const DEFAULT_LOAD_PATH = ["@", "@v#.#", "@stdlib"] ++const DEFAULT_LOAD_PATH = ["@", "@v#.#", "@stdlib", "@distro"] + + """ + LOAD_PATH diff --git a/patches/do-not-download-libuv.patch b/patches/do-not-download-libuv.patch new file mode 100644 index 0000000..cd81c44 --- /dev/null +++ b/patches/do-not-download-libuv.patch @@ -0,0 +1,17 @@ +Description: Let it download the embedded source tarball through a file:// URI +Author: Mo Zhou +Last-Update: 20180711 +Forward: no need + +Index: julia/deps/libuv.mk +=================================================================== +--- julia.orig/deps/libuv.mk ++++ julia/deps/libuv.mk +@@ -1,6 +1,5 @@ + ## LIBUV ## +-LIBUV_GIT_URL:=git://github.com/JuliaLang/libuv.git +-LIBUV_TAR_URL=https://api.github.com/repos/JuliaLang/libuv/tarball/$1 ++LIBUV_TAR_URL=file://$(CURDIR)/../debian/embedded/libuv-$1.tar.gz + $(eval $(call git-external,libuv,LIBUV,configure,,$(SRCCACHE))) + + UV_CFLAGS := -D_GNU_SOURCE diff --git a/patches/do-not-download-libwhich.patch b/patches/do-not-download-libwhich.patch new file mode 100644 index 0000000..8e6de14 --- /dev/null +++ b/patches/do-not-download-libwhich.patch @@ -0,0 +1,16 @@ +Description: prevent upstream build system from accessing internet +Author: Mo Zhou +Forwarded: no need +Last-Update: 20180719 +Index: julia/deps/libwhich.mk +=================================================================== +--- julia.orig/deps/libwhich.mk ++++ julia/deps/libwhich.mk +@@ -1,6 +1,5 @@ + ## LIBWHICH ## +-LIBWHICH_GIT_URL := git://github.com/vtjnash/libwhich.git +-LIBWHICH_TAR_URL = https://api.github.com/repos/vtjnash/libwhich/tarball/$1 ++LIBWHICH_TAR_URL = file://$(CURDIR)/../debian/embedded/libwhich-$1.tar.gz + $(eval $(call git-external,libwhich,LIBWHICH,,,$(BUILDDIR))) + + LIBWHICH_OBJ_LIB := $(build_depsbindir)/libwhich diff --git a/patches/do-not-download-llvm.patch b/patches/do-not-download-llvm.patch new file mode 100644 index 0000000..3e8ea05 --- /dev/null +++ b/patches/do-not-download-llvm.patch @@ -0,0 +1,13 @@ +Index: julia/deps/llvm.mk +=================================================================== +--- julia.orig/deps/llvm.mk ++++ julia/deps/llvm.mk +@@ -161,7 +161,7 @@ ifeq ($(BUILD_LLDB),0) + LLVM_CMAKE += -DLLVM_TOOL_LLDB_BUILD=OFF + endif + +-LLVM_SRC_URL := http://releases.llvm.org/$(LLVM_VER) ++LLVM_SRC_URL := file://$(shell pwd)/../debian/embedded/$(LLVM_VER) + + ifneq ($(LLVM_CLANG_TAR),) + $(LLVM_CLANG_TAR): | $(SRCCACHE) diff --git a/patches/do-not-download-pkgjl.patch b/patches/do-not-download-pkgjl.patch new file mode 100644 index 0000000..0d58665 --- /dev/null +++ b/patches/do-not-download-pkgjl.patch @@ -0,0 +1,16 @@ +Description: Prevent upstream build system from downloading Pkg.jl +Forward: no need +Author: Mo Zhou +Index: julia/stdlib/Makefile +=================================================================== +--- julia.orig/stdlib/Makefile ++++ julia/stdlib/Makefile +@@ -22,7 +22,7 @@ STDLIBS-EXT = Pkg + + # Download and extract Pkg + PKG_GIT_URL := git://github.com/JuliaLang/Pkg.jl.git +-PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 ++PKG_TAR_URL = file://$(CURDIR)/../debian/embedded/$1 + $(eval $(call git-external,Pkg,PKG,,,$(BUILDDIR))) + $(BUILDDIR)/$(PKG_SRC_DIR)/build-compiled: $(BUILDDIR)/$(PKG_SRC_DIR)/source-extracted + @# no build steps diff --git a/patches/doc-make.patch b/patches/doc-make.patch new file mode 100644 index 0000000..8c640a5 --- /dev/null +++ b/patches/doc-make.patch @@ -0,0 +1,43 @@ +Description: Prevent the build system from downloading anything while building docs. +Forwarded: no need. +Author: Mo Zhou +Last-Update: 2018-07-03 + +Index: julia/doc/make.jl +=================================================================== +--- julia.orig/doc/make.jl ++++ julia/doc/make.jl +@@ -3,8 +3,7 @@ empty!(LOAD_PATH) + push!(LOAD_PATH, @__DIR__, "@stdlib") + empty!(DEPOT_PATH) + pushfirst!(DEPOT_PATH, joinpath(@__DIR__, "deps")) +-using Pkg +-Pkg.instantiate() ++push!(LOAD_PATH, "../debian/embedded") + + using Documenter + +Index: julia/doc/Makefile +=================================================================== +--- julia.orig/doc/Makefile ++++ julia/doc/Makefile +@@ -23,10 +23,8 @@ help: + DOCUMENTER_OPTIONS := linkcheck=$(linkcheck) doctest=$(doctest) buildroot=$(call cygpath_w,$(BUILDROOT)) + + UnicodeData.txt: +- $(JLDOWNLOAD) http://www.unicode.org/Public/9.0.0/ucd/UnicodeData.txt +- +-deps: UnicodeData.txt +- $(JLCHECKSUM) UnicodeData.txt ++deps: ++ true + + clean: + -rm -rf _build/* deps/* docbuild.log UnicodeData.txt +Index: julia/doc/Project.toml +=================================================================== +--- julia.orig/doc/Project.toml ++++ julia/doc/Project.toml +@@ -1,2 +0,0 @@ +-[deps] +-Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" diff --git a/patches/doc-silent.patch b/patches/doc-silent.patch new file mode 100644 index 0000000..8aee92f --- /dev/null +++ b/patches/doc-silent.patch @@ -0,0 +1,27 @@ +diff --git a/debian/embedded/Documenter.jl-0.20.0/src/Writers/LaTeXWriter.jl b/debian/embedded/Documenter.jl-0.20.0/src/Writers/LaTeXWriter.jl +index f442d959..51ce92e7 100644 +--- a/debian/embedded/Documenter.jl-0.20.0/src/Writers/LaTeXWriter.jl ++++ b/debian/embedded/Documenter.jl-0.20.0/src/Writers/LaTeXWriter.jl +@@ -87,7 +87,7 @@ function render(doc::Documents.Document) + outdir = joinpath(doc.user.root, doc.user.build) + pdf = replace("$(doc.user.sitename).pdf", " " => "") + try +- run(`latexmk -f -interaction=nonstopmode -view=none -lualatex -shell-escape $file`) ++ run(`latexmk -silent -f -interaction=nonstopmode -view=none -lualatex -shell-escape $file`) + catch err + Utilities.warn("failed to compile. Check generated LaTeX file.") + cp(file, joinpath(outdir, file); force = true) + +diff --git a/debian/embedded/Documenter.jl-0.21.0/src/Writers/LaTeXWriter.jl b/debian/embedded/Documenter.jl-0.21.0/src/Writers/LaTeXWriter.jl +index 9b98b34e..21727866 100644 +--- a/debian/embedded/Documenter.jl-0.21.0/src/Writers/LaTeXWriter.jl ++++ b/debian/embedded/Documenter.jl-0.21.0/src/Writers/LaTeXWriter.jl +@@ -139,7 +139,7 @@ function compile_tex(doc::Documents.Document, settings::LaTeX, texfile::String) + Sys.which("latexmk") === nothing && (@error "LaTeXWriter: latexmk command not found."; return false) + @info "LaTeXWriter: using latexmk to compile tex." + try +- piperun(`latexmk -f -interaction=nonstopmode -view=none -lualatex -shell-escape $texfile`) ++ piperun(`latexmk -silent -f -interaction=nonstopmode -view=none -lualatex -shell-escape $texfile`) + return true + catch err + logs = cp(pwd(), mktempdir(); force=true) diff --git a/patches/doc-unicode-data-path.patch b/patches/doc-unicode-data-path.patch new file mode 100644 index 0000000..30caa21 --- /dev/null +++ b/patches/doc-unicode-data-path.patch @@ -0,0 +1,17 @@ +Description: build documentation using Debian's unicode data, + instead of a downloaded one +Forwarded: no need +Author: Mo Zhou +Index: julia/doc/src/manual/unicode-input.md +=================================================================== +--- julia.orig/doc/src/manual/unicode-input.md ++++ julia/doc/src/manual/unicode-input.md +@@ -31,7 +31,7 @@ function tab_completions(symbols...) + end + + function unicode_data() +- file = normpath(@__DIR__, "..", "..", "..", "..", "..", "doc", "UnicodeData.txt") ++ file = "/usr/share/unicode/UnicodeData.txt" + names = Dict{UInt32, String}() + open(file) do unidata + for line in readlines(unidata) diff --git a/patches/install-embedded-llvm-hack.patch b/patches/install-embedded-llvm-hack.patch new file mode 100644 index 0000000..4dbc121 --- /dev/null +++ b/patches/install-embedded-llvm-hack.patch @@ -0,0 +1,18 @@ +Description: LLVM's cmake doesn't install stuff to multiarch directory, which + breaks julia installation when MULTIARCH* options in Make.inc is turned on. + This hacky solution aims to workaround installation failure. +See: https://github.com/JuliaLang/julia/issues/27922 +Forward: no need +Author: Mo Zhou +Index: julia/deps/llvm.mk +=================================================================== +--- julia.orig/deps/llvm.mk ++++ julia/deps/llvm.mk +@@ -560,6 +560,7 @@ ifeq ($(OS),Darwin) + # https://github.com/JuliaLang/julia/issues/29981 + LLVM_INSTALL += && ln -s libLLVM.dylib $2$$(build_shlibdir)/libLLVM-$$(LLVM_VER_SHORT).dylib + endif ++LLVM_INSTALL += && find $2 -type f,l -name 'libLLVM*so*' -print -exec install -Dv '{}' $(shell pwd)/../$$(libdir)/julia/ \; + + $(eval $(call staged-install,llvm,llvm-$$(LLVM_VER)/build_$$(LLVM_BUILDTYPE), \ + LLVM_INSTALL,,,)) diff --git a/patches/install-julia-hack.patch b/patches/install-julia-hack.patch new file mode 100644 index 0000000..830f08c --- /dev/null +++ b/patches/install-julia-hack.patch @@ -0,0 +1,16 @@ +If DESTDIR is defined in d/rules, embedded LLVM installation would break. +If DESTDIR is not defined in d/rules, embedded LLVM installation works, but Julia breaks. +This hack makes both LLVM and Julia happy. + +Index: julia/Makefile +=================================================================== +--- julia.orig/Makefile ++++ julia/Makefile +@@ -328,6 +328,7 @@ JL_PRIVATE_LIBS-0 += libgfortran libgcc_ + endif + + ++override DESTDIR=./debian/tmp/ + install: $(build_depsbindir)/stringreplace $(BUILDROOT)/doc/_build/html/en/index.html + @$(MAKE) $(QUIET_MAKE) all + @for subdir in $(bindir) $(datarootdir)/julia/stdlib/$(VERSDIR) $(docdir) $(man1dir) $(includedir)/julia $(libdir) $(private_libdir) $(sysconfdir); do \ diff --git a/patches/jldownload-verbose-fakedownload.patch b/patches/jldownload-verbose-fakedownload.patch new file mode 100644 index 0000000..bb36464 --- /dev/null +++ b/patches/jldownload-verbose-fakedownload.patch @@ -0,0 +1,25 @@ +Description: Let the upstream downloader used during build be verbose, + and prevent it from accessing internet. +Author: Mo Zhou +Last-Update: 20180711 +Forwarded: no need + +Index: julia/deps/tools/jldownload +=================================================================== +--- julia.orig/deps/tools/jldownload ++++ julia/deps/tools/jldownload +@@ -2,6 +2,7 @@ + # + # usage: jldownload [<output-filename>] <url> + # ++set -x + + CACHE_HOST=https://cache.julialang.org + +@@ -44,4 +45,5 @@ fi + # forward to the original URL if it has not cached this download yet, or + # if the URL is not cacheable. We fallback to directly querying the + # uncached URL to protect against cache service downtime +-$GETURL $CACHE_URL || $GETURL $URL ++#$GETURL $CACHE_URL || $GETURL $URL ++$GETURL $URL diff --git a/patches/llvm-armhf-baseline.patch b/patches/llvm-armhf-baseline.patch new file mode 100644 index 0000000..5f2081e --- /dev/null +++ b/patches/llvm-armhf-baseline.patch @@ -0,0 +1,43 @@ +Description: Avoid baseline violation on armhf +Forwarded: not-yet +Bug-Debian: https://bugs.debian.org/919183 +Author: Graham Inggs <ginggs@debian.org> +Last-Update: 2018-01-22 + +--- a/deps/llvm.mk ++++ b/deps/llvm.mk +@@ -508,6 +508,7 @@ + $(eval $(call LLVM_PATCH,llvm-D50167-scev-umin)) + $(eval $(call LLVM_PATCH,llvm-windows-race)) + $(eval $(call LLVM_PATCH,llvm-rL326967-aligned-load)) # remove for 7.0 ++$(eval $(call LLVM_PATCH,clang-arm-default-vfp3-on-armv7a)) + endif # LLVM_VER + + # Remove hardcoded OS X requirements in compilter-rt cmake build +--- /dev/null ++++ b/deps/patches/clang-arm-default-vfp3-on-armv7a.patch +@@ -0,0 +1,24 @@ ++--- a/include/llvm/Support/ARMTargetParser.def +++++ b/include/llvm/Support/ARMTargetParser.def ++@@ -75,7 +75,7 @@ ARM_ARCH("armv6kz", ARMV6KZ, "6KZ", "v6k ++ ARM_ARCH("armv6-m", ARMV6M, "6-M", "v6m", ARMBuildAttrs::CPUArch::v6_M, ++ FK_NONE, ARM::AEK_NONE) ++ ARM_ARCH("armv7-a", ARMV7A, "7-A", "v7", ARMBuildAttrs::CPUArch::v7, ++- FK_NEON, ARM::AEK_DSP) +++ FK_VFPV3_D16, ARM::AEK_DSP) ++ ARM_ARCH("armv7ve", ARMV7VE, "7VE", "v7ve", ARMBuildAttrs::CPUArch::v7, ++ FK_NEON, (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ++ ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP)) ++--- a/lib/Target/ARM/ARM.td +++++ b/lib/Target/ARM/ARM.td ++@@ -530,7 +530,8 @@ def ARMv6sm : Architecture<"armv6s-m", ++ FeatureMClass]>; ++ ++ def ARMv7a : Architecture<"armv7-a", "ARMv7a", [HasV7Ops, ++- FeatureNEON, +++ FeatureVFP3, +++ FeatureD16, ++ FeatureDB, ++ FeatureDSP, ++ FeatureAClass]>; ++ diff --git a/patches/make-unwind-logic-error.patch b/patches/make-unwind-logic-error.patch new file mode 100644 index 0000000..e441fa3 --- /dev/null +++ b/patches/make-unwind-logic-error.patch @@ -0,0 +1,16 @@ +Description: don't try to touch libunwind when it's disabled +Author: Mo Zhou +Forwarded: https://github.com/JuliaLang/julia/issues/29163 +Index: julia/base/Makefile +=================================================================== +--- julia.orig/base/Makefile ++++ julia/base/Makefile +@@ -192,7 +192,7 @@ $(eval $(call symlink_system_library,lib + $(eval $(call symlink_system_library,libumfpack,SUITESPARSE)) + $(eval $(call symlink_system_library,libspqr,SUITESPARSE)) + $(eval $(call symlink_system_library,libsuitesparseconfig,SUITESPARSE)) +-ifneq ($(DISABLE_LIBUNWIND),0) ++ifneq ($(DISABLE_LIBUNWIND), 1) + $(eval $(call symlink_system_library,libunwind,LIBUNWIND)) + endif + endif # WINNT diff --git a/patches/no-debug-version.patch b/patches/no-debug-version.patch new file mode 100644 index 0000000..dd362e5 --- /dev/null +++ b/patches/no-debug-version.patch @@ -0,0 +1,20 @@ +Description: Do not compile and install the debugging version of Julia +Author: Sébastien Villemot <sebastien@debian.org> +Author: Mo Zhou <cdluminate@gmail.com> +Forwarded: not-needed +Last-Update: 2018-07-19 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: julia/Makefile +=================================================================== +--- julia.orig/Makefile ++++ julia/Makefile +@@ -4,7 +4,7 @@ include $(JULIAHOME)/Make.inc + VERSDIR := v`cut -d. -f1-2 < $(JULIAHOME)/VERSION` + + default: $(JULIA_BUILD_MODE) # contains either "debug" or "release" +-all: debug release ++all: release + + # sort is used to remove potential duplicates + DIRS := $(sort $(build_bindir) $(build_depsbindir) $(build_libdir) $(build_private_libdir) $(build_libexecdir) $(build_includedir) $(build_includedir)/julia $(build_sysconfdir)/julia $(build_datarootdir)/julia $(build_datarootdir)/julia/stdlib $(build_man1dir)) diff --git a/patches/privacy-breach.patch b/patches/privacy-breach.patch new file mode 100644 index 0000000..0b6106f --- /dev/null +++ b/patches/privacy-breach.patch @@ -0,0 +1,59 @@ +Purpose: fix lintian error caused by embedded documenter +Author: Mo Zhou <cdluminate@gmail.com> + +--- a/debian/embedded/Documenter/assets/html/documenter.css ++++ b/debian/embedded/Documenter/assets/html/documenter.css +@@ -21,7 +21,7 @@ body, input { + } + + pre, code, kbd { +- font-family: 'Roboto Mono', Monaco, courier, monospace; ++ font-family: Inconsolata, Monaco, courier, monospace; + font-size: 0.90em; + } + +--- a/debian/embedded/Documenter/assets/html/documenter.js ++++ b/debian/embedded/Documenter/assets/html/documenter.js +@@ -7,13 +7,14 @@ + + requirejs.config({ + paths: { +- 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min', +- 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min', +- 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.9.3/headroom.min', +- 'mathjax': 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_HTML', +- 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min', +- 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/julia.min', +- 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/julia-repl.min', ++ 'jquery': 'file:///usr/share/javascript/jquery/jquery.min.js', ++ 'jqueryui': 'file:///usr/share/javascript/jquery-ui/jquery-ui.min.js', ++ //'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.9.3/headroom.min', ++ 'headroom': 'http://localhost', ++ 'mathjax': 'file:///usr/share/javascript/mathjax/MathJax.js?config=TeX-AMS_HTML', ++ 'highlight': 'file:///usr/lib/nodejs/highlight.js/highlight.js', ++ 'highlight-julia': 'file:////usr/lib/nodejs/highlight.js/languages/julia.js', ++ 'highlight-julia-repl': 'file:////usr/lib/nodejs/highlight.js/languages/julia-repl.js', + }, + shim: { + 'mathjax' : { + +--- a/debian/embedded/Documenter/src/Writers/HTMLWriter.jl ++++ b/debian/embedded/Documenter/src/Writers/HTMLWriter.jl +@@ -98,11 +98,12 @@ import ...Documenter: + import ...Utilities.DOM: DOM, Tag, @tags + using ...Utilities.MDFlatten + +-const requirejs_cdn = "https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.min.js" +-const normalize_css = "https://cdnjs.cloudflare.com/ajax/libs/normalize/4.2.0/normalize.min.css" +-const google_fonts = "https://fonts.googleapis.com/css?family=Lato|Roboto+Mono" +-const fontawesome_css = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" +-const highlightjs_css = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css" ++const requirejs_cdn = "file:///usr/share/javascript/requirejs/require.min.js" ++const normalize_css = "file:///usr/share/javascript/normalize.css/normalize.min.css" ++const google_fonts = "file:///usr/share/doc/julia-doc/fontface.css" ++const fontawesome_css = "file:///usr/share/fonts-font-awesome/css/font-awesome.min.css" ++const highlightjs_css = "file:///usr/share/javascript/highlight.js/styles/default.css" ++ + + """ + [`HTMLWriter`](@ref)-specific globals that are passed to [`domify`](@ref) and diff --git a/patches/require-sse2-on-i386.patch b/patches/require-sse2-on-i386.patch new file mode 100644 index 0000000..9aa36ee --- /dev/null +++ b/patches/require-sse2-on-i386.patch @@ -0,0 +1,42 @@ +Description: Julia requires SSE2 on i386 + This patch adds an explicit error message if the CPU does not support SSE2. + The CPU features are queried using the x86 CPUID opcode. The wrapper function + __get_cpuid() is provided by GCC and Clang. See <cpuid.h> for the list of + supported CPU extension flags. +Author: Sébastien Villemot <sebastien@debian.org> +Author: Peter Colberg <peter@colberg.org> +Bug: https://github.com/JuliaLang/julia/issues/7185 +Forwarded: no +Last-Update: 2015-11-01 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: julia/src/codegen.cpp +=================================================================== +--- julia.orig/src/codegen.cpp ++++ julia/src/codegen.cpp +@@ -26,6 +26,9 @@ + #endif + + #include <setjmp.h> ++#ifdef __i386__ ++#include <cpuid.h> ++#endif + #include <string> + #include <sstream> + #include <fstream> +@@ -7378,6 +7381,15 @@ static void init_julia_llvm_env(Module * + + extern "C" void *jl_init_llvm(void) + { ++#ifdef __i386__ ++ unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0; ++ __get_cpuid(1, &eax, &ebx, &ecx, &edx); ++ if (!(edx & bit_SSE2)) { ++ fprintf(stderr, "Your processor does not have SSE2 extension, which is required by Julia. Exiting.\n"); ++ exit(EXIT_FAILURE); ++ } ++#endif ++ + const char *const argv_tailmerge[] = {"", "-enable-tail-merge=0"}; // NOO TOUCHIE; NO TOUCH! See #922 + cl::ParseCommandLineOptions(sizeof(argv_tailmerge)/sizeof(argv_tailmerge[0]), argv_tailmerge, "disable-tail-merge\n"); + #if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_) diff --git a/patches/series b/patches/series new file mode 100644 index 0000000..e0beeff --- /dev/null +++ b/patches/series @@ -0,0 +1,31 @@ +# Build system and feature +jldownload-verbose-fakedownload.patch +support-noopt.patch +require-sse2-on-i386.patch +no-debug-version.patch +do-not-download-libuv.patch +do-not-download-libwhich.patch +do-not-download-pkgjl.patch +do-not-download-llvm.patch +doc-make.patch +doc-unicode-data-path.patch +make-unwind-logic-error.patch +install-embedded-llvm-hack.patch +install-julia-hack.patch +llvm-armhf-baseline.patch + +# distro integration, wip, experimental, disabled by default +#default-load-path-distro.patch + +# Misc enhancement +appstream.patch + +# Test +test-skip-sigint.patch +test-skip-i386-spec.patch +test-skip-dns-ubuntu.patch + + +# This patch is for embedded sources. Already pre-applied. +# privacy-breach.patch +# doc-silent.patch diff --git a/patches/support-noopt.patch b/patches/support-noopt.patch new file mode 100644 index 0000000..af8cfd3 --- /dev/null +++ b/patches/support-noopt.patch @@ -0,0 +1,50 @@ +Description: Remove hardcoded GCC optimization flags + This is necessary in order to make DEB_BUILD_OPTIONS=noopt work as expected. + . + Note that the hack on llvm-config --cxxflags is not absolutely needed, because + the -O2 that it brings come before the -O0 brought by dpkg-buildflags. But I + leave it for clarity. +Author: Sébastien Villemot <sebastien@debian.org> +Forwarded: not-needed +Last-Update: 2015-11-17 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: julia/Make.inc +=================================================================== +--- julia.orig/Make.inc ++++ julia/Make.inc +@@ -413,7 +413,7 @@ ifneq ($(OS), WINNT) + JCXXFLAGS += -pedantic + endif + DEBUGFLAGS := -O0 -ggdb2 -DJL_DEBUG_BUILD -fstack-protector-all +-SHIPFLAGS := -O3 -ggdb2 -falign-functions ++SHIPFLAGS := -ggdb2 -falign-functions + endif + + ifeq ($(USECLANG),1) +Index: julia/deps/suitesparse.mk +=================================================================== +--- julia.orig/deps/suitesparse.mk ++++ julia/deps/suitesparse.mk +@@ -111,7 +111,7 @@ endif + + $(build_shlibdir)/libsuitesparse_wrapper.$(SHLIB_EXT): $(SRCDIR)/SuiteSparse_wrapper.c + mkdir -p $(build_shlibdir) +- $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -O2 -shared $(fPIC) $(SUITESPARSE_INC) $< -o $@ $(SUITESPARSE_LIB) ++ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared $(fPIC) $(SUITESPARSE_INC) $< -o $@ $(SUITESPARSE_LIB) + $(INSTALL_NAME_CMD)libsuitesparse_wrapper.$(SHLIB_EXT) $@ + touch -c $@ + +Index: julia/src/Makefile +=================================================================== +--- julia.orig/src/Makefile ++++ julia/src/Makefile +@@ -136,7 +136,7 @@ $(BUILDDIR)/%.o: $(SRCDIR)/%.c $(HEADERS + $(BUILDDIR)/%.dbg.obj: $(SRCDIR)/%.c $(HEADERS) | $(BUILDDIR) + @$(call PRINT_CC, $(CC) $(CPPFLAGS) $(CFLAGS) $(DEBUGFLAGS) -c $< -o $@) + $(BUILDDIR)/%.o: $(SRCDIR)/%.cpp $(SRCDIR)/llvm-version.h $(HEADERS) $(LLVM_CONFIG_ABSOLUTE) | $(BUILDDIR) +- @$(call PRINT_CC, $(CXX) $(shell $(LLVM_CONFIG_HOST) --cxxflags) $(CPPFLAGS) $(CXXFLAGS) $(SHIPFLAGS) $(CXX_DISABLE_ASSERTION) -c $< -o $@) ++ @$(call PRINT_CC, $(CXX) $(shell $(LLVM_CONFIG_HOST) --cxxflags | sed 's/^/ /;s/$$/ /;s/\s-O.\s/ /') $(CPPFLAGS) $(CXXFLAGS) $(SHIPFLAGS) $(CXX_DISABLE_ASSERTION) -c $< -o $@) + $(BUILDDIR)/%.dbg.obj: $(SRCDIR)/%.cpp $(SRCDIR)/llvm-version.h $(HEADERS) $(LLVM_CONFIG_ABSOLUTE) | $(BUILDDIR) + @$(call PRINT_CC, $(CXX) $(shell $(LLVM_CONFIG_HOST) --cxxflags) $(CPPFLAGS) $(CXXFLAGS) $(DEBUGFLAGS) -c $< -o $@) + diff --git a/patches/test-skip-dns-ubuntu.patch b/patches/test-skip-dns-ubuntu.patch new file mode 100644 index 0000000..8ec3904 --- /dev/null +++ b/patches/test-skip-dns-ubuntu.patch @@ -0,0 +1,49 @@ +Description: Skip DNS tests which fail on Ubuntu autopkgtest infrastructure +Author: Graham Inggs <ginggs@debian.org> +Last-Update: 2018-10-01 + +Index: julia/stdlib/Sockets/test/runtests.jl +=================================================================== +--- julia.orig/stdlib/Sockets/test/runtests.jl ++++ julia/stdlib/Sockets/test/runtests.jl +@@ -151,25 +151,25 @@ defaultport = rand(2000:4000) + end + + @testset "getnameinfo on some unroutable IP addresses (RFC 5737)" begin +- @test getnameinfo(ip"192.0.2.1") == "192.0.2.1" +- @test getnameinfo(ip"198.51.100.1") == "198.51.100.1" +- @test getnameinfo(ip"203.0.113.1") == "203.0.113.1" +- @test getnameinfo(ip"0.1.1.1") == "0.1.1.1" +- @test getnameinfo(ip"::ffff:0.1.1.1") == "::ffff:0.1.1.1" +- @test getnameinfo(ip"::ffff:192.0.2.1") == "::ffff:192.0.2.1" +- @test getnameinfo(ip"2001:db8::1") == "2001:db8::1" ++# @test getnameinfo(ip"192.0.2.1") == "192.0.2.1" ++# @test getnameinfo(ip"198.51.100.1") == "198.51.100.1" ++# @test getnameinfo(ip"203.0.113.1") == "203.0.113.1" ++# @test getnameinfo(ip"0.1.1.1") == "0.1.1.1" ++# @test getnameinfo(ip"::ffff:0.1.1.1") == "::ffff:0.1.1.1" ++# @test getnameinfo(ip"::ffff:192.0.2.1") == "::ffff:192.0.2.1" ++# @test getnameinfo(ip"2001:db8::1") == "2001:db8::1" + end + + @testset "getnameinfo on some valid IP addresses" begin + @test !isempty(getnameinfo(ip"::")::String) +- @test !isempty(getnameinfo(ip"0.0.0.0")::String) +- @test !isempty(getnameinfo(ip"10.1.0.0")::String) +- @test !isempty(getnameinfo(ip"10.1.0.255")::String) +- @test !isempty(getnameinfo(ip"10.1.255.1")::String) +- @test !isempty(getnameinfo(ip"255.255.255.255")::String) +- @test !isempty(getnameinfo(ip"255.255.255.0")::String) +- @test !isempty(getnameinfo(ip"192.168.0.1")::String) +- @test !isempty(getnameinfo(ip"::1")::String) ++# @test !isempty(getnameinfo(ip"0.0.0.0")::String) ++# @test !isempty(getnameinfo(ip"10.1.0.0")::String) ++# @test !isempty(getnameinfo(ip"10.1.0.255")::String) ++# @test !isempty(getnameinfo(ip"10.1.255.1")::String) ++# @test !isempty(getnameinfo(ip"255.255.255.255")::String) ++# @test !isempty(getnameinfo(ip"255.255.255.0")::String) ++# @test !isempty(getnameinfo(ip"192.168.0.1")::String) ++# @test !isempty(getnameinfo(ip"::1")::String) + end + + @testset "getaddrinfo" begin diff --git a/patches/test-skip-i386-spec.patch b/patches/test-skip-i386-spec.patch new file mode 100644 index 0000000..4de449b --- /dev/null +++ b/patches/test-skip-i386-spec.patch @@ -0,0 +1,40 @@ +Description: skip some tests specifically for i386 +Author: Mo Zhou +Forward: no need. +Index: julia/test/compiler/compiler.jl +=================================================================== +--- julia.orig/test/compiler/compiler.jl ++++ julia/test/compiler/compiler.jl +@@ -879,11 +879,15 @@ function break_21369() + end + i += 1 + end ++ if !(Sys.ARCH in [:i386, :i686]) + @test fr.func === :break_21369 ++ end + rethrow() + end + end ++if !(Sys.ARCH in [:i386, :i686]) + @test_throws ErrorException break_21369() # not TypeError ++end + + # issue #17003 + abstract type AArray_17003{T,N} end +Index: julia/test/stacktraces.jl +=================================================================== +--- julia.orig/test/stacktraces.jl ++++ julia/test/stacktraces.jl +@@ -76,10 +76,12 @@ let ct = current_task() + @test try_stacktrace()[1] == StackFrame(:try_stacktrace, @__FILE__, line_numbers[2]) + + # Test try...catch with catch_backtrace ++ if !(Sys.ARCH in [:i386, :i686]) + @test try_catch()[1:2] == [ + StackFrame(:bad_function, @__FILE__, line_numbers[1]), + StackFrame(:try_catch, @__FILE__, line_numbers[3]) + ] ++ end + end + + module inlined_test diff --git a/patches/test-skip-sigint.patch b/patches/test-skip-sigint.patch new file mode 100644 index 0000000..6816779 --- /dev/null +++ b/patches/test-skip-sigint.patch @@ -0,0 +1,26 @@ +Description: temporarily skip this test which causes random test failure. Further investigation needed. +Forward: never +Last-Update: 20180812 +Author: Mo Zhou + +Index: julia/test/stress.jl +=================================================================== +--- julia.orig/test/stress.jl ++++ julia/test/stress.jl +@@ -91,16 +91,3 @@ if !Sys.iswindows() + test_22566() + end + end # !Sys.iswindows +- +-# sig 2 is SIGINT per the POSIX.1-1990 standard +-if !Sys.iswindows() +- ccall(:jl_exit_on_sigint, Cvoid, (Cint,), 0) +- @test_throws InterruptException begin +- ccall(:kill, Cvoid, (Cint, Cint,), getpid(), 2) +- for i in 1:10 +- Libc.systemsleep(0.1) +- ccall(:jl_gc_safepoint, Cvoid, ()) # wait for SIGINT to arrive +- end +- end +- ccall(:jl_exit_on_sigint, Cvoid, (Cint,), 1) +-end diff --git a/prompt.example.jl b/prompt.example.jl new file mode 100644 index 0000000..74976d1 --- /dev/null +++ b/prompt.example.jl @@ -0,0 +1,10 @@ +# This example changes the default prompt string. +# Just include this file in ~/.julia/config/startup.jl +# For more tweaks to your REPL, please install the "OhMyREPL" package. +import REPL +function myrepl(repl) + repl.interface = REPL.setup_interface(repl) + repl.interface.modes[1].prompt = "⛬ >" + return +end +atreplinit(myrepl) diff --git a/rules b/rules new file mode 100755 index 0000000..a6865b7 --- /dev/null +++ b/rules @@ -0,0 +1,195 @@ +#!/usr/bin/make -f +include /usr/share/dpkg/default.mk +export DEB_BUILD_MAINT_OPTIONS=hardening=+all + +# Disable unaligned access on armhf +ifneq (,$(filter $(DEB_HOST_ARCH),armhf)) + export DEB_CFLAGS_MAINT_APPEND += -mno-unaligned-access +endif + +# Ensure pcre_h.jl and errno_h.jl are sorted reproducibly +export LC_ALL=C.UTF-8 +# HOME is needed to avoid "mkdir(): Permission denied" while building docs. +# Some tests also need a HOME directory. +export HOME=/tmp +# If you want to do a custom build of Julia against MKL, set it to 1. +export CUSTOM_MKL ?= 0 +# If you want to do a custom build for native machine architecture +export CUSTOM_NATIVE ?= 0 + +# NOTES: +# 1. Some of these flags come from upstream's Make.inc . +# 2. To enable USE_BLAS64=0 (ILP64), we need to set INTERFACE64=1 for OpenBLAS. +# 3. Julia is tightly coupled with a specific libuv1 version. we cannot use the one provided in archive. +# 4. ∴ is unicode "therefore", ⛬ is unicode "historic site" https://unicode-table.com/en/26EC/ +COMMON_FLAGS = \ + prefix=/usr \ + sysconfdir=/etc \ + MULTIARCH=$(DEB_HOST_MULTIARCH) \ + MULTIARCH_INSTALL=1 \ + NO_GIT=1 \ + TAGGED_RELEASE_BANNER='$(DEB_VENDOR) ⛬ julia/$(DEB_VERSION)' \ + USE_BLAS64=0 \ + USE_LLVM_SHLIB=1 \ + USE_SYSTEM_BLAS=1 \ + USE_SYSTEM_CURL=1 \ + USE_SYSTEM_DSFMT=1 \ + USE_SYSTEM_GMP=1 \ + USE_SYSTEM_LAPACK=1 \ + USE_SYSTEM_LIBGIT2=1 \ + USE_SYSTEM_LIBSSH2=1 \ + USE_SYSTEM_LIBUNWIND=1 \ + USE_SYSTEM_LIBUV=0 \ + USE_SYSTEM_LLVM=0 \ + USE_SYSTEM_MBEDTLS=1 \ + USE_SYSTEM_MPFR=1 \ + USE_SYSTEM_OPENSPECFUN=1 \ + USE_SYSTEM_PATCHELF=1 \ + USE_SYSTEM_PCRE=1 \ + USE_SYSTEM_SUITESPARSE=1 \ + USE_SYSTEM_UTF8PROC=1 \ + VERBOSE=1 + +# Set architecture specific CPU targets. See: #910784 +ifneq (,$(filter $(DEB_HOST_ARCH),amd64 kfreebsd-amd64 x32)) +COMMON_FLAGS += MARCH=x86-64 \ + JULIA_CPU_TARGET="generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)" +else ifneq (,$(filter $(DEB_HOST_ARCH),i386 hurd-i386 kfreebsd-i386)) +COMMON_FLAGS += MARCH=pentium4 \ + JULIA_CPU_TARGET="pentium4;sandybridge,-xsaveopt,clone_all" +else ifneq (,$(filter $(DEB_HOST_ARCH),armhf)) +COMMON_FLAGS += JULIA_CPU_TARGET="armv7-a;armv7-a,neon;armv7-a,neon,vfp4" +else ifneq (,$(filter $(DEB_HOST_ARCH),ppc64el)) +COMMON_FLAGS += JULIA_CPU_TARGET="pwr8" +else +COMMON_FLAGS += JULIA_CPU_TARGET="generic" +endif + +# Use libopenlibm on architectures that have it +ifneq (,$(filter $(DEB_HOST_ARCH),amd64 kfreebsd-amd64 x32)) +COMMON_FLAGS += USE_SYSTEM_OPENLIBM=1 USE_SYSTEM_LIBM=0 +else ifneq (,$(filter $(DEB_HOST_ARCH),i386 hurd-i386 kfreebsd-i386)) +COMMON_FLAGS += USE_SYSTEM_OPENLIBM=1 USE_SYSTEM_LIBM=0 +else ifneq (,$(filter $(DEB_HOST_ARCH),arm64 armhf mips mips64el mipsel powerpc ppc64 ppc64el)) +COMMON_FLAGS += USE_SYSTEM_OPENLIBM=1 USE_SYSTEM_LIBM=0 +else +# Use libm elsewhere +COMMON_FLAGS += USE_SYSTEM_OPENLIBM=0 USE_SYSTEM_LIBM=1 +endif + +# Use libopenblas on architectures that have it +ifneq (,$(filter $(DEB_HOST_ARCH),amd64 arm64 armhf i386 kfreebsd-amd64 kfreebsd-i386 mips64el ppc64el s390x)) +COMMON_FLAGS += LIBBLAS=-lopenblas LIBBLASNAME=libopenblas \ + LIBLAPACK=-lopenblas LIBLAPACKNAME=libopenblas +else +# Use libblas and liblapack elsewhere +COMMON_FLAGS += LIBBLAS=-lblas LIBBLASNAME=libblas \ + LIBLAPACK=-llapack LIBLAPACKNAME=liblapack +endif + +# [s390x] Disable libunwind +ifneq (,$(filter $(DEB_HOST_ARCH),s390x)) +COMMON_FLAGS += DISABLE_LIBUNWIND=1 +endif + +# Set number of parallel workers for tests +ifneq (,$(filter parallel=1,$(DEB_BUILD_OPTIONS))) +TESTS_ENV += JULIA_CPU_THREADS=2 +else ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) +TESTS_ENV += JULIA_CPU_THREADS=$(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) +else +TESTS_ENV += JULIA_CPU_THREADS=2 +endif +# Restart workers exceeding maximum resident memory size (requires JULIA_CPU_THREADS >= 2) +TESTS_ENV += JULIA_TEST_MAXRSS_MB=500 + +ifeq (1,$(CUSTOM_MKL)) +COMMON_FLAGS += USE_INTEL_MKL=1 USE_BLAS64=1 \ + LIBBLAS=-lmkl_rt LIBBLASNAME=libmkl_rt \ + LIBLAPACK=-lmkl_rt LIBLAPACKNAME=libmkl_rt \ + MKLROOT=/usr MKLLIB=/usr/lib/$(DEB_HOST_MULTIARCH) +endif +ifeq (1,$(CUSTOM_NATIVE)) +COMMON_FLAGS += MARCH=native JULIA_CPU_TARGET=native +endif + + +%: + dh $@ + +override_dh_auto_build-arch: + dh_auto_build -- $(COMMON_FLAGS) + +override_dh_auto_build-indep: + dh_auto_build -- $(COMMON_FLAGS) + -$(MAKE) -C doc pdf + +override_dh_auto_test-arch: +ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) +ifeq (,$(filter $(DEB_HOST_ARCH),amd64 i386)) + -env $(TESTS_ENV) make -C test $(COMMON_FLAGS) +else + env $(TESTS_ENV) make -C test $(COMMON_FLAGS) +endif +endif + +override_dh_auto_test-indep: + +override_dh_auto_clean: + make $(COMMON_FLAGS) distcleanall + make -f debian/shlibdeps.mk $(COMMON_FLAGS) clean + +override_dh_auto_install: + make $(COMMON_FLAGS) install + # FIXME: any better solution than this hack? + find deps -type f -name 'libLLVM*so*' -exec cp -v '{}' debian/tmp/usr/lib/$(shell gcc -print-multiarch)/julia/ \; + -ln -s libLLVM-6.0.so debian/tmp/usr/lib/$(shell gcc -print-multiarch)/julia/libLLVM-6.0.0.so + -ln -s libLLVM-6.0.so debian/tmp/usr/lib/$(shell gcc -print-multiarch)/julia/libLLVM.so + rm -rf usr # Otherwise dh_install does not see debian/tmp/usr + find debian -type f -name '*.so.debug' -delete + find debian -type f -name .gitignore -delete + find debian -type f -name 'LICENSE.md' -delete + +override_dh_missing: + dh_missing --list-missing + +override_dh_link-arch: + # Create *.so symlinks for dlopen'd libraries in private libdir. + make -f debian/shlibdeps.mk $(COMMON_FLAGS) + dh_link + +override_dh_shlibdeps: + # Generate dependencies for dlopen'd libraries using dummy executable. + # Suppress useless dependency warnings caused by unused library symbols. + dh_shlibdeps -- --warnings=1 debian/shlibdeps + +override_dh_compress: + dh_compress --exclude=examples/ + +override_dh_install-indep: + dh_install --exclude=build_h.jl --exclude=build.h + +override_dh_fixperms: + dh_fixperms + # Fix shebang and mode bits + find debian \( -type f -name '*.jl' \ + -exec grep -q '..usr/bin/env julia' '{}' \; \ + -a -exec sed -i -e 's@#!/usr/bin/env julia@#!/usr/bin/julia@g' '{}' \; \ + -a -exec chmod +x '{}' \; -print \) + +# Don't strip sys.so and libjulia.so.* to keep the sanity of this program. +# https://github.com/JuliaLang/julia/issues/23115#issuecomment-320715030 +# +# Julia sysimage (i.e. sys.so) sys.so is NOT compiled from any compiled +# language such as C/C++, but from Julia scripts instead. Julia precompiles .jl +# scripts under the base and stdlib directories into this ELF-formated shared +# object sys.so to speedup program startup time. A glance at the symbol table +# (readelf -sW sys.so) would illustrate that. For more detail about how such +# debugging information is useful, please refer the official documentation: +# https://docs.julialang.org/en/v1.0.0/manual/stacktraces/ +# +override_dh_strip: + dh_strip -X"sys.so" + +override_dh_makeshlibs: + dh_makeshlibs --no-scripts -XLLVM diff --git a/shlibdeps.c b/shlibdeps.c new file mode 100644 index 0000000..953a1cd --- /dev/null +++ b/shlibdeps.c @@ -0,0 +1,47 @@ +/* + * Query soname of shared library. + * Copyright © 2015 Peter Colberg. + * Distributed under the MIT license. + */ + +#define _GNU_SOURCE +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + +#define error(fmt, ...) fprintf(stderr, "%s: "fmt"\n", argv[0], ##__VA_ARGS__) + +/* + * For a given symbol name, this program prints the path relative to / + * of the shared library containing that symbol. The program must be + * linked against the shared libraries to be queried for symbols, and + * compiled as a position-independent executable using -fPIE. + */ +int main(int argc, const char *const *argv) +{ + Dl_info info; + void *sym; + + if (argc != 2) { + fprintf(stderr, "Usage: %s SYMBOL\n", argv[0]); + return 1; + } + if (!(sym = dlsym(RTLD_DEFAULT, argv[1]))) { + fprintf(stderr, "%s\n", dlerror()); + return 1; + } + if (dladdr(sym, &info) == 0) { + fprintf(stderr, "%s\n", dlerror()); + return 1; + } + if (info.dli_saddr != sym) { + error("mismatching symbol name: %s", info.dli_sname); + return 1; + } + if (info.dli_fname[0] != '/') { + error("library name not an absolute path: %s", info.dli_fname); + return 1; + } + printf("%s", info.dli_fname + 1); + return 0; +} diff --git a/shlibdeps.mk b/shlibdeps.mk new file mode 100644 index 0000000..52e68ae --- /dev/null +++ b/shlibdeps.mk @@ -0,0 +1,188 @@ +# This makefile compiles a dummy executable linked against +# those shared libraries that are dlopen'd by Julia modules +# in Base. The dummy executable is passed to dpkg-shlibdeps +# to generate library dependencies for the julia package. +# +# The dummy executable is further used to generate symbolic +# links lib*.so => lib*.so.SOVERSION in the private library +# path for Julia, which ensures that ccall() loads exactly +# those library versions that the julia package was built +# with and depends on. + +# Include Julia makefile with LIB*NAME definitions. +JULIAHOME := $(CURDIR) +include Make.inc + +TARGETS := debian/shlibdeps debian/libjulia$(SOMAJOR).links + +all: $(TARGETS) + +ifeq ($(USE_SYSTEM_ARPACK),1) +SHLIBDEPS += -larpack +endif + +ifeq ($(USE_SYSTEM_BLAS),1) +SHLIBDEPS += $(LIBBLAS) +# OpenBLAS library provides both BLAS and LAPACK. +ifneq ($(LIBBLASNAME),$(LIBLAPACKNAME)) +SHLIBDEPS += $(LIBLAPACK) +endif +endif + +ifeq ($(USE_SYSTEM_CURL),1) +SHLIBDEPS += -lcurl +endif + +ifeq ($(USE_SYSTEM_DSFMT),1) +SHLIBDEPS += -ldSFMT +endif + +ifeq ($(USE_SYSTEM_GMP),1) +SHLIBDEPS += -lgmp +endif + +ifeq ($(USE_SYSTEM_LIBGIT2),1) +SHLIBDEPS += -lgit2 +endif + +ifeq ($(USE_SYSTEM_LIBM),1) +SHLIBDEPS += $(LIBM) +else ifeq ($(USE_SYSTEM_OPENLIBM),1) +SHLIBDEPS += $(LIBM) +endif + +ifeq ($(USE_SYSTEM_LIBSSH2),1) +SHLIBDEPS += -lssh2 +endif + +ifeq ($(USE_SYSTEM_LIBUNWIND),1) +ifeq (,$(filter $(DEB_HOST_ARCH),s390x)) +SHLIBDEPS += -lunwind +endif +endif + +ifeq ($(USE_SYSTEM_LIBUV),1) +SHLIBDEPS += -luv +endif + +ifeq ($(USE_SYSTEM_LLVM),1) +SHLIBDEPS += -lLLVM -L/usr/lib/llvm-$(LLVM_VER)/lib/ +endif + +ifeq ($(USE_SYSTEM_MBEDTLS),1) +SHLIBDEPS += -lmbedtls -lmbedcrypto -lmbedx509 +endif + +ifeq ($(USE_SYSTEM_MPFR),1) +SHLIBDEPS += -lmpfr +endif + +ifeq ($(USE_SYSTEM_PCRE),1) +SHLIBDEPS += -lpcre2-8 +endif + +ifeq ($(USE_SYSTEM_SUITESPARSE),1) +SHLIBDEPS += -lcholmod -lspqr -lsuitesparseconfig -lumfpack +endif + +ifeq ($(USE_SYSTEM_UTF8PROC),1) +SHLIBDEPS += -lutf8proc +endif + +# The dummy executable is linked with --no-as-needed to prevent +# the linker from potentially disregarding the given libraries +# because none of the library symbols are used at compile time. +debian/shlibdeps: debian/shlibdeps.c + $(CC) -fPIE -o $@ $< -ldl -Wl,--no-as-needed $(SHLIBDEPS) + +# The soname for each library is looked up by invoking the +# dummy executable with the name of an arbitrary symbol such +# as a function exported by that library. Ideally, these +# should be functions that are ccall'd by the Julia modules. +debian/libjulia$(SOMAJOR).links: debian/shlibdeps + rm -f $@.tmp +ifeq ($(USE_SYSTEM_ARPACK),1) + debian/shlibdeps snaupd_ >> $@.tmp + echo " $(private_libdir)/libarpack.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_BLAS),1) + debian/shlibdeps daxpy_ >> $@.tmp + echo " $(private_libdir)/$(LIBBLASNAME).so" >> $@.tmp +ifneq ($(LIBBLASNAME),$(LIBLAPACKNAME)) + debian/shlibdeps dggsvd_ >> $@.tmp + echo " $(private_libdir)/$(LIBLAPACKNAME).so" >> $@.tmp +endif +endif +ifeq ($(USE_SYSTEM_CURL),1) + debian/shlibdeps curl_easy_recv >> $@.tmp + echo " $(private_libdir)/libcurl.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_DSFMT),1) + debian/shlibdeps dsfmt_get_idstring >> $@.tmp + echo " $(private_libdir)/libdSFMT.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_GMP),1) + debian/shlibdeps __gmpz_get_str >> $@.tmp + echo " $(private_libdir)/libgmp.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_LIBGIT2),1) + debian/shlibdeps git_libgit2_version >> $@.tmp + echo " $(private_libdir)/libgit2.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_LIBM),1) + debian/shlibdeps pow >> $@.tmp + echo " $(private_libdir)/$(LIBMNAME).so" >> $@.tmp +else ifeq ($(USE_SYSTEM_OPENLIBM),1) + debian/shlibdeps pow >> $@.tmp + echo " $(private_libdir)/$(LIBMNAME).so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_MPFR),1) + debian/shlibdeps mpfr_init2 >> $@.tmp + echo " $(private_libdir)/libmpfr.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_PCRE),1) + debian/shlibdeps pcre2_compile_8 >> $@.tmp + echo " $(private_libdir)/libpcre2-8.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_LIBSSH2),1) + debian/shlibdeps libssh2_version >> $@.tmp + echo " $(private_libdir)/libssh2.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_LIBUV),1) + debian/shlibdeps uv_tcp_open >> $@.tmp + echo " $(private_libdir)/libuv.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_LIBUNWIND),1) + debian/shlibdeps backtrace >> $@.tmp + echo " $(private_libdir)/libunwind.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_LLVM),1) + debian/shlibdeps llvm_regexec >> $@.tmp + echo " $(private_libdir)/libLLVM.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_MBEDTLS),1) + debian/shlibdeps mbedtls_net_init >> $@.tmp + echo " $(private_libdir)/libmbedtls.so" >> $@.tmp + debian/shlibdeps mbedtls_md5 >> $@.tmp + echo " $(private_libdir)/libmbedcrypto.so" >> $@.tmp + debian/shlibdeps mbedtls_x509_get_serial >> $@.tmp + echo " $(private_libdir)/libmbedx509.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_SUITESPARSE),1) + debian/shlibdeps cholmod_version >> $@.tmp + echo " $(private_libdir)/libcholmod.so" >> $@.tmp + debian/shlibdeps SuiteSparseQR_C_free >> $@.tmp + echo " $(private_libdir)/libspqr.so" >> $@.tmp + debian/shlibdeps SuiteSparse_config >> $@.tmp + echo " $(private_libdir)/libsuitesparseconfig.so" >> $@.tmp + debian/shlibdeps umfpack_dl_report_info >> $@.tmp + echo " $(private_libdir)/libumfpack.so" >> $@.tmp +endif +ifeq ($(USE_SYSTEM_UTF8PROC),1) + debian/shlibdeps utf8proc_errmsg >> $@.tmp + echo " $(private_libdir)/libutf8proc.so" >> $@.tmp +endif + mv $@.tmp $@ + +clean: + $(RM) $(TARGETS) diff --git a/source/format b/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/source/include-binaries b/source/include-binaries new file mode 100644 index 0000000..ab74339 --- /dev/null +++ b/source/include-binaries @@ -0,0 +1,18 @@ +debian/embedded/libuv-ed3700c849289ed01fe04273a7bf865340b2bd7e.tar.gz +debian/embedded/libwhich-81e9723c0273d78493dc8c8ed570f68d9ce7e89e.tar.gz +debian/embedded/93b6d6de857dc88e665d2c64397852ab9701ba24 +debian/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/puttygen-generated.png +debian/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/puttygen-export-private-key.png +debian/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/puttygen.png +debian/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/travis-variables.png +debian/embedded/Documenter.jl-0.20.0/docs/src/man/hosting/github-add-deploy-key.png +debian/embedded/Documenter.jl-0.20.0/docs/src/assets/favicon.ico +debian/embedded/Documenter.jl-0.20.0/docs/src/assets/logo.png +debian/embedded/Documenter.jl-0.20.0/test/examples/src/assets/favicon.ico +debian/embedded/Documenter.jl-0.20.0/test/examples/images/logo.jpg +debian/embedded/Documenter.jl-0.20.0/test/examples/images/logo.webp +debian/embedded/Documenter.jl-0.20.0/test/examples/images/logo.gif +debian/embedded/Documenter.jl-0.20.0/test/examples/images/logo.png +debian/embedded/DocStringExtensions.jl-0.5.0/docs/src/assets/logo.png +debian/embedded/llvm-6.0.0.src.tar.xz +debian/embedded/llvm-6.0.src.tar.xz diff --git a/tests/control b/tests/control new file mode 100644 index 0000000..6dd32e5 --- /dev/null +++ b/tests/control @@ -0,0 +1,4 @@ +# Justification for "needs-root": https://github.com/JuliaLang/julia/issues/28023 +Tests: runtests.sh +Restrictions: allow-stderr, needs-root +Depends: @, curl, dpkg-dev diff --git a/tests/runtests.sh b/tests/runtests.sh new file mode 100755 index 0000000..127aa71 --- /dev/null +++ b/tests/runtests.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -ex + +export JULIA_TEST_MAXRSS_MB=500 +export HOME=/tmp + +cd $AUTOPKGTEST_TMP + +/usr/bin/julia \ + --check-bounds=yes \ + --startup-file=no \ + /usr/share/julia/test/runtests.jl all diff --git a/upstream/metadata b/upstream/metadata new file mode 100644 index 0000000..4987687 --- /dev/null +++ b/upstream/metadata @@ -0,0 +1,15 @@ +Name: Julia +Bug-Database: https://github.com/julialang/julia/issues +Bug-Submit: https://github.com/julialang/julia/issues +Cite-As: "Julia: A Fresh Approach to Numerical Computing. Jeff Bezanson, Alan Edelman, Stefan Karpinski and Viral B. Shah (2017) SIAM Review, 59: 65–98. doi: 10.1137/141000671. url: http://julialang.org/publications/julia-fresh-approach-BEKS.pdf." +Documentation: https://docs.julialang.org/ +Reference: + Author: Jeff Bezanson, Alan Edelman, Stefan Karpinski and Viral B. Shah + Booktitle: SIAM Review + DOI: 10.1137/141000671 + Number: 59 + Pages: 65–98 + Title: "Julia: A Fresh Approach to Numerical Computing" + Year: 2017 +Repository: https://github.com/JuliaLang/julia +Repository-Browse: https://github.com/JuliaLang/julia diff --git a/watch b/watch new file mode 100644 index 0000000..ac69ac3 --- /dev/null +++ b/watch @@ -0,0 +1,5 @@ +version=4 +opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%julia-$1.tar.gz%,\ + dversionmangle=s/\+dfsg\d*$// ,repacksuffix=+dfsg" \ + https://github.com/JuliaLang/julia/tags \ + (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate