rdiscount 2.0.7 → 2.0.7.1

Sign up to get free protection for your applications and to get access to all the features.
data/BUILDING CHANGED
@@ -12,7 +12,7 @@ Use your rdiscount working copy when running ruby programs:
12
12
  $ export RUBYLIB=~/rdiscount/lib:$RUBYLIB
13
13
  $ ruby some-program.rb
14
14
 
15
- Gathering changes from an upstream Orc/discount.git clone requires first
15
+ Gathering changes from an upstream discount clone requires first
16
16
  grabbing the discount submodule into the root of the project and then running
17
17
  the rake gather task to copy discount source files into the ext/ directory:
18
18
 
@@ -25,14 +25,118 @@ the rake gather task to copy discount source files into the ext/ directory:
25
25
  $ rake gather
26
26
  $ rake build
27
27
 
28
- The rtomayko/discount.git repository's master branch is the default submodule
29
- head. It exists to merge branches for rdiscount specific patches to the upstream
30
- discount codebase.
31
28
 
32
- Do work in the submodule and then add a remote for your clone THAT YOU FORKED ON
33
- GITHUB BECAUSE YOU'RE GOING TO SEND ME A PULL REQUEST. After you've committed
34
- your great changes somewhere, push them up with:
29
+ UPGRADING Discount
30
+ ==================
31
+
32
+ The most common maintenance task is upgrading the version of Discount that
33
+ RDiscount is using.
34
+
35
+ Before doing anything, make sure you can build the current (unmodified) version
36
+ of RDiscount. See the section above for details.
37
+
38
+ Update the Discount submodule to the desired version:
35
39
 
36
40
  $ cd discount
