textview

package
v0.0.0-...-a4dcdc0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 14, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Overview

Package textview shows a document of Markdown or the app's own blocks with the primitives: texts with spans, views, scroll views and images. It is NSH's TextView: made for documents and the replies of AI models, with code, tables, footnotes and the app's own syntax.

TextView has no look, as the rest of base: it takes a style per Part.

Index

Constants

View Source
const CopyAction = "copy"

CopyAction is the ID of the code block action that copies the code.

Variables

This section is empty.

Functions

func PlainText

func PlainText(content []Inline) string

PlainText returns content as text: images their description, a footnote reference its number in brackets.

func Provide

func Provide(cx *core.Scope, plugins ...Plugin)

Provide gives every TextView below cx's owner plugins, after those of the views around it.

func RepairStreaming

func RepairStreaming(markdown string) string

RepairStreaming closes the syntax that the last block of Markdown still arriving (a reply streamed token by token) leaves open, so it shows as it will once the rest arrives: `**bold` as bold, a backtick and code as code, `$x^2` and `\(x^2` as formulas, `[text](htt` as its text and a table's header as a table, instead of markers as text. A last line not yet ended whose meaning the next characters decide is held back: a list marker alone, digits that may become one, a line of - or = (an underline now, a rule, an item or text later), a fence's opening line and the start of its closer. The blocks before the last are complete and kept.

Types

type Alert

type Alert uint8

Alert is the kind of a GitHub alert; AlertNone is a plain quotation.

const (
	AlertNone Alert = iota
	// AlertNote is useful information.
	AlertNote
	// AlertTip is advice.
	AlertTip
	// AlertImportant is what must not be missed.
	AlertImportant
	// AlertWarning is what needs attention at once.
	AlertWarning
	// AlertCaution is the risks of an action.
	AlertCaution
)

func (Alert) String

func (a Alert) String() string

String returns the alert's title in English: "Note", "Tip", ... The view says it in the language the app shows.

type Block

type Block interface {
	// Kind names the block's type ("paragraph", "codeBlock"), or a custom
	// node's name.
	Kind() string
	// contains filtered or unexported methods
}

Block is a block of a document: Paragraph, Heading, Blockquote, List, CodeBlock, Table, Rule, Details, Math or Custom.

type Blockquote

type Blockquote struct {
	Children []Block
	Alert    Alert
}

Blockquote is a quotation, or one of GitHub's alerts (> [!NOTE]).

func (Blockquote) Kind

func (Blockquote) Kind() string

type Break

type Break struct{}

Break is a hard line break.

type Classes

type Classes map[Part]string

Classes are Tailwind classes by part, under the parts' styles.

type Code

type Code struct{ Code string }

Code is code in text, as `this`.

type CodeAction

type CodeAction struct{ ID, Label string }

CodeAction is an action of the code blocks: its ID, CopyAction or the app's, and what screen readers say for it, its ID when empty.

type CodeActionEvent

type CodeActionEvent struct {
	ID   string
	Code CodeBlock
}

CodeActionEvent is a press on a code block's action.

type CodeBlock

type CodeBlock struct {
	Language, Meta string
	Code           string
}

CodeBlock is a block of code. Language is the info string's first word ("go"), Meta the rest; Code has no final line break.

func (CodeBlock) Kind

func (CodeBlock) Kind() string

type CodeBlockAction

type CodeBlockAction struct {
	ID, Label string
	Code      CodeBlock
	// Done reports, tracked, that the action just ran: the copy action's
	// check, for 1.6 seconds.
	Done func() bool
}

CodeBlockAction is what RenderCodeBlockAction gets about an action.

type ColumnAlign

type ColumnAlign uint8

ColumnAlign aligns a table's column.

const (
	AlignNone ColumnAlign = iota
	AlignLeft
	AlignCenter
	AlignRight
)

type Custom

type Custom struct {
	// Name is the extension's ("mention", "chart").
	Name string
	// Attributes are a pattern's groups ("1", or by name), a container's
	// label and attributes, a fence's "meta".
	Attributes map[string]string
	// Text is a pattern's match, or a fence's code.
	Text string
	// Data is the app's own.
	Data any
	// Children are a container's blocks; Content inline content.
	Children []Block
	Content  []Inline
}

Custom is a node an Extension or the app made, block or inline, shown by the TextView's RenderCustom or CustomSpan, else as its content.

func (Custom) Kind

func (c Custom) Kind() string

type Details

