bluecloth 2.0.7-x86-mingw32 → 2.0.11pre158-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.gemtest +0 -0
  3. data/History.md +4 -0
  4. data/LICENSE +1 -1
  5. data/Manifest.txt +103 -0
  6. data/README.md +103 -0
  7. data/Rakefile +95 -301
  8. data/ext/VERSION +1 -1
  9. data/ext/bluecloth.c +69 -23
  10. data/ext/bluecloth.h +13 -2
  11. data/ext/config.h +13 -2
  12. data/ext/css.c +14 -5
  13. data/ext/cstring.h +4 -2
  14. data/ext/docheader.c +13 -7
  15. data/ext/emmatch.c +188 -0
  16. data/ext/extconf.rb +7 -9
  17. data/ext/generate.c +333 -293
  18. data/ext/html5.c +24 -0
  19. data/ext/markdown.c +326 -185
  20. data/ext/markdown.h +52 -29
  21. data/ext/mkdio.c +82 -41
  22. data/ext/mkdio.h +44 -23
  23. data/ext/resource.c +4 -2
  24. data/ext/setup.c +47 -0
  25. data/ext/tags.c +123 -0
  26. data/ext/tags.h +19 -0
  27. data/lib/1.8/bluecloth_ext.so +0 -0
  28. data/lib/1.9/bluecloth_ext.so +0 -0
  29. data/lib/bluecloth.rb +77 -42
  30. data/spec/bluecloth/101_changes_spec.rb +18 -21
  31. data/spec/bluecloth/TEMPLATE +36 -0
  32. data/spec/bluecloth/autolinks_spec.rb +4 -7
  33. data/spec/bluecloth/blockquotes_spec.rb +20 -23
  34. data/spec/bluecloth/code_spans_spec.rb +2 -5
  35. data/spec/bluecloth/emphasis_spec.rb +2 -5
  36. data/spec/bluecloth/entities_spec.rb +2 -5
  37. data/spec/bluecloth/hrules_spec.rb +2 -5
  38. data/spec/bluecloth/images_spec.rb +2 -5
  39. data/spec/bluecloth/inline_html_spec.rb +26 -66
  40. data/spec/bluecloth/links_spec.rb +1 -5
  41. data/spec/bluecloth/lists_spec.rb +2 -5
  42. data/spec/bluecloth/paragraphs_spec.rb +2 -5
  43. data/spec/bluecloth/titles_spec.rb +2 -5
  44. data/spec/bluecloth_spec.rb +36 -22
  45. data/spec/bugfix_spec.rb +90 -10
  46. data/spec/contributions_spec.rb +2 -3
  47. data/spec/discount_spec.rb +50 -10
  48. data/spec/lib/helpers.rb +18 -117
  49. data/spec/lib/matchers.rb +7 -18
  50. data/spec/markdowntest_spec.rb +3 -39
  51. metadata +257 -143
  52. metadata.gz.sig +0 -0
  53. data/ChangeLog +0 -387
  54. data/README +0 -81
  55. data/Rakefile.local +0 -41
  56. data/rake/191_compat.rb +0 -26
  57. data/rake/dependencies.rb +0 -76
  58. data/rake/helpers.rb +0 -435
  59. data/rake/hg.rb +0 -273
  60. data/rake/manual.rb +0 -782
  61. data/rake/packaging.rb +0 -123
  62. data/rake/publishing.rb +0 -274
  63. data/rake/rdoc.rb +0 -30
  64. data/rake/style.rb +0 -62
  65. data/rake/svn.rb +0 -668
  66. data/rake/testing.rb +0 -187
  67. data/rake/verifytask.rb +0 -64
data/ext/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.8
1
+ 2.0.5
data/ext/bluecloth.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * BlueCloth -- a Ruby implementation of Markdown
3
- * $Id$
3
+ * $Id: bluecloth.c,v 0cda68a5fc00 2011/02/09 22:33:27 ged $
4
4
  *
5
5
  * = Authors
6
6
  *
@@ -32,11 +32,11 @@ VALUE bluecloth_default_opthash;
32
32
  static MMIOT *
33
33
  bluecloth_alloc( VALUE text, int flags ) {
34
34
  MMIOT *document;
35
-
35
+
36
36
  document = mkd_string( RSTRING_PTR(text), RSTRING_LEN(text), flags );
37
37
  if ( !document )
38
38
  rb_raise( rb_eRuntimeError, "Failed to create a BlueCloth object for: %s", RSTRING_PTR(text) );
39
-
39
+
40
40
  return document;
41
41
  }
