# oEdtk **oEdtk** is a Perl 5 toolkit for **industrial printing processing**. It provides the generic building blocks needed to write applications that parse fixed-record data streams (COBOL copybooks, XML or plain text) and turn them into composed documents (LaTeX/PDF, CSV, Excel) and database content: letters, mailings, invoices, banking statements, and similar high-volume productions. - **Purpose**: parse a data stream, extract records, and drive document composition and tracking at production scale. - **Problem it solves**: it factors out the repetitive plumbing of industrial document workflows (record unpacking, template-driven output, LaTeX composition, database loading, index/output management, tracking) so that each application only implements its own business rules. - **Intended users**: developers and integrators building editorial-production applications, and maintainers operating those applications in production. - **Main benefits**: one consistent parsing/composition model, a documented configuration layer, support for several database engines, and a large non-regression suite. - **Maturity**: a stable, CPAN-style release (`2.1126`). No module carries an explicit "experimental" label; the runtime environment defaults to `Dev` (`EDTK_TYPE_ENV=Dev` in the shipped template). Some modules are legacy and kept only for compatibility - see [Limits and constraints](#limits-and-constraints). Main features at a glance: - Fixed-record parsing driven by per-record "motifs" and output templates. - LaTeX composition (`pdflatex`) with an output manager for lots and batches. - Database administration: schema create/detect/upgrade/historise, bulk CSV load, backup buffering (PostgreSQL, MySQL/MariaDB, SQLite, Oracle). - Document tracking and statistics. - XML reading against DTD/XSD, and Cameleon-style readers. - Optional network services: e-mailing, ECM injection, Keycloak, dissemination plan. - A plug-in mechanism to attach corporate code without a registry. ## Table of contents - [Presentation](#presentation) - [Quick start](#quick-start) - [Requirements](#requirements) - [Installation](#installation) - [Configuration](#configuration) - [Usage](#usage) - [Use cases](#use-cases) - [Features](#features) - [Tests and validation](#tests-and-validation) - [Architecture](#architecture) - [Modules](#modules) - [Public interfaces](#public-interfaces) - [Limits and constraints](#limits-and-constraints) - [Troubleshooting](#troubleshooting) - [Development and contribution](#development-and-contribution) - [License, security and support](#license-security-and-support) ## Presentation oEdtk is not a single program: it is a **library plus a set of shipped helper scripts**. The core (`lib/oEdtk.pm` and the modules under `lib/oEdtk/`) is generic and self-contained; an application is a small Perl script you write that combines the pieces. The main entry point of an application is `oEdtk::Main`, which reads the configuration, opens the input/output handles and drives the record loop and the composition back-end. A companion distribution, **oEUser**, carries the modules that only specific applications need (user-side address helpers, generated record descriptors, editor-specific XML readers, and the document-injection client). It is a **separate distribution** and is **not a prerequisite** of oEdtk: the thin `oEdtk::*` delegates resolve the corresponding `oEUser::*` modules on demand, and fail with an explicit message when the companion is absent. See [`oEUser/README`](oEUser/README). This document covers the repository **and** the shipped Perl package (`README.md` is included in the distribution tarball). ## Quick start The shortest path to a first run: 1. **Prerequisites** - a Perl 5 interpreter (see [Requirements](#requirements)) and the XML-LibXML module. On Debian/Ubuntu: `sudo apt-get install perl libxml-libxml-perl`. 2. **Install** - from CPAN: ```sh cpan oEdtk ``` or, from a checkout: ```sh perl Makefile.PL && make && make test && make install ``` 3. **Verify** the module loads and reports its version: ```sh perl -MoEdtk -e 'print oEdtk_release()' ``` Expected output: a banner line `(c) 2005-2026 oedtk@free.fr - oEdtk v2.1126`. 4. **Write a minimal application** (`myapp.pl`) using the fixed-record model (see [`lib/oEdtk.pm`](lib/oEdtk.pm) SYNOPSIS): ```perl use strict; use oEdtk::Main; oe_new_job( $ARGV[0], $ARGV[1] ); # input file, output file oe_rec_motif( "016", "A67 A20 A*" ); # declare record keyed '016' oe_rec_output( "016", "%s<#DATE=%s>%s" ); while ( my $line = ) { chomp $line; oe_process_ref_rec( 0, 3, $line ); # offset, key length, line } oe_compo_link( $ARGV[0], $ARGV[1] ); # close handles, finalise ``` 5. **Run it**: ```sh perl myapp.pl input.txt output.tex ``` `myapp.pl` reads `input.txt`, unpacks every `016` record, builds the declared output, and writes it to `output.tex`. Producing a **PDF** additionally requires a LaTeX toolchain and a populated configuration (see [Configuration](#configuration)); without them, the composition back-end cannot run. ## Requirements ### Operating systems oEdtk is pure Perl 5 and runs on Linux, macOS and Windows. The **shipped helper scripts and the shipped `edtk.ini` template** assume Unix-style paths (`/usr/bin/perl`, `/usr/bin/gs`, `/usr/bin/pdftk`); on Windows they must be adapted. There is no stated minimum OS version. ### Runtime - **Perl >= 5.028** (`Makefile.PL` `MIN_PERL_VERSION`). ### System libraries - **XML-LibXML** (`>= 1.70`) and its underlying **libxml2**, used for XML input. On Windows install it with PPM; on Linux with the distribution's package manager. If libxml2 lives in a non-standard location, see [Installation](#installation). ### Perl dependencies Declared in [`Makefile.PL`](Makefile.PL) (`PREREQ_PM`) and mirrored in the generated [`cpanfile`](cpanfile). Key ones, with the pinned floors: | Module | Floor | Used for | |---|---|---| | `Config::IniFiles` | 2.30 | reading `edtk.ini` | | `DBI` | 1.60 | all database access | | `XML::LibXML` | 1.70 | XML input | | `XML::XPath` | 1.13 | XPath queries | | `Text::CSV` | 1.20 | CSV parsing | | `Spreadsheet::WriteExcel` | 1.00 | Excel output | | `Math::Round` | 0.06 | numeric formatting | Plus, among others: `Archive::Zip`, `Date::Calc`, `Email::Sender::Simple` and `Email::Sender::Transport::SMTP`, `JSON`, `JSON::PP`, `Data::UUID`, `File::Slurp`, `IPC::Run3`, `LWP::UserAgent` and the `HTTP::*` modules, `IO::Socket::SSL`, `Log::Log4perl`, `PDF::Create`, `PDF::Tk`, `Readonly`, `Regexp::Common`, `Term::ReadKey`, `Text::CSV_XS`, `Text::QRCode`, `Time::HiRes`, `Try::Tiny`, `YAML::Tiny`, and `CGI` + `CGI::FormBuilder` (the CGI front-ends load these at the top level, so they are hard requirements). A full install pulls all of them. ### Database drivers `DBI` is a hard requirement; the driver depends on the engine: - **`DBD::SQLite`** - a hard requirement (SQLite is the default file-backed engine). - **`DBD::Pg`** and **`DBD::mysql`** - *recommended* (declared in `META_MERGE`), needed for PostgreSQL and MySQL/MariaDB. - **`DBD::Oracle`** - optional; not installed by default (it needs the Oracle client to build). - **`DBD::Excel`**, **`DBD::MariaDB`** - optional (MariaDB is reached through `DBD::mysql`). ### External programs (per feature) - A **LaTeX distribution** providing `pdflatex` / `latex` for PDF/DVI composition (paths configured under `[COMPO]`). - **Ghostscript** (`gs`) and **pdftk** for the EDMS document path (`[EDOCMNGR]`). - An **SMTP** relay / send-mail facility for the mailing features. - **Docker** and `docker compose` - only for the test databases (see [Tests and validation](#tests-and-validation)). ### Development and test extras `Perl::Tidy`, `Perl::Critic`, `Test::Fatal`, `Test::MockModule`, `Test::Fake::HTTPD`, `Test::More >= 1.302`, `IPC::Run3`, `DBD::mysql`, `DBD::Pg` (declared in `TEST_REQUIRES`). ## Installation Methods are listed from the simplest to the most advanced. ### From CPAN (recommended) ```sh cpan oEdtk # or: cpanm oEdtk ``` Pulls the dependencies and installs the modules. **Verify**: `perl -MoEdtk -e 'print oEdtk_release()'`. ### From source (a checkout of this repository) ```sh perl Makefile.PL make # use 'dmake' on Win32 make test make install make clean ``` If libxml2 is in a non-standard location, pass include/library paths: ```sh perl Makefile.PL LIBS='-L/usr/lib' INC='-I/usr/include/libxml2' ``` **Verify**: `make test` reports the test count, and `perl -MoEdtk -e1` loads cleanly. ### Windows (ActivePerl / PPM) Install XML-LibXML (and `dmake`) with PPM, then run the same source steps with `dmake` instead of `make`. ### Optional companion distribution `oEUser` is a **separate** distribution (see [`oEUser/README`](oEUser/README)); it requires oEdtk **2.1120** or later. Install it with the same `perl Makefile.PL && make && make install` sequence from the `oEUser/` directory. ## Configuration ### Where the configuration comes from The configuration is an INI file (`edtk.ini`) read by `oEdtk::Config::config_read` ([`lib/oEdtk/Config.pm`](lib/oEdtk/Config.pm)). Resolution order: 1. `edtk.ini` next to the running script (`$Bin/edtk.ini`); 2. otherwise `/iniEdtk/edtk.ini`; 3. otherwise the shipped template `/iniEdtk/tplate.edtk.ini`. The `iniEdtk` key of the host-name section (`[]`) can redirect the read to another file; the literal value `local` disables the redirection. Merging is `[DEFAULT]` -> `[ENVDESC]` -> the sections the caller requests -> the host-name section (last wins). `config_read` injects `EDTK_HOST`, `USERNAME`, `EDTK_PRGNAME` (from `$0`) and `EDTK_PRGPATH` (the script directory, i.e. `$Bin`), and expands `$name` references. ### The template Start from the shipped template [`lib/oEdtk/iniEdtk/tplate.edtk.ini`](lib/oEdtk/iniEdtk/tplate.edtk.ini) and adapt it. Its sections: | Section | Role | |---|---| | `[DEFAULT]` | Global starting values (corporation, dictionaries, language, log level). | | `[ENVDESC]` | The runtime directory model (`EDTK_DIR_*`, file stems, extensions, timeouts). | | `[EDTK_DB]` | Database DSNs, users, retention, primary-key mode, bulk-load tuning. | | `[EDTK_STATS]` | Statistics DSNs and canned SQL queries. | | `[MAIL]` | Mail recipients, sender, subject, SMTP host. | | `[COMPO]` | LaTeX back-end, commands, line cutoff, batch-id format. | | `[EDOCMNGR]` | EDMS/GED index columns, formats, FTP host, lookup URL. | | `[SERVICES]` | Optional network services - inactive by default. | | `[MYHOSTNAME]` | Example host-name override section (always uppercase). | ### Key lexicon Every key the shipped template sets, by section, with what it drives and the values that change behaviour. A `$name` value (for example `$EDTK_DIR_BASE`) is expanded by `config_read`; an empty *Special values* cell means the value is free-form or has no special literal. **[DEFAULT]** | Key | Usage | Special values | |---|---|---| | `iniEdtk` | Redirects the read to another ini file; also read from the host-name section. | `local` disables the redirect. | | `EDTK_CORP` | Corporation name printed in the generated documents. | | | `EDTK_DICO` | Main dictionary (accents, entities) loaded by the text layer. | | | `EDTK_DICO_POST` | Postal-code dictionary. | | | `EDTK_SNIP_ADDR` | Address-snipping dictionary. | | | `EDTK_SNIP_RATE` | Address-snipping rate. | `0` disables snipping. | | `EDTK_LANG` | Language, i.e. the dictionary section to read. | e.g. `EN`, `FR`. | | `EDTK_LOG_LVL` | Log sensitivity read by `oEdtk::logger` (its `$LOGGERLEVEL`). | `4` is the mainline default. | **[ENVDESC]** - directories, file stems, extensions and timeouts. Every path is written relative to `EDTK_DIR_BASE` (default `$EDTK_PRGPATH`, the running script's directory) and to `EDTK_PRGNAME` (injected at runtime). | Key | Usage | Special values | |---|---|---| | `EDTK_DIR_BASE` | Root of the whole path tree. | default `$EDTK_PRGPATH`. | | `EDTK_DIR_APP`, `EDTK_DIR_SCRIPT` | Application root / per-application script directory. | | | `EDTK_DIR_CONFIG` | Configuration files and dictionaries. | | | `EDTK_DIR_APPTMP`, `EDTK_DIR_DB` | Temporary work area / database files. | | | `EDTK_DIR_DATA_IN` | Input flux directory. | | | `EDTK_DIR_LIB`, `EDTK_DIR_TMPLATE` | Shared libraries / document templates. | | | `EDTK_DIR_OUTMNGR`, `EDTK_DIR_EDOCMNGR`, `EDTK_DIR_DOCLIB` | Output, EDMS transit and document library. | | | `EDTK_DIR_LOG`, `EDTK_DIR_DOCSCRIPT` | Logs / per-application document area. | | | `EDTK_DOCLIB_LOCK` | Document-library lock file. | | | `EDTK_FDATAIN`, `EDTK_FDATAOUT`, `EDTK_FDATWORK` | Input / output / work file stems. | | | `EDTK_TYPE_ENV` | Environment label, prefixed to mail subjects by the messenger. | `Dev` (default), `Test`, `Production`. | | `EDTK_OUTMNGR_MERGE` | Whether the outgoing-routeur output is merged. | `no` (default) / `yes`. | | `EDTK_PRGNAME` | Running program name (injected). | | | `EDTK_VCS_LOCATION` | Version-control location recorded in outputs. | | | `EDTK_WATERMARKTEXT` | Watermark stamped on generated documents. | | | `EDTK_BIN_PERL` | Path to the Perl interpreter used when bundling. | | | `EDTK_EXT_COMP_OMGR` | Extension of the routeur-composed files. | `omgr`. | | `EDTK_EXT_COMPO` | Extension of a composed file. | defaults to `$EDTK_EXT_LATEX`. | | `EDTK_EXT_DATA`, `EDTK_EXT_DEFAULT` | Data-file extension / default extension. | `DAT` / `$EDTK_EXT_PDF`. | | `EDTK_EXT_EXCEL`, `_LATEX`, `_PCL`, `_PDF`, `_PERL`, `_WORK` | Extensions per artefact type. | `xls`, `tex`, `pcl`, `pdf`, `pl`, `txt`. | | `EDTK_WAITRUN` | Seconds to wait for a child process. | default `8`. | | `EDTK_XLS_MAX_ROW` | Maximum rows read from an XLS sheet. | default `30000`. | **[EDTK_DB]** - database DSNs, credentials, retention, primary-key mode and bulk-load tuning. | Key | Usage | Special values | |---|---|---| | `EDTK_DBI_DSN` (+ `_USER`, `_PASS`) | Active DSN and credentials of the main database. | | | `EDTK_DBI_DSN_BAK` (+ `_USER`, `_PASS`) | DSN and credentials of the backup database. | | | `EDTK_DBI_PARAM` | DSN of the parameter database. | | | `EDTK_DBI_ACQUIT`, `_DISTRIB`, `_DISTRIB_STATS`, `_OUTMNGR`, `_OUTMNGR_STATS`, `_TRACKING` | Logical table names of the acquittal, distribution, distribution-stats, outgoing, outgoing-stats and tracking tables. | | | `EDTK_MAX_USER_KEY` | Number of user tracking keys accepted. | `10` (mainline) / `5` (fork). | | `EDTK_TRACKING_KEYS` | Comma-separated extra tracking columns. | | | `EDTK_TRACK_MODE` | Tracking back-end. | `SQLite` (default) / `none` (tracking off). | | `EDTK_TRACK_SIG` | Which signals the tracker catches. | `warn` (all) / `halt` (die only); `no` disables. | | `EDTK_DB_MAX_DAYS_KEPT`, `_KEPT_STATS`, `_TRACKED`, `_AGREGED` | Retention in days of the main, stats, tracking and aggregated tables. | `2`, `100`, `400`, `600`. | | `EDTK_DB_CHECK_AUTO` | Enables the automatic consistency check. | `NO` (default) / `YES`. | | `EDTK_DB_CHECK_MONTH_DAY` | Day of month for the automatic check. | default `15`. | | `EDTK_DB_PK_IDJOB` | Keeps `ed_idjob` in the INDEX primary key. | `yes` (mainline) / any other value (fork schema). | | `EDTK_DB_IDJOB_DEFAULT` | Value written to `ed_idjob` when the key is kept. | empty until the S51 gate. | | `EDTK_DB_FetchHashKeyName` | Case-folding of fetched column names (`FetchHashKeyName`). | `NAME_uc` (default). | | `EDTK_DB_COPY_ENCODING` | Source encoding of the CSV bulk-load path. | `UTF8` = file already UTF-8; empty = legacy (Latin-1). | | `EDTK_DB_DEFER_INDEX_RATIO`, `_MIN_ROWS` | Index-deferral policy of the PostgreSQL bulk load (opt-in). | empty = off; when set, defaults `0.1` / `10000`. | | `EDTK_DB_BURST_MO` | ELT staging threshold, in MiB, on PostgreSQL. | `50` (default); `0` disables; empty/invalid falls back to 50. | **[EDTK_STATS]** | Key | Usage | Special values | |---|---|---| | `EDTK_DBI_STATS`, `EDTK_DSN_STATS` (+ `_USER`, `_PASS`) | DSN and credentials of the statistics database. | default to the main DSN. | | `EDTK_STATS_TRACKING`, `_OUTMNGR`, `_DISTRIB`, `_ACQUIT` | Statistics table names. | | | `EDTK_STATS_MANUFACT` | Manufacturer filter of the outgoing statistics. | comma- or space-separated `ED_IDMANUFACT` codes; empty = all. | | `EDTK_CSV_HEADER_METADATA`, `EDTK_CSV_HEADER_DISTRIB` | Column order of the CSV exports. | | | `EDTK_STATS_SQL00`..`SQL12`, `SQL90` | Named canned SQL queries of the statistics panel. | `SQL90` may name a `.sql` file (`$EDTK_PRGPATH/sql/...`). | **[MAIL]** | Key | Usage | Special values | |---|---|---| | `EDTK_MAIL_TO`, `EDTK_MAIL_TST` | Production / test recipient. | | | `EDTK_MAIL_SENDER` | Envelope sender. | | | `EDTK_MAIL_SUBJ` | Subject template. | `%date` and `%time` are substituted. | | `EDTK_MAIL_SMTP` | SMTP relay host. | | | `EDTK_MAIL_REFER`, `EDTK_MAIL_OMGR` | Body templates of the recap / outgoing mail. | | | `EDTK_MAIL_LIST_1`..`_5` | Named distribution lists. | | **[COMPO]** - the LaTeX back-end. | Key | Usage | Special values | |---|---|---| | `EDTK_BIN_COMPO` | Directory holding the TeX binaries. | | | `EDTK_COMPO` | The composition command. | e.g. `pdflatex -halt-on-error`. | | `EDTK_COMPO_CMD_PDF`, `_DVI`, `_DVIPDF` | Per-format composition commands. | | | `EDTK_COMPO_LIB` | Path to the `edtkdoc.cls` class file. | | | `EDTK_FILIERES_RECTO_VERSO` | Channels whose index is padded to an even page count. | empty = none. | | `EDTK_CMD_RUN_BG_NOWAIT` | Non-blocking background composition. | empty = blocking; set = non-blocking. | | `EDTK_LINE_CUTOFF` | Maximum characters before a newline in generated documents. | empty falls back to `120`. | | `EDTK_RP_KILL_NON_LATIN` | Strips non-Latin-1 (DEL and C1) characters from input records. | off by default. | | `EDTK_IDLDOC_FORMAT` | Document batch-id format. | `UUID` (default) / `LEGACY` or `old` (16-digit id, case-insensitive). | | `EDTK_COMPO_ASYNC` | Asynchronous composition (commented out in the template). | `yes` / `no`. | **[EDOCMNGR]** - EDMS/GED indexing and transfer. | Key | Usage | Special values | |---|---|---| | `EDMS_INDEX_COLS` | Columns of the EDMS index. | | | `EDMS_DATE_FORMAT` | Date format used in the index. | `%Y/%m/%d`. | | `EDMS_IDX_FORMAT` | Index format. | `DOCUBASE` (default) / `SCOPMASTER`. | | `EDMS_IDX_HEADER` | Index header line (`;`-separated). | | | `EDMS_ACTIVATE_HEADER_ALFRESCO` | Emits the Alfresco header line. | `YES` / `NO`. | | `EDMS_FTP_HOST`, `_PORT`, `_USER`, `_PASS` | FTP(S) transfer target. | | | `EDMS_FTP_DIR_IDX`, `_DIR_DOCS` | Remote index / document directories. | | | `EDTK_EDOCS_LINK` | Base URL of the document link. | | | `EDMS_HTML_HOST` | HTML host used to build the lookup URL. | | | `EDMS_URL_LOOKUP` | Lookup URL template. | `%s` and `%d` placeholders. | | `EDMS_BIN_GS`, `EDMS_BIN_PDFTK` | Ghostscript / pdftk binaries. | | **[SERVICES]** - optional network services. All are inactive by default: an empty value keeps the mainline behaviour. | Key | Usage | Special values | |---|---|---| | `NWS_EMAILING_URI` | E-mailing service base URL. | empty = unused (`/emails` is appended). | | `EMAILING_TEMPLATE`, `EMAILING_USER_AGENT` | E-mailing template name / User-Agent string. | empty = each client's shipped default. | | `KEYCLOAK_URL`, `_CLIENT_ID`, `_SECRET_ID` | Keycloak token endpoint and client credentials. | all three required together. | | `KEYCLOAK_REALM` | Keycloak realm path element. | empty = the client's shipped default. | | `DISSEMINATION_PLAN_URL` | Dissemination-plan service URL. | empty = the step is skipped. | | `EDTK_SSL_VERIFY` | TLS peer and host-name verification. | `1` (default, safe) / `0` (private CA only). | | `EDTK_SSL_CA_PATH` | CA bundle, a file or a directory. | empty = system trust store. | | `EDTK_ACQUIT_API` | Named acquittal callable, `Module::function`. | empty = no API acquittal. | | `EDTK_MAIL_ACQ` | Recipients of the acquittal recap report. | empty = no report. | | `APIECM_URL`, `APIECM_APIKEY_EDITIQUE` | ECM API base URL and the static editique API key. | empty = the ECM injector is unusable. | **[MYHOSTNAME]** - a worked example of a host-name override section. Section names are always uppercase; a section matching `uc(hostname())` is merged last, so it wins, and its `iniEdtk` key can redirect the whole read. A few keys the code reads are not shipped in the template and stay optional: `EDTK_DICO_COUNTRY` (country dictionary), `EDTK_DICO_XLAT` (LaTeX character translation), `EDTK_XML_CATALOG_FILES` (XML catalogs, read from `[MAIL]`), `EDTK_DB_STORAGE_ENGINE` (MySQL storage engine, default `MyISAM`), `EDTK_ENTIRE_YEARS_KEPT` and `EDTK_STATS_DAYS_FROM` (retention / history windows). ### The runtime directory model `[ENVDESC]` defines every path relative to `EDTK_DIR_BASE` (which is set to the script directory at runtime) and to `EDTK_PRGNAME` (the running program name). The main ones: - `EDTK_DIR_APP` / `EDTK_DIR_SCRIPT` - application root and the per-application script directory; - `EDTK_DIR_CONFIG` - configuration and dictionaries; - `EDTK_DIR_DATA_IN` (`EDTK_FDATAIN`, `EDTK_FDATWORK`) - input/work files; - `EDTK_DIR_APPTMP` - temporary work area; - `EDTK_DIR_OUTMNGR` / `EDTK_DIR_EDOCMNGR` / `EDTK_DIR_DOCLIB` - output, EDMS transit and document library; - `EDTK_DIR_LOG` - logs. ### Environment variables read by the code Besides the keys above (which are exported into the process environment at runtime), the code reads a set of `$ENV{...}` variables, including: - directory/identity: `EDTK_DIR_BASE`, `EDTK_DIR_APP`, `EDTK_DIR_SCRIPT`, `EDTK_DIR_APPTMP`, `EDTK_FDATAIN`, `EDTK_FDATAOUT`, `EDTK_PRGNAME`, `EDTK_VCS_LOCATION`, `EDTK_INIEDTK`; - database: `EDTK_DBI_DSN` (+ `_USER` / `_PASS`), `EDTK_DBI_TABLENAME`, `EDTK_DBI_TRACKING`, `EDTK_TRACK_MODE`, `EDTK_DBI_AutoCommit`, `EDTK_DBI_RaiseError`, `EDTK_DBI_PrintError`, `EDTK_MAX_USER_KEY`; - behaviour: `EDTK_EXT_DATA`, `EDTK_EXT_DEFAULT`, `EDTK_EXT_LATEX`, `EDTK_EXT_PERL`, `EDTK_EXT_WORK`, `EDTK_WAITRUN`, `EDTK_FTYP_DFLT`, `EDTK_FTYP_HOMOL`, `EDTK_OPTIONS`. ### Minimal example (no real secret) ```ini [DEFAULT] EDTK_CORP = My Corp EDTK_LANG = EN EDTK_LOG_LVL = 4 [ENVDESC] EDTK_DIR_BASE = $EDTK_PRGPATH EDTK_DIR_SCRIPT= $EDTK_DIR_BASE/app/$EDTK_PRGNAME [EDTK_DB] EDTK_DBI_DSN = DBI:SQLite:dbname=$EDTK_DIR_SCRIPT/oEdtk_db.tmp EDTK_DBI_DSN_USER = oedtk EDTK_DBI_DSN_PASS = change-me ``` ### Security `edtk.ini` can carry database and service passwords. Keep it out of version control, restrict its permissions, and never commit real credentials. The shipped template uses placeholder values only. ## Usage ### The application model An oEdtk application is a small script with a fixed shape (see the [Quick start](#quick-start) and [`lib/oEdtk.pm`](lib/oEdtk.pm) SYNOPSIS): 1. `oe_new_job($infile, $outfile)` - read the configuration, open the `IN`/`OUT` handles, start the composition back-end. 2. Declare each record once: `oe_rec_motif($key, $template)` (mandatory), `oe_rec_output($key, $sprintf_template)` and, optionally, `oe_rec_pre_process` / `oe_rec_process` / `recEdtk_post_process` to hook user subs. 3. Read the stream line by line and call `oe_process_ref_rec($offset, $keylen, $line)` for each - it recognises the record by key, unpacks it into the global `@DATATAB`, runs the hooks and builds the output. 4. `oe_compo_link($infile, $outfile)` - close the handles and finalise (emit the LaTeX trailer, wait for the composer, optionally import the result). `oe_new_job` also parses run-time options, among them `--index`, `--massmail`, `--edms`, `--cgi`, `--noinputfiles` and `--input_code=`. ### The migration CLI `lib/db_migrate.pl` is a standalone command line over `oEdtk::DBAdmin` that updates a database schema. Exactly one mode is required: ```sh perl lib/db_migrate.pl --check-only --dsn [--user U] [--pass P] perl lib/db_migrate.pl --dry-run --dsn perl lib/db_migrate.pl --historize --dsn [--stamp YYYYMMDD_HHMMSS] perl lib/db_migrate.pl --revert --dsn --stamp YYYYMMDD_HHMMSS perl lib/db_migrate.pl --additive --dsn [--with-constraints] ``` | Mode | Effect | |---|---| | `--check-only` | Detect the schema level and print the plan. **Nothing is written.** | | `--dry-run` | Like `--check-only`, plus the copy SQL and a DDL preview. | | `--historize` | Build a `T` target, copy by named columns, validate, switch over and keep the old schema as history (recommended). A base already at `T` is a no-op unless `--force`. | | `--revert` | Undo a `--historize` run (`--stamp` required). | | `--additive` | In-place additive update (add column, widening, `CREATE ... IF NOT EXISTS`) - never a drop, a narrowing or a rename; `--with-constraints` also changes the key after a duplicate pre-check. | Options: `--dsn`, `--user`, `--pass`, `--stamp`, `--force`, `--with-constraints`. Exit code `0` on success, `1` on a controlled abort (reason on stderr); `--check-only` and `--dry-run` are strictly read-only. The password is never printed. ### CGI front-ends The shipped scripts under `lib/oEdtk/lib/cgi-bin/` provide web front-ends: `edtk.cgi` (inline composition of an uploaded XML), `edtk_inged.cgi` (push a document into EDMS), `edtk_ged.cgi` (redirect to the document lookup) and `edtk_para.cgi` (end-user editor of inline parts). Each is gated by a configuration key named after the script basename, in the `[EDOCMNGR]` section. ### Helper scripts `lib/oEdtk/lib/` ships operational scripts, all run as `perl