commonmarker 0.23.10 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Cargo.lock +1049 -0
- data/Cargo.toml +6 -0
- data/README.md +144 -203
- data/ext/commonmarker/Cargo.toml +13 -0
- data/ext/commonmarker/extconf.rb +3 -6
- data/ext/commonmarker/src/lib.rs +153 -0
- data/ext/commonmarker/src/options.rs +140 -0
- data/ext/commonmarker/src/plugins/syntax_highlighting.rs +74 -0
- data/ext/commonmarker/src/plugins.rs +3 -0
- data/ext/commonmarker/src/utils.rs +8 -0
- data/lib/commonmarker/config.rb +84 -40
- data/lib/commonmarker/constants.rb +7 -0
- data/lib/commonmarker/extension.rb +14 -0
- data/lib/commonmarker/renderer.rb +1 -127
- data/lib/commonmarker/utils.rb +22 -0
- data/lib/commonmarker/version.rb +2 -2
- data/lib/commonmarker.rb +14 -29
- metadata +36 -188
- data/Rakefile +0 -109
- data/bin/commonmarker +0 -118
- data/commonmarker.gemspec +0 -38
- data/ext/commonmarker/arena.c +0 -104
- data/ext/commonmarker/autolink.c +0 -508
- data/ext/commonmarker/autolink.h +0 -8
- data/ext/commonmarker/blocks.c +0 -1622
- data/ext/commonmarker/buffer.c +0 -278
- data/ext/commonmarker/buffer.h +0 -116
- data/ext/commonmarker/case_fold_switch.inc +0 -4327
- data/ext/commonmarker/chunk.h +0 -135
- data/ext/commonmarker/cmark-gfm-core-extensions.h +0 -54
- data/ext/commonmarker/cmark-gfm-extension_api.h +0 -737
- data/ext/commonmarker/cmark-gfm-extensions_export.h +0 -42
- data/ext/commonmarker/cmark-gfm.h +0 -833
- data/ext/commonmarker/cmark-gfm_export.h +0 -42
- data/ext/commonmarker/cmark-gfm_version.h +0 -7
- data/ext/commonmarker/cmark.c +0 -55
- data/ext/commonmarker/cmark_ctype.c +0 -44
- data/ext/commonmarker/cmark_ctype.h +0 -33
- data/ext/commonmarker/commonmark.c +0 -514
- data/ext/commonmarker/commonmarker.c +0 -1308
- data/ext/commonmarker/commonmarker.h +0 -16
- data/ext/commonmarker/config.h +0 -76
- data/ext/commonmarker/core-extensions.c +0 -27
- data/ext/commonmarker/entities.inc +0 -2138
- data/ext/commonmarker/ext_scanners.c +0 -879
- data/ext/commonmarker/ext_scanners.h +0 -24
- data/ext/commonmarker/footnotes.c +0 -63
- data/ext/commonmarker/footnotes.h +0 -27
- data/ext/commonmarker/houdini.h +0 -57
- data/ext/commonmarker/houdini_href_e.c +0 -100
- data/ext/commonmarker/houdini_html_e.c +0 -66
- data/ext/commonmarker/houdini_html_u.c +0 -149
- data/ext/commonmarker/html.c +0 -502
- data/ext/commonmarker/html.h +0 -27
- data/ext/commonmarker/inlines.c +0 -1788
- data/ext/commonmarker/inlines.h +0 -29
- data/ext/commonmarker/iterator.c +0 -159
- data/ext/commonmarker/iterator.h +0 -26
- data/ext/commonmarker/latex.c +0 -468
- data/ext/commonmarker/linked_list.c +0 -37
- data/ext/commonmarker/man.c +0 -274
- data/ext/commonmarker/map.c +0 -129
- data/ext/commonmarker/map.h +0 -44
- data/ext/commonmarker/node.c +0 -1045
- data/ext/commonmarker/node.h +0 -167
- data/ext/commonmarker/parser.h +0 -59
- data/ext/commonmarker/plaintext.c +0 -218
- data/ext/commonmarker/plugin.c +0 -36
- data/ext/commonmarker/plugin.h +0 -34
- data/ext/commonmarker/references.c +0 -43
- data/ext/commonmarker/references.h +0 -26
- data/ext/commonmarker/registry.c +0 -63
- data/ext/commonmarker/registry.h +0 -24
- data/ext/commonmarker/render.c +0 -213
- data/ext/commonmarker/render.h +0 -62
- data/ext/commonmarker/scanners.c +0 -14056
- data/ext/commonmarker/scanners.h +0 -70
- data/ext/commonmarker/scanners.re +0 -341
- data/ext/commonmarker/strikethrough.c +0 -167
- data/ext/commonmarker/strikethrough.h +0 -9
- data/ext/commonmarker/syntax_extension.c +0 -149
- data/ext/commonmarker/syntax_extension.h +0 -34
- data/ext/commonmarker/table.c +0 -917
- data/ext/commonmarker/table.h +0 -12
- data/ext/commonmarker/tagfilter.c +0 -60
- data/ext/commonmarker/tagfilter.h +0 -8
- data/ext/commonmarker/tasklist.c +0 -156
- data/ext/commonmarker/tasklist.h +0 -8
- data/ext/commonmarker/utf8.c +0 -317
- data/ext/commonmarker/utf8.h +0 -35
- data/ext/commonmarker/xml.c +0 -182
- data/lib/commonmarker/node/inspect.rb +0 -47
- data/lib/commonmarker/node.rb +0 -83
- data/lib/commonmarker/renderer/html_renderer.rb +0 -256
    
        data/Cargo.toml
    ADDED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,11 +1,13 @@ | |
