From: Alan Schmitt <alan.schmitt@polytechnique.org>
To: "lwn" <lwn@lwn.net>, caml-list@inria.fr
Subject: [Caml-list] Attn: Development Editor, Latest OCaml Weekly News
Date: Tue, 11 Aug 2026 14:25:27 +0200 [thread overview]
Message-ID: <m2ldacaloo.fsf@petitepomme.net> (raw)
[-- Attachment #1.1.1: Type: text/plain, Size: 38159 bytes --]
Hello
Here is the latest OCaml Weekly News, for the week of August 04 to 11,
2026.
Table of Contents
─────────────────
Dune 3.24
New releases of Merlin and OCaml-LSP for OCaml 5.5 and trunk
sdl3 bindings
JFLA2027 : Premier appel à communications
hegel 0.14.0
New release 1.1.0 of ifs-fractals
OSEC-2026-14: mirage-crypto-pk: RSA signature verification raises undocumented exception
OSEC-2026-15: mirage-crypto-ec: EC public key out of bounds read
New package: floatml
ocaml-android reboot!
Ravel 1.0.1 — a functional language compiling to interaction nets
New package: P4-SpecTec
New package: NeoDriver 0.1.2 – Neo4j Database driver
opam-audit
shakuhachi v0.3.2 - A music collection manager
Bytream 0.1 – first release
Smaji Glyph Path
Smaji Glyph Path, two usage examples, Smaji Outline Description and Smaji Stroke Description
Old CWN
Dune 3.24
═════════
Archive: <https://discuss.ocaml.org/t/ann-dune-3-24/18316/8>
Continuing this thread, Ali Caglayan announced
──────────────────────────────────────────────
The Dune team is pleased to announce [the release of dune 3.24.2].
See [the full changelog] for the new fixes, and for attribution to the
contributors who made it all possible. Thank you, contributors!
If you encounter a problem with this release, please report it in [our
issue tracker].
[the release of dune 3.24.2]
<https://github.com/ocaml/dune/releases/tag/3.24.2>
[the full changelog] <https://github.com/ocaml/dune/releases/tag/3.24.2>
[our issue tracker] <https://github.com/ocaml/dune/issues>
New releases of Merlin and OCaml-LSP for OCaml 5.5 and trunk
════════════════════════════════════════════════════════════
Archive:
<https://discuss.ocaml.org/t/ann-new-releases-of-merlin-and-ocaml-lsp-for-ocaml-5-5-and-trunk/18414/1>
vds announced
─────────────
I am glad to announce Merlin `5.8.1-505', a new release that notably
fixes a caching issue that manifested frequently when using OCaml-LSP
with Dune in watch mode.
We also released preview versions of both Merlin and OCaml-LSP working
with today's OCaml compiler's trunk. You can use them to hack on the
compiler, but they will break again with futures changes to the types
AST.
sdl3 bindings
═════════════
Archive: <https://discuss.ocaml.org/t/ann-sdl3-bindings/18415/1>
sanette announced
─────────────────
Hello!
it's my pleasure to announce a (very) preliminary version of
`OCaml-sdl3' (or simply `sdl3' for the package name), which obviously
is a set of bindings for the [SDL3] library.
<https://github.com/sanette/ocaml-sdl3>
Why announcing a preliminary version? First, because I won't have much
time to work on it in the next couple of months, and second, because I
believe you can already have fun with it!
The bindings are generated by a program that uses `clang' to inspect
the SDL code. This is a first phase; not all functions are usable yet.
I have started to write manual wrappers for a few of them. (See the
examples).
_AI disclaimer:_ Although I have to admit chatGPT was my friend for
understanding how to use `clang' and `ctypes', I would like to state
here that the whole binding generator (plus all manual additions, of
course) was entirely written by (my) hand.
[SDL3] <https://www.libsdl.org/>
JFLA2027 : Premier appel à communications
═════════════════════════════════════════
Archive:
<https://discuss.ocaml.org/t/jfla2027-premier-appel-a-communications/18417/1>
Yannick Zakowski announced
──────────────────────────
This message is intentionally written in French. It is a call for
papers for the “Francophone Days on Functional Languages” to be held
at the end of January 2027 in Britany. Papers can be written in
English, but the presentations themselves are expected to be given in
French.
Merci de faire circuler : premier appel à communications
JFLA 2027 : Journées Francophones des Langages Applicatifs
<http://jfla.eu/jfla2027.html>
26 janvier au 29 janvier 2027
Maison Saint-François
Les 38èmes Journées Francophones des Langages Applicatifs (JFLA) se
tiendront en Bretagne, à Dinard (Ille-et-Vilaine), du mardi 26 janvier
2027 au vendredi 29 janvier 2027.
Les JFLA réunissent concepteur·rices, utilisateur·rices et
théoricien·nes ; elles ont pour ambition de couvrir les domaines des
langages applicatifs, de la preuve formelle, de la vérification de
programmes, et des objets mathématiques qui sous-tendent ces
outils. Ces domaines doivent être pris au sens large : nous souhaitons
promouvoir les ponts entre les différentes thématiques.
• Langages fonctionnels et applicatifs : sémantique, compilation,
optimisation, typage, extensions à d'autres paradigmes.
• Assistants de preuve : implémentation, nouvelles tactiques,
développements présentant un intérêt théorique, technique ou
méthodologique.
• Logique, correspondance preuve-programme, réalisabilité, extraction
de programmes, modèles.
• Spécification, prototypage, développements formels d'algorithmes.
• Vérification de programmes ou de modèles, vérification déductive,
interprétation abstraite, raffinement.
• Utilisation industrielle des langages fonctionnels et applicatifs,
ou des méthodes issues de la communauté scientifique. Outils et
plateformes pour le web.
• Enseignement ou diffusion des langages fonctionnels et
applicatifs. Environnements et méthodes de développement, retours
d'expérience.
Les articles soumis aux JFLA sont relus par au moins deux personnes
s'ils sont acceptés, et au moins trois personnes s'ils sont rejetés.
Les critiques du comité de programme sont toujours bienveillantes et
la plupart du temps encourageantes et constructives, même en cas de
rejet.
Il n'y a donc pas de raison de ne pas soumettre aux JFLA !
DATES IMPORTANTES
/!\\ Attention : les dates limites sont fermes et définitives. Il n'y
aura pas d'extension. /!
• Soumission des résumés et articles : 16 octobre 2026, GMT+2
• Notification aux auteurs et autrices : 2 décembre 2026, GMT+2
• Version finale des articles : 16 décembre 2026, GMT+2
SOUMISSIONS
Nous acceptons deux types de soumissions :
• Article de recherche (18 pages max.) portant sur des travaux
originaux. Nous acceptons des travaux en cours, pour lesquels
l'aspect recherche n'est pas entièrement finalisé. Nous encourageons
aussi la soumission d'articles présentant avec élégance un résultat
connu sous un angle nouveau.
• Article court (9 pages max.) décrivant un problème particulier, les
pistes en cours d'investigation, et visant à rechercher de l'aide de
la part de la communauté. Les articles courts peuvent également
présenter de manière synthétique et cohérente des résultats déjà
publiés. Enfin, ils peuvent présenter un outil logiciel dont
l'exposé constituera une démonstration.
CONSIGNES AUX AUTEURS ET AUTRICES
Les articles peuvent être rédigés en français ou en anglais.
La forme de l'article doit être soignée, et le contenu rédigé de
manière structurée et claire.
Le style LaTeX jflart doit impérativement être utilisé sans
modification de la mise en page. Le style LaTeX et sa documentation
sont disponibles depuis le site web de la conférence.
Les limites de pages sont strictes. Les références bibliographiques ne
sont pas comptabilisées dans la limite de pages. Les annexes aux
articles ne sont pas autorisées.
Les auteurs et autrices peuvent soumettre du matériel supplémentaire,
séparé de l'article soumis, sous forme de texte (version longue, sans
limite de pages) et/ou de développement logiciel. L'évaluation de ce
matériel supplémentaire est à la discrétion du comité de
programme. Les articles soumis doivent donc être auto-contenus et
évaluables sans ce matériel supplémentaire.
Les soumissions parallèles dans d'autres conférences, journaux ou
workshops avec actes ne sont pas autorisées.
Les membres du comité de programme sont autorisés à soumettre un
article. Les présidentes du comité ne le sont pas.
Les articles doivent être soumis via le site :
<https://types-hotcrp.paris.inria.fr/jfla27>
L'évaluation des articles suit un processus en simple-aveugle : les
rapports des articles sont anonymes, mais pas les auteurs et autrices.
Les articles acceptés seront publiés dans les actes de la conférence,
sur HAL, et les auteurs et autrices en donneront une présentation lors
des journées. Les présentations seront, de préférence, données en
français.
Yannick ZAKOWSKI et Stefania DUMBRAVA
JFLA 2027
hegel 0.14.0
════════════
Archive: <https://discuss.ocaml.org/t/ann-hegel-0-14-0/18423/1>
Ethan Chou announced
────────────────────
Hello,
After some feedback we've received about Hegel, I am happy to announce
v0.14.0 has removed the dependency on Core. The Core generators from
the previous versions now exist in an optional sublibrary called
Hegel_jane. Thanks to @c-cube for his help with his release!
For slightly more detail, see the release notes:
<https://github.com/hegeldev/hegel-ocaml/releases#release-v0.14.0>
New release 1.1.0 of ifs-fractals
═════════════════════════════════
Archive:
<https://discuss.ocaml.org/t/new-release-1-1-0-of-ifs-fractals/18425/1>
Cédric announced
────────────────
Hello everyone,
[ifs-fractals] — a small library and CLI that draws the attractors of
iterated function systems (the Barnsley fern and friends) with the
chaos game — just got its first feature release since arriving on opam
this summer. After sixteen years of intensive development ;-)
<https://us1.discourse-cdn.com/flex020/uploads/ocaml/original/2X/6/69533442f671ef2ba37fb0c5029780b8ec8b10c5.png>
What's new in 1.1.0:
• Headless PNG rendering. Until now the fractals could only be drawn
into a graphics window. You can now render straight to a file, no
display needed:
┌────
│ ifs-fractals -o fern.png -s 800x1280 barnsley
└────
• or from code, save_png barnsley 200000 "fern.png". This makes the
package usable on servers and in CI, and made testing much easier. A
fun constraint I set myself: no new dependencies — the PNG writer is
self-contained, writing 8-bit PNGs with stored deflate blocks in
pure OCaml.
• Density coloring. The chaos game doesn't visit the attractor
uniformly — some regions are hit far more often than others, and
that density is where much of the visual structure lives. With -c
(or save_png \~color:true), pixels are colored by their hit count on
a log scale. The image above is the result: the fern gets its veins
back.
┌────
│ ifs-fractals -c -o fern.png -s 800x1280 barnsley
└────
Install or upgrade with opam install ifs-fractals, then try
ifs-fractals –list to see all sixteen attractors.
If you're curious how new attractors get designed — how one finds the
six coefficients per affine map that produce a maple leaf or a
sunflower — I wrote the techniques up in a short paper, Building New
IFS Attractors: a Working Vocabulary of Affine Maps (
<https://doi.org/10.5281/zenodo.21804778> ), with a more narrative
account on my blog (
<https://www.cedricbonhomme.org/2026/07/27/challenging-claude-with-ifs-fractals/>
).
One disclosure, since it's the interesting part of the story: the new
attractors were designed by Claude (Anthropic's Fable 5 model) — the
blog post recounts that experiment. Everything else — the library, the
CLI, the PNG writer, and the paper itself — is my own work, not LLM
output.
• Repository:
<https://github.com/cedricbonhomme/iterated-function-systems>
• opam: <https://opam.ocaml.org/packages/ifs-fractals/>
• Changelog:
<https://github.com/cedricbonhomme/iterated-function-systems/blob/master/CHANGES.md>
Feedback and new fractal definitions are very welcome. Just make a
pull-request.
If you design an attractor you like, I'd love to see it!
[ifs-fractals]
<https://github.com/cedricbonhomme/iterated-function-systems>
OSEC-2026-14: mirage-crypto-pk: RSA signature verification raises undocumented exception
════════════════════════════════════════════════════════════════════════════════════════
Hannes Mehnert announced
────────────────────────
A new security advisory is available. As usual, it can be found at
<https://github.com/ocaml/security-advisories> and
<https://osv.dev/list?q=&ecosystem=opam>
Best,
Hannes
┌────
│ id: OSEC-2026-14
│ modified: "2026-08-07T13:00:00Z"
│ published: "2026-08-07T13:00:00Z"
│ severity: "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L"
│ severity_score: "4.3 (Medium)"
│ affected: "mirage-crypto-pk" {< "2.3.0"}
│ events: [
│ [
│ git "https://github.com/mirage/mirage-crypto.git" [
│ [fixed "a0f59a0c90eb067505b55a03d3bb104eacd6dd33"]
│ ]
│ ]
│ ]
│ credits: [
│ [reporter "Thomas Gazagnaire"]
│ [remediation_developer "Hannes Mehnert"]
│ ]
│ cwe: [ CWE-248 ]
│ affected_bindings: [
│ "Mirage_crypto_pk.Rsa.encrypt"
│ "Mirage_crypto_pk.Rsa.decrypt"
│ "Mirage_crypto_pk.Rsa.PKCS1.encrypt"
│ "Mirage_crypto_pk.Rsa.PKCS1.decrypt"
│ "Mirage_crypto_pk.Rsa.PKCS1.sig_encode"
│ "Mirage_crypto_pk.Rsa.PKCS1.sig_decode"
│ "Mirage_crypto_pk.Rsa.PKCS1.sign"
│ "Mirage_crypto_pk.Rsa.PKCS1.verify"
│ "Mirage_crypto_pk.Rsa.OAEP.encrypt"
│ "Mirage_crypto_pk.Rsa.OAEP.decrypt"
│ "Mirage_crypto_pk.Rsa.PSS.sign"
│ "Mirage_crypto_pk.Rsa.PSS.verify"
│ ]
└────
RSA signature verification raises undocumented exception
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
The RSA decrypt and encrypt functions raise an Invalid_argument
exception if the message is smaller than 2. This leads to X509
certificates with a signature value of 0 or 1 to throw this
Invalid_argument exception instead of a proper error.
◊ Fix
The fix is to reuse the Insufficient_key exception, which is
documented and caught further up in the stack.
◊ Timeline
• July 28th 2026: report to security@ocaml.org
• August 7th: release of mirage-crypto-pk 2.3.0 and security advisory
OSEC-2026-15: mirage-crypto-ec: EC public key out of bounds read
════════════════════════════════════════════════════════════════
Hannes Mehnert announced
────────────────────────
A new security advisory is available. As usual, it can be found at
<https://github.com/ocaml/security-advisories> and
<https://osv.dev/list?q=&ecosystem=opam>
Best,
Hannes
┌────
│ id: OSEC-2026-15
│ modified: "2026-08-07T13:00:00Z"
│ published: "2026-08-07T13:00:00Z"
│ severity: "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L"
│ severity_score: "4.3 (Medium)"
│ affected: "mirage-crypto-ec" {< "2.3.0"}
│ events: [
│ [
│ git "https://github.com/mirage/mirage-crypto.git" [
│ [fixed "1f0bf67044e67cf6e46911fcd77a0ff706b6c3e7"]
│ ]
│ ]
│ ]
│ credits: [
│ [reporter "Thomas Gazagnaire"]
│ [remediation_developer "Hannes Mehnert"]
│ ]
│ cwe: [ CWE-125 CWE-248 ]
│ affected_bindings: [
│ "Mirage_crypto_ec.P256.Dsa.pub_of_octets"
│ "Mirage_crypto_ec.P256.Dh.key_exchange"
│ "Mirage_crypto_ec.P384.Dsa.pub_of_octets"
│ "Mirage_crypto_ec.P384.Dh.key_exchange"
│ "Mirage_crypto_ec.P521.Dsa.pub_of_octets"
│ "Mirage_crypto_ec.P521.Dh.key_exchange"
│ ]
└────
EC public key out of bounds read
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
The internal Point.of_octets function is missing a length check for
compressed points, and thus is raising an exception when a short
buffer is provided. This affects all NIST curves (P-256, P-384, P-521)
and both `Dsa.pub_of_octets' and `Dh.key_exchange' functions.
◊ Fix
The fix is to check the length of the provided buffer.
◊ Timeline
• July 28th 2026: report to security@ocaml.org
• August 7th: release of mirage-crypto-pk 2.3.0 and security advisory
New package: floatml
════════════════════
Archive: <https://discuss.ocaml.org/t/ann-new-package-floatml/18431/1>
Opale announced
───────────────
Hi :) Wanted to announce a new package I worked on over the past week
I just published, *[floatml]*! It's a tiny wrapper around Rust's soft
float library ([`rustc_apfloat']), enabling fast and efficient
IEEE-754 `float16', `float32', `float64' and `float128' in OCaml. I
also made sure the code allocates as little as possible, so it should
be reasonably efficient.
*Disclaimer:* a good chunk of the code is LLM-authored. I chose the
interface I wanted and guided it, but the glue code with Rust is LLM
generated (and extensively tested!)
I had to create it for [Soteria], where we need reductions for
concrete float operations, to avoid using Z3 when possible. Maybe
you'll find a use for it too!
[floatml] <https://github.com/N1ark/floatml>
[`rustc_apfloat'] <https://github.com/rust-lang/rustc_apfloat>
[Soteria] <https://soteria-tools.com>
ocaml-android reboot!
═════════════════════
Archive:
<https://discuss.ocaml.org/t/ann-ocaml-android-reboot/18432/1>
Romain Beauxis announced
────────────────────────
Hi all!
I have just pushed a full reboot of the [Android cross-compiler] opam
repository!
The reboot follows the most recent practices set by the windows
counter part and is pretty clean, thanks to the vast improvements made
in cross-compiling support in the main OCaml compiler recently.
Not all packages have been migrated, due to lack of time. The old
branch is still available at `old-main'.
This is a community repository so, if cross-compiling OCaml code is in
your wheelhouse, feel free to submit some patches!
[Android cross-compiler]
<https://github.com/ocaml-cross/opam-cross-android>
Ravel 1.0.1 — a functional language compiling to interaction nets
═════════════════════════════════════════════════════════════════
Archive:
<https://discuss.ocaml.org/t/ann-new-package-ravel-1-0-1-a-functional-language-compiling-to-interaction-nets/18433/1>
Kayo Tei announced
──────────────────
Hi all!
I am happy to announce that Ravel 1.0.1 is now available on opam.
Ravel is a small functional language that compiles to interaction nets
— a graph-rewriting model with strong confluence and implicit
parallelism. It features user-defined algebraic data types, deep
pattern matching, first-class functions with lexical closures, and
automatic resource management via labeled duplication and erasure
nodes.
<https://opam.ocaml.org/packages/ravel/>
Feedback and contributions are welcome!
New package: P4-SpecTec
═══════════════════════
Archive:
<https://discuss.ocaml.org/t/ann-new-package-p4-spectec/18434/1>
Haechan Kwon announced
──────────────────────
Hi!
We are happy to announce the first public release of `p4spectec', a
framework for mechanizing the P4 language specification. It provides a
domain-specific language for writing formal specifications in the form
of *algorithmic inference rules* [(Lee et al., 2026)].
A specification written in P4-SpecTec is *executable*. By writing
typing rules with P4-SpecTec, you get a reference type checker. By
writing dynamic semantics rules, you get a reference interpreter. The
*prose backend* also generates human-readable documentation from the
mechanized specification.
<https://opam.ocaml.org/packages/p4spectec/>
For detailed instruction, source code and the mechanized P4
specification, check out the GitHub repository linked to the package.
[(Lee et al., 2026)] <https://arxiv.org/abs/2608.00639>
New package: NeoDriver 0.1.2 – Neo4j Database driver
════════════════════════════════════════════════════
Archive:
<https://discuss.ocaml.org/t/new-package-neodriver-0-1-2-neo4j-database-driver/18436/1>
Tomasz Barański announced
─────────────────────────
I'm happy to announce that first public release of Neo4j Driver.
It is a pure Ocaml driver for Neo4j database build for Eio. It is
intended to reach full feature parity with official drivers. Although
it's not there yet, at this stage it's fully usable with the following
features:
• Bolt protocol 3.0, 4.2–4.4, 5.0–5.8 and 6.0.
• Plain `bolt://' and TLS `bolt+s://' / `bolt+ssc://' connections.
• Auto-commit queries with lazy streaming results.
• Both explicit and managed transactions with automatic retry.
• Bookmarks.
• Temporal types with named time zones (embedded IANA database plus an
LMT fallback before 1970).
• Basic authentication (LOGON after HELLO on Bolt >= 5.1).
• TestKit conformance: 114 of 126 tests passing (12 skipped).
<https://opam.ocaml.org/packages/neodriver/>
opam-audit
══════════
Archive: <https://discuss.ocaml.org/t/ann-opam-audit/18438/1>
Hannes Mehnert announced
────────────────────────
Dear everyone,
I'm happy to announce that `opam-audit' has been released to opam in
its initial version. It is an opam plugin (so you install it in one
switch and have it available in all switches as `opam audit').
So, opam-audit keeps a local copy of the security-advisory database
from the [OCaml Security Team]. When you run `opam audit', it will
inspect all installed packages in your switch against the known
advisories and report which installed packages have a known security
vulnerability.
It either returns 0 if no known vulnerable packages were found, or
non-zero and a list of installed vulnerable packages. This way, your
CI systems can before publishing your application call `opam audit'
and ensure that no vulnerable package sneaked into your binary.
An earlier mention in here
<https://discuss.ocaml.org/t/request-for-comments-what-to-do-with-opam-packages-that-have-known-security-vulnerabilities/18087/2>
Source code at <https://github.com/hannesm/opam-audit> - bug reports
and feature requests are very welcome.
[OCaml Security Team] <https://ocaml.org/security>
shakuhachi v0.3.2 - A music collection manager
══════════════════════════════════════════════
Archive:
<https://discuss.ocaml.org/t/ann-shakuhachi-v0-3-2-a-music-collection-manager/18440/1>
EruEri announced
────────────────
Dear all,
I’m happy to announce the release shakuhachi v0.3.2, which also
contains 0.3.0 and 0.3.1 that I forgot to announce.
Shakuhachi is still a music collection manager.
The TL;DR of those releases:
• Regex substitution is slow and replacing it vastly improves the
speed of formatting.
• Fixing quite some wrong behaviors and my own mistakes.
• A lot of new functions exposed which make it a somewhat usable
foundation to built things on top.
• Fighting against OCaml's linkage strategy to allow plugins (using
dynlink) to have all the needed dependencies.
• Few new options (_eg_. _sorting items, avoiding inserting duplicate
songs, …_).
To see the list of all changes, you can read the changelog.
<https://codeberg.org/EruEri/shakuhachi>
Thanks you for your time
Sincerely yours.
Bytream 0.1 – first release
═══════════════════════════
Archive:
<https://discuss.ocaml.org/t/ann-bytream-0-1-first-release/18445/1>
Mikhail announced
─────────────────
Yo!
I am happy to announce the first public release of [Bytream], a
library for streaming bytes and crunching them.
This library contains angostic I/O runtime mechanisms for organization
byte streams processing for write and read in an efficient manner,
e.g. for buildings codecs and protocol implementations.
The idea and motivation for creating this project arose from the need
to effectively parse all kinds of binary formats and
protocols. Existing tandem [Angstrom] and [Faraday] is great, but it
is more expressive than I need. And [Bytesrw] and [Iostream] talk
about how to receive and send data, not how to process or record it.
That's why Bytream solves this problem. It borrows ideas from slices
and lifetimes from ByteSw and unbuffering from Angstrom, allowing you
to write regular OCaml code like with the Stdlib channels, which /work
in streaming/ mode /at any I/O runtime/.
[Bytream] <https://github.com/dx3mod/bytream>
[Angstrom] <https://ocaml.org/p/angstrom/latest>
[Faraday] <https://ocaml.org/p/faraday/latest>
[Bytesrw] <https://github.com/dbuenzli/bytesrw>
[Iostream] <https://ocaml.org/p/iostream/latest>
First release details
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Starting from the first version, two abstractions are already
available to you, one for input (`Bytream.In.t'), and the other for
outputting data (`Bytream.Out.t'). Both use [Bigarray] under the hood
to represent an array of bytes. The motivation for this choice is to
avoid duplication and fix runtime when transferring this data to
external functions.
As already mentioned, inheriting ideas from `Bytesrw', Bytream uses
the mechanism of chunks to feed the stream. An example illustrates the
basic concept of chunking:
┌────
│ (* Queue as a byte chunk source. *)
│ let queue =
│ let queue = Queue.create () in
│ Queue.add "he" queue;
│ (* ... *)
│ Queue.add "d!" queue;
│ queue
│ in
│
│ (* Reader function that returns chunks of text from the source. *)
│ let reader () =
│ match Queue.take_opt queue with
│ | None ->
│ (** For close incoming byte stream, the reader
│ should raise an End_of_file exception. *)
│ raise End_of_file
│ | Some chunk -> Bstr.of_string chunk
│ in
│
│ let in_stream = Bytream.In.make reader in
│ Bytream.In.input_string in_stream 7
│ (* - : string = "hello w" *)
└────
and alternative for outgoing byte stream.
┌────
│ (* Queue as a byte chunk sink. *)
│ let queue = Queue.create () in
│
│ (* Writer function that outputs chunks of text to the sink. *)
│ let writer (~buffer, ~length:len, ..) =
│ Queue.add Bstr.(sub_string ~off:0 ~len buffer) queue
│ in
│
│ let out_stream = Bytream.Out.make writer in
│ (* ... *)
└────
In real cases, we will of course use channels, files, sockets, and
other things to communicate with the outside world. And do it
streaming.
┌────
│ module Bson = struct
│ (* ... *)
│
│ let from_channel ic =
│ let in_stream = Bytream.In.of_channel ic in
│ Codec.input_document in_stream
│
│ let into_channel oc doc =
│ let out_stream = Bytream.Out.of_channel oc in
│ Codec.output_document out_stream doc
│
│ let to_string doc =
│ Bytream.Out.with_into_string @@ fun out_stream ->
│ Codec.output_document out_stream
└────
Working with `Lwt' through `Lwt_direct' is currently available in an
experimental capacity.
┌────
│ #require "bytream.lwt";;
│
│ let something_into_channel oc =
│ let%lwt out_stream = Bytream_lwt.Out.of_channel oc in
│ (* The usual Bytream code. *)
└────
With other direct style I/O runtimes (like `Eio', `Miou', etc), it
will work much better.
Or yet example.
┌────
│ match request with
│ | `Post "/archives/", body_stream ->
│ (* The reader has its own internal buffer mechanism that allows it to bufferize
│ the contents of the body stream and decode them without copying chunks. *)
│ let reader = Archive_reader.in_stream_of body_stream in
│ let archive_meta =
│ Bytream.In.make Archive_reader.(to_handler reader)
│ |> Archive_reader.input_archive_without_contents
│ in
│
│ let blob = Archive_reader.blob reader in
│ process_archive ~meta:archive_meta ~blob ()
│ (* ... *)
└────
[Bigarray] <https://ocaml.org/manual/5.5/api/Bigarray.html>
Plans for the next release
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
• Improve documentations
• Add unit tests
• Add combinators?
• *Your suggestions….*
Installation and play
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Already available at [OPAM]!
You can install the `bytream' library using the OPAM package manager
or any other method you prefer.
┌────
│ $ opam install bytream
└────
You can also get the latest version of the upstream (developer)
branch.
┌────
│ $ opam pin bytream.dev https://github.com/dx3mod/bytream.git
└────
If you are using [Dune], please add the `bytream' library to your
dependencies.
[OPAM] <https://opam.ocaml.org/>
[Dune] <https://dune.build/>
Showcases
╌╌╌╌╌╌╌╌╌
You can explore ecosystem libraries that use Bytream to better
understand its applicability.
• [Rpmfile] is the library for reading and writing RPM packages has
been ported from [Angstrom] since version 1.0.0 (*currently, we are
in the process of development*);
• [Intel_hex] **planned**;
• and many more…
[Rpmfile] <https://github.com/dx3mod/rpmfile>
[Angstrom] <https://github.com/inhabitedtype/angstrom>
[Intel_hex] <https://github.com/dx3mod/intel_hex>
Afterword
╌╌╌╌╌╌╌╌╌
I will be very happy to hear your opinion about this library. Maybe
you could provide some feedback. Also, comments from senior colleagues
about implementation details and the API would be appreciated. The
source code is open under the MIT license, so it's always ready for
changes.
Enjoy it! :camel: :hot_beverage:
Smaji Glyph Path
════════════════
Archive: <https://discuss.ocaml.org/t/ann-smaji-glyph-path/18446/1>
ZAN DoYe announced
──────────────────
[Smaji Glyph Path]
An OCaml library for manipulation of font glyph outlines. It provides
a suite of tools for analyzing, transforming, composing, and
converting glyph paths between different formats.
This library supports two primary path description standards:
1. SVG Path: Supports `<path>' element (including its `d' attribute)
and optional `<g>' element as containers.
2. Glif Format: Supports the data used to describe glyph outlines in
the Unified Font Object (UFO) format.
It has published on opam, so it can be installed easily by `opam
install smaji_glyph_path'
And here are [two use case samples]
[Smaji Glyph Path] <https://github.com/smaji-org/smaji_glyph_path>
[two use case samples]
<https://discuss.ocaml.org/t/smaji-glyph-path-two-usecases-smaji-outline-description-and-smaji-stroke-description/18447>
Smaji Glyph Path, two usage examples, Smaji Outline Description and Smaji Stroke Description
════════════════════════════════════════════════════════════════════════════════════════════
Archive:
<https://discuss.ocaml.org/t/smaji-glyph-path-two-usage-examples-smaji-outline-description-and-smaji-stroke-description/18447/1>
ZAN DoYe announced
──────────────────
[Smaji Glyph Path]
[Smaji Glyph Outline Description]
[Smaji Glyph Stroke Description]
I’d like to introduce two practical applications of the Smaji Glyph
Path library: *Smaji Glyph Outline Description(god)* and *Smaji Glyph
stroke description(gsd)*. Currently, these aren't published on opam
yet; I've just provided the links here as examples of how you can use
the Smaji Glyph Path library. If you find these examples helpful,
please let me know by replying or giving it a "like"—that'll let me
know there's interest so I can get them onto opam for better
maintenance.
I’ve designed a markup language that makes it very easy to build
glyphs by combining different strokes. Thanks to Smaji Glyph Path,
creating a glyph is basically like playing with building blocks—you
can even generate an animation of the entire writing process!
Check out these examples:
*Example 1:* Building the "八" character by combining two strokes.
┌────
│ <god version="1.0">
│ <glyph unicode="516b,0">
│ <stroke type="t" x="0" y="0" width="56" height="112"/>
│ <stroke type="p" x="76" y="0" width="56" height="112"/>
│ </glyph>
│ </god>
└────
<https://github.com/kandu/static/raw/master/smaji/cjkv/god/516b,0.outline.svg>
*Example 2:* Combining an existing "god" (不) and a horizontal stroke
(一) to create "丕" (with animation).
┌────
│ <god version="1.0">
│ <glyph unicode="4e15,0">
│ <character utf8= "不" x="0" y="0" width="128" height="120"/>
│ <stroke type="h" x="0" y="114" width="128" height="14"/>
│ </glyph>
│ </god>
└────
<https://github.com/kandu/static/raw/master/smaji/cjkv/god/4e15,0.animation.svg>
If this image is still, try to reload the image or open this image in
a new tab or window to restart the animation.
After using GOD for a while, I realized it’s actually better suited
for phonetic scripts rather than ideograph. Because of that, I
designed a new library specifically for ideograph (especially
Chinese): *Smaji Glyph Stroke Description (GSD)*.
For a deeper dive into GOD, the differences between it and GSD, and
the pros/cons of each use case, check out the links at the
beginning. I'll keep it brief here—feel free to check those out if
you're interested!
[Smaji Glyph Path] <https://github.com/smaji-org/smaji_glyph_path>
[Smaji Glyph Outline Description]
<https://github.com/smaji-org/smaji_god>
[Smaji Glyph Stroke Description]
<https://github.com/smaji-org/smaji_gsd>
Old CWN
═══════
If you happen to miss a CWN, you can [send me a message] and I'll mail
it to you, or go take a look at [the archive] or the [RSS feed of the
archives].
If you also wish to receive it every week by mail, you may subscribe
to the [caml-list].
[Alan Schmitt]
[send me a message] <mailto:alan.schmitt@polytechnique.org>
[the archive] <https://alan.petitepomme.net/cwn/>
[RSS feed of the archives] <https://alan.petitepomme.net/cwn/cwn.rss>
[caml-list] <https://sympa.inria.fr/sympa/info/caml-list>
[Alan Schmitt] <https://alan.petitepomme.net/>
[-- Attachment #1.1.2: Type: text/html, Size: 64518 bytes --]
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 568 bytes --]
next reply other threads:[~2026-08-11 12:25 UTC|newest]
Thread overview: 305+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-11 12:25 Alan Schmitt [this message]
-- strict thread matches above, loose matches on Subject: below --
2026-08-04 7:44 Alan Schmitt
2026-07-28 12:44 Alan Schmitt
2026-07-21 16:02 Alan Schmitt
2026-07-14 7:16 Alan Schmitt
2026-07-07 13:29 Alan Schmitt
2026-06-30 13:25 Alan Schmitt
2026-06-23 10:07 Alan Schmitt
2026-06-16 10:51 Alan Schmitt
2026-06-09 7:39 Alan Schmitt
2026-06-02 9:01 Alan Schmitt
2026-05-26 7:36 Alan Schmitt
2026-05-19 8:52 Alan Schmitt
2026-05-12 7:28 Alan Schmitt
2026-05-05 9:35 Alan Schmitt
2026-04-28 7:59 Alan Schmitt
2026-04-21 9:34 Alan Schmitt
2026-04-14 9:50 Alan Schmitt
2026-04-07 9:32 Alan Schmitt
2026-03-31 6:10 Alan Schmitt
2026-03-24 9:58 Alan Schmitt
2026-03-17 14:39 Alan Schmitt
2026-03-10 13:30 Alan Schmitt
2026-03-03 13:54 Alan Schmitt
2026-02-24 13:36 Alan Schmitt
2026-02-17 13:47 Alan Schmitt
2026-02-10 10:36 Alan Schmitt
2026-02-03 10:04 Alan Schmitt
2026-01-27 12:41 Alan Schmitt
2026-01-20 9:19 Alan Schmitt
2026-01-13 8:27 Alan Schmitt
2026-01-06 13:14 Alan Schmitt
2025-12-30 9:33 Alan Schmitt
2025-12-23 11:00 Alan Schmitt
2025-12-16 13:30 Alan Schmitt
2025-12-09 15:04 Alan Schmitt
2025-12-02 10:39 Alan Schmitt
2025-11-25 13:49 Alan Schmitt
2025-11-18 14:01 Alan Schmitt
2025-11-11 9:49 Alan Schmitt
2025-11-04 13:21 Alan Schmitt
2025-10-28 13:30 Alan Schmitt
2025-10-21 9:17 Alan Schmitt
2025-10-14 9:56 Alan Schmitt
2025-10-07 12:22 Alan Schmitt
2025-09-30 13:12 Alan Schmitt
2025-09-23 13:23 Alan Schmitt
2025-09-16 11:52 Alan Schmitt
2025-09-09 12:30 Alan Schmitt
2025-09-02 12:23 Alan Schmitt
2025-08-26 12:34 Alan Schmitt
2025-08-19 12:20 Alan Schmitt
2025-08-12 15:32 Alan Schmitt
2025-08-05 8:17 Alan Schmitt
2025-07-29 9:36 Alan Schmitt
2025-07-22 12:07 Alan Schmitt
2025-07-15 17:14 Alan Schmitt
2025-07-08 12:45 Alan Schmitt
2025-07-01 11:16 Alan Schmitt
2025-06-24 14:02 Alan Schmitt
2025-06-17 6:44 Alan Schmitt
2025-06-10 13:36 Alan Schmitt
2025-06-03 9:19 Alan Schmitt
2025-05-27 9:22 Alan Schmitt
2025-05-20 11:52 Alan Schmitt
2025-05-13 9:40 Alan Schmitt
2025-05-06 7:24 Alan Schmitt
2025-04-29 8:39 Alan Schmitt
2025-04-22 11:50 Alan Schmitt
2025-04-15 9:51 Alan Schmitt
2025-04-08 13:14 Alan Schmitt
2025-04-01 9:12 Alan Schmitt
2025-03-25 8:06 Alan Schmitt
2025-03-18 10:18 Alan Schmitt
2025-03-11 15:00 Alan Schmitt
2025-03-04 14:01 Alan Schmitt
2025-02-25 10:36 Alan Schmitt
2025-02-18 14:33 Alan Schmitt
2025-02-11 7:17 Alan Schmitt
2025-02-04 12:05 Alan Schmitt
2025-01-28 13:24 Alan Schmitt
2025-01-21 15:47 Alan Schmitt
2025-01-14 8:20 Alan Schmitt
2025-01-07 17:26 Alan Schmitt
2024-12-31 8:03 Alan Schmitt
2024-12-24 8:55 Alan Schmitt
2024-12-17 13:05 Alan Schmitt
2024-12-10 13:48 Alan Schmitt
2024-12-03 14:44 Alan Schmitt
2024-11-26 8:30 Alan Schmitt
2024-11-19 6:52 Alan Schmitt
2024-11-12 15:00 Alan Schmitt
2024-11-05 13:22 Alan Schmitt
2024-10-29 13:30 Alan Schmitt
2024-10-22 12:42 Alan Schmitt
2024-10-15 13:31 Alan Schmitt
2024-10-08 10:56 Alan Schmitt
2024-10-01 13:37 Alan Schmitt
2024-09-24 13:18 Alan Schmitt
2024-09-17 14:02 Alan Schmitt
2024-09-10 13:55 Alan Schmitt
2024-09-03 8:24 Alan Schmitt
2024-08-27 9:02 Alan Schmitt
2024-08-20 9:29 Alan Schmitt
2024-08-13 13:21 Alan Schmitt
2024-08-06 9:00 Alan Schmitt
2024-07-30 13:26 Alan Schmitt
2024-07-23 13:30 Alan Schmitt
2024-07-16 6:24 Alan Schmitt
2024-07-09 9:19 Alan Schmitt
2024-07-02 7:30 Alan Schmitt
2024-06-25 13:58 Alan Schmitt
2024-06-18 13:05 Alan Schmitt
2024-06-11 15:04 Alan Schmitt
2024-06-04 13:26 Alan Schmitt
2024-05-28 9:07 Alan Schmitt
2024-05-21 13:07 Alan Schmitt
2024-05-14 13:25 Alan Schmitt
2024-05-07 7:30 Alan Schmitt
2024-04-30 7:22 Alan Schmitt
2024-04-23 12:17 Alan Schmitt
2024-04-16 12:00 Alan Schmitt
2024-04-09 9:15 Alan Schmitt
2024-04-02 14:31 Alan Schmitt
2024-03-26 6:32 Alan Schmitt
2024-03-19 15:09 Alan Schmitt
2024-03-12 10:31 Alan Schmitt
2024-03-05 14:50 Alan Schmitt
2024-02-27 13:53 Alan Schmitt
2024-02-20 9:12 Alan Schmitt
2024-02-13 8:42 Alan Schmitt
2024-02-06 15:14 Alan Schmitt
2024-01-30 14:16 Alan Schmitt
2024-01-23 9:45 Alan Schmitt
2024-01-16 10:01 Alan Schmitt
2024-01-09 13:40 Alan Schmitt
2024-01-02 8:59 Alan Schmitt
2023-12-26 10:12 Alan Schmitt
2023-12-19 10:10 Alan Schmitt
2023-12-12 10:20 Alan Schmitt
2023-12-05 10:13 Alan Schmitt
2023-11-28 9:09 Alan Schmitt
2023-11-21 7:47 Alan Schmitt
2023-11-14 13:42 Alan Schmitt
2023-11-07 10:31 Alan Schmitt
2023-10-31 10:43 Alan Schmitt
2023-10-24 9:17 Alan Schmitt
2023-10-17 7:46 Alan Schmitt
2023-10-10 7:48 Alan Schmitt
2023-10-03 13:00 Alan Schmitt
2023-09-19 8:54 Alan Schmitt
2023-09-12 13:21 Alan Schmitt
2023-09-05 9:00 Alan Schmitt
2023-08-29 13:04 Alan Schmitt
2023-08-22 9:20 Alan Schmitt
2023-08-15 16:33 Alan Schmitt
2023-08-08 8:53 Alan Schmitt
2023-08-01 7:13 Alan Schmitt
2023-07-25 8:45 Alan Schmitt
2023-07-11 8:45 Alan Schmitt
2023-07-04 9:18 Alan Schmitt
2023-06-27 8:38 Alan Schmitt
2023-06-20 9:52 Alan Schmitt
2023-06-13 7:09 Alan Schmitt
2023-06-06 14:22 Alan Schmitt
2023-05-30 15:43 Alan Schmitt
2023-05-23 9:41 Alan Schmitt
2023-05-16 13:05 Alan Schmitt
2023-05-09 11:49 Alan Schmitt
2023-05-02 8:01 Alan Schmitt
2023-04-25 9:25 Alan Schmitt
2023-04-18 8:50 Alan Schmitt
2023-04-11 12:41 Alan Schmitt
2023-04-04 8:45 Alan Schmitt
2023-03-28 7:21 Alan Schmitt
2023-03-21 10:07 Alan Schmitt
2023-03-14 9:52 Alan Schmitt
2023-03-07 9:02 Alan Schmitt
2023-02-28 14:38 Alan Schmitt
2023-02-21 10:19 Alan Schmitt
2023-02-14 8:12 Alan Schmitt
2023-02-07 8:16 Alan Schmitt
2023-01-31 6:44 Alan Schmitt
2023-01-24 8:57 Alan Schmitt
2023-01-17 8:37 Alan Schmitt
2022-11-29 14:53 Alan Schmitt
2022-09-27 7:17 Alan Schmitt
2022-09-20 14:01 Alan Schmitt
2022-09-13 8:40 Alan Schmitt
2022-08-23 8:06 Alan Schmitt
2022-08-16 8:51 Alan Schmitt
2022-08-09 8:02 Alan Schmitt
2022-08-02 9:51 Alan Schmitt
2022-07-26 17:54 Alan Schmitt
2022-07-19 8:58 Alan Schmitt
2022-07-12 7:59 Alan Schmitt
2022-07-05 7:42 Alan Schmitt
2022-06-28 7:37 Alan Schmitt
2022-06-21 8:06 Alan Schmitt
2022-06-14 9:29 Alan Schmitt
2022-06-07 10:15 Alan Schmitt
2022-05-31 12:29 Alan Schmitt
2022-05-24 8:04 Alan Schmitt
2022-05-17 7:12 Alan Schmitt
2022-05-10 12:30 Alan Schmitt
2022-05-03 9:11 Alan Schmitt
2022-04-26 6:44 Alan Schmitt
2022-04-19 5:34 Alan Schmitt
2022-04-12 8:10 Alan Schmitt
2022-04-05 11:50 Alan Schmitt
2022-03-29 7:42 Alan Schmitt
2022-03-22 13:01 Alan Schmitt
2022-03-15 9:59 Alan Schmitt
2022-03-01 13:54 Alan Schmitt
2022-02-22 12:43 Alan Schmitt
2022-02-08 13:16 Alan Schmitt
2022-02-01 13:00 Alan Schmitt
2022-01-25 12:44 Alan Schmitt
2022-01-11 8:20 Alan Schmitt
2022-01-04 7:56 Alan Schmitt
2021-12-28 8:59 Alan Schmitt
2021-12-21 9:11 Alan Schmitt
2021-12-14 11:02 Alan Schmitt
2021-11-30 10:51 Alan Schmitt
2021-11-16 8:41 Alan Schmitt
2021-11-09 10:08 Alan Schmitt
2021-11-02 8:50 Alan Schmitt
2021-10-19 8:23 Alan Schmitt
2021-09-28 6:37 Alan Schmitt
2021-09-21 9:09 Alan Schmitt
2021-09-07 13:23 Alan Schmitt
2021-08-24 13:44 Alan Schmitt
2021-08-17 6:24 Alan Schmitt
2021-08-10 16:47 Alan Schmitt
2021-07-27 8:54 Alan Schmitt
2021-07-20 12:58 Alan Schmitt
2021-07-06 12:33 Alan Schmitt
2021-06-29 12:24 Alan Schmitt
2021-06-22 9:04 Alan Schmitt
2021-06-01 9:23 Alan Schmitt
2021-05-25 7:30 Alan Schmitt
2021-05-11 14:47 Alan Schmitt
2021-05-04 8:57 Alan Schmitt
2021-04-27 14:26 Alan Schmitt
2021-04-20 9:07 Alan Schmitt
2021-04-06 9:42 Alan Schmitt
2021-03-30 14:55 Alan Schmitt
2021-03-23 9:05 Alan Schmitt
2021-03-16 10:31 Alan Schmitt
2021-03-09 10:58 Alan Schmitt
2021-02-23 9:51 Alan Schmitt
2021-02-16 13:53 Alan Schmitt
2021-02-02 13:56 Alan Schmitt
2021-01-26 13:25 Alan Schmitt
2021-01-19 14:28 Alan Schmitt
2021-01-12 9:47 Alan Schmitt
2021-01-05 11:22 Alan Schmitt
2020-12-29 9:59 Alan Schmitt
2020-12-22 8:48 Alan Schmitt
2020-12-15 9:51 Alan Schmitt
2020-12-01 8:54 Alan Schmitt
2020-11-03 15:15 Alan Schmitt
2020-10-27 8:43 Alan Schmitt
2020-10-20 8:15 Alan Schmitt
2020-10-06 7:22 Alan Schmitt
2020-09-29 7:02 Alan Schmitt
2020-09-22 7:27 Alan Schmitt
2020-09-08 13:11 Alan Schmitt
2020-09-01 7:55 Alan Schmitt
2020-08-18 7:25 Alan Schmitt
2020-07-28 16:57 Alan Schmitt
2020-07-21 14:42 Alan Schmitt
2020-07-14 9:54 Alan Schmitt
2020-07-07 10:04 Alan Schmitt
2020-06-30 7:00 Alan Schmitt
2020-06-16 8:36 Alan Schmitt
2020-06-09 8:28 Alan Schmitt
2020-05-19 9:52 Alan Schmitt
2020-05-12 7:45 Alan Schmitt
2020-05-05 7:45 Alan Schmitt
2020-04-28 12:44 Alan Schmitt
2020-04-21 8:58 Alan Schmitt
2020-04-14 7:28 Alan Schmitt
2020-04-07 7:51 Alan Schmitt
2020-03-31 9:54 Alan Schmitt
2020-03-24 9:31 Alan Schmitt
2020-03-17 11:04 Alan Schmitt
2020-03-10 14:28 Alan Schmitt
2020-03-03 8:00 Alan Schmitt
2020-02-25 8:51 Alan Schmitt
2020-02-18 8:18 Alan Schmitt
2020-02-04 8:47 Alan Schmitt
2020-01-28 10:53 Alan Schmitt
2020-01-21 14:08 Alan Schmitt
2020-01-14 14:16 Alan Schmitt
2020-01-07 13:43 Alan Schmitt
2019-12-31 9:18 Alan Schmitt
2019-12-17 8:52 Alan Schmitt
2019-12-10 8:21 Alan Schmitt
2019-12-03 15:42 Alan Schmitt
2019-11-26 8:33 Alan Schmitt
2019-11-12 13:21 Alan Schmitt
2019-11-05 6:55 Alan Schmitt
2019-10-15 7:28 Alan Schmitt
2019-09-03 7:35 Alan Schmitt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m2ldacaloo.fsf@petitepomme.net \
--to=alan.schmitt@polytechnique.org \
--cc=caml-list@inria.fr \
--cc=lwn@lwn.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox