diff --git a/CLAUDE.md b/CLAUDE.md index b1a43363..4f545640 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,7 +13,6 @@ DRAW line SCALE x VIA date SCALE y FROM [0, 100000] LABEL title => 'Sales by Region', x => 'Date', y => 'Revenue' -THEME minimal ``` **Statistics**: @@ -257,7 +256,7 @@ For detailed API documentation, see [`src/doc/API.md`](src/doc/API.md). - Uses `tree-sitter-ggsql` grammar (507 lines, simplified approach) - Parses **full query** (SQL + VISUALISE) into concrete syntax tree (CST) -- Grammar supports: PLOT/TABLE/MAP types, DRAW/SCALE/FACET/PROJECT/LABEL/THEME clauses +- Grammar supports: PLOT/TABLE/MAP types, DRAW/SCALE/FACET/PROJECT/LABEL clauses - British and American spellings: `VISUALISE` / `VISUALIZE` - **SQL portion parsing**: Basic SQL structure (SELECT, WITH, CREATE, INSERT, subqueries) - **Recursive subquery support**: Fully recursive grammar for complex SQL @@ -305,7 +304,6 @@ pub struct Plot { pub facet: Option, // FACET clause pub project: Option, // PROJECT clause pub labels: Option, // LABEL clause - pub theme: Option, // THEME clause } /// Global mapping specification from VISUALISE clause @@ -1182,7 +1180,6 @@ Where `` can be: | `FACET` | ❌ No | Small multiples | `FACET region` | | `PROJECT` | ❌ No | Coordinate system | `PROJECT TO cartesian` | | `LABEL` | ❌ No | Text labels | `LABEL title => 'My Chart', x => 'Date'` | -| `THEME` | ❌ No | Visual styling | `THEME minimal` | ### DRAW Clause (Layers) @@ -1539,23 +1536,6 @@ LABEL caption => 'Data from Q4 2024' ``` -### THEME Clause - -**Syntax**: - -```sql -THEME [SETTING ] -``` - -**Base Themes**: `minimal`, `classic`, `gray`, `bw`, `dark`, `void` - -**Example**: - -```sql -THEME minimal -THEME dark SETTING background => '#1a1a1a' -``` - --- ## Complete Example Walkthrough @@ -1576,7 +1556,6 @@ DRAW point SCALE x VIA date FACET region LABEL title => 'Sales Trends by Region', x => 'Date', y => 'Total Quantity' -THEME minimal ``` ### Execution Flow @@ -1616,8 +1595,7 @@ Plot { Scale { aesthetic: "x", scale_type: Some(ScaleType::Date) } ], facet: Some(Facet::Wrap { variables: ["region"], scales: "fixed" }), - labels: Some(Labels { labels: {"title": "...", "x": "Date", "y": "Total Quantity"} }), - theme: Some(Theme::Minimal) + labels: Some(Labels { labels: {"title": "...", "x": "Date", "y": "Total Quantity"} }) } ``` diff --git a/EXAMPLES.md b/EXAMPLES.md index de6b6f87..fe4b19bb 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -8,7 +8,7 @@ This document provides a collection of basic examples demonstrating how to use g - [Multiple Layers](#multiple-layers) - [Scales and Transformations](#scales-and-transformations) - [Projections](#projections) -- [Labels and Themes](#labels-and-themes) +- [Labels](#labels) - [Faceting](#faceting) - [Common Table Expressions (CTEs)](#common-table-expressions-ctes) - [Advanced Examples](#advanced-examples) @@ -168,7 +168,7 @@ PROJECT y, x TO polar SETTING start => 90 --- -## Labels and Themes +## Labels ### Chart with Title and Axis Labels @@ -194,24 +194,6 @@ LABEL title => 'Performance Metrics', caption => 'Data source: Analytics DB' ``` -### Themed Visualization - -```sql -SELECT category, value FROM data -VISUALISE category AS x, value AS y -DRAW bar -THEME minimal -``` - -### Theme with Custom Properties - -```sql -SELECT x, y FROM data -VISUALISE x, y -DRAW point -THEME dark SETTING background => '#1a1a1a' -``` - --- ## Faceting @@ -455,7 +437,6 @@ FACET region LABEL title => 'Sales Trends by Region', x => 'Date', y => 'Total Quantity' -THEME minimal ``` ### Time Series with Multiple Aesthetics @@ -495,7 +476,6 @@ SCALE fill TO ['red', 'orange', 'yellow', 'green', 'blue', LABEL title => 'Top 10 Products by Revenue', x => 'Product', y => 'Revenue ($)' -THEME classic ``` ### Distribution with Custom range @@ -639,11 +619,9 @@ Draw Line 6. **Multiple Layers**: Combine layers (e.g., line + point) for richer visualizations. -7. **Themes**: Apply themes last in your specification for consistent styling. - -8. **Labels**: Always provide meaningful titles and axis labels for clarity. +7. **Labels**: Always provide meaningful titles and axis labels for clarity. -9. **Range Specification**: Use SCALE for all axis limits and aesthetic domain specifications. +8. **Range Specification**: Use SCALE for all axis limits and aesthetic domain specifications. --- diff --git a/README.md b/README.md index 9fdde0d9..cc754997 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,6 @@ WHERE year = 2024 VISUALISE date AS x, revenue AS y, region AS color DRAW line LABEL title => 'Sales by Region' -THEME minimal ``` ## Project Status @@ -37,7 +36,7 @@ THEME minimal - 📋 Additional readers - 📋 Additional writers - 📋 More geom types and statistical transformations -- 📋 Enhanced theme system +- 📋 More geom types ## Architecture @@ -219,7 +218,7 @@ Key grammar elements: - `SCALE SETTING` - Configure data-to-visual mappings - `FACET` - Create small multiples (WRAP for flowing layout, BY for grid) - `PROJECT` - Coordinate transformations (cartesian, flip, polar) -- `LABEL`, `THEME` - Styling and annotation +- `LABEL` - Text labels and annotation ## Jupyter Kernel diff --git a/doc/ggsql.xml b/doc/ggsql.xml index 36769a9e..0d804b19 100644 --- a/doc/ggsql.xml +++ b/doc/ggsql.xml @@ -94,7 +94,6 @@ PROJECT FACET LABEL - THEME VISUALISE VISUALIZE @@ -127,7 +126,6 @@ line path bar - col area tile polygon @@ -148,6 +146,7 @@ + x y xmin @@ -156,22 +155,48 @@ ymax xend yend + + theta + radius + thetamin + thetamax + radiusmin + radiusmax + thetaend + radiusend + weight + color colour fill stroke opacity + size shape linetype linewidth width height + + label family fontface hjust vjust + + coef + intercept + + panel + row + column + + offset + density + count + intensity @@ -202,23 +227,6 @@ cartesian polar - flip - fixed - trans - map - quickmap - - - - - minimal - classic - gray - grey - bw - dark - light - void @@ -252,27 +260,6 @@ tag - - - background - panel_background - panel_grid - panel_grid_major - panel_grid_minor - text_size - text_family - title_size - axis_text_size - axis_line - axis_line_width - panel_border - plot_margin - panel_spacing - legend_background - legend_position - legend_direction - - count @@ -407,7 +394,6 @@ - @@ -454,7 +440,6 @@ - @@ -494,7 +479,6 @@ - @@ -540,7 +524,6 @@ - @@ -583,7 +566,6 @@ - @@ -625,7 +607,6 @@ - @@ -648,46 +629,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -702,7 +643,6 @@ - diff --git a/ggsql-vscode/examples/sample.gsql b/ggsql-vscode/examples/sample.gsql index 859f3e03..06b0dd8a 100644 --- a/ggsql-vscode/examples/sample.gsql +++ b/ggsql-vscode/examples/sample.gsql @@ -9,7 +9,6 @@ DRAW point LABEL title => 'Horsepower vs Fuel Efficiency', x => 'Horsepower', y => 'Miles per Gallon' -THEME minimal -- ============================================================================ -- Example 2: Multi-Layer Visualization with CTE @@ -34,7 +33,6 @@ LABEL title => 'Sales Trends by Region', x => 'Month', y => 'Total Quantity', caption => 'Data from 2024' -THEME classic -- ============================================================================ -- Example 3: Bar Chart with Projection @@ -51,7 +49,6 @@ PROJECT y, x TO cartesian LABEL title => 'Top 10 Product Categories', x => 'Category', y => 'Total Sales' -THEME dark -- ============================================================================ -- Example 4: Polar Projection (Pie Chart) @@ -107,7 +104,6 @@ LABEL title => 'Temperature Range (Last 30 Days)', x => 'Date', y => 'Temperature (°C)', caption => 'Source: Weather Station Alpha' -THEME minimal -- ============================================================================ -- Example 7: Complex Join with Multiple Aesthetics @@ -134,7 +130,6 @@ LABEL title => 'Sales Performance Analysis', y => 'Revenue (log scale)', color => 'Product Category', size => 'Quantity Sold' -THEME grey -- ============================================================================ -- Example 8: Area Chart with Stacking @@ -170,7 +165,6 @@ SCALE y FROM [0, 500] LABEL title => 'Price Distribution by Category', x => 'Product Category', y => 'Price ($)' -THEME bw -- ============================================================================ -- Example 10: Annotated Scatter Plot diff --git a/ggsql-vscode/syntaxes/ggsql.tmLanguage.json b/ggsql-vscode/syntaxes/ggsql.tmLanguage.json index 55a37530..8af305e6 100644 --- a/ggsql-vscode/syntaxes/ggsql.tmLanguage.json +++ b/ggsql-vscode/syntaxes/ggsql.tmLanguage.json @@ -12,7 +12,6 @@ { "include": "#facet-clause" }, { "include": "#project-clause" }, { "include": "#label-clause" }, - { "include": "#theme-clause" }, { "include": "#sql-keywords" }, { "include": "#visualise-clause" }, { "include": "#operators" } @@ -83,6 +82,10 @@ "name": "keyword.operator.cast.ggsql", "match": "::" }, + { + "name": "keyword.operator.regex.ggsql", + "match": "!~\\*|~\\*|!~|~" + }, { "name": "punctuation.separator.comma.ggsql", "match": "," @@ -217,7 +220,7 @@ "beginCaptures": { "1": { "name": "keyword.other.ggsql" } }, - "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|THEME|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", + "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", "patterns": [ { "include": "#comments" }, { "include": "#strings" }, @@ -248,8 +251,29 @@ "aesthetics": { "patterns": [ { + "comment": "Position aesthetics (cartesian and polar)", + "name": "support.type.aesthetic.ggsql", + "match": "\\b(x|y|xmin|xmax|ymin|ymax|xend|yend|theta|radius|thetamin|thetamax|radiusmin|radiusmax|thetaend|radiusend)\\b" + }, + { + "comment": "Color and appearance aesthetics", + "name": "support.type.aesthetic.ggsql", + "match": "\\b(color|colour|fill|stroke|opacity|size|shape|linetype|linewidth|width|height)\\b" + }, + { + "comment": "Text aesthetics", + "name": "support.type.aesthetic.ggsql", + "match": "\\b(label|family|fontface|hjust|vjust)\\b" + }, + { + "comment": "Specialty and computed aesthetics", + "name": "support.type.aesthetic.ggsql", + "match": "\\b(weight|coef|intercept|offset|density|count|intensity)\\b" + }, + { + "comment": "Facet aesthetics", "name": "support.type.aesthetic.ggsql", - "match": "\\b(x|y|xmin|xmax|ymin|ymax|xend|yend|weight|color|colour|fill|stroke|opacity|size|shape|linetype|linewidth|width|height|label|family|fontface|hjust|vjust|panel|row|column)\\b" + "match": "\\b(panel|row|column)\\b" } ] }, @@ -290,11 +314,12 @@ "beginCaptures": { "1": { "name": "keyword.other.ggsql" } }, - "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|THEME|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", + "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", "patterns": [ { + "comment": "Geom types from grammar.js", "name": "support.type.geom.ggsql", - "match": "\\b(point|line|path|bar|col|area|tile|polygon|ribbon|histogram|density|smooth|boxplot|violin|text|label|segment|arrow|rule|linear|errorbar)\\b" + "match": "\\b(point|line|path|bar|area|tile|polygon|ribbon|histogram|density|smooth|boxplot|violin|text|label|segment|arrow|rule|linear|errorbar)\\b" }, { "include": "#common-clause-patterns" } ] @@ -304,9 +329,10 @@ "beginCaptures": { "1": { "name": "keyword.other.ggsql" } }, - "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|THEME|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", + "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", "patterns": [ { + "comment": "Scale type identifiers from grammar.js", "name": "keyword.control.scale-modifier.ggsql", "match": "\\b(?i:CONTINUOUS|DISCRETE|BINNED|ORDINAL|IDENTITY)\\b" }, @@ -315,10 +341,12 @@ "match": "\\b(?i:TO|VIA|RENAMING)\\b" }, { + "comment": "Transform/palette names", "name": "constant.language.scale-type.ggsql", - "match": "\\b(linear|log|log10|log2|sqrt|reverse|categorical|ordinal|date|datetime|time|viridis|plasma|magma|inferno|cividis|diverging|sequential|identity|manual)\\b" + "match": "\\b(linear|log|log10|log2|sqrt|reverse|date|datetime|time|viridis|plasma|magma|inferno|cividis|diverging|sequential|identity)\\b" }, { + "comment": "Scale properties", "name": "support.type.property.ggsql", "match": "\\b(type|limits|breaks|labels|expand|direction|na_value|palette|domain|range)\\b" }, @@ -330,7 +358,7 @@ "beginCaptures": { "1": { "name": "keyword.other.ggsql" } }, - "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|THEME|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", + "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", "patterns": [ { "name": "support.type.property.ggsql", @@ -352,15 +380,17 @@ "beginCaptures": { "1": { "name": "keyword.other.ggsql" } }, - "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|THEME|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", + "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", "patterns": [ { + "comment": "Coord types (currently implemented: cartesian, polar)", "name": "support.type.project.ggsql", - "match": "\\b(cartesian|polar|flip|fixed|trans|map|quickmap)\\b" + "match": "\\b(cartesian|polar)\\b" }, { + "comment": "Project properties", "name": "support.type.property.ggsql", - "match": "\\b(xlim|ylim|ratio|theta|clip)\\b" + "match": "\\b(clip|start|ratio)\\b" }, { "include": "#common-clause-patterns" } ] @@ -370,29 +400,12 @@ "beginCaptures": { "1": { "name": "keyword.other.ggsql" } }, - "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|THEME|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", + "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", "patterns": [ { + "comment": "Label types", "name": "support.type.property.ggsql", - "match": "\\b(title|subtitle|x|y|caption|tag|color|colour|fill|size|shape|linetype)\\b" - }, - { "include": "#common-clause-patterns" } - ] - }, - "theme-clause": { - "begin": "(?i)\\b(THEME)\\b", - "beginCaptures": { - "1": { "name": "keyword.other.ggsql" } - }, - "end": "(?i)(?=\\b(DRAW|SCALE|PROJECT|FACET|LABEL|THEME|VISUALISE|VISUALIZE|SELECT|WHERE|WITH)\\b)", - "patterns": [ - { - "name": "support.type.theme.ggsql", - "match": "\\b(minimal|classic|gray|grey|bw|dark|light|void)\\b" - }, - { - "name": "support.type.property.ggsql", - "match": "\\b(background|panel_background|panel_grid|panel_grid_major|panel_grid_minor|text_size|text_family|title_size|axis_text_size|axis_line|axis_line_width|panel_border|plot_margin|panel_spacing|legend_background|legend_position|legend_direction)\\b" + "match": "\\b(title|subtitle|caption|tag)\\b" }, { "include": "#common-clause-patterns" } ] diff --git a/src/cli.rs b/src/cli.rs index 23c173c9..6540fec4 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -279,9 +279,6 @@ fn cmd_parse(query: String, format: String) { if spec.facet.is_some() { println!(" Faceting: Yes"); } - if spec.theme.is_some() { - println!(" Theme: Yes"); - } } } _ => { diff --git a/src/lib.rs b/src/lib.rs index 6e3b8074..b6521e10 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,7 +15,6 @@ WHERE year = 2024 VISUALISE date AS x, revenue AS y, region AS color DRAW line LABEL title => 'Sales by Region' -THEME minimal ``` ## Architecture diff --git a/src/parser/builder.rs b/src/parser/builder.rs index a36002d4..3033595a 100644 --- a/src/parser/builder.rs +++ b/src/parser/builder.rs @@ -21,7 +21,7 @@ use super::SourceTree; /// /// Returns (name_node, value_node) without any interpretation. /// Works for both patterns: -/// - `name => value` (SETTING, PROJECT, THEME, LABEL, RENAMING) +/// - `name => value` (SETTING, PROJECT, LABEL, RENAMING) /// - `value AS name` (MAPPING explicit_mapping) /// /// Caller is responsible for interpreting the nodes based on their context. @@ -327,9 +327,6 @@ fn process_viz_clause(node: &Node, source: &SourceTree, spec: &mut Plot) -> Resu spec.labels = Some(new_labels); } } - "theme_clause" => { - spec.theme = Some(build_theme(&child, source)?); - } _ => { // Unknown clause type continue; @@ -1120,51 +1117,6 @@ fn build_labels(node: &Node, source: &SourceTree) -> Result { Ok(Labels { labels }) } -// ============================================================================ -// Theme Building -// ============================================================================ - -/// Build a Theme from a theme_clause node -fn build_theme(node: &Node, source: &SourceTree) -> Result { - let mut style: Option = None; - let mut properties = HashMap::new(); - - let mut cursor = node.walk(); - for child in node.children(&mut cursor) { - match child.kind() { - "THEME" | "SETTING" | "=>" | "," => continue, - "theme_name" => { - style = Some(source.get_text(&child)); - } - "theme_property" => { - // Parse theme property: name => value using field-based queries - let (name_node, value_node) = extract_name_value_nodes(&child, "theme property")?; - - // Parse property name - let prop_name = source.get_text(&name_node); - - // Parse property value - let prop_value = match value_node.kind() { - "string" | "number" | "boolean" => { - parse_value_node(&value_node, source, "theme property")? - } - _ => { - return Err(GgsqlError::ParseError(format!( - "Invalid theme property value type: {}", - value_node.kind() - ))); - } - }; - - properties.insert(prop_name, prop_value); - } - _ => {} - } - } - - Ok(Theme { style, properties }) -} - // ============================================================================ // Validation & Utilities // ============================================================================ @@ -1397,7 +1349,6 @@ mod tests { ViSuAlIsE date AS x, revenue AS y DrAw line ScAlE x SeTtInG type => 'date' - ThEmE minimal "#; let result = parse_test_query(query); @@ -1406,7 +1357,6 @@ mod tests { assert_eq!(specs.len(), 1); assert_eq!(specs[0].layers.len(), 1); assert_eq!(specs[0].scales.len(), 1); - assert!(specs[0].theme.is_some()); } #[test] diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 6c80d63a..2769c3e2 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -193,7 +193,6 @@ mod tests { VISUALISE x, y DRAW point LABEL title => 'Scatter Plot' - THEME minimal VISUALIZE DRAW bar MAPPING x AS x, y AS y "#; @@ -201,15 +200,13 @@ mod tests { let specs = parse_query(query).unwrap(); assert_eq!(specs.len(), 2); - // First viz should have layers, labels, and theme + // First viz should have layers and labels assert_eq!(specs[0].layers.len(), 1); assert!(specs[0].labels.is_some()); - assert!(specs[0].theme.is_some()); - // Second viz should have layer but no labels/theme + // Second viz should have layer but no labels assert_eq!(specs[1].layers.len(), 1); assert!(specs[1].labels.is_none()); - assert!(specs[1].theme.is_none()); } #[test] @@ -241,7 +238,6 @@ mod tests { DRAW line MAPPING cost AS y SCALE x VIA date LABEL title => 'Revenue and Cost Trends' - THEME minimal VISUALIZE DRAW bar MAPPING date AS x, revenue AS y VISUALISE @@ -251,11 +247,10 @@ mod tests { let specs = parse_query(query).unwrap(); assert_eq!(specs.len(), 3); - // Plot with 2 layers, scale, labels, theme + // Plot with 2 layers, scale, labels assert_eq!(specs[0].layers.len(), 2); assert_eq!(specs[0].scales.len(), 1); assert!(specs[0].labels.is_some()); - assert!(specs[0].theme.is_some()); // Second viz with 1 layer assert_eq!(specs[1].layers.len(), 1); diff --git a/src/plot/main.rs b/src/plot/main.rs index 08eb3d53..5f1e4374 100644 --- a/src/plot/main.rs +++ b/src/plot/main.rs @@ -14,8 +14,7 @@ //! ├─ scales: Vec (0+ ScaleNode, one per SCALE clause) //! ├─ facet: Option (optional, from FACET clause) //! ├─ project: Option (optional, from PROJECT clause) -//! ├─ labels: Option (optional, merged from LABEL clauses) -//! └─ theme: Option (optional, from THEME clause) +//! └─ labels: Option (optional, merged from LABEL clauses) //! ``` use crate::naming; @@ -64,8 +63,6 @@ pub struct Plot { pub project: Option, /// Text labels (merged from all LABEL clauses) pub labels: Option, - /// Theme styling (from THEME clause) - pub theme: Option, /// Aesthetic context for coordinate-specific aesthetic names /// Computed from the coord type and facet, used for transformations #[serde(skip)] @@ -79,15 +76,6 @@ pub struct Labels { pub labels: HashMap, } -/// Theme styling (from THEME clause) -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct Theme { - /// Base theme style - pub style: Option, - /// Theme property overrides - pub properties: HashMap, -} - // Manual PartialEq implementation (aesthetic_context is derived, not compared) impl PartialEq for Plot { fn eq(&self, other: &Self) -> bool { @@ -98,7 +86,6 @@ impl PartialEq for Plot { && self.facet == other.facet && self.project == other.project && self.labels == other.labels - && self.theme == other.theme } } @@ -113,7 +100,6 @@ impl Plot { facet: None, project: None, labels: None, - theme: None, aesthetic_context: None, } } @@ -128,7 +114,6 @@ impl Plot { facet: None, project: None, labels: None, - theme: None, aesthetic_context: None, } } diff --git a/tree-sitter-ggsql/grammar.js b/tree-sitter-ggsql/grammar.js index edc278f6..ea84a6a1 100644 --- a/tree-sitter-ggsql/grammar.js +++ b/tree-sitter-ggsql/grammar.js @@ -453,7 +453,6 @@ module.exports = grammar({ $.facet_clause, $.project_clause, $.label_clause, - $.theme_clause, ), // DRAW clause - syntax: DRAW geom [MAPPING ...] [REMAPPING ...] [SETTING ...] [FILTER ...] [PARTITION BY ...] [ORDER BY ...] @@ -665,7 +664,7 @@ module.exports = grammar({ // Facet aesthetics 'panel', 'row', 'column', // Computed variables - 'offset', + 'offset', 'density', 'count', 'intensity', // Allow any identifier for custom PROJECT aesthetics (e.g., PROJECT a, b TO polar) $.identifier ), @@ -820,34 +819,6 @@ module.exports = grammar({ label_type: $ => $.identifier, - // THEME clause - THEME [name] [SETTING prop => value, ...] - theme_clause: $ => choice( - // Just theme name - seq(caseInsensitive('THEME'), $.theme_name), - // Theme name with properties - seq( - caseInsensitive('THEME'), $.theme_name, caseInsensitive('SETTING'), - $.theme_property, - repeat(seq(',', $.theme_property)) - ), - // Just properties (custom theme) - seq( - caseInsensitive('THEME'), caseInsensitive('SETTING'), - $.theme_property, - repeat(seq(',', $.theme_property)) - ) - ), - - theme_name: $ => $.identifier, - - theme_property: $ => seq( - field('name', $.theme_property_name), - '=>', - field('value', choice($.string, $.number, $.boolean)) - ), - - theme_property_name: $ => $.identifier, - // Basic tokens bare_identifier: $ => token(/[a-zA-Z_][a-zA-Z0-9_]*/), quoted_identifier: $ => token(choice( diff --git a/tree-sitter-ggsql/queries/highlights.scm b/tree-sitter-ggsql/queries/highlights.scm index 576b19f1..bf2a8e76 100644 --- a/tree-sitter-ggsql/queries/highlights.scm +++ b/tree-sitter-ggsql/queries/highlights.scm @@ -31,34 +31,57 @@ ; Aesthetic names [ + ; Position aesthetics (cartesian) "x" "y" - "weight" "xmin" "xmax" "ymin" "ymax" "xend" "yend" + ; Position aesthetics (polar) + "theta" + "radius" + "thetamin" + "thetamax" + "radiusmin" + "radiusmax" + "thetaend" + "radiusend" + ; Aggregation aesthetic + "weight" + ; Color aesthetics "color" "colour" "fill" "stroke" "opacity" + ; Size and shape "size" "shape" "linetype" "linewidth" "width" "height" + ; Text aesthetics "label" "family" "fontface" "hjust" "vjust" + ; Specialty aesthetics + "coef" + "intercept" + ; Facet aesthetics "panel" "row" "column" + ; Computed variables + "offset" + "density" + "count" + "intensity" ] @attribute ; String literals @@ -81,7 +104,6 @@ ; Property names (project_property_name) @property -(theme_property_name) @property (label_type) @property ; Operators diff --git a/tree-sitter-ggsql/test/corpus/basic.txt b/tree-sitter-ggsql/test/corpus/basic.txt index 3a9f080b..b1baacdd 100644 --- a/tree-sitter-ggsql/test/corpus/basic.txt +++ b/tree-sitter-ggsql/test/corpus/basic.txt @@ -438,14 +438,13 @@ DRAW point (geom_type))))) ================================================================================ -Plot with scales and theme +Plot with scales ================================================================================ VISUALISE x, y, group AS color DRAW point SCALE CONTINUOUS x FROM [0, 100] SCALE color TO viridis -THEME minimal -------------------------------------------------------------------------------- @@ -486,11 +485,6 @@ THEME minimal (scale_clause (aesthetic_name) (scale_to_clause - (identifier - (bare_identifier))))) - (viz_clause - (theme_clause - (theme_name (identifier (bare_identifier)))))))