vendor/github.com/russross/blackfriday/markdown.go
author Mikael Berthe <mikael@lilotux.net>
Sun, 16 Feb 2020 18:54:01 +0100
changeset 251 1c52a0eeb952
permissions -rw-r--r--
Update dependencies This should fix #22.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
// Blackfriday Markdown Processor
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
// Available at http://github.com/russross/blackfriday
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
// Copyright © 2011 Russ Ross <russ@russross.com>.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
// Distributed under the Simplified BSD License.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
// See README.md for details.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
// Markdown parsing and processing
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    14
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
package blackfriday
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
import (
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
	"bytes"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
	"fmt"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
	"strings"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    22
	"unicode/utf8"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    23
)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    25
const VERSION = "1.5"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    26
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    27
// These are the supported markdown parsing extensions.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
// OR these values together to select multiple extensions.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
const (
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
	EXTENSION_NO_INTRA_EMPHASIS          = 1 << iota // ignore emphasis markers inside words
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
	EXTENSION_TABLES                                 // render tables
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
	EXTENSION_FENCED_CODE                            // render fenced code blocks
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
	EXTENSION_AUTOLINK                               // detect embedded URLs that are not explicitly marked
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
	EXTENSION_STRIKETHROUGH                          // strikethrough text using ~~test~~
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
	EXTENSION_LAX_HTML_BLOCKS                        // loosen up HTML block parsing rules
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    36
	EXTENSION_SPACE_HEADERS                          // be strict about prefix header rules
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    37
	EXTENSION_HARD_LINE_BREAK                        // translate newlines into line breaks
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    38
	EXTENSION_TAB_SIZE_EIGHT                         // expand tabs to eight spaces instead of four
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    39
	EXTENSION_FOOTNOTES                              // Pandoc-style footnotes
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
	EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK             // No need to insert an empty line to start a (code, quote, ordered list, unordered list) block
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
	EXTENSION_HEADER_IDS                             // specify header IDs  with {#id}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
	EXTENSION_TITLEBLOCK                             // Titleblock ala pandoc
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
	EXTENSION_AUTO_HEADER_IDS                        // Create the header ID from the text
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
	EXTENSION_BACKSLASH_LINE_BREAK                   // translate trailing backslashes into line breaks
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
	EXTENSION_DEFINITION_LISTS                       // render definition lists
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    46
	EXTENSION_JOIN_LINES                             // delete newline and join lines
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    47
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    48
	commonHtmlFlags = 0 |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    49
		HTML_USE_XHTML |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
		HTML_USE_SMARTYPANTS |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
		HTML_SMARTYPANTS_FRACTIONS |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
		HTML_SMARTYPANTS_DASHES |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
		HTML_SMARTYPANTS_LATEX_DASHES
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    55
	commonExtensions = 0 |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    56
		EXTENSION_NO_INTRA_EMPHASIS |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
		EXTENSION_TABLES |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
		EXTENSION_FENCED_CODE |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
		EXTENSION_AUTOLINK |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    60
		EXTENSION_STRIKETHROUGH |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
		EXTENSION_SPACE_HEADERS |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
		EXTENSION_HEADER_IDS |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
		EXTENSION_BACKSLASH_LINE_BREAK |
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
		EXTENSION_DEFINITION_LISTS
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
// These are the possible flag values for the link renderer.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
// Only a single one of these values will be used; they are not ORed together.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
// These are mostly of interest if you are writing a new output format.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
const (
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
	LINK_TYPE_NOT_AUTOLINK = iota
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
	LINK_TYPE_NORMAL
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
	LINK_TYPE_EMAIL
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
// These are the possible flag values for the ListItem renderer.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
// Multiple flag values may be ORed together.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
// These are mostly of interest if you are writing a new output format.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
const (
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
	LIST_TYPE_ORDERED = 1 << iota
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
	LIST_TYPE_DEFINITION
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
	LIST_TYPE_TERM
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
	LIST_ITEM_CONTAINS_BLOCK
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
	LIST_ITEM_BEGINNING_OF_LIST
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
	LIST_ITEM_END_OF_LIST
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
// These are the possible flag values for the table cell renderer.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
// Only a single one of these values will be used; they are not ORed together.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
// These are mostly of interest if you are writing a new output format.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
const (
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
	TABLE_ALIGNMENT_LEFT = 1 << iota
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
	TABLE_ALIGNMENT_RIGHT
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
	TABLE_ALIGNMENT_CENTER = (TABLE_ALIGNMENT_LEFT | TABLE_ALIGNMENT_RIGHT)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
// The size of a tab stop.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
const (
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
	TAB_SIZE_DEFAULT = 4
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   100
	TAB_SIZE_EIGHT   = 8
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
// blockTags is a set of tags that are recognized as HTML block tags.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
// Any of these can be included in markdown text without special escaping.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   105
var blockTags = map[string]struct{}{
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
	"blockquote": {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
	"del":        {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
	"div":        {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
	"dl":         {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   110
	"fieldset":   {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
	"form":       {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
	"h1":         {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
	"h2":         {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
	"h3":         {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
	"h4":         {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
	"h5":         {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
	"h6":         {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
	"iframe":     {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
	"ins":        {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   120
	"math":       {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   121
	"noscript":   {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
	"ol":         {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
	"pre":        {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   124
	"p":          {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   125
	"script":     {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   126
	"style":      {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   127
	"table":      {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
	"ul":         {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
	// HTML5
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
	"address":    {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   132
	"article":    {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
	"aside":      {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
	"canvas":     {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
	"figcaption": {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
	"figure":     {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
	"footer":     {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
	"header":     {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
	"hgroup":     {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
	"main":       {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
	"nav":        {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
	"output":     {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
	"progress":   {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
	"section":    {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
	"video":      {},
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   146
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   147
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   148
// Renderer is the rendering interface.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   149
// This is mostly of interest if you are implementing a new rendering format.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   150
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   151
// When a byte slice is provided, it contains the (rendered) contents of the
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   152
// element.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   153
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   154
// When a callback is provided instead, it will write the contents of the
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   155
// respective element directly to the output buffer and return true on success.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   156
// If the callback returns false, the rendering function should reset the
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   157
// output buffer as though it had never been called.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   158
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   159
// Currently Html and Latex implementations are provided
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   160
type Renderer interface {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   161
	// block-level callbacks
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   162
	BlockCode(out *bytes.Buffer, text []byte, infoString string)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   163
	BlockQuote(out *bytes.Buffer, text []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   164
	BlockHtml(out *bytes.Buffer, text []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   165
	Header(out *bytes.Buffer, text func() bool, level int, id string)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   166
	HRule(out *bytes.Buffer)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   167
	List(out *bytes.Buffer, text func() bool, flags int)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   168
	ListItem(out *bytes.Buffer, text []byte, flags int)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   169
	Paragraph(out *bytes.Buffer, text func() bool)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   170
	Table(out *bytes.Buffer, header []byte, body []byte, columnData []int)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   171
	TableRow(out *bytes.Buffer, text []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   172
	TableHeaderCell(out *bytes.Buffer, text []byte, flags int)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   173
	TableCell(out *bytes.Buffer, text []byte, flags int)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   174
	Footnotes(out *bytes.Buffer, text func() bool)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   175
	FootnoteItem(out *bytes.Buffer, name, text []byte, flags int)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   176
	TitleBlock(out *bytes.Buffer, text []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   177
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   178
	// Span-level callbacks
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   179
	AutoLink(out *bytes.Buffer, link []byte, kind int)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   180
	CodeSpan(out *bytes.Buffer, text []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   181
	DoubleEmphasis(out *bytes.Buffer, text []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   182
	Emphasis(out *bytes.Buffer, text []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   183
	Image(out *bytes.Buffer, link []byte, title []byte, alt []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   184
	LineBreak(out *bytes.Buffer)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   185
	Link(out *bytes.Buffer, link []byte, title []byte, content []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   186
	RawHtmlTag(out *bytes.Buffer, tag []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   187
	TripleEmphasis(out *bytes.Buffer, text []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   188
	StrikeThrough(out *bytes.Buffer, text []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   189
	FootnoteRef(out *bytes.Buffer, ref []byte, id int)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   190
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   191
	// Low-level callbacks
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   192
	Entity(out *bytes.Buffer, entity []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   193
	NormalText(out *bytes.Buffer, text []byte)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   194
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   195
	// Header and footer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   196
	DocumentHeader(out *bytes.Buffer)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   197
	DocumentFooter(out *bytes.Buffer)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   198
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   199
	GetFlags() int
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   200
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   201
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   202
// Callback functions for inline parsing. One such function is defined
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   203
// for each character that triggers a response when parsing inline data.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   204
type inlineParser func(p *parser, out *bytes.Buffer, data []byte, offset int) int
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   205
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   206
// Parser holds runtime state used by the parser.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   207
// This is constructed by the Markdown function.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   208
type parser struct {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   209
	r              Renderer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   210
	refOverride    ReferenceOverrideFunc
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   211
	refs           map[string]*reference
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   212
	inlineCallback [256]inlineParser
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   213
	flags          int
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   214
	nesting        int
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   215
	maxNesting     int
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   216
	insideLink     bool
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   217
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   218
	// Footnotes need to be ordered as well as available to quickly check for
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   219
	// presence. If a ref is also a footnote, it's stored both in refs and here
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   220
	// in notes. Slice is nil if footnotes not enabled.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   221
	notes       []*reference
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   222
	notesRecord map[string]struct{}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   223
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   224
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   225
func (p *parser) getRef(refid string) (ref *reference, found bool) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   226
	if p.refOverride != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   227
		r, overridden := p.refOverride(refid)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   228
		if overridden {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   229
			if r == nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   230
				return nil, false
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   231
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   232
			return &reference{
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   233
				link:     []byte(r.Link),
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   234
				title:    []byte(r.Title),
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   235
				noteId:   0,
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   236
				hasBlock: false,
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   237
				text:     []byte(r.Text)}, true
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   238
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   239
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   240
	// refs are case insensitive
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   241
	ref, found = p.refs[strings.ToLower(refid)]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   242
	return ref, found
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   243
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   244
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   245
func (p *parser) isFootnote(ref *reference) bool {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   246
	_, ok := p.notesRecord[string(ref.link)]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   247
	return ok
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   248
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   249
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   250
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   251
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   252
// Public interface
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   253
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   254
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   255
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   256
// Reference represents the details of a link.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   257
// See the documentation in Options for more details on use-case.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   258
type Reference struct {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   259
	// Link is usually the URL the reference points to.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   260
	Link string
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   261
	// Title is the alternate text describing the link in more detail.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   262
	Title string
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   263
	// Text is the optional text to override the ref with if the syntax used was
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   264
	// [refid][]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   265
	Text string
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   266
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   267
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   268
// ReferenceOverrideFunc is expected to be called with a reference string and
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   269
// return either a valid Reference type that the reference string maps to or
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   270
// nil. If overridden is false, the default reference logic will be executed.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   271
// See the documentation in Options for more details on use-case.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   272
type ReferenceOverrideFunc func(reference string) (ref *Reference, overridden bool)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   273
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   274
// Options represents configurable overrides and callbacks (in addition to the
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   275
// extension flag set) for configuring a Markdown parse.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   276
type Options struct {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   277
	// Extensions is a flag set of bit-wise ORed extension bits. See the
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   278
	// EXTENSION_* flags defined in this package.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   279
	Extensions int
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   280
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   281
	// ReferenceOverride is an optional function callback that is called every
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   282
	// time a reference is resolved.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   283
	//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   284
	// In Markdown, the link reference syntax can be made to resolve a link to
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   285
	// a reference instead of an inline URL, in one of the following ways:
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   286
	//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   287
	//  * [link text][refid]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   288
	//  * [refid][]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   289
	//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   290
	// Usually, the refid is defined at the bottom of the Markdown document. If
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   291
	// this override function is provided, the refid is passed to the override
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   292
	// function first, before consulting the defined refids at the bottom. If
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   293
	// the override function indicates an override did not occur, the refids at
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   294
	// the bottom will be used to fill in the link details.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   295
	ReferenceOverride ReferenceOverrideFunc
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   296
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   297
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   298
// MarkdownBasic is a convenience function for simple rendering.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   299
// It processes markdown input with no extensions enabled.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   300
func MarkdownBasic(input []byte) []byte {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   301
	// set up the HTML renderer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   302
	htmlFlags := HTML_USE_XHTML
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   303
	renderer := HtmlRenderer(htmlFlags, "", "")
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   304
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   305
	// set up the parser
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   306
	return MarkdownOptions(input, renderer, Options{Extensions: 0})
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   307
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   308
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   309
// Call Markdown with most useful extensions enabled
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   310
// MarkdownCommon is a convenience function for simple rendering.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   311
// It processes markdown input with common extensions enabled, including:
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   312
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   313
// * Smartypants processing with smart fractions and LaTeX dashes
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   314
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   315
// * Intra-word emphasis suppression
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   316
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   317
// * Tables
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   318
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   319
// * Fenced code blocks
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   320
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   321
// * Autolinking
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   322
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   323
// * Strikethrough support
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   324
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   325
// * Strict header parsing
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   326
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   327
// * Custom Header IDs
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   328
func MarkdownCommon(input []byte) []byte {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   329
	// set up the HTML renderer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   330
	renderer := HtmlRenderer(commonHtmlFlags, "", "")
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   331
	return MarkdownOptions(input, renderer, Options{
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   332
		Extensions: commonExtensions})
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   333
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   334
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   335
// Markdown is the main rendering function.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   336
// It parses and renders a block of markdown-encoded text.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   337
// The supplied Renderer is used to format the output, and extensions dictates
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   338
// which non-standard extensions are enabled.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   339
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   340
// To use the supplied Html or LaTeX renderers, see HtmlRenderer and
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   341
// LatexRenderer, respectively.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   342
func Markdown(input []byte, renderer Renderer, extensions int) []byte {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   343
	return MarkdownOptions(input, renderer, Options{
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   344
		Extensions: extensions})
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   345
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   346
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   347
// MarkdownOptions is just like Markdown but takes additional options through
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   348
// the Options struct.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   349
func MarkdownOptions(input []byte, renderer Renderer, opts Options) []byte {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   350
	// no point in parsing if we can't render
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   351
	if renderer == nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   352
		return nil
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   353
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   354
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   355
	extensions := opts.Extensions
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   356
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   357
	// fill in the render structure
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   358
	p := new(parser)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   359
	p.r = renderer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   360
	p.flags = extensions
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   361
	p.refOverride = opts.ReferenceOverride
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   362
	p.refs = make(map[string]*reference)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   363
	p.maxNesting = 16
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   364
	p.insideLink = false
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   365
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   366
	// register inline parsers
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   367
	p.inlineCallback['*'] = emphasis
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   368
	p.inlineCallback['_'] = emphasis
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   369
	if extensions&EXTENSION_STRIKETHROUGH != 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   370
		p.inlineCallback['~'] = emphasis
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   371
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   372
	p.inlineCallback['`'] = codeSpan
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   373
	p.inlineCallback['\n'] = lineBreak
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   374
	p.inlineCallback['['] = link
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   375
	p.inlineCallback['<'] = leftAngle
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   376
	p.inlineCallback['\\'] = escape
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   377
	p.inlineCallback['&'] = entity
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   378
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   379
	if extensions&EXTENSION_AUTOLINK != 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   380
		p.inlineCallback[':'] = autoLink
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   381
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   382
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   383
	if extensions&EXTENSION_FOOTNOTES != 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   384
		p.notes = make([]*reference, 0)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   385
		p.notesRecord = make(map[string]struct{})
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   386
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   387
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   388
	first := firstPass(p, input)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   389
	second := secondPass(p, first)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   390
	return second
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   391
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   392
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   393
// first pass:
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   394
// - normalize newlines
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   395
// - extract references (outside of fenced code blocks)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   396
// - expand tabs (outside of fenced code blocks)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   397
// - copy everything else
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   398
func firstPass(p *parser, input []byte) []byte {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   399
	var out bytes.Buffer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   400
	tabSize := TAB_SIZE_DEFAULT
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   401
	if p.flags&EXTENSION_TAB_SIZE_EIGHT != 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   402
		tabSize = TAB_SIZE_EIGHT
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   403
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   404
	beg := 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   405
	lastFencedCodeBlockEnd := 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   406
	for beg < len(input) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   407
		// Find end of this line, then process the line.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   408
		end := beg
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   409
		for end < len(input) && input[end] != '\n' && input[end] != '\r' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   410
			end++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   411
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   412
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   413
		if p.flags&EXTENSION_FENCED_CODE != 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   414
			// track fenced code block boundaries to suppress tab expansion
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   415
			// and reference extraction inside them:
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   416
			if beg >= lastFencedCodeBlockEnd {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   417
				if i := p.fencedCodeBlock(&out, input[beg:], false); i > 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   418
					lastFencedCodeBlockEnd = beg + i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   419
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   420
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   421
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   422
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   423
		// add the line body if present
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   424
		if end > beg {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   425
			if end < lastFencedCodeBlockEnd { // Do not expand tabs while inside fenced code blocks.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   426
				out.Write(input[beg:end])
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   427
			} else if refEnd := isReference(p, input[beg:], tabSize); refEnd > 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   428
				beg += refEnd
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   429
				continue
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   430
			} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   431
				expandTabs(&out, input[beg:end], tabSize)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   432
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   433
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   434
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   435
		if end < len(input) && input[end] == '\r' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   436
			end++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   437
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   438
		if end < len(input) && input[end] == '\n' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   439
			end++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   440
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   441
		out.WriteByte('\n')
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   442
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   443
		beg = end
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   444
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   445
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   446
	// empty input?
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   447
	if out.Len() == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   448
		out.WriteByte('\n')
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   449
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   450
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   451
	return out.Bytes()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   452
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   453
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   454
// second pass: actual rendering
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   455
func secondPass(p *parser, input []byte) []byte {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   456
	var output bytes.Buffer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   457
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   458
	p.r.DocumentHeader(&output)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   459
	p.block(&output, input)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   460
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   461
	if p.flags&EXTENSION_FOOTNOTES != 0 && len(p.notes) > 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   462
		p.r.Footnotes(&output, func() bool {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   463
			flags := LIST_ITEM_BEGINNING_OF_LIST
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   464
			for i := 0; i < len(p.notes); i += 1 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   465
				ref := p.notes[i]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   466
				var buf bytes.Buffer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   467
				if ref.hasBlock {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   468
					flags |= LIST_ITEM_CONTAINS_BLOCK
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   469
					p.block(&buf, ref.title)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   470
				} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   471
					p.inline(&buf, ref.title)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   472
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   473
				p.r.FootnoteItem(&output, ref.link, buf.Bytes(), flags)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   474
				flags &^= LIST_ITEM_BEGINNING_OF_LIST | LIST_ITEM_CONTAINS_BLOCK
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   475
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   476
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   477
			return true
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   478
		})
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   479
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   480
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   481
	p.r.DocumentFooter(&output)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   482
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   483
	if p.nesting != 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   484
		panic("Nesting level did not end at zero")
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   485
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   486
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   487
	return output.Bytes()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   488
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   489
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   490
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   491
// Link references
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   492
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   493
// This section implements support for references that (usually) appear
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   494
// as footnotes in a document, and can be referenced anywhere in the document.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   495
// The basic format is:
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   496
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   497
//    [1]: http://www.google.com/ "Google"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   498
//    [2]: http://www.github.com/ "Github"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   499
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   500
// Anywhere in the document, the reference can be linked by referring to its
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   501
// label, i.e., 1 and 2 in this example, as in:
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   502
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   503
//    This library is hosted on [Github][2], a git hosting site.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   504
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   505
// Actual footnotes as specified in Pandoc and supported by some other Markdown
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   506
// libraries such as php-markdown are also taken care of. They look like this:
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   507
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   508
//    This sentence needs a bit of further explanation.[^note]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   509
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   510
//    [^note]: This is the explanation.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   511
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   512
// Footnotes should be placed at the end of the document in an ordered list.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   513
// Inline footnotes such as:
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   514
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   515
//    Inline footnotes^[Not supported.] also exist.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   516
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   517
// are not yet supported.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   518
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   519
// References are parsed and stored in this struct.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   520
type reference struct {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   521
	link     []byte
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   522
	title    []byte
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   523
	noteId   int // 0 if not a footnote ref
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   524
	hasBlock bool
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   525
	text     []byte
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   526
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   527
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   528
func (r *reference) String() string {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   529
	return fmt.Sprintf("{link: %q, title: %q, text: %q, noteId: %d, hasBlock: %v}",
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   530
		r.link, r.title, r.text, r.noteId, r.hasBlock)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   531
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   532
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   533
// Check whether or not data starts with a reference link.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   534
// If so, it is parsed and stored in the list of references
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   535
// (in the render struct).
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   536
// Returns the number of bytes to skip to move past it,
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   537
// or zero if the first line is not a reference.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   538
func isReference(p *parser, data []byte, tabSize int) int {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   539
	// up to 3 optional leading spaces
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   540
	if len(data) < 4 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   541
		return 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   542
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   543
	i := 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   544
	for i < 3 && data[i] == ' ' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   545
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   546
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   547
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   548
	noteId := 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   549
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   550
	// id part: anything but a newline between brackets
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   551
	if data[i] != '[' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   552
		return 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   553
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   554
	i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   555
	if p.flags&EXTENSION_FOOTNOTES != 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   556
		if i < len(data) && data[i] == '^' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   557
			// we can set it to anything here because the proper noteIds will
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   558
			// be assigned later during the second pass. It just has to be != 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   559
			noteId = 1
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   560
			i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   561
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   562
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   563
	idOffset := i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   564
	for i < len(data) && data[i] != '\n' && data[i] != '\r' && data[i] != ']' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   565
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   566
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   567
	if i >= len(data) || data[i] != ']' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   568
		return 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   569
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   570
	idEnd := i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   571
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   572
	// spacer: colon (space | tab)* newline? (space | tab)*
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   573
	i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   574
	if i >= len(data) || data[i] != ':' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   575
		return 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   576
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   577
	i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   578
	for i < len(data) && (data[i] == ' ' || data[i] == '\t') {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   579
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   580
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   581
	if i < len(data) && (data[i] == '\n' || data[i] == '\r') {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   582
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   583
		if i < len(data) && data[i] == '\n' && data[i-1] == '\r' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   584
			i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   585
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   586
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   587
	for i < len(data) && (data[i] == ' ' || data[i] == '\t') {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   588
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   589
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   590
	if i >= len(data) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   591
		return 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   592
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   593
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   594
	var (
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   595
		linkOffset, linkEnd   int
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   596
		titleOffset, titleEnd int
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   597
		lineEnd               int
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   598
		raw                   []byte
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   599
		hasBlock              bool
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   600
	)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   601
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   602
	if p.flags&EXTENSION_FOOTNOTES != 0 && noteId != 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   603
		linkOffset, linkEnd, raw, hasBlock = scanFootnote(p, data, i, tabSize)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   604
		lineEnd = linkEnd
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   605
	} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   606
		linkOffset, linkEnd, titleOffset, titleEnd, lineEnd = scanLinkRef(p, data, i)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   607
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   608
	if lineEnd == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   609
		return 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   610
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   611
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   612
	// a valid ref has been found
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   613
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   614
	ref := &reference{
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   615
		noteId:   noteId,
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   616
		hasBlock: hasBlock,
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   617
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   618
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   619
	if noteId > 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   620
		// reusing the link field for the id since footnotes don't have links
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   621
		ref.link = data[idOffset:idEnd]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   622
		// if footnote, it's not really a title, it's the contained text
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   623
		ref.title = raw
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   624
	} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   625
		ref.link = data[linkOffset:linkEnd]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   626
		ref.title = data[titleOffset:titleEnd]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   627
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   628
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   629
	// id matches are case-insensitive
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   630
	id := string(bytes.ToLower(data[idOffset:idEnd]))
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   631
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   632
	p.refs[id] = ref
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   633
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   634
	return lineEnd
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   635
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   636
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   637
func scanLinkRef(p *parser, data []byte, i int) (linkOffset, linkEnd, titleOffset, titleEnd, lineEnd int) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   638
	// link: whitespace-free sequence, optionally between angle brackets
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   639
	if data[i] == '<' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   640
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   641
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   642
	linkOffset = i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   643
	if i == len(data) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   644
		return
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   645
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   646
	for i < len(data) && data[i] != ' ' && data[i] != '\t' && data[i] != '\n' && data[i] != '\r' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   647
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   648
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   649
	linkEnd = i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   650
	if data[linkOffset] == '<' && data[linkEnd-1] == '>' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   651
		linkOffset++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   652
		linkEnd--
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   653
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   654
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   655
	// optional spacer: (space | tab)* (newline | '\'' | '"' | '(' )
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   656
	for i < len(data) && (data[i] == ' ' || data[i] == '\t') {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   657
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   658
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   659
	if i < len(data) && data[i] != '\n' && data[i] != '\r' && data[i] != '\'' && data[i] != '"' && data[i] != '(' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   660
		return
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   661
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   662
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   663
	// compute end-of-line
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   664
	if i >= len(data) || data[i] == '\r' || data[i] == '\n' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   665
		lineEnd = i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   666
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   667
	if i+1 < len(data) && data[i] == '\r' && data[i+1] == '\n' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   668
		lineEnd++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   669
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   670
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   671
	// optional (space|tab)* spacer after a newline
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   672
	if lineEnd > 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   673
		i = lineEnd + 1
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   674
		for i < len(data) && (data[i] == ' ' || data[i] == '\t') {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   675
			i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   676
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   677
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   678
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   679
	// optional title: any non-newline sequence enclosed in '"() alone on its line
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   680
	if i+1 < len(data) && (data[i] == '\'' || data[i] == '"' || data[i] == '(') {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   681
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   682
		titleOffset = i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   683
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   684
		// look for EOL
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   685
		for i < len(data) && data[i] != '\n' && data[i] != '\r' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   686
			i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   687
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   688
		if i+1 < len(data) && data[i] == '\n' && data[i+1] == '\r' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   689
			titleEnd = i + 1
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   690
		} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   691
			titleEnd = i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   692
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   693
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   694
		// step back
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   695
		i--
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   696
		for i > titleOffset && (data[i] == ' ' || data[i] == '\t') {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   697
			i--
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   698
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   699
		if i > titleOffset && (data[i] == '\'' || data[i] == '"' || data[i] == ')') {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   700
			lineEnd = titleEnd
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   701
			titleEnd = i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   702
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   703
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   704
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   705
	return
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   706
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   707
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   708
// The first bit of this logic is the same as (*parser).listItem, but the rest
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   709
// is much simpler. This function simply finds the entire block and shifts it
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   710
// over by one tab if it is indeed a block (just returns the line if it's not).
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   711
// blockEnd is the end of the section in the input buffer, and contents is the
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   712
// extracted text that was shifted over one tab. It will need to be rendered at
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   713
// the end of the document.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   714
func scanFootnote(p *parser, data []byte, i, indentSize int) (blockStart, blockEnd int, contents []byte, hasBlock bool) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   715
	if i == 0 || len(data) == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   716
		return
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   717
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   718
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   719
	// skip leading whitespace on first line
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   720
	for i < len(data) && data[i] == ' ' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   721
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   722
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   723
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   724
	blockStart = i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   725
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   726
	// find the end of the line
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   727
	blockEnd = i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   728
	for i < len(data) && data[i-1] != '\n' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   729
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   730
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   731
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   732
	// get working buffer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   733
	var raw bytes.Buffer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   734
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   735
	// put the first line into the working buffer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   736
	raw.Write(data[blockEnd:i])
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   737
	blockEnd = i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   738
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   739
	// process the following lines
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   740
	containsBlankLine := false
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   741
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   742
gatherLines:
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   743
	for blockEnd < len(data) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   744
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   745
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   746
		// find the end of this line
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   747
		for i < len(data) && data[i-1] != '\n' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   748
			i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   749
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   750
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   751
		// if it is an empty line, guess that it is part of this item
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   752
		// and move on to the next line
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   753
		if p.isEmpty(data[blockEnd:i]) > 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   754
			containsBlankLine = true
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   755
			blockEnd = i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   756
			continue
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   757
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   758
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   759
		n := 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   760
		if n = isIndented(data[blockEnd:i], indentSize); n == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   761
			// this is the end of the block.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   762
			// we don't want to include this last line in the index.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   763
			break gatherLines
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   764
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   765
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   766
		// if there were blank lines before this one, insert a new one now
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   767
		if containsBlankLine {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   768
			raw.WriteByte('\n')
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   769
			containsBlankLine = false
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   770
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   771
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   772
		// get rid of that first tab, write to buffer
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   773
		raw.Write(data[blockEnd+n : i])
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   774
		hasBlock = true
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   775
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   776
		blockEnd = i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   777
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   778
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   779
	if data[blockEnd-1] != '\n' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   780
		raw.WriteByte('\n')
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   781
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   782
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   783
	contents = raw.Bytes()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   784
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   785
	return
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   786
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   787
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   788
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   789
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   790
// Miscellaneous helper functions
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   791
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   792
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   793
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   794
// Test if a character is a punctuation symbol.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   795
// Taken from a private function in regexp in the stdlib.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   796
func ispunct(c byte) bool {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   797
	for _, r := range []byte("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~") {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   798
		if c == r {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   799
			return true
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   800
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   801
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   802
	return false
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   803
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   804
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   805
// Test if a character is a whitespace character.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   806
func isspace(c byte) bool {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   807
	return ishorizontalspace(c) || isverticalspace(c)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   808
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   809
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   810
// Test if a character is a horizontal whitespace character.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   811
func ishorizontalspace(c byte) bool {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   812
	return c == ' ' || c == '\t'
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   813
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   814
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   815
// Test if a character is a vertical whitespace character.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   816
func isverticalspace(c byte) bool {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   817
	return c == '\n' || c == '\r' || c == '\f' || c == '\v'
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   818
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   819
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   820
// Test if a character is letter.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   821
func isletter(c byte) bool {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   822
	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   823
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   824
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   825
// Test if a character is a letter or a digit.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   826
// TODO: check when this is looking for ASCII alnum and when it should use unicode
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   827
func isalnum(c byte) bool {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   828
	return (c >= '0' && c <= '9') || isletter(c)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   829
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   830
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   831
// Replace tab characters with spaces, aligning to the next TAB_SIZE column.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   832
// always ends output with a newline
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   833
func expandTabs(out *bytes.Buffer, line []byte, tabSize int) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   834
	// first, check for common cases: no tabs, or only tabs at beginning of line
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   835
	i, prefix := 0, 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   836
	slowcase := false
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   837
	for i = 0; i < len(line); i++ {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   838
		if line[i] == '\t' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   839
			if prefix == i {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   840
				prefix++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   841
			} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   842
				slowcase = true
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   843
				break
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   844
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   845
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   846
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   847
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   848
	// no need to decode runes if all tabs are at the beginning of the line
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   849
	if !slowcase {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   850
		for i = 0; i < prefix*tabSize; i++ {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   851
			out.WriteByte(' ')
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   852
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   853
		out.Write(line[prefix:])
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   854
		return
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   855
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   856
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   857
	// the slow case: we need to count runes to figure out how
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   858
	// many spaces to insert for each tab
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   859
	column := 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   860
	i = 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   861
	for i < len(line) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   862
		start := i
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   863
		for i < len(line) && line[i] != '\t' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   864
			_, size := utf8.DecodeRune(line[i:])
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   865
			i += size
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   866
			column++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   867
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   868
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   869
		if i > start {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   870
			out.Write(line[start:i])
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   871
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   872
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   873
		if i >= len(line) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   874
			break
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   875
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   876
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   877
		for {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   878
			out.WriteByte(' ')
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   879
			column++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   880
			if column%tabSize == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   881
				break
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   882
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   883
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   884
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   885
		i++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   886
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   887
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   888
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   889
// Find if a line counts as indented or not.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   890
// Returns number of characters the indent is (0 = not indented).
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   891
func isIndented(data []byte, indentSize int) int {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   892
	if len(data) == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   893
		return 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   894
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   895
	if data[0] == '\t' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   896
		return 1
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   897
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   898
	if len(data) < indentSize {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   899
		return 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   900
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   901
	for i := 0; i < indentSize; i++ {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   902
		if data[i] != ' ' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   903
			return 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   904
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   905
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   906
	return indentSize
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   907
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   908
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   909
// Create a url-safe slug for fragments
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   910
func slugify(in []byte) []byte {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   911
	if len(in) == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   912
		return in
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   913
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   914
	out := make([]byte, 0, len(in))
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   915
	sym := false
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   916
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   917
	for _, ch := range in {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   918
		if isalnum(ch) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   919
			sym = false
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   920
			out = append(out, ch)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   921
		} else if sym {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   922
			continue
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   923
		} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   924
			out = append(out, '-')
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   925
			sym = true
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   926
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   927
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   928
	var a, b int
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   929
	var ch byte
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   930
	for a, ch = range out {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   931
		if ch != '-' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   932
			break
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   933
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   934
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   935
	for b = len(out) - 1; b > 0; b-- {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   936
		if out[b] != '-' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   937
			break
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   938
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   939
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   940
	return out[a : b+1]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   941
}