37
- $ git remote add you git@github.com:you/discount.git
38
- $ git push you HEAD:topic-branch-name
41
+ $ git fetch
42
+ $ git checkout v2.0.7.x # insert desired version
43
+ $ cd ..
44
+
45
+ Copy the new Discount sources to the appropriate directories for RDiscount:
46
+
47
+ $ rake gather
48
+
49
+ Update rdiscount.gemspec to include all *.c, *.h, and *.rb files in
50
+ ext. This must be done manually. Here's a quick way to get the full list:
51
+
52
+ $ echo ext/*.c ext/*.h ext/*.rb ext/VERSION | tr ' ' "\n" | sort
53
+
54
+ Build the RDiscount gem. If you get errors related to missing files
55
+ in ext, make sure you updated the gemspec correctly in the previous step.
56
+
57
+ $ gem build rdiscount.gemspec
58
+
59
+ Install this new gem locally. It is recommended that you use RVM to
60
+ create an isolated installation environment. If you get an error after the line
61
+ "Building native extensions", see the troubleshooting section below.
62
+
63
+ $ rvm ruby@rdiscount --create # recommended; requires RVM
64
+ $ gem install rdiscount-*.gem
65
+
66
+ Make sure the gem can be imported:
67
+
68
+ $ ruby -e 'require "rdiscount"'
69
+
70
+ Make sure the tests (still) pass:
71
+
72
+ $ rake test
73
+
74
+ Worked? Swell! The hard part is past.
75
+
76
+ Check the Discount release notes to determine whether it has gained any new
77
+ features that should be exposed through the RDiscount Ruby interface
78
+ (lib/rdiscount.rb), such as new MKD_* flags. If so, update the
79
+ Ruby interface.
80
+
81
+ For new Discount extensions, you will need to update:
82
+
83
+ * lib/rdiscount.rb with new accessors and
84
+ * the rb_rdiscount__get_flags function in ext/rdiscount.c with new
85
+ accessor-to-flag mappings for each new extension.
86
+
87
+ You should also look for RDiscount-specific bugs & feature requests in the
88
+ GitHub tracker and fix a few.
89
+
90
+ If any bugs were fixed or features added, be sure to rerun the
91
+ release tests mentioned above.
92
+
93
+ Update the CHANGELOG.
94
+
95
+ Update rdiscount.gemspec with the new version number and date.
96
+ Push that change as the final commit with a message in the format
97
+ "2.0.7 release".
98
+
99
+ Tag the release commit:
100
+
101
+ $ git tag 2.0.7 # insert desired version
102
+
103
+ Rebuild the gem file and push it to RubyGems.
104
+
105
+ $ gem build rdiscount.gemspec
106
+ $ gem push rdiscount-NEW_VERSION.gem
107
+
108
+ Announce the new release! For releases with new features it is recommended to
109
+ write a full blog post.
110
+
111
+
112
+ Troubleshooting Native Extension Issues
113
+ ---------------------------------------
114
+
115
+ The most likely place where errors will crop up is when you attempt to build
116
+ the C extension. If this happens, you will have to debug manually. Below are
117
+ a few recommended sanity checks:
118
+
119
+ Ensure the Makefile is generated correctly:
120
+
121
+ $ cd ext
122
+ $ ruby extconf.rb
123
+
124
+ Ensure make succeeds:
125
+
126
+ $ make
127
+
128
+ If you get linker errors related to there being duplicate symbols for _main,
129
+ you probably need to update the deploy target of the Rakefile to exclude
130
+ new *.c files from Discount that have a main function.
131
+
132
+ For issues related to config.h or extconf.rb, there was probably some
133
+ change to Discount's configure.sh that broke them. You will probably need
134
+ to update these files in ext/ manually.
135
+
136
+ For other errors, you'll have to investigate yourself. Common error classes:
137
+ * 'ext/configure.sh' fails:
138
+ - Create a patch to the upstream Discount.
139
+ * Some files missing from ext/ that are present in discount/:
140
+ - Update 'rake deploy' target to copy more files.
141
+ * Some files missing when `gem build` is run:
142
+ - Update gemspec to enumerate the correct files in ext/.
data/Rakefile CHANGED
@@ -111,14 +111,50 @@ CLEAN.include 'doc'
111
111
 
112
112
  desc 'Gather required discount sources into extension directory'
113
113
  task :gather => 'discount/markdown.h' do |t|
114
- files =
115
- FileList[
116
- 'discount/{markdown,mkdio,amalloc,cstring,tags}.h',
117
- 'discount/{markdown,docheader,dumptree,generate,mkdio,resource,toc,Csio,xml,css,basename,emmatch,tags,html5}.c'
118
- ]
119
- cp files, 'ext/',
120
- :preserve => true,
121
- :verbose => true
114
+ rdiscount_ext_files = [
115
+ "config.h",
116
+ "extconf.rb",
117
+ "rdiscount.c",
118
+ ]
119
+
120
+ discount_c_files_with_main_function = [
121
+ "main.c",
122
+ "makepage.c",
123
+ "mkd2html.c",
124
+ "theme.c",
125
+ ]
126
+
127
+ # Ensure configure.sh was run
128
+ if not File.exists? 'discount/mkdio.h'
129
+ abort "discount/mkdio.h not found. Did you run ./configure.sh in the discount directory?"
130
+ end
131
+
132
+ # Delete all *.c and *.h files from ext that are not specific to RDiscount.
133
+ Dir.chdir("ext") do
134
+ c_files_to_delete = Dir["*.c"].select { |e| !rdiscount_ext_files.include? e }
135
+ h_files_to_delete = Dir["*.h"].select { |e| !rdiscount_ext_files.include? e }
136
+
137
+ rm (c_files_to_delete + h_files_to_delete),
138
+ :verbose => true
139
+ end
140
+
141
+ # Copy all *.c and *.h files from discount -> ext except those that
142
+ # RDiscount overrides. Also exclude Discount files with main functions.
143
+ Dir.chdir("discount") do
144
+ c_files_to_copy = Dir["*.c"].select { |e|
145
+ (!rdiscount_ext_files.include? e) &&
146
+ (!discount_c_files_with_main_function.include? e)
147
+ }
148
+ h_files_to_copy = Dir["*.h"].select { |e| !rdiscount_ext_files.include? e }
149
+
150
+ cp (c_files_to_copy + h_files_to_copy), '../ext/',
151
+ :preserve => true,
152
+ :verbose => true
153
+ end
154
+
155
+ cp 'discount/VERSION', 'ext/'
156
+
157
+ # Copy man page
122
158
  cp 'discount/markdown.7', 'man/'
123
159
  end
124
160
 
data/ext/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.0.7
data/ext/amalloc.c ADDED
@@ -0,0 +1,111 @@
1
+ /*
2
+ * debugging malloc()/realloc()/calloc()/free() that attempts
3
+ * to keep track of just what's been allocated today.
4
+ */
5
+
6
+ #include <stdio.h>
7
+ #include <stdlib.h>
8
+
9
+ #define MAGIC 0x1f2e3d4c
10
+
11
+ struct alist { int magic, size; struct alist *next, *last; };
12
+
13
+ static struct alist list = { 0, 0, 0, 0 };
14
+
15
+ static int mallocs=0;
16
+ static int reallocs=0;
17
+ static int frees=0;
18
+
19
+ void *
20
+ acalloc(int size, int count)
21
+ {
22
+ struct alist *ret = calloc(size + sizeof(struct alist), count);
23
+
24
+ if ( ret ) {
25
+ ret->magic = MAGIC;
26
+ ret->size = size * count;
27
+ if ( list.next ) {
28
+ ret->next = list.next;
29
+ ret->last = &list;
30
+ ret->next->last = ret;
31
+ list.next = ret;
32
+ }
33
+ else {
34
+ ret->last = ret->next = &list;
35
+ list.next = list.last = ret;
36
+ }
37
+ ++mallocs;
38
+ return ret+1;
39
+ }
40
+ return 0;
41
+ }
42
+
43
+
44
+ void*
45
+ amalloc(int size)
46
+ {
47
+ return acalloc(size,1);
48
+ }
49
+
50
+
51
+ void
52
+ afree(void *ptr)
53
+ {
54
+ struct alist *p2 = ((struct alist*)ptr)-1;
55
+
56
+ if ( p2->magic == MAGIC ) {
57
+ p2->last->next = p2->next;
58
+ p2->next->last = p2->last;
59
+ ++frees;
60
+ free(p2);
61
+ }
62
+ else
63
+ free(ptr);
64
+ }
65
+
66
+
67
+ void *
68
+ arealloc(void *ptr, int size)
69
+ {
70
+ struct alist *p2 = ((struct alist*)ptr)-1;
71
+ struct alist save;
72
+
73
+ if ( p2->magic == MAGIC ) {
74
+ save.next = p2->next;
75
+ save.last = p2->last;
76
+ p2 = realloc(p2, sizeof(*p2) + size);
77
+
78
+ if ( p2 ) {
79
+ p2->size = size;
80
+ p2->next->last = p2;
81
+ p2->last->next = p2;
82
+ ++reallocs;
83
+ return p2+1;
84
+ }
85
+ else {
86
+ save.next->last = save.last;
87
+ save.last->next = save.next;
88
+ return 0;
89
+ }
90
+ }
91
+ return realloc(ptr, size);
92
+ }
93
+
94
+
95
+ void
96
+ adump()
97
+ {
98
+ struct alist *p;
99
+
100
+
101
+ for ( p = list.next; p && (p != &list); p = p->next ) {
102
+ fprintf(stderr, "allocated: %d byte%s\n", p->size, (p->size==1) ? "" : "s");
103
+ fprintf(stderr, " [%.*s]\n", p->size, (char*)(p+1));
104
+ }
105
+
106
+ if ( getenv("AMALLOC_STATISTICS") ) {
107
+ fprintf(stderr, "%d malloc%s\n", mallocs, (mallocs==1)?"":"s");
108
+ fprintf(stderr, "%d realloc%s\n", reallocs, (reallocs==1)?"":"s");
109
+ fprintf(stderr, "%d free%s\n", frees, (frees==1)?"":"s");
110
+ }
111
+ }
data/ext/extconf.rb CHANGED
@@ -15,9 +15,11 @@ end
15
15
  DWORD = sized_int(4, ["unsigned long", "unsigned int"])
