bluecloth 2.0.5-x86-mingw32 → 2.0.6.pre120-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/markdown.c CHANGED
@@ -32,11 +32,11 @@ static struct kw blocktags[] = { KW("!--"), KW("STYLE"), KW("SCRIPT"),
32
32
  KW("ADDRESS"), KW("BDO"), KW("BLOCKQUOTE"),
33
33
  KW("CENTER"), KW("DFN"), KW("DIV"), KW("H1"),
34
34
  KW("H2"), KW("H3"), KW("H4"), KW("H5"),
35
- KW("H6"), KW("IFRAME"), KW("LISTING"), KW("NOBR"),
35
+ KW("H6"), KW("LISTING"), KW("NOBR"),
36
36
  KW("UL"), KW("P"), KW("OL"), KW("DL"),
37
37
  KW("PLAINTEXT"), KW("PRE"), KW("TABLE"),
38
38
  KW("WBR"), KW("XMP"), SC("HR"), SC("BR"),
39
- KW("MAP") };
39
+ KW("IFRAME"), KW("MAP") };
40
40
  #define SZTAGS (sizeof blocktags / sizeof blocktags[0])
41
41
  #define MAXTAG 11 /* sizeof "BLOCKQUOTE" */
42
42
 
@@ -230,6 +230,8 @@ htmlblock(Paragraph *p, struct kw *tag)
230
230
  /* consume trailing gunk in close tag */
231
231
  c = flogetc(&f);
232
232
  }
233
+ if ( !f.t )
234
+ return 0;
233
235
  ret = f.t->next;
234
236
  f.t->next = 0;
235
237
  return ret;
@@ -259,6 +261,37 @@ comment(Paragraph *p)
259
261
  }
260
262
 
261
263
 
264
+ /* tables look like
265
+ * header|header{|header}
266
+ * ------|------{|......}
267
+ * {body lines}
268
+ */
269
+ static int
270
+ istable(Line *t)
271
+ {
272
+ char *p;
273
+ Line *dashes = t->next;
274
+ int contains = 0; /* found character bits; 0x01 is |, 0x02 is - */
275
+
276
+ /* two lines, first must contain | */
277
+ if ( !(dashes && memchr(T(t->text), '|', S(t->text))) )
278
+ return 0;
279
+
280
+ /* second line must contain - or | and nothing
281
+ * else except for whitespace or :
282
+ */
283
+ for ( p = T(dashes->text)+S(dashes->text)-1; p >= T(dashes->text); --p)
284
+ if ( *p == '|' )
285
+ contains |= 0x01;
286
+ else if ( *p == '-' )
287
+ contains |= 0x02;
288
+ else if ( ! ((*p == ':') || isspace(*p)) )
289
+ return 0;
290
+
291
+ return (contains & 0x03);
292
+ }
293
+
294
+
262
295
  /* footnotes look like ^<whitespace>{0,3}[stuff]: <content>$
263
296
  */
264
297
  static int
@@ -554,17 +587,17 @@ szmarkerclass(char *p)
554
587
  * marker %[kind:]name%
555
588
  */
556
589
  static int
557
- isdivmarker(Line *p)
590
+ isdivmarker(Line *p, int start)
558
591
  {
559
592
  #if DIV_QUOTE
560
593
  char *s = T(p->text);
561
594
  int len = S(p->text);
562
595
  int i;
563
596
 
564
- if ( !(len && s[0] == '%' && s[len-1] == '%') ) return 0;
597
+ if ( !(len && s[start] == '%' && s[len-1] == '%') ) return 0;
565
598
 
566
- i = szmarkerclass(s+1);
567
- --len;
599
+ i = szmarkerclass(s+start+1)+start;
600
+ len -= start+1;
568
601
 
569
602
  while ( ++i < len )
570
603
  if ( !isalnum(s[i]) )
@@ -601,13 +634,15 @@ quoteblock(Paragraph *p)
601
634
  t->dle = mkd_firstnonblank(t);
602
635
  }
603
636
 
