<feed xmlns='http://www.w3.org/2005/Atom'>
<title>sisudoc-ocda-lib/dlang/src/ocda/load_pod.d, branch main</title>
<subtitle>SiSU Spine: tools</subtitle>
<link rel='alternate' type='text/html' href='https://git.sisudoc.org/projects/sisudoc-ocda-lib/'/>
<entry>
<title>format 2.1: ocda-read, the readers folded in</title>
<updated>2026-10-13T00:24:11+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-10-13T00:24:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sisudoc.org/projects/sisudoc-ocda-lib/commit/?id=4e4f2f8c2b2c043077390cb4ccf7ce97ffe4ac6b'/>
<id>4e4f2f8c2b2c043077390cb4ccf7ce97ffe4ac6b</id>
<content type='text'>
ocda-read, one reader where there were two. The .ssp reader and the
.ocda.db reader each had their own parser; this one is built on the
library, so every mode reads a .ssp, a .ocda.db and a pod, and says
the same thing of each. Its output modules are the .ssp reader's,
copied (the reader repositories are kept, frozen) and moved onto the
library's model; --languages and --files come from the database
reader.

  ocda-read [--tree|--html|--llm-text|--llm-jsonl|--images|
             --verify --image-dir=&lt;d&gt;|--languages|--files|
             --report-unknown|--validate] &lt;file&gt; [lang]

In D every mode of both readers; in Gleam the modes the Gleam readers
had (the summary, --tree, --languages, --files, --report-unknown),
whose output is the D reader's, byte for byte. In each language it
lives in src/read/ and is not part of the library: dub configurations
keep it out of a dependant's build in D, and Gleam compiles all of
src/ but a dependant need not use it.

Checked over the markup document samples: against the .ssp reader on
a .ssp, byte for byte after the first line in every D mode but the
summary, whose closing hint differs; against the database reader on a
.ocda.db, --files and --languages (its id column left out); the same
output from the .ssp, the .ocda.db and the .sisupod; and D == Gleam.
The database reader's --outline is not reproduced: it ordered
headings within their own section, so that other sections' headings
fell among the body's. --outline here is --tree.

What writing it found in the library: the database loader could not
say what it had not understood. It asked for columns by name and so
never saw the rest, and reported that it had understood everything.
It now counts them on the conditions under which the .ssp writes the
same property, and --report-unknown is the same from every form.

ocda.inventory answers two questions about the file rather than the
document: its languages, in the manifest's order, each with the
markup it was made from and the sha256 of its .ssp, for every form
alike; and what a .ocda.db carries besides the abstraction. In Gleam
the sha256 comes from OTP's crypto through a four line Erlang FFI.

The flake's default is all three D programs in one result: built
separately into the same link, each replaced the one before.

(assisted by Claude-Code)


</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
ocda-read, one reader where there were two. The .ssp reader and the
.ocda.db reader each had their own parser; this one is built on the
library, so every mode reads a .ssp, a .ocda.db and a pod, and says
the same thing of each. Its output modules are the .ssp reader's,
copied (the reader repositories are kept, frozen) and moved onto the
library's model; --languages and --files come from the database
reader.

  ocda-read [--tree|--html|--llm-text|--llm-jsonl|--images|
             --verify --image-dir=&lt;d&gt;|--languages|--files|
             --report-unknown|--validate] &lt;file&gt; [lang]

In D every mode of both readers; in Gleam the modes the Gleam readers
had (the summary, --tree, --languages, --files, --report-unknown),
whose output is the D reader's, byte for byte. In each language it
lives in src/read/ and is not part of the library: dub configurations
keep it out of a dependant's build in D, and Gleam compiles all of
src/ but a dependant need not use it.

Checked over the markup document samples: against the .ssp reader on
a .ssp, byte for byte after the first line in every D mode but the
summary, whose closing hint differs; against the database reader on a
.ocda.db, --files and --languages (its id column left out); the same
output from the .ssp, the .ocda.db and the .sisupod; and D == Gleam.
The database reader's --outline is not reproduced: it ordered
headings within their own section, so that other sections' headings
fell among the body's. --outline here is --tree.

What writing it found in the library: the database loader could not
say what it had not understood. It asked for columns by name and so
never saw the rest, and reported that it had understood everything.
It now counts them on the conditions under which the .ssp writes the
same property, and --report-unknown is the same from every form.

ocda.inventory answers two questions about the file rather than the
document: its languages, in the manifest's order, each with the
markup it was made from and the sha256 of its .ssp, for every form
alike; and what a .ocda.db carries besides the abstraction. In Gleam
the sha256 comes from OTP's crypto through a four line Erlang FFI.

The flake's default is all three D programs in one result: built
separately into the same link, each replaced the one before.

(assisted by Claude-Code)


</pre>
</div>
</content>
</entry>
<entry>
<title>format 2.0: abstraction as library, in D and Gleam</title>
<updated>2026-09-26T13:47:07+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-26T13:47:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sisudoc.org/projects/sisudoc-ocda-lib/commit/?id=fda48e417435e31a3122bfa7ca563333628aed99'/>
<id>fda48e417435e31a3122bfa7ca563333628aed99</id>
<content type='text'>
The object-centric document abstraction that sisudoc-spine builds from
SiSU markup, read as a library: the model, and a loader for each form
it is written in - the .ssp (text), the .ocda.db (sqlite), and a pod
archive carrying a .ssp (.sisupod, .zip). Begun 2026-09-25; this is
the library as it stood at format 2.0.

The readers (sisudoc-ssp-reader, sisudoc-ocda-db-reader) each read one
form and print. A writer needs neither: it needs the document. So the
model and the loaders live here, ocda.model imports nothing, and a
program built on the library cannot tell which form it was handed.
ocda.load is the one place that decides what a path is, so a new
input form is added once and every program gains it. The model and
the .ssp loader began as the .ssp reader's code, moved and renamed to
the level they belong to; the .ocda.db loader is new.

