greenmat 3.2.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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +14 -0
  3. data/Gemfile +9 -0
  4. data/README.md +36 -0
  5. data/Rakefile +62 -0
  6. data/bin/greenmat +7 -0
  7. data/ext/greenmat/autolink.c +296 -0
  8. data/ext/greenmat/autolink.h +49 -0
  9. data/ext/greenmat/buffer.c +196 -0
  10. data/ext/greenmat/buffer.h +83 -0
  11. data/ext/greenmat/extconf.rb +6 -0
  12. data/ext/greenmat/gm_markdown.c +161 -0
  13. data/ext/greenmat/gm_render.c +534 -0
  14. data/ext/greenmat/greenmat.h +30 -0
  15. data/ext/greenmat/houdini.h +29 -0
  16. data/ext/greenmat/houdini_href_e.c +108 -0
  17. data/ext/greenmat/houdini_html_e.c +83 -0
  18. data/ext/greenmat/html.c +826 -0
  19. data/ext/greenmat/html.h +84 -0
  20. data/ext/greenmat/html_blocks.h +229 -0
  21. data/ext/greenmat/html_smartypants.c +445 -0
  22. data/ext/greenmat/markdown.c +2912 -0
  23. data/ext/greenmat/markdown.h +138 -0
  24. data/ext/greenmat/stack.c +62 -0
  25. data/ext/greenmat/stack.h +26 -0
  26. data/greenmat.gemspec +72 -0
  27. data/lib/greenmat.rb +92 -0
  28. data/lib/greenmat/compat.rb +73 -0
  29. data/lib/greenmat/render_man.rb +65 -0
  30. data/lib/greenmat/render_strip.rb +48 -0
  31. data/test/benchmark.rb +24 -0
  32. data/test/custom_render_test.rb +28 -0
  33. data/test/greenmat_compat_test.rb +38 -0
  34. data/test/html5_test.rb +69 -0
  35. data/test/html_render_test.rb +241 -0
  36. data/test/html_toc_render_test.rb +76 -0
  37. data/test/markdown_test.rb +337 -0
  38. data/test/pathological_inputs_test.rb +34 -0
  39. data/test/safe_render_test.rb +36 -0
  40. data/test/smarty_html_test.rb +45 -0
  41. data/test/smarty_pants_test.rb +48 -0
  42. data/test/stripdown_render_test.rb +40 -0
  43. data/test/test_helper.rb +33 -0
  44. metadata +158 -0
