get-module-content for showing module implementation
Normally Scribble, the Racket’s documentation tool, does not provide a way to see how a function/object/module is actually defined in the code. Just recently I wound a good-enough way to insert the whole content of the module we are documenting with Scribble.
The input is a module name in the form that you would use in absolute require form, except that it is a string, not a bare syntax.
get-module-content will reach out to Your Racket package database and find a module that you gave. It will read it and remove all comments. It returns a Racket string.
The string? returned by get-module-content can later be used to either extract some more info but it can be effectively used to insert the full module implementation block.
get-module-content usage inside Scribble
In Scribble I insert the module source code like so:
Racket executables made by raco exe are known to be quite large. One of tools that can be used to help reduce the size of produced binaries is the gzexe program.
gzexe is a tool that can compress a executable binary. It can be acquired by installing gzip on most Linux distributions (included in the app-arch/gzip package on Gentoo).
hello-world: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV),
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
for GNU/Linux 3.2.0, stripped
This “small” executable weights 46 MB!
In comparison busybox weights around 2 MB.
Compressing with gzexe
Keep in mind that gzexe will overwrite the compressed file and create a backup with appended "~".
1
gzexehello-world
And this gives us only 8,5 MB. Nice!
In comparison bazel, which is a single-binary build system written in JAVA, executable takes 33 MB on my Gentoo machine. I tried compressing it with gzexe and it reduces it only by 10%, to around 29 MB.
gzexeis not a silver bullet but with Racket exes it works very nicely.
Some Elisp package compilation failures are caused by not setting the loadpath correctly. It mostly happens when you compile source from a directory that is not the current working directory. For example:
1
elisp-compileelisp/*.el
In most cases you can cd or override the S variable to set it to location where ELisp source resides.
But in other cases you can append to load path the directory with source, see:
elisp-make-autoload-file allows to name the generated autoload file. For sake of easier debugging and writing Gentoo SITEFILEs, please do not rename the generated file.
The name of that file should always be ${PN}-autoloads.el.
Use new elisp-enable-tests function
elisp-enable-tests allows to set up IUSE, RESTRICT, BDEPEND and the test runner function for running tests with the specified test runner.
The 1st (test-runner) argument must be one of:
buttercup — for buttercup provided via app-emacs/buttercup,
ert-runner — for ert-runner provided via app-emacs/ert-runner,
ert — for ERT, the built-in GNU Emacs test utility.
The 2nd argument is the directory where test are located, the leftover arguments are passed to the selected test runner.
Example:
1 2 3 4 5 6 7 8 910
EAPI=8
inheritelisp
# Other package settings ...SITEFILE="50${PN}-gentoo.el"DOCS=(README.md)
elisp-enable-testsbuttercuptest
Remove empty SITEFILEs
Recently a feature was added to elisp.eclass that will cause build process to generate the required SITEFILE with boilerplate code if it does not exist.
So if your SITEFILE looked like this:
1
(add-to-list'load-path"@SITELISP@")
… then, you can just remove that file.
But remember to keep the SITEFILE variable inside your ebuild:
1
SITEFILE="50${PN}-gentoo.el"
Remove pkg.el files
The *-pkg.el files are useless to Gentoo distribution model of Emacs Lisp packages and should be removed. It is as simple as adding this line to a ebuild:
1
ELISP_REMOVE="${PN}-pkg.el"
Beware that some packages will try to find their ${PN}-pkg.el file, but in most cases this will show up in failing package tests.
Use official repository
It is tedious to repackage Elpa tarballs, so use the official upstream even if you have to snapshot a specific commit.
To snapshot GitHub repos you would generally use this code:
1 2 3 4 5 6 7 8 910
# First check if we have the correct version to prevent# autobumping package version without changing the commit.[[${PV}==*_p20220325]]&&COMMIT=65c496d3d1d1298345beb9845840067bffb2ffd8
# Use correct URL that supports snapshots.SRC_URI="https://github.com/domtronn/${PN}/archive/${COMMIT}.tar.gz -> ${P}.tar.gz"# Override the temporary build directory variable.S="${WORKDIR}"/${PN}-${COMMIT}
Git is good, git tags are good. In case if upstream does not tag their package or just forgets to, kindly ask them to create a git tag when bumping Emacs package versions.
I wanted to echo parameter values when I set them in my blog’s frog.rkt config file.
Nothing simpler in Racket!
First I create this macro for echoing a single parameter value when it is set:
1 2 3 4 5 6 7 8 9101112
(define-syntax-rule(verbose-set-parameterparameter-idparameter-value)(begin;; Set the parameter.(parameter-idparameter-value);; Then call the parameter and print it's value.;; The "'parameter-id" is special syntax;; for turning a "parameter-id" identifier to a symbol.;; We can also write it like:;; > (quote parameter-id);; to be less confusing.(printf"[DEBUG] (~a ~v)\n"'parameter-id(parameter-id))))
then, I create a wrapper for above macro that can take multiple parameter pairs:
12345
(define-syntax-rule(verbose-set-parameters(parameter-idparameter-value)...)(begin;; Unpack a chain of "(parameter-id parameter-value)" pairs;; using the "..." syntax.(verbose-set-parameterparameter-idparameter-value)...))
Notice that even the form of setting a parameter, that is (parameter-procedure "value"), remains the same, but in reality it is just similar to how the syntax macro pattern-matches on it.
Inspecting macro expansion
In racket-mode inside GNU Emacs we can inspect the macro expansion with racket-expand-region. Stepping through the expansion provided this result:
By implementing a method for equality equal-to? and two extraction methods equal-hash-code-of and equal-secondary-hash-code-of we can define our own object comparison rules.
Instead of changing CSS style for Your Racket projects documentation, You may be interested in compiling Markdown files generated form Scribble source into HTML documentation website.
Creating MkDocs project
Create docs directory and mkdocs.yml config file in current directory, along with a dummy index.md file in docs folder.
1
mkdocsnew.
Edit the name of the project.
Replace Racket-Project with your project name.
12
---site_name:Racket-Project
Building Scribble
Generate markdown files form scribble documentation.
Replace Racket-Project.scrbl with path to your scribble documentation main source file.
Compile HTML documentation from the markdown source.
1
mkdocsbuild
HTML files should appear in the site directory.
Running the server
Some features, like search for example are only available when running the mkdocs server.
1
mkdocsserve
Caveats
Some scribble functions do not look good or work correctly for markdown-to-HTML compilation by MkDocs.
table-of-contents - looks like a source block
index-section - letter links do not work
Example configuration
1 2 3 4 5 6 7 8 9101112131415161718
site_name:Racket-Ebuildsite_author:xgqt@riseup.netsite_description:library to ease ebuild creationsite_url:https://gitlab.com/gentoo-racket/racket-ebuildrepo_name:gentoo-racket/racket-ebuildrepo_url:https://gitlab.com/gentoo-racket/racket-ebuildplugins:-searchtheme:name:materialextra:social:-icon:fontawesome/brands/gitlablink:https://gitlab.com/gentoo-racket/racket-ebuild
Racket provides a executable plt-games, when ran (from console) it opens a menu of miscellaneous games, among them: jewel, minesweeper, aces, spider, checkers. & more (20 games total).
#lang racket/base(requireracket/gui/baseracket/mathplot)(plot-new-window?#true)(plot3d(surface3d(lambda(xy)(*(cosx)(siny)))(-pi)pi(-pi)pi)#:title"An R × R → R function"#:x-label"x"#:y-label"y"#:z-label"cos(x) sin(y)")
Browser
There's a included library to render web pages, just "(require browser)".
You can use Racket's Foreign Function Interface to interact with non-Racket libraries to make use of very fast libraries written in (mainly) FORTRAN & C.