quireloom

    Deterministic booklet imposition and fold-order verification in pure MoonBit

    booklet
    imposition
    printing
    Download zip
    Author
    Version
    0.2.0
    License
    Apache-2.0
    Last updated
    17 days ago
    Downloads
    34

    No dependencies

    #Novanke/quireloom

    Pure MoonBit booklet imposition, source-page provenance and print-job validation.

    Version 0.2.0 adds selected page ranges, chapter assembly, balanced or mixed-size gatherings, calibrated manual duplex schedules, preflight, source-labelled JSON and CSV, SVG proof atlases and a command-line adapter.

    AI assisted implementation and technical documentation. Source artwork/PDF parsing and printer-driver control are outside the scope. Manual refeed order requires a physical calibration. Competition acceptance is determined by the organizer.

    BackStack

    pub(all) enum BackStack {
    SameOrder
    Reversed
    }

    Binding

    pub(all) enum Binding {
    Left
    Right
    } derive(Eq,
    Debug
    )

    Binding::equal

    fn Binding::equal(Binding, Binding) -> Bool

    Binding::not_equal

    fn Binding::not_equal(x : Binding, y : Binding) -> Bool

    Binding::to_repr

    Booklet

    pub(all) struct Booklet {
    document : Document
    gatherings : Array[Signature]
    sheets : Array[Sheet]
    binding : Binding
    duplex : Duplex
    }

    Collation

    pub(all) enum Collation {
    Collated
    Uncollated
    }

    ContentPage

    pub(all) enum ContentPage {
    Source(String, Int)
    Empty
    } derive(Eq,
    Debug
    )

    ContentPage::equal

    fn ContentPage::equal(ContentPage, ContentPage) -> Bool

    ContentPage::not_equal

    fn ContentPage::not_equal(x : ContentPage, y : ContentPage) -> Bool

    Document

    pub(all) struct Document {
    pages : Array[ContentPage]
    sections : Array[SectionSpan]
    }

    Duplex

    pub(all) enum Duplex {
    LongEdge
    ShortEdge
    } derive(Eq,
    Debug
    )

    Duplex::equal

    fn Duplex::equal(Duplex, Duplex) -> Bool

    Duplex::not_equal

    fn Duplex::not_equal(x : Duplex, y : Duplex) -> Bool

    Duplex::to_repr

    Face

    pub(all) struct Face {
    left : Slot
    right : Slot
    rotation : Int
    } derive(Eq,
    Debug
    )

    Face::equal

    fn Face::equal(Face, Face) -> Bool

    Face::not_equal

    fn Face::not_equal(x : Face, y : Face) -> Bool

    Face::to_repr

    Impression

    pub(all) struct Impression {
    copy : Int
    sheet : Int
    back : Bool
    }

    JobSpec

    pub(all) struct JobSpec {
    sections : Array[Section]
    maximum : Int
    policy : SignaturePolicy
    capacities : Array[Int]?
    binding : Binding
    duplex : Duplex
    paper : Paper
    print : PrintOptions
    }

    Layout

    pub(all) struct Layout {
    left : Rect
    right : Rect
    } derive(Eq,
    Debug
    )

    Layout::equal

    fn Layout::equal(Layout, Layout) -> Bool

    Layout::not_equal

    fn Layout::not_equal(x : Layout, y : Layout) -> Bool

    Layout::to_repr

    Paper

    pub(all) struct Paper {
    width : Int
    height : Int
    margin : Int
    gutter : Int
    creep : Int
    } derive(Eq,
    Debug
    )

    All distances are integer millimetres. Creep means an explicit inward shift.

    Paper::equal

    fn Paper::equal(Paper, Paper) -> Bool

    Paper::not_equal

    fn Paper::not_equal(x : Paper, y : Paper) -> Bool

    Paper::to_repr

    Placement

    pub(all) struct Placement {
    logical_page : Int
    sheet : Int
    back : Bool
    right : Bool
    rotation : Int
    }

    Plan

    pub(all) struct Plan {
    page_count : Int
    signature_pages : Int
    binding : Binding
    duplex : Duplex
    sheets : Array[Sheet]
    } derive(Eq,
    Debug
    )

    Plan::equal

    fn Plan::equal(Plan, Plan) -> Bool

    Plan::not_equal

    fn Plan::not_equal(x : Plan, y : Plan) -> Bool

    Plan::to_repr

    PlanError

    pub(all) enum PlanError {
    PageCount
    SignatureSize
    Geometry
    CorruptPlan(String)
    } derive(Eq,
    Debug
    )

    PlanError::equal

    fn PlanError::equal(PlanError, PlanError) -> Bool

    PlanError::not_equal

    fn PlanError::not_equal(x : PlanError, y : PlanError) -> Bool

    Preflight

    pub(all) struct Preflight {
    logical_pages : Int
    content_pages : Int
    explicit_blanks : Int
    padding_blanks : Int
    sheets : Int
    gatherings : Int
    repeated_references : Int
    issues : Array[PreflightIssue]
    }

    PreflightIssue

    pub(all) struct PreflightIssue {
    blocking : Bool
    field : String
    message : String
    }

    PrintJob

    pub(all) struct PrintJob {
    booklet : Booklet
    paper : Paper
    schedule : PrintSchedule
    }

    PrintMode

    pub(all) enum PrintMode {
    Automatic
    Manual(BackStack)
    }

    PrintOptions

    pub(all) struct PrintOptions {
    copies : Int
    reverse_sheets : Bool
    collation : Collation
    mode : PrintMode
    }

    PrintPass

    pub(all) struct PrintPass {
    reload : Bool
    impressions : Array[Impression]
    }

    PrintSchedule

    pub(all) struct PrintSchedule {
    options : PrintOptions
    passes : Array[PrintPass]
    }

    Rect

    pub(all) struct Rect {
    x : Int
    y : Int
    width : Int
    height : Int
    } derive(Eq,
    Debug
    )

    Rect::equal

    fn Rect::equal(Rect, Rect) -> Bool

    Rect::not_equal

    fn Rect::not_equal(x : Rect, y : Rect) -> Bool

    Rect::to_repr

    Section

    pub(all) struct Section {
    source : String
    source_pages : Int
    selection : String
    start_on_recto : Bool
    }

    SectionSpan

    pub(all) struct SectionSpan {
    source : String
    first : Int
    count : Int
    }

    Sheet

    pub(all) struct Sheet {
    signature : Int
    depth : Int
    front : Face
    back : Face
    } derive(Eq,
    Debug
    )

    Sheet::equal

    fn Sheet::equal(Sheet, Sheet) -> Bool

    Sheet::not_equal

    fn Sheet::not_equal(x : Sheet, y : Sheet) -> Bool

    Sheet::to_repr

    Signature

    pub(all) struct Signature {
    index : Int
    start : Int
    pages : Int
    real_pages : Int
    } derive(Eq,
    Debug
    )

    Signature::equal

    fn Signature::equal(Signature, Signature) -> Bool

    Signature::not_equal

    fn Signature::not_equal(x : Signature, y : Signature) -> Bool

    SignaturePolicy

    pub(all) enum SignaturePolicy {
    Fill
    Balanced
    }

    Slot

    pub(all) enum Slot {
    Page(Int)
    Blank
    } derive(Eq,
    Debug
    )

    Slot::equal

    fn Slot::equal(Slot, Slot) -> Bool

    Slot::not_equal

    fn Slot::not_equal(x : Slot, y : Slot) -> Bool

    Slot::to_repr

    WorkflowError

    pub(all) struct WorkflowError {
    field : String
    message : String
    } derive(Eq,
    Debug
    )

    WorkflowError::equal

    WorkflowError::not_equal

    fn WorkflowError::not_equal(x : WorkflowError, y : WorkflowError) -> Bool

    assemble_document

    fn assemble_document(sections : Array[Section]) -> Result[Document, WorkflowError]

    Join selected source pages. Odd logical pages are rectos for either binding. Alignment blanks belong to the document and remain distinguishable from padding.

    build_job

    fn build_job(spec : JobSpec) -> Result[PrintJob, WorkflowError]

    Compile a request only when the document, imposition, geometry and schedule pass.

    command_help

    fn command_help() -> String

    csv_report

    fn csv_report(plan : Plan) -> Result[String, PlanError]

    Each row is one face, with empty fields for deliberate blanks.

    explicit_gatherings

    fn explicit_gatherings(pages : Int, sizes : Array[Int]) -> Result[Array[Signature], WorkflowError]

    Use a binder-specified sequence of gathering capacities, with no empty group.

    impose

    fn impose(pages : Int, maximum : Int) -> Result[Plan, PlanError]

    Sheet order is signature order, then outside to inside.

    impose_document

    fn impose_document(document : Document, gatherings : Array[Signature], binding : Binding, duplex : Duplex) -> Result[Booklet, WorkflowError]

    Impose logical positions, keeping the source map separate from padding.

    impose_with

    fn impose_with(pages : Int, maximum : Int, binding : Binding, duplex : Duplex) -> Result[Plan, PlanError]

    A short-edge back is the complete canonical back rotated by 180 degrees.

    job_csv

    fn job_csv(job : PrintJob) -> Result[String, WorkflowError]

    One record per impression, with RFC-style quoting for arbitrary source labels.

    job_manifest

    fn job_manifest(job : PrintJob) -> Result[String, WorkflowError]

    Resolved manifest records source provenance and actual print-pass order.

    job_proof

    fn job_proof(job : PrintJob, sheet_index : Int, back : Bool) -> Result[String, WorkflowError]

    A dimensioned source-labelled proof; source artwork is not embedded.

    job_spec_json

    fn job_spec_json(spec : JobSpec) -> Result[String, WorkflowError]

    Canonical, escaped request serialization. Reparse to reproduce the same job.

    json_report

    fn json_report(plan : Plan) -> Result[String, PlanError]

    Only fixed field names and checked integers enter JSON, so no raw text escapes.

    layout

    fn layout(paper : Paper, depth : Int) -> Result[Layout, PlanError]

    Reject clipping, overlapping panels and unsafe integer arithmetic.

    locate_source

    fn locate_source(booklet : Booklet, source : String, number : Int) -> Result[Array[Placement], WorkflowError]

    Locate every use of a source page, including repeated selections.

    parse_job

    fn parse_job(text : String) -> Result[JobSpec, WorkflowError]

    parse_selection

    fn parse_selection(text : String, source_pages : Int) -> Result[Array[Slot], WorkflowError]

    Comma-separated page numbers, ascending/descending inclusive ranges and b. Order and duplicates are intentional. Offsets are UTF-16 code-unit indices.

    plan_gatherings

    fn plan_gatherings(pages : Int, maximum : Int, policy : SignaturePolicy) -> Result[Array[Signature], WorkflowError]

    Balanced distributes whole sheets across the fewest possible gatherings. Sizes differ by at most one sheet; padding is still confined to the end.

    preflight

    fn preflight(booklet : Booklet, paper : Paper) -> Result[Preflight, WorkflowError]

    Structural errors return Err; paper and content advisories are collected. A repeated reference is an advisory because selection duplication is allowed.

    proof_atlas

    fn proof_atlas(job : PrintJob, first_sheet : Int, count : Int) -> Result[String, WorkflowError]

    Paginate large jobs with first_sheet/count; each atlas is limited to 64 sheets.

    recover

    fn recover(plan : Plan) -> Result[Array[Slot], PlanError]

    Undo print orientation, then traverse folded leaves from outside to inside. This verifier consumes a supplied plan; it does not regenerate an imposition.

    recover_booklet

    fn recover_booklet(booklet : Booklet) -> Result[Array[ContentPage], WorkflowError]

    Consume the supplied faces instead of reimposing a fresh plan for comparison.

    run_command

    fn run_command(args : Array[String]) -> Result[String, WorkflowError]

    Pure command adapter: argv excludes the runtime/program names.

    schedule_print

    fn schedule_print(booklet : Booklet, options : PrintOptions) -> Result[PrintSchedule, WorkflowError]

    Schedule explicit impressions. Manual refeed order is chosen by the caller; it expresses a calibrated stack permutation, not a printer-driver promise.

    signatures

    fn signatures(pages : Int, maximum : Int) -> Result[Array[Signature], PlanError]

    Split a book into sequential gatherings, padding only the final one to four.

    svg_proof

    fn svg_proof(plan : Plan, paper : Paper, sheet_index : Int, back : Bool) -> Result[String, PlanError]

    A proof contains page labels and a fold line, not source PDF artwork.

    validate_config

    fn validate_config(pages : Int, signature_pages : Int) -> Result[Unit, PlanError]

    Bounded inputs keep page arithmetic exact on every backend.

    validate_document

    fn validate_document(document : Document) -> Result[Unit, WorkflowError]

    Validate externally constructed documents before using their page map.

    validate_gatherings

    fn validate_gatherings(pages : Int, groups : Array[Signature]) -> Result[Unit, WorkflowError]

    verify

    fn verify(plan : Plan) -> Result[Unit, PlanError]

    Require exact reading order, including every final blank.

    verify_schedule

    fn verify_schedule(booklet : Booklet, schedule : PrintSchedule) -> Result[Unit, WorkflowError]

    Check coverage and actual refeed pairings, including externally edited passes.