Skip to content

Commit 9c529d1

Browse files
authored
Update vegalite theme (#133)
1 parent 559dec8 commit 9c529d1

3 files changed

Lines changed: 96 additions & 4 deletions

File tree

src/parser/builder.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,40 @@ fn extract_name_value_nodes<'a>(node: &'a Node<'a>, context: &str) -> Result<(No
3737
Ok((name_node, value_node))
3838
}
3939

40-
/// Parse a string node, removing quotes
40+
/// Parse a string node, removing quotes and processing escape sequences
4141
fn parse_string_node(node: &Node, source: &SourceTree) -> String {
4242
let text = source.get_text(node);
43-
text.trim_matches(|c| c == '\'' || c == '"').to_string()
43+
let unquoted = text.trim_matches(|c| c == '\'' || c == '"');
44+
process_escape_sequences(unquoted)
45+
}
46+
47+
/// Process escape sequences in a string (e.g., \n, \t, \\, \')
48+
fn process_escape_sequences(s: &str) -> String {
49+
let mut result = String::with_capacity(s.len());
50+
let mut chars = s.chars().peekable();
51+
52+
while let Some(c) = chars.next() {
53+
if c == '\\' {
54+
match chars.next() {
55+
Some('n') => result.push('\n'),
56+
Some('t') => result.push('\t'),
57+
Some('r') => result.push('\r'),
58+
Some('\\') => result.push('\\'),
59+
Some('\'') => result.push('\''),
60+
Some('"') => result.push('"'),
61+
Some(other) => {
62+
// Unknown escape sequence - keep as-is
63+
result.push('\\');
64+
result.push(other);
65+
}
66+
None => result.push('\\'), // Trailing backslash
67+
}
68+
} else {
69+
result.push(c);
70+
}
71+
}
72+
73+
result
4474
}
4575

4676
/// Parse a number node into f64

src/writer/vegalite/mod.rs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,65 @@ impl VegaLiteWriter {
358358
schema: "https://vega.github.io/schema/vega-lite/v6.json".to_string(),
359359
}
360360
}
361+
362+
/// Build default Vega-Lite config matching ggplot2's theme_gray()
363+
///
364+
/// Font sizes converted from ggplot2 points to pixels (1 pt ≈ 1.33 px at 96 DPI):
365+
/// - axis.text: 8.8 pts (rel(0.8) × 11) → 12 px
366+
/// - axis.title: 11 pts → 15 px
367+
/// - legend.text: 8.8 pts → 12 px
368+
/// - legend.title: 11 pts → 15 px
369+
/// - plot.title: 13.2 pts (rel(1.2) × 11) → 18 px
370+
/// - tick size: ~2.75 pts → 4 px
371+
fn default_theme_config(&self) -> Value {
372+
json!({
373+
"view": {
374+
"stroke": null,
375+
"fill": "#EBEBEB"
376+
},
377+
"axis": {
378+
"domain": false,
379+
"grid": true,
380+
"gridColor": "#FFFFFF",
381+
"gridWidth": 1,
382+
"tickColor": "#333333",
383+
"tickSize": 4,
384+
"labelColor": "#4D4D4D",
385+
"labelFontSize": 12,
386+
"titleColor": "#000000",
387+
"titleFontSize": 15,
388+
"titleFontWeight": "normal",
389+
"titlePadding": 10
390+
},
391+
"legend": {
392+
"labelColor": "#4D4D4D",
393+
"labelFontSize": 12,
394+
"titleColor": "#000000",
395+
"titleFontSize": 15,
396+
"titleFontWeight": "normal",
397+
"titlePadding": 8,
398+
"rowPadding": 6
399+
},
400+
"title": {
401+
"color": "#000000",
402+
"fontSize": 18,
403+
"fontWeight": "normal",
404+
"subtitleColor": "#4D4D4D",
405+
"subtitleFontSize": 15,
406+
"subtitleFontWeight": "normal",
407+
"anchor": "start",
408+
"frame": "group",
409+
"offset": 10
410+
},
411+
"header": {
412+
"labelColor": "#000000",
413+
"labelFontSize": 15,
414+
"labelFontWeight": "normal",
415+
"labelPadding": 5,
416+
"title": null
417+
}
418+
})
419+
}
361420
}
362421

363422
impl Default for VegaLiteWriter {
@@ -442,7 +501,10 @@ impl Writer for VegaLiteWriter {
442501
apply_faceting(&mut vl_spec, facet, facet_df);
443502
}
444503

445-
// 11. Serialize
504+
// 11. Add default theme config (ggplot2-like gray theme)
505+
vl_spec["config"] = self.default_theme_config();
506+
507+
// 12. Serialize
446508
serde_json::to_string_pretty(&vl_spec).map_err(|e| {
447509
GgsqlError::WriterError(format!("Failed to serialize Vega-Lite JSON: {}", e))
448510
})

tree-sitter-ggsql/grammar.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ module.exports = grammar({
870870
)
871871
)),
872872

873-
string: $ => seq("'", repeat(choice(/[^'\\]/, seq('\\', /.*/))), "'"),
873+
string: $ => seq("'", repeat(choice(/[^'\\]/, /\\./)), "'"),
874874

875875
boolean: $ => choice('true', 'false'),
876876

0 commit comments

Comments
 (0)