diff --git a/Cargo.lock b/Cargo.lock index 4645b3f..14c7929 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -718,7 +718,7 @@ dependencies = [ [[package]] name = "texpand-cli" -version = "0.1.1" +version = "0.1.2" dependencies = [ "anyhow", "arboard", @@ -731,7 +731,7 @@ dependencies = [ [[package]] name = "texpand-core" -version = "0.1.1" +version = "0.1.2" dependencies = [ "anyhow", "serde", @@ -741,7 +741,7 @@ dependencies = [ [[package]] name = "texpand-vscode" -version = "0.1.0" +version = "0.1.2" dependencies = [ "anyhow", "serde", diff --git a/texpand-cli/Cargo.toml b/texpand-cli/Cargo.toml index 479c919..f220279 100644 --- a/texpand-cli/Cargo.toml +++ b/texpand-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "texpand-cli" -version = "0.1.1" +version = "0.1.2" edition = "2024" [dependencies] diff --git a/texpand-core/Cargo.toml b/texpand-core/Cargo.toml index e40ea51..8661769 100644 --- a/texpand-core/Cargo.toml +++ b/texpand-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "texpand-core" -version = "0.1.1" +version = "0.1.2" edition = "2024" [dependencies] diff --git a/texpand-core/src/compressor.rs b/texpand-core/src/compressor.rs index df0554a..0c74ddf 100644 --- a/texpand-core/src/compressor.rs +++ b/texpand-core/src/compressor.rs @@ -40,13 +40,18 @@ impl CompressorState { } /// Emit a single token, applying identifier-spacing and `#`-newline rules. - pub fn emit_token(&mut self, text: &str) { + /// + /// Set `skip_space_before` to `true` to suppress the identifier-space + /// insertion for the current token (used for `literal_suffix` inside a + /// `user_defined_literal` node, where `123_km` must remain `123_km`). + pub fn emit_token(&mut self, text: &str, skip_space_before: bool) { if let Some(ch) = text.chars().next() { // Any `#` leaf must sit on its own line. if ch == '#' && !self.output.is_empty() && !self.output.ends_with('\n') { self.output.push('\n'); } - if let Some(prev) = self.prev_last + if !skip_space_before + && let Some(prev) = self.prev_last && is_ident_char(prev) && is_ident_char(ch) { @@ -208,7 +213,7 @@ fn compress_impl( && let Ok(text) = node.utf8_text(source.as_bytes()) && !text.is_empty() { - st.emit_token(text); + st.emit_token(text, node.kind() == "literal_suffix"); // `#define FOO …` — ensure at least one space between the // macro name and the replacement text so that // #define FOO"abc" and #define FOO(expr) @@ -525,4 +530,22 @@ func(); ); assert!(s.contains("FOO(x)"), "function-like FOO(x): {s:?}"); } + + #[test] + fn test_user_defined_literal_no_space() { + // User-defined literals must not get a space between the literal + // and its suffix: `123_km` not `123 _km`. + let s = compress_source("auto x = 123_km;\n"); + assert!(s.contains("123_km"), "user-defined literal broken: {s:?}"); + let s = compress_source("auto y = 1.5_deg;\n"); + assert!( + s.contains("1.5_deg"), + "user-defined float literal broken: {s:?}" + ); + let s = compress_source("auto y = 114min;\n"); + assert!( + s.contains("114min"), + "literal without '_' prefix broken: {s:?}" + ); + } } diff --git a/texpand-core/src/expander.rs b/texpand-core/src/expander.rs index f14c332..f2a6640 100644 --- a/texpand-core/src/expander.rs +++ b/texpand-core/src/expander.rs @@ -220,7 +220,7 @@ fn expand_recursive( if !state.completed.contains(&key) { if let Some(cs) = cs.as_mut() { if let Ok(text) = node.utf8_text(source.as_bytes()) { - cs.emit_token(text); + cs.emit_token(text, false); } } else { output.push_str(&source[node_start..node_end]); @@ -282,20 +282,19 @@ fn expand_recursive( // ── Everything else (leaf → emit text) ──────────────────── _ => { - if node.child_count() == 0 { - if let Some(ref mut cs) = cs { - if node.kind() != "comment" - && let Ok(text) = node.utf8_text(source.as_bytes()) - { - cs.emit_token(text); - } - } else { - if node_start > byte_pos { - output.push_str(&source[byte_pos..node_start]); - } - output.push_str(&source[node_start..node_end]); - byte_pos = node_end; + if node.child_count() == 0 + && let Some(ref mut cs) = cs + { + if node.kind() != "comment" + && let Ok(text) = node.utf8_text(source.as_bytes()) + { + cs.emit_token(text, false); + } + if node_start > byte_pos { + output.push_str(&source[byte_pos..node_start]); } + output.push_str(&source[node_start..node_end]); + byte_pos = node_end; } } } diff --git a/texpand-vscode/Cargo.toml b/texpand-vscode/Cargo.toml index 557ba22..dfc3b70 100644 --- a/texpand-vscode/Cargo.toml +++ b/texpand-vscode/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "texpand-vscode" -version = "0.1.0" +version = "0.1.2" edition = "2024" [dependencies] diff --git a/texpand-vscode/extension/README.md b/texpand-vscode/extension/README.md index ad00a94..cb7acac 100644 --- a/texpand-vscode/extension/README.md +++ b/texpand-vscode/extension/README.md @@ -53,6 +53,10 @@ None yet. ## Release Notes +### 0.1.2 + +- Fix: user-defined literals (e.g. `123_km`) no longer get a spurious space inserted during compression. + ### 0.1.0 Initial release. Basic expansion, compression, clipboard and file output. diff --git a/texpand-vscode/extension/README.zh-CN.md b/texpand-vscode/extension/README.zh-CN.md index 1be3a66..b9b0df7 100644 --- a/texpand-vscode/extension/README.zh-CN.md +++ b/texpand-vscode/extension/README.zh-CN.md @@ -53,6 +53,10 @@ ## 更新日志 +### 0.1.2 + +- 修复:用户定义字面量(例如 `123_km`)在压缩时不再被错误插入空格。 + ### 0.1.0 初始发布,支持基础展开、压缩、剪贴板与文件输出。