rvt 0.4.0

Apache-2.0 clean-room reader for Autodesk Revit files (.rvt, .rfa, .rte, .rft) without Revit: metadata, previews and the embedded schema of 2016-2026 files, and typed elements with measured geometry from Revit 2024 and 2025 projects, exported as IFC4, glTF and plan SVG.
Documentation
# git-cliff config — Q-11 / #348
#
# rvt-rs CHANGELOG.md is hand-curated with rich narrative per release
# (see entries for [0.1.0], [0.1.1], [0.1.2] — each has multi-paragraph
# "Added / Changed / Fixed" sections with context the bare commit
# subject can't carry). Wholesale regeneration from `git log` would
# lose that content. The workflow (see .github/workflows/changelog.yml)
# therefore uses this config to write ONLY unreleased commits to a
# separate file (`CHANGELOG-UNRELEASED.md`) that release managers
# copy-paste into CHANGELOG.md when curating a version. On tag push
# git-cliff emits `RELEASE_NOTES.md` as a workflow artifact for the
# GitHub Release body.
#
# Conventional-commit prefixes observed in rvt-rs history (via
# `git log --oneline`): feat, fix, docs, test, perf, refactor, ci,
# chore (including `chore(release): vX.Y.Z`). Scopes are optional
# and the parsers below match both scoped (`feat(ifc):`) and
# unscoped (`feat:`) forms.

[changelog]
# Header mirrors the existing CHANGELOG.md preamble so auto-generated
# output is drop-in compatible when a maintainer chooses to overwrite.
header = """
# Changelog

All notable changes will be documented here. This project follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
[semver](https://semver.org/spec/v2.0.0.html).
"""

# Body renders each version as `## [X.Y.Z] — YYYY-MM-DD` (em-dash
# separator) to match the existing manual entries. Groups map to
# Keep a Changelog's canonical "Added / Changed / Fixed" subheadings.
body = """
{% if version %}\
    ## [{{ version | trim_start_matches(pat="v") }}] — {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
    ## [Unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
    ### {{ group | upper_first }}
    {% for commit in commits %}
        - {{ commit.message | split(pat="\n") | first | upper_first }}\
    {% endfor %}
{% endfor %}\n
"""

footer = "<!-- generated by git-cliff -->"
trim = true

[git]
conventional_commits = true
# Drop non-conventional commits from the output entirely — keeps the
# auto-section focused on release-relevant changes.
filter_unconventional = true
# Match both scoped (`feat(ifc):`) and unscoped (`feat:`) prefixes.
# Order matters: `^chore\\(release\\)` must be tested before the
# generic `^chore` skip rule, or tag-bump commits get dropped.
commit_parsers = [
    { message = "^chore\\(release\\)", skip = true },
    { message = "^chore\\(changelog\\)", skip = true },
    { message = "^chore\\(deps\\)", group = "Dependencies" },
    { message = "^feat", group = "Added" },
    { message = "^fix", group = "Fixed" },
    { message = "^perf", group = "Performance" },
    { message = "^refactor", group = "Changed" },
    { message = "^docs", group = "Documentation" },
    { message = "^test", group = "Testing" },
    { message = "^ci", skip = true },
    { message = "^chore", skip = true },
]
filter_commits = true
# Matches v0.1.0, v0.1.2, v1.0.0-rc1 etc. Release tag format is
# documented in RELEASE.md.
tag_pattern = "v[0-9]*"
sort_commits = "oldest"