16
16
  WORD = sized_int(2, ["unsigned int", "unsigned short"])
17
17
  BYTE = "unsigned char"
18
+ VERSION = IO.read('VERSION').strip
18
19
 
19
20
  $defs.push("-DDWORD='#{DWORD}'")
20
21
  $defs.push("-DWORD='#{WORD}'")
21
22
  $defs.push("-DBYTE='#{BYTE}'")
23
+ $defs.push("-DVERSION=\\\"#{VERSION}\\\"")
22
24
 
23
25
  create_makefile('rdiscount')
data/ext/flags.c ADDED
@@ -0,0 +1,84 @@
1
+ #include <stdio.h>
2
+ #include "markdown.h"
3
+
4
+ struct flagnames {
5
+ DWORD flag;
6
+ char *name;
7
+ };
8
+
9
+ static struct flagnames flagnames[] = {
10
+ { MKD_NOLINKS, "!LINKS" },
11
+ { MKD_NOIMAGE, "!IMAGE" },
12
+ { MKD_NOPANTS, "!PANTS" },
13
+ { MKD_NOHTML, "!HTML" },
14
+ { MKD_STRICT, "STRICT" },
15
+ { MKD_TAGTEXT, "TAGTEXT" },
16
+ { MKD_NO_EXT, "!EXT" },
17
+ { MKD_CDATA, "CDATA" },
18
+ { MKD_NOSUPERSCRIPT, "!SUPERSCRIPT" },
19
+ { MKD_NORELAXED, "!RELAXED" },
20
+ { MKD_NOTABLES, "!TABLES" },
21
+ { MKD_NOSTRIKETHROUGH,"!STRIKETHROUGH" },
22
+ { MKD_TOC, "TOC" },
23
+ { MKD_1_COMPAT, "MKD_1_COMPAT" },
24
+ { MKD_AUTOLINK, "AUTOLINK" },
25
+ { MKD_SAFELINK, "SAFELINK" },
26
+ { MKD_NOHEADER, "!HEADER" },
27
+ { MKD_TABSTOP, "TABSTOP" },
28
+ { MKD_NODIVQUOTE, "!DIVQUOTE" },
29
+ { MKD_NOALPHALIST, "!ALPHALIST" },
30
+ { MKD_NODLIST, "!DLIST" },
31
+ { MKD_EXTRA_FOOTNOTE, "FOOTNOTE" },
32
+ };
33
+ #define NR(x) (sizeof x/sizeof x[0])
34
+
35
+
36
+ void
37
+ mkd_flags_are(FILE *f, DWORD flags, int htmlplease)
38
+ {
39
+ int i;
40
+ int not, set, even=1;
41
+ char *name;
42
+
43
+ if ( htmlplease )
44
+ fprintf(f, "<table class=\"mkd_flags_are\">\n");
45
+ for (i=0; i < NR(flagnames); i++) {
46
+ set = flags & flagnames[i].flag;
47
+ name = flagnames[i].name;
48
+ if ( not = (*name == '!') ) {
49
+ ++name;
50
+ set = !set;
51
+ }
52
+
53
+ if ( htmlplease ) {
54
+ if ( even ) fprintf(f, " <tr>");
55
+ fprintf(f, "<td>");
56
+ }
57
+ else
58
+ fputc(' ', f);
59
+
60
+ if ( !set )
61
+ fprintf(f, htmlplease ? "<s>" : "!");
62
+
63
+ fprintf(f, "%s", name);
64
+
65
+ if ( htmlplease ) {
66
+ if ( !set )
67
+ fprintf(f, "</s>");
68
+ fprintf(f, "</td>");
69
+ if ( !even ) fprintf(f, "</tr>\n");
70
+ }
71
+ even = !even;
72
+ }
73
+ if ( htmlplease ) {
74
+ if ( even ) fprintf(f, "</tr>\n");
75
+ fprintf(f, "</table>\n");
76
+ }
77
+ }
78
+
79
+ void
80
+ mkd_mmiot_flags(FILE *f, MMIOT *m, int htmlplease)
81
+ {
82
+ if ( m )
83
+ mkd_flags_are(f, m->flags, htmlplease);
84
+ }
data/ext/generate.c CHANGED
@@ -963,7 +963,7 @@ maybe_tag_or_link(MMIOT *f)
963
963
  }