@@ -0,0 +1,138 @@
1
+ /* markdown.h - generic markdown parser */
2
+
3
+ /*
4
+ * Copyright (c) 2009, Natacha Porté
5
+ *
6
+ * Permission to use, copy, modify, and distribute this software for any
7
+ * purpose with or without fee is hereby granted, provided that the above
8
+ * copyright notice and this permission notice appear in all copies.
9
+ *
10
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
+ */
18
+
19
+ #ifndef MARKDOWN_H__
20
+ #define MARKDOWN_H__
21
+
22
+ #include "buffer.h"
23
+ #include "autolink.h"
24
+
25
+ #ifdef __cplusplus
26
+ extern "C" {
27
+ #endif
28
+
29
+ /********************
30
+ * TYPE DEFINITIONS *
31
+ ********************/
32
+
33
+ /* mkd_autolink - type of autolink */
34
+ enum mkd_autolink {
35
+ MKDA_NOT_AUTOLINK, /* used internally when it is not an autolink*/
36
+ MKDA_NORMAL, /* normal http/http/ftp/mailto/etc link */
37
+ MKDA_EMAIL, /* e-mail link without explit mailto: */
38
+ };
39
+
40
+ enum mkd_tableflags {
41
+ MKD_TABLE_ALIGN_L = 1,
42
+ MKD_TABLE_ALIGN_R = 2,
43
+ MKD_TABLE_ALIGN_CENTER = 3,
44
+ MKD_TABLE_ALIGNMASK = 3,
45
+ MKD_TABLE_HEADER = 4
46
+ };
47
+
48
+ enum mkd_extensions {
49
+ MKDEXT_NO_INTRA_EMPHASIS = (1 << 0),
50
+ MKDEXT_TABLES = (1 << 1),
51
+ MKDEXT_FENCED_CODE = (1 << 2),
52
+ MKDEXT_AUTOLINK = (1 << 3),
53
+ MKDEXT_STRIKETHROUGH = (1 << 4),
54
+ MKDEXT_UNDERLINE = (1 << 5),
55
+ MKDEXT_SPACE_HEADERS = (1 << 6),
56
+ MKDEXT_SUPERSCRIPT = (1 << 7),
57
+ MKDEXT_LAX_SPACING = (1 << 8),
58
+ MKDEXT_DISABLE_INDENTED_CODE = (1 << 9),
59
+ MKDEXT_HIGHLIGHT = (1 << 10),
60
+ MKDEXT_FOOTNOTES = (1 << 11),
61
+ MKDEXT_QUOTE = (1 << 12)
62
+ };
63
+
64
+ /* sd_callbacks - functions for rendering parsed data */
65
+ struct sd_callbacks {
66
+ /* block level callbacks - NULL skips the block */
67
+ void (*blockcode)(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque);
68
+ void (*blockquote)(struct buf *ob, const struct buf *text, void *opaque);
69
+ void (*blockhtml)(struct buf *ob,const struct buf *text, void *opaque);
70
+ void (*header)(struct buf *ob, const struct buf *text, int level, void *opaque);
71
+ void (*hrule)(struct buf *ob, void *opaque);
72
+ void (*list)(struct buf *ob, const struct buf *text, int flags, void *opaque);
73
+ void (*listitem)(struct buf *ob, const struct buf *text, int flags, void *opaque);
74
+ void (*paragraph)(struct buf *ob, const struct buf *text, void *opaque);
75
+ void (*table)(struct buf *ob, const struct buf *header, const struct buf *body, void *opaque);
76
+ void (*table_row)(struct buf *ob, const struct buf *text, void *opaque);
77
+ void (*table_cell)(struct buf *ob, const struct buf *text, int flags, void *opaque);
78
+ void (*footnotes)(struct buf *ob, const struct buf *text, void *opaque);
79
+ void (*footnote_def)(struct buf *ob, const struct buf *text, unsigned int num, void *opaque);
80
+
81
+ /* span level callbacks - NULL or return 0 prints the span verbatim */
82
+ int (*autolink)(struct buf *ob, const struct buf *link, enum mkd_autolink type, void *opaque);
83
+ int (*codespan)(struct buf *ob, const struct buf *text, void *opaque);
84
+ int (*double_emphasis)(struct buf *ob, const struct buf *text, void *opaque);
85
+ int (*emphasis)(struct buf *ob, const struct buf *text, void *opaque);
86
+ int (*underline)(struct buf *ob, const struct buf *text, void *opaque);
87
+ int (*highlight)(struct buf *ob, const struct buf *text, void *opaque);
88
+ int (*quote)(struct buf *ob, const struct buf *text, void *opaque);
89
+ int (*image)(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *alt, void *opaque);
90
+ int (*linebreak)(struct buf *ob, void *opaque);
91
+ int (*link)(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *content, void *opaque);
92
+ int (*raw_html_tag)(struct buf *ob, const struct buf *tag, void *opaque);
93
+ int (*triple_emphasis)(struct buf *ob, const struct buf *text, void *opaque);
94
+ int (*strikethrough)(struct buf *ob, const struct buf *text, void *opaque);
95
+ int (*superscript)(struct buf *ob, const struct buf *text, void *opaque);
96
+ int (*footnote_ref)(struct buf *ob, unsigned int num, void *opaque);
97
+
98
+ /* low level callbacks - NULL copies input directly into the output */
99
+ void (*entity)(struct buf *ob, const struct buf *entity, void *opaque);
100
+ void (*normal_text)(struct buf *ob, const struct buf *text, void *opaque);
101
+
102
+ /* header and footer */
103
+ void (*doc_header)(struct buf *ob, void *opaque);
104
+ void (*doc_footer)(struct buf *ob, void *opaque);
105
+ };
106
+
107
+ struct sd_markdown;
108
+
109
+ /*********
110
+ * FLAGS *
111
+ *********/
112
+
113
+ /* list/listitem flags */
114
+ #define MKD_LIST_ORDERED 1
115
+ #define MKD_LI_BLOCK 2 /* <li> containing block data */
116
+
117
+ /**********************
118
+ * EXPORTED FUNCTIONS *
119
+ **********************/
120
+
121
+ extern struct sd_markdown *
122
+ sd_markdown_new(
123
+ unsigned int extensions,
124
+ size_t max_nesting,
125
+ const struct sd_callbacks *callbacks,
126
+ void *opaque);
127
+
128
+ extern void
129
+ sd_markdown_render(struct buf *ob, const uint8_t *document, size_t doc_size, struct sd_markdown *md);
130
+
131
+ extern void
132
+ sd_markdown_free(struct sd_markdown *md);
133
+
134
+ #ifdef __cplusplus
135
+ }
136
+ #endif
137
+
138
+ #endif
@@ -0,0 +1,62 @@
1
+ #include "stack.h"
2
+ #include <string.h>
3
+
4
+ int
5
+ greenmat_stack_grow(struct stack *st, size_t new_size)
6
+ {
7
+ void **new_st;
8
+
9
+ if (st->asize >= new_size)
10
+ return 0;
11
+
12
+ new_st = realloc(st->item, new_size * sizeof(void *));
13
+ if (new_st == NULL)
14
+ return -1;
15
+
16
+ memset(new_st + st->asize, 0x0,
17
+ (new_size - st->asize) * sizeof(void *));
18
+
19
+ st->item = new_st;
20
+ st->asize = new_size;
21
+
22
+ if (st->size > new_size)
23
+ st->size = new_size;
24
+
25
+ return 0;
26
+ }
27
+
28
+ void
29
+ greenmat_stack_free(struct stack *st)
30
+ {
31
+ if (!st)
32
+ return;
33
+
34
+ free(st->item);
35
+
36
+ st->item = NULL;
37
+ st->size = 0;
38
+ st->asize = 0;
39
+ }
40
+
41
+ int
42
+ greenmat_stack_init(struct stack *st, size_t initial_size)
43
+ {
44
+ st->item = NULL;
45
+ st->size = 0;
46
+ st->asize = 0;
47
+
48
+ if (!initial_size)
49
+ initial_size = 8;
50
+
51
+ return greenmat_stack_grow(st, initial_size);
52
+ }
53
+
54
+ int
55
+ greenmat_stack_push(struct stack *st, void *item)
56
+ {
57
+ if (greenmat_stack_grow(st, st->size * 2) < 0)
58
+ return -1;
59
+
60
+ st->item[st->size++] = item;
61
+ return 0;
62
+ }
@@ -0,0 +1,26 @@
1
+ #ifndef STACK_H__
2
+ #define STACK_H__
3
+
4
+ #include <stdlib.h>
5
+
6
+ #ifdef __cplusplus
7
+ extern "C" {
8
+ #endif
9
+
10
+ struct stack {
11
+ void **item;
12
+ size_t size;
13
+ size_t asize;
14
+ };
15
+
16
+ void greenmat_stack_free(struct stack *);
17
+ int greenmat_stack_grow(struct stack *, size_t);
18
+ int greenmat_stack_init(struct stack *, size_t);
19
+
20
+ int greenmat_stack_push(struct stack *, void *);
21
+
22
+ #ifdef __cplusplus
23
+ }
24
+ #endif
25
+
26
+ #endif
@@ -0,0 +1,72 @@
1
+ # encoding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'greenmat'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'greenmat'
8
+ s.version = Greenmat::VERSION
9
+ s.summary = "A Markdown parser for Qiita, based on Redcarpet."
10
+ s.description = s.summary
11
+ s.email = 'nkymyj@gmail.com'
12
+ s.homepage = 'https://github.com/increments/greenmat'
13
+ s.authors = ["Natacha Porté", "Vicent Martí"]
14
+ s.license = 'MIT'
15
+ s.required_ruby_version = '>= 2.0.0'
16
+ # = MANIFEST =
17
+ s.files = %w[
18
+ COPYING
19
+ Gemfile
20
+ README.md
21
+ Rakefile
22
+ bin/greenmat
23
+ ext/greenmat/autolink.c
24
+ ext/greenmat/autolink.h
25
+ ext/greenmat/buffer.c
26
+ ext/greenmat/buffer.h
27
+ ext/greenmat/extconf.rb
28
+ ext/greenmat/houdini.h
29
+ ext/greenmat/houdini_href_e.c
30
+ ext/greenmat/houdini_html_e.c
31
+ ext/greenmat/html.c
32
+ ext/greenmat/html.h
33
+ ext/greenmat/html_blocks.h
34
+ ext/greenmat/html_smartypants.c
35
+ ext/greenmat/markdown.c
36
+ ext/greenmat/markdown.h
37
+ ext/greenmat/gm_markdown.c
38
+ ext/greenmat/gm_render.c
39
+ ext/greenmat/greenmat.h
40
+ ext/greenmat/stack.c
41
+ ext/greenmat/stack.h
42
+ lib/greenmat.rb
43
+ lib/greenmat/compat.rb
44
+ lib/greenmat/render_man.rb
45
+ lib/greenmat/render_strip.rb
46
+ greenmat.gemspec
47
+ test/benchmark.rb
48
+ test/custom_render_test.rb
49
+ test/html5_test.rb
50
+ test/html_render_test.rb
51
+ test/html_toc_render_test.rb
52
+ test/markdown_test.rb
53
+ test/pathological_inputs_test.rb
54
+ test/greenmat_compat_test.rb
55
+ test/safe_render_test.rb
56
+ test/smarty_html_test.rb
57
+ test/smarty_pants_test.rb
58
+ test/stripdown_render_test.rb
59
+ test/test_helper.rb
60
+ ]
61
+ # = MANIFEST =
62
+ s.test_files = s.files.grep(%r{^test/})
63
+ s.extra_rdoc_files = ["COPYING"]
64
+ s.extensions = ["ext/greenmat/extconf.rb"]
65
+ s.executables = ["greenmat"]
66
+ s.require_paths = ["lib"]
67
+
68
+ s.add_development_dependency "rake-compiler", "~> 0.8.3"
69
+ s.add_development_dependency "rspec", "~> 3.2"
70
+ s.add_development_dependency "rubygems-xcodeproj_generator", '~> 0.1'
71
+ s.add_development_dependency "test-unit", "~> 3.0.9"
72
+ end
@@ -0,0 +1,92 @@
1
+ require 'greenmat.so'
2
+ require 'greenmat/compat'
3
+
4
+ module Greenmat
5
+ VERSION = '3.2.0.0'
6
+
7
+ class Markdown
8
+ attr_reader :renderer
9
+ end
10
+
11
+ module Render
12
+
13
+ # XHTML Renderer
14
+ class XHTML < HTML
15
+ def initialize(extensions = {})
16
+ super(extensions.merge(xhtml: true))
17
+ end
18
+ end
19
+
20
+ # HTML + SmartyPants renderer
21
+ class SmartyHTML < HTML
22
+ include SmartyPants
23
+ end
24
+
25
+ # A renderer object you can use to deal with users' input. It
26
+ # enables +escape_html+ and +safe_links_only+ by default.
27
+ #
28
+ # The +block_code+ callback is also overriden not to include
29
+ # the lang's class as the user can basically specify anything
30
+ # with the vanilla one.
31
+ class Safe < HTML
32
+ def initialize(extensions = {})
33
+ super({
34
+ escape_html: true,
35
+ safe_links_only: true
36
+ }.merge(extensions))
37
+ end
38
+
39
+ def block_code(code, lang)
40
+ "<pre>" \
41
+ "<code>#{html_escape(code)}</code>" \
42
+ "</pre>"
43
+ end
44
+
45
+ private
46
+
47
+ # TODO: This is far from ideal to have such method as we
48
+ # are duplicating existing code from Houdini. This method
49
+ # should be defined at the C level.
50
+ def html_escape(string)
51
+ string.gsub(/['&\"<>\/]/, {
52
+ '&' => '&amp;',
53
+ '<' => '&lt;',
54
+ '>' => '&gt;',
55
+ '"' => '&quot;',
56
+ "'" => '&#x27;',
57
+ "/" => '&#x2F;',
58
+ })
59
+ end
60
+ end
61
+
62
+ # SmartyPants Mixin module
63
+ #
64
+ # Implements SmartyPants.postprocess, which
65
+ # performs smartypants replacements on the HTML file,
66
+ # once it has been fully rendered.
67
+ #
68
+ # To add SmartyPants postprocessing to your custom
69
+ # renderers, just mixin the module `include SmartyPants`
70
+ #
71
+ # You can also use this as a standalone SmartyPants
72
+ # implementation.
73
+ #
74
+ # Example:
75
+ #
76
+ # # Mixin
77
+ # class CoolRenderer < HTML
78
+ # include SmartyPants
79
+ # # more code here
80
+ # end
81
+ #
82
+ # # Standalone
83
+ # Greenmat::Render::SmartyPants.render("you're")
84
+ #
85
+ module SmartyPants
86
+ extend self
87
+ def self.render(text)
88
+ postprocess text
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,73 @@
1
+ require 'greenmat'
2
+
3
+ # Creates an instance of Greenmat with the RedCloth API.
4
+ class GreenmatCompat
5
+ attr_accessor :text
6
+
7
+ def initialize(text, *exts)
8
+ exts_hash, render_hash = *parse_extensions_and_renderer_options(exts)
9
+ @text = text
10
+ renderer = Greenmat::Render::HTML.new(render_hash)
11
+ @markdown = Greenmat::Markdown.new(renderer, exts_hash)
12
+ end
13
+
14
+ def to_html(*_dummy)
15
+ @markdown.render(text)
16
+ end
17
+
18
+ private
19
+
20
+ EXTENSION_MAP = {
21
+ # old name => new name
22
+ :autolink => :autolink,
23
+ :fenced_code => :fenced_code_blocks,
24
+ :filter_html => :filter_html,
25
+ :hard_wrap => :hard_wrap,
26
+ :prettify => :prettify,
27
+ :lax_htmlblock => :lax_spacing,
28
+ :no_image => :no_images,
29
+ :no_intraemphasis => :no_intra_emphasis,
30
+ :no_links => :no_links,
31
+ :filter_styles => :no_styles,
32
+ :safelink => :safe_links_only,
33
+ :space_header => :space_after_headers,
34
+ :strikethrough => :strikethrough,
35
+ :tables => :tables,
36
+ :generate_toc => :with_toc_data,
37
+ :xhtml => :xhtml,
38
+
39
+ # old names with no new mapping
40
+ :gh_blockcode => nil,
41
+ :no_tables => nil,
42
+ :smart => nil,
43
+ :strict => nil
44
+ }
45
+
46
+ RENDERER_OPTIONS = [:filter_html, :no_images, :no_links, :no_styles,
47
+ :safe_links_only, :with_toc_data, :hard_wrap, :prettify, :xhtml]
48
+
49
+ def rename_extensions(exts)
50
+ exts.map do |old_name|
51
+ if new_name = EXTENSION_MAP[old_name]
52
+ new_name
53
+ else
54
+ old_name
55
+ end
56
+ end.compact
57
+ end
58
+
59
+ # Returns two hashes, the extensions and renderer options
60
+ # given the extension list
61
+ def parse_extensions_and_renderer_options(exts)
62
+ exts = rename_extensions(exts)
63
+ exts.partition {|ext| !RENDERER_OPTIONS.include?(ext) }.
64
+ map {|list| list_to_truthy_hash(list) }
65
+ end
66
+
67
+ # Turns a list of symbols into a hash of <tt>symbol => true</tt>.
68
+ def list_to_truthy_hash(list)
69
+ list.inject({}) {|h, k| h[k] = true; h }
70
+ end
71
+ end
72
+
73
+ Markdown = GreenmatCompat unless defined? Markdown