type Details struct {
	Open     bool
	Summary  []Inline
	Children []Block
}

Details is a disclosure (<details>): its summary, always shown, and its blocks, shown while open. Open is whether it starts open.

func (Details) Kind

func (Details) Kind() string

type Document

type Document struct {
	Blocks []Block
	// Footnotes are the notes the blocks refer to, in the order of their
	// first reference.
	Footnotes []Footnote
}

Document is what a TextView shows: its blocks, then its footnotes.

func Parse

func Parse(markdown string, extensions ...Extension) Document

Parse reads Markdown into a document: CommonMark with GitHub's tables, task lists, strikethrough, autolinks, footnotes and alerts, formulas, and the syntax of extensions. HTML inside reads as ParseHTML reads it; the Markdown between an element's tags, on lines of their own or in a paragraph (<b>x *y*</b>), stays Markdown.

Formulas are TeX between dollars: $x$ and $$x$$ in text, a block between $$ fences on lines of their own, or fenced code of language math, as GitHub shows it. Single dollars around a space or before a digit are prose ("costs $5 and $10"). TeX's own \(x\) and \[x\] are formulas too.

func ParseHTML

func ParseHTML(source string, extensions ...Extension) Document

ParseHTML reads HTML into a document: a fragment, or a whole page's body. Elements a reader does not show are skipped (metadata, scripts, styles, form controls, embedded media, and elements hidden, aria-hidden or styled display: none, such as KaTeX's HTML beside its MathML), and GitHub's own markup reads back as what it writes: alerts, task list boxes, code languages and formulas with a TeX annotation. Extensions with a Tag make custom nodes of their elements; patterns apply to text.

func ParseWith

func ParseWith(markdown string, o Options, extensions ...Extension) Document

ParseWith is Parse with options.

func (Document) PlainText

func (d Document) PlainText() string

PlainText returns the document as text, what copying all of it gives: blocks apart by a blank line, list items and table rows by a line break, table cells by a tab.

type Emphasis

type Emphasis struct{ Content []Inline }

Emphasis is emphasized text, as *this*.

type Extension

type Extension struct {
	Name string
	// Pattern is inline syntax matched in text, outside code and links
	// (`@(\w+)` for mentions). Each match is an inline node: its Text the
	// match, its groups the attributes "1", "2", ... and by name.
	Pattern *regexp.Regexp
	// Language makes fenced code of this language (“`chart) a block
	// node: its Text the code, the rest of the info string the attribute
	// "meta".
	Language string
	// Container makes containers of this name (:::note … :::, as
	// remark-directive writes them) block nodes of the Markdown inside:
	// the label after the name (:::note[Heads up]) is the attribute
	// "label", {key=value .class #id} the other attributes. A container
	// inside another closes with fewer colons than the outer one.
	Container string
	// Tag makes HTML elements of this name, in any case (<Callout>), custom
	// nodes: their attributes the node's, their text its Text, and what
	// they hold its blocks when they stand alone, else its inline content.
	// An element may close itself as JSX writes it (<Callout />).
	Tag string
}

Extension is syntax of the app's that becomes Custom nodes named Name, which the TextView's RenderCustom (blocks) and CustomSpan (inline) show. Set one of Pattern, Language, Container or Tag.

type Footnote

type Footnote struct {
	Label    string
	Index    int
	Children []Block
}

Footnote is a footnote of a document: its label ("1", "note"), its number from 1 and its blocks.

type FootnoteReference

type FootnoteReference struct {
	Label string
	Index int
}

FootnoteReference refers to a footnote by its label and number.

type Heading

type Heading struct {
	Level   int
	Content []Inline
	Anchor  string
}

Heading is a title of level 1 to 6. Anchor is its slug, as GitHub makes it ("getting-started"), unique in its document.

func (Heading) Kind

func (Heading) Kind() string

type Highlight

type Highlight struct {
	Start, End int
	Class      string
	Style      core.Style
}

Highlight styles the bytes from Start to End of a code block's code, Class under Style.

type Highlighter

type Highlighter func(code CodeBlock) []Highlight

Highlighter colors code: byte ranges of the code with their styles, in order and apart. Ranges out of order, overlapping or off a character boundary are skipped. It runs while the block is built, so the signals it reads (the appearance) build the block again.

type Image

type Image struct {
	Src, Alt, Title string
	Width, Height   core.Length
}

Image is an image: its URL, the text that describes it and its title. Width and Height are the size it asks for; unset is its natural size.

type Inline

type Inline interface {
	// contains filtered or unexported methods
}

Inline is content of a block's text: Text, Strong, Emphasis, Strikethrough, Underline, Mark, Superscript, Subscript, Small, Code, Keyboard, Math, Link, Image, Break, FootnoteReference or Custom.

type Keyboard

type Keyboard struct{ Text string }

Keyboard is keys to press, as <kbd>Ctrl</kbd>+<kbd>C</kbd>.

type Link struct {
	URL, Title string
	Content    []Inline
}

Link is a link to URL.

type LinkPressEvent

type LinkPressEvent struct{ URL string }

LinkPressEvent is a press on a link: its URL, "#<anchor>" for a heading of the document, "#footnote-<label>" for a footnote.

type List

type List struct {
	Ordered bool
	Start   int
	Loose   bool
	Items   []ListItem
}

List is a bulleted or numbered list. Start is an ordered list's first number; Loose lists have blank lines between their items.

func (List) Kind

func (List) Kind() string

type ListItem

type ListItem struct {
	Task, Done bool
	Children   []Block
}

ListItem is an item of a list. Task items (- [ ], - [x]) have a box, checked when Done.

type Mark

type Mark struct {
	Content []Inline
	Color   core.Color
}

Mark is marked text, as <mark>this</mark>. Color is the background it asks for; zero is the view's.

type Math

type Math struct {
	TeX string
	// Display is set on a formula that is a block of its own, as
	// RenderMath gets it.
	Display bool
}

Math is a formula written in TeX, a block of its own or inline in text. HTML gives one for MathML with a TeX annotation, as KaTeX and MathJax write it.

func (Math) Kind

func (Math) Kind() string

type Options

type Options struct {
	// NoMath reads dollars and \( \[ as text and math fences as code.
	NoMath bool
	// NoHTML shows HTML in the Markdown as text.
	NoHTML bool
	// NoAlerts reads > [!NOTE] and its kin as plain quotations.
	NoAlerts bool
	// Frontmatter reads YAML front matter (--- … --- first) as a Custom
	// block "frontmatter" whose Text is the YAML, rather than a rule and
	// text.
	Frontmatter bool
	// MDX reads JSX elements as Custom nodes named by their tag, with
	// their attributes and content, and {expressions} as Custom nodes
	// "expression" whose Text is the expression; HTML is then read as
	// elements too.
	MDX bool
	// Streaming repairs the syntax the last block leaves open before
	// parsing (RepairStreaming), for a document still arriving.
	Streaming bool
}

Options say what a Markdown document reads beyond CommonMark and GitHub's syntax, as NSH's MarkdownOptions; the zero value is NSH's default.

type Paragraph

type Paragraph struct{ Content []Inline }

Paragraph is a block of text.

func (Paragraph) Kind

func (Paragraph) Kind() string

type Part

type Part uint8

Part is a part of a TextView the app styles. A node with several parts (PartHeading then PartHeading2) merges their styles, later parts winning.