964
964
  else if ( isspace(c) )
965
965
  break;
966
- else if ( ! (c == '/' || c == '-' || c == '_' || isalnum(c) ) )
966
+ else if ( ! (c == '/' || isalnum(c) ) )
967
967
  maybetag=0;
968
968
  }
969
969
 
data/ext/rdiscount.c CHANGED
@@ -1,4 +1,5 @@
1
1
  #include <stdio.h>
2
+ #include <locale.h>
2
3
  #include "ruby.h"
3
4
  #include "mkdio.h"
4
5
 
@@ -16,6 +17,17 @@ rb_rdiscount_to_html(int argc, VALUE *argv, VALUE self)
16
17
  Check_Type(text, T_STRING);
17
18
 
18
19
  int flags = rb_rdiscount__get_flags(self);
20
+
21
+ /*
22
+ * Force Discount to use ASCII character encoding for isalnum(), isalpha(),
23
+ * and similar functions.
24
+ *
25
+ * Ruby tends to use UTF-8 encoding, which is ill-defined for these
26
+ * functions since they expect 8-bit codepoints (and UTF-8 has codepoints
27
+ * of at least 21 bits).
28
+ */
29
+ char *old_locale = setlocale(LC_CTYPE, NULL);
30
+ setlocale(LC_CTYPE, "C"); // ASCII (and passthru characters > 127)
19
31
 
