doc.odin 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. //+build ignore
  2. /*
  3. Bindings against CMark (https://github.com/commonmark/cmark)
  4. Original authors: John MacFarlane, Vicent Marti, Kārlis Gaņģis, Nick Wellnhofer.
  5. See LICENSE for license details.
  6. */
  7. package vendor_commonmark
  8. /*
  9. Parsing - Simple interface:
  10. ```odin
  11. import cm "vendor:commonmark"
  12. hellope_world :: proc() {
  13. fmt.printf("CMark version: %v\n", cm.version_string())
  14. str := "Hellope *world*!"
  15. root := cm.parse_document(raw_data(str), len(str), cm.DEFAULT_OPTIONS)
  16. defer cm.node_free(root)
  17. html := cm.render_html(root, cm.DEFAULT_OPTIONS)
  18. defer cm.free(html)
  19. fmt.println(html)
  20. }
  21. ```
  22. Parsing - Streaming interface:
  23. ```odin
  24. import cm "vendor:commonmark"
  25. streaming :: proc() {
  26. using cm
  27. STR :: "Hellope *world*!\n\n"
  28. N :: 50
  29. STREAM_SIZE :: 42
  30. str_buf: [len(STR) * N]u8
  31. for i in 0..<N {
  32. copy(str_buf[i*len(STR):], STR)
  33. }
  34. parser := parser_new(DEFAULT_OPTIONS)
  35. defer parser_free(parser)
  36. buf := str_buf[:]
  37. for len(buf) > STREAM_SIZE {
  38. parser_feed(parser, raw_data(buf), STREAM_SIZE)
  39. buf = buf[STREAM_SIZE:]
  40. }
  41. if len(buf) > 0 {
  42. parser_feed(parser, raw_data(buf), len(buf))
  43. buf = buf[len(buf):]
  44. }
  45. root := parser_finish(parser)
  46. defer cm.node_free(root)
  47. html := cm.render_html(root, cm.DEFAULT_OPTIONS)
  48. defer cm.free(html)
  49. fmt.println(html)
  50. }
  51. ```
  52. An iterator will walk through a tree of nodes, starting from a root
  53. node, returning one node at a time, together with information about
  54. whether the node is being entered or exited.
  55. The iterator will first descend to a child node, if there is one.
  56. When there is no child, the iterator will go to the next sibling.
  57. When there is no next sibling, the iterator will return to the parent
  58. (but with an `Event_Type.Exit`).
  59. The iterator will return `.Done` when it reaches the root node again.
  60. One natural application is an HTML renderer, where an `.Enter` event
  61. outputs an open tag and an `.Exit` event outputs a close tag.
  62. An iterator might also be used to transform an AST in some systematic
  63. way, for example, turning all level-3 headings into regular paragraphs.
  64. ```odin
  65. usage_example(root: ^Node) {
  66. ev_type: Event_Type
  67. iter := iter_new(root)
  68. defer iter_free(iter)
  69. for {
  70. ev_type = iter_next(iter)
  71. if ev_type == .Done do break
  72. cur := iter_get_node(iter)
  73. // Do something with `cur` and `ev_type`
  74. }
  75. }
  76. ```
  77. Iterators will never return `.Exit` events for leaf nodes,
  78. which are nodes of type:
  79. * HTML_Block
  80. * Thematic_Break
  81. * Code_Block
  82. * Text
  83. * Soft_Break
  84. * Line_Break
  85. * Code
  86. * HTML_Inline
  87. Nodes must only be modified after an `.Exit` event, or an `.Enter` event for
  88. leaf nodes.
  89. */