diff options
Diffstat (limited to 'gemini/gemtext/types.go')
-rw-r--r-- | gemini/gemtext/types.go | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/gemini/gemtext/types.go b/gemini/gemtext/types.go new file mode 100644 index 0000000..440fed4 --- /dev/null +++ b/gemini/gemtext/types.go @@ -0,0 +1,184 @@ +package gemtext + +// LineType represents the different types of lines in a gemtext document. +type LineType int + +const ( + // LineTypeText is the default case when nothing else matches. + // + // It indicates that the line object is a TextLine. + LineTypeText LineType = iota + 1 + + // LineTypeLink is a link line. + // + // =>[<ws>]<url>[<ws><label>][\r]\n + // + // The line is a LinkLine. + LineTypeLink + + // LineTypePreformatToggle switches the document between pre-formatted text or not. + // + // ```[<alt-text>][\r]\n + // + // The line object is a PreformatToggleLine. + LineTypePreformatToggle + + // LineTypePreformattedText is any line between two PreformatToggles. + // + // The line is a PreformattedTextLine. + LineTypePreformattedText + + // LineTypeHeading1 is a top-level heading. + // + // #[<ws>]body[\r]\n + // + // The line is a HeadingLine. + LineTypeHeading1 + + // LineTypeHeading2 is a second-level heading. + // + // ##[<ws>]body[\r]\n + // + // The line is a HeadingLine. + LineTypeHeading2 + + // LineTypeHeading3 is a third-level heading. + // + // ###[<ws>]<body>[\r]\n + // + // The line is a HeadingLine. + LineTypeHeading3 + + // LineTypeListItem is an unordered list item. + // + // * <body>[\r]\n + // + // The line object is a ListItemLine. + LineTypeListItem + + // LineTypeQuote is a quote line. + // + // ><body>[\r]\n + // + // The line object is a QuoteLine. + LineTypeQuote +) + +// Line is the interface implemented by all specific line types. +// +// Many of those concrete implementation types have additional useful fields, +// so it can be a good idea to cast these to their concrete types based on the +// return value of the Type() method. +type Line interface { + // Type returns the specific type of the gemtext line. + Type() LineType + + // Raw reproduces the original bytes from the source reader. + Raw() []byte + + // String represents the original bytes from the source reader as a string. + String() string +} + +// Document is the list of lines that make up a full text/gemini resource. +type Document []Line + +// TextLine is a line of LineTypeText. +type TextLine struct { + raw []byte +} + +func (tl TextLine) Type() LineType { return LineTypeText } +func (tl TextLine) Raw() []byte { return tl.raw } +func (tl TextLine) String() string { return string(tl.raw) } + +// LinkLine is a line of LineTypeLink. +type LinkLine struct { + raw []byte + url []byte + label []byte +} + +func (ll LinkLine) Type() LineType { return LineTypeLink } +func (ll LinkLine) Raw() []byte { return ll.raw } +func (ll LinkLine) String() string { return string(ll.raw) } + +// URL returns the original url portion of the line. +// +// It is not guaranteed to be a valid URL. +func (ll LinkLine) URL() string { return string(ll.url) } + +// Label returns the label portion of the line. +func (ll LinkLine) Label() string { return string(ll.label) } + +// PreformatToggleLine is a preformatted text toggle line. +type PreformatToggleLine struct { + raw []byte + altText []byte +} + +func (tl PreformatToggleLine) Type() LineType { return LineTypePreformatToggle } +func (tl PreformatToggleLine) Raw() []byte { return tl.raw } +func (tl PreformatToggleLine) String() string { return string(tl.raw) } + +// AltText returns the alt-text portion of the line. +// +// If the line was parsed as part of a full document by Parse(), +// and this is a *closing* toggle, any alt-text present will be +// stripped and this will be empty. If the line was parsed by +// ParseLine() no such correction is performed. +func (tl PreformatToggleLine) AltText() string { return string(tl.altText) } + +func (tl *PreformatToggleLine) clearAlt() { tl.altText = nil } + +// PreformattedTextLine represents a line between two toggles. +// +// It is never returned by ParseLine but can be part of a +// document parsed by Parse(). +type PreformattedTextLine struct { + raw []byte +} + +func (tl PreformattedTextLine) Type() LineType { return LineTypePreformattedText } +func (tl PreformattedTextLine) Raw() []byte { return tl.raw } +func (tl PreformattedTextLine) String() string { return string(tl.raw) } + +// HeadingLine is a line of LineTypeHeading[1,2,3]. +type HeadingLine struct { + raw []byte + lineType LineType + body []byte +} + +func (hl HeadingLine) Type() LineType { return hl.lineType } +func (hl HeadingLine) Raw() []byte { return hl.raw } +func (hl HeadingLine) String() string { return string(hl.raw) } + +// Body returns the portion of the line with the header text. +func (hl HeadingLine) Body() string { return string(hl.body) } + +// ListItemLine is a line of LineTypeListItem. +type ListItemLine struct { + raw []byte + body []byte +} + +func (li ListItemLine) Type() LineType { return LineTypeListItem } +func (li ListItemLine) Raw() []byte { return li.raw } +func (li ListItemLine) String() string { return string(li.raw) } + +// Body returns the text of the list item. +func (li ListItemLine) Body() string { return string(li.body) } + +// QuoteLine is a line of LineTypeQuote. +type QuoteLine struct { + raw []byte + body []byte +} + +func (ql QuoteLine) Type() LineType { return LineTypeQuote } +func (ql QuoteLine) Raw() []byte { return ql.raw } +func (ql QuoteLine) String() string { return string(ql.raw) } + +// Body returns the text of the quote. +func (ql QuoteLine) Body() string { return string(ql.body) } |