node.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. package ast
  2. // An attribute can be attached to block elements. They are specified as
  3. // {#id .classs key="value"} where quotes for values are mandatory, multiple
  4. // key/value pairs are separated by whitespace.
  5. type Attribute struct {
  6. ID []byte
  7. Classes [][]byte
  8. Attrs map[string][]byte
  9. }
  10. // ListType contains bitwise or'ed flags for list and list item objects.
  11. type ListType int
  12. // These are the possible flag values for the ListItem renderer.
  13. // Multiple flag values may be ORed together.
  14. // These are mostly of interest if you are writing a new output format.
  15. const (
  16. ListTypeOrdered ListType = 1 << iota
  17. ListTypeDefinition
  18. ListTypeTerm
  19. ListItemContainsBlock
  20. ListItemBeginningOfList // TODO: figure out if this is of any use now
  21. ListItemEndOfList
  22. )
  23. // CellAlignFlags holds a type of alignment in a table cell.
  24. type CellAlignFlags int
  25. // These are the possible flag values for the table cell renderer.
  26. // Only a single one of these values will be used; they are not ORed together.
  27. // These are mostly of interest if you are writing a new output format.
  28. const (
  29. TableAlignmentLeft CellAlignFlags = 1 << iota
  30. TableAlignmentRight
  31. TableAlignmentCenter = (TableAlignmentLeft | TableAlignmentRight)
  32. )
  33. func (a CellAlignFlags) String() string {
  34. switch a {
  35. case TableAlignmentLeft:
  36. return "left"
  37. case TableAlignmentRight:
  38. return "right"
  39. case TableAlignmentCenter:
  40. return "center"
  41. default:
  42. return ""
  43. }
  44. }
  45. // DocumentMatters holds the type of a {front,main,back}matter in the document
  46. type DocumentMatters int
  47. // These are all possible Document divisions.
  48. const (
  49. DocumentMatterNone DocumentMatters = iota
  50. DocumentMatterFront
  51. DocumentMatterMain
  52. DocumentMatterBack
  53. )
  54. // CitationTypes holds the type of a citation, informative, normative or suppressed
  55. type CitationTypes int
  56. const (
  57. CitationTypeNone CitationTypes = iota
  58. CitationTypeSuppressed
  59. CitationTypeInformative
  60. CitationTypeNormative
  61. )
  62. // Node defines an ast node
  63. type Node interface {
  64. AsContainer() *Container
  65. AsLeaf() *Leaf
  66. GetParent() Node
  67. SetParent(newParent Node)
  68. GetChildren() []Node
  69. SetChildren(newChildren []Node)
  70. }
  71. // Container is a type of node that can contain children
  72. type Container struct {
  73. Parent Node
  74. Children []Node
  75. Literal []byte // Text contents of the leaf nodes
  76. Content []byte // Markdown content of the block nodes
  77. *Attribute // Block level attribute
  78. }
  79. // return true if can contain children of a given node type
  80. // used by custom nodes to over-ride logic in canNodeContain
  81. type CanContain interface {
  82. CanContain(Node) bool
  83. }
  84. // AsContainer returns itself as *Container
  85. func (c *Container) AsContainer() *Container {
  86. return c
  87. }
  88. // AsLeaf returns nil
  89. func (c *Container) AsLeaf() *Leaf {
  90. return nil
  91. }
  92. // GetParent returns parent node
  93. func (c *Container) GetParent() Node {
  94. return c.Parent
  95. }
  96. // SetParent sets the parent node
  97. func (c *Container) SetParent(newParent Node) {
  98. c.Parent = newParent
  99. }
  100. // GetChildren returns children nodes
  101. func (c *Container) GetChildren() []Node {
  102. return c.Children
  103. }
  104. // SetChildren sets children node
  105. func (c *Container) SetChildren(newChildren []Node) {
  106. c.Children = newChildren
  107. }
  108. // Leaf is a type of node that cannot have children
  109. type Leaf struct {
  110. Parent Node
  111. Literal []byte // Text contents of the leaf nodes
  112. Content []byte // Markdown content of the block nodes
  113. *Attribute // Block level attribute
  114. }
  115. // AsContainer returns nil
  116. func (l *Leaf) AsContainer() *Container {
  117. return nil
  118. }
  119. // AsLeaf returns itself as *Leaf
  120. func (l *Leaf) AsLeaf() *Leaf {
  121. return l
  122. }
  123. // GetParent returns parent node
  124. func (l *Leaf) GetParent() Node {
  125. return l.Parent
  126. }
  127. // SetParent sets the parent nodd
  128. func (l *Leaf) SetParent(newParent Node) {
  129. l.Parent = newParent
  130. }
  131. // GetChildren returns nil because Leaf cannot have children
  132. func (l *Leaf) GetChildren() []Node {
  133. return nil
  134. }
  135. // SetChildren will panic if trying to set non-empty children
  136. // because Leaf cannot have children
  137. func (l *Leaf) SetChildren(newChildren []Node) {
  138. if len(newChildren) != 0 {
  139. panic("leaf node cannot have children")
  140. }
  141. }
  142. // Document represents markdown document node, a root of ast
  143. type Document struct {
  144. Container
  145. }
  146. // DocumentMatter represents markdown node that signals a document
  147. // division: frontmatter, mainmatter or backmatter.
  148. type DocumentMatter struct {
  149. Container
  150. Matter DocumentMatters
  151. }
  152. // BlockQuote represents markdown block quote node
  153. type BlockQuote struct {
  154. Container
  155. }
  156. // Aside represents an markdown aside node.
  157. type Aside struct {
  158. Container
  159. }
  160. // List represents markdown list node
  161. type List struct {
  162. Container
  163. ListFlags ListType
  164. Tight bool // Skip <p>s around list item data if true
  165. BulletChar byte // '*', '+' or '-' in bullet lists
  166. Delimiter byte // '.' or ')' after the number in ordered lists
  167. Start int // for ordered lists this indicates the starting number if > 0
  168. RefLink []byte // If not nil, turns this list item into a footnote item and triggers different rendering
  169. IsFootnotesList bool // This is a list of footnotes
  170. }
  171. // ListItem represents markdown list item node
  172. type ListItem struct {
  173. Container
  174. ListFlags ListType
  175. Tight bool // Skip <p>s around list item data if true
  176. BulletChar byte // '*', '+' or '-' in bullet lists
  177. Delimiter byte // '.' or ')' after the number in ordered lists
  178. RefLink []byte // If not nil, turns this list item into a footnote item and triggers different rendering
  179. IsFootnotesList bool // This is a list of footnotes
  180. }
  181. // Paragraph represents markdown paragraph node
  182. type Paragraph struct {
  183. Container
  184. }
  185. // Math represents markdown MathAjax inline node
  186. type Math struct {
  187. Leaf
  188. }
  189. // MathBlock represents markdown MathAjax block node
  190. type MathBlock struct {
  191. Container
  192. }
  193. // Heading represents markdown heading node
  194. type Heading struct {
  195. Container
  196. Level int // This holds the heading level number
  197. HeadingID string // This might hold heading ID, if present
  198. IsTitleblock bool // Specifies whether it's a title block
  199. IsSpecial bool // We are a special heading (starts with .#)
  200. }
  201. // HorizontalRule represents markdown horizontal rule node
  202. type HorizontalRule struct {
  203. Leaf
  204. }
  205. // Emph represents markdown emphasis node
  206. type Emph struct {
  207. Container
  208. }
  209. // Strong represents markdown strong node
  210. type Strong struct {
  211. Container
  212. }
  213. // Del represents markdown del node
  214. type Del struct {
  215. Container
  216. }
  217. // Link represents markdown link node
  218. type Link struct {
  219. Container
  220. Destination []byte // Destination is what goes into a href
  221. Title []byte // Title is the tooltip thing that goes in a title attribute
  222. NoteID int // NoteID contains a serial number of a footnote, zero if it's not a footnote
  223. Footnote Node // If it's a footnote, this is a direct link to the footnote Node. Otherwise nil.
  224. DeferredID []byte // If a deferred link this holds the original ID.
  225. AdditionalAttributes []string // Defines additional attributes to use during rendering.
  226. }
  227. // CrossReference is a reference node.
  228. type CrossReference struct {
  229. Container
  230. Destination []byte // Destination is where the reference points to
  231. Suffix []byte // Potential citation suffix, i.e. (#myid, text)
  232. }
  233. // Citation is a citation node.
  234. type Citation struct {
  235. Leaf
  236. Destination [][]byte // Destination is where the citation points to. Multiple ones are allowed.
  237. Type []CitationTypes // 1:1 mapping of destination and citation type
  238. Suffix [][]byte // Potential citation suffix, i.e. [@!RFC1035, p. 144]
  239. }
  240. // Image represents markdown image node
  241. type Image struct {
  242. Container
  243. Destination []byte // Destination is what goes into a href
  244. Title []byte // Title is the tooltip thing that goes in a title attribute
  245. }
  246. // Text represents markdown text node
  247. type Text struct {
  248. Leaf
  249. }
  250. // HTMLBlock represents markdown html node
  251. type HTMLBlock struct {
  252. Leaf
  253. }
  254. // CodeBlock represents markdown code block node
  255. type CodeBlock struct {
  256. Leaf
  257. IsFenced bool // Specifies whether it's a fenced code block or an indented one
  258. Info []byte // This holds the info string
  259. FenceChar byte
  260. FenceLength int
  261. FenceOffset int
  262. }
  263. // Softbreak represents markdown softbreak node
  264. // Note: not used currently
  265. type Softbreak struct {
  266. Leaf
  267. }
  268. // Hardbreak represents markdown hard break node
  269. type Hardbreak struct {
  270. Leaf
  271. }
  272. // NonBlockingSpace represents markdown non-blocking space node
  273. type NonBlockingSpace struct {
  274. Leaf
  275. }
  276. // Code represents markdown code node
  277. type Code struct {
  278. Leaf
  279. }
  280. // HTMLSpan represents markdown html span node
  281. type HTMLSpan struct {
  282. Leaf
  283. }
  284. // Table represents markdown table node
  285. type Table struct {
  286. Container
  287. }
  288. // TableCell represents markdown table cell node
  289. type TableCell struct {
  290. Container
  291. IsHeader bool // This tells if it's under the header row
  292. Align CellAlignFlags // This holds the value for align attribute
  293. ColSpan int // How many columns to span
  294. }
  295. // TableHeader represents markdown table head node
  296. type TableHeader struct {
  297. Container
  298. }
  299. // TableBody represents markdown table body node
  300. type TableBody struct {
  301. Container
  302. }
  303. // TableRow represents markdown table row node
  304. type TableRow struct {
  305. Container
  306. }
  307. // TableFooter represents markdown table foot node
  308. type TableFooter struct {
  309. Container
  310. }
  311. // Caption represents a figure, code or quote caption
  312. type Caption struct {
  313. Container
  314. }
  315. // CaptionFigure is a node (blockquote or codeblock) that has a caption
  316. type CaptionFigure struct {
  317. Container
  318. HeadingID string // This might hold heading ID, if present
  319. }
  320. // Callout is a node that can exist both in text (where it is an actual node) and in a code block.
  321. type Callout struct {
  322. Leaf
  323. ID []byte // number of this callout
  324. }
  325. // Index is a node that contains an Index item and an optional, subitem.
  326. type Index struct {
  327. Leaf
  328. Primary bool
  329. Item []byte
  330. Subitem []byte
  331. ID string // ID of the index
  332. }
  333. // Subscript is a subscript node
  334. type Subscript struct {
  335. Leaf
  336. }
  337. // Subscript is a superscript node
  338. type Superscript struct {
  339. Leaf
  340. }
  341. // Footnotes is a node that contains all footnotes
  342. type Footnotes struct {
  343. Container
  344. }
  345. func removeNodeFromArray(a []Node, node Node) []Node {
  346. n := len(a)
  347. for i := 0; i < n; i++ {
  348. if a[i] == node {
  349. return append(a[:i], a[i+1:]...)
  350. }
  351. }
  352. return nil
  353. }
  354. // AppendChild appends child to children of parent
  355. // It panics if either node is nil.
  356. func AppendChild(parent Node, child Node) {
  357. RemoveFromTree(child)
  358. child.SetParent(parent)
  359. newChildren := append(parent.GetChildren(), child)
  360. parent.SetChildren(newChildren)
  361. }
  362. // RemoveFromTree removes this node from tree
  363. func RemoveFromTree(n Node) {
  364. if n.GetParent() == nil {
  365. return
  366. }
  367. // important: don't clear n.Children if n has no parent
  368. // we're called from AppendChild and that might happen on a node
  369. // that accumulated Children but hasn't been inserted into the tree
  370. n.SetChildren(nil)
  371. p := n.GetParent()
  372. newChildren := removeNodeFromArray(p.GetChildren(), n)
  373. if newChildren != nil {
  374. p.SetChildren(newChildren)
  375. }
  376. }
  377. // GetLastChild returns last child of node n
  378. // It's implemented as stand-alone function to keep Node interface small
  379. func GetLastChild(n Node) Node {
  380. a := n.GetChildren()
  381. if len(a) > 0 {
  382. return a[len(a)-1]
  383. }
  384. return nil
  385. }
  386. // GetFirstChild returns first child of node n
  387. // It's implemented as stand-alone function to keep Node interface small
  388. func GetFirstChild(n Node) Node {
  389. a := n.GetChildren()
  390. if len(a) > 0 {
  391. return a[0]
  392. }
  393. return nil
  394. }
  395. // GetNextNode returns next sibling of node n (node after n)
  396. // We can't make it part of Container or Leaf because we loose Node identity
  397. func GetNextNode(n Node) Node {
  398. parent := n.GetParent()
  399. if parent == nil {
  400. return nil
  401. }
  402. a := parent.GetChildren()
  403. len := len(a) - 1
  404. for i := 0; i < len; i++ {
  405. if a[i] == n {
  406. return a[i+1]
  407. }
  408. }
  409. return nil
  410. }
  411. // GetPrevNode returns previous sibling of node n (node before n)
  412. // We can't make it part of Container or Leaf because we loose Node identity
  413. func GetPrevNode(n Node) Node {
  414. parent := n.GetParent()
  415. if parent == nil {
  416. return nil
  417. }
  418. a := parent.GetChildren()
  419. len := len(a)
  420. for i := 1; i < len; i++ {
  421. if a[i] == n {
  422. return a[i-1]
  423. }
  424. }
  425. return nil
  426. }
  427. // WalkStatus allows NodeVisitor to have some control over the tree traversal.
  428. // It is returned from NodeVisitor and different values allow Node.Walk to
  429. // decide which node to go to next.
  430. type WalkStatus int
  431. const (
  432. // GoToNext is the default traversal of every node.
  433. GoToNext WalkStatus = iota
  434. // SkipChildren tells walker to skip all children of current node.
  435. SkipChildren
  436. // Terminate tells walker to terminate the traversal.
  437. Terminate
  438. )
  439. // NodeVisitor is a callback to be called when traversing the syntax tree.
  440. // Called twice for every node: once with entering=true when the branch is
  441. // first visited, then with entering=false after all the children are done.
  442. type NodeVisitor interface {
  443. Visit(node Node, entering bool) WalkStatus
  444. }
  445. // NodeVisitorFunc casts a function to match NodeVisitor interface
  446. type NodeVisitorFunc func(node Node, entering bool) WalkStatus
  447. // Walk traverses tree recursively
  448. func Walk(n Node, visitor NodeVisitor) WalkStatus {
  449. isContainer := n.AsContainer() != nil
  450. status := visitor.Visit(n, true) // entering
  451. if status == Terminate {
  452. // even if terminating, close container node
  453. if isContainer {
  454. visitor.Visit(n, false)
  455. }
  456. return status
  457. }
  458. if isContainer && status != SkipChildren {
  459. children := n.GetChildren()
  460. for _, n := range children {
  461. status = Walk(n, visitor)
  462. if status == Terminate {
  463. return status
  464. }
  465. }
  466. }
  467. if isContainer {
  468. status = visitor.Visit(n, false) // exiting
  469. if status == Terminate {
  470. return status
  471. }
  472. }
  473. return GoToNext
  474. }
  475. // Visit calls visitor function
  476. func (f NodeVisitorFunc) Visit(node Node, entering bool) WalkStatus {
  477. return f(node, entering)
  478. }
  479. // WalkFunc is like Walk but accepts just a callback function
  480. func WalkFunc(n Node, f NodeVisitorFunc) {
  481. visitor := NodeVisitorFunc(f)
  482. Walk(n, visitor)
  483. }