Repository navigation
✨ Honor enclosing demands on fields and strings when writing (#447) - #528
Merged
Merged
Conversation
A non-None `enclosing` ('{', '"' or 'no-enclosing') on a Field or
String is now honored by the `AddEnclosingMiddleware` with precedence
over all other enclosing rules. Assigning a new value resets the
demand, such that stale demands cannot be applied to changed values.
Also makes `AddEnclosingMiddleware._enclose` safe for int values
(previously, `value.isdigit()` raised AttributeError for int values
when `enclose_integers=False`).
Towards #447
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`MonthAbbreviationMiddleware` and `MonthIntMiddleware` now set a
`no-enclosing` demand on the month field, such that the default
unparse stack writes `month = jan` instead of `month = {jan}`
(which would turn the string reference into a literal).
Also fixes a latent bug where the middlewares' unchanged-month paths
returned the `Field` object instead of its value, assigning the field
to itself as value.
Fixes #447
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Previously, a plain parse -> write roundtrip turned unresolved string
references and concatenations into literals (e.g. `month = jan`
became `month = {jan}`), silently changing their semantics.
The `RemoveEnclosingMiddleware` now sets a `no-enclosing` demand on
unenclosed, non-numeric values, which the `AddEnclosingMiddleware`
honors. Plain integer values (e.g. `year = 2019`) remain subject to
the writer's `enclose_integers` option, as before.
Related to #447
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collaborator
Author
|
reviewed |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #447
What this PR does
Adds an explicit, always-honored enclosing demand to field and string values, and uses it to make month macros (and other bibtex string references) survive writing with the default stack.
1.
Field.enclosing/String.enclosing(new model attribute)'{','"','no-enclosing', orNone(default = writer middleware decides).AddEnclosingMiddlewarehonors a non-None demand with precedence overreuse_previous_enclosing, the int-rule, anddefault_enclosing.valueresets the demand toNone, so a stale demand can never be applied to a changed value (and the demand is naturally "consumed" once the enclosed value is written).2. Month middlewares set the demand (the actual #447 use-case)
MonthAbbreviationMiddlewareandMonthIntMiddlewarenow demandno-enclosingfor the macros/ints they produce. With the default unparse stack:MonthLongStringMiddlewaredeliberately sets no demand (full month names are literals).3. Parse→write roundtrip no longer corrupts references (latent bug)
Previously, a plain
parse_string→write_stringroundtrip turnedmonth = janintomonth = {jan}andpages = intro # outrointo{intro # outro}— silently changing semantics.RemoveEnclosingMiddlewarenow sets theno-enclosingdemand on unenclosed, non-numeric values. Bare integers (year = 2019) remain governed byenclose_integers, as before.Note: This changes default write output for unenclosed non-numeric inputs (verbatim instead of brace-normalized). I'd argue the old behavior was a bug since it changed semantics, but it's in a separate commit (7e37177) for easy discussion/removal.
Drive-by fixes
AddEnclosingMiddleware._encloseno longer crashes onintvalues whenenclose_integers=False(value.isdigit()→AttributeError).Fieldobject instead of its value (assigning the field to itself asfield.value).Design discussion
Alternatives considered (marker
strsubclass, parser-metadata convention, month special-casing in the writer) — the explicit attribute was chosen because it is discoverable, expresses any enclosing preference (not just "none"), is robust against field-key renames/duplicates, and fails safe via the value-setter reset.🤖 Generated with Claude Code