42
42
 
@@ -44,7 +44,7 @@ bluecloth_alloc( VALUE text, int flags ) {
44
44
  /*
45
45
  * GC Free function
46
46
  */
47
- static void
47
+ static void
48
48
  bluecloth_gc_free( MMIOT *document ) {
49
49
  if ( document ) {
50
50
  mkd_cleanup( document );
@@ -100,7 +100,7 @@ bluecloth_check_ptr( VALUE self ) {
100
100
  rb_raise( rb_eTypeError, "wrong argument type %s (expected BlueCloth object)",
101
101
  rb_class2name(CLASS_OF( self )) );
102
102
  }
103
-
103
+
104
104
  return DATA_PTR( self );
105
105
  }
106
106
 
@@ -181,12 +181,13 @@ bluecloth_s_discount_version( VALUE klass ) {
181
181
  * superscript notation. Defaults to +true+.
182
182
  *
183
183
  */
184
- static VALUE
184
+ 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, textcopy, 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
 
@@ -201,7 +202,7 @@ bluecloth_initialize( int argc, VALUE *argv, VALUE self ) {
201
202
  text = rb_str_new( "", 0 );
202
203
  }
203
204
  else {
204
- text = rb_obj_as_string( text );
205
+ text = rb_obj_dup( rb_obj_as_string(text) );
205
206
  }
206
207
 
207
208
  /* Merge the options hash with the defaults and turn it into a flags int */
@@ -210,13 +211,21 @@ bluecloth_initialize( int argc, VALUE *argv, VALUE self ) {
210
211
  fullhash = rb_funcall( bluecloth_cBlueCloth, rb_intern("opthash_from_flags"), 1, optflags );
211
212
 
212
213
  flags = NUM2INT( optflags );
214
+
215
+ #ifdef M17N_SUPPORTED
216
+ bluecloth_debug( "Bytes before utf8ification: %s",
217
+ RSTRING_PTR(rb_funcall(text, rb_intern("dump"), 0, Qnil)) );
218
+ utf8text = rb_str_export_to_enc( rb_str_dup(text), rb_utf8_encoding() );
219
+ DATA_PTR( self ) = document = bluecloth_alloc( utf8text, flags );
220
+ #else
213
221
  DATA_PTR( self ) = document = bluecloth_alloc( text, flags );
222
+ #endif /* M17N_SUPPORTED */
223
+
214
224
  if ( !mkd_compile(document, flags) )
215
225
  rb_raise( rb_eRuntimeError, "Failed to compile markdown" );
216
226
 
217
- textcopy = rb_str_dup( text );
218
- OBJ_FREEZE( textcopy );
219
- rb_iv_set( self, "@text", textcopy );
227
+ OBJ_FREEZE( text );
228
+ rb_iv_set( self, "@text", text );
220
229
  OBJ_FREEZE( fullhash );
221
230
  rb_iv_set( self, "@options", fullhash );
222
231
 
@@ -242,12 +251,20 @@ bluecloth_to_html( VALUE self ) {
242
251
  VALUE result = Qnil;
243
252
 
244
253
  bluecloth_debug( "Compiling document %p", document );
245
-
254
+
246
255
  if ( (length = mkd_document( document, &output )) != EOF ) {
247
- bluecloth_debug( "Pointer to results: %p, length = %d", output, length );
248
- result = rb_str_new( output, length );
256
+ #ifdef M17N_SUPPORTED
257
+ VALUE orig_encoding = rb_obj_encoding( rb_iv_get(self, "@text") );
258
+ VALUE utf8_result = rb_enc_str_new( output, strlen(output), rb_utf8_encoding() );
259
+ result = rb_str_encode( utf8_result, orig_encoding, 0, Qnil );
260
+ bluecloth_debug( "Bytes after un-utf8ification (if necessary): %s",
261
+ RSTRING_PTR(rb_funcall(result, rb_intern("dump"), 0, Qnil)) );
262
+ #else
263
+ result = rb_str_new2( output );
264
+ #endif /* M17N_SUPPORTED */
249
265
 
250
266
  OBJ_INFECT( result, self );
267
+
251
268
  return result;
252
269
  } else {
253
270
  return Qnil;
@@ -283,7 +300,7 @@ bluecloth_header( VALUE self ) {
283
300
  VALUE fieldstring, headers = rb_hash_new();
284
301
 
285
302
  bluecloth_debug( "Fetching pandoc headers for document %p", document );
286
-
303
+
287
304
  if ( (field = mkd_doc_title(document)) ) {
288
305
  fieldstring = rb_str_new2( field );
289
306
  OBJ_INFECT( fieldstring, self );
@@ -312,6 +329,9 @@ bluecloth_header( VALUE self ) {
312
329
  void Init_bluecloth_ext( void ) {
313
330
  bluecloth_cBlueCloth = rb_define_class( "BlueCloth", rb_cObject );
314
331
 
332
+ mkd_with_html5_tags();
333
+ mkd_initialize();
334
+
315
335
  rb_define_alloc_func( bluecloth_cBlueCloth, bluecloth_s_allocate );
316
336
  rb_define_singleton_method( bluecloth_cBlueCloth, "discount_version",
317
337
  bluecloth_s_discount_version, 0 );
@@ -321,10 +341,10 @@ void Init_bluecloth_ext( void ) {
321
341
  rb_define_method( bluecloth_cBlueCloth, "to_html", bluecloth_to_html, 0 );
322
342
  rb_define_method( bluecloth_cBlueCloth, "header", bluecloth_header, 0 );
323
343
  rb_define_alias( bluecloth_cBlueCloth, "pandoc_header", "header" );
324
-
344
+
325
345
  /* The original Markdown text the object was constructed with */
326
346
  rb_define_attr( bluecloth_cBlueCloth, "text", 1, 0 );
327
-
347
+
328
348
  /* The options hash that describes the options in effect when the object was created */
329
349
  rb_define_attr( bluecloth_cBlueCloth, "options", 1, 0 );
330
350
 
@@ -339,22 +359,37 @@ void Init_bluecloth_ext( void ) {
339
359
 
340
360
  /* Do not do Smartypants-style mangling of quotes, dashes, or ellipses. */
341
361
  rb_define_const( bluecloth_cBlueCloth, "MKD_NOPANTS", INT2FIX(MKD_NOPANTS) );
342
-
362
+
343
363
  /* Escape all opening angle brackets in the input text instead of allowing block-level HTML */
344
364
  rb_define_const( bluecloth_cBlueCloth, "MKD_NOHTML", INT2FIX(MKD_NOHTML) );
345
365
 
346
366
  /* disable SUPERSCRIPT, RELAXED_EMPHASIS */
347
367
  rb_define_const( bluecloth_cBlueCloth, "MKD_STRICT", INT2FIX(MKD_STRICT) );
348
-
368
+
349
369
  /* process text inside an html tag; no <em>, no <bold>, no html or [] expansion */
350
370
  rb_define_const( bluecloth_cBlueCloth, "MKD_TAGTEXT", INT2FIX(MKD_TAGTEXT) );
351
-
371
+
352
372
  /* don't allow pseudo-protocols */
353
373
  rb_define_const( bluecloth_cBlueCloth, "MKD_NO_EXT", INT2FIX(MKD_NO_EXT) );
354
-
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
+
384
+ /* disallow tables */
385
+ rb_define_const( bluecloth_cBlueCloth, "MKD_NOTABLES", INT2FIX(MKD_NOTABLES) );
386
+
387
+ /* forbid ~~strikethrough~~ */
388
+ rb_define_const( bluecloth_cBlueCloth, "MKD_NOSTRIKETHROUGH", INT2FIX(MKD_NOSTRIKETHROUGH) );
389
+
355
390
  /* do table-of-contents processing */
356
391
  rb_define_const( bluecloth_cBlueCloth, "MKD_TOC", INT2FIX(MKD_TOC) );
357
-
392
+
358
393
  /* MarkdownTest 1.0 Compatibility Mode */
359
394
  rb_define_const( bluecloth_cBlueCloth, "MKD_1_COMPAT", INT2FIX(MKD_1_COMPAT) );
360
395
 
@@ -367,10 +402,21 @@ void Init_bluecloth_ext( void ) {
367
402
  /* Be paranoid about link protocols */
368
403
  rb_define_const( bluecloth_cBlueCloth, "MKD_SAFELINK", INT2FIX(MKD_SAFELINK) );
369
404
 
370
-
371
405
  /* don't process header blocks */
372
406
  rb_define_const( bluecloth_cBlueCloth, "MKD_NOHEADER", INT2FIX(MKD_NOHEADER) );
373
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
+
374
420
 
375
421
  /* Make sure the Ruby side is loaded */
376
422
  rb_require( "bluecloth" );
data/ext/bluecloth.h CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * BlueCloth -- a Ruby implementation of Markdown
3
- * $Id$
3
+ * $Id: bluecloth.h,v 0cda68a5fc00 2011/02/09 22:33:27 ged $
4
4
  *
5
5
  */
6
6
 
@@ -8,12 +8,23 @@
8
8
  #define BLUECLOTH_H
9
9
 
10
10
  #include "config.h"
11
+ #include "assert.h"
11
12
 
12
13
  #include "mkdio.h"
13
14
  #include "ruby.h"
14
15
 
15
- #ifdef HAVE_RUBY_ENCODING_H
16
+ void mkd_initialize _(( void ));
17
+ void mkd_with_html5_tags _(( void ));
18
+
19
+ #if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H
20
+ # define M17N_SUPPORTED
16
21
  # include "ruby/encoding.h"
17
22
  #endif
18
23
 
24
+ /* Replace the macro from encoding.h that refers to static 'rb_encoding_list' */
25
+ #ifdef ENC_FROM_ENCINDEX
26
+ #undef ENC_FROM_ENCINDEX
27
+ #define ENC_FROM_ENCINDEX(idx) (rb_enc_from_index(idx))
28
+ #endif
29
+
19
30
  #endif
data/ext/config.h CHANGED
@@ -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;
data/ext/cstring.h CHANGED
@@ -10,13 +10,15 @@
10
10
  #include <string.h>
11
11
  #include <stdlib.h>
12
12
 
13
- #include "amalloc.h"
13
+ #ifndef __WITHOUT_AMALLOC
14
+ # include "amalloc.h"
15
+ #endif
14
16
 
15
17
  /* expandable Pascal-style string.
16
18
  */
17
19
  #define STRING(type) struct { type *text; int size, alloc; }
18
20
 
19
- #define CREATE(x) T(x) = (void*)(S(x) = (x).alloc = 0)
21
+ #define CREATE(x) ( (T(x) = (void*)0), (S(x) = (x).alloc = 0) )
20
22
  #define EXPAND(x) (S(x)++)[(S(x) < (x).alloc) \
21
23
  ? (T(x)) \
22
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
- #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
  }
data/ext/emmatch.c ADDED
@@ -0,0 +1,188 @@
1
+ /* markdown: a C implementation of John Gruber's Markdown markup language.
2
+ *
3
+ * Copyright (C) 2010 David L Parsons.
4
+ * The redistribution terms are provided in the COPYRIGHT file that must
5
+ * be distributed with this source code.
6
+ */
7
+ #include <stdio.h>
8
+ #include <string.h>
9
+ #include <stdarg.h>
10
+ #include <stdlib.h>
11
+ #include <time.h>
12
+ #include <ctype.h>
13
+
14
+ #include "config.h"
15
+
16
+ #include "cstring.h"
17
+ #include "markdown.h"
18
+ #include "amalloc.h"
19
+
20
+
21
+ /* emmatch: the emphasis mangler that's run after a block
22
+ * of html has been generated.
23
+ *
24
+ * It should create MarkdownTest_1.0 (and _1.0.3)
25
+ * compatable emphasis for non-pathological cases
26
+ * and it should fail in a standards-compliant way
27
+ * when someone attempts to feed it junk.
28
+ *
29
+ * Emmatching is done after the input has been
30
+ * processed into a STRING (f->Q) of text and
31
+ * emphasis blocks. After ___mkd_emblock() finishes,
32
+ * it truncates f->Q and leaves the rendered paragraph
33
+ * if f->out.
34
+ */
35
+
36
+
37
+ /* empair() -- find the NEAREST matching emphasis token (or
38
+ * subtoken of a 3+ long emphasis token.
39
+ */
40
+ static int
41
+ empair(MMIOT *f, int first, int last, int match)
42
+ {
43
+
44
+ int i;
45
+ block *begin, *p;
46
+
47
+ begin = &T(f->Q)[first];
48
+
49
+ for (i=first+1; i <= last; i++) {
50
+ p = &T(f->Q)[i];
51
+
52
+ if ( (p->b_type != bTEXT) && (p->b_count <= 0) )
53
+ continue; /* break? */
54
+
55
+ if ( p->b_type == begin->b_type ) {
56
+ if ( p->b_count == match ) /* exact match */
57
+ return i;
58
+
59
+ if ( p->b_count > 2 ) /* fuzzy match */
60
+ return i;
61
+ }
62
+ }
63
+ return 0;
64
+ } /* empair */
65
+
66
+
67
+ /* emfill() -- if an emphasis token has leftover stars or underscores,
68
+ * convert them back into character and append them to b_text.
69
+ */
70
+ static void
71
+ emfill(block *p)
72
+ {
73
+ int j;
74
+
75
+ if ( p->b_type == bTEXT )
76
+ return;
77
+
78
+ for (j=0; j < p->b_count; j++)
79
+ EXPAND(p->b_text) = p->b_char;
80
+ p->b_count = 0;
81
+ } /* emfill */
82
+
83
+
84
+ static void
85
+ emclose(MMIOT *f, int first, int last)
86
+ {
87
+ int j;
88
+
89
+ for (j=first+1; j<last-1; j++)
90
+ emfill(&T(f->Q)[j]);
91
+ }
92
+
93
+
94
+ static struct emtags {
95
+ char open[10];
96
+ char close[10];
97
+ int size;
98
+ } emtags[] = { { "<em>" , "</em>", 5 }, { "<strong>", "</strong>", 9 } };
99
+
100
+
101
+ static void emblock(MMIOT*,int,int);
102
+
103
+
104
+ /* emmatch() -- match emphasis for a single emphasis token.
105
+ */
106
+ static void
107
+ emmatch(MMIOT *f, int first, int last)
108
+ {
109
+ block *start = &T(f->Q)[first];
110
+ int e, e2, match;
111
+
112
+ switch (start->b_count) {
113
+ case 2: if ( e = empair(f,first,last,match=2) )
114
+ break;
115
+ case 1: e = empair(f,first,last,match=1);
116
+ break;
117
+ case 0: return;
118
+ default:
119
+ e = empair(f,first,last,1);
120
+ e2= empair(f,first,last,2);
121
+
122
+ if ( e2 >= e ) {
123
+ e = e2;
124
+ match = 2;
125
+ }
126
+ else
127
+ match = 1;
128
+ break;
129
+ }
130
+
131
+ if ( e ) {
132
+ /* if we found emphasis to match, match it, recursively call
133
+ * emblock to match emphasis inside the new html block, add
134
+ * the emphasis markers for the block, then (tail) recursively
135
+ * call ourself to match any remaining emphasis on this token.
136
+ */
137
+ block *end = &T(f->Q)[e];
138
+
139
+ end->b_count -= match;
140
+ start->b_count -= match;
141
+
142
+ emblock(f, first, e);
143
+
144
+ PREFIX(start->b_text, emtags[match-1].open, emtags[match-1].size-1);
145
+ SUFFIX(end->b_post, emtags[match-1].close, emtags[match-1].size);
146
+
147
+ emmatch(f, first, last);
148
+ }
149
+ } /* emmatch */
150
+
151
+
152
+ /* emblock() -- walk a blocklist, attempting to match emphasis
153
+ */
154
+ static void
155
+ emblock(MMIOT *f, int first, int last)
156
+ {
157
+ int i;
158
+
159
+ for ( i = first; i <= last; i++ )
160
+ if ( T(f->Q)[i].b_type != bTEXT )
161
+ emmatch(f, i, last);
162
+ emclose(f, first, last);
163
+ } /* emblock */
164
+
165
+
166
+ /* ___mkd_emblock() -- emblock a string of blocks, then concatenate the
167
+ * resulting text onto f->out.
168
+ */
169
+ void
170
+ ___mkd_emblock(MMIOT *f)
171
+ {
172
+ int i;
173
+ block *p;
174
+
175
+ emblock(f, 0, S(f->Q)-1);
176
+
177
+ for (i=0; i < S(f->Q); i++) {
178
+ p = &T(f->Q)[i];
179
+ emfill(p);
180
+
181
+ if ( S(p->b_post) ) { SUFFIX(f->out, T(p->b_post), S(p->b_post));
182
+ DELETE(p->b_post); }
183
+ if ( S(p->b_text) ) { SUFFIX(f->out, T(p->b_text), S(p->b_text));
184
+ DELETE(p->b_text); }
185
+ }
186
+
187
+ S(f->Q) = 0;
188
+ } /* ___mkd_emblock */