markdown

package
v0.4.9 Latest Latest
Warning

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

Go to latest
Published: May 27, 2020 License: AGPL-3.0 Imports: 5 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultSerializer = NewSerializer(map[string]NodeSerializerFunc{
	"blockquote": func(state *SerializerState, node, _parent *model.Node, _index int) {
		state.WrapBlock("> ", nil, node, func() { state.RenderContent(node) })
	},
	"code_block": func(state *SerializerState, node, _parent *model.Node, _index int) {
		params, _ := node.Attrs["params"].(string)
		state.Write("```" + params + "\n")
		state.Text(node.TextContent(), false)
		state.EnsureNewLine()
		state.Write("```")
		state.CloseBlock(node)
	},
	"heading": func(state *SerializerState, node, _parent *model.Node, _index int) {
		level := getAttrInt(node.Attrs, "level", 1)
		state.Write(strings.Repeat("#", level) + " ")
		state.RenderInline(node)
		state.CloseBlock(node)
	},
	"horizontal_rule": func(state *SerializerState, node, _parent *model.Node, _index int) {
		markup := "---"
		if m, ok := node.Attrs["markup"].(string); ok {
			markup = m
		}
		state.Write(markup)
		state.CloseBlock(node)
	},
	"bullet_list": func(state *SerializerState, node, _parent *model.Node, _index int) {
		bullet := "*"
		if b, ok := node.Attrs["bullet"].(string); ok {
			bullet = b
		}
		state.RenderList(node, "  ", func(_ int) string { return bullet + " " })
	},
	"ordered_list": func(state *SerializerState, node, _parent *model.Node, _index int) {
		start := getAttrInt(node.Attrs, "order", 1)
		maxW := len(fmt.Sprintf("%d", start+node.ChildCount()-1))
		space := strings.Repeat(" ", maxW+2)
		state.RenderList(node, space, func(i int) string {
			nStr := fmt.Sprintf("%d", start+i)
			return strings.Repeat(" ", maxW-len(nStr)) + nStr + ". "
		})
	},
	"list_item": func(state *SerializerState, node, _parent *model.Node, _index int) {
		state.RenderContent(node)
	},
	"paragraph": func(state *SerializerState, node, _parent *model.Node, _index int) {
		state.RenderInline(node)
		state.CloseBlock(node)
	},
	"image": func(state *SerializerState, node, _parent *model.Node, _index int) {
		alt, _ := node.Attrs["alt"].(string)
		src, _ := node.Attrs["src"].(string)
		title := ""
		if t, ok := node.Attrs["title"].(string); ok {
			title = state.Quote(t)
		}
		state.Write(fmt.Sprintf("![%s](%s)%s", state.Esc(alt), state.Esc(src), title))
	},
	"hard_break": func(state *SerializerState, node, parent *model.Node, index int) {
		for i := index; i < parent.ChildCount(); i++ {
			if child, err := parent.Child(i); err == nil {
				if child.Type != node.Type {
					state.Write("\\\n")
					return
				}
			}
		}
	},
	"text": func(state *SerializerState, node, _parent *model.Node, _index int) {
		state.Text(*node.Text)
	},
}, map[string]MarkSerializerSpec{
	"em":     {Open: "*", Close: "*", Mixable: true, ExpelEnclosingWhitespace: true},
	"strong": {Open: "**", Close: "**", Mixable: true, ExpelEnclosingWhitespace: true},
	"link": {
		Open: func(_state *SerializerState, mark *model.Mark, parent *model.Node, index int) string {
			if isPlainURL(mark, parent, index, 1) {
				return "<"
			}
			return "["
		},
		Close: func(state *SerializerState, mark *model.Mark, parent *model.Node, index int) string {
			if isPlainURL(mark, parent, index, -1) {
				return ">"
			}
			href, _ := mark.Attrs["href"].(string)
			title, _ := mark.Attrs["title"].(string)
			if title != "" {
				title = " " + state.Quote(title)
			}
			return fmt.Sprintf("](%s%s)", state.Esc(href), title)
		},
	},
	"code": {
		Open: func(_state *SerializerState, _mark *model.Mark, parent *model.Node, index int) string {
			child, err := parent.Child(index)
			if err != nil {
				return "`"
			}
			return backticksFor(child, -1)
		},
		Close: func(_state *SerializerState, _mark *model.Mark, parent *model.Node, index int) string {
			child, err := parent.Child(index - 1)
			if err != nil {
				return "`"
			}
			return backticksFor(child, 1)
		},
		NoEscape: true,
	},
})

