Metadata-Version: 2.4
Name: icfpy
Version: 1.0.0
Summary: Pure-Python parser, validator, builder, writer and ICX index generator for the Indent Comma Format (ICF).
Project-URL: Homepage, https://icformat.org
Author: Edison Williams
License: MIT
Keywords: icf,icx,indent-comma-format,parser,serialization
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Markup
Requires-Python: >=3.9
Provides-Extra: dev
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# icfpy

A pure-Python library to **parse, validate, build in-memory, write, and convert**
[Indent Comma Format (ICF)](https://icformat.org) files, plus generate **ICX**
companion index files.

- **Python 3.9+**, **zero runtime dependencies** (standard library only).
- JSON output is hand-rolled — no third-party JSON/CSV/XML library.
- A faithful behavioral port of the Java library [`icfj`](https://icformat.org).

## What is ICF?

ICF is a compact, hierarchical, schema-driven data format that combines the
compactness of CSV, the readability of YAML, and the hierarchy of JSON/XML. A document
declares its schema once (`@schema`), optionally carries user metadata (`@metadata`) and
shared reference data (`@masters`), then stores records positionally (`@data` /
`@record`) as comma-separated rows. See `icf_format_specification_v_1.md` and
`icx_index_specification_v_1.md` for the full specs.

## Install

```bash
pip install -e .[dev]   # from a checkout, with the dev tools
# or, once published:
pip install icfpy
```

## Quickstart

```python
import icfpy

# 1. Parse ICF text (or a file path) and navigate the data.
doc = icfpy.parse(open("invoice.icf", encoding="utf-8").read())
data = doc.to_icf_node()
city = data.path("indexdata").path("masterindex").path("Project").path("Location").as_text()

# `path(...)` never raises — absent fields yield IcfMissing, so chains are safe.
missing = data.path("nope").path("still_nope").as_text()   # -> ""

# 2. Validate (never raises on content problems).
result = icfpy.validate(icf_text)
if not result.is_valid:
    for err in result.errors:
        print(err)        # e.g. "ERROR (line 7) [FIELD_COUNT_MISMATCH] ..."

# 3. Build a node from scratch and write it back to ICF text.
root = icfpy.IcfNode.object()
root.put_object("vendor").put("id", "V001").put("email", "v@example.com")
root.put_array("items").add_object().put("sku", "A1").put("qty", 100)
icf = icfpy.write(root)   # infers a schema; object -> one record, array -> many

# 4. Generate the ICX companion index and serialize it.
source = icfpy.parse(icf)
icx_doc = icfpy.generate_icx(source, "invoice.icf", icf)   # populates Line/Offset/Size/Checksum
icx_text = icfpy.write(icx_doc)
```

## Facade API

| Function | Description |
|---|---|
| `icfpy.parse(text_or_path)` | Parse; raises `IcfParseError` on error-level diagnostics. |
| `icfpy.parse_lenient(text)` | Best-effort parse; never raises on content errors. |
| `icfpy.validate(text_or_path)` | Returns a `ValidationResult` (errors + warnings). |
| `icfpy.is_valid(text_or_path)` | `True` when there are no error-level diagnostics. |
| `icfpy.write(doc_or_node[, path])` | Serialize to ICF text; optionally write a UTF-8 file. |
| `icfpy.write_with_checksum(doc_or_node[, path])` | Like `write`, but injects a computed `@checksum` (spec §19, honoring `@hashmethod`). |
| `icfpy.generate_icx(source[, name[, text]])` | Build the ICX index as an `IcfDocument`. |

See [`DOCUMENTATION.md`](DOCUMENTATION.md) for the complete public API and
[`CLAUDE.md`](CLAUDE.md) for the spec gotchas that shape the implementation.

## Development

```bash
pip install -e .[dev]
pytest              # run the test suite (includes four round-trip fixtures)
ruff check .        # lint
ruff format --check .
mypy src/icfpy      # type-check
```

## License

Copyright (c) 2026 Edison Williams. The ICF/ICX specifications are licensed under
[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). The icfpy library is licensed under MIT License.
