diff --git a/.azure/pipelines/build-whiteboard.yaml b/.azure/pipelines/build-whiteboard.yaml index 36d22d2..068b28b 100644 --- a/.azure/pipelines/build-whiteboard.yaml +++ b/.azure/pipelines/build-whiteboard.yaml @@ -237,6 +237,7 @@ stages: "$(Build.BinariesDirectory)\SQLBI.Whiteboard.Core.dll" "$(Build.BinariesDirectory)\SQLBI.Whiteboard.Dax.dll" "$(Build.BinariesDirectory)\SQLBI.Whiteboard.Export.dll" + "$(Build.BinariesDirectory)\SQLBI.Whiteboard.Kql.dll" "$(Build.BinariesDirectory)\SQLBI.Whiteboard.SqlServer.dll" "$(Build.BinariesDirectory)\SQLBI.Whiteboard.ThumbnailHandler.dll" failOnStderr: true diff --git a/CHANGELOG.md b/CHANGELOG.md index aae73c6..da4f873 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,17 @@ broke. The heading is parsed by `scripts/release-notes.ps1`, so keep its shape; under it is ordinary Markdown, and the renderer handles paragraphs, lists, links, `code` and **bold**. +## 1.3.1 - 5 September 2026 + +### KQL joins DAX and SQL in text containers +A text container can now be Kusto Query Language. Paste a query or drop a `.kql` file, +choose **KQL** from the title-bar chip, and it is highlighted like the rest: operators, +functions, columns, string literals, and the comments between them. **F6** formats it, +and a query that does not parse is left exactly as it was rather than half rewritten. +The spacing you chose around a join hint, as in `kind=inner`, survives formatting, because +that is how the queries people bring to a session are usually written. Highlighting and +formatting both read Kusto through Microsoft's own parser, and both run locally. + ## 1.3.0 - 3 September 2026 ### Export a board to PowerPoint diff --git a/Directory.Build.props b/Directory.Build.props index c33bae5..c6b72f4 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,7 +5,7 @@ scripts/build-installer.ps1 both read it from here, so releasing is a reviewed change to this line rather than an edit in a pipeline variable group. --> - 1.3.0 + 1.3.1 latest enable enable diff --git a/README.md b/README.md index 1e515ee..abfc511 100644 --- a/README.md +++ b/README.md @@ -199,7 +199,7 @@ Use **Copy settings** after finding a useful combination so the exact values can | F2 | Edit the selected text container, or rename the selected frame | | View > Frame | Add a frame the size of the screen: a slide drawn on the board, selected by its edge or its tab, which Export takes as it is | | Language chip | Choose Plain text, DAX, or SQL Server on a selected text container | -| F6 | Format DAX or SQL on the selected text container. In F2, formats in place | +| F6 | Format DAX, SQL, or KQL on the selected text container. In F2, formats in place | | Ctrl+Enter | Commit the F2 edit, including an F6 format done in that session, and return to display mode | | Escape | Cancel the active text edit, close the command strip, or leave full screen or canvas only | | Ctrl+S / Ctrl+O | Save / open a board | @@ -221,9 +221,9 @@ With the mouse, selection is automatic: click a container to move it, or drag th Imported images, LiveViews, and text objects act as containers. A completed stroke is linked when it touches exactly one container, including crossing its edge; a stroke touching multiple containers remains independent. Moving or resizing a container transforms its linked strokes with it. **View → Bring to front** and **View → Send to back** reorder the selected container and those linked strokes. Deleting a container also deletes all of its linked strokes. Undo/redo treats each complete container operation as one action. -Paste plain text to create a selected text container in display mode. **Help → Preferences** has Snippet format order: paste tries those languages from top to bottom and uses the first that accepts the text. Plain text always accepts, so leaving it first keeps every paste as plain text. Recognized extensions (`.dax`, `.sql`, `.txt`) keep their language; other dropped text files use the same order. Choose **Plain text**, **DAX**, or **SQL Server** from the title-bar chip afterward. Press **F6** to format DAX or SQL on the selected container without entering edit. Press **F2** to edit the body; the same list is in the title bar while editing. In F2, **F6** formats in place; **Ctrl+Enter** commits that edit (including the format) and returns to display. **Escape** restores the previous text, language, and dimensions. Text reflows while its edit-mode resize grip changes the width, and the height grows automatically when necessary. Double-click still centers and fits the container. Syntax highlighting applies in both edit and display modes. A language-aware title identifies a defined DAX or SQL object when possible. SQL Server mode targets SQL Server 2025 T-SQL, preserves `GO` batch separators, and leaves invalid scripts unchanged. In display mode, resizing preserves the aspect ratio and scales the complete text visual without reflowing it. +Paste plain text to create a selected text container in display mode. **Help → Preferences** has Snippet format order: paste tries those languages from top to bottom and uses the first that accepts the text. Plain text always accepts, so leaving it first keeps every paste as plain text. Recognized extensions (`.dax`, `.sql`, `.kql`, `.txt`) keep their language; other dropped text files use the same order. Choose **Plain text**, **DAX**, **SQL Server**, or **KQL** from the title-bar chip afterward. Press **F6** to format DAX, SQL, or KQL on the selected container without entering edit. Press **F2** to edit the body; the same list is in the title bar while editing. In F2, **F6** formats in place; **Ctrl+Enter** commits that edit (including the format) and returns to display. **Escape** restores the previous text, language, and dimensions. Text reflows while its edit-mode resize grip changes the width, and the height grows automatically when necessary. Double-click still centers and fits the container. Syntax highlighting applies in both edit and display modes. A language-aware title identifies a defined DAX, SQL, or KQL object when possible. SQL Server mode targets SQL Server 2025 T-SQL, preserves `GO` batch separators, and leaves invalid scripts unchanged. KQL mode reads Kusto through Microsoft's own parser and likewise leaves an invalid query unchanged. In display mode, resizing preserves the aspect ratio and scales the complete text visual without reflowing it. -Image files, and `.txt`, `.dax`, and `.sql` files, can be dropped directly from File Explorer. Their initial center is the board position at which they were dropped. DAX and SQL files open in the matching language mode. Other dropped text files use Snippet format order. +Image files, and `.txt`, `.dax`, `.sql`, and `.kql` files, can be dropped directly from File Explorer. Their initial center is the board position at which they were dropped. DAX, SQL, and KQL files open in the matching language mode. Other dropped text files use Snippet format order. ### `.wimport` recipes @@ -254,6 +254,7 @@ is installed. The source is `vscode/sqlbi-whiteboard`. - `SQLBI.Whiteboard.Core` contains world geometry, camera math, retained board objects, commands, hit testing, and archive persistence. It has no UI-framework dependency. - `SQLBI.Whiteboard.Dax` contains the framework-neutral DAX lexer, parser, classifier, and deterministic formatter adapted from Prompt Assistant. - `SQLBI.Whiteboard.SqlServer` contains the framework-neutral SQL Server 2025 adapter over Microsoft's ScriptDOM parser and script generator. +- `SQLBI.Whiteboard.Kql` contains the framework-neutral Kusto Query Language adapter over Microsoft's own Kusto parser, classifier, and formatter. - `vscode/sqlbi-whiteboard` is a VS Code custom editor that shows `preview.png` from a `.wboard` ZIP. It is not part of the desktop installer. - `SQLBI.Whiteboard` is the WPF shell. `TouchInkCanvas` supplies system-managed wet ink for the finger, while `BoardSurface` renders completed ink, images, text, and selection on a white canvas in camera space, plus the pen's own wet stroke. A transient AvalonEdit surface is overlaid only while a text container is being edited; language services translate parser classifications into WPF text styles. - `SQLBI.Whiteboard/LiveView` owns Windows Graphics Capture and the Direct3D-to-WPF bridge. Capture retains one GPU frame per active LiveView; CPU bitmap conversion occurs only when copying or saving a snapshot. diff --git a/Whiteboard.sln b/Whiteboard.sln index 0f5252c..e2e7b80 100644 --- a/Whiteboard.sln +++ b/Whiteboard.sln @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLBI.Whiteboard.Dax", "src EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLBI.Whiteboard.SqlServer", "src\SQLBI.Whiteboard.SqlServer\SQLBI.Whiteboard.SqlServer.csproj", "{B2B15228-5085-4652-B7C7-F82F3781A486}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLBI.Whiteboard.Kql", "src\SQLBI.Whiteboard.Kql\SQLBI.Whiteboard.Kql.csproj", "{2BDED826-A102-4601-910E-15E3243ADCA2}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLBI.Whiteboard.Core.SmokeTests", "tests\SQLBI.Whiteboard.Core.SmokeTests\SQLBI.Whiteboard.Core.SmokeTests.csproj", "{53EF7855-88C7-4D6A-A194-4AF36CF10615}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLBI.Whiteboard", "src\SQLBI.Whiteboard\SQLBI.Whiteboard.csproj", "{C9300257-0FA9-47E5-B719-F8C957FE5427}" @@ -67,6 +69,18 @@ Global {B2B15228-5085-4652-B7C7-F82F3781A486}.Release|Any CPU.Build.0 = Release|Any CPU {B2B15228-5085-4652-B7C7-F82F3781A486}.Release|x86.ActiveCfg = Release|Any CPU {B2B15228-5085-4652-B7C7-F82F3781A486}.Release|x86.Build.0 = Release|Any CPU + {2BDED826-A102-4601-910E-15E3243ADCA2}.Debug|x64.ActiveCfg = Debug|Any CPU + {2BDED826-A102-4601-910E-15E3243ADCA2}.Debug|x64.Build.0 = Debug|Any CPU + {2BDED826-A102-4601-910E-15E3243ADCA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BDED826-A102-4601-910E-15E3243ADCA2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BDED826-A102-4601-910E-15E3243ADCA2}.Debug|x86.ActiveCfg = Debug|Any CPU + {2BDED826-A102-4601-910E-15E3243ADCA2}.Debug|x86.Build.0 = Debug|Any CPU + {2BDED826-A102-4601-910E-15E3243ADCA2}.Release|x64.ActiveCfg = Release|Any CPU + {2BDED826-A102-4601-910E-15E3243ADCA2}.Release|x64.Build.0 = Release|Any CPU + {2BDED826-A102-4601-910E-15E3243ADCA2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BDED826-A102-4601-910E-15E3243ADCA2}.Release|Any CPU.Build.0 = Release|Any CPU + {2BDED826-A102-4601-910E-15E3243ADCA2}.Release|x86.ActiveCfg = Release|Any CPU + {2BDED826-A102-4601-910E-15E3243ADCA2}.Release|x86.Build.0 = Release|Any CPU {53EF7855-88C7-4D6A-A194-4AF36CF10615}.Debug|x64.ActiveCfg = Debug|Any CPU {53EF7855-88C7-4D6A-A194-4AF36CF10615}.Debug|x64.Build.0 = Debug|Any CPU {53EF7855-88C7-4D6A-A194-4AF36CF10615}.Debug|Any CPU.ActiveCfg = Debug|Any CPU diff --git a/docs/wimport.md b/docs/wimport.md index c53fe35..8dedd90 100644 --- a/docs/wimport.md +++ b/docs/wimport.md @@ -73,6 +73,7 @@ container. The whole body, fence included, becomes plain text. | --- | --- | --- | | DAX | `dax` | `.dax` | | SQL Server | `sql`, `tsql` | `.sql` | +| KQL | `kql`, `kusto` | `.kql` | Further languages (Python, C#, TypeScript, …) will be extra rows in this table. Do not invent fence tags Whiteboard does not list here: they import as plain text. @@ -134,8 +135,8 @@ A complete sample is `docs/samples/contoso-workshop.wimport`. - File name ends in `.wimport`. - Every container is a `##` heading with exactly one payload. - Images and linked code exist next to the file, using relative paths. -- Image files are png/jpeg/bmp/gif/svg. Code files you link are `.dax` or `.sql`, or the code is - embedded in a `dax` / `sql` / `tsql` fence. +- Image files are png/jpeg/bmp/gif/svg. Code files you link are `.dax`, `.sql`, or `.kql`, or the + code is embedded in a `dax` / `sql` / `tsql` / `kql` fence. - Row breaks are a thematic break on its own line, not a fake heading. - You did not use `http://`, YAML, or explicit positions. - Opening the file in a Markdown preview still reads as a normal document. diff --git a/site/compare.html b/site/compare.html index 34fce9b..4e1d636 100644 --- a/site/compare.html +++ b/site/compare.html @@ -45,7 +45,7 @@

What this is and is not

What this is

-

A native Windows application for a live explanation: pressure-aware ink, an unbounded canvas, SQL and DAX containers with local formatting, LiveView capture of a window or a display, and portable .wboard files. No account. The guide is how a session runs.

+

A native Windows application for a live explanation: pressure-aware ink, an unbounded canvas, DAX, SQL, and KQL containers with local formatting, LiveView capture of a window or a display, and portable .wboard files. No account. The guide is how a session runs.

What this is not