const (
	// PartRoot is the text view itself, a column of its blocks: text
	// styles here pass to every part.
	PartRoot Part = iota
	PartParagraph
	// PartHeading is every heading, before its level's part.
	PartHeading
	PartHeading1
	PartHeading2
	PartHeading3
	PartHeading4
	PartHeading5
	PartHeading6
	// PartBlockquote is quotations and alerts: a column of their blocks.
	PartBlockquote
	// PartAlert is every alert (> [!NOTE]), after PartBlockquote and
	// before its kind's part.
	PartAlert
	PartAlertNote
	PartAlertTip
	PartAlertImportant
	PartAlertWarning
	PartAlertCaution
	// PartAlertTitle is the title line of an alert ("Note"), inside the
	// alert's box.
	PartAlertTitle
	// PartAlertContent is the column of an alert's blocks, below its
	// title.
	PartAlertContent
	// PartList is every list, a column of its items, before
	// PartOrderedList or PartUnorderedList.
	PartList
	PartOrderedList
	PartUnorderedList
	// PartListItem is every item: a row of its marker and its content.
	PartListItem
	// PartListMarker is an item's marker: "•", "◦" or "▪" by depth, or its
	// number.
	PartListMarker
	// PartTaskMarker is a task item's box in place of PartListMarker,
	// PartTaskMarkerChecked after it when done.
	PartTaskMarker
	PartTaskMarkerChecked
	// PartListItemContent is the column of an item's blocks.
	PartListItemContent
	// PartTaskDone is the content of a done task, after
	// PartListItemContent.
	PartTaskDone
	// PartCodeBlock is a code block: its scroll view and the actions over
	// it.
	PartCodeBlock
	// PartCodeBlockHeader is the row of a code block's actions, absolutely
	// placed over it.
	PartCodeBlockHeader
	// PartCodeBlockAction is each action button in PartCodeBlockHeader.
	PartCodeBlockAction
	// PartCodeBlockScroll is the horizontal scroll view of a block's code.
	PartCodeBlockScroll
	// PartCodeBlockCode is the text of a block's code.
	PartCodeBlockCode
	// PartCode is code in text.
	PartCode
	// PartKeyboard is keys to press (<kbd>).
	PartKeyboard
	PartStrong
	PartEmphasis
	PartStrikethrough
	PartUnderline
	// PartMark is marked text (<mark>), under the color it asks for.
	PartMark
	PartSuperscript
	PartSubscript
	PartSmall
	PartLink
	// PartImage is images alone in a paragraph: their natural size, at
	// most the text's width, unless they ask for one.
	PartImage
	// PartTable is a table: the scroll view of its cells.
	PartTable
	// PartTableActions holds RenderTableActions' content, above the table.
	PartTableActions
	// PartTableScroll is the horizontal scroll view of a table's grid;
	// it scrolls when the columns cannot shrink further.
	PartTableScroll
	// PartTableRow is every row: a view behind its cells, for backgrounds
	// and borders. Text styles go on the cells.
	PartTableRow
	// PartTableHead is the header row, after PartTableRow.
	PartTableHead
	PartTableCell
	// PartTableHeaderCell is the header row's cells, after PartTableCell.
	PartTableHeaderCell
	// PartRule is a thematic break, a view.
	PartRule
	// PartMath is a formula in text: its TeX.
	PartMath
	// PartMathBlock is a formula block: its TeX.
	PartMathBlock
	// PartDetails is a disclosure: a column of its summary and, while
	// open, its blocks.
	PartDetails
	// PartSummary is a disclosure's summary, a row of its marker and its
	// text; a press opens or closes it.
	PartSummary
	// PartSummaryMarker is the summary's marker: "▸" closed, "▾" open.
	PartSummaryMarker
	// PartFootnotes is the column of footnotes after the blocks.
	PartFootnotes
	// PartFootnote is a footnote: a row of its label and its blocks.
	PartFootnote
	PartFootnoteLabel
	// PartFootnoteReference is a reference to a footnote in text: its
	// number in brackets.
	PartFootnoteReference
	// PartCustom is custom nodes shown as their content.
	PartCustom
)

type Plugin

type Plugin struct {
	Extension Extension
	Render    func(cx *core.Scope, node Custom) core.Node
}

Plugin is an extension a view gives every TextView below it, with what shows its custom nodes: Render comes before a view's RenderCustom, which shows the nodes Render leaves (returning nil).

type Rule

type Rule struct{}

Rule is a thematic break.

func (Rule) Kind

func (Rule) Kind() string

type Small

type Small struct{ Content []Inline }

Small is smaller text, as <small>this</small>.

type Strikethrough

type Strikethrough struct{ Content []Inline }

Strikethrough is struck text, as ~~this~~.

type Strong

type Strong struct{ Content []Inline }

Strong is strong text, as **this**.

type Styles

type Styles map[Part]core.Style

Styles are styles by part.

type Subscript

type Subscript struct{ Content []Inline }

Subscript is text below the line, as <sub>2</sub>.

type Superscript

type Superscript struct{ Content []Inline }

Superscript is text above the line, as <sup>2</sup>.

type Table

type Table struct {
	Align []ColumnAlign
	Head  []TableCell
	Rows  [][]TableCell
}

Table is a table: its column alignments, its header row and its body.

func (Table) Columns

func (t Table) Columns() int

Columns returns the number of columns: the widest row's.

func (Table) Kind

func (Table) Kind() string

type TableCell

type TableCell struct {
	Content []Inline
	ColSpan int
}

TableCell is a cell of a table. ColSpan is the columns it spans; 0 is one.

type Text

type Text struct{ Text string }

Text is plain text.

type TextView

