bluecloth 2.0.9 → 2.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/ChangeLog +29 -2
- data/Rakefile +18 -15
- data/ext/VERSION +1 -1
- data/ext/bluecloth.c +26 -5
- data/ext/config.h +13 -2
- data/ext/css.c +14 -5
- data/ext/cstring.h +1 -1
- data/ext/docheader.c +13 -7
- data/ext/emmatch.c +1 -1
- data/ext/generate.c +134 -48
- data/ext/markdown.c +207 -94
- data/ext/markdown.h +37 -28
- data/ext/mkdio.c +39 -32
- data/ext/mkdio.h +34 -24
- data/ext/resource.c +3 -1
- data/ext/setup.c +47 -0
- data/ext/tags.c +15 -2
- data/ext/tags.h +1 -0
- data/lib/bluecloth.rb +65 -40
- data/rake/documentation.rb +9 -1
- data/rake/hg.rb +34 -3
- data/rake/packaging.rb +1 -1
- data/rake/publishing.rb +2 -9
- data/rake/testing.rb +53 -88
- data/spec/bluecloth/101_changes_spec.rb +17 -17
- data/spec/bluecloth/autolinks_spec.rb +1 -1
- data/spec/bluecloth/blockquotes_spec.rb +18 -18
- data/spec/bluecloth/code_spans_spec.rb +1 -1
- data/spec/bluecloth/emphasis_spec.rb +1 -1
- data/spec/bluecloth/entities_spec.rb +1 -1
- data/spec/bluecloth/hrules_spec.rb +1 -1
- data/spec/bluecloth/images_spec.rb +1 -1
- data/spec/bluecloth/inline_html_spec.rb +1 -1
- data/spec/bluecloth/links_spec.rb +1 -1
- data/spec/bluecloth/lists_spec.rb +1 -1
- data/spec/bluecloth/paragraphs_spec.rb +1 -1
- data/spec/bluecloth/titles_spec.rb +1 -1
- data/spec/bluecloth_spec.rb +13 -13
- data/spec/bugfix_spec.rb +6 -1
- data/spec/contributions_spec.rb +1 -1
- data/spec/discount_spec.rb +2 -2
- data/spec/lib/helpers.rb +1 -124
- data/spec/lib/matchers.rb +1 -1
- data/spec/markdowntest_spec.rb +1 -1
- metadata +10 -10
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/ChangeLog
CHANGED
@@ -1,4 +1,31 @@
|
|
1
|
-
|
1
|
+
147[tip] 6f434470d71c 2011-01-17 09:16 -0800 ged
|
2
|
+
Added tag 2.0.10 for changeset 85dc2533f18e
|
3
|
+
|
4
|
+
146[2.0.10] 85dc2533f18e 2011-01-17 09:16 -0800 ged
|
5
|
+
Added signature for changeset 3dd45baec201
|
6
|
+
|
7
|
+
145 3dd45baec201 2011-01-17 09:14 -0800 ged
|
8
|
+
Bumping version.
|
9
|
+
|
10
|
+
144 a12b01a92197 2011-01-17 09:13 -0800 ged
|
11
|
+
Updated to Discount 2.0.4:
|
12
|
+
|
13
|
+
143 5ef78d71c329 2010-10-15 08:20 -0700 ged
|
14
|
+
Adding an example for the 'Wrong (different) allignment in code block' ticket (refs #71).
|
15
|
+
|
16
|
+
142 0efe9f9e4598 2010-10-15 08:19 -0700 ged
|
17
|
+
Converting to RSpec 2.0.
|
18
|
+
|
19
|
+
141[github/master,master] 8372e8b4c95e 2010-09-23 07:25 -0700 ged
|
20
|
+
Added tag 2.0.9 for changeset 5bbf74a21ecb
|
21
|
+
|
22
|
+
140[2.0.9] 5bbf74a21ecb 2010-09-23 07:25 -0700 ged
|
23
|
+
Added signature for changeset 0a9f01744efb
|
24
|
+
|
25
|
+
139 0a9f01744efb 2010-09-23 07:24 -0700 ged
|
26
|
+
Added tag 2.0.8 for changeset 8ccd2cfe599e
|
27
|
+
|
28
|
+
138 486a5a2a8cd2 2010-09-23 07:15 -0700 ged
|
2
29
|
Bump version, update the Windows build to use 1.9.2 instead of 1.9.1.
|
3
30
|
|
4
31
|
137 1caa0c888dfe 2010-09-17 15:03 -0700 ged
|
@@ -19,7 +46,7 @@
|
|
19
46
|
132 3f36f96bfb8e 2010-08-16 11:50 -0700 ged
|
20
47
|
Install extension in arch-specific subdir [RPS]
|
21
48
|
|
22
|
-
131 8ccd2cfe599e 2010-08-11 09:54 -0600 ged
|
49
|
+
131[2.0.8] 8ccd2cfe599e 2010-08-11 09:54 -0600 ged
|
23
50
|
Bump version to 2.0.8
|
24
51
|
|
25
52
|
130 f2d6de73c6d6 2010-08-11 09:54 -0600 ged
|
data/Rakefile
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
#
|
5
5
|
# Based on various other Rakefiles, especially one by Ben Bleything
|
6
6
|
#
|
7
|
-
# Copyright (c) 2007-
|
7
|
+
# Copyright (c) 2007-2011 The FaerieMUD Consortium
|
8
8
|
#
|
9
9
|
# Authors:
|
10
10
|
# * Michael Granger <ged@FaerieMUD.org>
|
@@ -42,6 +42,7 @@ rescue LoadError
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
require 'pathname'
|
45
46
|
require 'rbconfig'
|
46
47
|
require 'rake'
|
47
48
|
require 'rake/testtask'
|
@@ -173,9 +174,9 @@ include RakefileHelpers
|
|
173
174
|
# Set the build ID if the mercurial executable is available
|
174
175
|
if hg = which( 'hg' )
|
175
176
|
id = `#{hg} id -n`.chomp
|
176
|
-
PKG_BUILD =
|
177
|
+
PKG_BUILD = (id.chomp[ /^[[:xdigit:]]+/ ] || '1')
|
177
178
|
else
|
178
|
-
PKG_BUILD = '
|
179
|
+
PKG_BUILD = '0'
|
179
180
|
end
|
180
181
|
SNAPSHOT_PKG_NAME = "#{PKG_FILE_NAME}.#{PKG_BUILD}"
|
181
182
|
SNAPSHOT_GEM_NAME = "#{SNAPSHOT_PKG_NAME}.gem"
|
@@ -192,7 +193,6 @@ RDOC_OPTIONS = [
|
|
192
193
|
]
|
193
194
|
YARD_OPTIONS = [
|
194
195
|
'--use-cache',
|
195
|
-
'--no-private',
|
196
196
|
'--protected',
|
197
197
|
'-r', README_FILE,
|
198
198
|
'--exclude', 'extconf\\.rb',
|
@@ -220,16 +220,15 @@ DEPENDENCIES = {
|
|
220
220
|
|
221
221
|
# Developer Gem dependencies: gemname => version
|
222
222
|
DEVELOPMENT_DEPENDENCIES = {
|
223
|
-
'rake'
|
224
|
-
'rcodetools'
|
225
|
-
'rcov'
|
226
|
-
'
|
227
|
-
'RedCloth'
|
228
|
-
'rspec'
|
229
|
-
'ruby-termios'
|
230
|
-
'text-format'
|
231
|
-
'tmail'
|
232
|
-
'diff-lcs' => '>= 1.1.2',
|
223
|
+
'rake' => '~> 0.8.7',
|
224
|
+
'rcodetools' => '~> 0.7.0.0',
|
225
|
+
'rcov' => '~> 0.8.1.2.0',
|
226
|
+
'yard' => '~> 0.6.1',
|
227
|
+
'RedCloth' => '~> 4.2.3',
|
228
|
+
'rspec' => '~> 2.0.1',
|
229
|
+
'ruby-termios' => '~> 0.9.6',
|
230
|
+
'text-format' => '~> 1.0.0',
|
231
|
+
'tmail' => '~> 1.2.3.1',
|
233
232
|
'tidy-ext' => '>= 0.1.10',
|
234
233
|
'rake-compiler' => '>= 0.7.0',
|
235
234
|
}
|
@@ -251,9 +250,10 @@ GEMSPEC = Gem::Specification.new do |gem|
|
|
251
250
|
"structurally valid XHTML (or HTML).",
|
252
251
|
].join( "\n" )
|
253
252
|
|
254
|
-
gem.authors = "Michael Granger"
|
253
|
+
gem.authors = ["Michael Granger"]
|
255
254
|
gem.email = ["ged@FaerieMUD.org"]
|
256
255
|
gem.homepage = 'http://deveiate.org/projects/BlueCloth/'
|
256
|
+
gem.licenses = ["BSD"]
|
257
257
|
|
258
258
|
gem.has_rdoc = true
|
259
259
|
gem.rdoc_options = RDOC_OPTIONS
|
@@ -275,6 +275,9 @@ GEMSPEC = Gem::Specification.new do |gem|
|
|
275
275
|
gem.signing_key = '/Volumes/Keys/ged-private_gem_key.pem'
|
276
276
|
gem.cert_chain = [File.expand_path('~/.gem/ged-public_gem_cert.pem')]
|
277
277
|
|
278
|
+
|
279
|
+
gem.required_ruby_version = '>= 1.8.7'
|
280
|
+
|
278
281
|
DEPENDENCIES.each do |name, version|
|
279
282
|
version = '>= 0' if version.length.zero?
|
280
283
|
gem.add_runtime_dependency( name, version )
|
data/ext/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.4
|
data/ext/bluecloth.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* BlueCloth -- a Ruby implementation of Markdown
|
3
|
-
* $Id: bluecloth.c,v
|
3
|
+
* $Id: bluecloth.c,v a12b01a92197 2011/01/17 17:13:22 ged $
|
4
4
|
*
|
5
5
|
* = Authors
|
6
6
|
*
|
@@ -185,8 +185,9 @@ static VALUE
|
|
185
185
|
bluecloth_initialize( int argc, VALUE *argv, VALUE self ) {
|
186
186
|
if ( !bluecloth_check_ptr(self) ) {
|
187
187
|
MMIOT *document;
|
188
|
-
VALUE text,
|
188
|
+
VALUE text, optflags, fullhash, opthash = Qnil;
|
189
189
|
int flags = 0;
|
190
|
+
VALUE utf8text = Qnil;
|
190
191
|
|
191
192
|
rb_scan_args( argc, argv, "02", &text, &opthash );
|
192
193
|
|
@@ -254,12 +255,12 @@ bluecloth_to_html( VALUE self ) {
|
|
254
255
|
if ( (length = mkd_document( document, &output )) != EOF ) {
|
255
256
|
#ifdef M17N_SUPPORTED
|
256
257
|
VALUE orig_encoding = rb_obj_encoding( rb_iv_get(self, "@text") );
|
257
|
-
VALUE utf8_result = rb_enc_str_new( output,
|
258
|
+
VALUE utf8_result = rb_enc_str_new( output, strlen(output), rb_utf8_encoding() );
|
258
259
|
result = rb_str_encode( utf8_result, orig_encoding, 0, Qnil );
|
259
260
|
bluecloth_debug( "Bytes after un-utf8ification (if necessary): %s",
|
260
261
|
RSTRING_PTR(rb_funcall(result, rb_intern("dump"), 0, Qnil)) );
|
261
262
|
#else
|
262
|
-
result =
|
263
|
+
result = rb_str_new2( output );
|
263
264
|
#endif /* M17N_SUPPORTED */
|
264
265
|
|
265
266
|
OBJ_INFECT( result, self );
|
@@ -371,6 +372,15 @@ void Init_bluecloth_ext( void ) {
|
|
371
372
|
/* don't allow pseudo-protocols */
|
372
373
|
rb_define_const( bluecloth_cBlueCloth, "MKD_NO_EXT", INT2FIX(MKD_NO_EXT) );
|
373
374
|
|
375
|
+
/* Generate code for xml ![CDATA[...]] */
|
376
|
+
rb_define_const( bluecloth_cBlueCloth, "MKD_CDATA", INT2FIX(MKD_CDATA) );
|
377
|
+
|
378
|
+
/* Don't use superscript extension */
|
379
|
+
rb_define_const( bluecloth_cBlueCloth, "MKD_NOSUPERSCRIPT", INT2FIX(MKD_NOSUPERSCRIPT) );
|
380
|
+
|
381
|
+
/* Relaxed emphasis -- emphasis happens everywhere */
|
382
|
+
rb_define_const( bluecloth_cBlueCloth, "MKD_NORELAXED", INT2FIX(MKD_NORELAXED) );
|
383
|
+
|
374
384
|
/* disallow tables */
|
375
385
|
rb_define_const( bluecloth_cBlueCloth, "MKD_NOTABLES", INT2FIX(MKD_NOTABLES) );
|
376
386
|
|
@@ -392,10 +402,21 @@ void Init_bluecloth_ext( void ) {
|
|
392
402
|
/* Be paranoid about link protocols */
|
393
403
|
rb_define_const( bluecloth_cBlueCloth, "MKD_SAFELINK", INT2FIX(MKD_SAFELINK) );
|
394
404
|
|
395
|
-
|
396
405
|
/* don't process header blocks */
|
397
406
|
rb_define_const( bluecloth_cBlueCloth, "MKD_NOHEADER", INT2FIX(MKD_NOHEADER) );
|
398
407
|
|
408
|
+
/* Expand tabs to 4 spaces */
|
409
|
+
rb_define_const( bluecloth_cBlueCloth, "MKD_TABSTOP", INT2FIX(MKD_TABSTOP) );
|
410
|
+
|
411
|
+
/* Forbid '>%class%' blocks */
|
412
|
+
rb_define_const( bluecloth_cBlueCloth, "MKD_NODIVQUOTE", INT2FIX(MKD_NODIVQUOTE) );
|
413
|
+
|
414
|
+
/* Forbid alphabetic lists */
|
415
|
+
rb_define_const( bluecloth_cBlueCloth, "MKD_NOALPHALIST", INT2FIX(MKD_NOALPHALIST) );
|
416
|
+
|
417
|
+
/* Forbid definition lists */
|
418
|
+
rb_define_const( bluecloth_cBlueCloth, "MKD_NODLIST", INT2FIX(MKD_NODLIST) );
|
419
|
+
|
399
420
|
|
400
421
|
/* Make sure the Ruby side is loaded */
|
401
422
|
rb_require( "bluecloth" );
|
data/ext/config.h
CHANGED
@@ -1,11 +1,22 @@
|
|
1
1
|
/*
|
2
|
-
*
|
3
|
-
* by ged@tenar.home.faeriemud.org
|
2
|
+
* Hacked-up version of the config file generated by discount
|
4
3
|
*/
|
5
4
|
|
6
5
|
#ifndef CONFIG_H_RZLE3ADO
|
7
6
|
#define CONFIG_H_RZLE3ADO
|
8
7
|
|
8
|
+
#include "extconf.h"
|
9
|
+
|
10
|
+
#if SIZEOF_LONG == 8
|
11
|
+
# define DWORD unsigned int
|
12
|
+
# define WORD unsigned short
|
13
|
+
#else
|
14
|
+
# define DWORD unsigned long
|
15
|
+
# define WORD unsigned int
|
16
|
+
#endif
|
17
|
+
|
18
|
+
#define BYTE unsigned char
|
19
|
+
|
9
20
|
#ifdef RUBY_EXTCONF_H
|
10
21
|
# include RUBY_EXTCONF_H
|
11
22
|
#endif
|
data/ext/css.c
CHANGED
@@ -28,9 +28,10 @@ stylesheets(Paragraph *p, Cstring *f)
|
|
28
28
|
|
29
29
|
for ( ; p ; p = p->next ) {
|
30
30
|
if ( p->typ == STYLE ) {
|
31
|
-
for ( q = p->text; q ; q = q->next )
|
31
|
+
for ( q = p->text; q ; q = q->next ) {
|
32
32
|
Cswrite(f, T(q->text), S(q->text));
|
33
33
|
Csputc('\n', f);
|
34
|
+
}
|
34
35
|
}
|
35
36
|
if ( p->down )
|
36
37
|
stylesheets(p->down, f);
|
@@ -44,17 +45,25 @@ int
|
|
44
45
|
mkd_css(Document *d, char **res)
|
45
46
|
{
|
46
47
|
Cstring f;
|
48
|
+
int size;
|
47
49
|
|
48
|
-
if ( res &&
|
50
|
+
if ( res && d && d->compiled ) {
|
51
|
+
*res = 0;
|
49
52
|
CREATE(f);
|
50
53
|
RESERVE(f, 100);
|
51
54
|
stylesheets(d->code, &f);
|
52
55
|
|
56
|
+
if ( (size = S(f)) > 0 ) {
|
57
|
+
EXPAND(f) = 0;
|
53
58
|
/* HACK ALERT! HACK ALERT! HACK ALERT! */
|
54
|
-
|
59
|
+
*res = T(f);/* we know that a T(Cstring) is a character pointer */
|
55
60
|
/* so we can simply pick it up and carry it away, */
|
56
|
-
|
61
|
+
/* leaving the husk of the Ctring on the stack */
|
57
62
|
/* END HACK ALERT */
|
63
|
+
}
|
64
|
+
else
|
65
|
+
DELETE(f);
|
66
|
+
return size;
|
58
67
|
}
|
59
68
|
return EOF;
|
60
69
|
}
|
@@ -69,7 +78,7 @@ mkd_generatecss(Document *d, FILE *f)
|
|
69
78
|
int written = EOF, size = mkd_css(d, &res);
|
70
79
|
|
71
80
|
if ( size > 0 )
|
72
|
-
written = fwrite(res,
|
81
|
+
written = fwrite(res, 1, size, f);
|
73
82
|
if ( res )
|
74
83
|
free(res);
|
75
84
|
return (written == size) ? size : EOF;
|
data/ext/cstring.h
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
*/
|
19
19
|
#define STRING(type) struct { type *text; int size, alloc; }
|
20
20
|
|
21
|
-
#define CREATE(x) T(x) = (void*)(S(x) = (x).alloc = 0)
|
21
|
+
#define CREATE(x) ( (T(x) = (void*)0), (S(x) = (x).alloc = 0) )
|
22
22
|
#define EXPAND(x) (S(x)++)[(S(x) < (x).alloc) \
|
23
23
|
? (T(x)) \
|
24
24
|
: (T(x) = T(x) ? realloc(T(x), sizeof T(x)[0] * ((x).alloc += 100)) \
|
data/ext/docheader.c
CHANGED
@@ -14,13 +14,19 @@
|
|
14
14
|
#include "markdown.h"
|
15
15
|
#include "amalloc.h"
|
16
16
|
|
17
|
-
|
17
|
+
static char *
|
18
|
+
onlyifset(Line *l)
|
19
|
+
{
|
20
|
+
char *ret = T(l->text) + l->dle;
|
21
|
+
|
22
|
+
return ret[0] ? ret : 0;
|
23
|
+
}
|
18
24
|
|
19
25
|
char *
|
20
26
|
mkd_doc_title(Document *doc)
|
21
27
|
{
|
22
|
-
if ( doc && doc->
|
23
|
-
return
|
28
|
+
if ( doc && doc->title )
|
29
|
+
return onlyifset(doc->title);
|
24
30
|
return 0;
|
25
31
|
}
|
26
32
|
|
@@ -28,8 +34,8 @@ mkd_doc_title(Document *doc)
|
|
28
34
|
char *
|
29
35
|
mkd_doc_author(Document *doc)
|
30
36
|
{
|
31
|
-
if ( doc && doc->
|
32
|
-
return
|
37
|
+
if ( doc && doc->author )
|
38
|
+
return onlyifset(doc->author);
|
33
39
|
return 0;
|
34
40
|
}
|
35
41
|
|
@@ -37,7 +43,7 @@ mkd_doc_author(Document *doc)
|
|
37
43
|
char *
|
38
44
|
mkd_doc_date(Document *doc)
|
39
45
|
{
|
40
|
-
if ( doc && doc->
|
41
|
-
return
|
46
|
+
if ( doc && doc->date )
|
47
|
+
return onlyifset(doc->date);
|
42
48
|
return 0;
|
43
49
|
}
|
data/ext/emmatch.c
CHANGED
@@ -163,7 +163,7 @@ emblock(MMIOT *f, int first, int last)
|
|
163
163
|
} /* emblock */
|
164
164
|
|
165
165
|
|
166
|
-
/* ___mkd_emblock() -- emblock a string of blocks, then
|
166
|
+
/* ___mkd_emblock() -- emblock a string of blocks, then concatenate the
|
167
167
|
* resulting text onto f->out.
|
168
168
|
*/
|
169
169
|
void
|
data/ext/generate.c
CHANGED
@@ -351,6 +351,53 @@ linkysize(MMIOT *f, Footnote *ref)
|
|
351
351
|
}
|
352
352
|
|
353
353
|
|
354
|
+
/* extract a <...>-encased url from the input stream.
|
355
|
+
* (markdown 1.0.2b8 compatibility; older versions
|
356
|
+
* of markdown treated the < and > as syntactic
|
357
|
+
* sugar that didn't have to be there. 1.0.2b8
|
358
|
+
* requires a closing >, and then falls into the
|
359
|
+
* title or closing )
|
360
|
+
*/
|
361
|
+
static int
|
362
|
+
linkybroket(MMIOT *f, int image, Footnote *p)
|
363
|
+
{
|
364
|
+
int c;
|
365
|
+
int good = 0;
|
366
|
+
|
367
|
+
T(p->link) = cursor(f);
|
368
|
+
for ( S(p->link)=0; (c = pull(f)) != '>'; ++S(p->link) ) {
|
369
|
+
/* pull in all input until a '>' is found, or die trying.
|
370
|
+
*/
|
371
|
+
if ( c == EOF )
|
372
|
+
return 0;
|
373
|
+
else if ( (c == '\\') && ispunct(peek(f,2)) ) {
|
374
|
+
++S(p->link);
|
375
|
+
pull(f);
|
376
|
+
}
|
377
|
+
}
|
378
|
+
|
379
|
+
c = eatspace(f);
|
380
|
+
|
381
|
+
/* next nonspace needs to be a title, a size, or )
|
382
|
+
*/
|
383
|
+
if ( ( c == '\'' || c == '"' ) && linkytitle(f,c,p) )
|
384
|
+
good=1;
|
385
|
+
else if ( image && (c == '=') && linkysize(f,p) )
|
386
|
+
good=1;
|
387
|
+
else
|
388
|
+
good=( c == ')' );
|
389
|
+
|
390
|
+
if ( good ) {
|
391
|
+
if ( peek(f, 1) == ')' )
|
392
|
+
pull(f);
|
393
|
+
|
394
|
+
___mkd_tidy(&p->link);
|
395
|
+
}
|
396
|
+
|
397
|
+
return good;
|
398
|
+
} /* linkybroket */
|
399
|
+
|
400
|
+
|
354
401
|
/* extract a (-prefixed url from the input stream.
|
355
402
|
* the label is either of the format `<link>`, where I
|
356
403
|
* extract until I find a >, or it is of the format
|
@@ -368,6 +415,8 @@ linkyurl(MMIOT *f, int image, Footnote *p)
|
|
368
415
|
|
369
416
|
if ( c == '<' ) {
|
370
417
|
pull(f);
|
418
|
+
if ( !(f->flags & MKD_1_COMPAT) )
|
419
|
+
return linkybroket(f,image,p);
|
371
420
|
mayneedtotrim=1;
|
372
421
|
}
|
373
422
|
|
@@ -405,10 +454,10 @@ static struct _protocol {
|
|
405
454
|
int nlen;
|
406
455
|
} protocol[] = {
|
407
456
|
#define _aprotocol(x) { x, (sizeof x)-1 }
|
408
|
-
_aprotocol( "https
|
409
|
-
_aprotocol( "http
|
410
|
-
_aprotocol( "news
|
411
|
-
_aprotocol( "ftp
|
457
|
+
_aprotocol( "https:" ),
|
458
|
+
_aprotocol( "http:" ),
|
459
|
+
_aprotocol( "news:" ),
|
460
|
+
_aprotocol( "ftp:" ),
|
412
461
|
#undef _aprotocol
|
413
462
|
};
|
414
463
|
#define NRPROTOCOLS (sizeof protocol / sizeof protocol[0])
|
@@ -445,9 +494,9 @@ typedef struct linkytype {
|
|
445
494
|
} linkytype;
|
446
495
|
|
447
496
|
static linkytype imaget = { 0, 0, "<img src=\"", "\"",
|
448
|
-
1, " alt=\"", "\" />",
|
497
|
+
1, " alt=\"", "\" />", MKD_NOIMAGE|MKD_TAGTEXT, IS_URL };
|
449
498
|
static linkytype linkt = { 0, 0, "<a href=\"", "\"",
|
450
|
-
0, ">", "</a>",
|
499
|
+
0, ">", "</a>", MKD_NOLINKS, IS_URL };
|
451
500
|
|
452
501
|
/*
|
453
502
|
* pseudo-protocols for [][];
|
@@ -457,8 +506,8 @@ static linkytype linkt = { 0, 0, "<a href=\"", "\"",
|
|
457
506
|
* raw: just dump the link without any processing
|
458
507
|
*/
|
459
508
|
static linkytype specials[] = {
|
460
|
-
{ "id:", 3, "<
|
461
|
-
{ "raw:", 4, 0, 0, 0, 0, 0,
|
509
|
+
{ "id:", 3, "<span id=\"", "\"", 0, ">", "</span>", 0, 0 },
|
510
|
+
{ "raw:", 4, 0, 0, 0, 0, 0, MKD_NOHTML, 0 },
|
462
511
|
{ "lang:", 5, "<span lang=\"", "\"", 0, ">", "</span>", 0, 0 },
|
463
512
|
{ "abbr:", 5, "<abbr title=\"", "\"", 0, ">", "</abbr>", 0, 0 },
|
464
513
|
{ "class:", 6, "<span class=\"", "\"", 0, ">", "</span>", 0, 0 },
|
@@ -489,10 +538,13 @@ printlinkyref(MMIOT *f, linkytype *tag, char *link, int size)
|
|
489
538
|
{
|
490
539
|
char *edit;
|
491
540
|
|
541
|
+
if ( f->flags & IS_LABEL )
|
542
|
+
return;
|
543
|
+
|
492
544
|
Qstring(tag->link_pfx, f);
|
493
545
|
|
494
546
|
if ( tag->kind & IS_URL ) {
|
495
|
-
if ( f->cb->e_url && (edit = (*f->cb->e_url)(link, size, f->cb->e_data)) ) {
|
547
|
+
if ( f->cb && f->cb->e_url && (edit = (*f->cb->e_url)(link, size, f->cb->e_data)) ) {
|
496
548
|
puturl(edit, strlen(edit), f, 0);
|
497
549
|
if ( f->cb->e_free ) (*f->cb->e_free)(edit, f->cb->e_data);
|
498
550
|
}
|
@@ -500,11 +552,11 @@ printlinkyref(MMIOT *f, linkytype *tag, char *link, int size)
|
|
500
552
|
puturl(link + tag->szpat, size - tag->szpat, f, 0);
|
501
553
|
}
|
502
554
|
else
|
503
|
-
___mkd_reparse(link + tag->szpat, size - tag->szpat,
|
555
|
+
___mkd_reparse(link + tag->szpat, size - tag->szpat, MKD_TAGTEXT, f);
|
504
556
|
|
505
557
|
Qstring(tag->link_sfx, f);
|
506
558
|
|
507
|
-
if ( f->cb->e_flags && (edit = (*f->cb->e_flags)(link, size, f->cb->e_data)) ) {
|
559
|
+
if ( f->cb && f->cb->e_flags && (edit = (*f->cb->e_flags)(link, size, f->cb->e_data)) ) {
|
508
560
|
Qchar(' ', f);
|
509
561
|
Qstring(edit, f);
|
510
562
|
if ( f->cb->e_free ) (*f->cb->e_free)(edit, f->cb->e_data);
|
@@ -522,13 +574,13 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
|
|
522
574
|
if ( image )
|
523
575
|
tag = &imaget;
|
524
576
|
else if ( tag = pseudo(ref->link) ) {
|
525
|
-
if ( f->flags & (
|
577
|
+
if ( f->flags & (MKD_NO_EXT|MKD_SAFELINK) )
|
526
578
|
return 0;
|
527
579
|
}
|
528
|
-
else if ( (f->flags &
|
529
|
-
|
530
|
-
|
531
|
-
/* if
|
580
|
+
else if ( (f->flags & MKD_SAFELINK) && T(ref->link)
|
581
|
+
&& (T(ref->link)[0] != '/')
|
582
|
+
&& !isautoprefix(T(ref->link), S(ref->link)) )
|
583
|
+
/* if MKD_SAFELINK, only accept links that are local or
|
532
584
|
* a well-known protocol
|
533
585
|
*/
|
534
586
|
return 0;
|
@@ -538,7 +590,9 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
|
|
538
590
|
if ( f->flags & tag->flags )
|
539
591
|
return 0;
|
540
592
|
|
541
|
-
if (
|
593
|
+
if ( f->flags & IS_LABEL )
|
594
|
+
___mkd_reparse(T(text), S(text), tag->flags, f);
|
595
|
+
else if ( tag->link_pfx ) {
|
542
596
|
printlinkyref(f, tag, T(ref->link), S(ref->link));
|
543
597
|
|
544
598
|
if ( tag->WxH ) {
|
@@ -548,7 +602,7 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
|
|
548
602
|
|
549
603
|
if ( S(ref->title) ) {
|
550
604
|
Qstring(" title=\"", f);
|
551
|
-
___mkd_reparse(T(ref->title), S(ref->title),
|
605
|
+
___mkd_reparse(T(ref->title), S(ref->title), MKD_TAGTEXT, f);
|
552
606
|
Qchar('"', f);
|
553
607
|
}
|
554
608
|
|
@@ -587,7 +641,10 @@ linkylinky(int image, MMIOT *f)
|
|
587
641
|
else {
|
588
642
|
int goodlink, implicit_mark = mmiottell(f);
|
589
643
|
|
590
|
-
if (
|
644
|
+
if ( isspace(peek(f,1)) )
|
645
|
+
pull(f);
|
646
|
+
|
647
|
+
if ( peek(f,1) == '[' ) {
|
591
648
|
pull(f); /* consume leading '[' */
|
592
649
|
goodlink = linkylabel(f, &key.tag);
|
593
650
|
}
|
@@ -609,6 +666,8 @@ linkylinky(int image, MMIOT *f)
|
|
609
666
|
if ( ref = bsearch(&key, T(*f->footnotes), S(*f->footnotes),
|
610
667
|
sizeof key, (stfu)__mkd_footsort) )
|
611
668
|
status = linkyformat(f, name, image, ref);
|
669
|
+
else if ( f->flags & IS_LABEL )
|
670
|
+
status = linkyformat(f, name, image, &imaget);
|
612
671
|
}
|
613
672
|
}
|
614
673
|
}
|
@@ -744,19 +803,19 @@ codespan(MMIOT *f, int size)
|
|
744
803
|
|
745
804
|
|
746
805
|
/* before letting a tag through, validate against
|
747
|
-
*
|
806
|
+
* MKD_NOLINKS and MKD_NOIMAGE
|
748
807
|
*/
|
749
808
|
static int
|
750
809
|
forbidden_tag(MMIOT *f)
|
751
810
|
{
|
752
811
|
int c = toupper(peek(f, 1));
|
753
812
|
|
754
|
-
if ( f->flags &
|
813
|
+
if ( f->flags & MKD_NOHTML )
|
755
814
|
return 1;
|
756
815
|
|
757
|
-
if ( c == 'A' && (f->flags &
|
816
|
+
if ( c == 'A' && (f->flags & MKD_NOLINKS) && !isthisalnum(f,2) )
|
758
817
|
return 1;
|
759
|
-
if ( c == 'I' && (f->flags &
|
818
|
+
if ( c == 'I' && (f->flags & MKD_NOIMAGE)
|
760
819
|
&& strncasecmp(cursor(f)+1, "MG", 2) == 0
|
761
820
|
&& !isthisalnum(f,4) )
|
762
821
|
return 1;
|
@@ -803,7 +862,7 @@ process_possible_link(MMIOT *f, int size)
|
|
803
862
|
int mailto = 0;
|
804
863
|
char *text = cursor(f);
|
805
864
|
|
806
|
-
if ( f->flags &
|
865
|
+
if ( f->flags & MKD_NOLINKS ) return 0;
|
807
866
|
|
808
867
|
if ( (size > 7) && strncasecmp(text, "mailto:", 7) == 0 ) {
|
809
868
|
/* if it says it's a mailto, it's a mailto -- who am
|
@@ -850,7 +909,7 @@ maybe_tag_or_link(MMIOT *f)
|
|
850
909
|
int c, size;
|
851
910
|
int maybetag = 1;
|
852
911
|
|
853
|
-
if ( f->flags &
|
912
|
+
if ( f->flags & MKD_TAGTEXT )
|
854
913
|
return 0;
|
855
914
|
|
856
915
|
for ( size=0; (c = peek(f, size+1)) != '>'; size++) {
|
@@ -1013,7 +1072,7 @@ smartypants(int c, int *flags, MMIOT *f)
|
|
1013
1072
|
{
|
1014
1073
|
int i;
|
1015
1074
|
|
1016
|
-
if ( f->flags & (
|
1075
|
+
if ( f->flags & (MKD_NOPANTS|MKD_TAGTEXT|IS_LABEL) )
|
1017
1076
|
return 0;
|
1018
1077
|
|
1019
1078
|
for ( i=0; i < NRSMART; i++)
|
@@ -1081,7 +1140,7 @@ tickhandler(MMIOT *f, int tickchar, int minticks, spanhandler spanner)
|
|
1081
1140
|
return 0;
|
1082
1141
|
}
|
1083
1142
|
|
1084
|
-
#define tag_text(f) (f->flags &
|
1143
|
+
#define tag_text(f) (f->flags & MKD_TAGTEXT)
|
1085
1144
|
|
1086
1145
|
|
1087
1146
|
static void
|
@@ -1092,7 +1151,7 @@ text(MMIOT *f)
|
|
1092
1151
|
int smartyflags = 0;
|
1093
1152
|
|
1094
1153
|
while (1) {
|
1095
|
-
if ( (f->flags &
|
1154
|
+
if ( (f->flags & MKD_AUTOLINK) && isalpha(peek(f,1)) && !tag_text(f) )
|
1096
1155
|
maybe_autolink(f);
|
1097
1156
|
|
1098
1157
|
c = pull(f);
|
@@ -1131,32 +1190,48 @@ text(MMIOT *f)
|
|
1131
1190
|
case '[': if ( tag_text(f) || !linkylinky(0, f) )
|
1132
1191
|
Qchar(c, f);
|
1133
1192
|
break;
|
1134
|
-
#if SUPERSCRIPT
|
1135
1193
|
/* A^B -> A<sup>B</sup> */
|
1136
|
-
case '^': if ( (f->flags & (
|
1194
|
+
case '^': if ( (f->flags & (MKD_NOSUPERSCRIPT|MKD_STRICT|MKD_TAGTEXT))
|
1195
|
+
|| (isthisnonword(f,-1) && peek(f,-1) != ')')
|
1196
|
+
|| isthisspace(f,1) )
|
1137
1197
|
Qchar(c,f);
|
1138
1198
|
else {
|
1139
1199
|
char *sup = cursor(f);
|
1140
1200
|
int len = 0;
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1201
|
+
|
1202
|
+
if ( peek(f,1) == '(' ) {
|
1203
|
+
int here = mmiottell(f);
|
1204
|
+
pull(f);
|
1205
|
+
|
1206
|
+
if ( (len = parenthetical('(',')',f)) <= 0 ) {
|
1207
|
+
mmiotseek(f,here);
|
1208
|
+
Qchar(c, f);
|
1209
|
+
break;
|
1210
|
+
}
|
1211
|
+
sup++;
|
1212
|
+
}
|
1213
|
+
else {
|
1214
|
+
while ( isthisalnum(f,1+len) )
|
1215
|
+
++len;
|
1216
|
+
if ( !len ) {
|
1217
|
+
Qchar(c,f);
|
1218
|
+
break;
|
1219
|
+
}
|
1220
|
+
shift(f,len);
|
1144
1221
|
}
|
1145
|
-
|
1222
|
+
Qstring("<sup>",f);
|
1146
1223
|
___mkd_reparse(sup, len, 0, f);
|
1147
1224
|
Qstring("</sup>", f);
|
1148
1225
|
}
|
1149
1226
|
break;
|
1150
|
-
#endif
|
1151
1227
|
case '_':
|
1152
|
-
#if RELAXED_EMPHASIS
|
1153
1228
|
/* Underscores don't count if they're in the middle of a word */
|
1154
|
-
if ( !(f->flags &
|
1155
|
-
|
1229
|
+
if ( !(f->flags & (MKD_NORELAXED|MKD_STRICT))
|
1230
|
+
&& isthisalnum(f,-1)
|
1231
|
+
&& isthisalnum(f,1) ) {
|
1156
1232
|
Qchar(c, f);
|
1157
1233
|
break;
|
1158
1234
|
}
|
1159
|
-
#endif
|
1160
1235
|
case '*':
|
1161
1236
|
/* Underscores & stars don't count if they're out in the middle
|
1162
1237
|
* of whitespace */
|
@@ -1174,7 +1249,7 @@ text(MMIOT *f)
|
|
1174
1249
|
}
|
1175
1250
|
break;
|
1176
1251
|
|
1177
|
-
case '~': if ( (f->flags & (
|
1252
|
+
case '~': if ( (f->flags & (MKD_NOSTRIKETHROUGH|MKD_TAGTEXT|MKD_STRICT)) || !tickhandler(f,c,2,delspan) )
|
1178
1253
|
Qchar(c, f);
|
1179
1254
|
break;
|
1180
1255
|
|
@@ -1187,6 +1262,14 @@ text(MMIOT *f)
|
|
1187
1262
|
break;
|
1188
1263
|
case '<': Qstring("<", f);
|
1189
1264
|
break;
|
1265
|
+
case '^': if ( f->flags & (MKD_STRICT|MKD_NOSUPERSCRIPT) ) {
|
1266
|
+
Qchar('\\', f);
|
1267
|
+
shift(f,-1);
|
1268
|
+
break;
|
1269
|
+
}
|
1270
|
+
Qchar(c, f);
|
1271
|
+
break;
|
1272
|
+
|
1190
1273
|
case '>': case '#': case '.': case '-':
|
1191
1274
|
case '+': case '{': case '}': case ']':
|
1192
1275
|
case '!': case '[': case '*': case '_':
|
@@ -1230,9 +1313,9 @@ static void
|
|
1230
1313
|
printheader(Paragraph *pp, MMIOT *f)
|
1231
1314
|
{
|
1232
1315
|
Qprintf(f, "<h%d", pp->hnumber);
|
1233
|
-
if ( f->flags &
|
1316
|
+
if ( f->flags & MKD_TOC ) {
|
1234
1317
|
Qprintf(f, " id=\"", pp->hnumber);
|
1235
|
-
mkd_string_to_anchor(T(pp->text->text), S(pp->text->text), Qchar, f);
|
1318
|
+
mkd_string_to_anchor(T(pp->text->text), S(pp->text->text), Qchar, f, 1);
|
1236
1319
|
Qchar('"', f);
|
1237
1320
|
}
|
1238
1321
|
Qchar('>', f);
|
@@ -1432,7 +1515,6 @@ htmlify(Paragraph *p, char *block, char *arguments, MMIOT *f)
|
|
1432
1515
|
}
|
1433
1516
|
|
1434
1517
|
|
1435
|
-
#if DL_TAG_EXTENSION
|
1436
1518
|
static void
|
1437
1519
|
definitionlist(Paragraph *p, MMIOT *f)
|
1438
1520
|
{
|
@@ -1455,7 +1537,6 @@ definitionlist(Paragraph *p, MMIOT *f)
|
|
1455
1537
|
Qstring("</dl>", f);
|
1456
1538
|
}
|
1457
1539
|
}
|
1458
|
-
#endif
|
1459
1540
|
|
1460
1541
|
|
1461
1542
|
static void
|
@@ -1464,7 +1545,7 @@ listdisplay(int typ, Paragraph *p, MMIOT* f)
|
|
1464
1545
|
if ( p ) {
|
1465
1546
|
Qprintf(f, "<%cl", (typ==UL)?'u':'o');
|
1466
1547
|
if ( typ == AL )
|
1467
|
-
Qprintf(f, " type
|
1548
|
+
Qprintf(f, " type=\"a\"");
|
1468
1549
|
Qprintf(f, ">\n");
|
1469
1550
|
|
1470
1551
|
for ( ; p ; p = p->next ) {
|
@@ -1507,11 +1588,9 @@ display(Paragraph *p, MMIOT *f)
|
|
1507
1588
|
listdisplay(p->typ, p->down, f);
|
1508
1589
|
break;
|
1509
1590
|
|
1510
|
-
#if DL_TAG_EXTENSION
|
1511
1591
|
case DL:
|
1512
1592
|
definitionlist(p->down, f);
|
1513
1593
|
break;
|
1514
|
-
#endif
|
1515
1594
|
|
1516
1595
|
case HR:
|
1517
1596
|
Qstring("<hr />", f);
|
@@ -1543,14 +1622,21 @@ display(Paragraph *p, MMIOT *f)
|
|
1543
1622
|
int
|
1544
1623
|
mkd_document(Document *p, char **res)
|
1545
1624
|
{
|
1625
|
+
int size;
|
1626
|
+
|
1546
1627
|
if ( p && p->compiled ) {
|
1547
1628
|
if ( ! p->html ) {
|
1548
1629
|
htmlify(p->code, 0, 0, p->ctx);
|
1549
1630
|
p->html = 1;
|
1550
1631
|
}
|
1551
1632
|
|
1633
|
+
size = S(p->ctx->out);
|
1634
|
+
|
1635
|
+
if ( (size == 0) || T(p->ctx->out)[size-1] )
|
1636
|
+
EXPAND(p->ctx->out) = 0;
|
1637
|
+
|
1552
1638
|
*res = T(p->ctx->out);
|
1553
|
-
return
|
1639
|
+
return size;
|
1554
1640
|
}
|
1555
1641
|
return EOF;
|
1556
1642
|
}
|