604
- if ( !(q = skipempty(t->next)) || ((q != t->next) && !isquote(q)) ) {
637
+ q = skipempty(t->next);
638
+
639
+ if ( (q == 0) || ((q != t->next) && (!isquote(q) || isdivmarker(q,1))) ) {
605
640
  ___mkd_freeLineRange(t, q);
606
641
  t = q;
607
642
  break;
608
643
  }
609
644
  }
610
- if ( isdivmarker(p->text) ) {
645
+ if ( isdivmarker(p->text,0) ) {
611
646
  char *prefix = "class";
612
647
  int i;
613
648
 
@@ -628,6 +663,25 @@ quoteblock(Paragraph *p)
628
663
  }
629
664
 
630
665
 
666
+ /*
667
+ * A table block starts with a table header (see istable()), and continues
668
+ * until EOF or a line that /doesn't/ contain a |.
669
+ */
670
+ static Line *
671
+ tableblock(Paragraph *p)
672
+ {
673
+ Line *t, *q;
674
+
675
+ for ( t = p->text; t && (q = t->next); t = t->next ) {
676
+ if ( !memchr(T(q->text), '|', S(q->text)) ) {
677
+ t->next = 0;
678
+ return q;
679
+ }
680
+ }
681
+ return 0;
682
+ }
683
+
684
+
631
685
  static Paragraph *Pp(ParagraphRoot *, Line *, int);
632
686
  static Paragraph *compile(Line *, int, MMIOT *);
633
687
 
@@ -659,7 +713,7 @@ listitem(Paragraph *p, int indent)
659
713
  * need any indentation
660
714
  */
661
715
  if ( q != t->next ) {
662
- if (q->dle < 4) {
716
+ if (q->dle < indent) {
663
717
  q = t->next;
664
718
  t->next = 0;
665
719
  return q;
@@ -684,9 +738,10 @@ listblock(Paragraph *top, int trim, MMIOT *f)
684
738
  {
685
739
  ParagraphRoot d = { 0, 0 };
686
740
  Paragraph *p;
687
- Line *q = top->text, *text;
688
- Line *label;
689
- int para = 0;
741
+ Line *q = top->text, *text, *label;
742
+ int isdl = (top->typ == DL),
743
+ para = 0,
744
+ ltype;
690
745
 
691
746
  while (( text = q )) {
692
747
  if ( top->typ == DL ) {
@@ -710,7 +765,8 @@ listblock(Paragraph *top, int trim, MMIOT *f)
710
765
 
711
766
  if ( para && (top->typ != DL) && p->down ) p->down->align = PARA;
712
767
 
713
- if ( !(q = skipempty(text)) || (islist(q, &trim) == 0) )
768
+ if ( !(q = skipempty(text)) || ((ltype = islist(q, &trim)) == 0)
769
+ || (isdl != (ltype == DL)) )
714
770
  break;
715
771
 
716
772
  if ( para = (q != text) ) {
@@ -840,6 +896,64 @@ consume(Line *ptr, int *eaten)
840
896
  }
841
897
 
842
898
 
899
+ /*
900
+ * top-level compilation; break the document into
901
+ * style, html, and source blocks with footnote links
902
+ * weeded out.
903
+ */
904
+ static Paragraph *
905
+ compile_document(Line *ptr, MMIOT *f)
906
+ {
907
+ ParagraphRoot d = { 0, 0 };
908
+ ANCHOR(Line) source = { 0, 0 };
909
+ Paragraph *p = 0;
910
+ struct kw *tag;
911
+ int eaten;
912
+
913
+ while ( ptr ) {
914
+ if ( !(f->flags & DENY_HTML) && (tag = isopentag(ptr)) ) {
915
+ /* If we encounter a html/style block, compile and save all
916
+ * of the cached source BEFORE processing the html/style.
917
+ */
918
+ if ( T(source) ) {
919
+ E(source)->next = 0;
920
+ p = Pp(&d, 0, SOURCE);
921
+ p->down = compile(T(source), 1, f);
922
+ T(source) = E(source) = 0;
923
+ }
924
+ p = Pp(&d, ptr, strcmp(tag->id, "STYLE") == 0 ? STYLE : HTML);
925
+ if ( strcmp(tag->id, "!--") == 0 )
926
+ ptr = comment(p);
927
+ else
928
+ ptr = htmlblock(p, tag);
929
+ }
930
+ else if ( isfootnote(ptr) ) {
931
+ /* footnotes, like cats, sleep anywhere; pull them
932
+ * out of the input stream and file them away for
933
+ * later processing
934
+ */
935
+ ptr = consume(addfootnote(ptr, f), &eaten);
936
+ }
937
+ else {
938
+ /* source; cache it up to wait for eof or the
939
+ * next html/style block
940
+ */
941
+ ATTACH(source,ptr);
942
+ ptr = ptr->next;
943
+ }
944
+ }
945
+ if ( T(source) ) {
946
+ /* if there's any cached source at EOF, compile
947
+ * it now.
948
+ */
949
+ E(source)->next = 0;
950
+ p = Pp(&d, 0, SOURCE);
951
+ p->down = compile(T(source), 1, f);
952
+ }
953
+ return T(d);
954
+ }
955
+
956
+
843
957
  /*
844
958
  * break a collection of markdown input into
845
959
  * blocks of lists, code, html, and text to
@@ -850,22 +964,15 @@ compile(Line *ptr, int toplevel, MMIOT *f)
850
964
  {
851
965
  ParagraphRoot d = { 0, 0 };
852
966
  Paragraph *p = 0;
853
- struct kw *tag;
854
967
  Line *r;
855
968
  int para = toplevel;
969
+ int blocks = 0;
856
970
  int hdr_type, list_type, indent;
857
971
 
858
972
  ptr = consume(ptr, &para);
859
973
 
860
974
  while ( ptr ) {
861
- if ( toplevel && !(f->flags & DENY_HTML) && (tag = isopentag(ptr)) ) {
862
- p = Pp(&d, ptr, strcmp(tag->id, "STYLE") == 0 ? STYLE : HTML);
863
- if ( strcmp(tag->id, "!--") == 0 )
864
- ptr = comment(p);
865
- else
866
- ptr = htmlblock(p, tag);
867
- }
868
- else if ( iscode(ptr) ) {
975
+ if ( iscode(ptr) ) {
869
976
  p = Pp(&d, ptr, CODE);
870
977
 
871
978
  if ( f->flags & MKD_1_COMPAT) {
@@ -897,9 +1004,9 @@ compile(Line *ptr, int toplevel, MMIOT *f)
897
1004
  p = Pp(&d, ptr, HDR);
898
1005
  ptr = headerblock(p, hdr_type);
899
1006
  }
900
- else if ( toplevel && (isfootnote(ptr)) ) {
901
- ptr = consume(addfootnote(ptr, f), &para);
902
- continue;
1007
+ else if ( istable(ptr) && !(f->flags & (STRICT|NOTABLES)) ) {
1008
+ p = Pp(&d, ptr, TABLE);
1009
+ ptr = tableblock(p);
903
1010
  }
904
1011
  else {
905
1012
  p = Pp(&d, ptr, MARKUP);
@@ -909,7 +1016,8 @@ compile(Line *ptr, int toplevel, MMIOT *f)
909
1016
  if ( (para||toplevel) && !p->align )
910
1017
  p->align = PARA;
911
1018
 
912
- para = toplevel;
1019
+ blocks++;
1020
+ para = toplevel || (blocks > 1);
913
1021
  ptr = consume(ptr, &para);
914
1022
 
915
1023
  if ( para && !p->align )
@@ -960,7 +1068,7 @@ mkd_compile(Document *doc, int flags)
960
1068
 
961
1069
  initialize();
962
1070
 
963
- doc->code = compile(T(doc->content), 1, doc->ctx);
1071
+ doc->code = compile_document(T(doc->content), doc->ctx);
964
1072
  qsort(T(*doc->ctx->footnotes), S(*doc->ctx->footnotes),
965
1073
  sizeof T(*doc->ctx->footnotes)[0],
966
1074
  (stfu)__mkd_footsort);
data/ext/markdown.h CHANGED
@@ -37,7 +37,7 @@ typedef struct paragraph {
37
37
  char *ident; /* %id% tag for QUOTE */
38
38
  enum { WHITESPACE=0, CODE, QUOTE, MARKUP,
39
39
  HTML, STYLE, DL, UL, OL, AL, LISTITEM,
40
- HDR, HR } typ;
40
+ HDR, HR, TABLE, SOURCE } typ;
41
41
  enum { IMPLICIT=0, PARA, CENTER} align;
42
42
  int hnumber; /* <Hn> for typ == HDR */
43
43
  } Paragraph;
@@ -74,11 +74,12 @@ typedef struct mmiot {
74
74
  #define INSIDE_TAG 0x0020
75
75
  #define NO_PSEUDO_PROTO 0x0040
76
76
  #define CDATA_OUTPUT 0x0080
77
+ #define NOTABLES 0x0400
77
78
  #define TOC 0x1000
78
79
  #define MKD_1_COMPAT 0x2000
79
80
  #define AUTOLINK 0x4000
80
81
  #define SAFELINK 0x8000
81
- #define USER_FLAGS 0xF0FF
82
+ #define USER_FLAGS 0xFCFF
82
83
  #define EMBEDDED DENY_A|DENY_IMG|NO_PSEUDO_PROTO|CDATA_OUTPUT
83
84
  char *base;
84
85
  } MMIOT;
data/ext/mkdio.h CHANGED
@@ -63,6 +63,7 @@ extern char markdown_version[];
63
63
  * <em>, no <bold>, no html or [] expansion */
64
64
  #define MKD_NO_EXT 0x0040 /* don't allow pseudo-protocols */
65
65
  #define MKD_CDATA 0x0080 /* generate code for xml ![CDATA[...]] */
66
+ #define MKD_NOTABLES 0x0400 /* disallow tables */
66
67
  #define MKD_TOC 0x1000 /* do table-of-contents processing */
67
68
  #define MKD_1_COMPAT 0x2000 /* compatability with MarkdownTest_1.0 */
68
69
  #define MKD_AUTOLINK 0x4000 /* make http://foo.com link even without <>s */
Binary file
Binary file
data/lib/bluecloth.rb CHANGED
@@ -29,13 +29,7 @@
29
29
  class BlueCloth
30
30
 
31
31
  # Release Version
32
- VERSION = '2.0.5'
33
-
34
- # SVN Revision
35
- SVNREV = %q$Rev$
36
-
37
- # SVN Id tag
38
- SVNID = %q$Id$
32
+ VERSION = '2.0.6'
39
33
 
40
34
  # The defaults for all supported options.
41
35
  DEFAULT_OPTIONS = {
@@ -153,7 +147,16 @@ class BlueCloth
153
147
 
154
148
  end # class BlueCloth
155
149
 
156
- require 'bluecloth_ext'
150
+ # Load the correct version if it's a Windows binary gem
151
+ if RUBY_PLATFORM =~/(mswin|mingw)/i
152
+ major_minor = RUBY_VERSION[ /^(\d+\.\d+)/ ] or
153
+ raise "Oops, can't extract the major/minor version from #{RUBY_VERSION.dump}"
154
+ require "#{major_minor}/nokogiri"
155
+ else
156
+ require 'bluecloth_ext'
157
+ end
158
+
159
+
157
160
 
158
161
  # Set the top-level 'Markdown' constant if it isn't already set
159
162
  ::Markdown = ::BlueCloth unless defined?( ::Markdown )
data/rake/helpers.rb CHANGED
@@ -68,13 +68,19 @@ def trace( *msg )
68
68
  end
69
69
 
70
70
 
71
+ ### Return the specified args as a string, quoting any that have a space.
72
+ def quotelist( *args )
73
+ return args.flatten.collect {|part| part =~ /\s/ ? part.inspect : part}
74
+ end
75
+
76
+
71
77
  ### Run the specified command +cmd+ with system(), failing if the execution
72
78
  ### fails.
73
79
  def run( *cmd )
74
80
  cmd.flatten!
75
81
 
76
82
  if cmd.length > 1
77
- trace( cmd.collect {|part| part =~ /\s/ ? part.inspect : part} )
83
+ trace( quotelist(*cmd) )
78
84
  else
79
85
  trace( cmd )
80
86
  end
@@ -90,6 +96,15 @@ def run( *cmd )
90
96
  end
91
97
 
92
98
 
99
+ ### Run the given +cmd+ with the specified +args+ without interpolation by the shell and
100
+ ### return anything written to its STDOUT.
101
+ def read_command_output( cmd, *args )
102
+ trace "Reading output from: %s" % [ cmd, quotelist(cmd, *args) ]
103
+ output = IO.read( '|-' ) or exec cmd, *args
104
+ return output
105
+ end
106
+
107
+
93
108
  ### Run a subordinate Rake process with the same options and the specified +targets+.
94
109
  def rake( *targets )
95
110
  opts = ARGV.select {|arg| arg[0,1] == '-' }
@@ -410,3 +425,10 @@ def in_subdirectory( subdir )
410
425
  end
411
426
 
412
427
 
428
+ ### Make an easily-comparable version vector out of +ver+ and return it.
429
+ def vvec( ver )
430
+ return ver.split('.').collect {|char| char.to_i }.pack('N*')
431
+ end
432
+
433
+
434
+
data/rake/hg.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  #
2
2
  # Mercurial Rake Tasks
3
3
 
4
+ require 'enumerator'
5
+
4
6
  #
5
7
  # Authors:
6
8
  # * Michael Granger <ged@FaerieMUD.org>
@@ -27,7 +29,7 @@ unless defined?( HG_DOTDIR )
27
29
 
28
30
  ### Generate a commit log from a diff and return it as a String.
29
31
  def make_commit_log
30
- diff = IO.read( '|-' ) or exec 'hg', 'diff'
32
+ diff = read_command_output( 'hg', 'diff' )
31
33
  fail "No differences." if diff.empty?
32
34
 
33
35
  return diff
@@ -46,25 +48,42 @@ unless defined?( HG_DOTDIR )
46
48
 
47
49
  ### Generate a changelog.
48
50
  def make_changelog
49
- log = IO.read( '|-' ) or exec 'hg', 'log', '--style', 'compact'
51
+ log = read_command_output( 'hg', 'log', '--style', 'compact' )
50
52
  return log
51
53
  end
52
54
 
53
55
  ### Get the 'tip' info and return it as a Hash
54
56
  def get_tip_info
55
- data = IO.read( '|-' ) or exec 'hg', 'tip'
57
+ data = read_command_output( 'hg', 'tip' )
56
58
  return YAML.load( data )
57
59
  end
58
60
 
59
61
  ### Return the ID for the current rev
60
62
  def get_current_rev
61
- id = IO.read( '|-' ) or exec 'hg', '-q', 'identify'
63
+ id = read_command_output( 'hg', '-q', 'identify' )
62
64
  return id.chomp
63
65
  end
64
66
 
67
+ ### Read the list of existing tags and return them as an Array
68
+ def get_tags
69
+ taglist = read_command_output( 'hg', 'tags' )
70
+ return taglist.split( /\n/ )
71
+ end
72
+
73
+
74
+ ### Read any remote repo paths known by the current repo and return them as a hash.
75
+ def get_repo_paths
76
+ paths = {}
77
+ pathspec = read_command_output( 'hg', 'paths' )
78
+ pathspec.split.each_slice( 3 ) do |name, _, url|
79
+ paths[ name ] = url
80
+ end
81
+ return paths
82
+ end
83
+
65
84
  ### Return the list of files which are of status 'unknown'
66
85
  def get_unknown_files
67
- list = IO.read( '|-' ) or exec 'hg', 'status', '-un', '--no-color'
86
+ list = read_command_output( 'hg', 'status', '-un', '--no-color' )
68
87
  list = list.split( /\n/ )
69
88
 
70
89
  trace "New files: %p" % [ list ]
@@ -82,7 +101,7 @@ unless defined?( HG_DOTDIR )
82
101
  end
83
102
 
84
103
 
85
- ### Add the list of +pathnames+ to the svn:ignore list.
104
+ ### Add the list of +pathnames+ to the .hgignore list.
86
105
  def hg_ignore_files( *pathnames )
87
106
  patterns = pathnames.flatten.collect do |path|
88
107
  '^' + Regexp.escape(path) + '$'
@@ -128,11 +147,26 @@ unless defined?( HG_DOTDIR )
128
147
 
129
148
  desc "Prepare for a new release"
130
149
  task :prep_release do
131
- # Get the rev for the tag name
132
- # Look for an existing tag with that rev, and if it exists abort
133
- # Tag the current rev
150
+ tags = get_tags()
151
+ rev = get_current_rev()
152
+
153
+ # Look for a tag for the current release version, and if it exists abort
154
+ if tags.include?( PKG_VERSION )
155
+ error "Version #{PKG_VERSION} already has a tag. Did you mean " +
156
+ "to increment the version in #{VERSION_FILE}?"
157
+ fail
158
+ end
159
+
134
160
  # Sign the current rev
161
+ log "Signing rev #{rev}"
162
+ run 'hg', 'sign'
163
+
164
+ # Tag the current rev
165
+ log "Tagging rev #{rev} as #{PKG_VERSION}"
166
+ run 'hg', 'tag', PKG_VERSION
167
+
135
168
  # Offer to push
169
+ Rake::Task['hg:push'].invoke
136
170
  end
137
171
 
138
172
  desc "Check for new files and offer to add/ignore/delete them."
@@ -174,20 +208,45 @@ unless defined?( HG_DOTDIR )
174
208
  task :add => :newfiles
175
209
 
176
210
 
211
+ desc "Pull and update from the default repo"
212
+ task :pull do
213
+ paths = get_repo_paths()
214
+ if origin_url = paths['default']
215
+ ask_for_confirmation( "Pull and update from '#{origin_url}'?", false ) do
216
+ run 'hg', 'pull', '-u'
217
+ end
218
+ else
219
+ trace "Skipping pull: No 'default' path."
220
+ end
221
+ end
222
+
177
223
  desc "Check the current code in if tests pass"
178
- task :checkin => ['hg:newfiles', 'test', COMMIT_MSG_FILE] do
224
+ task :checkin => ['hg:pull', 'hg:newfiles', 'test', COMMIT_MSG_FILE] do
179
225
  targets = get_target_args()
180
226
  $stderr.puts '---', File.read( COMMIT_MSG_FILE ), '---'
181
227
  ask_for_confirmation( "Continue with checkin?" ) do
182
228
  run 'hg', 'ci', '-l', COMMIT_MSG_FILE, targets
183
229
  rm_f COMMIT_MSG_FILE
184
230
  end
231
+ Rake::Task['hg:push'].invoke
185
232
  end
186
233
  task :commit => :checkin
187
234
  task :ci => :checkin
188
235
 
189
236
  CLEAN.include( COMMIT_MSG_FILE )
190
237
 
238
+ desc "Push to the default origin repo (if there is one)"
239
+ task :push do
240
+ paths = get_repo_paths()
241
+ if origin_url = paths['default']
242
+ ask_for_confirmation( "Push to '#{origin_url}'?", false ) do
243
+ run 'hg', 'push'
244
+ end
245
+ else
246
+ trace "Skipping push: No 'default' path."
247
+ end
248
+ end
249
+
191
250
  end
192
251
 
193
252
  if HG_DOTDIR.exist?
@@ -199,7 +258,7 @@ unless defined?( HG_DOTDIR )
199
258
  task :checkin => 'hg:ci'
200
259
 
201
260
  desc "Tag and sign revision before a release"
202
- task :prep_release => 'hg:tag'
261
+ task :prep_release => 'hg:prep_release'
203
262
 
204
263
  file COMMIT_MSG_FILE do
205
264
  edit_commit_log()