type TextView struct {
	// Markdown is the document, read by Parse with Extensions.
	Markdown     string
	MarkdownFunc func() string
	// HTML is the document as HTML, read by ParseHTML with Extensions,
	// when no Markdown is given.
	HTML     string
	HTMLFunc func() string
	// Document is the document as blocks the app made, when neither
	// Markdown nor HTML is given.
	Document     Document
	DocumentFunc func() Document
	// Extensions go after those Provide gives the views below it.
	Extensions []Extension
	// Options say what the Markdown reads, Streaming among them.
	Options Options
	// StreamingCaret, as a document streams in, follows its end: inline
	// after the last text of the last block (into quotes, lists and
	// custom nodes' content, after a code block's code, in a table's last
	// cell), else on a line of its own after it.
	StreamingCaret core.Node

	// Styles style the parts; StyleOf's result for a part goes under
	// them, again when what it reads changes, and Classes under both.
	Classes Classes
	Styles  Styles
	StyleOf func(Part) core.Style
	// Selectable makes the view a selectable view: one selection runs
	// across its blocks, and on into the texts around inside an outer
	// selectable view.
	Selectable bool
	// Highlighter colors code blocks; without one their code is plain.
	Highlighter Highlighter

	// OnLinkPress receives a pressed link's URL: a heading's anchor is
	// "#<anchor>", a footnote reference "#footnote-<label>". Nothing opens
	// a URL unless OpenLinks; the app decides.
	OnLinkPress func(LinkPressEvent)
	// OpenLinks also opens a pressed link to another site or app (a URL
	// with a scheme: https:, mailto:) outside the app with Scope.OpenURL,
	// after OnLinkPress; anchors are only reported.
	OpenLinks bool
	// OnImagePress receives an image pressed that is in no link, for the
	// app to show it larger.
	OnImagePress func(image Image)
	// RenderCustom shows a custom node: a block, or an inline node as an
	// attachment in its text unless CustomSpan shows it. Without either, a
	// node shows its content.
	RenderCustom func(cx *core.Scope, node Custom) core.Node
	// CustomSpan shows a custom node in text as a span.
	CustomSpan func(node Custom) core.Span
	// RenderMath shows a formula: a block of its own when its Display is
	// set ($$…$$ on lines of its own), else as an attachment in its text.
	// Without it a formula shows its TeX in PartMath or PartMathBlock.
	RenderMath func(cx *core.Scope, math Math) core.Node
	// RenderCodeBlock shows a code block in place of the default: the code
	// in a horizontal scroll view.
	RenderCodeBlock func(cx *core.Scope, code CodeBlock) core.Node
	// CodeBlockActions are buttons over each code block's top right
	// corner, in PartCodeBlockHeader, each a PartCodeBlockAction showing
	// RenderCodeBlockAction (its label, else its ID, as text without it).
	// CopyAction copies the code, and reports itself done for 1.6
	// seconds; a press on any reports OnCodeBlockAction.
	CodeBlockActions      []CodeAction
	RenderCodeBlockAction func(cx *core.Scope, action CodeBlockAction) core.Node
	OnCodeBlockAction     func(CodeActionEvent)
	// RenderTableActions shows content above each table, in
	// PartTableActions.
	RenderTableActions func(cx *core.Scope, table Table) core.Node
	// NoTableScroll lets a table shrink past its columns' floors rather
	// than scroll; NoTableScrollbar and NoCodeBlockScrollbar hide the
	// scroll bars of tables and code blocks.
	NoTableScroll, NoTableScrollbar, NoCodeBlockScrollbar bool
	// RenderImage shows an image in place of the default: alone in a
	// paragraph, a block; in a line of text, an attachment.
	RenderImage func(cx *core.Scope, image Image) core.Node
	TestID      string
	// OnLayout and Tooltip are its view's, as a core.View's.
	OnLayout func(core.Bounds)
	Tooltip  core.Node
}

TextView shows a document: Markdown or HTML, parsed once per change, else the app's own Document. Its blocks are rows keyed by position and kind, so a document that grows at its end (a reply streaming in) builds only its last block again.

func (TextView) Render

func (tv TextView) Render(cx *core.Scope) core.Node

Render implements core.Node.

type Underline

type Underline struct{ Content []Inline }

Underline is underlined text, as <u>this</u>.

Directories

Path Synopsis
Package highlight colors the code blocks of a TextView with chroma's lexers and NSH's reading palette, light and dark.
Package highlight colors the code blocks of a TextView with chroma's lexers and NSH's reading palette, light and dark.
Package locales says the text view's own messages in the language the app shows.
Package locales says the text view's own messages in the language the app shows.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址