Jumbee.Console.Documents 0.1.10

dotnet add package Jumbee.Console.Documents --version 0.1.10
                    
NuGet\Install-Package Jumbee.Console.Documents -Version 0.1.10
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Jumbee.Console.Documents" Version="0.1.10" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Jumbee.Console.Documents" Version="0.1.10" />
                    
Directory.Packages.props
<PackageReference Include="Jumbee.Console.Documents" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Jumbee.Console.Documents --version 0.1.10
                    
#r "nuget: Jumbee.Console.Documents, 0.1.10"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Jumbee.Console.Documents@0.1.10
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Jumbee.Console.Documents&version=0.1.10
                    
Install as a Cake Addin
#tool nuget:?package=Jumbee.Console.Documents&version=0.1.10
                    
Install as a Cake Tool

Jumbee.Console Documents

alternate text is missing from this package README image

About

This is an add-on library for Jumbee.Console that provides TUI viewers and editors for different document formats.

Formats supported

  • Markdown
  • AsciiDoc
  • Mermaid
  • Mermaid embedded in Markdown

Getting Started

See GETTING-STARTED.md on the project site, and the project documentation.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.10 0 8/2/2026
0.1.9 37 8/1/2026
0.1.8 41 7/31/2026
0.1.7 80 7/30/2026
0.1.6 88 7/29/2026
0.1.5 114 7/23/2026
0.1.4 108 7/21/2026
0.1.3 92 7/20/2026
0.1.2 91 7/20/2026
0.1.1 98 7/19/2026

CHANGELOG - Jumbee.Console
==========================

0.1.10
------

CHANGED

 * BREAKING: control events are now EventHandler / EventHandler<T> throughout. Eleven public events were
   declared as plain Action / Action<T>, so the same concept had two different shapes depending on which
   control you were holding - TabPanel.SelectionChanged was an Action<int> while ListBox.SelectionChanged
   and DataTable.SelectionChanged were EventHandler<int>. Writing a handler in the conventional
   (sender, args) form was wrong about half the time, and the compiler's only complaint was an arity
   mismatch.

       Event                                     Was                  Now
       ------------------------------------------------------------------------------
       ControlFrame.Scrolled                     Action               EventHandler
       InteractiveSourceEditor.TextChanged       Action<string>       EventHandler<string>
       MultiTabCodeEditor.ActiveDocumentChanged  Action<CodeEditor?>  EventHandler<CodeEditor?>
       MultiTabCodeEditor.DocumentClosed         Action<CodeEditor>   EventHandler<CodeEditor>
       MultiTabCodeEditor.DocumentOpened         Action<CodeEditor>   EventHandler<CodeEditor>
       SplitPanel.SplitChanged                   Action<int>          EventHandler<int>
       TabPanel.NewTabRequested                  Action               EventHandler
       TabPanel.SelectionChanged                 Action<int>          EventHandler<int>
       TabPanel.TabRemoved                       Action<TabItem>      EventHandler<TabItem>
       TerminalEmulator.Exited                   Action               EventHandler
       TerminalEmulator.TitleChanged             Action<string>       EventHandler<string>

   To migrate, add the sender parameter:

       tabs.SelectionChanged += i => ...        becomes    tabs.SelectionChanged += (_, i) => ...
       term.Exited += Quit;                     becomes    term.Exited += (_, _) => Quit();

   Deliberately unchanged: Control.OnHelp and the On* focus/initialization hooks (framework plumbing with
   their own delegate types), and IPty.Exited on the pseudo-console transport, which is not a control event.

FIXED

 * Setting DataTable.SelectedIndex before the control has been laid out no longer measures a degenerate
   table. Selecting a row at construction time - the normal way to restore a saved cursor - ran the scroll
   calculation while ActualWidth was still 0, which clamped the measurement probe to a single cell wide. A
   multi-column table one cell wide gives every column a minimum width of 0, so the layout was asked to
   divide space between ratios summing to zero (Debug.Assert: "Sum or ratios must be > 0"). Debug builds
   tripped the assertion; Release builds compiled it out and carried on with the meaningless measurement,
   which is why it stayed invisible. The probe is now skipped until there is a layout, and a selection made
   before then has its scroll resolved on the first render.

