redcarpet 2.1.1 → 2.2.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.
Potentially problematic release.
This version of redcarpet might be problematic. Click here for more details.
- data/Gemfile +2 -0
- data/Gemfile.lock +20 -0
- data/README.markdown +25 -20
- data/Rakefile +8 -20
- data/ext/redcarpet/autolink.c +52 -16
- data/ext/redcarpet/autolink.h +22 -7
- data/ext/redcarpet/buffer.c +2 -0
- data/ext/redcarpet/buffer.h +8 -0
- data/ext/redcarpet/html.c +8 -1
- data/ext/redcarpet/html.h +1 -0
- data/ext/redcarpet/html_smartypants.c +4 -0
- data/ext/redcarpet/markdown.c +173 -85
- data/ext/redcarpet/markdown.h +13 -5
- data/ext/redcarpet/rc_markdown.c +2 -2
- data/ext/redcarpet/rc_render.c +30 -3
- data/ext/redcarpet/redcarpet.h +2 -0
- data/ext/redcarpet/stack.h +8 -0
- data/lib/redcarpet.rb +2 -2
- data/redcarpet.gemspec +6 -3
- data/test/redcarpet_test.rb +24 -1
- metadata +26 -8
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            PATH
         | 
| 2 | 
            +
              remote: .
         | 
| 3 | 
            +
              specs:
         | 
| 4 | 
            +
                redcarpet (2.1.1)
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            GEM
         | 
| 7 | 
            +
              remote: http://rubygems.org/
         | 
| 8 | 
            +
              specs:
         | 
| 9 | 
            +
                nokogiri (1.5.5)
         | 
| 10 | 
            +
                rake (0.9.2.2)
         | 
| 11 | 
            +
                rake-compiler (0.8.1)
         | 
| 12 | 
            +
                  rake
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            PLATFORMS
         | 
| 15 | 
            +
              ruby
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            DEPENDENCIES
         | 
| 18 | 
            +
              nokogiri
         | 
| 19 | 
            +
              rake-compiler
         | 
| 20 | 
            +
              redcarpet!
         | 
    
        data/README.markdown
    CHANGED
    
    | @@ -9,14 +9,14 @@ case since version 2 -- it now has its own API, but retains the old name. Yes, | |
| 9 9 | 
             
            that does mean that Redcarpet 2 is not backwards-compatible with the 1.X
         | 
| 10 10 | 
             
            versions.
         | 
