diff options
Diffstat (limited to 'vendor')
| -rw-r--r-- | vendor/README.md | 9 | ||||
| -rw-r--r-- | vendor/commonmark/LICENSE | 170 | ||||
| -rw-r--r-- | vendor/commonmark/build.bat | 4 | ||||
| -rw-r--r-- | vendor/commonmark/cmark.odin | 526 | ||||
| -rw-r--r-- | vendor/commonmark/cmark_static.lib | bin | 0 -> 855878 bytes | |||
| -rw-r--r-- | vendor/commonmark/doc.odin | 117 |
6 files changed, 825 insertions, 1 deletions
diff --git a/vendor/README.md b/vendor/README.md index 628ea2727..1e24b4d0a 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -134,4 +134,11 @@ See also LICENSE in the `GGPO` directory itself. `botan.lib` is available under Botan's [BSD](https://botan.randombit.net/license.txt) license.
See also LICENSE in the `botan` directory itself.
-Includes full bindings as well as wrappers to match the `core:crypto` API.
\ No newline at end of file +Includes full bindings as well as wrappers to match the `core:crypto` API.
+
+## CommonMark
+
+[CMark](https://github.com/commonmark/cmark) CommonMark parsing library.
+
+See also LICENSE in the `commonmark` directory itself.
+Includes full bindings and Windows `.lib` and `.dll`.
\ No newline at end of file diff --git a/vendor/commonmark/LICENSE b/vendor/commonmark/LICENSE new file mode 100644 index 000000000..c87c7a615 --- /dev/null +++ b/vendor/commonmark/LICENSE @@ -0,0 +1,170 @@ +Copyright (c) 2014, John MacFarlane
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-----
+
+houdini.h, houdini_href_e.c, houdini_html_e.c, houdini_html_u.c
+
+derive from https://github.com/vmg/houdini (with some modifications)
+
+Copyright (C) 2012 Vicent Martí
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-----
+
+buffer.h, buffer.c, chunk.h
+
+are derived from code (C) 2012 Github, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-----
+
+utf8.c and utf8.c
+
+are derived from utf8proc
+(<http://www.public-software-group.org/utf8proc>),
+(C) 2009 Public Software Group e. V., Berlin, Germany.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+-----
+
+The normalization code in normalize.py was derived from the
+markdowntest project, Copyright 2013 Karl Dubost:
+
+The MIT License (MIT)
+
+Copyright (c) 2013 Karl Dubost
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-----
+
+The CommonMark spec (test/spec.txt) is
+
+Copyright (C) 2014-15 John MacFarlane
+
+Released under the Creative Commons CC-BY-SA 4.0 license:
+<http://creativecommons.org/licenses/by-sa/4.0/>.
+
+-----
+
+The test software in test/ is
+
+Copyright (c) 2014, John MacFarlane
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file diff --git a/vendor/commonmark/build.bat b/vendor/commonmark/build.bat new file mode 100644 index 000000000..1783e4651 --- /dev/null +++ b/vendor/commonmark/build.bat @@ -0,0 +1,4 @@ +@echo off
+pushd W:\Odin-other\Odin-test
+call build.bat
+popd
\ No newline at end of file diff --git a/vendor/commonmark/cmark.odin b/vendor/commonmark/cmark.odin new file mode 100644 index 000000000..313435870 --- /dev/null +++ b/vendor/commonmark/cmark.odin @@ -0,0 +1,526 @@ +/* + Bindings against CMark (https://github.com/commonmark/cmark) + + Original authors: John MacFarlane, Vicent Marti, Kārlis Gaņģis, Nick Wellnhofer. + See LICENSE for license details. +*/ +package commonmark + +import "core:c" +import "core:c/libc" +import "core:runtime" + +BINDING_VERSION :: Version_Info{major = 0, minor = 30, patch = 2} + +when ODIN_OS == .Windows { + foreign import lib { + "cmark_static.lib", + } +} else when ODIN_OS == .Linux { + foreign import lib { + "libcmark.a", + } +} + +Option :: enum c.int { + Source_Position = 1, // Include a `data-sourcepos` attribute on all block elements. + Hard_Breaks = 2, // Render `softbreak` as hard line breaks. + Safe = 3, // Defined for API compatibility, now enabled by default. + Unsafe = 17, // Render raw HTML and unsafe links (`javascript:`, `vbscript:`, + // `file:`, and `data:`, except for `image/png`, `image/gif`, + // `image/jpeg`, or `image/webp` mime types). By default, + // raw HTML is replaced by a placeholder HTML comment. Unsafe + // links are replaced by empty strings. + No_Breaks = 4, // Render `softbreak` elements as spaces. + Normalize = 8, // Legacy option, no effect. + Validate_UTF8 = 9, // Validate UTF-8 input before parsing, replacing illegal + // sequences with the replacement character U+FFFD. + Smart = 10, // Convert straight quotes to curly, --- to em dashes, -- to en dashes. +} +Options :: bit_set[Option; c.int] + +DEFAULT_OPTIONS :: Options{} + +Node_Type :: enum u16 { + // Error status + None = 0, + + /* Block */ + Document, + Block_Quote, + List, + Item, + Code_Block, + HTML_Block, + Custom_Block, + Paragraph, + Heading, + Thematic_Break, + + /* Inline */ + Text, + Soft_Break, + Line_Break, + Code, + HTML_Inline, + Custom_Inline, + Emph, + Strong, + Link, + Image, + + First_Block = Document, + Last_Block = Thematic_Break, + + First_Inline = Text, + Last_Inline = Image, +} + +List_Type :: enum c.int { + None, + Bullet, + Ordered, +} + +Delim_Type :: enum c.int { + None, + Period, + Paren, +} + +// Version information +Version_Info :: struct { + patch: u8, + minor: u8, + major: u8, + _: u8, +} + +@(default_calling_convention="c", link_prefix="cmark_") +foreign lib { + version :: proc() -> (res: Version_Info) --- + version_string :: proc() -> (res: cstring) --- +} + +// Simple API +@(default_calling_convention="c", link_prefix="cmark_") +foreign lib { + // Convert 'text' (assumed to be a UTF-8 encoded string with length `len`) from CommonMark Markdown to HTML + // returning a null-terminated, UTF-8-encoded string. It is the caller's responsibility + // to free the returned buffer. + markdown_to_html :: proc(text: cstring, length: c.size_t, options: Options) -> (html: cstring) --- +} + +markdown_to_html_from_string :: proc(text: string, options: Options) -> (html: string) { + return string(markdown_to_html(cstring(raw_data(text)), len(text), options)) +} + +// Custom allocator - Defines the memory allocation functions to be used by CMark +// when parsing and allocating a document tree +Allocator :: struct { + calloc: proc "c" (num: c.size_t, size: c.size_t) -> rawptr, + realloc: proc "c" (ptr: rawptr, new_size: c.size_t) -> rawptr, + free: proc "c" (ptr: rawptr), +} + +@(default_calling_convention="c", link_prefix="cmark_") +foreign lib { + // Returns a pointer to the default memory allocator. + get_default_mem_allocator :: proc() -> (mem: ^Allocator) --- +} + +bufsize_t :: distinct i32 + +// Node creation, destruction, and tree traversal +Node :: struct { + mem: ^Allocator, + + next: ^Node, + prev: ^Node, + parent: ^Node, + first_child: ^Node, + last_child: ^Node, + + user_data: rawptr, + data: [^]u8, + len: bufsize_t, + + start_line: c.int, + start_column: c.int, + end_line: c.int, + end_column: c.int, + + type: Node_Type, + flags: Node_Flags, + + as: struct #raw_union { + list: List, + code: Code, + heading: Heading, + link: Link, + custom: Custom, + html_block_type: c.int, + }, +} + +Node_Flag :: enum u16 { + Open = 0, + Last_Line_Blank = 1, + Last_Line_Checked = 2, +} +Node_Flags :: bit_set[Node_Flag; u16] + +List :: struct { + marker_offset: c.int, + padding: c.int, + start: c.int, + list_type: u8, + delimiter: u8, + bullet_char: u8, + tight: c.bool, +} + +Code :: struct { + info: cstring, + fence_length: u8, + fence_offset: u8, + fence_char: u8, + fenced: b8, +} + +Heading :: struct { + internal_offset: c.int, + level: i8, + setext: c.bool, +} + + +Link :: struct { + url: cstring, + title: cstring, +} + +Custom :: struct { + on_enter: cstring, + on_exit: cstring, +} + +@(default_calling_convention="c", link_prefix="cmark_") +foreign lib { + // Creates a new node of type 'type'. + // Note that the node may have other required properties, which it is the caller's responsibility + // to assign. + node_new :: proc(type: Node_Type) -> (node: ^Node) --- + + // Same as `node_new`, but explicitly listing the memory allocator used to allocate the node. + // Note: be sure to use the same allocator for every node in a tree, or bad things can happen. + node_new_with_mem :: proc(type: Node_Type, mem: ^Allocator) -> (node: ^Node) --- + + // Frees the memory allocated for a node and any children. + node_free :: proc(node: ^Node) --- + + /* + Tree Traversal + */ + // Returns the next node in the sequence after `node`, or nil if there is none. + node_next :: proc(node: ^Node) -> (next: ^Node) --- + + // Returns the previous node in the sequence after `node`, or nil if there is none. + node_previous :: proc(node: ^Node) -> (prev: ^Node) --- + + // Returns the parent of `node`, or nil if there is none. + node_parent :: proc(node: ^Node) -> (parent: ^Node) --- + + // Returns the first child of `node`, or nil if `node` has no children. + node_first_child :: proc(node: ^Node) -> (child: ^Node) --- + + // Returns the last child of `node`, or nil if `node` has no children. + node_last_child :: proc(node: ^Node) -> (child: ^Node) --- + +} + +Iter :: distinct rawptr + +Event_Type :: enum c.int { + None, + Done, + Enter, + Exit, +} + +@(default_calling_convention="c", link_prefix="cmark_") +foreign lib { + // Creates a new iterator starting at 'root'. The current node and event + // type are undefined until `iter_next` is called for the first time. + // The memory allocated for the iterator should be released using + // 'iter_free' when it is no longer needed. + iter_new :: proc(root: ^Node) -> (iter: ^Iter) --- + + // Frees the memory allocated for an iterator. + iter_free :: proc(iter: ^Iter) --- + + // Advances to the next node and returns the event type (`.Enter`, `.Exit`, `.Done`) + iter_next :: proc(iter: ^Iter) -> (event_type: Event_Type) --- + + // Returns the current node. + iter_get_node :: proc(iter: ^Iter) -> (node: ^Node) --- + + // Returns the current event type. + iter_get_event_type :: proc(iter: ^Iter) -> (event_type: Event_Type) --- + + // Returns the root node. + iter_get_root :: proc(iter: ^Iter) -> (root: ^Node) --- + + // Resets the iterator so that the current node is `current` and + // the event type is `event_type`. The new current node must be a + // descendant of the root node or the root node itself. + iter_reset :: proc(iter: ^Iter, current: ^Node, event_type: Event_Type) --- +} + +// Accessors +@(default_calling_convention="c", link_prefix="cmark_") +foreign lib { + // Returns the user data of `node`. + node_get_user_data :: proc(node: ^Node) -> (user_data: rawptr) --- + + // Sets arbitrary user data for `node`. Returns `true` on success, `false` on failure. + node_set_user_data :: proc(node: ^Node, user_data: rawptr) -> (success: b32) --- + + // Returns the type of `node`, or `.None` on error. + node_get_type :: proc(node: ^Node) -> (node_type: Node_Type) --- + + // Like `node_get_type`, but returns a string representation of the type, or "<unknown>". + node_get_type_string :: proc(node: ^Node) -> (node_type: cstring) --- + + // Returns the string contents of `node`, or an empty string if none is set. + // Returns `nil` if called on a node that does not have string content. + node_get_literal :: proc(node: ^Node) -> (content: cstring) --- + + // Sets the string contents of `node`. Returns `true` on success, `false` on failure. + node_set_literal :: proc(node: ^Node, content: cstring) -> (success: b32) --- + + // Returns the heading level of `node`, or 0 if `node` is not a heading. + node_get_heading_level :: proc(node: ^Node) -> (level: c.int) --- + + // Sets the heading level of `node`. Returns `true` on success, `false` on failure. + node_set_heading_level :: proc(node: ^Node, level: c.int) -> (success: b32) --- + + // Returns the list type of `node`, or `.No_List` if not a list. + node_get_list_type :: proc(node: ^Node) -> (list_type: List_Type) --- + + // Sets the list type of `node`. Returns `true` on success, `false` on failure. + node_set_list_type :: proc(node: ^Node, list_type: List_Type) -> (success: b32) --- + + // Returns the list delimiter type of `node`, or `.No_Delim` if not a list. + node_get_list_delim :: proc(node: ^Node) -> (delim_type: Delim_Type) --- + + // Sets the delimiter type of `node`. Returns `true` on success, `false` on failure. + node_set_list_delim :: proc(node: ^Node, delim_type: Delim_Type) -> (success: b32) --- + + // Returns starting number of `node`, if it is an ordered list, otherwise 0. + node_get_list_start :: proc(node: ^Node) -> (start: c.int) --- + + // Sets starting number of `node`, if it is an ordered list. + // Returns `true` on success, `false` on failure. + node_set_list_start :: proc(node: ^Node, start: c.int) -> (success: b32) --- + + // Returns `true` if `node` is a tight list, `false` otherwise. + node_get_list_tight :: proc(node: ^Node) -> (tight: b32) --- + + // Sets the "tightness" of a list. Returns `true` on success, `false` on failure. + node_set_list_tight :: proc(node: ^Node, tight: b32) -> (success: b32) --- + + // Returns the info string from a fenced code block. + get_fence_info :: proc(node: ^Node) -> (fence_info: cstring) --- + + // Sets the info string in a fenced code block, returning `true` on success and `false` on failure. + node_set_fence_info :: proc(node: ^Node, fence_info: cstring) -> (success: b32) --- + + // Returns the URL of a link or image `node`, or an empty string if no URL is set. + // Returns nil if called on a node that is not a link or image. + node_get_url :: proc(node: ^Node) -> (url: cstring) --- + + // Sets the URL of a link or image `node`. Returns `true` on success, `false` on failure. + node_set_url :: proc(node: ^Node, url: cstring) -> (success: b32) --- + + // Returns the title of a link or image `node`, or an empty string if no title is set. + // Returns nil if called on a node that is not a link or image. + node_get_title :: proc(node: ^Node) -> (title: cstring) --- + + // Sets the title of a link or image `node`. Returns `true` on success, `false` on failure. + node_set_title :: proc(node: ^Node, title: cstring) -> (success: b32) --- + + // Returns the literal "on enter" text for a custom `node`, or an empty string if no on_enter is set. + // Returns nil if called on a non-custom node. + node_get_on_enter :: proc(node: ^Node) -> (on_enter: cstring) --- + + // Sets the literal text to render "on enter" for a custom `node`. + // Any children of the node will be rendered after this text. + // Returns `true` on success, `false`on failure. + node_set_on_enter :: proc(node: ^Node, on_enter: cstring) -> (success: b32) --- + + // Returns the line on which `node` begins. + node_get_start_line :: proc(node: ^Node) -> (line: c.int) --- + + // Returns the column at which `node` begins. + node_get_start_column :: proc(node: ^Node) -> (column: c.int) --- + + // Returns the line on which `node` ends. + node_get_end_line :: proc(node: ^Node) -> (line: c.int) --- + + // Returns the column at which `node` ends. + node_get_end_column :: proc(node: ^Node) -> (column: c.int) --- +} + +// Tree Manipulation +@(default_calling_convention="c", link_prefix="cmark_") +foreign lib { + // Unlinks a `node`, removing it from the tree, but not freeing its memory. + // (Use `node_free` for that.) + node_unlink :: proc(node: ^Node) --- + + // Inserts 'sibling' before `node`. Returns `true` on success, `false` on failure. + node_insert_before :: proc(node: ^Node, sibling: ^Node) -> (success: b32) --- + + // Inserts 'sibling' after `node`. Returns `true` on success, `false` on failure. + node_insert_after :: proc(node: ^Node, sibling: ^Node) -> (success: b32) --- + + // Replaces 'oldnode' with 'newnode' and unlinks 'oldnode' + // (but does not free its memory). + // Returns `true` on success, `false` on failure. + node_replace :: proc(old_node: ^Node, new_node: ^Node) -> (success: b32) --- + + // Adds 'child' to the beginning of the children of `node`. + // Returns `true` on success, `false` on failure. + node_prepend_child :: proc(node: ^Node, child: ^Node) -> (success: b32) --- + + // Adds 'child' to the end of the children of `node`. + // Returns `true` on success, `false` on failure. + node_append_child :: proc(node: ^Node, child: ^Node) -> (success: b32) --- + + // Consolidates adjacent text nodes. + consolidate_text_nodes :: proc(root: ^Node) --- +} + +Parser :: distinct rawptr + +@(default_calling_convention="c", link_prefix="cmark_") +foreign lib { + // Creates a new parser object. + parser_new :: proc(options: Options) -> (parser: ^Parser) --- + + // Creates a new parser object with the given memory allocator. + parser_new_with_mem :: proc(options: Options, mem: ^Allocator) -> (parser: ^Parser) --- + + // Frees memory allocated for a parser object. + parser_free :: proc(parser: ^Parser) --- + + // Feeds a string of length 'len' to 'parser'. + parser_feed :: proc(parser: ^Parser, buffer: [^]byte, len: c.size_t) --- + + // Finish parsing and return a pointer to a tree of nodes. + parser_finish :: proc(parser: ^Parser) -> (root: ^Node) --- + + // Parse a CommonMark document in 'buffer' of length 'len'. + // Returns a pointer to a tree of nodes. The memory allocated for + // the node tree should be released using 'node_free' when it is no longer needed. + parse_document :: proc(buffer: [^]byte, len: c.size_t, options: Options) -> (root: ^Node) --- + + // Parse a CommonMark document in file 'f', returning a pointer to a tree of nodes. + // The memory allocated for the node tree should be released using 'node_free' + // when it is no longer needed. + // + // Called `parse_from_libc_file` so as not to confuse with Odin's file handling. + + @(link_name = "parse_from_file") + parse_from_libc_file :: proc(file: ^libc.FILE, options: Options) -> (root: ^Node) --- +} + +parser_feed_from_string :: proc "c" (parser: ^Parser, s: string) { + parser_feed(parser, raw_data(s), len(s)) +} +parse_document_from_string :: proc "c" (s: string, options: Options) -> (root: ^Node) { + return parse_document(raw_data(s), len(s), options) +} + +// Rendering +@(default_calling_convention="c", link_prefix="cmark_") +foreign lib { + // Render a `node` tree as XML. + // It is the caller's responsibilityto free the returned buffer. + render_xml :: proc(root: ^Node, options: Options) -> (xml: cstring) --- + + // Render a `node` tree as an HTML fragment. + // It is up to the user to add an appropriate header and footer. + // It is the caller's responsibility to free the returned buffer. + render_html :: proc(root: ^Node, options: Options) -> (html: cstring) --- + + // Render a `node` tree as a groff man page, without the header. + // It is the caller's responsibility to free the returned buffer. + render_man :: proc(root: ^Node, options: Options, width: c.int) -> (groff: cstring) --- + + // Render a `node` tree as a commonmark document. + // It is the caller's responsibility to free the returned buffer. + render_commonmark :: proc(root: ^Node, options: Options, width: c.int) -> (commonmark: cstring) --- + + // Render a `node` tree as a LaTeX document. + // It is the caller's responsibility to free the returned buffer. + render_latex :: proc(root: ^Node, options: Options, width: c.int) -> (latex: cstring) --- +} + +// Helpers to free results from `render_*`. +free_rawptr :: proc "c" (ptr: rawptr) { + cmm := get_default_mem_allocator() + cmm.free(ptr) +} +free_cstring :: proc "c" (str: cstring) { + free_rawptr(rawptr(str)) +} +free_string :: proc "c" (s: string) { + free_rawptr(raw_data(s)) +} +free :: proc{free_rawptr, free_cstring} + +// Wrap CMark allocator as Odin allocator +@(private) +cmark_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode, + size, alignment: int, + old_memory: rawptr, old_size: int, loc := #caller_location) -> (res: []byte, err: runtime.Allocator_Error) { + + cmark_alloc := cast(^Allocator)allocator_data + switch mode { + case .Alloc: + ptr := cmark_alloc.calloc(1, c.size_t(size)) + res = transmute([]byte)runtime.Raw_Slice{ptr, size} + return res, nil + + case .Free: + cmark_alloc.free(old_memory) + return nil, nil + + case .Free_All: + return nil, .Mode_Not_Implemented + + case .Resize: + new_ptr := cmark_alloc.realloc(old_memory, c.size_t(size)) + res = transmute([]byte)runtime.Raw_Slice{new_ptr, size} + if size > old_size { + runtime.mem_zero(raw_data(res[old_size:]), size - old_size) + } + return res, nil + + case .Query_Features: + return nil, nil + + case .Query_Info: + return nil, .Mode_Not_Implemented + } + return nil, nil +} + +get_default_mem_allocator_as_odin :: proc() -> runtime.Allocator { + return runtime.Allocator{ + procedure = cmark_allocator_proc, + data = rawptr(get_default_mem_allocator()), + } +}
\ No newline at end of file diff --git a/vendor/commonmark/cmark_static.lib b/vendor/commonmark/cmark_static.lib Binary files differnew file mode 100644 index 000000000..ee733d87c --- /dev/null +++ b/vendor/commonmark/cmark_static.lib diff --git a/vendor/commonmark/doc.odin b/vendor/commonmark/doc.odin new file mode 100644 index 000000000..24f6780f3 --- /dev/null +++ b/vendor/commonmark/doc.odin @@ -0,0 +1,117 @@ +// +ignore +/* + Bindings against CMark (https://github.com/commonmark/cmark) + + Original authors: John MacFarlane, Vicent Marti, Kārlis Gaņģis, Nick Wellnhofer. + See LICENSE for license details. +*/ +package commonmark + +/* + Parsing - Simple interface: + + ```odin + import cm "vendor:commonmark" + + hellope_world :: proc() { + fmt.printf("CMark version: %v\n", cm.version_string()) + + str := "Hellope *world*!" + root := cm.parse_document(raw_data(str), len(str), cm.DEFAULT_OPTIONS) + defer cm.node_free(root) + + html := cm.render_html(root, cm.DEFAULT_OPTIONS) + defer cm.free(html) + + fmt.println(html) + } + ``` + + Parsing - Streaming interface: + + ```odin + import cm "vendor:commonmark" + + streaming :: proc() { + using cm + + STR :: "Hellope *world*!\n\n" + N :: 50 + STREAM_SIZE :: 42 + + str_buf: [len(STR) * N]u8 + for i in 0..<N { + copy(str_buf[i*len(STR):], STR) + } + + parser := parser_new(DEFAULT_OPTIONS) + defer parser_free(parser) + + buf := str_buf[:] + for len(buf) > STREAM_SIZE { + parser_feed(parser, raw_data(buf), STREAM_SIZE) + buf = buf[STREAM_SIZE:] + } + + if len(buf) > 0 { + parser_feed(parser, raw_data(buf), len(buf)) + buf = buf[len(buf):] + } + + root := parser_finish(parser) + defer cm.node_free(root) + + html := cm.render_html(root, cm.DEFAULT_OPTIONS) + defer cm.free(html) + + fmt.println(html) + } + + ``` + + An iterator will walk through a tree of nodes, starting from a root + node, returning one node at a time, together with information about + whether the node is being entered or exited. + + The iterator will first descend to a child node, if there is one. + When there is no child, the iterator will go to the next sibling. + When there is no next sibling, the iterator will return to the parent + (but with an `Event_Type.Exit`). + + The iterator will return `.Done` when it reaches the root node again. + + One natural application is an HTML renderer, where an `.Enter` event + outputs an open tag and an `.Exit` event outputs a close tag. + + An iterator might also be used to transform an AST in some systematic + way, for example, turning all level-3 headings into regular paragraphs. + + ```odin + usage_example(root: ^Node) { + ev_type: Event_Type + iter := iter_new(root) + defer iter_free(iter) + for { + ev_type = iter_next(iter) + if ev_type == .Done do break + cur := iter_get_node(iter) + // Do something with `cur` and `ev_type` + } + } + ``` + + Iterators will never return `.Exit` events for leaf nodes, + which are nodes of type: + + * HTML_Block + * Thematic_Break + * Code_Block + * Text + * Soft_Break + * Line_Break + * Code + * HTML_Inline + + Nodes must only be modified after an `.Exit` event, or an `.Enter` event for + leaf nodes. +*/
\ No newline at end of file |