DOCS

 * New control-guide section at docs/controls/. A hub page maps a task to the control that does it
   ("I want to... / Use") across the whole library, then one guide per category: Control Model, Text and
   Input, Lists and Data, Charts, Navigation, Documents, Terminal and Spectre Interop. Two cross-cutting
   guides sit alongside them: Writing Applications, on the retained-mode model and what the framework owns
   versus what you own, and "What happens when...", a behavioural FAQ for when the app runs but does
   something unexpected. The existing Layouts, Selection Controls, Display Widgets, Links, Live Data and
   Composite Controls guides were folded into the same structure, with Select, Button, GlassPanel and the
   status widgets documented for the first time.

 * MermaidViewer no longer claims class, ER and sequence diagrams are unsupported - all three have been
   rendered for some time, along with flowcharts and state diagrams. The type's own summary said otherwise,
   so the feature was invisible to anyone reading the API reference.

 * The first-app example in the repository README was missing a semicolon and did not compile. The copy in
   the NuGet package README was correct; the two had drifted.

 * Spectre Interop no longer shows an example that fails when its own advice is followed. The page tells you
   to import Spectre.Console, then used a bare Style - which is ambiguous with Jumbee.Console.Style once both
   namespaces are in scope. Now qualified, with a note that Style and Color both need qualifying in interop
   files.

 * llms.txt covers the new guides, and the NuGet package README now links both it and the control guides.

 * Doc snippets are compiled by the test suite. A new internal test project
   (tests/Jumbee.Console.DocSnippets, not shipped) extracts every C# code fence from the control guides, the
   two READMEs and GETTING-STARTED - 102 of them - and compiles them against the real assemblies, ignoring
   only the placeholder identifiers a reader is expected to supply. Every example above was verified this
   way; the missing semicolon and the ambiguous Style were both found by it.


0.1.9
-----

ADDED

 * Headless mouse simulation in Jumbee.Console.Snapshot - ConsoleSnapshot.Click (with clicks: for
   double-clicks and button: for right-clicks), MouseMove, Wheel, ResetMouse, plus RenderAfterClick /
   ToTextAfterClick. Snapshot tests could send keys but not pointer input, so click-to-select, double-click
   activation, hover and wheel scrolling - real behaviour on DataTable, ListBox, Tree, Button and others -
   could not be tested without a terminal. The hit-test and the enter/leave/press/release dispatch order
   mirror the live ConsoleManager path, so a simulated click reaches the same handler a real one does.

 * Style(Color foreground, Color background) - a direct two-colour constructor. Previously a style with a
   background needed the markup-string form (new Style("black on white")) or composition
   ((Style)fg | Style.Bg(bg)); the get-only ForegroundColor / BackgroundColor properties made the
   two-argument form look like it should already exist.

 * ConsoleSnapshot.SavePngAfter gained routeGlobal and ILayout overloads, matching RenderAfter /
   ToTextAfter. A PNG capture driven by a global hotkey, or of an Overlay (where a modal's frame actually
   lives), no longer needs a two-step RenderAfter -> SavePng(buffer) workaround.

