bluecloth 2.0.9 → 2.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data.tar.gz.sig +0 -0
  2. data/ChangeLog +29 -2
  3. data/Rakefile +18 -15
  4. data/ext/VERSION +1 -1
  5. data/ext/bluecloth.c +26 -5
  6. data/ext/config.h +13 -2
  7. data/ext/css.c +14 -5
  8. data/ext/cstring.h +1 -1
  9. data/ext/docheader.c +13 -7
  10. data/ext/emmatch.c +1 -1
  11. data/ext/generate.c +134 -48
  12. data/ext/markdown.c +207 -94
  13. data/ext/markdown.h +37 -28
  14. data/ext/mkdio.c +39 -32
  15. data/ext/mkdio.h +34 -24
  16. data/ext/resource.c +3 -1
  17. data/ext/setup.c +47 -0
  18. data/ext/tags.c +15 -2
  19. data/ext/tags.h +1 -0
  20. data/lib/bluecloth.rb +65 -40
  21. data/rake/documentation.rb +9 -1
  22. data/rake/hg.rb +34 -3
  23. data/rake/packaging.rb +1 -1
  24. data/rake/publishing.rb +2 -9
  25. data/rake/testing.rb +53 -88
  26. data/spec/bluecloth/101_changes_spec.rb +17 -17
  27. data/spec/bluecloth/autolinks_spec.rb +1 -1
  28. data/spec/bluecloth/blockquotes_spec.rb +18 -18
  29. data/spec/bluecloth/code_spans_spec.rb +1 -1
  30. data/spec/bluecloth/emphasis_spec.rb +1 -1
  31. data/spec/bluecloth/entities_spec.rb +1 -1
  32. data/spec/bluecloth/hrules_spec.rb +1 -1
  33. data/spec/bluecloth/images_spec.rb +1 -1
  34. data/spec/bluecloth/inline_html_spec.rb +1 -1
  35. data/spec/bluecloth/links_spec.rb +1 -1
  36. data/spec/bluecloth/lists_spec.rb +1 -1
  37. data/spec/bluecloth/paragraphs_spec.rb +1 -1
  38. data/spec/bluecloth/titles_spec.rb +1 -1
  39. data/spec/bluecloth_spec.rb +13 -13
  40. data/spec/bugfix_spec.rb +6 -1
  41. data/spec/contributions_spec.rb +1 -1
  42. data/spec/discount_spec.rb +2 -2
  43. data/spec/lib/helpers.rb +1 -124
  44. data/spec/lib/matchers.rb +1 -1
  45. data/spec/markdowntest_spec.rb +1 -1
  46. metadata +10 -10
  47. metadata.gz.sig +0 -0
data.tar.gz.sig CHANGED
Binary file
data/ChangeLog CHANGED
@@ -1,4 +1,31 @@
1
- 138[tip] 486a5a2a8cd2 2010-09-23 07:15 -0700 ged
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-2010 The FaerieMUD Consortium
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 = "pre%03d" % [(id.chomp[ /^[[:xdigit:]]+/ ] || '1')]
177
+ PKG_BUILD = (id.chomp[ /^[[:xdigit:]]+/ ] || '1')
177
178
  else
178
- PKG_BUILD = 'pre000'
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' => '>= 0.8.7',
224
- 'rcodetools' => '>= 0.7.0.0',
225
- 'rcov' => '>= 0.8.1.2.0',
226
- 'rdoc' => '>= 2.4.3',
227
- 'RedCloth' => '>= 4.0.3',
228
- 'rspec' => '>= 1.2.6',
229
- 'ruby-termios' => '>= 0.9.6',
230
- 'text-format' => '>= 1.0.0',
231
- 'tmail' => '>= 1.2.3.1',
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 )
@@ -1 +1 @@
1
- 1.6.8
1
+ 2.0.4
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * BlueCloth -- a Ruby implementation of Markdown
3
- * $Id: bluecloth.c,v 1caa0c888dfe 2010/09/17 22:03:06 ged $
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, utf8text, optflags, fullhash, opthash = Qnil;
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, length, rb_utf8_encoding() );
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 = rb_str_new( output, length );
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" );
@@ -1,11 +1,22 @@
1
1
  /*
2
- * configuration for markdown, generated Tue Dec 23 06:19:25 PST 2008
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 && *res && d && d->compiled ) {
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
- *res = T(f); /* we know that a T(Cstring) is a character pointer */
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
- return S(f); /* leaving the husk of the Ctring on the stack */
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, size, 1, f);
81
+ written = fwrite(res, 1, size, f);
73
82
  if ( res )