DefaultSerializer is a serializer for the [basic schema](#schema).

Functions

This section is empty.

Types

type MarkSerializerSpec

type MarkSerializerSpec struct {
	Open                     interface{} // Can be a string or a func
	Close                    interface{} // Can be a string or a func
	Mixable                  bool
	ExpelEnclosingWhitespace bool
	NoEscape                 bool
}

MarkSerializerSpec is the serializer info for a mark.

type NodeSerializerFunc

type NodeSerializerFunc func(state *SerializerState, node, parent *model.Node, index int)

NodeSerializerFunc is the function to serialize a node.

type Serializer

type Serializer struct {
	Nodes map[string]NodeSerializerFunc
	Marks map[string]MarkSerializerSpec
}

Serializer is a specification for serializing a ProseMirror document as Markdown/CommonMark text.

func NewSerializer

func NewSerializer(nodes map[string]NodeSerializerFunc, marks map[string]MarkSerializerSpec) *Serializer

NewSerializer constructs a serializer with the given configuration. The `nodes` object should map node names in a given schema to function that take a serializer state and such a node, and serialize the node.

The `marks` object should hold objects with `open` and `close` properties, which hold the strings that should appear before and after a piece of text marked that way, either directly or as a function that takes a serializer state and a mark, and returns a string. `open` and `close` can also be functions, which will be called as

(state: MarkdownSerializerState, mark: Mark, parent: Fragment, index:
number) → string

Where `parent` and `index` allow you to inspect the mark's context to see which nodes it applies to.

Mark information objects can also have a `mixable` property which, when `true`, indicates that the order in which the mark's opening and closing syntax appears relative to other mixable marks can be varied. (For example, you can say `**a *b***` and `*a **b***`, but not “ `a *b*` “.)

To disable character escaping in a mark, you can give it an `escape` property of `false`. Such a mark has to have the highest precedence (must always be the innermost mark).

The `expelEnclosingWhitespace` mark property causes the serializer to move enclosing whitespace from inside the marks to outside the marks. This is necessary for emphasis marks as CommonMark does not permit enclosing whitespace inside emphasis marks, see: http://spec.commonmark.org/0.26/#example-330

func (*Serializer) Serialize

func (s *Serializer) Serialize(content *model.Node, options ...map[string]interface{}) string

Serialize the content of the given node to [CommonMark](http://commonmark.org/).

type SerializerState

type SerializerState struct {
	Nodes       map[string]NodeSerializerFunc
	Marks       map[string]MarkSerializerSpec
	Delim       string
	Out         string
	Closed      *model.Node
	InTightList bool
	// contains filtered or unexported fields
}

SerializerState is an object used to track state and expose methods related to markdown serialization. Instances are passed to node and mark serialization methods (see `toMarkdown`).

func NewSerializerState

func NewSerializerState(
	nodes map[string]NodeSerializerFunc,
	marks map[string]MarkSerializerSpec,
	options map[string]interface{},
) *SerializerState

NewSerializerState is the constructor for NewSerializerState.

Options are the options passed to the serializer.

tightLists:: ?bool
Whether to render lists in a tight style. This can be overridden
on a node level by specifying a tight attribute on the node.
Defaults to false.

func (*SerializerState) CloseBlock

func (s *SerializerState) CloseBlock(node *model.Node)

CloseBlock closes the block for the given node.

func (*SerializerState) EnsureNewLine

func (s *SerializerState) EnsureNewLine()

EnsureNewLine ensures the current content ends with a newline.

func (*SerializerState) Esc

func (s *SerializerState) Esc(str string, startOfLine ...bool) string

Esc escapes the given string so that it can safely appear in Markdown content. If `startOfLine` is true, also escape characters that has special meaning only at the start of the line.

func (*SerializerState) MarkString

func (s *SerializerState) MarkString(mark *model.Mark, open bool, parent *model.Node, index int) string

MarkString gets the markdown string for a given opening or closing mark.

func (*SerializerState) Quote

func (s *SerializerState) Quote(str string) string

Quote wraps the string as a quote.

func (*SerializerState) Render

func (s *SerializerState) Render(node, parent *model.Node, index int)

Render the given node as a block.

func (*SerializerState) RenderContent

func (s *SerializerState) RenderContent(parent *model.Node)

RenderContent renders the contents of `parent` as block nodes.

func (*SerializerState) RenderInline

func (s *SerializerState) RenderInline(parent *model.Node)

RenderInline renders the contents of `parent` as inline content.

func (*SerializerState) RenderList

func (s *SerializerState) RenderList(node *model.Node, delim string, firstDelim func(i int) string)

RenderList renders a node's content as a list. `delim` should be the extra indentation added to all lines except the first in an item, `firstDelim` is a function going from an item index to a delimiter for the first line of the item.

func (*SerializerState) Text

func (s *SerializerState) Text(text string, escape ...bool)

Text adds the given text to the document. When escape is not `false`, it will be escaped.

func (*SerializerState) WrapBlock

func (s *SerializerState) WrapBlock(delim string, firstDelim *string, node *model.Node, f func())

WrapBlock renders a block, prefixing each line with `delim`, and the first line in `firstDelim`. `node` should be the node that is closed at the end of the block, and `f` is a function that renders the content of the block.

func (*SerializerState) Write

func (s *SerializerState) Write(content ...string)

Write prepares the state for writing output (closing closed paragraphs, adding delimiters, and so on), and then optionally add content (unescaped) to the output.

Jump to

Keyboard shortcuts

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