The Gleam library is a deliberate field-for-field mirror of the D one,
including where that is not the most idiomatic Gleam: a difference in
one language and not the other would show in every comparison and
mean nothing.

The claim holds only if the loaders agree, so the library asks:

  ocda-agree  &lt;doc&gt;.ssp &lt;doc&gt;.ocda.db [lang]   ten fields, per object
  ocda-dump   &lt;file&gt; [lang]                    the whole model,
                                               canonically

The dump is an oracle, not an output format, and the D and Gleam
dumps are byte identical, so four questions are a diff: D and Gleam,
each from the .ssp and from the .ocda.db. Over the markup document
samples all four hold, every document-language; a .sisupod gives the
same model as the .ssp beside it.

None of that held at first, and what the checks found is the record
of how the specification became enough:

- an object whose first text line is blank lost it (the loader asked
  whether the text was empty, not whether a line had been seen);
  seven sample documents open verse that way. Found by agree; fixed
  here and in the .ssp reader, which carried the same code.
- found by the dump: the identifier and the anchor are omitted by the
  text form when they can be derived and stored by the database
  always, so the loaders derive them, and the rule went into the
  specification (derived values); make and doc_has share one table in
  the database under a key prefix, which the loaders strip; the JSON
  columns were scanned, not parsed, and Phobos writes "/" as "\/";
  and translation.ocn_aligned is a fact about the file, not the
  document, so neither loader puts it in the model.
- in Gleam, a JSON element decoder fell through to a fallback giving
  "", so a float column read as empty strings: a value that could not
  be read turned into one that looked read.
- found by the writers: anchor_tags, heading_lev_anchor, segment_epub
  and segment_epub_is were in the specification and read by nothing.

ocda.images gives an image's bytes from whichever form the document
came from (the database's files table, the archive entry, or beside
a .ssp at media/image/), and says beforehand whether it can.

The Gleam library reads a .zip pod but not a .sisupod: the zstd frame
around it has no implementation on the BEAM that builds sandboxed. It
says so, and says zstd -d, rather than calling the file malformed.

gleam/ builds with nix-gleam's builder, kept in gleam/nix-gleam/ (MIT)

Use:

  dlang/  nix build        ocda-dump, ocda-agree; or a dub path
                           dependency on dlang/
  gleam/  nix build        ocda-lib dump | agree

See README.md, and dlang/README.md and gleam/README.md.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The object-centric document abstraction that sisudoc-spine builds from
SiSU markup, read as a library: the model, and a loader for each form
it is written in - the .ssp (text), the .ocda.db (sqlite), and a pod
archive carrying a .ssp (.sisupod, .zip). Begun 2026-09-25; this is
the library as it stood at format 2.0.

The readers (sisudoc-ssp-reader, sisudoc-ocda-db-reader) each read one
form and print. A writer needs neither: it needs the document. So the
model and the loaders live here, ocda.model imports nothing, and a
program built on the library cannot tell which form it was handed.
ocda.load is the one place that decides what a path is, so a new
input form is added once and every program gains it. The model and
the .ssp loader began as the .ssp reader's code, moved and renamed to
the level they belong to; the .ocda.db loader is new.

The Gleam library is a deliberate field-for-field mirror of the D one,
including where that is not the most idiomatic Gleam: a difference in
one language and not the other would show in every comparison and
mean nothing.

The claim holds only if the loaders agree, so the library asks:

  ocda-agree  &lt;doc&gt;.ssp &lt;doc&gt;.ocda.db [lang]   ten fields, per object
  ocda-dump   &lt;file&gt; [lang]                    the whole model,
                                               canonically

The dump is an oracle, not an output format, and the D and Gleam
dumps are byte identical, so four questions are a diff: D and Gleam,
each from the .ssp and from the .ocda.db. Over the markup document
samples all four hold, every document-language; a .sisupod gives the
same model as the .ssp beside it.

None of that held at first, and what the checks found is the record
of how the specification became enough:

- an object whose first text line is blank lost it (the loader asked
  whether the text was empty, not whether a line had been seen);
  seven sample documents open verse that way. Found by agree; fixed
  here and in the .ssp reader, which carried the same code.
- found by the dump: the identifier and the anchor are omitted by the
  text form when they can be derived and stored by the database
  always, so the loaders derive them, and the rule went into the
  specification (derived values); make and doc_has share one table in
  the database under a key prefix, which the loaders strip; the JSON
  columns were scanned, not parsed, and Phobos writes "/" as "\/";
  and translation.ocn_aligned is a fact about the file, not the
  document, so neither loader puts it in the model.
- in Gleam, a JSON element decoder fell through to a fallback giving
  "", so a float column read as empty strings: a value that could not
  be read turned into one that looked read.
- found by the writers: anchor_tags, heading_lev_anchor, segment_epub
  and segment_epub_is were in the specification and read by nothing.

ocda.images gives an image's bytes from whichever form the document
came from (the database's files table, the archive entry, or beside
a .ssp at media/image/), and says beforehand whether it can.

The Gleam library reads a .zip pod but not a .sisupod: the zstd frame
around it has no implementation on the BEAM that builds sandboxed. It
says so, and says zstd -d, rather than calling the file malformed.

gleam/ builds with nix-gleam's builder, kept in gleam/nix-gleam/ (MIT)

Use:

  dlang/  nix build        ocda-dump, ocda-agree; or a dub path
                           dependency on dlang/
  gleam/  nix build        ocda-lib dump | agree

See README.md, and dlang/README.md and gleam/README.md.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
</feed>