74
83
  free(res);
75
84
  return (written == size) ? size : EOF;
@@ -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)) \
@@ -14,13 +14,19 @@
14
14
  #include "markdown.h"
15
15
  #include "amalloc.h"
16
16
 
17
- #define afterdle(t) (T((t)->text) + (t)->dle)
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->headers )
23
- return afterdle(doc->headers);
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->headers && doc->headers->next )
32
- return afterdle(doc->headers->next);
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->headers && doc->headers->next && doc->headers->next->next )
41
- return afterdle(doc->headers->next->next);
46
+ if ( doc && doc->date )
47
+ return onlyifset(doc->date);
42
48
  return 0;
43
49
  }
@@ -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 concatinate the
166
+ /* ___mkd_emblock() -- emblock a string of blocks, then concatenate the
167
167
  * resulting text onto f->out.
168
168
  */
169
169
  void
@@ -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=\"", "\" />", DENY_IMG|INSIDE_TAG, IS_URL };
497
+ 1, " alt=\"", "\" />", MKD_NOIMAGE|MKD_TAGTEXT, IS_URL };
449
498
  static linkytype linkt = { 0, 0, "<a href=\"", "\"",
450
- 0, ">", "</a>", DENY_A, IS_URL };
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, "<a id=\"", "\"", 0, ">", "</a>", 0, IS_URL },
461
- { "raw:", 4, 0, 0, 0, 0, 0, DENY_HTML, 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, INSIDE_TAG, f);
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 & (NO_PSEUDO_PROTO|SAFELINK) )
577
+ if ( f->flags & (MKD_NO_EXT|MKD_SAFELINK) )
526
578
  return 0;
527
579
  }
528
- else if ( (f->flags & SAFELINK) && T(ref->link)
529
- && (T(ref->link)[0] != '/')
530
- && !isautoprefix(T(ref->link), S(ref->link)) )
531
- /* if SAFELINK, only accept links that are local or
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 ( tag->link_pfx ) {
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), INSIDE_TAG, f);
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 ( eatspace(f) == '[' ) {
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
- * DENY_A and DENY_IMG
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 & DENY_HTML )
813
+ if ( f->flags & MKD_NOHTML )
755
814
  return 1;
756
815
 
757
- if ( c == 'A' && (f->flags & DENY_A) && !isthisalnum(f,2) )
816
+ if ( c == 'A' && (f->flags & MKD_NOLINKS) && !isthisalnum(f,2) )
758
817
  return 1;
759
- if ( c == 'I' && (f->flags & DENY_IMG)
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 & DENY_A ) return 0;
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 & INSIDE_TAG )
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 & (DENY_SMARTY|INSIDE_TAG) )
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 & INSIDE_TAG)
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 & AUTOLINK) && isalpha(peek(f,1)) && !tag_text(f) )
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 & (STRICT|INSIDE_TAG)) || isthisspace(f,-1) || isthisspace(f,1) )
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
- Qstring("<sup>",f);
1142
- while ( !isthisspace(f,1+len) ) {
1143
- ++len;
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
- shift(f,len);
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 & STRICT) && isthisalnum(f,-1)
1155
- && isthisalnum(f,1) ) {
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 & (NOSTRIKETHROUGH|INSIDE_TAG|STRICT)) || !tickhandler(f,c,2,delspan) )
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("&lt;", 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 & TOC ) {
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=a");
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 S(p->ctx->out);
1639
+ return size;
1554
1640
  }
1555
1641
  return EOF;
1556
1642
  }