| 1 | 
            -
            #  | 
| 1 | 
            +
            # Commonmarker
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 3 | 
            +
            > **Note**
         | 
| 4 | 
            +
            > This README refers to the behavior in the new 1.0.0.pre gem.
         | 
| 4 5 |  | 
| 5 | 
            -
            Ruby wrapper for [ | 
| 6 | 
            -
            GitHub's fork of the reference parser for CommonMark. It passes all of the C tests, and is therefore spec-complete. It also includes extensions to the CommonMark spec as documented in the [GitHub Flavored Markdown spec](http://github.github.com/gfm/), such as support for tables, strikethroughs, and autolinking.
         | 
| 6 | 
            +
            Ruby wrapper for Rust's [comrak](https://github.com/kivikakk/comrak) crate.
         | 
| 7 7 |  | 
| 8 | 
            -
             | 
| 8 | 
            +
            It passes all of the CommonMark test suite, and is therefore spec-complete. It also includes extensions to the CommonMark spec as documented in the [GitHub Flavored Markdown spec](http://github.github.com/gfm/), such as support for tables, strikethroughs, and autolinking.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            For more information on available extensions, see [the documentation below](#extension-options).
         | 
| 9 11 |  | 
| 10 12 | 
             
            ## Installation
         | 
| 11 13 |  | 
| @@ -25,234 +27,168 @@ Or install it yourself as: | |
| 25 27 |  | 
| 26 28 | 
             
            ### Converting to HTML
         | 
| 27 29 |  | 
| 28 | 
            -
            Call ` | 
| 29 | 
            -
             | 
| 30 | 
            -
            ``` ruby
         | 
| 31 | 
            -
            require 'commonmarker'
         | 
| 32 | 
            -
            CommonMarker.render_html('Hi *there*', :DEFAULT)
         | 
| 33 | 
            -
            # <p>Hi <em>there</em></p>\n
         | 
| 34 | 
            -
            ```
         | 
| 35 | 
            -
             | 
| 36 | 
            -
            The second argument is optional--[see below](#options) for more information.
         | 
| 37 | 
            -
             | 
| 38 | 
            -
            ### Generating a document
         | 
| 30 | 
            +
            Call `to_html` on a string to convert it to HTML:
         | 
| 39 31 |  | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
            ``` ruby
         | 
| 32 | 
            +
            ```ruby
         | 
| 43 33 | 
             
            require 'commonmarker'
         | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
            doc.walk do |node|
         | 
| 49 | 
            -
              puts node.type # [:document, :paragraph, :text, :emph, :text]
         | 
| 50 | 
            -
            end
         | 
| 34 | 
            +
            Commonmarker.to_html('"Hi *there*"', options: {
         | 
| 35 | 
            +
                parse: { smart: true }
         | 
| 36 | 
            +
            })
         | 
| 37 | 
            +
            # <p>“Hi <em>there</em>”</p>\n
         | 
| 51 38 | 
             
            ```
         | 
| 52 39 |  | 
| 53 40 | 
             
            The second argument is optional--[see below](#options) for more information.
         | 
| 54 41 |  | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
            You can use `walk` or `each` to iterate over nodes:
         | 
| 58 | 
            -
             | 
| 59 | 
            -
            - `walk` will iterate on a node and recursively iterate on a node's children.
         | 
| 60 | 
            -
            - `each` will iterate on a node and its children, but no further.
         | 
| 42 | 
            +
            ## Options and plugins
         | 
| 61 43 |  | 
| 62 | 
            -
             | 
| 63 | 
            -
            require 'commonmarker'
         | 
| 64 | 
            -
             | 
| 65 | 
            -
            # parse the files specified on the command line
         | 
| 66 | 
            -
            doc = CommonMarker.render_doc("# The site\n\n [GitHub](https://www.github.com)")
         | 
| 44 | 
            +
            ### Options
         | 
| 67 45 |  | 
| 68 | 
            -
             | 
| 69 | 
            -
            doc.walk do |node|
         | 
| 70 | 
            -
              if node.type == :link
         | 
| 71 | 
            -
                printf("URL = %s\n", node.url)
         | 
| 72 | 
            -
              end
         | 
| 73 | 
            -
            end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
            # Capitalize all regular text in headers
         | 
| 76 | 
            -
            doc.walk do |node|
         | 
| 77 | 
            -
              if node.type == :header
         | 
| 78 | 
            -
                node.each do |subnode|
         | 
| 79 | 
            -
                  if subnode.type == :text
         | 
| 80 | 
            -
                    subnode.string_content = subnode.string_content.upcase
         | 
| 81 | 
            -
                  end
         | 
| 82 | 
            -
                end
         | 
| 83 | 
            -
              end
         | 
| 84 | 
            -
            end
         | 
| 85 | 
            -
             | 
| 86 | 
            -
            # Transform links to regular text
         | 
| 87 | 
            -
            doc.walk do |node|
         | 
| 88 | 
            -
              if node.type == :link
         | 
| 89 | 
            -
                node.insert_before(node.first_child)
         | 
| 90 | 
            -
                node.delete
         | 
| 91 | 
            -
              end
         | 
| 92 | 
            -
            end
         | 
| 93 | 
            -
            ```
         | 
| 94 | 
            -
             | 
| 95 | 
            -
            ### Creating a custom renderer
         | 
| 96 | 
            -
             | 
| 97 | 
            -
            You can also derive a class from CommonMarker's `HtmlRenderer` class. This produces slower output, but is far more customizable. For example:
         | 
| 98 | 
            -
             | 
| 99 | 
            -
            ``` ruby
         | 
| 100 | 
            -
            class MyHtmlRenderer < CommonMarker::HtmlRenderer
         | 
| 101 | 
            -
              def initialize
         | 
| 102 | 
            -
                super
         | 
| 103 | 
            -
                @headerid = 1
         | 
| 104 | 
            -
              end
         | 
| 105 | 
            -
             | 
| 106 | 
            -
              def header(node)
         | 
| 107 | 
            -
                block do
         | 
| 108 | 
            -
                  out("<h", node.header_level, " id=\"", @headerid, "\">",
         | 
| 109 | 
            -
                           :children, "</h", node.header_level, ">")
         | 
| 110 | 
            -
                  @headerid += 1
         | 
| 111 | 
            -
                end
         | 
| 112 | 
            -
              end
         | 
| 113 | 
            -
            end
         | 
| 46 | 
            +
            Commonmarker accepts the same parse, render, and extensions options that comrak does, as a hash dictionary with symbol keys:
         | 
| 114 47 |  | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
              STDERR.write("#{w}\n")
         | 
| 121 | 
            -
            end
         | 
| 48 | 
            +
            ```ruby
         | 
| 49 | 
            +
            Commonmarker.to_html('"Hi *there*"', options:{
         | 
| 50 | 
            +
              parse: { smart: true },
         | 
| 51 | 
            +
              render: { hardbreaks: false}
         | 
| 52 | 
            +
            })
         | 
| 122 53 | 
             
            ```
         | 
| 123 54 |  | 
| 124 | 
            -
             | 
| 125 | 
            -
             | 
| 126 | 
            -
            CommonMarker accepts the same options that CMark does, as symbols. Note that there is a distinction in CMark for "parse" options and "render" options, which are represented in the tables below.
         | 
| 55 | 
            +
            Note that there is a distinction in comrak for "parse" options and "render" options, which are represented in the tables below.
         | 
| 127 56 |  | 
| 128 57 | 
             
            ### Parse options
         | 
| 129 58 |  | 
| 130 | 
            -
            | Name | 
| 131 | 
            -
            |  | 
| 132 | 
            -
            |  | 
| 133 | 
            -
            |  | 
| 134 | 
            -
            | `:UNSAFE`                     | Allow raw/custom HTML and unsafe links.
         | 
| 135 | 
            -
            | `:VALIDATE_UTF8`              | Replace illegal sequences with the replacement character `U+FFFD`.
         | 
| 136 | 
            -
            | `:SMART`                      | Use smart punctuation (curly quotes, etc.).
         | 
| 137 | 
            -
            | `:LIBERAL_HTML_TAG`           | Support liberal parsing of inline HTML tags.
         | 
| 138 | 
            -
            | `:FOOTNOTES`                  | Parse footnotes.
         | 
| 139 | 
            -
            | `:STRIKETHROUGH_DOUBLE_TILDE` | Parse strikethroughs by double tildes (compatibility with [redcarpet](https://github.com/vmg/redcarpet))
         | 
| 59 | 
            +
            | Name                  | Description                                                                          | Default |
         | 
| 60 | 
            +
            | --------------------- | ------------------------------------------------------------------------------------ | ------- |
         | 
| 61 | 
            +
            | `smart`               | Punctuation (quotes, full-stops and hyphens) are converted into 'smart' punctuation. | `false` |
         | 
| 62 | 
            +
            | `default_info_string` | The default info string for fenced code blocks.                                      | `""`    |
         | 
| 140 63 |  | 
| 141 64 | 
             
            ### Render options
         | 
| 142 65 |  | 
| 143 | 
            -
            | Name | 
| 144 | 
            -
            |  | 
| 145 | 
            -
            |  | 
| 146 | 
            -
            |  | 
| 147 | 
            -
            |  | 
| 148 | 
            -
            |  | 
| 149 | 
            -
            |  | 
| 150 | 
            -
            | `:VALIDATE_UTF8`                 | Replace illegal sequences with the replacement character `U+FFFD`. |
         | 
| 151 | 
            -
            | `:SMART`                         | Use smart punctuation (curly quotes, etc.).                     |
         | 
| 152 | 
            -
            | `:GITHUB_PRE_LANG`               | Use GitHub-style `<pre lang>` for fenced code blocks.           |
         | 
| 153 | 
            -
            | `:LIBERAL_HTML_TAG`              | Support liberal parsing of inline HTML tags.                    |
         | 
| 154 | 
            -
            | `:FOOTNOTES`                     | Render footnotes.                                               |
         | 
| 155 | 
            -
            | `:STRIKETHROUGH_DOUBLE_TILDE`    | Parse strikethroughs by double tildes (compatibility with [redcarpet](https://github.com/vmg/redcarpet)) |
         | 
| 156 | 
            -
            | `:TABLE_PREFER_STYLE_ATTRIBUTES` | Use `style` insted of `align` for table cells.                  |
         | 
| 157 | 
            -
            | `:FULL_INFO_STRING`              | Include full info strings of code blocks in separate attribute. |
         | 
| 158 | 
            -
             | 
| 159 | 
            -
            ### Passing options
         | 
| 160 | 
            -
             | 
| 161 | 
            -
            To apply a single option, pass it in as a symbol argument:
         | 
| 162 | 
            -
             | 
| 163 | 
            -
            ``` ruby
         | 
| 164 | 
            -
            CommonMarker.render_doc("\"Hello,\" said the spider.", :SMART)
         | 
| 165 | 
            -
            # <p>“Hello,” said the spider.</p>\n
         | 
| 166 | 
            -
            ```
         | 
| 66 | 
            +
            | Name              | Description                                                                                            | Default |
         | 
| 67 | 
            +
            | ----------------- | ------------------------------------------------------------------------------------------------------ | ------- |
         | 
| 68 | 
            +
            | `hardbreaks`      | [Soft line breaks](http://spec.commonmark.org/0.27/#soft-line-breaks) translate into hard line breaks. | `true`  |
         | 
| 69 | 
            +
            | `github_pre_lang` | GitHub-style `<pre lang="xyz">` is used for fenced code blocks with info tags.                         | `true`  |
         | 
| 70 | 
            +
            | `width`           | The wrap column when outputting CommonMark.                                                            | `80`    |
         | 
| 71 | 
            +
            | `unsafe`          | Allow rendering of raw HTML and potentially dangerous links.                                           | `false` |
         | 
| 72 | 
            +
            | `escape`          | Escape raw HTML instead of clobbering it.                                                              | `false` |
         | 
| 167 73 |  | 
| 168 | 
            -
             | 
| 74 | 
            +
            As well, there are several extensions which you can toggle in the same manner:
         | 
| 169 75 |  | 
| 170 | 
            -
            ``` | 
| 171 | 
            -
             | 
| 76 | 
            +
            ```ruby
         | 
| 77 | 
            +
            Commonmarker.to_html('"Hi *there*"', options: {
         | 
| 78 | 
            +
                extension: { footnotes: true, description_lists: true },
         | 
| 79 | 
            +
                render: { hardbreaks: false}
         | 
| 80 | 
            +
            })
         | 
| 172 81 | 
             
            ```
         | 
| 173 82 |  | 
| 174 | 
            -
             | 
| 175 | 
            -
             | 
| 176 | 
            -
             | 
| 177 | 
            -
             | 
| 178 | 
            -
             | 
| 83 | 
            +
            ### Extension options
         | 
| 84 | 
            +
             | 
| 85 | 
            +
            | Name                     | Description                                                                                                         | Default |
         | 
| 86 | 
            +
            | ------------------------ | ------------------------------------------------------------------------------------------------------------------- | ------- |
         | 
| 87 | 
            +
            | `strikethrough`          | Enables the [strikethrough extension](https://github.github.com/gfm/#strikethrough-extension-) from the GFM spec.   | `true`  |
         | 
| 88 | 
            +
            | `tagfilter`              | Enables the [tagfilter extension](https://github.github.com/gfm/#disallowed-raw-html-extension-) from the GFM spec. | `true`  |
         | 
| 89 | 
            +
            | `table`                  | Enables the [table extension](https://github.github.com/gfm/#tables-extension-) from the GFM spec.                  | `true`  |
         | 
| 90 | 
            +
            | `autolink`               | Enables the [autolink extension](https://github.github.com/gfm/#autolinks-extension-) from the GFM spec.            | `true`  |
         | 
| 91 | 
            +
            | `tasklist`               | Enables the [task list extension](https://github.github.com/gfm/#task-list-items-extension-) from the GFM spec.     | `true`  |
         | 
| 92 | 
            +
            | `superscript`            | Enables the superscript Comrak extension.                                                                           | `false` |
         | 
| 93 | 
            +
            | `header_ids`             | Enables the header IDs Comrak extension. from the GFM spec.                                                         | `""`    |
         | 
| 94 | 
            +
            | `footnotes`              | Enables the footnotes extension per `cmark-gfm`.                                                                    | `false` |
         | 
| 95 | 
            +
            | `description_lists`      | Enables the description lists extension.                                                                            | `false` |
         | 
| 96 | 
            +
            | `front_matter_delimiter` | Enables the front matter extension.                                                                                 | `""`    |
         | 
| 97 | 
            +
            | `shortcodes`             | Enables the shortcodes extension.                                                                                   | `true`  |
         | 
| 98 | 
            +
             | 
| 99 | 
            +
            For more information on these options, see [the comrak documentation](https://github.com/kivikakk/comrak#usage).
         | 
| 100 | 
            +
             | 
| 101 | 
            +
            ### Plugins
         | 
| 102 | 
            +
             | 
| 103 | 
            +
            In addition to the possibilities provided by generic CommonMark rendering, Commonmarker also supports plugins as a means of
         | 
| 104 | 
            +
            providing further niceties.
         | 
| 105 | 
            +
             | 
| 106 | 
            +
            #### Syntax Highlighter Plugin
         | 
| 107 | 
            +
             | 
| 108 | 
            +
            The library comes with [a set of pre-existing themes](https://docs.rs/syntect/5.0.0/syntect/highlighting/struct.ThemeSet.html#implementations) for highlighting code:
         | 
| 109 | 
            +
             | 
| 110 | 
            +
            - `"base16-ocean.dark"`
         | 
| 111 | 
            +
            - `"base16-eighties.dark"`
         | 
| 112 | 
            +
            - `"base16-mocha.dark"`
         | 
| 113 | 
            +
            - `"base16-ocean.light"`
         | 
| 114 | 
            +
            - `"InspiredGitHub"`
         | 
| 115 | 
            +
            - `"Solarized (dark)"`
         | 
| 116 | 
            +
            - `"Solarized (light)"`
         | 
| 117 | 
            +
             | 
| 118 | 
            +
            ````ruby
         | 
| 119 | 
            +
            code = <<~CODE
         | 
| 120 | 
            +
              ```ruby
         | 
| 121 | 
            +
              def hello
         | 
| 122 | 
            +
                puts "hello"
         | 
| 123 | 
            +
              end
         | 
| 124 | 
            +
              ```
         | 
| 125 | 
            +
            CODE
         | 
| 179 126 |  | 
| 180 | 
            -
             | 
| 127 | 
            +
            # pass in a theme name from a pre-existing set
         | 
| 128 | 
            +
            puts Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "InspiredGitHub" } })
         | 
| 181 129 |  | 
| 182 | 
            -
             | 
| 183 | 
            -
             | 
| 184 | 
            -
             | 
| 185 | 
            -
             | 
| 186 | 
            -
             | 
| 130 | 
            +
            # <pre style="background-color:#ffffff;" lang="ruby"><code>
         | 
| 131 | 
            +
            # <span style="font-weight:bold;color:#a71d5d;">def </span><span style="font-weight:bold;color:#795da3;">hello
         | 
| 132 | 
            +
            # </span><span style="color:#62a35c;">puts </span><span style="color:#183691;">"hello"
         | 
| 133 | 
            +
            # </span><span style="font-weight:bold;color:#a71d5d;">end
         | 
| 134 | 
            +
            # </span>
         | 
| 135 | 
            +
            # </code></pre>
         | 
| 136 | 
            +
            ````
         | 
| 187 137 |  | 
| 188 | 
            -
             | 
| 138 | 
            +
            By default, the plugin uses the `"base16-ocean.dark"` theme to syntax highlight code.
         | 
| 189 139 |  | 
| 190 | 
            -
             | 
| 140 | 
            +
            To disable this plugin, set the value to `nil`:
         | 
| 191 141 |  | 
| 192 | 
            -
             | 
| 142 | 
            +
            ````ruby
         | 
| 143 | 
            +
            code = <<~CODE
         | 
| 144 | 
            +
              ```ruby
         | 
| 145 | 
            +
              def hello
         | 
| 146 | 
            +
                puts "hello"
         | 
| 147 | 
            +
              end
         | 
| 148 | 
            +
              ```
         | 
| 149 | 
            +
            CODE
         | 
| 193 150 |  | 
| 194 | 
            -
             | 
| 151 | 
            +
            Commonmarker.to_html(code, plugins: { syntax_highlighter: nil })
         | 
| 195 152 |  | 
| 196 | 
            -
             | 
| 197 | 
            -
             | 
| 198 | 
            -
             | 
| 153 | 
            +
            # <pre lang="ruby"><code>def hello
         | 
| 154 | 
            +
            #   puts "hello"
         | 
| 155 | 
            +
            # end
         | 
| 156 | 
            +
            # </code></pre>
         | 
| 157 | 
            +
            ````
         | 
| 199 158 |  | 
| 200 | 
            -
             | 
| 201 | 
            -
            ```
         | 
| 159 | 
            +
            To output CSS classes instead of `style` attributes, set the `theme` key to `""`:
         | 
| 202 160 |  | 
| 203 | 
            -
             | 
| 204 | 
            -
             | 
| 205 | 
            -
             | 
| 161 | 
            +
            ````ruby
         | 
| 162 | 
            +
            code = <<~CODE
         | 
| 163 | 
            +
              ```ruby
         | 
| 164 | 
            +
              def hello
         | 
| 165 | 
            +
                puts "hello"
         | 
| 166 | 
            +
              end
         | 
| 167 | 
            +
            CODE
         | 
| 206 168 |  | 
| 207 | 
            -
             | 
| 208 | 
            -
            doc = CommonMarker.render_doc('*Hello* world!', :DEFAULT)
         | 
| 209 | 
            -
            puts(doc.to_xml)
         | 
| 210 | 
            -
             | 
| 211 | 
            -
            <?xml version="1.0" encoding="UTF-8"?>
         | 
| 212 | 
            -
            <!DOCTYPE document SYSTEM "CommonMark.dtd">
         | 
| 213 | 
            -
            <document xmlns="http://commonmark.org/xml/1.0">
         | 
| 214 | 
            -
              <paragraph>
         | 
| 215 | 
            -
                <emph>
         | 
| 216 | 
            -
                  <text xml:space="preserve">Hello</text>
         | 
| 217 | 
            -
                </emph>
         | 
| 218 | 
            -
                <text xml:space="preserve"> world!</text>
         | 
| 219 | 
            -
              </paragraph>
         | 
| 220 | 
            -
            </document>
         | 
| 221 | 
            -
            ```
         | 
| 169 | 
            +
            Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "" } })
         | 
| 222 170 |  | 
| 223 | 
            -
             | 
| 171 | 
            +
            # <pre class="syntax-highlighting"><code><span class="source ruby"><span class="meta function ruby"><span class="keyword control def ruby">def</span></span><span class="meta function ruby"> # <span class="entity name function ruby">hello</span></span>
         | 
| 172 | 
            +
            #   <span class="support function builtin ruby">puts</span> <span class="string quoted double ruby"><span class="punctuation definition string begin ruby">"</span>hello<span class="punctuation definition string end ruby">"</span></span>
         | 
| 173 | 
            +
            # <span class="keyword control ruby">end</span>\n</span></code></pre>
         | 
| 174 | 
            +
            ````
         | 
| 224 175 |  | 
| 225 | 
            -
             | 
| 176 | 
            +
            To use a custom theme, you can provide a `path` to a directory containing `.tmtheme` files to load:
         | 
| 226 177 |  | 
| 227 178 | 
             
            ```ruby
         | 
| 228 | 
            -
             | 
| 229 | 
            -
            puts(doc.to_plaintext)
         | 
| 230 | 
            -
             | 
| 231 | 
            -
            Hello world!
         | 
| 179 | 
            +
            Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "Monokai", path: "./themes" } })
         | 
| 232 180 | 
             
            ```
         | 
| 233 181 |  | 
| 234 | 
            -
             | 
| 235 | 
            -
             | 
| 236 | 
            -
            Commonmark will be generated when calling `to_commonmark` or using `--to=commonmark` on the command line.
         | 
| 237 | 
            -
             | 
| 238 | 
            -
            ``` ruby
         | 
| 239 | 
            -
            text = <<-TEXT
         | 
| 240 | 
            -
            1. I am a numeric list.
         | 
| 241 | 
            -
            2. I continue the list.
         | 
| 242 | 
            -
            * Suddenly, an unordered list!
         | 
| 243 | 
            -
            * What fun!
         | 
| 244 | 
            -
            TEXT
         | 
| 182 | 
            +
            ## Output formats
         | 
| 245 183 |  | 
| 246 | 
            -
             | 
| 247 | 
            -
            puts(doc.to_commonmark)
         | 
| 184 | 
            +
            Commonmarker can currently only generate output in one format: HTML.
         | 
| 248 185 |  | 
| 249 | 
            -
             | 
| 250 | 
            -
            2.  I continue the list.
         | 
| 186 | 
            +
            ### HTML
         | 
| 251 187 |  | 
| 252 | 
            -
             | 
| 188 | 
            +
            ```ruby
         | 
| 189 | 
            +
            puts Commonmarker.to_html('*Hello* world!')
         | 
| 253 190 |  | 
| 254 | 
            -
             | 
| 255 | 
            -
              - What fun\!
         | 
| 191 | 
            +
            # <p><em>Hello</em> world!</p>
         | 
| 256 192 | 
             
            ```
         | 
| 257 193 |  | 
| 258 194 | 
             
            ## Developing locally
         | 
| @@ -264,7 +200,7 @@ script/bootstrap | |
| 264 200 | 
             
            bundle exec rake compile
         | 
| 265 201 | 
             
            ```
         | 
| 266 202 |  | 
| 267 | 
            -
            If there were no errors, you're done! Otherwise, make sure to follow the  | 
| 203 | 
            +
            If there were no errors, you're done! Otherwise, make sure to follow the comrak dependency instructions.
         | 
| 268 204 |  | 
| 269 205 | 
             
            ## Benchmarks
         | 
| 270 206 |  | 
| @@ -273,16 +209,21 @@ Some rough benchmarks: | |
| 273 209 | 
             
            ```
         | 
| 274 210 | 
             
            $ bundle exec rake benchmark
         | 
| 275 211 |  | 
| 276 | 
            -
            input size =  | 
| 212 | 
            +
            input size = 11064832 bytes
         | 
| 277 213 |  | 
| 278 | 
            -
             | 
| 279 | 
            -
             | 
| 280 | 
            -
             | 
| 281 | 
            -
             | 
| 214 | 
            +
            Warming up --------------------------------------
         | 
| 215 | 
            +
                       redcarpet     2.000  i/100ms
         | 
| 216 | 
            +
            commonmarker with to_html
         | 
| 217 | 
            +
                                     1.000  i/100ms
         | 
| 218 | 
            +
                        kramdown     1.000  i/100ms
         | 
| 219 | 
            +
            Calculating -------------------------------------
         | 
| 220 | 
            +
                       redcarpet     22.317  (± 4.5%) i/s -    112.000  in   5.036374s
         | 
| 282 221 | 
             
            commonmarker with to_html
         | 
| 283 | 
            -
              0. | 
| 284 | 
            -
             | 
| 285 | 
            -
             | 
| 286 | 
            -
             | 
| 287 | 
            -
             | 
| 222 | 
            +
                                      5.815  (± 0.0%) i/s -     30.000  in   5.168869s
         | 
| 223 | 
            +
                        kramdown      0.327  (± 0.0%) i/s -      2.000  in   6.121486s
         | 
| 224 | 
            +
             | 
| 225 | 
            +
            Comparison:
         | 
| 226 | 
            +
                       redcarpet:       22.3 i/s
         | 
| 227 | 
            +
            commonmarker with to_html:        5.8 i/s - 3.84x  (± 0.00) slower
         | 
| 228 | 
            +
                        kramdown:        0.3 i/s - 68.30x  (± 0.00) slower
         | 
| 288 229 | 
             
            ```
         | 
| @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            [package]
         | 
| 2 | 
            +
            name = "commonmarker"
         | 
| 3 | 
            +
            version = "1.0.0"
         | 
| 4 | 
            +
            edition = "2021"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            [dependencies]
         | 
| 7 | 
            +
            magnus =  "0.6"
         | 
| 8 | 
            +
            comrak = { version = "0.20", features = ["shortcodes"] }
         | 
| 9 | 
            +
            syntect = { version = "5.1", features = ["plist-load"] }
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            [lib]
         | 
| 12 | 
            +
            name = "commonmarker"
         | 
| 13 | 
            +
            crate-type = ["cdylib"]
         | 
    
        data/ext/commonmarker/extconf.rb
    CHANGED
    
    
| @@ -0,0 +1,153 @@ | |
| 1 | 
            +
            extern crate core;
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            use std::path::PathBuf;
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            use ::syntect::highlighting::ThemeSet;
         | 
| 6 | 
            +
            use comrak::{
         | 
| 7 | 
            +
                adapters::SyntaxHighlighterAdapter,
         | 
| 8 | 
            +
                markdown_to_html, markdown_to_html_with_plugins,
         | 
| 9 | 
            +
                plugins::syntect::{SyntectAdapter, SyntectAdapterBuilder},
         | 
| 10 | 
            +
                ComrakOptions, ComrakPlugins,
         | 
| 11 | 
            +
            };
         | 
| 12 | 
            +
            use magnus::{
         | 
| 13 | 
            +
                define_module, exception, function, r_hash::ForEach, scan_args, Error, RHash, Symbol, Value,
         | 
| 14 | 
            +
            };
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            mod options;
         | 
| 17 | 
            +
            use options::iterate_options_hash;
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            mod plugins;
         | 
| 20 | 
            +
            use plugins::{
         | 
| 21 | 
            +
                syntax_highlighting::{fetch_syntax_highlighter_path, fetch_syntax_highlighter_theme},
         | 
| 22 | 
            +
                SYNTAX_HIGHLIGHTER_PLUGIN,
         | 
| 23 | 
            +
            };
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            mod utils;
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            pub const EMPTY_STR: &str = "";
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            fn commonmark_to_html(args: &[Value]) -> Result<String, magnus::Error> {
         | 
| 30 | 
            +
                let args = scan_args::scan_args::<_, (), (), (), _, ()>(args)?;
         | 
| 31 | 
            +
                let (rb_commonmark,): (String,) = args.required;
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                let kwargs = scan_args::get_kwargs::<_, (), (Option<RHash>, Option<RHash>), ()>(
         | 
| 34 | 
            +
                    args.keywords,
         | 
| 35 | 
            +
                    &[],
         | 
| 36 | 
            +
                    &["options", "plugins"],
         | 
| 37 | 
            +
                )?;
         | 
| 38 | 
            +
                let (rb_options, rb_plugins) = kwargs.optional;
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                let mut comrak_options = ComrakOptions::default();
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                if let Some(rb_options) = rb_options {
         | 
| 43 | 
            +
                    rb_options.foreach(|key: Symbol, value: RHash| {
         | 
| 44 | 
            +
                        iterate_options_hash(&mut comrak_options, key, value)?;
         | 
| 45 | 
            +
                        Ok(ForEach::Continue)
         | 
| 46 | 
            +
                    })?;
         | 
| 47 | 
            +
                }
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                if let Some(rb_plugins) = rb_plugins {
         | 
| 50 | 
            +
                    let mut comrak_plugins = ComrakPlugins::default();
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    let syntax_highlighter: Option<&dyn SyntaxHighlighterAdapter>;
         | 
| 53 | 
            +
                    let adapter: SyntectAdapter;
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                    let theme = match rb_plugins.get(Symbol::new(SYNTAX_HIGHLIGHTER_PLUGIN)) {
         | 
| 56 | 
            +
                        Some(syntax_highlighter_options) => {
         | 
| 57 | 
            +
                            match fetch_syntax_highlighter_theme(syntax_highlighter_options) {
         | 
| 58 | 
            +
                                Ok(theme) => theme,
         | 
| 59 | 
            +
                                Err(e) => {
         | 
| 60 | 
            +
                                    return Err(e);
         | 
| 61 | 
            +
                                }
         | 
| 62 | 
            +
                            }
         | 
| 63 | 
            +
                        }
         | 
| 64 | 
            +
                        None => None, // no `syntax_highlighter:` defined
         | 
| 65 | 
            +
                    };
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    match theme {
         | 
| 68 | 
            +
                        None => syntax_highlighter = None,
         | 
| 69 | 
            +
                        Some(theme) => {
         | 
| 70 | 
            +
                            if theme.is_empty() {
         | 
| 71 | 
            +
                                // no theme? uss css classes
         | 
| 72 | 
            +
                                adapter = SyntectAdapter::new(None);
         | 
| 73 | 
            +
                                syntax_highlighter = Some(&adapter);
         | 
| 74 | 
            +
                            } else {
         | 
| 75 | 
            +
                                let path = match rb_plugins.get(Symbol::new(SYNTAX_HIGHLIGHTER_PLUGIN)) {
         | 
| 76 | 
            +
                                    Some(syntax_highlighter_options) => {
         | 
| 77 | 
            +
                                        fetch_syntax_highlighter_path(syntax_highlighter_options)?
         | 
| 78 | 
            +
                                    }
         | 
| 79 | 
            +
                                    None => PathBuf::from("".to_string()), // no `syntax_highlighter:` defined
         | 
| 80 | 
            +
                                };
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                                if path.exists() {
         | 
| 83 | 
            +
                                    if !path.is_dir() {
         | 
| 84 | 
            +
                                        return Err(Error::new(
         | 
| 85 | 
            +
                                            exception::arg_error(),
         | 
| 86 | 
            +
                                            "`path` needs to be a directory",
         | 
| 87 | 
            +
                                        ));
         | 
| 88 | 
            +
                                    }
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                                    let builder = SyntectAdapterBuilder::new();
         | 
| 91 | 
            +
                                    let mut ts = ThemeSet::load_defaults();
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                                    match ts.add_from_folder(&path) {
         | 
| 94 | 
            +
                                        Ok(_) => {}
         | 
| 95 | 
            +
                                        Err(e) => {
         | 
| 96 | 
            +
                                            return Err(Error::new(
         | 
| 97 | 
            +
                                                exception::arg_error(),
         | 
| 98 | 
            +
                                                format!("failed to load theme set from path: {e}"),
         | 
| 99 | 
            +
                                            ));
         | 
| 100 | 
            +
                                        }
         | 
| 101 | 
            +
                                    }
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                                    // check if the theme exists in the dir
         | 
| 104 | 
            +
                                    match ts.themes.get(&theme) {
         | 
| 105 | 
            +
                                        Some(theme) => theme,
         | 
| 106 | 
            +
                                        None => {
         | 
| 107 | 
            +
                                            return Err(Error::new(
         | 
| 108 | 
            +
                                                exception::arg_error(),
         | 
| 109 | 
            +
                                                format!("theme `{}` does not exist", theme),
         | 
| 110 | 
            +
                                            ));
         | 
| 111 | 
            +
                                        }
         | 
| 112 | 
            +
                                    };
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                                    adapter = builder.theme_set(ts).theme(&theme).build();
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                                    syntax_highlighter = Some(&adapter);
         | 
| 117 | 
            +
                                } else {
         | 
| 118 | 
            +
                                    // no path? default theme lookup
         | 
| 119 | 
            +
                                    ThemeSet::load_defaults()
         | 
| 120 | 
            +
                                        .themes
         | 
| 121 | 
            +
                                        .get(&theme)
         | 
| 122 | 
            +
                                        .ok_or_else(|| {
         | 
| 123 | 
            +
                                            Error::new(
         | 
| 124 | 
            +
                                                exception::arg_error(),
         | 
| 125 | 
            +
                                                format!("theme `{}` does not exist", theme),
         | 
| 126 | 
            +
                                            )
         | 
| 127 | 
            +
                                        })?;
         | 
| 128 | 
            +
                                    adapter = SyntectAdapter::new(Some(&theme));
         | 
| 129 | 
            +
                                    syntax_highlighter = Some(&adapter);
         | 
| 130 | 
            +
                                }
         | 
| 131 | 
            +
                            }
         | 
| 132 | 
            +
                        }
         | 
| 133 | 
            +
                    }
         | 
| 134 | 
            +
                    comrak_plugins.render.codefence_syntax_highlighter = syntax_highlighter;
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                    Ok(markdown_to_html_with_plugins(
         | 
| 137 | 
            +
                        &rb_commonmark,
         | 
| 138 | 
            +
                        &comrak_options,
         | 
| 139 | 
            +
                        &comrak_plugins,
         | 
| 140 | 
            +
                    ))
         | 
| 141 | 
            +
                } else {
         | 
| 142 | 
            +
                    Ok(markdown_to_html(&rb_commonmark, &comrak_options))
         | 
| 143 | 
            +
                }
         | 
| 144 | 
            +
            }
         | 
| 145 | 
            +
             | 
| 146 | 
            +
            #[magnus::init]
         | 
| 147 | 
            +
            fn init() -> Result<(), Error> {
         | 
| 148 | 
            +
                let module = define_module("Commonmarker")?;
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                module.define_module_function("commonmark_to_html", function!(commonmark_to_html, -1))?;
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                Ok(())
         | 
| 153 | 
            +
            }
         |