FIXED

 * PNG snapshots draw Braille instead of missing-glyph boxes. ToImage resolved one font for the whole image
   and only consulted FallbackFontFamilies when the named font wasn't installed - so the default (Consolas,
   which has no Braille glyphs) always won and every Braille cell rasterised as a box. Braille charts looked
   correct in the terminal and in text snapshots, so it failed silently in saved images only. The fallbacks
   are now given to the text renderer, which substitutes per glyph.

 * DataTable drops columns instead of wrapping when it's too narrow, controlled by the new
   DropNarrowColumns property (on by default). Squeezed below the width its content needed, the table used
   to break headers mid-word and split values across lines (11.4 rendering as 11 / .4); it now drops whole
   columns from the right, keeping the leftmost identifier column, the way terminal process monitors do.
   Widths are measured from the rows currently on screen. Set the property to false for the old behaviour.

 * DataTable's selection bar and click hit-testing land on the right row when a header wraps. Chrome height
   was estimated from a probe table filled with placeholder cells, but column widths are allocated from cell
   content, so the probe's header wrapped to a different number of lines than the real table's. The
   selection bar drifted up one row per extra header line as the control narrowed - highlighting the wrong
   row, and mapping clicks to it - while SelectedIndex stayed correct, so the app looked right in state and
   wrong on screen. Chrome is now measured from the table actually being drawn. (Now correct at every width,
   since the column-dropping change above removes the wrapping that used to break it.)

 * Rapid clicks are no longer swallowed. Control routes the second click of a rapid pair to OnDoubleClick,
   so any control that overrode only OnClick silently consumed it - double-clicking a Button activated it
   once, not twice. Fixed on Button, Link, Select, Menu, MenuBar, Autocomplete, TabHeader, the tab bar's "+"
   button, and Dialog's buttons. (ToggleButton, ToggleList, ListBox and Tree already handled both.)

 * DataTable now raises RowActivated on double-click. The event's own documentation said it fires on
   "Enter / double-click", but only the Enter path was implemented - the control overrode OnClick and never
   OnDoubleClick, so a double-click only ever re-selected the row. Found by the new mouse simulation above,
   on its first use.

CHANGED

 * UI.MouseButton's setter is now internal (was private) so Jumbee.Console.Snapshot can latch it when
   simulating a right-click. The property itself is unchanged for consumers.


0.1.8
-----

FIXED

 * Several controls had the documentation for overridden members replaced by the base class's text, because
   an override with <inheritdoc/> (or no doc comment) inherits the base summary. On HandlesInput /
   WantsMouse this stated the opposite of the truth - the pages read "the default (false) ignores it" for
   controls that override it to true, so DataTable, ListBox, Tree, Menu, MenuBar, Button, Link and
   MarkdownViewer all appeared to need an opt-in that was already on.

DOCS

 * Testing a modal dialog - new worked example in GETTING-STARTED's "Testing without a terminal", covering
   the Overlay a modal attaches to. Snapshotting the root layout renders a frame with no dialog in it; you
   have to snapshot the overlay.

 * Plot.AddBars / AddLiveBars now point at Canvas + Drawing.FilledLine for a sub-cell filled/area chart, and
   state that bars take no PlotBrush and so can't be drawn in braille.

 * DockPanel.DockedControl and Grid now name Boundary as the way to give a child a fixed extent. The "0
   means fill the parent" trap was documented; the fix for a child with no Width/Height of its own (a
   ControlFrame, a nested layout) was not.


0.1.7
-----

ADDED

 * ProgressBar control - a composable, themeable single-row task-progress display: a settable description, a
   smooth sub-cell fill bar, and optional percentage, elapsed/remaining-time and spinner columns, plus an
   indeterminate pulse for work whose total isn't known.

FIXED

 * Framed controls now render their frame inside a VerticalStackPanel / HorizontalStackPanel. A margin on a
   stacked control now reserves space as expected.

