diff options
author | tjpcc <tjp@ctrl-c.club> | 2023-01-13 10:50:30 -0700 |
---|---|---|
committer | tjpcc <tjp@ctrl-c.club> | 2023-01-13 10:50:30 -0700 |
commit | aa23984bc21f99e00b8552e928d23ef02bb745f3 (patch) | |
tree | b11e6489cde0bbfd21a4a4472e9fa837aa0abf25 /gemtext/types.go | |
parent | 13f553c965d0e8c1f609cbbbf66e81fc1450b850 (diff) |
Initial gemtext package.
Contains:
- gemtext AST (Document and line types)
- Parse from an io.Reader
- ParseLine a []byte
- doc comments on everything
- ParseLine tests for every line type
Still needs tests for Parse & Document.
Diffstat (limited to 'gemtext/types.go')
-rw-r--r-- | gemtext/types.go | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/gemtext/types.go b/gemtext/types.go new file mode 100644 index 0000000..fb9352a --- /dev/null +++ b/gemtext/types.go @@ -0,0 +1,171 @@ +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 +} + +// 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 } + +// LinkLine is a line of LineTypeLink. +type LinkLine struct { + raw []byte + + // URL is the original bytes of the url portion of the line. + // + // It is not guaranteed to be a valid URL. + URL []byte + + // Label is the label portion of the line. + // + // If there was no label it will always be nil, never []byte{}. + Label []byte +} + +func (ll LinkLine) Type() LineType { return LineTypeLink } +func (ll LinkLine) Raw() []byte { return ll.raw } + +// PreformatToggleLine is a preformatted text toggle line. +type PreformatToggleLine struct { + raw []byte + + // AltText contains the alt-text portion of the line. + // + // It will either have len() > 0 or be nil. + // + // 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 nil. If the line was parsed by + // ParseLine() no such correction is performed. + AltText []byte +} + +func (tl PreformatToggleLine) Type() LineType { return LineTypePreformatToggle } +func (tl PreformatToggleLine) Raw() []byte { return tl.raw } +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 } + +// HeadingLine is a line of LineTypeHeading[1,2,3]. +type HeadingLine struct { + raw []byte + lineType LineType + + // Body is the portion of the line with the header text. + Body []byte +} + +func (hl HeadingLine) Type() LineType { return hl.lineType } +func (hl HeadingLine) Raw() []byte { return hl.raw } + +// ListItemLine is a line of LineTypeListItem. +type ListItemLine struct { + raw []byte + + // Body is the text of the list item. + Body []byte +} + +func (li ListItemLine) Type() LineType { return LineTypeListItem } +func (li ListItemLine) Raw() []byte { return li.raw } + +// QuoteLine is a line of LineTypeQuote. +type QuoteLine struct { + raw []byte + + // Body is the text of the quote. + Body []byte +} + +func (ql QuoteLine) Type() LineType { return LineTypeQuote } +func (ql QuoteLine) Raw() []byte { return ql.raw } |