diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index b4d301a..a79310c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -29,7 +29,7 @@ body: options: - "parser (a specific input format)" - "engine (layout, rendering, the AST pipeline)" - - "cli (the annave command)" + - "cli (the pdfengine command)" - "config (style, limits, or message YAML)" - "docs" - "plugin" @@ -40,7 +40,7 @@ body: id: environment attributes: label: Environment - description: OS, Go version, and pdfengine version (see `annave version` or CHANGELOG.md). + description: OS, Go version, and pdfengine version (see `pdfengine version` or CHANGELOG.md). validations: required: false - type: textarea diff --git a/.github/labels.json b/.github/labels.json index e517844..a80bcac 100644 --- a/.github/labels.json +++ b/.github/labels.json @@ -28,7 +28,7 @@ {"name": "area/parser", "color": "bfd4f2", "description": "internal/parser/ - one file per input format"}, {"name": "area/engine", "color": "bfd4f2", "description": "internal/engine/, internal/ast/, schema/, and the root pdfengine package"}, - {"name": "area/cli", "color": "bfd4f2", "description": "cmd/ - the annave CLI and the debug tool"}, + {"name": "area/cli", "color": "bfd4f2", "description": "cmd/ - the pdfengine CLI and the debug tool"}, {"name": "area/config", "color": "bfd4f2", "description": "config/ - style, limits, and message YAML"}, {"name": "area/ci", "color": "bfd4f2", "description": ".github/, .goreleaser.yaml, .golangci.yml, cliff.toml"}, {"name": "area/docs", "color": "bfd4f2", "description": "docs/, assets/, root *.md, LICENSE, NOTICE"}, diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 502e61e..05ceb4d 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -27,5 +27,5 @@ Closes # - [ ] This change does not introduce a way for external content (untrusted documents, issue/PR text) to be treated as instructions by an agent. -The contribution is licensed under the Apache License 2.0 of this repository +The contribution is licensed under the MIT License of this repository (see [LICENSE](../LICENSE)), and [docs/CONTRIBUTING.md](../docs/CONTRIBUTING.md) has been read. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f476469..7b8ec7e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,13 +33,13 @@ jobs: with: go-version: "stable" - - uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 + - uses: goreleaser/goreleaser-action@a4f02ab5355a589de60d917a659ce617ed19b3de # v7.3.0 with: distribution: goreleaser - version: "v2.18.2" + version: "v2.18.3" args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Must exist in this repo's secrets with write access to - # annavetech/homebrew-annave, for pushing the updated cask. + # annavetech/homebrew-tap, for pushing the updated cask. HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} diff --git a/.gitignore b/.gitignore index 5e71278..9314fd9 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ Thumbs.db # Binaries /server +/pdfengine *.exe *.exe~ *.dll diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 3226dad..13f87e2 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,6 +1,6 @@ -# ANNÁVE PDF Engine: release pipeline +# PDF Engine: release pipeline # -# Builds the `annave` CLI for darwin/linux, amd64/arm64, publishes a GitHub +# Builds the `pdfengine` CLI for darwin/linux, amd64/arm64, publishes a GitHub # release with checksums, and pushes a Homebrew cask (not `brews`) to the tap. # # Run by release.yml only after CI passes for that tag; the GoReleaser @@ -14,12 +14,12 @@ version: 2 -project_name: annave-pdf-engine +project_name: pdfengine builds: - - id: annave - main: ./cmd/cli - binary: annave + - id: pdfengine + main: ./cmd/pdfengine + binary: pdfengine env: - CGO_ENABLED=0 goos: @@ -30,9 +30,9 @@ builds: - arm64 archives: - - id: annave + - id: pdfengine ids: - - annave + - pdfengine formats: [tar.gz] name_template: >- {{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }} @@ -41,23 +41,23 @@ checksum: name_template: "checksums.txt" homebrew_casks: - - name: annave-pdf-engine + - name: pdfengine ids: - - annave + - pdfengine binaries: - - annave + - pdfengine repository: owner: annavetech - name: homebrew-annave + name: homebrew-tap token: "{{ .Env.HOMEBREW_TAP_TOKEN }}" directory: Casks homepage: "https://www.annave.tech" - description: "Convert documents to PDF from the command line (ANNÁVE PDF Engine)" + description: "Convert documents to PDF from the command line" hooks: post: install: | if OS.mac? - system_command "/usr/bin/xattr", args: ["-dr", "com.apple.quarantine", "#{staged_path}/annave"] + system_command "/usr/bin/xattr", args: ["-dr", "com.apple.quarantine", "#{staged_path}/pdfengine"] end release: diff --git a/CHANGELOG.md b/CHANGELOG.md index b3daa29..fc939cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -All notable changes to ANNÁVE PDF Engine are documented here. +All notable changes to PDF Engine are documented here. Versioning follows [Semantic Versioning](https://semver.org/). --- @@ -9,6 +9,16 @@ Versioning follows [Semantic Versioning](https://semver.org/). --- +## [1.4.0] - 2026-10-14 + +### Changed +- License changed from Apache 2.0 to MIT. +- **Breaking (CLI):** the CLI command is renamed from `annave` to `pdfengine`, and its source moves from `cmd/cli` to `cmd/pdfengine`. Install it with `go install github.com/annavetech/pdfengine/cmd/pdfengine@latest`. +- Homebrew install moved to `brew install annavetech/tap/pdfengine`. +- The internal `AnnaveError` type in `internal/engine` is renamed to `Error`. The public `pdfengine.Error` type is unchanged. + +--- + ## [1.3.1] - 2026-09-27 Upgrading from 1.2.0 requires three changes: the import path is now `github.com/annavetech/pdfengine`, call sites must be adapted to the new `Convert` and `New` signatures described below, and the minimum Go version is 1.26. diff --git a/CODEOWNERS b/CODEOWNERS index 909fb04..e7ee542 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -13,7 +13,7 @@ /internal/ast/ @annaveretennykova /schema/ @annaveretennykova -# The annave CLI and the debug tool. +# The pdfengine CLI and the debug tool. /cmd/ @annaveretennykova # Style, limits, and message config. diff --git a/LICENSE b/LICENSE index 1caa57b..35be1d9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,176 +1,7 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Copyright (c) 2026 Anna Veretennykova - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - 1. Definitions. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship made available under - the License, as indicated by a copyright notice that is included in - or attached to the work (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean, as submitted to the Licensor for inclusion - in the Work by the copyright owner or by an individual or Legal Entity - authorized to submit on behalf of the copyright owner. For the purposes - of this definition, "submit" means any form of electronic, verbal, or - written communication sent to the Licensor or its representatives, - including but not limited to communication on electronic mailing lists, - source code control systems, and issue tracking systems that are managed - by, or on behalf of, the Licensor for the purpose of discussing and - improving the Work, but excluding communication that is conspicuously - marked or designated in writing by the copyright owner as "Not a - Contribution." - - "Contributor" shall mean Licensor and any Legal Entity on behalf of - whom a Contribution has been received by the Licensor and included - within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by the combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a cross-claim - or counterclaim in a lawsuit) alleging that the Work or any Contribution - constitutes patent or contributory patent infringement, then any patent - licenses granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or Derivative - Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file, you must include a - readable copy of the attribution notices contained within such - NOTICE file, in at least one of the following places: within a - NOTICE text file distributed as part of the Derivative Works; - within the Source form or documentation, if provided along with - the Derivative Works; or, within a display generated by the - Derivative Works, if and wherever such third-party notices - normally appear. The contents of the NOTICE file are for - informational purposes only and do not modify the License. - You may add Your own attribution notices within Derivative Works - that You distribute, alongside or in addition to the NOTICE text - from the Work, provided that such additional attribution notices - cannot be construed as modifying the License. - - You may add Your own license statement for Your modifications and - may provide additional grant of rights to use, modify, and distribute - those modifications, provided that Your use, reproduction, - and distribution of the Work otherwise complies with the conditions - stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any conditions of TITLE, - MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. - You are solely responsible for determining the appropriateness of - using or redistributing the Work and assume any risks associated - with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or exemplary damages of any character arising as a - result of this License or out of the use or inability to use the - Work (even if such Contributor has been advised of the possibility - of such damages). - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may offer only - conditions consistent with this License. - - END OF TERMS AND CONDITIONS - - Copyright 2026 Anna Veretennykova - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/NOTICE b/NOTICE index 2d5fc8d..e52abed 100644 --- a/NOTICE +++ b/NOTICE @@ -1,4 +1,4 @@ -ANNÁVE PDF Engine +PDF Engine Copyright 2026 Anna Veretennykova https://www.annave.tech diff --git a/README.md b/README.md index 1577ecb..bdd053e 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# ANNÁVE PDF Engine +# PDF Engine Convert any document format to PDF from Go code or the command line. No headless browser. No C dependencies. Self-hosted. * **Author:** Anna Veretennykova · [www.annave.tech](https://www.annave.tech) -* **License:** Apache 2.0 +* **License:** MIT --- @@ -18,25 +18,24 @@ Every available option has a cost that isn't obvious until production: | PDFco / HTML2PDF / similar | Per-call pricing, your documents leave your infrastructure | | ReportLab (Python) | Python runtime required, not embeddable in Go services | -ANNÁVE PDF Engine is a single Go binary (~10 MB with embedded fonts). It takes raw text or structured JSON as input and returns PDF bytes. No runtime dependencies. No external calls. Deploy it once and it runs indefinitely. +PDF Engine is a single Go binary (~10 MB with embedded fonts). It takes raw text or structured JSON as input and returns PDF bytes. No runtime dependencies. No external calls. Deploy it once and it runs indefinitely. --- ## Installation -The `annave` CLI converts documents to PDF without running a server. +The `pdfengine` CLI converts documents to PDF without running a server. ```bash # Go -go install github.com/annavetech/pdfengine/cmd/cli@latest +go install github.com/annavetech/pdfengine/cmd/pdfengine@latest # Homebrew (macOS, Linux) -brew tap annavetech/annave -brew install annave-pdf-engine +brew install annavetech/tap/pdfengine ``` ```bash -annave pdf convert report.md -o report.pdf +pdfengine pdf convert report.md -o report.pdf ``` --- @@ -126,13 +125,13 @@ Full schema: [`schema/document.v1.schema.json`](schema/document.v1.schema.json) All three are embedded in the binary at build time; editing one and running `go build` changes the default for every `Engine` that does not override it. -`style.yaml` and `limits.yaml` can also be replaced per `Engine`, at runtime, without a rebuild: `pdfengine.New(pdfengine.WithStyleFile(path), pdfengine.WithLimitsFile(path))`, or `annave pdf convert --style-file path --limits-file path` from the CLI. The library never reads a file unless one of these options names it explicitly; see [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md). +`style.yaml` and `limits.yaml` can also be replaced per `Engine`, at runtime, without a rebuild: `pdfengine.New(pdfengine.WithStyleFile(path), pdfengine.WithLimitsFile(path))`, or `pdfengine pdf convert --style-file path --limits-file path` from the CLI. The library never reads a file unless one of these options names it explicitly; see [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md). --- ## Architecture -The public `pdfengine` package and the `annave` CLI both call straight into a six-stage internal pipeline (`internal/engine`). The pipeline has no knowledge of where its input came from or how its output is delivered. +The public `pdfengine` package and the `pdfengine` CLI both call straight into a six-stage internal pipeline (`internal/engine`). The pipeline has no knowledge of where its input came from or how its output is delivered. ``` pdfengine.New(opts...) (*Engine, error) @@ -187,14 +186,14 @@ go test -fuzz=FuzzMdParser -fuzztime=30s ./internal/parser/... ## Building a release binary ```bash -go build -o annave ./cmd/cli +go build -o pdfengine ./cmd/pdfengine ``` The binary embeds all fonts and configuration. No external files are needed at runtime. For cross-compilation (e.g. Linux on macOS): ```bash -GOOS=linux GOARCH=amd64 go build -o annave-linux ./cmd/cli +GOOS=linux GOARCH=amd64 go build -o pdfengine-linux ./cmd/pdfengine ``` --- diff --git a/cmd/cli/main.go b/cmd/cli/main.go deleted file mode 100644 index 4dc8b71..0000000 --- a/cmd/cli/main.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2026 Anna Veretennykova -// -// SPDX-License-Identifier: Apache-2.0 - -package main - -import "github.com/annavetech/pdfengine/cmd/cli/cmd" - -func main() { - cmd.Execute() -} diff --git a/cmd/debug/main.go b/cmd/debug/main.go index 1404473..f2aa866 100644 --- a/cmd/debug/main.go +++ b/cmd/debug/main.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package main diff --git a/cmd/cli/cmd/pdf.go b/cmd/pdfengine/cmd/pdf.go similarity index 86% rename from cmd/cli/cmd/pdf.go rename to cmd/pdfengine/cmd/pdf.go index 9a08d40..a84c104 100644 --- a/cmd/cli/cmd/pdf.go +++ b/cmd/pdfengine/cmd/pdf.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package cmd diff --git a/cmd/cli/cmd/pdf_convert.go b/cmd/pdfengine/cmd/pdf_convert.go similarity index 90% rename from cmd/cli/cmd/pdf_convert.go rename to cmd/pdfengine/cmd/pdf_convert.go index b8cea84..377d392 100644 --- a/cmd/cli/cmd/pdf_convert.go +++ b/cmd/pdfengine/cmd/pdf_convert.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package cmd @@ -36,10 +36,10 @@ Reads from a file argument, or from stdin with --stdin. Writes to the path given by --output, or to stdout if --output is omitted. Examples: - annave pdf convert README.md -o output.pdf - annave pdf convert report.docx -o report.pdf - cat data.csv | annave pdf convert --stdin --format csv > table.pdf - annave pdf convert --stdin --format md < spec.md > spec.pdf`, + pdfengine pdf convert README.md -o output.pdf + pdfengine pdf convert report.docx -o report.pdf + cat data.csv | pdfengine pdf convert --stdin --format csv > table.pdf + pdfengine pdf convert --stdin --format md < spec.md > spec.pdf`, Args: func(cmd *cobra.Command, args []string) error { if convertStdin && len(args) > 0 { return fmt.Errorf("cannot use --stdin together with a file argument") @@ -105,14 +105,14 @@ Examples: pipe := engine.NewPipeline(cfg) pdfBytes, err := pipe.Run(string(input), format) if err != nil { - if ae, ok := err.(*engine.AnnaveError); ok { + if ae, ok := err.(*engine.Error); ok { return fmt.Errorf("%s: %s", ae.Code, ae.Message) } return err } if convertOutput == "" { - // Write PDF to stdout. Useful for piping: annave pdf convert ... > out.pdf + // Write PDF to stdout. Useful for piping: pdfengine pdf convert ... > out.pdf _, err = os.Stdout.Write(pdfBytes) return err } diff --git a/cmd/cli/cmd/root.go b/cmd/pdfengine/cmd/root.go similarity index 66% rename from cmd/cli/cmd/root.go rename to cmd/pdfengine/cmd/root.go index 1e3465b..f091dbc 100644 --- a/cmd/cli/cmd/root.go +++ b/cmd/pdfengine/cmd/root.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package cmd @@ -14,16 +14,16 @@ import ( ) var rootCmd = &cobra.Command{ - Use: "annave", - Short: "ANNÁVE TECH developer tools", - Long: "ANNÁVE TECH: developer tools by Anna Veretennykova (www.annave.tech)", + Use: "pdfengine", + Short: "Convert documents to PDF", + Long: "PDF Engine: convert documents to PDF from the command line.", } var versionCmd = &cobra.Command{ Use: "version", Short: "Print the version", Run: func(cmd *cobra.Command, args []string) { - fmt.Printf("ANNÁVE PDF Engine v%s\n", engine.EngineVersion) + fmt.Printf("PDF Engine v%s\n", engine.EngineVersion) }, } diff --git a/cmd/pdfengine/main.go b/cmd/pdfengine/main.go new file mode 100644 index 0000000..affeb67 --- /dev/null +++ b/cmd/pdfengine/main.go @@ -0,0 +1,11 @@ +// Copyright 2026 Anna Veretennykova +// +// SPDX-License-Identifier: MIT + +package main + +import "github.com/annavetech/pdfengine/cmd/pdfengine/cmd" + +func main() { + cmd.Execute() +} diff --git a/config/config.go b/config/config.go index 996edab..c53cfc8 100644 --- a/config/config.go +++ b/config/config.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT // Package config embeds the YAML configuration files that ship with the binary. // No external files are required at runtime. diff --git a/config/limits.yaml b/config/limits.yaml index be327ea..9938cc0 100644 --- a/config/limits.yaml +++ b/config/limits.yaml @@ -1,14 +1,14 @@ -# ANNÁVE PDF Engine: Input and Output Limits +# PDF Engine: Input and Output Limits # # Adjust these values to match your deployment constraints. # # This file is the embedded default: edit it and rebuild the binary -# (go build ./cmd/cli) to change it for every Engine that does not override +# (go build ./cmd/pdfengine) to change it for every Engine that does not override # it. # # To change the limits without rebuilding, a caller passes its own YAML file # in this exact shape to pdfengine.New via WithLimitsFile(path) (library) or -# annave pdf convert --limits-file path (CLI). No external file is read +# pdfengine pdf convert --limits-file path (CLI). No external file is read # unless the caller supplies one this way. input: diff --git a/config/messages.yaml b/config/messages.yaml index 579e2da..952306f 100644 --- a/config/messages.yaml +++ b/config/messages.yaml @@ -1,4 +1,4 @@ -# ANNÁVE PDF Engine: Error and Status Messages +# PDF Engine: Error and Status Messages # # All user-facing messages are defined here. # Error codes follow the pattern ENGINE_ERR_SLUG. diff --git a/config/style.yaml b/config/style.yaml index 40a8e3c..d1dbd93 100644 --- a/config/style.yaml +++ b/config/style.yaml @@ -1,4 +1,4 @@ -# ANNÁVE PDF Engine: Document Style Configuration +# PDF Engine: Document Style Configuration # # All sizes are in CSS pixels at 96 DPI. # 1 px at 96 DPI = 0.2646 mm = 0.75 pt @@ -10,7 +10,7 @@ # # To change the style without rebuilding, a caller passes its own YAML file # in this exact shape to pdfengine.New via WithStyleFile(path) (library) or -# annave pdf convert --style-file path (CLI). No external file is read +# pdfengine pdf convert --style-file path (CLI). No external file is read # unless the caller supplies one this way. page: diff --git a/doc.go b/doc.go index ace46ca..0ac0acc 100644 --- a/doc.go +++ b/doc.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT // Package pdfengine converts Markdown, plain text, JSON, HTML, CSV, YAML, // XML, reStructuredText, Jupyter notebooks, Word documents, and images to PDF. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 5748702..bdfcdf3 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -1,10 +1,10 @@ @@ -13,7 +13,7 @@ updated: 2026-08-23 ## Design pattern -The engine is a public Go package (`pdfengine`, at the module root) wrapping a six-stage conversion pipeline (`internal/engine`). The pipeline itself has no knowledge of where its input came from or how its output is delivered: it takes a document and a format, and returns PDF bytes or an error. Two consumers drive it today: the `pdfengine` package (for library callers) and `cmd/cli` (for the `annave` command). Both call straight into `internal/engine`; there is no separate ports-and-adapters interface layer between them and the pipeline, and no runtime-pluggable delivery mechanism: adding a new one (a future MCP server, for example) means writing a new package that imports `internal/engine` or `pdfengine` directly, the same way `cmd/cli` does. +The engine is a public Go package (`pdfengine`, at the module root) wrapping a six-stage conversion pipeline (`internal/engine`). The pipeline itself has no knowledge of where its input came from or how its output is delivered: it takes a document and a format, and returns PDF bytes or an error. Two consumers drive it today: the `pdfengine` package (for library callers) and `cmd/pdfengine` (for the `pdfengine` command). Both call straight into `internal/engine`; there is no separate ports-and-adapters interface layer between them and the pipeline, and no runtime-pluggable delivery mechanism: adding a new one (a future MCP server, for example) means writing a new package that imports `internal/engine` or `pdfengine` directly, the same way `cmd/pdfengine` does. Configuration (style, limits, messages) is resolved once, when a `pdfengine.Engine` or `internal/engine.Pipeline` is constructed, into an immutable `internal/engine.Config`; see `docs/CONFIGURATION.md`. Two `Engine` values can hold two different `Config`s in the same process. @@ -21,7 +21,7 @@ Configuration (style, limits, messages) is resolved once, when a `pdfengine.Engi ┌──────────────────────────────────────────────────────┐ │ Consumers │ │ pdfengine (module root) : public library entry point │ -│ cmd/cli/ : cobra CLI │ +│ cmd/pdfengine/ : cobra CLI │ └──────────────────────────────────────────────────────┘ │ pdfengine.New(opts...) (*Engine, error) │ (*Engine).Convert(ctx, data, format) ([]byte, error) @@ -217,7 +217,7 @@ FormatYour, FormatYour: &YourParser{}, ``` -3. **Add a test in `internal/parser/yourformat_test.go`** using a real fixture from the ANNÁVE PDF Engine documentation as input. +3. **Add a test in `internal/parser/yourformat_test.go`** using a real fixture from the PDF Engine documentation as input. 4. **Update `config/messages.yaml`** to include the new format in the `ENGINE_ERR_UNSUPPORTED_FORMAT` message list. @@ -227,10 +227,10 @@ Nothing else changes. The pipeline and renderer are format-agnostic. ## Error types (`internal/engine/errors.go`) -All pipeline errors are `*AnnaveError`: +All pipeline errors are `*Error`: ```go -type AnnaveError struct { +type Error struct { Code string Stage EngineStage Message string diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index c41de90..3ea07e8 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -1,10 +1,10 @@ @@ -13,9 +13,9 @@ updated: 2026-08-23 The engine uses three YAML files in `config/`. All three are embedded into the binary at build time via `//go:embed`, and every `Engine` uses those embedded values by default. -**To change the embedded default:** edit the YAML file, then rebuild with `go build ./cmd/cli`. +**To change the embedded default:** edit the YAML file, then rebuild with `go build ./cmd/pdfengine`. -**To change `style.yaml` or `limits.yaml` without rebuilding:** pass your own file to `pdfengine.New` (`pdfengine.New(pdfengine.WithStyleFile(path))`, `pdfengine.New(pdfengine.WithLimitsFile(path))`, or both together), or, from the CLI, `annave pdf convert --style-file path` / `--limits-file path`. The library itself never reads a file unless one of these options names it explicitly: there is no implicit directory convention, no environment-variable lookup, and no filesystem scan inside the library. A caller that wants a discovery convention of its own (an environment variable, a fixed path, a flag) resolves that path itself and passes the result to one of these options. `config/messages.yaml` has no such override; every `Engine` uses the embedded messages. +**To change `style.yaml` or `limits.yaml` without rebuilding:** pass your own file to `pdfengine.New` (`pdfengine.New(pdfengine.WithStyleFile(path))`, `pdfengine.New(pdfengine.WithLimitsFile(path))`, or both together), or, from the CLI, `pdfengine pdf convert --style-file path` / `--limits-file path`. The library itself never reads a file unless one of these options names it explicitly: there is no implicit directory convention, no environment-variable lookup, and no filesystem scan inside the library. A caller that wants a discovery convention of its own (an environment variable, a fixed path, a flag) resolves that path itself and passes the result to one of these options. `config/messages.yaml` has no such override; every `Engine` uses the embedded messages. Two `Engine` values built with different `WithStyleFile`/`WithLimitsFile` options hold genuinely independent configuration in the same process; nothing here is a single process-wide setting. diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 17b5224..1028dee 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -1,10 +1,10 @@ @@ -18,13 +18,13 @@ git clone https://github.com/annavetech/pdfengine.git cd pdfengine # Build -go build ./cmd/cli +go build ./cmd/pdfengine # Run tests go test ./... # Convert a document locally -go run ./cmd/cli pdf convert README.md -o output.pdf +go run ./cmd/pdfengine pdf convert README.md -o output.pdf ``` Go 1.26.8 or later is required. @@ -41,7 +41,7 @@ go test ./... go test -v ./internal/engine/... # Single test function -go test -v -run TestPipeline_Run_Markdown ./internal/engine/... +go test -v -run TestPipeline_Run_GoldenMarkdown ./internal/engine/... # Fuzz the Markdown parser for 30 seconds go test -fuzz=FuzzMdParser -fuzztime=30s ./internal/parser/... @@ -78,7 +78,7 @@ of a normal `go test ./...`. ```go // Copyright 2026 Anna Veretennykova // - // SPDX-License-Identifier: Apache-2.0 + // SPDX-License-Identifier: MIT ``` - Comments only when the reason is non-obvious: not what the code does, but why it does it that way. - No `_test.go` file uses mocks for the database or filesystem. The pipeline tests call `Pipeline.Run` directly. No fakes for the PDF renderer: tests assert on the error return, not the PDF content. @@ -94,7 +94,7 @@ See `docs/ARCHITECTURE.md` for the full walkthrough. Short version: 1. Create `internal/parser/yourformat.go` with a struct implementing `parser.Parser` (two methods: `CanParse`, `Parse`). 2. Add the format constant and extension mappings to `internal/parser/registry.go`. 3. Register the parser: add the format to the `ordered` slice in `NewRegistry(maxInputChars)`, binary formats (magic-byte checks) before text formats, and add the parser to `byFormat` in `newByFormat()`. -4. Write a test in `internal/parser/yourformat_test.go`. The test fixture should be a real document from the ANNÁVE PDF Engine documentation, not lorem ipsum. This doubles as self-documenting content that people will not delete. +4. Write a test in `internal/parser/yourformat_test.go`. The test fixture should be a real document from the PDF Engine documentation, not lorem ipsum. This doubles as self-documenting content that people will not delete. 5. Update the `ENGINE_ERR_UNSUPPORTED_FORMAT` message in `config/messages.yaml` to include the new format name. The pipeline and renderer require no changes. @@ -127,7 +127,7 @@ The six stages are fixed at the architectural level. Adding a seventh stage requ The engine follows [Semantic Versioning](https://semver.org). The version is set in `internal/engine/config.go`: ```go -const EngineVersion = "1.3.1" +const EngineVersion = "1.4.0" ``` - Patch (1.0.x): bug fixes, no API or config key changes diff --git a/docs/DEPENDENCIES.md b/docs/DEPENDENCIES.md index 146b6b8..e5167dc 100644 --- a/docs/DEPENDENCIES.md +++ b/docs/DEPENDENCIES.md @@ -1,10 +1,10 @@ @@ -78,7 +78,7 @@ HTML parsing, used by `bluemonday` (indirect requirement). Also provides the `ht ### `github.com/spf13/cobra v1.10.2` -Used directly by `cmd/cli` for the CLI command tree (`pdf`, `pdf convert`). The core engine (`internal/engine`) does not depend on cobra. +Used directly by `cmd/pdfengine` for the CLI command tree (`pdf`, `pdf convert`). The core engine (`internal/engine`) does not depend on cobra. | Version range | Result | |---|---| diff --git a/docs/ERROR_CODES.md b/docs/ERROR_CODES.md index 640fad7..f789021 100644 --- a/docs/ERROR_CODES.md +++ b/docs/ERROR_CODES.md @@ -1,10 +1,10 @@ diff --git a/docs/USE_CASES.md b/docs/USE_CASES.md index dc830c2..8bd778c 100644 --- a/docs/USE_CASES.md +++ b/docs/USE_CASES.md @@ -1,10 +1,10 @@ @@ -20,7 +20,7 @@ Seven practical scenarios with working examples and notes on edge cases. **Scenario:** A CLI tool or CI pipeline converts a Markdown README or technical specification to a PDF for distribution. ```bash -annave pdf convert README.md -o output.pdf +pdfengine pdf convert README.md -o output.pdf ``` Or as a library call, with the format given explicitly: @@ -42,7 +42,7 @@ pdf, err := e.Convert(context.Background(), []byte(markdown), pdfengine.FormatMa **Scenario:** Export a spreadsheet or database query result as a formatted PDF table. ```bash -annave pdf convert report.csv -o report.pdf +pdfengine pdf convert report.csv -o report.pdf ``` Example input (`report.csv`): @@ -65,7 +65,7 @@ PDF Engine,Service,Running **Scenario:** Convert a Word document to PDF as part of a document-processing pipeline. ```bash -annave pdf convert document.docx -o document.pdf +pdfengine pdf convert document.docx -o document.pdf ``` **What to watch:** @@ -81,7 +81,7 @@ annave pdf convert document.docx -o document.pdf **Scenario:** Convert a `.ipynb` notebook for sharing or archiving. ```bash -annave pdf convert analysis.ipynb -o analysis.pdf +pdfengine pdf convert analysis.ipynb -o analysis.pdf ``` **What to watch:** @@ -97,7 +97,7 @@ annave pdf convert analysis.ipynb -o analysis.pdf **Scenario:** A server-side template renders an HTML report, which is then converted to PDF. ```bash -annave pdf convert report.html -o report.pdf +pdfengine pdf convert report.html -o report.pdf ``` Or, from a Go service that already has the HTML in memory: @@ -119,7 +119,7 @@ pdf, err := e.Convert(context.Background(), []byte(html), pdfengine.FormatHTML) **Scenario:** Convert a 50-page technical specification or legal document. ```bash -annave pdf convert spec.md -o spec.pdf +pdfengine pdf convert spec.md -o spec.pdf ``` If the document exceeds the default limits, `Convert` returns an error: @@ -144,7 +144,7 @@ Then rebuild. **Scenario:** Wrap a PNG or JPEG in a PDF page, for archiving or consistent delivery format. ```bash -annave pdf convert diagram.png -o diagram.pdf +pdfengine pdf convert diagram.png -o diagram.pdf ``` **What to watch:** diff --git a/docs/WHITEPAPER.md b/docs/WHITEPAPER.md index cab1903..2e1dd8f 100644 --- a/docs/WHITEPAPER.md +++ b/docs/WHITEPAPER.md @@ -1,10 +1,10 @@ @@ -39,7 +39,7 @@ Neither category is well-suited to the use case of "accept a document in any com ## Architecture summary -The engine is a six-stage pipeline (`internal/engine`), driven directly by two consumers: the public `pdfengine` package and the `annave` CLI. See `docs/ARCHITECTURE.md` for the full package map. +The engine is a six-stage pipeline (`internal/engine`), driven directly by two consumers: the public `pdfengine` package and the `pdfengine` CLI. See `docs/ARCHITECTURE.md` for the full package map. ``` Normalise → Parse → Validate → Layout → Paginate → Render diff --git a/engine.go b/engine.go index fc56c8a..de83aaa 100644 --- a/engine.go +++ b/engine.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package pdfengine diff --git a/error.go b/error.go index 3232389..a6e1a7b 100644 --- a/error.go +++ b/error.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package pdfengine @@ -39,12 +39,12 @@ func (e *Error) Error() string { return fmt.Sprintf("[%s/%s] %s", e.Stage, e.Code, e.Message) } -// translateError copies the fields of an internal *engine.AnnaveError into +// translateError copies the fields of an internal *engine.Error into // a public *Error. It never returns the internal error itself, so a caller // doing errors.As on an internal type can never succeed against a value // this package returns. func translateError(err error) error { - var ae *engine.AnnaveError + var ae *engine.Error if errors.As(err, &ae) { return &Error{Code: ae.Code, Stage: toStage(ae.Stage), Message: ae.Message} } diff --git a/format.go b/format.go index 67cfe08..8bc551d 100644 --- a/format.go +++ b/format.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package pdfengine diff --git a/internal/ast/types.go b/internal/ast/types.go index 592cbeb..2ced70b 100644 --- a/internal/ast/types.go +++ b/internal/ast/types.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package ast diff --git a/internal/engine/config.go b/internal/engine/config.go index e4958dc..44341cb 100644 --- a/internal/engine/config.go +++ b/internal/engine/config.go @@ -1,12 +1,12 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine import "strings" -const EngineVersion = "1.3.1" +const EngineVersion = "1.4.0" const SchemaVersion = "1" func IsSchemaCompatible(version string) bool { diff --git a/internal/engine/errors.go b/internal/engine/errors.go index e224f24..3993d2b 100644 --- a/internal/engine/errors.go +++ b/internal/engine/errors.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine @@ -17,16 +17,16 @@ const ( StageRender EngineStage = "render" ) -type AnnaveError struct { +type Error struct { Code string `json:"code"` Stage EngineStage `json:"stage"` Message string `json:"message"` } -func (e *AnnaveError) Error() string { +func (e *Error) Error() string { return fmt.Sprintf("[%s/%s] %s", e.Stage, e.Code, e.Message) } -func NewError(code string, stage EngineStage, message string) *AnnaveError { - return &AnnaveError{Code: code, Stage: stage, Message: message} +func NewError(code string, stage EngineStage, message string) *Error { + return &Error{Code: code, Stage: stage, Message: message} } diff --git a/internal/engine/golden_test.go b/internal/engine/golden_test.go index cb0573e..d4a7e7d 100644 --- a/internal/engine/golden_test.go +++ b/internal/engine/golden_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/engine/layout.go b/internal/engine/layout.go index 62c9563..0772e79 100644 --- a/internal/engine/layout.go +++ b/internal/engine/layout.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/engine/liveconfig.go b/internal/engine/liveconfig.go index 83499bb..4662397 100644 --- a/internal/engine/liveconfig.go +++ b/internal/engine/liveconfig.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/engine/measurer.go b/internal/engine/measurer.go index efee201..64f5261 100644 --- a/internal/engine/measurer.go +++ b/internal/engine/measurer.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/engine/measurer_test.go b/internal/engine/measurer_test.go index 882524b..b04b9e4 100644 --- a/internal/engine/measurer_test.go +++ b/internal/engine/measurer_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/engine/normalizer.go b/internal/engine/normalizer.go index 60cf0f2..068e0b9 100644 --- a/internal/engine/normalizer.go +++ b/internal/engine/normalizer.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/engine/normalizer_test.go b/internal/engine/normalizer_test.go index f3f4933..1b82962 100644 --- a/internal/engine/normalizer_test.go +++ b/internal/engine/normalizer_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/engine/override.go b/internal/engine/override.go index f54adb3..d1d6518 100644 --- a/internal/engine/override.go +++ b/internal/engine/override.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/engine/paginator.go b/internal/engine/paginator.go index 055bdc7..13ec59a 100644 --- a/internal/engine/paginator.go +++ b/internal/engine/paginator.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/engine/pipeline.go b/internal/engine/pipeline.go index 9091c10..bb91562 100644 --- a/internal/engine/pipeline.go +++ b/internal/engine/pipeline.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/engine/pipeline_test.go b/internal/engine/pipeline_test.go index 89ef345..ac6976f 100644 --- a/internal/engine/pipeline_test.go +++ b/internal/engine/pipeline_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine @@ -70,9 +70,9 @@ func TestPipeline_Run_RejectsOversizedInput(t *testing.T) { if err == nil { t.Fatal("expected error for oversized input, got nil") } - ae, ok := err.(*AnnaveError) + ae, ok := err.(*Error) if !ok { - t.Fatalf("expected *AnnaveError, got %T: %v", err, err) + t.Fatalf("expected *Error, got %T: %v", err, err) } if ae.Stage != StageInput { t.Errorf("expected stage %q, got %q", StageInput, ae.Stage) @@ -87,9 +87,9 @@ func TestPipeline_Run_RejectsUnsupportedFormat(t *testing.T) { if err == nil { t.Fatal("expected error for an unrecognised format, got nil") } - ae, ok := err.(*AnnaveError) + ae, ok := err.(*Error) if !ok { - t.Fatalf("expected *AnnaveError, got %T: %v", err, err) + t.Fatalf("expected *Error, got %T: %v", err, err) } if ae.Code != "ENGINE_ERR_UNSUPPORTED_FORMAT" { t.Errorf("expected code %q, got %q", "ENGINE_ERR_UNSUPPORTED_FORMAT", ae.Code) @@ -213,9 +213,9 @@ func TestPipeline_Run_ParserLimitErrors(t *testing.T) { cfg.Limits.Input.MaxInputChars = tc.maxInputChars } _, err := NewPipeline(cfg).Run(tc.input, tc.format) - var ae *AnnaveError + var ae *Error if !errors.As(err, &ae) { - t.Fatalf("Run() error = %v, want *AnnaveError", err) + t.Fatalf("Run() error = %v, want *Error", err) } if ae.Code != "ENGINE_ERR_PARSE_FAILED" { t.Errorf("Code = %q, want %q", ae.Code, "ENGINE_ERR_PARSE_FAILED") @@ -426,9 +426,9 @@ func TestPipeline_Run_AutoBracketTextIsNotJSON(t *testing.T) { // TestPipeline_Run_ExplicitJSONInvalidFails checks that explicit json with invalid input still fails. func TestPipeline_Run_ExplicitJSONInvalidFails(t *testing.T) { _, err := NewPipeline(mustDefaultConfig(t)).Run("{draft} notes", parser.FormatJSON) - var ae *AnnaveError + var ae *Error if !errors.As(err, &ae) { - t.Fatalf("Run() error = %v, want *AnnaveError", err) + t.Fatalf("Run() error = %v, want *Error", err) } if ae.Code != "ENGINE_ERR_PARSE_FAILED" { t.Errorf("Code = %q, want %q", ae.Code, "ENGINE_ERR_PARSE_FAILED") @@ -439,9 +439,9 @@ func TestPipeline_Run_ExplicitJSONInvalidFails(t *testing.T) { func TestPipeline_Run_UndecodableNotebookFails(t *testing.T) { for _, f := range []parser.InputFormat{parser.FormatAuto, parser.FormatIPYNB} { _, err := NewPipeline(mustDefaultConfig(t)).Run(`{"cells": [1, 2], "nbformat": 4}`, f) - var ae *AnnaveError + var ae *Error if !errors.As(err, &ae) { - t.Fatalf("Run(%q) error = %v, want *AnnaveError", f, err) + t.Fatalf("Run(%q) error = %v, want *Error", f, err) } if ae.Code != "ENGINE_ERR_PARSE_FAILED" { t.Errorf("Run(%q) Code = %q, want %q", f, ae.Code, "ENGINE_ERR_PARSE_FAILED") diff --git a/internal/engine/renderer.go b/internal/engine/renderer.go index 703a268..51588d2 100644 --- a/internal/engine/renderer.go +++ b/internal/engine/renderer.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/engine/style.go b/internal/engine/style.go index 81dbcfb..8fc0522 100644 --- a/internal/engine/style.go +++ b/internal/engine/style.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/engine/testdata/basic.md b/internal/engine/testdata/basic.md index bfc0690..ed6d389 100644 --- a/internal/engine/testdata/basic.md +++ b/internal/engine/testdata/basic.md @@ -1,4 +1,4 @@ -# ANNÁVE PDF Engine +# PDF Engine A Go library and CLI that convert documents to PDF. Supports Markdown, HTML, DOCX, CSV, JSON, YAML, XML, RST, Jupyter Notebooks, and images. @@ -40,8 +40,8 @@ document: ## Quick start ```bash -go build ./cmd/cli -annave pdf convert README.md -o output.pdf +go build ./cmd/pdfengine +pdfengine pdf convert README.md -o output.pdf ``` > All configuration is embedded at build time. No external files are read at runtime. diff --git a/internal/engine/validator.go b/internal/engine/validator.go index d22083e..46b5a89 100644 --- a/internal/engine/validator.go +++ b/internal/engine/validator.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package engine diff --git a/internal/parser/csv.go b/internal/parser/csv.go index 349de4c..11a5f1d 100644 --- a/internal/parser/csv.go +++ b/internal/parser/csv.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/csv_test.go b/internal/parser/csv_test.go index fc1f9e3..ad6253d 100644 --- a/internal/parser/csv_test.go +++ b/internal/parser/csv_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/docx.go b/internal/parser/docx.go index cd8da38..69a7f21 100644 --- a/internal/parser/docx.go +++ b/internal/parser/docx.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/docx_test.go b/internal/parser/docx_test.go index 3a432c8..7d07eaf 100644 --- a/internal/parser/docx_test.go +++ b/internal/parser/docx_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/html.go b/internal/parser/html.go index eb6b5eb..4a3e81c 100644 --- a/internal/parser/html.go +++ b/internal/parser/html.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/image.go b/internal/parser/image.go index 109dc2f..179ca3b 100644 --- a/internal/parser/image.go +++ b/internal/parser/image.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/image_test.go b/internal/parser/image_test.go index b5d1a94..afda2b5 100644 --- a/internal/parser/image_test.go +++ b/internal/parser/image_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/interface.go b/internal/parser/interface.go index bb61d46..fe7074e 100644 --- a/internal/parser/interface.go +++ b/internal/parser/interface.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/ipynb.go b/internal/parser/ipynb.go index 253f71a..2265a85 100644 --- a/internal/parser/ipynb.go +++ b/internal/parser/ipynb.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/ipynb_test.go b/internal/parser/ipynb_test.go index 050f325..f227f32 100644 --- a/internal/parser/ipynb_test.go +++ b/internal/parser/ipynb_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/json.go b/internal/parser/json.go index e41ee5d..aa6085f 100644 --- a/internal/parser/json.go +++ b/internal/parser/json.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/json_test.go b/internal/parser/json_test.go index f7baeff..e58234a 100644 --- a/internal/parser/json_test.go +++ b/internal/parser/json_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/md.go b/internal/parser/md.go index 5820976..16d372a 100644 --- a/internal/parser/md.go +++ b/internal/parser/md.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/md_bench_test.go b/internal/parser/md_bench_test.go index 46ffbe7..c18adda 100644 --- a/internal/parser/md_bench_test.go +++ b/internal/parser/md_bench_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/md_test.go b/internal/parser/md_test.go index 2352ede..5301d04 100644 --- a/internal/parser/md_test.go +++ b/internal/parser/md_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/registry.go b/internal/parser/registry.go index 4a2f9fd..d4fe7f3 100644 --- a/internal/parser/registry.go +++ b/internal/parser/registry.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/registry_test.go b/internal/parser/registry_test.go index 60a3f08..5aa8fa8 100644 --- a/internal/parser/registry_test.go +++ b/internal/parser/registry_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/rst.go b/internal/parser/rst.go index e738ac4..c0afff2 100644 --- a/internal/parser/rst.go +++ b/internal/parser/rst.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/txt.go b/internal/parser/txt.go index 4d7d487..9e30fa6 100644 --- a/internal/parser/txt.go +++ b/internal/parser/txt.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/xml.go b/internal/parser/xml.go index 370abb4..779398f 100644 --- a/internal/parser/xml.go +++ b/internal/parser/xml.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/xml_test.go b/internal/parser/xml_test.go index ebcb8e2..09d0c8e 100644 --- a/internal/parser/xml_test.go +++ b/internal/parser/xml_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/yaml.go b/internal/parser/yaml.go index db6cb24..d0a82e0 100644 --- a/internal/parser/yaml.go +++ b/internal/parser/yaml.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/internal/parser/yaml_test.go b/internal/parser/yaml_test.go index 92280ce..3d5152f 100644 --- a/internal/parser/yaml_test.go +++ b/internal/parser/yaml_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package parser diff --git a/option.go b/option.go index 6cfd15b..85b335d 100644 --- a/option.go +++ b/option.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package pdfengine diff --git a/pdfengine_test.go b/pdfengine_test.go index 526f602..0392862 100644 --- a/pdfengine_test.go +++ b/pdfengine_test.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT package pdfengine_test @@ -40,7 +40,7 @@ func TestConvert_AllFormats(t *testing.T) { input string f pdfengine.Format }{ - {"markdown", "# ANNÁVE PDF Engine\n\nConverts documents to PDF.", pdfengine.FormatMarkdown}, + {"markdown", "# PDF Engine\n\nConverts documents to PDF.", pdfengine.FormatMarkdown}, {"text", "This is a plain text report.\n\nIt has two paragraphs.", pdfengine.FormatText}, {"json", `{"type":"document","children":[{"type":"heading","level":1,"text":"Report"}]}`, pdfengine.FormatJSON}, {"html", "

Report

A paragraph.

", pdfengine.FormatHTML}, diff --git a/schema/document.v1.schema.json b/schema/document.v1.schema.json index dbf13f5..06f7a31 100644 --- a/schema/document.v1.schema.json +++ b/schema/document.v1.schema.json @@ -1,7 +1,7 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://www.annave.tech/pdfengine/schema/document.v1", - "title": "ANNÁVE PDF Engine: Document", + "title": "PDF Engine: Document", "description": "The canonical document representation accepted by the engine's JSON input format. All other formats (Markdown, HTML, CSV, etc.) are converted to this structure internally before layout and rendering.", "type": "object", "required": ["type", "children"], diff --git a/schema/embed.go b/schema/embed.go index a40f975..f55ec22 100644 --- a/schema/embed.go +++ b/schema/embed.go @@ -1,6 +1,6 @@ // Copyright 2026 Anna Veretennykova // -// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT // Package schema embeds the JSON Schema definitions shipped with the engine. package schema