20
32
  MMIOT *doc = mkd_string(RSTRING_PTR(text), RSTRING_LEN(text), flags);
21
33
 
@@ -29,6 +41,7 @@ rb_rdiscount_to_html(int argc, VALUE *argv, VALUE self)
29
41
  }
30
42
  mkd_cleanup(doc);
31
43
 
44
+ setlocale(LC_CTYPE, old_locale);
32
45
 
33
46
  /* force the input encoding */
34
47
  if ( rb_respond_to(text, rb_intern("encoding")) ) {
data/ext/version.c ADDED
@@ -0,0 +1,22 @@
1
+ #include "config.h"
2
+
3
+ char markdown_version[] = VERSION
4
+ #if 4 != 4
5
+ " TAB=4"
6
+ #endif
7
+ #if USE_AMALLOC
8
+ " DEBUG"
9
+ #endif
10
+ #if USE_DISCOUNT_DL
11
+ # if USE_EXTRA_DL
12
+ " DL=BOTH"
13
+ # else
14
+ " DL=DISCOUNT"
15
+ # endif
16
+ #elif USE_EXTRA_DL
17
+ " DL=EXTRA"
18
+ #else
19
+ " DL=NONE"
20
+ #endif
21
+
22
+ ;
data/ext/xmlpage.c ADDED
@@ -0,0 +1,48 @@
1
+ /*
2
+ * xmlpage -- write a skeletal xhtml page
3
+ *
4
+ * Copyright (C) 2007 David L Parsons.
5
+ * The redistribution terms are provided in the COPYRIGHT file that must
6
+ * be distributed with this source code.
7
+ */
8
+ #include "config.h"
9
+ #include <stdio.h>
10
+ #include <stdlib.h>
11
+ #include <ctype.h>
12
+
13
+ #include "cstring.h"
14
+ #include "markdown.h"
15
+ #include "amalloc.h"
16
+
17
+
18
+ int
19
+ mkd_xhtmlpage(Document *p, int flags, FILE *out)
20
+ {
21
+ char *title;
22
+ extern char *mkd_doc_title(Document *);
23
+
24
+ if ( mkd_compile(p, flags) ) {
25
+ fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
26
+ fprintf(out, "<!DOCTYPE html "
27
+ " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\""
28
+ " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
29
+
30
+ fprintf(out, "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n");
31
+
32
+ fprintf(out, "<head>\n");
33
+ if ( title = mkd_doc_title(p) )
34
+ fprintf(out, "<title>%s</title>\n", title);
35
+ mkd_generatecss(p, out);
36
+ fprintf(out, "</head>\n");
37
+
38
+ fprintf(out, "<body>\n");
39
+ mkd_generatehtml(p, out);
40
+ fprintf(out, "</body>\n");
41
+ fprintf(out, "</html>\n");
42
+
43
+ mkd_cleanup(p);
44
+
45
+ return 0;
46
+ }
47
+ return -1;
48
+ }
data/rdiscount.gemspec CHANGED
@@ -1,8 +1,8 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rdiscount'
3
- s.version = '2.0.7'
3
+ s.version = '2.0.7.1'
4
4
  s.summary = "Fast Implementation of Gruber's Markdown in C"
5
- s.date = '2013-01-29'
5
+ s.date = '2013-02-26'
6
6
  s.email = 'rtomayko@gmail.com'
7
7
  s.homepage = 'http://github.com/rtomayko/rdiscount'
8
8
  s.authors = ["Ryan Tomayko", "David Loren Parsons", "Andrew White", "David Foster"]
@@ -15,6 +15,8 @@ Gem::Specification.new do |s|
15
15
  bin/rdiscount
16
16
  discount
17
17
  ext/Csio.c
18
+ ext/VERSION
19
+ ext/amalloc.c
18
20
  ext/amalloc.h
19
21
  ext/basename.c
20
22
  ext/config.h
@@ -24,6 +26,7 @@ Gem::Specification.new do |s|
24
26
  ext/dumptree.c
25
27
  ext/emmatch.c
26
28
  ext/extconf.rb
29
+ ext/flags.c
27
30
  ext/generate.c
28
31
  ext/html5.c
29
32
  ext/markdown.c
@@ -36,7 +39,9 @@ Gem::Specification.new do |s|
36
39
  ext/tags.c
37
40
  ext/tags.h
38
41
  ext/toc.c
42
+ ext/version.c
39
43
  ext/xml.c
44
+ ext/xmlpage.c
40
45
  lib/markdown.rb
41
46
  lib/rdiscount.rb
42
47
  man/markdown.7
@@ -117,5 +117,10 @@ Obtuse text.[^1]
117
117
  EOS
118
118
  assert rd.to_html.include?('<a href="#fn:1" rel="footnote">1</a>')
119
119
  end
120
+
121
+ def test_that_unicode_urls_encoded_correctly
122
+ rd = RDiscount.new("[Test](http://example.com/ß)")
123
+ assert_equal "<p><a href=\"http://example.com/%C3%9F\">Test</a></p>\n", rd.to_html
124
+ end
120
125
 
121
126
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdiscount
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.7
4
+ version: 2.0.7.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2013-01-29 00:00:00.000000000 Z
15
+ date: 2013-02-26 00:00:00.000000000 Z
16
16
  dependencies: []
17
17
  description:
18
18
  email: rtomayko@gmail.com
@@ -29,6 +29,8 @@ files:
29
29
  - Rakefile
30
30
  - bin/rdiscount
31
31
  - ext/Csio.c
32
+ - ext/VERSION
33
+ - ext/amalloc.c
32
34
  - ext/amalloc.h
33
35
  - ext/basename.c
34
36
  - ext/config.h
@@ -38,6 +40,7 @@ files:
38
40
  - ext/dumptree.c
39
41
  - ext/emmatch.c
40
42
  - ext/extconf.rb
43
+ - ext/flags.c
41
44
  - ext/generate.c
42
45
  - ext/html5.c
43
46
  - ext/markdown.c
@@ -50,7 +53,9 @@ files:
50
53
  - ext/tags.c
51
54
  - ext/tags.h
52
55
  - ext/toc.c
56
+ - ext/version.c
53
57
  - ext/xml.c
58
+ - ext/xmlpage.c
54
59
  - lib/markdown.rb
55
60
  - lib/rdiscount.rb
56
61
  - man/markdown.7