Documentation
¶
Overview ¶
Package parser implements gemtext specification concepts by defining various structures and methods for manipulating gemtext.
To represent a gemtext document which is line-oriented, flat, and nonhierarchical, this package uses an Abstract Syntax List (ASL) instead of the usual Abstract Syntax Tree (AST). Under the hood, ASLs are just slices.
There are different ways to use this package. You can parse a gemtext document using Parse or ParseFile. From there, you can convert it to HTML with ToHTML or ToHTMLFile, or transform it using the different ASL methods before generating a new gemtext document with ToGemtext or ToGemtextFile. You may even want to programmatically create a gemtext document by passing the different Element types, Text, Link, Heading, List, Quote, and PreformatToggle, to NewASL.
Index ¶
- Variables
- func ToGemtext(asl ASL) string
- func ToGemtextFile(name string, asl ASL, perm os.FileMode) error
- func ToHTML(asl ASL) string
- func ToHTMLFile(name string, asl ASL, perm os.FileMode) error
- type ASL
- func (asl *ASL) Clone() ASL
- func (asl *ASL) DeleteAll(f func(Element) bool)
- func (asl *ASL) DeleteFirst(n uint) error
- func (asl *ASL) DeleteLast(n uint) error
- func (asl *ASL) InsertAfter(elems []Element, f func(Element) bool)
- func (asl *ASL) InsertBefore(elems []Element, f func(Element) bool)
- func (asl *ASL) InsertFirst(elems ...Element)
- func (asl *ASL) InsertLast(elems ...Element)
- func (asl *ASL) Replace(elems []Element, f func(Element) bool)
- func (asl *ASL) Visit(f func(Element))
- type Element
- type Heading
- type Link
- type List
- type PreformatToggle
- type Quote
- type Text
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ElementTypes = elementTypes{ // contains filtered or unexported fields }
ElementTypes exposes the different element types:
p.ElementTypes.Text() p.ElementTypes.Link() p.ElementTypes.Heading() p.ElementTypes.List() p.ElementTypes.Quote() p.ElementTypes.PreformatToggle()
Their names can be accessed as strings:
p.ElementTypes.Text().Name() // Text
It can be used to check what type an Element is:
func example(e p.Element) {
if e.Type() == p.ElementTypes.Text() {
// Do something
}
}
-
var HeadingLevels = headingLevels{ // contains filtered or unexported fields }
HeadingLevels exposes the different heading levels:
p.HeadingLevels.Heading() p.HeadingLevels.SubHeading() p.HeadingLevels.SubSubHeading() p.HeadingLevels.NotHeading()
Their values can be accessed as int8:
p.HeadingLevels.Heading().Value() // 1
It can be used to check what level a Heading is:
func example(h p.Heading) {
if h.Level() == p.HeadingLevels.Heading() {
// Do something
}
}
Functions ¶
func ToGemtext ¶
ToGemtext turns asl into gemtext.
Example ¶
package main
import (
"fmt"
p "github.com/mcecode/gemtext-parser"
)
func main() {
asl := p.NewASL(
p.NewHeading("Some Heading", p.HeadingLevels.Heading()),
p.NewText("Some text..."),
p.NewLink("Some link", "gemini://example.org"),
)
gemtext := p.ToGemtext(asl)
fmt.Println(gemtext)
}
Output: # Some Heading Some text... => gemini://example.org Some link
func ToGemtextFile ¶
ToGemtextFile turns asl into gemtext, then writes it into the named file. Returns an error if there's an error while writing the file.
Example ¶
package main
import (
p "github.com/mcecode/gemtext-parser"
)
func main() {
asl := p.NewASL(
p.NewHeading("Some Heading", p.HeadingLevels.Heading()),
p.NewText("Some text..."),
p.NewLink("Some link", "gemini://example.org"),
)
p.ToGemtextFile("testdata/example.gmi", asl, 0600)
}
func ToHTML ¶
ToHTML turns asl into HTML.
Example ¶
package main
import (
"fmt"
p "github.com/mcecode/gemtext-parser"
)
func main() {
asl := p.NewASL(
p.NewHeading("Some Heading", p.HeadingLevels.Heading()),
p.NewText("Some text..."),
p.NewLink("Some link", "gemini://example.org"),
)
html := p.ToHTML(asl)
fmt.Println(html)
}
Output: <h1>Some Heading</h1> <p>Some text...</p> <p><a href="gemini://example.org">Some link</a></p>
func ToHTMLFile ¶
ToHTMLFile turns asl into HTML, then writes it into the named file. Returns an error if there's an error while writing the file.
Example ¶
package main
import (
p "github.com/mcecode/gemtext-parser"
)
func main() {
asl := p.NewASL(
p.NewHeading("Some Heading", p.HeadingLevels.Heading()),
p.NewText("Some text..."),
p.NewLink("Some link", "gemini://example.org"),
)
p.ToGemtextFile("testdata/example.html", asl, 0600)
}
Types ¶
type ASL ¶
type ASL struct {
// contains filtered or unexported fields
}
ASL represents an Abstract Syntax List of a gemtext document.
func NewASL ¶
Example ¶
package main
import (
"github.com/sanity-io/litter"
p "github.com/mcecode/gemtext-parser"
)
var dumper = litter.Options{StripPackageNames: true, HidePrivateFields: false}
func main() {
empty := p.NewASL()
dumper.Dump(empty)
asl := p.NewASL(p.NewText("Some text..."))
dumper.Dump(asl)
}
Output: ASL{ elems: nil, } ASL{ elems: []Element{ Text{ text: "Some text...", }, }, }
func Parse ¶
Parse parses s into an ASL.
Example ¶
package main
import (
"fmt"
"github.com/sanity-io/litter"
p "github.com/mcecode/gemtext-parser"
)
var dumper = litter.Options{StripPackageNames: true, HidePrivateFields: false}
func main() {
s := fmt.Sprint(
"# Some Heading\n",
"Some text...\n",
"=> gemini://example.org Some link\n",
)
asl := p.Parse(s)
dumper.Dump(asl)
}
Output: ASL{ elems: []Element{ Heading{ text: "Some Heading", level: headingLevel{ value: 1, }, }, Text{ text: "Some text...", }, Link{ text: "Some link", url: "gemini://example.org", }, }, }
func ParseFile ¶
ParseFile reads the named file, then parses it into an ASL. Returns an error if there's an error while reading the file.
Example ¶
Contents of testdata/example.gmi:
# Some Heading Some text... => gemini://example.org Some link
package main
import (
"github.com/sanity-io/litter"
p "github.com/mcecode/gemtext-parser"
)
var dumper = litter.Options{StripPackageNames: true, HidePrivateFields: false}
func main() {
asl, _ := p.ParseFile("testdata/example.gmi")
dumper.Dump(asl)
}
Output: ASL{ elems: []Element{ Heading{ text: "Some Heading", level: headingLevel{ value: 1, }, }, Text{ text: "Some text...", }, Link{ text: "Some link", url: "gemini://example.org", }, }, }
func (*ASL) Clone ¶
Clone returns a clone of asl.
Example ¶
package main
import (
"github.com/sanity-io/litter"
p "github.com/mcecode/gemtext-parser"
)
var dumper = litter.Options{StripPackageNames: true, HidePrivateFields: false}
func main() {
asl := p.NewASL(p.NewText("Some text..."))
dumper.Dump(asl)
clone := asl.Clone()
dumper.Dump(clone)
}
Output: ASL{ elems: []Element{ Text{ text: "Some text...", }, }, } ASL{ elems: []Element{ Text{ text: "Some text...", }, }, }
func (*ASL) DeleteAll ¶
DeleteAll deletes all elements where f returns true. Does nothing if f returns false for all elements.
Example ¶
package main
import (
"github.com/sanity-io/litter"
p "github.com/mcecode/gemtext-parser"
)
var dumper = litter.Options{StripPackageNames: true, HidePrivateFields: false}
func main() {
asl := p.NewASL(
p.NewHeading("Some Heading", p.HeadingLevels.Heading()),
p.NewText("Some text..."),
p.NewLink("Some link", "gemini://example.org"),
)
asl.DeleteAll(func(e p.Element) bool {
if e.Type() == p.ElementTypes.Heading() ||
e.Type() == p.ElementTypes.Link() {
return true
}
return false
})
dumper.Dump(asl)
}
Output: ASL{ elems: []Element{ Text{ text: "Some text...", }, }, }
func (*ASL) DeleteFirst ¶
DeleteFirst deletes the first n elements of the list. Returns an error if n is larger than the number of elements asl currently has.
Example ¶
package main
import (
"github.com/sanity-io/litter"
p "github.com/mcecode/gemtext-parser"
)
var dumper = litter.Options{StripPackageNames: true, HidePrivateFields: false}
func main() {
asl := p.NewASL(
p.NewHeading("Some Heading", p.HeadingLevels.Heading()),
p.NewText("Some text..."),
p.NewLink("Some link", "gemini://example.org"),
)
asl.DeleteFirst(2)
dumper.Dump(asl)
}
Output: ASL{ elems: []Element{ Link{ text: "Some link", url: "gemini://example.org", }, }, }
func (*ASL) DeleteLast ¶
DeleteLast deletes the last n elements of the list. Returns an error if n is larger than the number of elements asl currently has.
Example ¶
package main
import (
"github.com/sanity-io/litter"
p "github.com/mcecode/gemtext-parser"
)
var dumper = litter.Options{StripPackageNames: true, HidePrivateFields: false}
func main() {
asl := p.NewASL(
p.NewHeading("Some Heading", p.HeadingLevels.Heading()),
p.NewText("Some text..."),
p.NewLink("Some link", "gemini://example.org"),
)
asl.DeleteLast(2)
dumper.Dump(asl)
}
Output: ASL{ elems: []Element{ Heading{ text: "Some Heading", level: headingLevel{ value: 1, }, }, }, }
func (*ASL) InsertAfter ¶
InsertAfter inserts elems after the first element where f returns true. Does nothing if f returns false for all elements.
Example ¶
package main
import (
"github.com/sanity-io/litter"
p "github.com/mcecode/gemtext-parser"
)
var dumper = litter.Options{StripPackageNames: true, HidePrivateFields: false}
func main() {
asl := p.NewASL(
p.NewHeading("Some Heading", p.HeadingLevels.Heading()),
p.NewText("Some text..."),
p.NewLink("Some link", "gemini://example.org"),
)
asl.InsertAfter(
[]p.Element{p.NewQuote("Some quote")},
func(e p.Element) bool {
if e.Type() == p.ElementTypes.Text() {
return true
}
return false
},
)
dumper.Dump(asl)
}
Output: ASL{ elems: []Element{ Heading{ text: "Some Heading", level: headingLevel{ value: 1, }, }, Text{ text: "Some text...", }, Quote{ text: "Some quote", }, Link{ text: "Some link", url: "gemini://example.org", }, }, }
func (*ASL) InsertBefore ¶
InsertBefore inserts elems before the first element where f returns true. Does nothing if f returns false for all elements.
Example ¶
package main
import (
"github.com/sanity-io/litter"
p "github.com/mcecode/gemtext-parser"
)
var dumper = litter.Options{StripPackageNames: true, HidePrivateFields: false}
func main() {
asl := p.NewASL(
p.NewHeading("Some Heading", p.HeadingLevels.Heading()),
p.NewText("Some text..."),
p.NewLink("Some link", "gemini://example.org"),
)
asl.InsertBefore(
[]p.Element{p.NewQuote("Some quote")},
func(e p.Element) bool {
if e.Type() == p.ElementTypes.Text() {
return true
}
return false
},
)
dumper.Dump(asl)
}
Output: ASL{ elems: []Element{ Heading{ text: "Some Heading", level: headingLevel{ value: 1, }, }, Quote{ text: "Some quote", }, Text{ text: "Some text...", }, Link{ text: "Some link", url: "gemini://example.org", }, }, }
func (*ASL) InsertFirst ¶
InsertFirst inserts elems at the start of the list.
Example ¶
package main
import (
"github.com/sanity-io/litter"
p "github.com/mcecode/gemtext-parser"
)
var dumper = litter.Options{StripPackageNames: true, HidePrivateFields: false}
func main() {
asl := p.NewASL(p.NewText("Some text..."))
asl.InsertFirst(
p.NewHeading("Some Heading", p.HeadingLevels.Heading()),
p.NewText(""),
)
dumper.Dump(asl)
}
Output: ASL{ elems: []Element{ Heading{ text: "Some Heading", level: headingLevel{ value: 1, }, }, Text{ text: "", }, Text{ text: "Some text...", }, }, }
func (*ASL) InsertLast ¶
InsertLast inserts elems at the end of the list.
Example ¶
package main
import (
"github.com/sanity-io/litter"
p "github.com/mcecode/gemtext-parser"
)
var dumper = litter.Options{StripPackageNames: true, HidePrivateFields: false}
func main() {
asl := p.NewASL(p.NewText("Some text..."))
asl.InsertLast(
p.NewText(""),
p.NewLink("Some link", "gemini://example.org"),
)
dumper.Dump(asl)
}
Output: ASL{ elems: []Element{ Text{ text: "Some text...", }, Text{ text: "", }, Link{ text: "Some link", url: "gemini://example.org", }, }, }
func (*ASL) Replace ¶
Replace replaces the first element where f returns true with elems. Does nothing if f returns false for all elements.
Example ¶
package main
import (
"github.com/sanity-io/litter"
p "github.com/mcecode/gemtext-parser"
)
var dumper = litter.Options{StripPackageNames: true, HidePrivateFields: false}
func main() {
asl := p.NewASL(
p.NewHeading("Some Heading", p.HeadingLevels.Heading()),
p.NewText("Some text..."),
p.NewLink("Some link", "gemini://example.org"),
)
asl.Replace(
[]p.Element{p.NewText("Some other text...")},
func(e p.Element) bool {
if e.Type() == p.ElementTypes.Text() {
return true
}
return false
},
)
dumper.Dump(asl)
}
Output: ASL{ elems: []Element{ Heading{ text: "Some Heading", level: headingLevel{ value: 1, }, }, Text{ text: "Some other text...", }, Link{ text: "Some link", url: "gemini://example.org", }, }, }
func (*ASL) Visit ¶
Visit iterates over all elements that asl has, passing each element to f.
Example ¶
package main
import (
"fmt"
p "github.com/mcecode/gemtext-parser"
)
func main() {
asl := p.NewASL(
p.NewHeading("Some Heading", p.HeadingLevels.Heading()),
p.NewText("Some text..."),
p.NewLink("Some link", "gemini://example.org"),
)
asl.Visit(func(e p.Element) {
fmt.Printf("Got a %s!\n", e.Type().Name())
})
}
Output: Got a Heading! Got a Text! Got a Link!
type Element ¶
Element is the interface that all elements implement. It represents an abstraction of the different gemtext line types.
Type() returns the type of the element. It can be compared with ElementTypes:
func example(e p.Element) {
if e.Type() == p.ElementTypes.Text() {
// Do something
}
}
Text() returns any text associated with the element. For Text, Heading, List, and Quote, it returns the main text of the element. For Link, it returns the user-friendly link name. For PreformatToggle, it returns the alt text.
URL() returns a URL associated with the element. Only Link actually returns a URL, other elements will return an empty string.
Level() returns the heading level associated with the element. Only Heading actually returns a heading level, other elements will return HeadingLevels.NotHeading(). It can be compared with HeadingLevels:
func example(h p.Heading) {
if h.Level() == p.HeadingLevels.Heading() {
// Do something
}
}
type Heading ¶
type Heading struct {
// contains filtered or unexported fields
}
Heading represents a heading line.
func NewHeading ¶
Example ¶
package main
import (
"fmt"
p "github.com/mcecode/gemtext-parser"
)
func main() {
h := p.NewHeading("Example Heading", p.HeadingLevels.SubHeading())
fmt.Println(h.Type().Name())
fmt.Println(h.Text())
fmt.Println(h.Level().Value())
}
Output: Heading Example Heading 2
type Link ¶
type Link struct {
// contains filtered or unexported fields
}
Link represents a link line.
type List ¶
type List struct {
// contains filtered or unexported fields
}
List represents a list item.
type PreformatToggle ¶
type PreformatToggle struct {
// contains filtered or unexported fields
}
PreformatToggle represents a preformat toggle line.
func NewPreformatToggle ¶
func NewPreformatToggle(text string) PreformatToggle
Example ¶
package main
import (
"fmt"
p "github.com/mcecode/gemtext-parser"
)
func main() {
pt := p.NewPreformatToggle("Example Alt Text")
fmt.Println(pt.Type().Name())
fmt.Println(pt.Text())
}
Output: PreformatToggle Example Alt Text
func (PreformatToggle) Level ¶
func (pt PreformatToggle) Level() headingLevel
func (PreformatToggle) Text ¶
func (pt PreformatToggle) Text() string
func (PreformatToggle) Type ¶
func (pt PreformatToggle) Type() elementType
func (PreformatToggle) URL ¶
func (pt PreformatToggle) URL() string
type Quote ¶
type Quote struct {
// contains filtered or unexported fields
}
Quote represents a quote line.
type Text ¶
type Text struct {
// contains filtered or unexported fields
}
Text represents a text line.