From 0cb02865a696bce0ad8b24899097abec81da2c69 Mon Sep 17 00:00:00 2001 From: David de Hilster Date: Sun, 26 Jul 2026 11:47:17 -0400 Subject: [PATCH] docs(help): parse-tree help page and graphic announcement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds vscode/parsetrees.md — a full guide to parse trees in VS Code: where the .tree files land, how to read a tree line, the text-file right-click actions (Highlight text on any node, Display Rule Fired, Generate @PATH, Open Pass File, fold/unfold), and the parse-tree graphic (three ways to open it, zoom/pan/shift-scroll controls, drill-down default, per-level label staggering, and the right-click menu incl. Reveal Text on any node). Adds an announcement (vscode/announcements/2026-07-26-parse-tree-graphic.md) introducing the graphic, with a screenshot, linking to the new page. Links the page from the Getting started list on vscode/home.md. Co-Authored-By: Claude Opus 5 (1M context) --- .../2026-07-26-parse-tree-graphic.md | 88 +++++++++++++ .../vscode/announcements/ParseTreeGraphic.png | Bin 0 -> 18702 bytes Help/markdown/vscode/home.md | 1 + Help/markdown/vscode/parsetrees.md | 122 ++++++++++++++++++ 4 files changed, 211 insertions(+) create mode 100644 Help/markdown/vscode/announcements/2026-07-26-parse-tree-graphic.md create mode 100644 Help/markdown/vscode/announcements/ParseTreeGraphic.png create mode 100644 Help/markdown/vscode/parsetrees.md diff --git a/Help/markdown/vscode/announcements/2026-07-26-parse-tree-graphic.md b/Help/markdown/vscode/announcements/2026-07-26-parse-tree-graphic.md new file mode 100644 index 0000000..3ced5a4 --- /dev/null +++ b/Help/markdown/vscode/announcements/2026-07-26-parse-tree-graphic.md @@ -0,0 +1,88 @@ +# 📢 Announcement — See Your Parse Tree + +![NLP++ parse-tree graphic](ParseTreeGraphic.png) + +**Every `.tree` file your analyzer writes can now be drawn as a classic linguistic tree +diagram** — right inside VS Code, beside the text file it came from. + +NLP++ has always given you the parse tree as text: one indented line per node, with its +span and type. That's precise, and it's still there. But a tree is a *picture*, and now you +can see it as one — phrases branching over their words, exactly the way a linguist would +draw it on a whiteboard. + +--- + +## Opening the graphic + +From any `.tree` file: + +- 🌲 **The tree button** in the editor title bar — draws the whole tree. +- 🖱️ **Right-click → Graph Entire Tree** — the same thing, from the context menu. +- 🖱️ **Right-click → Graph Selected Portion of Tree** — draws just the **selected lines**, + or, with nothing selected, the **subtree under your cursor**. Perfect for looking at one + noun phrase in a 400-node tree. + +The graphic is strictly on-demand: opening a `.tree` file never draws anything on its own, +so tree files still open instantly. And it re-uses a single panel, so asking for another +tree replaces the one you're looking at instead of piling up tabs. + +--- + +## Getting around the tree + +The whole diagram is live. The hint bar along the bottom sums it up, but here it is in full: + +| Do this | Get this | +| --- | --- | +| **Scroll** | Zoom in and out | +| **Shift + scroll** | Squeeze or spread the horizontal spacing between nodes | +| **Drag** | Pan around the canvas | +| **Click a phrase node** | Open **one level** — just that node's children | +| **Click a word (leaf)** | **Reveal it in the text** — selects that word in the input file | +| **Right-click** | Menu (below) | + +Trees open with the root expanded and everything else closed, so you **drill down one node +at a time** rather than being hit with hundreds of tokens at once. Small trees (roughly 30 +nodes or fewer) open fully, and every tree is fit to the window when it opens. + +Labels don't collide, either: at **every level** of the tree, labels that would overlap are +staggered into the minimum number of extra rows needed — and they drop back onto a single +line as soon as they fit, or as soon as you spread the tree out with Shift + scroll. + +--- + +## The right-click menu + +Right-click anywhere in the graphic: + +- **Reveal Text** — on **any** node, word or phrase. Selects that node's whole span in the + analyzed text file. Right-click an `_np` and the entire noun phrase lights up. +- **Expand all below** / **Collapse all below** — open or close an entire subtree at once + (shown on nodes that have children). +- **Center all** — fit the whole tree back into the window. +- **Expand all** / **Collapse all** — open or close the entire tree. + +--- + +## The text `.tree` file still does everything it did + +The graphic is an *alternative* view, not a replacement. In the `.tree` file itself, put +your cursor on **any node line** and right-click: + +- **Highlight text** — selects that node's text in the input file and opens it beside the + tree. Works on any node, at any depth — click a phrase node and you highlight the whole + phrase; click a word and you highlight the word. +- **Display Rule Fired** — opens the pass that built the node and jumps straight to the rule + that fired (for nodes that came from a dictionary, it searches the dictionaries instead). +- **Generate @PATH** — writes the context `@PATH` for that node, ready to paste into a rule. +- **Open Pass File** — jumps to the pass that produced this tree. +- **Fold / Unfold** (all, or recursively) — collapse the text tree the same way you collapse + the graphic. + +Between the two views you get both halves of the picture: the graphic for *shape* — how the +parse actually came together — and the text file for *detail*, the spans, the rules, and the +paths you need when you sit down to write the next rule. + +**Read the full guide:** [Parse Trees](../parsetrees.md) + +_See more on the [Help home](../home.md)._ diff --git a/Help/markdown/vscode/announcements/ParseTreeGraphic.png b/Help/markdown/vscode/announcements/ParseTreeGraphic.png new file mode 100644 index 0000000000000000000000000000000000000000..fbac579a59dac23bc3668a2dba507ffbd1980f97 GIT binary patch literal 18702 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