| 11 11 |  | 
| 12 | 
            -
            Redcarpet is powered by the [Sundown](https://www.github.com/ | 
| 12 | 
            +
            Redcarpet is powered by the [Sundown](https://www.github.com/vmg/sundown)
         | 
| 13 13 | 
             
            library. You might want to find out more about Sundown to see what makes this
         | 
| 14 14 | 
             
            Ruby library so awesome.
         | 
| 15 15 |  | 
| 16 16 | 
             
            This library is written by people
         | 
| 17 17 | 
             
            -------------------------------------------------------
         | 
| 18 18 |  | 
| 19 | 
            -
            Redcarpet 2 has been rewritten from scratch by Vicent Martí (@ | 
| 19 | 
            +
            Redcarpet 2 has been rewritten from scratch by Vicent Martí (@vmg). Why
         | 
| 20 20 | 
             
            are you not following me on Twitter?
         | 
| 21 21 |  | 
| 22 22 | 
             
            Redcarpet would not be possible without the Sundown library and its authors
         | 
| @@ -32,7 +32,7 @@ extensions, but the parser is standalone and requires no installed libraries. | |
| 32 32 |  | 
| 33 33 | 
             
            The Redcarpet source (including Sundown as a submodule) is available at GitHub:
         | 
| 34 34 |  | 
| 35 | 
            -
                $ git clone git://github.com/ | 
| 35 | 
            +
                $ git clone git://github.com/vmg/redcarpet.git
         | 
| 36 36 |  | 
| 37 37 | 
             
            And it's like *really* simple to use
         | 
| 38 38 | 
             
            ------------------------------------
         | 
| @@ -78,7 +78,7 @@ settings, and reused between parses. | |
| 78 78 | 
             
                                Two `~` characters mark the start of a strikethrough,
         | 
| 79 79 | 
             
                                e.g. `this is ~~good~~ bad`
         | 
| 80 80 |  | 
| 81 | 
            -
                            : | 
| 81 | 
            +
                            :lax_spacing - HTML blocks do not require to be surrounded
         | 
| 82 82 | 
             
                                by an empty line as in the Markdown standard.
         | 
| 83 83 |  | 
| 84 84 | 
             
                            :space_after_headers - A space is always required between the
         | 
| @@ -126,32 +126,33 @@ instantiating the renderer: | |
| 126 126 |  | 
| 127 127 | 
             
                Render::HTML.new(render_options={})
         | 
| 128 128 |  | 
| 129 | 
            -
             | 
| 129 | 
            +
            Initializes an HTML renderer. The following flags are available:
         | 
| 130 130 |  | 
| 131 | 
            -
             | 
| 131 | 
            +
                :filter_html - do not allow any user-inputted HTML in the output
         | 
| 132 132 |  | 
| 133 | 
            -
             | 
| 133 | 
            +
                :no_images - do not generate any `<img>` tags
         | 
| 134 134 |  | 
| 135 | 
            -
             | 
| 135 | 
            +
                :no_links - do not generate any `<a>` tags
         | 
| 136 136 |  | 
| 137 | 
            -
             | 
| 137 | 
            +
                :no_styles - do not generate any `<style>` tags
         | 
| 138 138 |  | 
| 139 | 
            -
             | 
| 139 | 
            +
                :safe_links_only - only generate links for protocols which are considered safe
         | 
| 140 140 |  | 
| 141 | 
            -
             | 
| 142 | 
            -
             | 
| 141 | 
            +
                :with_toc_data - add HTML anchors to each header in the output HTML,
         | 
| 142 | 
            +
                    to allow linking to each section.
         | 
| 143 143 |  | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 146 | 
            -
             | 
| 144 | 
            +
                :hard_wrap - insert HTML `<br>` tags inside on paragraphs where the origin
         | 
| 145 | 
            +
                    Markdown document had newlines (by default, Markdown ignores these
         | 
| 146 | 
            +
                    newlines).
         | 
| 147 147 |  | 
| 148 | 
            -
             | 
| 149 | 
            -
             | 
| 148 | 
            +
                :xhtml - output XHTML-conformant tags. This option is always enabled in the
         | 
| 149 | 
            +
                    `Render::XHTML` renderer.
         | 
| 150 150 |  | 
| 151 | 
            +
                    :link_attributes - hash of extra attributes to add to links
         | 
| 151 152 |  | 
| 152 | 
            -
             | 
| 153 | 
            +
            Example:
         | 
| 153 154 |  | 
| 154 | 
            -
             | 
| 155 | 
            +
                rndr = Redcarpet::Render::HTML.new(:no_links => true, :hard_wrap => true)
         | 
| 155 156 |  | 
| 156 157 |  | 
| 157 158 | 
             
            The `HTML` renderer has an alternate version, `Redcarpet::Render::HTML_TOC`,
         | 
| @@ -295,7 +296,7 @@ software accordingly, and force your users to install it. That's the | |
| 295 296 | 
             
            only way to have reliable and predictable Markdown output on your program.
         | 
| 296 297 |  | 
| 297 298 | 
             
            Still, if major forces (let's say, tornadoes or other natural disasters) force you
         | 
| 298 | 
            -
            to keep a Markdown-compatibility  | 
| 299 | 
            +
            to keep a Markdown-compatibility layer, Redcarpet also supports this:
         | 
| 299 300 |  | 
| 300 301 | 
             
                require 'redcarpet/compat'
         | 
| 301 302 |  | 
| @@ -311,6 +312,10 @@ that's a maintance nightmare and won't work. | |
| 311 312 | 
             
            On a related topic: if your Markdown gem has a `lib/markdown.rb` file that
         | 
| 312 313 | 
             
            monkeypatches the Markdown class, you're a terrible human being. Just saying.
         | 
| 313 314 |  | 
| 315 | 
            +
            Testing
         | 
| 316 | 
            +
            -------
         | 
| 317 | 
            +
            Tests run a lot faster without `bundle exec` :)
         | 
| 318 | 
            +
             | 
| 314 319 | 
             
            Boring legal stuff
         | 
| 315 320 | 
             
            ------------------
         | 
| 316 321 |  | 
    
        data/Rakefile
    CHANGED
    
    | @@ -3,7 +3,7 @@ require 'rake/clean' | |
| 3 3 | 
             
            require 'rake/extensiontask'
         | 
| 4 4 | 
             
            require 'digest/md5'
         | 
| 5 5 |  | 
| 6 | 
            -
            task :default => :test
         | 
| 6 | 
            +
            task :default => [:checkout, :test]
         | 
| 7 7 |  | 
| 8 8 | 
             
            # ==========================================================
         | 
| 9 9 | 
             
            # Ruby Extension
         | 
| @@ -11,6 +11,13 @@ task :default => :test | |
| 11 11 |  | 
| 12 12 | 
             
            Rake::ExtensionTask.new('redcarpet')
         | 
| 13 13 |  | 
| 14 | 
            +
            task :checkout do |t|
         | 
| 15 | 
            +
              unless File.exists?('sundown/src/markdown.h')
         | 
| 16 | 
            +
                sh 'git submodule init'
         | 
| 17 | 
            +
                sh 'git submodule update'
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| 20 | 
            +
             | 
| 14 21 | 
             
            # ==========================================================
         | 
| 15 22 | 
             
            # Testing
         | 
| 16 23 | 
             
            # ==========================================================
         | 
| @@ -109,22 +116,3 @@ task :update_gem do | |
| 109 116 | 
             
              puts "updated #{GEMFILE}"
         | 
| 110 117 | 
             
            end
         | 
| 111 118 |  | 
| 112 | 
            -
            desc 'Gather required Sundown sources into extension directory'
         | 
| 113 | 
            -
            task :gather => 'sundown/src/markdown.h' do |t|
         | 
| 114 | 
            -
              files =
         | 
| 115 | 
            -
                FileList[
         | 
| 116 | 
            -
                  'sundown/src/{markdown,buffer,stack,autolink,html_blocks}.h',
         | 
| 117 | 
            -
                  'sundown/src/{markdown,buffer,stack,autolink}.c',
         | 
| 118 | 
            -
                  'sundown/html/{html,html_smartypants,houdini_html_e,houdini_href_e}.c',
         | 
| 119 | 
            -
                  'sundown/html/{html,houdini}.h',
         | 
| 120 | 
            -
                ]
         | 
| 121 | 
            -
              cp files, 'ext/redcarpet/',
         | 
| 122 | 
            -
                :preserve => true,
         | 
| 123 | 
            -
                :verbose => true
         | 
| 124 | 
            -
            end
         | 
| 125 | 
            -
             | 
| 126 | 
            -
            file 'sundown/src/markdown.h' do |t|
         | 
| 127 | 
            -
              abort "The Sundown submodule is required."
         | 
| 128 | 
            -
            end
         | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
    
        data/ext/redcarpet/autolink.c
    CHANGED
    
    | @@ -15,12 +15,17 @@ | |
| 15 15 | 
             
             */
         | 
| 16 16 |  | 
| 17 17 | 
             
            #include "buffer.h"
         | 
| 18 | 
            +
            #include "autolink.h"
         | 
| 18 19 |  | 
| 19 20 | 
             
            #include <string.h>
         | 
| 20 21 | 
             
            #include <stdlib.h>
         | 
| 21 22 | 
             
            #include <stdio.h>
         | 
| 22 23 | 
             
            #include <ctype.h>
         | 
| 23 24 |  | 
| 25 | 
            +
            #if defined(_WIN32)
         | 
| 26 | 
            +
            #define strncasecmp	_strnicmp
         | 
| 27 | 
            +
            #endif
         | 
| 28 | 
            +
             | 
| 24 29 | 
             
            int
         | 
| 25 30 | 
             
            sd_autolink_issafe(const uint8_t *link, size_t link_len)
         | 
| 26 31 | 
             
            {
         | 
| @@ -44,7 +49,7 @@ sd_autolink_issafe(const uint8_t *link, size_t link_len) | |
| 44 49 | 
             
            }
         | 
| 45 50 |  | 
| 46 51 | 
             
            static size_t
         | 
| 47 | 
            -
            autolink_delim(uint8_t *data, size_t link_end, size_t  | 
| 52 | 
            +
            autolink_delim(uint8_t *data, size_t link_end, size_t max_rewind, size_t size)
         | 
| 48 53 | 
             
            {
         | 
| 49 54 | 
             
            	uint8_t cclose, copen = 0;
         | 
| 50 55 | 
             
            	size_t i;
         | 
| @@ -128,7 +133,7 @@ autolink_delim(uint8_t *data, size_t link_end, size_t offset, size_t size) | |
| 128 133 | 
             
            }
         | 
| 129 134 |  | 
| 130 135 | 
             
            static size_t
         | 
| 131 | 
            -
            check_domain(uint8_t *data, size_t size)
         | 
| 136 | 
            +
            check_domain(uint8_t *data, size_t size, int allow_short)
         | 
| 132 137 | 
             
            {
         | 
| 133 138 | 
             
            	size_t i, np = 0;
         | 
| 134 139 |  | 
| @@ -140,23 +145,37 @@ check_domain(uint8_t *data, size_t size) | |
| 140 145 | 
             
            		else if (!isalnum(data[i]) && data[i] != '-') break;
         | 
| 141 146 | 
             
            	}
         | 
| 142 147 |  | 
| 143 | 
            -
            	 | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 148 | 
            +
            	if (allow_short) {
         | 
| 149 | 
            +
            		/* We don't need a valid domain in the strict sense (with
         | 
| 150 | 
            +
            		 * least one dot; so just make sure it's composed of valid
         | 
| 151 | 
            +
            		 * domain characters and return the length of the the valid
         | 
| 152 | 
            +
            		 * sequence. */
         | 
| 153 | 
            +
            		return i;
         | 
| 154 | 
            +
            	} else {
         | 
| 155 | 
            +
            		/* a valid domain needs to have at least a dot.
         | 
| 156 | 
            +
            		 * that's as far as we get */
         | 
| 157 | 
            +
            		return np ? i : 0;
         | 
| 158 | 
            +
            	}
         | 
| 146 159 | 
             
            }
         | 
| 147 160 |  | 
| 148 161 | 
             
            size_t
         | 
| 149 | 
            -
            sd_autolink__www( | 
| 162 | 
            +
            sd_autolink__www(
         | 
| 163 | 
            +
            	size_t *rewind_p,
         | 
| 164 | 
            +
            	struct buf *link,
         | 
| 165 | 
            +
            	uint8_t *data,
         | 
| 166 | 
            +
            	size_t max_rewind,
         | 
| 167 | 
            +
            	size_t size,
         | 
| 168 | 
            +
            	unsigned int flags)
         | 
| 150 169 | 
             
            {
         | 
| 151 170 | 
             
            	size_t link_end;
         | 
| 152 171 |  | 
| 153 | 
            -
            	if ( | 
| 172 | 
            +
            	if (max_rewind > 0 && !ispunct(data[-1]) && !isspace(data[-1]))
         | 
| 154 173 | 
             
            		return 0;
         | 
| 155 174 |  | 
| 156 175 | 
             
            	if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0)
         | 
| 157 176 | 
             
            		return 0;
         | 
| 158 177 |  | 
| 159 | 
            -
            	link_end = check_domain(data, size);
         | 
| 178 | 
            +
            	link_end = check_domain(data, size, 0);
         | 
| 160 179 |  | 
| 161 180 | 
             
            	if (link_end == 0)
         | 
| 162 181 | 
             
            		return 0;
         | 
| @@ -164,7 +183,7 @@ sd_autolink__www(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offse | |
| 164 183 | 
             
            	while (link_end < size && !isspace(data[link_end]))
         | 
| 165 184 | 
             
            		link_end++;
         | 
| 166 185 |  | 
| 167 | 
            -
            	link_end = autolink_delim(data, link_end,  | 
| 186 | 
            +
            	link_end = autolink_delim(data, link_end, max_rewind, size);
         | 
| 168 187 |  | 
| 169 188 | 
             
            	if (link_end == 0)
         | 
| 170 189 | 
             
            		return 0;
         | 
| @@ -176,12 +195,18 @@ sd_autolink__www(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offse | |
| 176 195 | 
             
            }
         | 
| 177 196 |  | 
| 178 197 | 
             
            size_t
         | 
| 179 | 
            -
            sd_autolink__email( | 
| 198 | 
            +
            sd_autolink__email(
         | 
| 199 | 
            +
            	size_t *rewind_p,
         | 
| 200 | 
            +
            	struct buf *link,
         | 
| 201 | 
            +
            	uint8_t *data,
         | 
| 202 | 
            +
            	size_t max_rewind,
         | 
| 203 | 
            +
            	size_t size,
         | 
| 204 | 
            +
            	unsigned int flags)
         | 
| 180 205 | 
             
            {
         | 
| 181 206 | 
             
            	size_t link_end, rewind;
         | 
| 182 207 | 
             
            	int nb = 0, np = 0;
         | 
| 183 208 |  | 
| 184 | 
            -
            	for (rewind = 0; rewind <  | 
| 209 | 
            +
            	for (rewind = 0; rewind < max_rewind; ++rewind) {
         | 
| 185 210 | 
             
            		uint8_t c = data[-rewind - 1];
         | 
| 186 211 |  | 
| 187 212 | 
             
            		if (isalnum(c))
         | 
| @@ -213,7 +238,7 @@ sd_autolink__email(size_t *rewind_p, struct buf *link, uint8_t *data, size_t off | |
| 213 238 | 
             
            	if (link_end < 2 || nb != 1 || np == 0)
         | 
| 214 239 | 
             
            		return 0;
         | 
| 215 240 |  | 
| 216 | 
            -
            	link_end = autolink_delim(data, link_end,  | 
| 241 | 
            +
            	link_end = autolink_delim(data, link_end, max_rewind, size);
         | 
| 217 242 |  | 
| 218 243 | 
             
            	if (link_end == 0)
         | 
| 219 244 | 
             
            		return 0;
         | 
| @@ -225,21 +250,32 @@ sd_autolink__email(size_t *rewind_p, struct buf *link, uint8_t *data, size_t off | |
| 225 250 | 
             
            }
         | 
| 226 251 |  | 
| 227 252 | 
             
            size_t
         | 
| 228 | 
            -
            sd_autolink__url( | 
| 253 | 
            +
            sd_autolink__url(
         | 
| 254 | 
            +
            	size_t *rewind_p,
         | 
| 255 | 
            +
            	struct buf *link,
         | 
| 256 | 
            +
            	uint8_t *data,
         | 
| 257 | 
            +
            	size_t max_rewind,
         | 
| 258 | 
            +
            	size_t size,
         | 
| 259 | 
            +
            	unsigned int flags)
         | 
| 229 260 | 
             
            {
         | 
| 230 261 | 
             
            	size_t link_end, rewind = 0, domain_len;
         | 
| 231 262 |  | 
| 232 263 | 
             
            	if (size < 4 || data[1] != '/' || data[2] != '/')
         | 
| 233 264 | 
             
            		return 0;
         | 
| 234 265 |  | 
| 235 | 
            -
            	while (rewind <  | 
| 266 | 
            +
            	while (rewind < max_rewind && isalpha(data[-rewind - 1]))
         | 
| 236 267 | 
             
            		rewind++;
         | 
| 237 268 |  | 
| 238 269 | 
             
            	if (!sd_autolink_issafe(data - rewind, size + rewind))
         | 
| 239 270 | 
             
            		return 0;
         | 
| 271 | 
            +
             | 
| 240 272 | 
             
            	link_end = strlen("://");
         | 
| 241 273 |  | 
| 242 | 
            -
            	domain_len = check_domain( | 
| 274 | 
            +
            	domain_len = check_domain(
         | 
| 275 | 
            +
            		data + link_end,
         | 
| 276 | 
            +
            		size - link_end,
         | 
| 277 | 
            +
            		flags & SD_AUTOLINK_SHORT_DOMAINS);
         | 
| 278 | 
            +
             | 
| 243 279 | 
             
            	if (domain_len == 0)
         | 
| 244 280 | 
             
            		return 0;
         | 
| 245 281 |  | 
| @@ -247,7 +283,7 @@ sd_autolink__url(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offse | |
| 247 283 | 
             
            	while (link_end < size && !isspace(data[link_end]))
         | 
| 248 284 | 
             
            		link_end++;
         | 
| 249 285 |  | 
| 250 | 
            -
            	link_end = autolink_delim(data, link_end,  | 
| 286 | 
            +
            	link_end = autolink_delim(data, link_end, max_rewind, size);
         | 
| 251 287 |  | 
| 252 288 | 
             
            	if (link_end == 0)
         | 
| 253 289 | 
             
            		return 0;
         | 
    
        data/ext/redcarpet/autolink.h
    CHANGED
    
    | @@ -19,17 +19,32 @@ | |
| 19 19 |  | 
| 20 20 | 
             
            #include "buffer.h"
         | 
| 21 21 |  | 
| 22 | 
            -
             | 
| 22 | 
            +
            #ifdef __cplusplus
         | 
| 23 | 
            +
            extern "C" {
         | 
| 24 | 
            +
            #endif
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            enum {
         | 
| 27 | 
            +
            	SD_AUTOLINK_SHORT_DOMAINS = (1 << 0),
         | 
| 28 | 
            +
            };
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            int
         | 
| 23 31 | 
             
            sd_autolink_issafe(const uint8_t *link, size_t link_len);
         | 
| 24 32 |  | 
| 25 | 
            -
             | 
| 26 | 
            -
            sd_autolink__www(size_t *rewind_p, struct buf *link, | 
| 33 | 
            +
            size_t
         | 
| 34 | 
            +
            sd_autolink__www(size_t *rewind_p, struct buf *link,
         | 
| 35 | 
            +
            	uint8_t *data, size_t offset, size_t size, unsigned int flags);
         | 
| 27 36 |  | 
| 28 | 
            -
             | 
| 29 | 
            -
            sd_autolink__email(size_t *rewind_p, struct buf *link, | 
| 37 | 
            +
            size_t
         | 
| 38 | 
            +
            sd_autolink__email(size_t *rewind_p, struct buf *link,
         | 
| 39 | 
            +
            	uint8_t *data, size_t offset, size_t size, unsigned int flags);
         | 
| 30 40 |  | 
| 31 | 
            -
             | 
| 32 | 
            -
            sd_autolink__url(size_t *rewind_p, struct buf *link, | 
| 41 | 
            +
            size_t
         | 
| 42 | 
            +
            sd_autolink__url(size_t *rewind_p, struct buf *link,
         | 
| 43 | 
            +
            	uint8_t *data, size_t offset, size_t size, unsigned int flags);
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            #ifdef __cplusplus
         | 
| 46 | 
            +
            }
         | 
| 47 | 
            +
            #endif
         | 
| 33 48 |  | 
| 34 49 | 
             
            #endif
         | 
| 35 50 |  | 
    
        data/ext/redcarpet/buffer.c
    CHANGED
    
    
    
        data/ext/redcarpet/buffer.h
    CHANGED
    
    | @@ -22,6 +22,10 @@ | |
| 22 22 | 
             
            #include <stdarg.h>
         | 
| 23 23 | 
             
            #include <stdint.h>
         | 
| 24 24 |  | 
| 25 | 
            +
            #ifdef __cplusplus
         | 
| 26 | 
            +
            extern "C" {
         | 
| 27 | 
            +
            #endif
         | 
| 28 | 
            +
             | 
| 25 29 | 
             
            #if defined(_MSC_VER)
         | 
| 26 30 | 
             
            #define __attribute__(x)
         | 
| 27 31 | 
             
            #define inline
         | 
| @@ -85,4 +89,8 @@ void bufslurp(struct buf *, size_t); | |
| 85 89 | 
             
            /* bufprintf: formatted printing to a buffer */
         | 
| 86 90 | 
             
            void bufprintf(struct buf *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
         | 
| 87 91 |  | 
| 92 | 
            +
            #ifdef __cplusplus
         | 
| 93 | 
            +
            }
         | 
| 94 | 
            +
            #endif
         | 
| 95 | 
            +
             | 
| 88 96 | 
             
            #endif
         | 
    
        data/ext/redcarpet/html.c
    CHANGED
    
    | @@ -491,6 +491,13 @@ toc_header(struct buf *ob, const struct buf *text, int level, void *opaque) | |
| 491 491 | 
             
            {
         | 
| 492 492 | 
             
            	struct html_renderopt *options = opaque;
         | 
| 493 493 |  | 
| 494 | 
            +
            	/* set the level offset if this is the first header
         | 
| 495 | 
            +
            	 * we're parsing for the document */
         | 
| 496 | 
            +
            	if (options->toc_data.current_level == 0) {
         | 
| 497 | 
            +
            		options->toc_data.level_offset = level - 1;
         | 
| 498 | 
            +
            	}
         | 
| 499 | 
            +
            	level -= options->toc_data.level_offset;
         | 
| 500 | 
            +
             | 
| 494 501 | 
             
            	if (level > options->toc_data.current_level) {
         | 
| 495 502 | 
             
            		while (level > options->toc_data.current_level) {
         | 
| 496 503 | 
             
            			BUFPUTSL(ob, "<ul>\n<li>\n");
         | 
| @@ -516,7 +523,7 @@ toc_header(struct buf *ob, const struct buf *text, int level, void *opaque) | |
| 516 523 | 
             
            static int
         | 
| 517 524 | 
             
            toc_link(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *content, void *opaque)
         | 
| 518 525 | 
             
            {
         | 
| 519 | 
            -
            	if (content && content->size) | 
| 526 | 
            +
            	if (content && content->size)
         | 
| 520 527 | 
             
            		bufput(ob, content->data, content->size);
         | 
| 521 528 | 
             
            	return 1;
         | 
| 522 529 | 
             
            }
         | 
    
        data/ext/redcarpet/html.h
    CHANGED
    
    
    
        data/ext/redcarpet/markdown.c
    CHANGED
    
    | @@ -25,6 +25,10 @@ | |
| 25 25 | 
             
            #include <ctype.h>
         | 
| 26 26 | 
             
            #include <stdio.h>
         | 
| 27 27 |  | 
| 28 | 
            +
            #if defined(_WIN32)
         | 
| 29 | 
            +
            #define strncasecmp	_strnicmp
         | 
| 30 | 
            +
            #endif
         | 
| 31 | 
            +
             | 
| 28 32 | 
             
            #define REF_TABLE_SIZE 8
         | 
| 29 33 |  | 
| 30 34 | 
             
            #define BUFFER_BLOCK 0
         | 
| @@ -497,7 +501,7 @@ parse_emph1(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size | |
| 497 501 | 
             
            		if (data[i] == c && !_isspace(data[i - 1])) {
         | 
| 498 502 |  | 
| 499 503 | 
             
            			if (rndr->ext_flags & MKDEXT_NO_INTRA_EMPHASIS) {
         | 
| 500 | 
            -
            				if ( | 
| 504 | 
            +
            				if (i + i < size && isalnum(data[i + 1]))
         | 
| 501 505 | 
             
            					continue;
         | 
| 502 506 | 
             
            			}
         | 
| 503 507 |  | 
| @@ -592,6 +596,11 @@ char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t of | |
| 592 596 | 
             
            	uint8_t c = data[0];
         | 
| 593 597 | 
             
            	size_t ret;
         | 
| 594 598 |  | 
| 599 | 
            +
            	if (rndr->ext_flags & MKDEXT_NO_INTRA_EMPHASIS) {
         | 
| 600 | 
            +
            		if (offset > 0 && !_isspace(data[-1]) && data[-1] != '>')
         | 
| 601 | 
            +
            			return 0;
         | 
| 602 | 
            +
            	}
         | 
| 603 | 
            +
             | 
| 595 604 | 
             
            	if (size > 2 && data[1] != c) {
         | 
| 596 605 | 
             
            		/* whitespace cannot follow an opening emphasis;
         | 
| 597 606 | 
             
            		 * strikethrough only takes two characters '~~' */
         | 
| @@ -767,7 +776,7 @@ char_autolink_www(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_ | |
| 767 776 |  | 
| 768 777 | 
             
            	link = rndr_newbuf(rndr, BUFFER_SPAN);
         | 
| 769 778 |  | 
| 770 | 
            -
            	if ((link_len = sd_autolink__www(&rewind, link, data, offset, size)) > 0) {
         | 
| 779 | 
            +
            	if ((link_len = sd_autolink__www(&rewind, link, data, offset, size, 0)) > 0) {
         | 
| 771 780 | 
             
            		link_url = rndr_newbuf(rndr, BUFFER_SPAN);
         | 
| 772 781 | 
             
            		BUFPUTSL(link_url, "http://");
         | 
| 773 782 | 
             
            		bufput(link_url, link->data, link->size);
         | 
| @@ -799,7 +808,7 @@ char_autolink_email(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, siz | |
| 799 808 |  | 
| 800 809 | 
             
            	link = rndr_newbuf(rndr, BUFFER_SPAN);
         | 
| 801 810 |  | 
| 802 | 
            -
            	if ((link_len = sd_autolink__email(&rewind, link, data, offset, size)) > 0) {
         | 
| 811 | 
            +
            	if ((link_len = sd_autolink__email(&rewind, link, data, offset, size, 0)) > 0) {
         | 
| 803 812 | 
             
            		ob->size -= rewind;
         | 
| 804 813 | 
             
            		rndr->cb.autolink(ob, link, MKDA_EMAIL, rndr->opaque);
         | 
| 805 814 | 
             
            	}
         | 
| @@ -819,7 +828,7 @@ char_autolink_url(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_ | |
| 819 828 |  | 
| 820 829 | 
             
            	link = rndr_newbuf(rndr, BUFFER_SPAN);
         | 
| 821 830 |  | 
| 822 | 
            -
            	if ((link_len = sd_autolink__url(&rewind, link, data, offset, size)) > 0) {
         | 
| 831 | 
            +
            	if ((link_len = sd_autolink__url(&rewind, link, data, offset, size, 0)) > 0) {
         | 
| 823 832 | 
             
            		ob->size -= rewind;
         | 
| 824 833 | 
             
            		rndr->cb.autolink(ob, link, MKDA_NORMAL, rndr->opaque);
         | 
| 825 834 | 
             
            	}
         | 
| @@ -1150,9 +1159,10 @@ is_hrule(uint8_t *data, size_t size) | |
| 1150 1159 | 
             
            	return n >= 3;
         | 
| 1151 1160 | 
             
            }
         | 
| 1152 1161 |  | 
| 1153 | 
            -
            /* check if a line  | 
| 1162 | 
            +
            /* check if a line begins with a code fence; return the
         | 
| 1163 | 
            +
             * width of the code fence */
         | 
| 1154 1164 | 
             
            static size_t
         | 
| 1155 | 
            -
             | 
| 1165 | 
            +
            prefix_codefence(uint8_t *data, size_t size)
         | 
| 1156 1166 | 
             
            {
         | 
| 1157 1167 | 
             
            	size_t i = 0, n = 0;
         | 
| 1158 1168 | 
             
            	uint8_t c;
         | 
| @@ -1177,41 +1187,54 @@ is_codefence(uint8_t *data, size_t size, struct buf *syntax) | |
| 1177 1187 | 
             
            	if (n < 3)
         | 
| 1178 1188 | 
             
            		return 0;
         | 
| 1179 1189 |  | 
| 1180 | 
            -
            	 | 
| 1181 | 
            -
             | 
| 1190 | 
            +
            	return i;
         | 
| 1191 | 
            +
            }
         | 
| 1182 1192 |  | 
| 1183 | 
            -
             | 
| 1184 | 
            -
             | 
| 1193 | 
            +
            /* check if a line is a code fence; return its size if it is */
         | 
| 1194 | 
            +
            static size_t
         | 
| 1195 | 
            +
            is_codefence(uint8_t *data, size_t size, struct buf *syntax)
         | 
| 1196 | 
            +
            {
         | 
| 1197 | 
            +
            	size_t i = 0, syn_len = 0;
         | 
| 1198 | 
            +
            	uint8_t *syn_start;
         | 
| 1185 1199 |  | 
| 1186 | 
            -
             | 
| 1200 | 
            +
            	i = prefix_codefence(data, size);
         | 
| 1201 | 
            +
            	if (i == 0)
         | 
| 1202 | 
            +
            		return 0;
         | 
| 1187 1203 |  | 
| 1188 | 
            -
             | 
| 1189 | 
            -
             | 
| 1204 | 
            +
            	while (i < size && data[i] == ' ')
         | 
| 1205 | 
            +
            		i++;
         | 
| 1190 1206 |  | 
| 1191 | 
            -
             | 
| 1192 | 
            -
            				syn++; i++;
         | 
| 1193 | 
            -
            			}
         | 
| 1207 | 
            +
            	syn_start = data + i;
         | 
| 1194 1208 |  | 
| 1195 | 
            -
             | 
| 1196 | 
            -
             | 
| 1209 | 
            +
            	if (i < size && data[i] == '{') {
         | 
| 1210 | 
            +
            		i++; syn_start++;
         | 
| 1197 1211 |  | 
| 1198 | 
            -
             | 
| 1199 | 
            -
             | 
| 1200 | 
            -
             | 
| 1201 | 
            -
            				syntax->data++; syn--;
         | 
| 1202 | 
            -
            			}
         | 
| 1212 | 
            +
            		while (i < size && data[i] != '}' && data[i] != '\n') {
         | 
| 1213 | 
            +
            			syn_len++; i++;
         | 
| 1214 | 
            +
            		}
         | 
| 1203 1215 |  | 
| 1204 | 
            -
             | 
| 1205 | 
            -
             | 
| 1216 | 
            +
            		if (i == size || data[i] != '}')
         | 
| 1217 | 
            +
            			return 0;
         | 
| 1206 1218 |  | 
| 1207 | 
            -
             | 
| 1208 | 
            -
             | 
| 1209 | 
            -
             | 
| 1210 | 
            -
             | 
| 1211 | 
            -
            			}
         | 
| 1219 | 
            +
            		/* strip all whitespace at the beginning and the end
         | 
| 1220 | 
            +
            		 * of the {} block */
         | 
| 1221 | 
            +
            		while (syn_len > 0 && _isspace(syn_start[0])) {
         | 
| 1222 | 
            +
            			syn_start++; syn_len--;
         | 
| 1212 1223 | 
             
            		}
         | 
| 1213 1224 |  | 
| 1214 | 
            -
            		 | 
| 1225 | 
            +
            		while (syn_len > 0 && _isspace(syn_start[syn_len - 1]))
         | 
| 1226 | 
            +
            			syn_len--;
         | 
| 1227 | 
            +
             | 
| 1228 | 
            +
            		i++;
         | 
| 1229 | 
            +
            	} else {
         | 
| 1230 | 
            +
            		while (i < size && !_isspace(data[i])) {
         | 
| 1231 | 
            +
            			syn_len++; i++;
         | 
| 1232 | 
            +
            		}
         | 
| 1233 | 
            +
            	}
         | 
| 1234 | 
            +
             | 
| 1235 | 
            +
            	if (syntax) {
         | 
| 1236 | 
            +
            		syntax->data = syn_start;
         | 
| 1237 | 
            +
            		syntax->size = syn_len;
         | 
| 1215 1238 | 
             
            	}
         | 
| 1216 1239 |  | 
| 1217 1240 | 
             
            	while (i < size && data[i] != '\n') {
         | 
| @@ -1416,19 +1439,48 @@ parse_paragraph(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t | |
| 1416 1439 | 
             
            	while (i < size) {
         | 
| 1417 1440 | 
             
            		for (end = i + 1; end < size && data[end - 1] != '\n'; end++) /* empty */;
         | 
| 1418 1441 |  | 
| 1419 | 
            -
            		if (is_empty(data + i, size - i) | 
| 1442 | 
            +
            		if (is_empty(data + i, size - i))
         | 
| 1443 | 
            +
            			break;
         | 
| 1444 | 
            +
             | 
| 1445 | 
            +
            		if ((level = is_headerline(data + i, size - i)) != 0)
         | 
| 1446 | 
            +
            			break;
         | 
| 1447 | 
            +
             | 
| 1448 | 
            +
            		if (is_atxheader(rndr, data + i, size - i) ||
         | 
| 1449 | 
            +
            			is_hrule(data + i, size - i) ||
         | 
| 1450 | 
            +
            			prefix_quote(data + i, size - i)) {
         | 
| 1451 | 
            +
            			end = i;
         | 
| 1420 1452 | 
             
            			break;
         | 
| 1453 | 
            +
            		}
         | 
| 1421 1454 |  | 
| 1422 | 
            -
            		 | 
| 1423 | 
            -
             | 
| 1455 | 
            +
            		/*
         | 
| 1456 | 
            +
            		 * Early termination of a paragraph with the same logic
         | 
| 1457 | 
            +
            		 * as Markdown 1.0.0. If this logic is applied, the
         | 
| 1458 | 
            +
            		 * Markdown 1.0.3 test suite won't pass cleanly
         | 
| 1459 | 
            +
            		 *
         | 
| 1460 | 
            +
            		 * :: If the first character in a new line is not a letter,
         | 
| 1461 | 
            +
            		 * let's check to see if there's some kind of block starting
         | 
| 1462 | 
            +
            		 * here
         | 
| 1463 | 
            +
            		 */
         | 
| 1464 | 
            +
            		if ((rndr->ext_flags & MKDEXT_LAX_SPACING) && !isalnum(data[i])) {
         | 
| 1465 | 
            +
            			if (prefix_oli(data + i, size - i) ||
         | 
| 1466 | 
            +
            				prefix_uli(data + i, size - i)) {
         | 
| 1424 1467 | 
             
            				end = i;
         | 
| 1425 1468 | 
             
            				break;
         | 
| 1426 1469 | 
             
            			}
         | 
| 1427 | 
            -
            		}
         | 
| 1428 1470 |  | 
| 1429 | 
            -
             | 
| 1430 | 
            -
            			 | 
| 1431 | 
            -
             | 
| 1471 | 
            +
            			/* see if an html block starts here */
         | 
| 1472 | 
            +
            			if (data[i] == '<' && rndr->cb.blockhtml &&
         | 
| 1473 | 
            +
            				parse_htmlblock(ob, rndr, data + i, size - i, 0)) {
         | 
| 1474 | 
            +
            				end = i;
         | 
| 1475 | 
            +
            				break;
         | 
| 1476 | 
            +
            			}
         | 
| 1477 | 
            +
             | 
| 1478 | 
            +
            			/* see if a code fence starts here */
         | 
| 1479 | 
            +
            			if ((rndr->ext_flags & MKDEXT_FENCED_CODE) != 0 &&
         | 
| 1480 | 
            +
            				is_codefence(data + i, size - i, NULL) != 0) {
         | 
| 1481 | 
            +
            				end = i;
         | 
| 1482 | 
            +
            				break;
         | 
| 1483 | 
            +
            			}
         | 
| 1432 1484 | 
             
            		}
         | 
| 1433 1485 |  | 
| 1434 1486 | 
             
            		i = end;
         | 
| @@ -1500,9 +1552,10 @@ parse_fencedcode(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t | |
| 1500 1552 |  | 
| 1501 1553 | 
             
            	while (beg < size) {
         | 
| 1502 1554 | 
             
            		size_t fence_end;
         | 
| 1555 | 
            +
            		struct buf fence_trail = { 0, 0, 0, 0 };
         | 
| 1503 1556 |  | 
| 1504 | 
            -
            		fence_end = is_codefence(data + beg, size - beg,  | 
| 1505 | 
            -
            		if (fence_end != 0) {
         | 
| 1557 | 
            +
            		fence_end = is_codefence(data + beg, size - beg, &fence_trail);
         | 
| 1558 | 
            +
            		if (fence_end != 0 && fence_trail.size == 0) {
         | 
| 1506 1559 | 
             
            			beg += fence_end;
         | 
| 1507 1560 | 
             
            			break;
         | 
| 1508 1561 | 
             
            		}
         | 
| @@ -1577,8 +1630,7 @@ parse_listitem(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t s | |
| 1577 1630 | 
             
            {
         | 
| 1578 1631 | 
             
            	struct buf *work = 0, *inter = 0;
         | 
| 1579 1632 | 
             
            	size_t beg = 0, end, pre, sublist = 0, orgpre = 0, i;
         | 
| 1580 | 
            -
            	int in_empty = 0, has_inside_empty = 0;
         | 
| 1581 | 
            -
            	size_t has_next_uli, has_next_oli;
         | 
| 1633 | 
            +
            	int in_empty = 0, has_inside_empty = 0, in_fence = 0;
         | 
| 1582 1634 |  | 
| 1583 1635 | 
             
            	/* keeping track of the first indentation prefix */
         | 
| 1584 1636 | 
             
            	while (orgpre < 3 && orgpre < size && data[orgpre] == ' ')
         | 
| @@ -1606,6 +1658,8 @@ parse_listitem(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t s | |
| 1606 1658 |  | 
| 1607 1659 | 
             
            	/* process the following lines */
         | 
| 1608 1660 | 
             
            	while (beg < size) {
         | 
| 1661 | 
            +
            		size_t has_next_uli = 0, has_next_oli = 0;
         | 
| 1662 | 
            +
             | 
| 1609 1663 | 
             
            		end++;
         | 
| 1610 1664 |  | 
| 1611 1665 | 
             
            		while (end < size && data[end - 1] != '\n')
         | 
| @@ -1625,8 +1679,17 @@ parse_listitem(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t s | |
| 1625 1679 |  | 
| 1626 1680 | 
             
            		pre = i;
         | 
| 1627 1681 |  | 
| 1628 | 
            -
            		 | 
| 1629 | 
            -
             | 
| 1682 | 
            +
            		if (rndr->ext_flags & MKDEXT_FENCED_CODE) {
         | 
| 1683 | 
            +
            			if (is_codefence(data + beg + i, end - beg - i, NULL) != 0)
         | 
| 1684 | 
            +
            				in_fence = !in_fence;
         | 
| 1685 | 
            +
            		}
         | 
| 1686 | 
            +
             | 
| 1687 | 
            +
            		/* Only check for new list items if we are **not** inside
         | 
| 1688 | 
            +
            		 * a fenced code block */
         | 
| 1689 | 
            +
            		if (!in_fence) {
         | 
| 1690 | 
            +
            			has_next_uli = prefix_uli(data + beg + i, end - beg - i);
         | 
| 1691 | 
            +
            			has_next_oli = prefix_oli(data + beg + i, end - beg - i);
         | 
| 1692 | 
            +
            		}
         | 
| 1630 1693 |  | 
| 1631 1694 | 
             
            		/* checking for ul/ol switch */
         | 
| 1632 1695 | 
             
            		if (in_empty && (
         | 
| @@ -1647,10 +1710,12 @@ parse_listitem(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t s | |
| 1647 1710 | 
             
            			if (!sublist)
         | 
| 1648 1711 | 
             
            				sublist = work->size;
         | 
| 1649 1712 | 
             
            		}
         | 
| 1650 | 
            -
            		/* joining only indented stuff after empty lines | 
| 1651 | 
            -
             | 
| 1652 | 
            -
             | 
| 1653 | 
            -
             | 
| 1713 | 
            +
            		/* joining only indented stuff after empty lines;
         | 
| 1714 | 
            +
            		 * note that now we only require 1 space of indentation
         | 
| 1715 | 
            +
            		 * to continue a list */
         | 
| 1716 | 
            +
            		else if (in_empty && pre == 0) {
         | 
| 1717 | 
            +
            			*flags |= MKD_LI_END;
         | 
| 1718 | 
            +
            			break;
         | 
| 1654 1719 | 
             
            		}
         | 
| 1655 1720 | 
             
            		else if (in_empty) {
         | 
| 1656 1721 | 
             
            			bufputc(work, '\n');
         | 
| @@ -1758,7 +1823,12 @@ parse_atxheader(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t | |
| 1758 1823 | 
             
            /* htmlblock_end • checking end of HTML block : </tag>[ \t]*\n[ \t*]\n */
         | 
| 1759 1824 | 
             
            /*	returns the length on match, 0 otherwise */
         | 
| 1760 1825 | 
             
            static size_t
         | 
| 1761 | 
            -
             | 
| 1826 | 
            +
            htmlblock_end_tag(
         | 
| 1827 | 
            +
            	const char *tag,
         | 
| 1828 | 
            +
            	size_t tag_len,
         | 
| 1829 | 
            +
            	struct sd_markdown *rndr,
         | 
| 1830 | 
            +
            	uint8_t *data,
         | 
| 1831 | 
            +
            	size_t size)
         | 
| 1762 1832 | 
             
            {
         | 
| 1763 1833 | 
             
            	size_t i, w;
         | 
| 1764 1834 |  | 
| @@ -1776,25 +1846,60 @@ htmlblock_end(const char *tag, size_t tag_len, struct sd_markdown *rndr, uint8_t | |
| 1776 1846 | 
             
            	i += w;
         | 
| 1777 1847 | 
             
            	w = 0;
         | 
| 1778 1848 |  | 
| 1779 | 
            -
            	if ( | 
| 1780 | 
            -
            		 | 
| 1781 | 
            -
            			w = is_empty(data + i, size - i);
         | 
| 1782 | 
            -
            	} else  {
         | 
| 1783 | 
            -
            		if (i < size && (w = is_empty(data + i, size - i)) == 0)
         | 
| 1784 | 
            -
            			return 0; /* non-blank line after tag line */
         | 
| 1785 | 
            -
            	}
         | 
| 1849 | 
            +
            	if (i < size)
         | 
| 1850 | 
            +
            		w = is_empty(data + i, size - i);
         | 
| 1786 1851 |  | 
| 1787 1852 | 
             
            	return i + w;
         | 
| 1788 1853 | 
             
            }
         | 
| 1789 1854 |  | 
| 1855 | 
            +
            static size_t
         | 
| 1856 | 
            +
            htmlblock_end(const char *curtag,
         | 
| 1857 | 
            +
            	struct sd_markdown *rndr,
         | 
| 1858 | 
            +
            	uint8_t *data,
         | 
| 1859 | 
            +
            	size_t size,
         | 
| 1860 | 
            +
            	int start_of_line)
         | 
| 1861 | 
            +
            {
         | 
| 1862 | 
            +
            	size_t tag_size = strlen(curtag);
         | 
| 1863 | 
            +
            	size_t i = 1, end_tag;
         | 
| 1864 | 
            +
            	int block_lines = 0;
         | 
| 1865 | 
            +
             | 
| 1866 | 
            +
            	while (i < size) {
         | 
| 1867 | 
            +
            		i++;
         | 
| 1868 | 
            +
            		while (i < size && !(data[i - 1] == '<' && data[i] == '/')) {
         | 
| 1869 | 
            +
            			if (data[i] == '\n')
         | 
| 1870 | 
            +
            				block_lines++;
         | 
| 1871 | 
            +
             | 
| 1872 | 
            +
            			i++;
         | 
| 1873 | 
            +
            		}
         | 
| 1874 | 
            +
             | 
| 1875 | 
            +
            		/* If we are only looking for unindented tags, skip the tag
         | 
| 1876 | 
            +
            		 * if it doesn't follow a newline.
         | 
| 1877 | 
            +
            		 *
         | 
| 1878 | 
            +
            		 * The only exception to this is if the tag is still on the
         | 
| 1879 | 
            +
            		 * initial line; in that case it still counts as a closing
         | 
| 1880 | 
            +
            		 * tag
         | 
| 1881 | 
            +
            		 */
         | 
| 1882 | 
            +
            		if (start_of_line && block_lines > 0 && data[i - 2] != '\n')
         | 
| 1883 | 
            +
            			continue;
         | 
| 1884 | 
            +
             | 
| 1885 | 
            +
            		if (i + 2 + tag_size >= size)
         | 
| 1886 | 
            +
            			break;
         | 
| 1887 | 
            +
             | 
| 1888 | 
            +
            		end_tag = htmlblock_end_tag(curtag, tag_size, rndr, data + i - 1, size - i + 1);
         | 
| 1889 | 
            +
            		if (end_tag)
         | 
| 1890 | 
            +
            			return i + end_tag - 1;
         | 
| 1891 | 
            +
            	}
         | 
| 1892 | 
            +
             | 
| 1893 | 
            +
            	return 0;
         | 
| 1894 | 
            +
            }
         | 
| 1895 | 
            +
             | 
| 1790 1896 |  | 
| 1791 1897 | 
             
            /* parse_htmlblock • parsing of inline HTML block */
         | 
| 1792 1898 | 
             
            static size_t
         | 
| 1793 1899 | 
             
            parse_htmlblock(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, int do_render)
         | 
| 1794 1900 | 
             
            {
         | 
| 1795 | 
            -
            	size_t i, j = 0;
         | 
| 1901 | 
            +
            	size_t i, j = 0, tag_end;
         | 
| 1796 1902 | 
             
            	const char *curtag = NULL;
         | 
| 1797 | 
            -
            	int found;
         | 
| 1798 1903 | 
             
            	struct buf work = { data, 0, 0, 0 };
         | 
| 1799 1904 |  | 
| 1800 1905 | 
             
            	/* identification of the opening tag */
         | 
| @@ -1855,40 +1960,23 @@ parse_htmlblock(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t | |
| 1855 1960 |  | 
| 1856 1961 | 
             
            	/* looking for an unindented matching closing tag */
         | 
| 1857 1962 | 
             
            	/*	followed by a blank line */
         | 
| 1858 | 
            -
            	 | 
| 1859 | 
            -
            	found = 0;
         | 
| 1963 | 
            +
            	tag_end = htmlblock_end(curtag, rndr, data, size, 1);
         | 
| 1860 1964 |  | 
| 1861 1965 | 
             
            	/* if not found, trying a second pass looking for indented match */
         | 
| 1862 1966 | 
             
            	/* but not if tag is "ins" or "del" (following original Markdown.pl) */
         | 
| 1863 | 
            -
            	if (strcmp(curtag, "ins") != 0 && strcmp(curtag, "del") != 0) {
         | 
| 1864 | 
            -
            		 | 
| 1865 | 
            -
            		i = 1;
         | 
| 1866 | 
            -
            		while (i < size) {
         | 
| 1867 | 
            -
            			i++;
         | 
| 1868 | 
            -
            			while (i < size && !(data[i - 1] == '<' && data[i] == '/'))
         | 
| 1869 | 
            -
            				i++;
         | 
| 1870 | 
            -
             | 
| 1871 | 
            -
            			if (i + 2 + tag_size >= size)
         | 
| 1872 | 
            -
            				break;
         | 
| 1873 | 
            -
             | 
| 1874 | 
            -
            			j = htmlblock_end(curtag, tag_size, rndr, data + i - 1, size - i + 1);
         | 
| 1875 | 
            -
             | 
| 1876 | 
            -
            			if (j) {
         | 
| 1877 | 
            -
            				i += j - 1;
         | 
| 1878 | 
            -
            				found = 1;
         | 
| 1879 | 
            -
            				break;
         | 
| 1880 | 
            -
            			}
         | 
| 1881 | 
            -
            		}
         | 
| 1967 | 
            +
            	if (!tag_end && strcmp(curtag, "ins") != 0 && strcmp(curtag, "del") != 0) {
         | 
| 1968 | 
            +
            		tag_end = htmlblock_end(curtag, rndr, data, size, 0);
         | 
| 1882 1969 | 
             
            	}
         | 
| 1883 1970 |  | 
| 1884 | 
            -
            	if (! | 
| 1971 | 
            +
            	if (!tag_end)
         | 
| 1972 | 
            +
            		return 0;
         | 
| 1885 1973 |  | 
| 1886 1974 | 
             
            	/* the end of the block has been found */
         | 
| 1887 | 
            -
            	work.size =  | 
| 1975 | 
            +
            	work.size = tag_end;
         | 
| 1888 1976 | 
             
            	if (do_render && rndr->cb.blockhtml)
         | 
| 1889 1977 | 
             
            		rndr->cb.blockhtml(ob, &work, rndr->opaque);
         | 
| 1890 1978 |  | 
| 1891 | 
            -
            	return  | 
| 1979 | 
            +
            	return tag_end;
         | 
| 1892 1980 | 
             
            }
         | 
| 1893 1981 |  | 
| 1894 1982 | 
             
            static void
         | 
| @@ -2460,9 +2548,9 @@ sd_markdown_free(struct sd_markdown *md) | |
| 2460 2548 | 
             
            void
         | 
| 2461 2549 | 
             
            sd_version(int *ver_major, int *ver_minor, int *ver_revision)
         | 
| 2462 2550 | 
             
            {
         | 
| 2463 | 
            -
            	*ver_major =  | 
| 2464 | 
            -
            	*ver_minor =  | 
| 2465 | 
            -
            	*ver_revision =  | 
| 2551 | 
            +
            	*ver_major = SUNDOWN_VER_MAJOR;
         | 
| 2552 | 
            +
            	*ver_minor = SUNDOWN_VER_MINOR;
         | 
| 2553 | 
            +
            	*ver_revision = SUNDOWN_VER_REVISION;
         | 
| 2466 2554 | 
             
            }
         | 
| 2467 2555 |  | 
| 2468 2556 | 
             
            /* vim: set filetype=c: */
         | 
    
        data/ext/redcarpet/markdown.h
    CHANGED
    
    | @@ -22,10 +22,14 @@ | |
| 22 22 | 
             
            #include "buffer.h"
         | 
| 23 23 | 
             
            #include "autolink.h"
         | 
| 24 24 |  | 
| 25 | 
            -
            # | 
| 26 | 
            -
             | 
| 27 | 
            -
            # | 
| 28 | 
            -
             | 
| 25 | 
            +
            #ifdef __cplusplus
         | 
| 26 | 
            +
            extern "C" {
         | 
| 27 | 
            +
            #endif
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            #define SUNDOWN_VERSION "1.16.0"
         | 
| 30 | 
            +
            #define SUNDOWN_VER_MAJOR 1
         | 
| 31 | 
            +
            #define SUNDOWN_VER_MINOR 16
         | 
| 32 | 
            +
            #define SUNDOWN_VER_REVISION 0
         | 
| 29 33 |  | 
| 30 34 | 
             
            /********************
         | 
| 31 35 | 
             
             * TYPE DEFINITIONS *
         | 
| @@ -52,9 +56,9 @@ enum mkd_extensions { | |
| 52 56 | 
             
            	MKDEXT_FENCED_CODE = (1 << 2),
         | 
| 53 57 | 
             
            	MKDEXT_AUTOLINK = (1 << 3),
         | 
| 54 58 | 
             
            	MKDEXT_STRIKETHROUGH = (1 << 4),
         | 
| 55 | 
            -
            	MKDEXT_LAX_HTML_BLOCKS = (1 << 5),
         | 
| 56 59 | 
             
            	MKDEXT_SPACE_HEADERS = (1 << 6),
         | 
| 57 60 | 
             
            	MKDEXT_SUPERSCRIPT = (1 << 7),
         | 
| 61 | 
            +
            	MKDEXT_LAX_SPACING = (1 << 8),
         | 
| 58 62 | 
             
            };
         | 
| 59 63 |  | 
| 60 64 | 
             
            /* sd_callbacks - functions for rendering parsed data */
         | 
| @@ -125,6 +129,10 @@ sd_markdown_free(struct sd_markdown *md); | |
| 125 129 | 
             
            extern void
         | 
| 126 130 | 
             
            sd_version(int *major, int *minor, int *revision);
         | 
| 127 131 |  | 
| 132 | 
            +
            #ifdef __cplusplus
         | 
| 133 | 
            +
            }
         | 
| 134 | 
            +
            #endif
         | 
| 135 | 
            +
             | 
| 128 136 | 
             
            #endif
         | 
| 129 137 |  | 
| 130 138 | 
             
            /* vim: set filetype=c: */
         | 
    
        data/ext/redcarpet/rc_markdown.c
    CHANGED
    
    | @@ -44,8 +44,8 @@ static void rb_redcarpet_md_flags(VALUE hash, unsigned int *enabled_extensions_p | |
| 44 44 | 
             
            	if (rb_hash_lookup(hash, CSTR2SYM("strikethrough")) == Qtrue)
         | 
| 45 45 | 
             
            		extensions |= MKDEXT_STRIKETHROUGH;
         | 
| 46 46 |  | 
| 47 | 
            -
            	if (rb_hash_lookup(hash, CSTR2SYM(" | 
| 48 | 
            -
            		extensions |=  | 
| 47 | 
            +
            	if (rb_hash_lookup(hash, CSTR2SYM("lax_spacing")) == Qtrue)
         | 
| 48 | 
            +
            		extensions |= MKDEXT_LAX_SPACING;
         | 
| 49 49 |  | 
| 50 50 | 
             
            	if (rb_hash_lookup(hash, CSTR2SYM("space_after_headers")) == Qtrue)
         | 
| 51 51 | 
             
            		extensions |= MKDEXT_SPACE_HEADERS;
         | 
    
        data/ext/redcarpet/rc_render.c
    CHANGED
    
    | @@ -234,6 +234,27 @@ rndr_doc_footer(struct buf *ob, void *opaque) | |
| 234 234 | 
             
            	BLOCK_CALLBACK("doc_footer", 0);
         | 
| 235 235 | 
             
            }
         | 
| 236 236 |  | 
| 237 | 
            +
            static int
         | 
| 238 | 
            +
            cb_link_attribute(VALUE key, VALUE val, VALUE payload)
         | 
| 239 | 
            +
            {
         | 
| 240 | 
            +
            	struct buf *ob = (struct buf *)payload;
         | 
| 241 | 
            +
            	key = rb_obj_as_string(key);
         | 
| 242 | 
            +
            	val = rb_obj_as_string(val);
         | 
| 243 | 
            +
            	bufprintf(ob, " %s=\"%s\"", StringValueCStr(key), StringValueCStr(val));
         | 
| 244 | 
            +
            	return ST_CONTINUE;
         | 
| 245 | 
            +
            }
         | 
| 246 | 
            +
             | 
| 247 | 
            +
            static void
         | 
| 248 | 
            +
            rndr_link_attributes(struct buf *ob, const struct buf *url, void *opaque)
         | 
| 249 | 
            +
            {
         | 
| 250 | 
            +
            	struct redcarpet_renderopt *opt = opaque;
         | 
| 251 | 
            +
            	struct rb_redcarpet_rndr *rndr;
         | 
| 252 | 
            +
             | 
| 253 | 
            +
            	Data_Get_Struct(opt->self, struct rb_redcarpet_rndr, rndr);
         | 
| 254 | 
            +
            	Check_Type(opt->link_attributes, T_HASH);
         | 
| 255 | 
            +
            	rb_hash_foreach(opt->link_attributes, &cb_link_attribute, (VALUE)ob);
         | 
| 256 | 
            +
            }
         | 
| 257 | 
            +
             | 
| 237 258 | 
             
            static struct sd_callbacks rb_redcarpet_callbacks = {
         | 
| 238 259 | 
             
            	rndr_blockcode,
         | 
| 239 260 | 
             
            	rndr_blockquote,
         | 
| @@ -342,12 +363,11 @@ static VALUE rb_redcarpet_html_init(int argc, VALUE *argv, VALUE self) | |
| 342 363 | 
             
            {
         | 
| 343 364 | 
             
            	struct rb_redcarpet_rndr *rndr;
         | 
| 344 365 | 
             
            	unsigned int render_flags = 0;
         | 
| 345 | 
            -
            	VALUE hash;
         | 
| 366 | 
            +
            	VALUE hash, link_attr = Qnil;
         | 
| 346 367 |  | 
| 347 368 | 
             
            	Data_Get_Struct(self, struct rb_redcarpet_rndr, rndr);
         | 
| 348 369 |  | 
| 349 | 
            -
            	if (rb_scan_args(argc, argv, "01", &hash) == 1)
         | 
| 350 | 
            -
            	{
         | 
| 370 | 
            +
            	if (rb_scan_args(argc, argv, "01", &hash) == 1) {
         | 
| 351 371 | 
             
            		Check_Type(hash, T_HASH);
         | 
| 352 372 |  | 
| 353 373 | 
             
            		/* escape_html */
         | 
| @@ -382,11 +402,18 @@ static VALUE rb_redcarpet_html_init(int argc, VALUE *argv, VALUE self) | |
| 382 402 |  | 
| 383 403 | 
             
            		if (rb_hash_aref(hash, CSTR2SYM("xhtml")) == Qtrue)
         | 
| 384 404 | 
             
            			render_flags |= HTML_USE_XHTML;
         | 
| 405 | 
            +
             | 
| 406 | 
            +
            		link_attr = rb_hash_aref(hash, CSTR2SYM("link_attributes"));
         | 
| 385 407 | 
             
            	}
         | 
| 386 408 |  | 
| 387 409 | 
             
            	sdhtml_renderer(&rndr->callbacks, (struct html_renderopt *)&rndr->options.html, render_flags);
         | 
| 388 410 | 
             
            	rb_redcarpet__overload(self, rb_cRenderHTML);
         | 
| 389 411 |  | 
| 412 | 
            +
            	if (!NIL_P(link_attr)) {
         | 
| 413 | 
            +
            		rndr->options.link_attributes = link_attr;
         | 
| 414 | 
            +
            		rndr->options.html.link_attributes = &rndr_link_attributes;
         | 
| 415 | 
            +
            	}
         | 
| 416 | 
            +
             | 
| 390 417 | 
             
            	return Qnil;
         | 
| 391 418 | 
             
            }
         | 
| 392 419 |  | 
    
        data/ext/redcarpet/redcarpet.h
    CHANGED
    
    | @@ -3,6 +3,7 @@ | |
| 3 3 |  | 
| 4 4 | 
             
            #define RSTRING_NOT_MODIFIED
         | 
| 5 5 | 
             
            #include "ruby.h"
         | 
| 6 | 
            +
            #include "st.h"
         | 
| 6 7 | 
             
            #include <stdio.h>
         | 
| 7 8 |  | 
| 8 9 | 
             
            #ifdef HAVE_RUBY_ENCODING_H
         | 
| @@ -21,6 +22,7 @@ extern void Init_redcarpet_rndr(); | |
| 21 22 |  | 
| 22 23 | 
             
            struct redcarpet_renderopt {
         | 
| 23 24 | 
             
            	struct html_renderopt html;
         | 
| 25 | 
            +
            	VALUE link_attributes;
         | 
| 24 26 | 
             
            	VALUE self;
         | 
| 25 27 | 
             
            	VALUE base_class;
         | 
| 26 28 | 
             
            #ifdef HAVE_RUBY_ENCODING_H
         | 
    
        data/ext/redcarpet/stack.h
    CHANGED
    
    | @@ -3,6 +3,10 @@ | |
| 3 3 |  | 
| 4 4 | 
             
            #include <stdlib.h>
         | 
| 5 5 |  | 
| 6 | 
            +
            #ifdef __cplusplus
         | 
| 7 | 
            +
            extern "C" {
         | 
| 8 | 
            +
            #endif
         | 
| 9 | 
            +
             | 
| 6 10 | 
             
            struct stack {
         | 
| 7 11 | 
             
            	void **item;
         | 
| 8 12 | 
             
            	size_t size;
         | 
| @@ -18,4 +22,8 @@ int stack_push(struct stack *, void *); | |
| 18 22 | 
             
            void *stack_pop(struct stack *);
         | 
| 19 23 | 
             
            void *stack_top(struct stack *);
         | 
| 20 24 |  | 
| 25 | 
            +
            #ifdef __cplusplus
         | 
| 26 | 
            +
            }
         | 
| 27 | 
            +
            #endif
         | 
| 28 | 
            +
             | 
| 21 29 | 
             
            #endif
         | 
    
        data/lib/redcarpet.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            require 'redcarpet.so'
         | 
| 2 2 |  | 
| 3 3 | 
             
            module Redcarpet
         | 
| 4 | 
            -
              VERSION = '2. | 
| 4 | 
            +
              VERSION = '2.2.0'
         | 
| 5 5 |  | 
| 6 6 | 
             
              class Markdown
         | 
| 7 7 | 
             
                attr_reader :renderer
         | 
| @@ -77,7 +77,7 @@ class RedcarpetCompat | |
| 77 77 | 
             
                :fenced_code => :fenced_code_blocks,
         | 
| 78 78 | 
             
                :filter_html => :filter_html,
         | 
| 79 79 | 
             
                :hard_wrap => :hard_wrap,
         | 
| 80 | 
            -
                :lax_htmlblock => : | 
| 80 | 
            +
                :lax_htmlblock => :lax_spacing,
         | 
| 81 81 | 
             
                :no_image => :no_images,
         | 
| 82 82 | 
             
                :no_intraemphasis => :no_intra_emphasis,
         | 
| 83 83 | 
             
                :no_links => :no_links,
         | 
    
        data/redcarpet.gemspec
    CHANGED
    
    | @@ -1,16 +1,18 @@ | |
| 1 1 | 
             
            # encoding: utf-8
         | 
| 2 2 | 
             
            Gem::Specification.new do |s|
         | 
| 3 3 | 
             
              s.name = 'redcarpet'
         | 
| 4 | 
            -
              s.version = '2. | 
| 4 | 
            +
              s.version = '2.2.0'
         | 
| 5 5 | 
             
              s.summary = "Markdown that smells nice"
         | 
| 6 6 | 
             
              s.description = 'A fast, safe and extensible Markdown to (X)HTML parser'
         | 
| 7 | 
            -
              s.date = ' | 
| 7 | 
            +
              s.date = '2012-10-11'
         | 
| 8 8 | 
             
              s.email = 'vicent@github.com'
         | 
| 9 | 
            -
              s.homepage = 'http://github.com/ | 
| 9 | 
            +
              s.homepage = 'http://github.com/vmg/redcarpet'
         | 
| 10 10 | 
             
              s.authors = ["Natacha Porté", "Vicent Martí"]
         | 
| 11 11 | 
             
              # = MANIFEST =
         | 
| 12 12 | 
             
              s.files = %w[
         | 
| 13 13 | 
             
                COPYING
         | 
| 14 | 
            +
                Gemfile
         | 
| 15 | 
            +
                Gemfile.lock
         | 
| 14 16 | 
             
                README.markdown
         | 
| 15 17 | 
             
                Rakefile
         | 
| 16 18 | 
             
                bin/redcarpet
         | 
| @@ -47,5 +49,6 @@ Gem::Specification.new do |s| | |
| 47 49 | 
             
              s.extensions = ["ext/redcarpet/extconf.rb"]
         | 
| 48 50 | 
             
              s.executables = ["redcarpet"]
         | 
| 49 51 | 
             
              s.require_paths = ["lib"]
         | 
| 52 | 
            +
              s.add_development_dependency "nokogiri"
         | 
| 50 53 | 
             
              s.add_development_dependency "rake-compiler"
         | 
| 51 54 | 
             
            end
         | 
    
        data/test/redcarpet_test.rb
    CHANGED
    
    | @@ -127,6 +127,12 @@ EOE | |
| 127 127 |  | 
| 128 128 | 
             
                assert rd =~ /<br>/
         | 
| 129 129 | 
             
              end
         | 
| 130 | 
            +
             | 
| 131 | 
            +
              def test_that_link_attributes_work
         | 
| 132 | 
            +
                rndr = Redcarpet::Render::HTML.new(:link_attributes => {:rel => 'blank'})
         | 
| 133 | 
            +
                md = Redcarpet::Markdown.new(rndr)
         | 
| 134 | 
            +
                assert md.render('This is a [simple](http://test.com) test.').include?('rel="blank"')
         | 
| 135 | 
            +
              end
         | 
| 130 136 | 
             
            end
         | 
| 131 137 |  | 
| 132 138 | 
             
            class MarkdownTest < Test::Unit::TestCase
         | 
| @@ -187,7 +193,7 @@ class MarkdownTest < Test::Unit::TestCase | |
| 187 193 | 
             
              end
         | 
| 188 194 |  | 
| 189 195 | 
             
              def test_para_before_block_html_should_not_wrap_in_p_tag
         | 
| 190 | 
            -
                markdown = render_with({: | 
| 196 | 
            +
                markdown = render_with({:lax_spacing => true},
         | 
| 191 197 | 
             
                  "Things to watch out for\n" +
         | 
| 192 198 | 
             
                  "<ul>\n<li>Blah</li>\n</ul>\n")
         | 
| 193 199 |  | 
| @@ -311,6 +317,15 @@ fenced | |
| 311 317 | 
             
                assert render_with({:fenced_code_blocks => true}, text) =~ /<code/
         | 
| 312 318 | 
             
              end
         | 
| 313 319 |  | 
| 320 | 
            +
              def test_that_fenced_flag_works_without_space
         | 
| 321 | 
            +
                text = "foo\nbar\n```\nsome\ncode\n```\nbaz"
         | 
| 322 | 
            +
                out = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :fenced_code_blocks => true, :lax_spacing => true).render(text)
         | 
| 323 | 
            +
                assert out.include?("<pre><code>")
         | 
| 324 | 
            +
             | 
| 325 | 
            +
                out = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :fenced_code_blocks => true).render(text)
         | 
| 326 | 
            +
                assert !out.include?("<pre><code>")
         | 
| 327 | 
            +
              end
         | 
| 328 | 
            +
             | 
| 314 329 | 
             
              def test_that_headers_are_linkable
         | 
| 315 330 | 
             
                markdown = @markdown.render('### Hello [GitHub](http://github.com)')
         | 
| 316 331 | 
             
                html_equal "<h3>Hello <a href=\"http://github.com\">GitHub</a></h3>", markdown
         | 
| @@ -327,6 +342,14 @@ text | |
| 327 342 | 
             
                rd = render_with({:space_after_headers => true}, "#123 a header yes\n")
         | 
| 328 343 | 
             
                assert rd !~ /<h1>/
         | 
| 329 344 | 
             
              end
         | 
| 345 | 
            +
             | 
| 346 | 
            +
              def test_proper_intra_emphasis
         | 
| 347 | 
            +
                md = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :no_intra_emphasis => true)
         | 
| 348 | 
            +
                assert render_with({:no_intra_emphasis => true}, "http://en.wikipedia.org/wiki/Dave_Allen_(comedian)") !~ /<em>/
         | 
| 349 | 
            +
                assert render_with({:no_intra_emphasis => true}, "this fails: hello_world_") !~ /<em>/
         | 
| 350 | 
            +
                assert render_with({:no_intra_emphasis => true}, "this also fails: hello_world_#bye") !~ /<em>/
         | 
| 351 | 
            +
                assert render_with({:no_intra_emphasis => true}, "this works: hello_my_world") !~ /<em>/
         | 
| 352 | 
            +
              end
         | 
| 330 353 | 
             
            end
         | 
| 331 354 |  | 
| 332 355 | 
             
            class CustomRenderTest < Test::Unit::TestCase
         | 
    
        metadata
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: redcarpet
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              hash:  | 
| 4 | 
            +
              hash: 7
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 2
         | 
| 8 | 
            -
              -  | 
| 9 | 
            -
              -  | 
| 10 | 
            -
              version: 2. | 
| 8 | 
            +
              - 2
         | 
| 9 | 
            +
              - 0
         | 
| 10 | 
            +
              version: 2.2.0
         | 
| 11 11 | 
             
            platform: ruby
         | 
| 12 12 | 
             
            authors: 
         | 
| 13 13 | 
             
            - "Natacha Port\xC3\xA9"
         | 
| @@ -16,10 +16,11 @@ autorequire: | |
| 16 16 | 
             
            bindir: bin
         | 
| 17 17 | 
             
            cert_chain: []
         | 
| 18 18 |  | 
| 19 | 
            -
            date:  | 
| 19 | 
            +
            date: 2012-10-11 00:00:00 +02:00
         | 
| 20 | 
            +
            default_executable: 
         | 
| 20 21 | 
             
            dependencies: 
         | 
| 21 22 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 22 | 
            -
              name:  | 
| 23 | 
            +
              name: nokogiri
         | 
| 23 24 | 
             
              prerelease: false
         | 
| 24 25 | 
             
              requirement: &id001 !ruby/object:Gem::Requirement 
         | 
| 25 26 | 
             
                none: false
         | 
| @@ -32,6 +33,20 @@ dependencies: | |
| 32 33 | 
             
                    version: "0"
         | 
| 33 34 | 
             
              type: :development
         | 
| 34 35 | 
             
              version_requirements: *id001
         | 
| 36 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 37 | 
            +
              name: rake-compiler
         | 
| 38 | 
            +
              prerelease: false
         | 
| 39 | 
            +
              requirement: &id002 !ruby/object:Gem::Requirement 
         | 
| 40 | 
            +
                none: false
         | 
| 41 | 
            +
                requirements: 
         | 
| 42 | 
            +
                - - ">="
         | 
| 43 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 44 | 
            +
                    hash: 3
         | 
| 45 | 
            +
                    segments: 
         | 
| 46 | 
            +
                    - 0
         | 
| 47 | 
            +
                    version: "0"
         | 
| 48 | 
            +
              type: :development
         | 
| 49 | 
            +
              version_requirements: *id002
         | 
| 35 50 | 
             
            description: A fast, safe and extensible Markdown to (X)HTML parser
         | 
| 36 51 | 
             
            email: vicent@github.com
         | 
| 37 52 | 
             
            executables: 
         | 
| @@ -42,6 +57,8 @@ extra_rdoc_files: | |
| 42 57 | 
             
            - COPYING
         | 
| 43 58 | 
             
            files: 
         | 
| 44 59 | 
             
            - COPYING
         | 
| 60 | 
            +
            - Gemfile
         | 
| 61 | 
            +
            - Gemfile.lock
         | 
| 45 62 | 
             
            - README.markdown
         | 
| 46 63 | 
             
            - Rakefile
         | 
| 47 64 | 
             
            - bin/redcarpet
         | 
| @@ -70,7 +87,8 @@ files: | |
| 70 87 | 
             
            - lib/redcarpet/render_strip.rb
         | 
| 71 88 | 
             
            - redcarpet.gemspec
         | 
| 72 89 | 
             
            - test/redcarpet_test.rb
         | 
| 73 | 
            -
             | 
| 90 | 
            +
            has_rdoc: true
         | 
| 91 | 
            +
            homepage: http://github.com/vmg/redcarpet
         | 
| 74 92 | 
             
            licenses: []
         | 
| 75 93 |  | 
| 76 94 | 
             
            post_install_message: 
         | 
| @@ -99,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 99 117 | 
             
            requirements: []
         | 
| 100 118 |  | 
| 101 119 | 
             
            rubyforge_project: 
         | 
| 102 | 
            -
            rubygems_version: 1. | 
| 120 | 
            +
            rubygems_version: 1.6.2
         | 
| 103 121 | 
             
            signing_key: 
         | 
| 104 122 | 
             
            specification_version: 3
         | 
| 105 123 | 
             
            summary: Markdown that smells nice
         |