{"id":13929253,"url":"https://github.com/nickpascucci/verso","last_synced_at":"2025-07-19T11:31:19.293Z","repository":{"id":57671580,"uuid":"234587316","full_name":"nickpascucci/verso","owner":"nickpascucci","description":"A new approach to literate programming.","archived":false,"fork":false,"pushed_at":"2024-07-07T08:49:24.000Z","size":378,"stargazers_count":74,"open_issues_count":2,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-11T15:30:17.701Z","etag":null,"topics":["literate-programming"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nickpascucci.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-17T16:18:50.000Z","updated_at":"2024-09-26T15:00:27.000Z","dependencies_parsed_at":"2022-09-02T14:11:08.641Z","dependency_job_id":null,"html_url":"https://github.com/nickpascucci/verso","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickpascucci%2Fverso","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickpascucci%2Fverso/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickpascucci%2Fverso/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickpascucci%2Fverso/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickpascucci","download_url":"https://codeload.github.com/nickpascucci/verso/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226597674,"owners_count":17657188,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["literate-programming"],"created_at":"2024-08-07T18:02:12.885Z","updated_at":"2024-11-26T18:30:36.316Z","avatar_url":"https://github.com/nickpascucci.png","language":"Rust","funding_links":[],"categories":["others"],"sub_categories":[],"readme":"# verso|recto - A Different Approach to Literate Programming\n\n[![CI Status](https://github.com/nickpascucci/verso/workflows/Rust/badge.svg)](https://github.com/nickpascucci/verso/actions)\n[![Crates.io](https://img.shields.io/crates/v/verso)](https://crates.io/crates/verso)\n\n\u003e Literate programming is the art of preparing programs for human readers.\n\n_Norman Ramsey, on the [noweb homepage](https://www.cs.tufts.edu/~nr/noweb/)._\n\nLiterate Programming (LP) tries to address a common problem with software systems: by reading the\ncode one can discover _how_ a thing is done, but not _why_ it is done that way. Every program has a\n\"theory of operation\" embedded within its logic, but this is often hidden. Comments within the code\nand documentation of APIs are helpful but insufficient for this task. Often the documentation\ngeneration systems provided with a programming language do not provide a way to contextualize the\ncode they describe within the larger system. For programs which rely on a more advanced mathematical\nbackground, it is also often difficult to embed equations or other markup in the documentation.\n\nExisting LP tools such as _WEB_, _noweb_, and _Org Babel_ attempt to address this by taking the\nfollowing approach:\n\n1. Embed the program source code within a prose document which explains the author's thinking.\n2. Provide mechanisms for organizing code into abstract chunks, which can be recombined in\n   different orders than they are defined and referenced throughout the document.\n3. Process the combined document in one of two ways: either `tangle` the source code out of the\n   document into a computer-friendly version, or `weave` the document into a form ready for humans\n   to read.\n\nOverall this is an improvement on inline documentation and can provide much more context to the\nreader than mainstream approaches. Unfortunately it does suffer some serious drawbacks as well:\n\n- The source code is embedded within a markup file, making it inaccessible to language-specific\n  tooling such as editors, compilers, and static analysis tools. In order to use these the code must\n  first be tangled.\n- Similarly, to build your literate program the end user must have the appropriate tools installed\n  in addition to the language tooling needed to compile the source.\n- Most programmers have spent years working directly in the machine-friendly source representation\n  rather than a literate style, introducing a barrier to entry to writing literate programs. Porting\n  an existing project to a literate representation is nontrivial.\n\n`verso|recto` takes a different approach. It considers the source file as a first-class citizen to\nbe referenced by the documentation. Rather than embedding source code in documents, or documents in\nsource code, lightweight annotations are used to mark sections of interest within the code which can\nbe easily referenced by prose documents. There is no `tangle` step, and source files remain fully\nvalid inputs for compilers, editors, and other tools. There is no need to translate line numbers or\nformatting between literate sources and what the compiler sees.\n\n## What traditional LP systems get right\n\nA lot of things! Here are a few ideas that the traditional systems pioneered and `verso|recto`\nborrows:\n\n- Support a many-to-many relationship between LP documents and source files.\n  - In `noweb`, a document may contain several root chunks which can each be sent to different\n    source files, and multiple LP documents can be fed into the `tangle` tool at once (they are\n    concatenated).\n- The more modern tools support multiple programming and markup languages.\n- `noweb` offers a pipelined architecture which makes it easy to insert processing stages to meet a\n  user's needs.\n- They generate indices and cross references within the human-readable output.\n\n## Using `verso|recto`\n\n`verso|recto` is driven by annotations within your source files, defining regions which can be\nreferenced by other documents. These regions are called \"fragments\".\n\n### Annotating a file\n\nAnnotations are quite simple. To mark a region of code and make a fragment, simply add a pair of\ncomments around the region with the symbols `@\u003c` and `\u003e@` followed by a unique ID. The ID can be any\nstring of alphanumeric characters and the characters `/`, `_`, or `-`, though it should be both\nunique within your project and valid in the source file you're annotating. (The period character\n(`.`) is reserved, as it is used for inserting metadata about fragments.) Other characters may be\nadded to the \"safe\" list in the future. If a character you want to use is not listed here, please\nfile an issue on GitHub (or better yet, send a PR)!\n\nFragments can also be nested. This is particularly useful when you want to annotate a region of a\nsource file that is already contained within a larger \"outer\" fragment. The annotations for the\n\"inner\" fragment will not appear in the output. This is best illustrated with an example; see the\nfollowing [source](./examples/test/nested.rs), [prose](./examples/test/nested.md), and\n[output](./examples/reference/test/nested.md) files.\n\n### Referencing annotations\n\nIn order to insert a fragment in another file, add a line containing the symbol `@@` followed by the\nID of the annotation (e.g. `@@12345`). When the file is woven using the `recto` command (see the\nnext section), the line will be replaced with the contents of th fragment. You can add any markup\nyou like around the line to provide formatting.\n\nTo insert a group of fragments, a regular expression can be used after the `@*` symbol. All of the\nfragments whose ID matches the expression will be inserted in place of the symbol, in lexicographic\norder by their IDs.\n\nSometimes it is also desirable to refer to metadata about a fragment. Currently, `verso|recto`\nsupports the following metadata insertion operators:\n\n1. _Filename._ `@?id.file` inserts the name of the file the fragment was drawn from.\n2. _Line number._ `@?id.line` inserts the line number on which the fragment began.\n3. _Column number._ `@?id.col` inserts the column number at which the fragment began. (Currently\n   this value is always 0, as fragments always begin at the start of a line.)\n4. _Quick location._ `@?id.loc` inserts the file name, starting line number, and column number for\n   the fragment in the format `file (line:col)`. This is useful if you just want to quickly refer to\n   the metadata without futzing with the formatting.\n\n### Weaving a document for human consumption\n\nThe `verso` command will read all of the files specified on the command line, extract their\nfragments, and output the result to stdout. In turn the `recto` command will read fragments from\nstdin. This makes the two programs easy to use together via pipes:\n\n```\nverso main.rs lib.rs | recto build chap1.tex chap2.tex blog/home.md\n      ^       ^              ^     ^         ^         ^\n      +-------+              |     +---------+---------+\n      |                      |                         |\n      |                      |                         |\n      +--- Source files      +--- Output directory     +--- Prose files\n```\n\nEach of the woven files is written to the output directory, provided as the first argument, in the\nsame relative location as given on the command line. So, for example, the file `blog/home.md` above\nwill be written to `build/blog/home.md` when it is woven.\n\nNote that, although the two programs appear to run in parallel, `verso` won't send input to `recto`\nuntil it has successfully extracted fragments from all of the source files it was given and that\n`recto` will not start weaving files together until it receives those fragments. Because of this if\n`verso` fails, `recto` will also fail.\n\n### Full symbology\n\nFor reference, here is a table with the full symbology. Note that in the (hopefully rare) case that\nyour language has symbols which collide with the defaults used by `verso|recto`, you can override\nthem by using the listed environment variables.\n\n| Name            | Symbol   | Description                       | Override Variable             |\n| --------------- | -------- | --------------------------------- | ----------------------------- |\n| Fragment Open   | `@\u003c`     | Starts a named fragment.          | `VERSO_FRAGMENT_OPEN_SYMBOL`  |\n| Fragment Close  | `\u003e@`     | Ends a named fragment.            | `VERSO_FRAGMENT_CLOSE_SYMBOL` |\n| Halt            | `@!halt` | Halts fragment extraction.        | `VERSO_HALT_SYMBOL`           |\n| Insert Fragment | `@@`     | Insert a fragment by ID.          | `RECTO_INSERTION_SYMBOL`      |\n| Insert Pattern  | `@*`     | Insert a fragment by ID pattern.  | `RECTO_PATTERN_SYMBOL`        |\n| Insert Metadata | `@?`     | Insert metadata about a fragment. | `RECTO_METADATA_SYMBOL`       |\n\n## The Name\n\n\u003e Recto and verso are respectively, the text written or printed on the \"right\" or \"front\" side and\n\u003e on the \"back\" side of a leaf of paper in a bound item such as a codex, book, broadsheet, or\n\u003e pamphlet.\n\n_[Wikipedia - Recto and Verso](https://en.wikipedia.org/wiki/Recto_and_verso)_\n\n_(Note that, conveniently, the `verso` program goes on the left of the pipe while `recto` goes on\nthe right.)_\n\n## Contributors\n\n- [@nickpascucci](https://github.com/nickpascucci/)\n- [@karlicoss](https://github.com/karlicoss/)\n- [@elidhu](https://github.com/elidhu/)\n\n## Future Work\n\n- Add support for custom formatting of annotation properties within the woven output.\n- Paralellize file processing in Verso, and both reading from `stdin` and file reading in Recto.\n- Add `--fragments-from` option to specify a source other than stdin for fragments.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickpascucci%2Fverso","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickpascucci%2Fverso","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickpascucci%2Fverso/lists"}