DOCS

 * Added /llms.txt generation (per https://llmstxt.org/) to the API-docs script - a curated, link-listed
   index of the docs and public API for LLM tooling.


0.1.6
-----

ADDED

 * PlotPalette (Jumbee.Console.Styles) and IStyleTheme.PlotSeries - plot colours are now themeable: the
   axis, grid, tick and surface chrome plus the series palette come from the active theme instead of being
   passed per call, so a runtime theme switch re-colours existing plots.

 * Plot.DamageTracking - opt-in partial redraw. The plot reports only the sub-rectangles a draw actually
   changed and the compositor skips the rest; roughly 5x off the composite for a sparse figure. Off by
   default - see the remarks on the property for when it pays and when it costs.

 * ConsolePlot: axis ticks can be set to 0, which removes that axis's grid lines and labels.

CHANGED

 * TextLabel takes its colours from IStyleTheme.LabelText (both foreground and background) until one is set
   explicitly. Colours passed to the constructor still win and now register as theme overrides, so a later
   theme switch re-colours only the labels that never asked for a colour. A theme supplying a background
   lets labels sit on a coloured strip without every caller passing one.

FIXED

 * CompositeControl swallowed clicks on display composites. A composite that opted into the mouse
   (WantsMouse) but whose children were not themselves focusable or mouse-listening produced cells with no
   listener, so a click anywhere over such a child never reached the composite. Those cells now carry the
   composite's own listener, restoring click-to-focus for panes like a plot; a child with its own listener
   is unaffected.

 * ConsolePlot: custom tick values are honoured, and Clear no longer rewrites the whole buffer.

DOCS

 * Documented the cost model of damage tracking, not just its benefit: it narrows what the compositor scans
   and never what the terminal receives, and because the scan it replaces is a linear buffer walk while
   damage bookkeeping is scattered, break-even needs the changing region to be a small fraction of the
   control - see Control.TracksDamage and "When damage tracking pays" in docs/internal/Rendering Model.md.

EXAMPLES

 * New AudioScope demo - a real-time oscilloscope, spectroscope and vectorscope over one shared audio
   source. Fully managed and cross-platform: MP3/WAV decode through NLayer, capture through WASAPI (Windows)
   or ALSA (Linux), with device selection, loopback, mono, --overlap, --tick and four colour schemes.

 * Both Docker images gained an audio-scope target with a bundled sample track, and now ship the ALSA
   runtime so "audio-scope live" works on a Linux host given --device /dev/snd.


0.1.5
-----

ADDED

 * Color.FromHexString - parses a hex colour string (e.g. "#FF8800") into a Jumbee.Console.Color.

 * 24-bit (true-color) support in ConsolePlot - plot chrome and series take full RGB Jumbee.Console.Color
   values.

 * Plot screen-anchored axis titles - the Y title pins to the top-left and the X title to the bottom-right,
   so they stay put as the axes rescale.

CHANGED

 * Performance optimizations for the Plot control.

 * UI.Start: the frame-rate parameter is now fps (frames per second) instead of paintInterval.

 * Overlay and TextLabel are now sealed.

FIXED

 * Fixed a latent crash when drawing scatter points outside a fixed axis range - such a point mapped past
   the plot buffer and threw IndexOutOfRangeException; it is now correctly clipped.

 * UI/threading robustness: self-heal a UI run that was previously hard-killed, plus assorted input, UI and
   threading fixes.


0.1.4
-----

FIXED

 * MarkdownViewer now word-wraps paragraph text to the control width. Previously a paragraph wider than the
   view clipped at the right edge and dropped everything past the first row (its doc already claimed it
   "reflows to the control width"). Implemented via a new opt-in wrapWords mode on AnsiConsoleBuffer
   (word-boundaried, with a character-level fallback for an over-long word); other controls are unaffected.

 * The package now bundles the XML documentation of its private assemblies (Jumbee.Console.Styles, the
   Spectre.Console fork, ConsolePlot, ...) alongside their DLLs in lib/. Previously only the DLLs shipped,
   so the theming / Color / IStyleTheme / IGlyphTheme API (in Jumbee.Console.Styles) and the bundled Spectre
   types had no IntelliSense or doc surface for consumers. (The bundling target's .xml match never fired
   because the XML doc copies don't carry ReferenceSourceTarget=ProjectReference.)

ADDED

 * UI.HotKeys.Char(char) - builds a ConsoleKeyInfo for a bare letter, digit, punctuation, or space key so it
   can be registered as a global hotkey (e.g. UI.RegisterHotKey(UI.HotKeys.Char('q'), UI.Stop)). It mirrors
   the input decoder exactly - including that punctuation keys (e.g. /) carry key code 0 with the character
   - so a registered hotkey matches a real keypress, and the same value drives a headless routeGlobal
   snapshot test.

 * Tree.SelectionChanged event - raised whenever the highlighted node changes (arrow/vim keys,
   Home/End/PageUp/PageDown, or a mouse click), mirroring ListBox.SelectionChanged. Lets a detail pane
   follow tree navigation instead of only reacting to NodeActivated (leaf Enter/double-click).

 * TreeGuide.None - a connector-less tree where hierarchy is shown by indentation (and node glyphs) alone.

 * Tree.TreeNode.Tag and ListBox.ListBoxItem.Tag - an object? slot for arbitrary application data, so a node
   or row can map back to its domain object without a side dictionary.

CHANGED

 * Tree.TreeNode.UpdateTree() is now public (was protected) - it appeared in the docs but wasn't callable
   (CS0122). It forces a redraw of the owning tree, for the rare case a mutation didn't go through a
   property setter.

DOCS

 * Documented that ConsoleSnapshot.ToTextAfter / RenderAfter deliver keys to the control argument itself,
   not to whatever UI.SetFocus last targeted - pass the control that actually changes (for a composite app,
   the specific child under test, not the root).

 * Refreshed the "Snapshot Testing" internals page to the current input API (routeGlobal, UI.HotKeys.Char)
   and cross-linked the getting-started "Testing without a terminal" guide. The getting-started hotkey
   examples now use UI.HotKeys.Char; the previous punctuation example built the key with ConsoleKey.Oem2,
   which does not match a real / keypress.

 * UI.RegisterHotKey: documented that the hotkey table is process-global (not scoped to a UI.Start root) -
   so a hotkey letter never reaches a focused text field (unregister and re-register around focus), and a
   second app instance re-registers the same keys (register and exercise one at a time in headless tests).

 * Grid: documented its fixed-cell sizing (each value is an absolute cell count; the grid's size is their
   sum; 0 is a collapsed row or column, NOT fill-the-parent like DockPanel) - use DockPanel or SplitPanel
   for proportional and fill layouts.

 * SplitPanel.MinFirst: documented it clamps to >= 1, so SplitPosition can't reach 0 (a "fully collapsed"
   pane is a 1-cell sliver).

 * Composite Controls: added the single-child idiom (SetContent(new Boundary(child))).

 * Troubleshooting: added the Jumbee.Console.Tree vs Spectre.Console.Tree name-ambiguity (CS0104) fix, and
   clarified that MarkdownViewer lives in core Jumbee.Console while the other viewers are in
   Jumbee.Console.Documents.


0.1.3
-----

CHANGED

 * ConsoleSnapshot.Key(key, ...) now fills in KeyChar for letter and digit keys (lowercase, uppercase under
   Shift, the control char under Ctrl), so a simulated key matches a hotkey registered the natural way (a
   bare letter). Previously it left KeyChar='\0', so ToTextAfter(..., routeGlobal: true) silently failed to
   fire bare-letter global hotkeys. Non-character keys (arrows, function keys) are unchanged.

DOCS

 * Documented that text snapshots (ConsoleSnapshot.ToText) don't capture colour or decoration - assert
   colour with SavePng / ToImage, or render a visible marker.

 * Documented the runtime-reconfiguration pattern on UI.Layout (read-only): for a full-screen "zen" toggle,
   collapse a SplitPanel pane via SplitPosition or reassign DockPanel.DockedControl / FillControl, rather
   than swapping the root.


0.1.2
-----

ADDED

 * UI.SendInput(target, key, routeGlobal) - an opt-in overload that runs the global hotkey dispatch (keys
   registered with UI.RegisterHotKey) before routing to the focused control, mirroring the live input path.
   Backward-compatible; existing calls route straight to the control as before.

 * Jumbee.Console.Snapshot: ConsoleSnapshot.RenderAfter and ToTextAfter now accept a routeGlobal flag, so a
   headless snapshot test can exercise an app's global keybindings, not just control-routed input. Build the
   simulated key the same way the hotkey was registered so it compares equal.

CHANGED

 * The bundled package README now includes a runnable first-app example and a note about the private
   Spectre.Console fork: do not also reference the upstream Spectre.Console NuGet package (the assembly
   identities collide and the build fails with CS1704).


0.1.1
-----

 * Initial public release.