mirror of
https://github.com/storytold/cadcraft.git
synced 2026-11-03 08:52:05 -06:00
entget gives TEXT strings as the file has them, like MTEXT
Decoding the carets in entity_groups broke entmod (it reads the groups as a file, so `A^ B` came back as `A^B`) and reached into an ATTDEF's embedded MTEXT. entity_groups is left as on main: it gives the file's groups, as it already does for MTEXT, and entmod reads them back unchanged (test entmod_of_entget_keeps_the_strings). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
a6c1fc6341
commit
e61b4dd3d3
@@ -152,17 +152,5 @@ pub fn entity_groups(d: &Drawing, e: &Entity) -> (String, Vec<Tag>) {
|
||||
entity(&mut w, d, e, "0", paper, &cx);
|
||||
let mut tags = w.t.into_iter();
|
||||
let kind = tags.next().filter(|t| t.code == 0).map(|t| t.value.as_str()).unwrap_or_default();
|
||||
// Strings as AutoLISP sees them: `10^2`, not the file's `10^ 2`. Only the groups written
|
||||
// escaped: the text (1) and an ATTDEF's prompt (3), not a DIMENSION's style name (3).
|
||||
let escaped = |code: i32| match kind.as_str() {
|
||||
"TEXT" | "ATTRIB" | "DIMENSION" => code == 1,
|
||||
"ATTDEF" => matches!(code, 1 | 3),
|
||||
_ => false,
|
||||
};
|
||||
let tags = tags
|
||||
.take_while(|t| t.code != 0)
|
||||
.filter(|t| t.code != 330)
|
||||
.map(|t| if escaped(t.code) { Tag::s(t.code, crate::dxf_read::mtext_dxf::unescape_carets(&t.value.as_str())) } else { t })
|
||||
.collect();
|
||||
(kind, tags)
|
||||
(kind, tags.take_while(|t| t.code != 0).filter(|t| t.code != 330).collect())
|
||||
}
|
||||
|
||||
@@ -55,21 +55,21 @@ fn drawing() -> Drawing {
|
||||
modes: Default::default(),
|
||||
};
|
||||
d.add(&Space::Model, Common::default(), EntityKind::AttDef(attdef)).unwrap();
|
||||
let dm = Dimension { style: "A^ B".into(), ..dimension("<> x10^3") };
|
||||
d.add(&Space::Model, Common::default(), EntityKind::Dimension(dm)).unwrap();
|
||||
d.add(&Space::Model, Common::default(), EntityKind::Dimension(dimension("<> x10^3"))).unwrap();
|
||||
d
|
||||
}
|
||||
|
||||
fn strings(d: &Drawing) -> Vec<String> {
|
||||
d.model
|
||||
.iter()
|
||||
.flat_map(|e| match &e.kind {
|
||||
EntityKind::Text(t) => vec![t.value.clone()],
|
||||
EntityKind::AttDef(a) => vec![a.text.value.clone(), a.prompt.clone()],
|
||||
EntityKind::Dimension(dm) => vec![dm.text.clone()],
|
||||
_ => Vec::new(),
|
||||
})
|
||||
.collect()
|
||||
fn strings(k: &EntityKind) -> Vec<String> {
|
||||
match k {
|
||||
EntityKind::Text(t) => vec![t.value.clone()],
|
||||
EntityKind::AttDef(a) => vec![a.text.value.clone(), a.prompt.clone()],
|
||||
EntityKind::Dimension(dm) => vec![dm.text.clone()],
|
||||
_ => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn all_strings(d: &Drawing) -> Vec<String> {
|
||||
d.model.iter().flat_map(|e| strings(&e.kind)).collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -80,20 +80,19 @@ fn carets_are_written_escaped_and_read_back() {
|
||||
assert!(dxf.contains(escaped), "{escaped}");
|
||||
}
|
||||
let back = read_dxf(dxf.as_bytes()).unwrap();
|
||||
assert_eq!(strings(&back), ["10^2 m, A^JB", "1^3", "Area in m^2", "<> x10^3"]);
|
||||
assert_eq!(all_strings(&back), ["10^2 m, A^JB", "1^3", "Area in m^2", "<> x10^3"]);
|
||||
// Older files have bare carets: kept as they are.
|
||||
let old = read_dxf(dxf.replace("10^ 2 m", "10^2 m").as_bytes()).unwrap();
|
||||
assert_eq!(strings(&old)[0], "10^2 m, A^JB");
|
||||
assert_eq!(all_strings(&old)[0], "10^2 m, A^JB");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn entget_shows_plain_carets() {
|
||||
fn entmod_of_entget_keeps_the_strings() {
|
||||
// entget gives the groups as the file has them (as for MTEXT), and entmod reads them back.
|
||||
let d = drawing();
|
||||
let groups = |i: usize| cadcraft_io::entity_groups(&d, d.model.iter().nth(i).unwrap()).1;
|
||||
let has = |g: &[cadcraft_dxf::Tag], code: i32, value: &str| g.iter().any(|t| t.code == code && t.value.as_str() == value);
|
||||
assert!(has(&groups(0), 1, "10^2 m, A^JB"));
|
||||
assert!(has(&groups(1), 3, "Area in m^2"));
|
||||
// A DIMENSION's group 3 is its style name, written as it is.
|
||||
let dim = groups(2);
|
||||
assert!(has(&dim, 1, "<> x10^3") && has(&dim, 3, "A^ B"), "{dim:?}");
|
||||
for e in d.model.iter() {
|
||||
let (kind, groups) = cadcraft_io::entity_groups(&d, e);
|
||||
let (_, back) = cadcraft_io::entity_from_groups(&kind, &groups).unwrap();
|
||||
assert_eq!(strings(&back), strings(&e.kind), "{kind}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ our output in AutoCAD black-box.
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-31 | minor | A caret in a TEXT, ATTDEF, ATTRIB or DIMENSION string is written as `^` and a space and read back, as the DXF Reference has it: AutoCAD read the bare `^2` of `10^2` as a control character; AutoLISP's entget shows the plain caret |
|
||||
| 2026-10-31 | minor | A caret in a TEXT, ATTDEF, ATTRIB or DIMENSION string is written as `^` and a space and read back, as the DXF Reference has it: AutoCAD read the bare `^2` of `10^2` as a control character |
|
||||
| 2026-10-29 | minor | R2000 DXF: CLASS records written without group 91 (instance count), which came with the 2004 format; AutoCAD LT 2026 stopped responding on every R2000 DXF CADCraft saved (checked black-box in AutoCAD LT 2026) |
|
||||
| 2026-10-26 | minor | CC-046: ATTEDIT and -ATTEDIT value changes invalidate derived justified baselines before DXF/DWG export; preserve alignment anchors, unchanged values and Aligned/Fit endpoints. Review follow-up: baseline recomputation preserves insertion elevation independently of alignment elevation. The shared writer correction also applies to justified TEXT. Independent of attribute editor UI; reverting the follow-up restores elevation loss on recomputation, while reverting the value setter restores stale XY baselines. |
|
||||
| 2026-10-25 | minor | LAYOUT SAveas (`layout.saveas`) writes a layout as a drawing template: its page setup and paper space objects, no model space objects or other layouts, and only the named objects they use |
|
||||
|
||||
Reference in New Issue
Block a user