class TUI::MarkdownView

Overview

Renders a Markdown source string: numbered headings with per-level emphasis (since a terminal can't grow font size), real word-wrapped paragraphs/list items/blockquotes preserving inline styling, nested list indentation with continuation lines aligned under the text (not the marker), and GFM tables with alignment-aware column widths drawn with box-drawing borders. Parsing/wrapping/layout are hand-rolled in TUI::Markdown (this library has zero runtime dependencies) — see TUI::Markdown::Parser/Wrap/Layout for the algorithms; this class is just the Scrollable host: styling properties, caching, and the standard scroll-key handling every other Scrollable already has.

Included Modules

Defined in:

tui/widgets/markdown_view.cr

Constructors

Instance Method Summary

Instance methods inherited from module TUI::Scrollable

content_size : Int32 content_size, focus_if(condition : Bool) : Nil focus_if, focused=(focused : Bool) focused=, focused? : Bool focused?, handle_click(local_row : Int32, local_col : Int32, scroll : ScrollControl) : Bool handle_click, handle_key(ev : KeyEvent, scroll : ScrollControl) : Bool handle_key, header_rows : Int32 header_rows, render_content(buffer : Buffer, scroll : ScrollControl) : Nil render_content, status_hint : String status_hint, title : String title

Constructor Detail

def self.new(source : String = "") #

[View source]

Instance Method Detail

def bold_italic_style : Style #

[View source]
def bold_italic_style=(bold_italic_style : Style) #

[View source]
def bold_style : Style #

[View source]
def bold_style=(bold_style : Style) #

[View source]
def code_style : Style #

[View source]
def code_style=(code_style : Style) #

[View source]
def content_size : Int32 #

Reports the physical row count for the width this content was LAST actually rendered at (#render_content updates that width every call) — Window#render calls #content_size before it has built the buffer that would tell content this frame's width (confirmed by reading Window#render: total = @content.content_size runs before inner = Buffer.new(inner_width, ...)), so there is structurally no way to answer for the CURRENT frame's width here. This is stale by exactly one frame during an active resize (used only for Scroller#clamp's max-offset math) and self-heals the same frame #render_content next runs with the real width — the same resize-tolerance philosophy Scroller#clamp itself already relies on, rather than widening Scrollable's abstract contract for this one widget's benefit.


[View source]
def handle_click(local_row : Int32, local_col : Int32, scroll : ScrollControl) : Bool #
Description copied from module TUI::Scrollable

A positional (mouse) event, pre-translated by Window into content-local row/col (0,0 = content's own first cell).


[View source]
def handle_key(ev : KeyEvent, scroll : ScrollControl) : Bool #
Description copied from module TUI::Scrollable

Everything but positional mouse hit-testing.


[View source]
def heading_indent_step : Int32 #

[View source]
def heading_indent_step=(heading_indent_step : Int32) #

[View source]
def heading_styles : Array(Style) #

Heading styles by level (index 0 = h1), decreasing emphasis since Style has no font-size — numbering (see #number_headings) is the primary way level is conveyed, this is a secondary visual cue.


[View source]
def heading_styles=(heading_styles : Array(Style)) #

Heading styles by level (index 0 = h1), decreasing emphasis since Style has no font-size — numbering (see #number_headings) is the primary way level is conveyed, this is a secondary visual cue.


[View source]
def hrule_style : Style #

[View source]
def hrule_style=(hrule_style : Style) #

[View source]
def italic_style : Style #

[View source]
def italic_style=(italic_style : Style) #

[View source]
def link_style : Style #

[View source]
def link_style=(link_style : Style) #

[View source]
def list_bullet_glyphs : Array(String) #

[View source]
def list_bullet_glyphs=(list_bullet_glyphs : Array(String)) #

[View source]
def list_indent_step : Int32 #

[View source]
def list_indent_step=(list_indent_step : Int32) #

[View source]
def list_marker_style : Style #

[View source]
def list_marker_style=(list_marker_style : Style) #

[View source]
def load(source : String) : Nil #

Replaces the rendered content and invalidates the cached layout (see #content_size for why layout is cached at all) so the next #content_size/#render_content call re-lays-out unconditionally, even if the new document happens to need the same width as the old cached layout.


[View source]
def number_headings=(number_headings : Bool) #

Nested-outline numbering ("1.2.3 Title") in front of every heading. Disable to keep indentation/styling but drop the prefix.


[View source]
def number_headings? : Bool #

Nested-outline numbering ("1.2.3 Title") in front of every heading. Disable to keep indentation/styling but drop the prefix.


[View source]
def quote_indent_step : Int32 #

[View source]
def quote_indent_step=(quote_indent_step : Int32) #

[View source]
def quote_style : Style #

[View source]
def quote_style=(quote_style : Style) #

[View source]
def render_content(buffer : Buffer, scroll : ScrollControl) : Nil #
Description copied from module TUI::Scrollable

Render into buffer, a region already sized to the content area (border/scrollbar column already excluded by Window). Row 0 is content's own first row.


[View source]
def status_hint : String #

[View source]
def table_border_style : Style #

[View source]
def table_border_style=(table_border_style : Style) #

[View source]
def table_header_style : Style #

[View source]
def table_header_style=(table_header_style : Style) #

[View source]
def title : String #

Set by a host app (e.g. to a document's filename); shown as the hosting Window's border title, same convention as DetailView#title.


[View source]
def title=(title : String) #

Set by a host app (e.g. to a document's filename); shown as the hosting Window's border title, same convention as DetailView#title.


[View source]