Lamp BibleDownload

Authoring modules

The data model: how a module document is shaped, how verses are referenced, and how annotations attach to text. For the mechanics of producing the file, see Building a .lamp file.

The pipeline

A module is authored as JSON against a published schema, then converted to SQLite and compressed. This page covers the first step — the shape of the JSON. The conversion is on Building a .lamp file.

source text  →  module JSON  →  SQLite  →  raw DEFLATE  →  module.lamp
                └── this page ──┘  └──────── building a .lamp ───────┘

The container, briefly

A .lamp file is a SQLite database compressed with raw DEFLATE (zlib level 9, wbits=-15). One file holds one module — one translation, one book of a commentary, one highlight set — and is named after it. Compression is typically 95% or better.

The library bundled inside the app keeps many modules in a single database, so its tables carry identifier columns to separate co-resident modules. A standalone .lamp names its one module in a module_format table instead; where its tables keep a module_id column as well, every row must carry that same ID.

Verse references

Every reference in every schema uses a single integer format, BBCCCVVV: two digits of book number, three of chapter, three of verse.

ReferenceValue
Genesis 1:11001001
Matthew 1:140001001
Ephesians 2:849002008

Ranges are expressed as a start and end pair, conventionally sv and ev. Because the encoding sorts correctly as an integer, range queries and ordering come free.

Annotated text

Text fields are either a plain string or an object carrying the string plus offset-based annotations. Keeping annotations out of the text — rather than wrapping it in markup — means the plain text stays clean for search, display and speech.

{
  "text": "In the beginning God created the heaven and the earth.",
  "annotations": [
    {
      "type": "strongs",
      "start": 7,
      "end": 16,
      "text": "beginning",
      "data": { "strongs": "H7225" }
    },
    {
      "type": "strongs",
      "start": 17,
      "end": 20,
      "text": "God",
      "data": { "strongs": "H430", "lemma": "אֱלֹהִים" }
    }
  ]
}

start is inclusive and end exclusive, so text[start:end] must equal the annotation’s own text field. That redundancy is deliberate — it is what lets a validator catch a bad offset.

Annotation types vary a little by schema; the common ones are:

TypeCarries
strongsStrong’s number, optional lemma and morphology code
scripturesv, optional ev, or a list of refs
red-letterWords of Christ
greek / hebrewOriginal-language text, optionally with a Strong’s number
lexicon-refCross-reference to another lexicon entry
linkExternal URL
emphasisBold, italic or underline

The schemas

Each module type has a JSON Schema, all sharing common definitions for annotations, references, metadata and media. Every one is downloadable here, along with a worked sample module that validates against it.

SchemaShape
translation_schema.jsonMetadata, then books → chapters → verses. Chapters carry section headings; verses carry content, footnotes, and paragraph and poetry markers.
lexicon_schema.jsonEntries keyed by identifier, with lemma, transliteration, pronunciation, definition, numbered senses, usage and references.
lexicon_mapping_schema.jsonA map from one keying system to another — Strong’s to BDB, for example, where one key may map to several entries.
commentary_schema.jsonOne file per book: chapters → sections → pericopae → verse commentary, with footnotes and an abbreviations list. Version 2.2 adds an optional source-ordered form, below.
commentary_series_schema.jsonSeries-level metadata: editor, publisher, preface, abbreviations, bibliography and the volume list.
book_schema.jsonA long-form publication: metadata, then sections — front matter, parts, chapters, appendices — nesting to any depth, each holding content blocks. Footnotes and media are defined once for the whole book.
notes_schema.jsonA simplified commentary: one file per book, chapters with an introduction and verse notes keyed by sv/ev.
devotional_schema.jsonMetadata, summary, and content either as a flat block array or as introduction/sections/conclusion, plus footnotes.
highlight_schema.jsonVerses, each with highlight spans carrying start and end character offsets, a style and a colour.
plan_schema.jsonReading assignments by day.
quiz_schema.jsonQuestions and answers per reading, graded by age group.

Commentary schema 2.2

Version 2.2 adds a second way to write a pericope, meant for commentaries converted from a printed edition. Instead of verses, a pericope may carry content: an array of classified blocks — heading, translation, commentary, paragraph and so on — in the order they appear in the source, each recording where in the source it came from. Do not reorder them by role or by verse; the app shows them in the order given.

Footnotes can likewise be defined once for the whole book, in a top-level footnotes array. A pericope lists the ones it uses in footnoteIds, and a block’s text marks where each one falls with footnote_refs.

Both are optional. The earlier structure — chapters → sections → pericopae → verses, with footnotes on the pericope or the verse — is still accepted, and it is the one the sample commentary uses.

Worked example: a translation

{
  "meta": {
    "schemaVersion": "1.0",
    "id": "MYBIBLEs",
    "type": "translation",
    "name": "My Bible",
    "abbreviation": "MYBIBLE",
    "language": "en",
    "textDirection": "ltr",
    "translationPhilosophy": "formal",
    "versification": "standard",
    "features": { "strongs": true, "morphology": true }
  },
  "books": [
    {
      "id": "Gen",
      "name": "Genesis",
      "number": 1,
      "testament": "OT",
      "chapters": [
        {
          "chapter": 1,
          "headings": [{ "text": "The Creation", "beforeVerse": 1, "level": 1 }],
          "verses": [
            {
              "v": 1,
              "ref": 1001001,
              "content": { "text": "At first, God made the sky and the land.", "annotations": [] },
              "paragraph": true
            }
          ]
        }
      ]
    }
  ]
}

Translation identifiers

By convention a trailing s marks a Strong’s-tagged edition. The identifier must be unique across installed modules, since it is what highlights and settings refer to.

Worked example: highlights

This one marks the words God made in the example above, beginning at character 10 and ending at 18.

{
  "meta": {
    "schemaVersion": "1.0",
    "id": "my_highlights",
    "type": "highlights",
    "name": "My Highlights",
    "translationId": "MYBIBLEs"
  },
  "verses": [
    {
      "ref": 1001001,
      "highlights": [
        { "sc": 10, "ec": 18, "style": 0, "color": "FFE066" }
      ]
    }
  ]
}

sc and ec are character offsets within the verse text of the named translation, start inclusive and end exclusive. style is 0 for a filled highlight, 1 for a solid underline, 2 for dashed and 3 for dotted. color is a hex code, written without the #.

Media

Notes, devotionals, commentaries and lexicons can reference images and audio. In markdown interchange these live in a media/ folder beside the document, with UUID-prefixed filenames to avoid collisions; in a shared package they travel inside the ZIP. Supported formats are JPEG, PNG, GIF, WebP and HEIC for images, and M4A, MP3, WAV, AAC and OGG for audio — M4A being the recommended choice.

Building and installing

Once the JSON is right, turning it into an installable file is four steps: create the tables, insert your rows, compress with raw DEFLATE, verify. That is covered in full — with the table definitions for every type and a complete reference implementation — on Building a .lamp file.

A working sample module of each type, with its source JSON, is on Downloads. Starting from one of those is usually faster than starting from the schema.