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

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2004-2008, Michael Granger
1
+ Copyright (c) 2004-2010, Michael Granger
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
data/README CHANGED
@@ -60,10 +60,10 @@ You can also install as a site library via the Rakefile:
60
60
 
61
61
  == Source
62
62
 
63
- You can check out the current development source with Subversion from
63
+ You can check out the current development source with Mercurial from
64
64
  the following URL:
65
65
 
66
- svn://deveiate.org/BlueCloth/trunk
66
+ http://repo.deveiate.org/BlueCloth
67
67
 
68
68
  You can report bugs, suggest improvements, or check on development
69
69
  activity at the project page:
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
- #!rake
1
+ #!rake -*- ruby -*-
2
2
  #
3
3
  # BlueCloth rakefile
4
4
  #
5
5
  # Based on various other Rakefiles, especially one by Ben Bleything
6
6
  #
7
- # Copyright (c) 2007-2009 The FaerieMUD Consortium
7
+ # Copyright (c) 2007-2010 The FaerieMUD Consortium
8
8
  #
9
9
  # Authors:
10
10
  # * Michael Granger <ged@FaerieMUD.org>
@@ -32,6 +32,14 @@ rescue LoadError
32
32
  end
33
33
  end
34
34
 
35
+ begin
36
+ require 'rubygems'
37
+ rescue LoadError
38
+ module Gem
39
+ class Specification; end
40
+ end
41
+ end
42
+
35
43
  require 'rbconfig'
36
44
  require 'rake'
37
45
  require 'rake/testtask'
@@ -105,9 +113,9 @@ RAKE_TASKLIBS_URL = 'http://repo.deveiate.org/rake-tasklibs'
105
113
  LOCAL_RAKEFILE = BASEDIR + 'Rakefile.local'
106
114
 
107
115
  EXTRA_PKGFILES = Rake::FileList.new
108
- EXTRA_PKGFILES.include "#{BASEDIR}/LICENSE.discount"
109
- EXTRA_PKGFILES.include "#{BASEDIR}/spec/data/**/*.{txt,text,html}"
110
- EXTRA_PKGFILES.include "#{BASEDIR}/ext/VERSION"
116
+ EXTRA_PKGFILES.include( "#{BASEDIR}/LICENSE.discount" )
117
+ EXTRA_PKGFILES.include( "#{BASEDIR}/spec/data/**/*.{txt,text,html}" )
118
+ EXTRA_PKGFILES.include( "#{BASEDIR}/ext/VERSION" )
111
119
 
112
120
  RELEASE_FILES = TEXT_FILES +
113
121
  SPEC_FILES +
@@ -119,8 +127,13 @@ RELEASE_FILES = TEXT_FILES +
119
127
  RAKE_TASKLIBS +
120
128
  EXTRA_PKGFILES
121
129
 
130
+
122
131
  RELEASE_FILES << LOCAL_RAKEFILE.to_s if LOCAL_RAKEFILE.exist?
123
132
 
133
+ RELEASE_ANNOUNCE_ADDRESSES = [
134
+ "Ruby-Talk List <ruby-talk@ruby-lang.org>",
135
+ ]
136
+
124
137
  COVERAGE_MINIMUM = ENV['COVERAGE_MINIMUM'] ? Float( ENV['COVERAGE_MINIMUM'] ) : 85.0
125
138
  RCOV_EXCLUDES = 'spec,tests,/Library/Ruby,/var/lib,/usr/local/lib'
126
139
  RCOV_OPTS = [
@@ -140,7 +153,7 @@ if !RAKE_TASKDIR.exist?
140
153
 
141
154
  if ans =~ /^y/i
142
155
  $stderr.puts "Okay, fetching #{RAKE_TASKLIBS_URL} into #{RAKE_TASKDIR}..."
143
- system 'hg', 'clone', RAKE_TASKLIBS_URL, RAKE_TASKDIR
156
+ system 'hg', 'clone', RAKE_TASKLIBS_URL, "./#{RAKE_TASKDIR}"
144
157
  if ! $?.success?
145
158
  fail "Damn. That didn't work. Giving up; maybe try manually fetching?"
146
159
  end
@@ -154,12 +167,12 @@ end
154
167
 
155
168
  require RAKE_TASKDIR + 'helpers.rb'
156
169
 
157
- # Define some constants that depend on the 'svn' tasklib
170
+ # Set the build ID if the mercurial executable is available
158
171
  if hg = which( 'hg' )
159
- id = IO.read('|-') or exec hg, 'id', '-q'
160
- PKG_BUILD = id.chomp
172
+ id = IO.read('|-') or exec hg.to_s, 'id', '-n'
173
+ PKG_BUILD = 'pre' + (id.chomp[ /^[[:xdigit:]]+/ ] || '1')
161
174
  else
162
- PKG_BUILD = 0
175
+ PKG_BUILD = 'pre0'
163
176
  end
164
177
  SNAPSHOT_PKG_NAME = "#{PKG_FILE_NAME}.#{PKG_BUILD}"
165
178
  SNAPSHOT_GEM_NAME = "#{SNAPSHOT_PKG_NAME}.gem"
@@ -176,7 +189,7 @@ RDOC_OPTIONS = [
176
189
  ]
177
190
 
178
191
  # Release constants
179
- SMTP_HOST = 'mail.faeriemud.org'
192
+ SMTP_HOST = "mail.faeriemud.org"
180
193
  SMTP_PORT = 465 # SMTP + SSL
181
194
 
182
195
  # Project constants
@@ -186,29 +199,23 @@ PROJECT_DOCDIR = "#{PROJECT_PUBDIR}/#{PKG_NAME}"
186
199
  PROJECT_SCPPUBURL = "#{PROJECT_HOST}:#{PROJECT_PUBDIR}"
187
200
  PROJECT_SCPDOCURL = "#{PROJECT_HOST}:#{PROJECT_DOCDIR}"
188
201
 
189
- # Rubyforge stuff
190
- RUBYFORGE_GROUP = 'deveiate'
191
- RUBYFORGE_PROJECT = 'bluecloth'
192
-
193
202
  # Gem dependencies: gemname => version
194
203
  DEPENDENCIES = {
195
204
  }
196
205
 
197
206
  # Developer Gem dependencies: gemname => version
198
207
  DEVELOPMENT_DEPENDENCIES = {
199
- 'amatch' => '>= 0.2.3',
200
- 'rake' => '>= 0.8.1',
208
+ 'rake' => '>= 0.8.7',
201
209
  'rcodetools' => '>= 0.7.0.0',
202
- 'rcov' => '>= 0',
210
+ 'rcov' => '>= 0.8.1.2.0',
211
+ 'rdoc' => '>= 2.4.3',
203
212
  'RedCloth' => '>= 4.0.3',
204
- 'rspec' => '>= 0',
205
- 'rubyforge' => '>= 0',
213
+ 'rspec' => '>= 1.2.6',
206
214
  'termios' => '>= 0',
207
215
  'text-format' => '>= 1.0.0',
208
216
  'tmail' => '>= 1.2.3.1',
209
- 'ultraviolet' => '>= 0.10.2',
210
- 'libxml-ruby' => '>= 0.8.3',
211
- 'rdoc' => '>= 2.4.3',
217
+ 'diff-lcs' => '>= 1.1.2',
218
+ 'rake-compiler' => '>= 0.7.0',
212
219
  }
213
220
 
214
221
  # Non-gem requirements: packagename => version
@@ -231,7 +238,6 @@ GEMSPEC = Gem::Specification.new do |gem|
231
238
  gem.authors = "Michael Granger"
232
239
  gem.email = ["ged@FaerieMUD.org"]
233
240
  gem.homepage = 'http://deveiate.org/projects/BlueCloth/'
234
- gem.rubyforge_project = RUBYFORGE_PROJECT
235
241
 
236
242
  gem.has_rdoc = true
237
243
  gem.rdoc_options = RDOC_OPTIONS
@@ -240,7 +246,7 @@ GEMSPEC = Gem::Specification.new do |gem|
240
246
  gem.bindir = BINDIR.relative_path_from(BASEDIR).to_s
241
247
  gem.executables = BIN_FILES.select {|pn| File.executable?(pn) }.
242
248
  collect {|pn| File.basename(pn) }
243
- gem.require_paths << EXTDIR.relative_path_from( BASEDIR ).to_s
249
+ gem.require_paths << EXTDIR.relative_path_from( BASEDIR ).to_s if EXTDIR.exist?
244
250
 
245
251
  if EXTCONF.exist?
246
252
  gem.extensions << EXTCONF.relative_path_from( BASEDIR ).to_s
@@ -254,22 +260,20 @@ GEMSPEC = Gem::Specification.new do |gem|
254
260
  gem.add_runtime_dependency( name, version )
255
261
  end
256
262
 
257
- # Developmental dependencies don't work as of RubyGems 1.2.0
258
- unless Gem::Version.new( Gem::RubyGemsVersion ) <= Gem::Version.new( "1.2.0" )
259
- DEVELOPMENT_DEPENDENCIES.each do |name, version|
260
- version = '>= 0' if version.length.zero?
261
- gem.add_development_dependency( name, version )
262
- end
263
- end
264
-
265
263
  REQUIREMENTS.each do |name, version|
266
264
  gem.requirements << [ name, version ].compact.join(' ')
267
265
  end
268
266
  end
269
267
 
268
+
269
+ task :prerelease do
270
+ GEMSPEC.version.version += '.' + PKG_BUILD
271
+ end
272
+
273
+
270
274
  $trace = Rake.application.options.trace ? true : false
271
275
  $dryrun = Rake.application.options.dryrun ? true : false
272
-
276
+ $include_dev_dependencies = false
273
277
 
274
278
  # Load any remaining task libraries
275
279
  RAKE_TASKLIBS.each do |tasklib|
@@ -302,10 +306,9 @@ task :default => [:clean, :local, :spec, :rdoc, :package]
302
306
  ### Task the local Rakefile can append to -- no-op by default
303
307
  task :local
304
308
 
305
-
306
309
  ### Task: clean
307
- CLEAN.include 'coverage'
308
- CLOBBER.include 'artifacts', 'coverage.info', PKGDIR
310
+ CLEAN.include 'coverage', '**/*.orig', '**/*.rej'
311
+ CLOBBER.include 'artifacts', 'coverage.info', 'ChangeLog', PKGDIR
309
312
 
310
313
  ### Task: changelog
311
314
  file 'ChangeLog' do |task|
data/Rakefile.local CHANGED
@@ -1,5 +1,7 @@
1
1
  #!rake
2
2
 
3
+ require 'rake/extensiontask'
4
+
3
5
  # C extension constants
4
6
  EXT_MAKEFILE = EXTDIR + 'Makefile'
5
7
  EXT_SOURCES = FileList[ EXTDIR + '*.c' ]
@@ -14,50 +16,28 @@ DOCFILES << 'LICENSE.discount'
14
16
  #####################################################################
15
17
 
16
18
  # Make both the default task and the spec task depend on building the extension
17
- task :local => :build
18
- task :spec => :build
19
+ task :local => :compile
20
+ task :spec => :compile
19
21
  namespace :spec do
20
- task :doc => [ :build ]
21
- task :quiet => [ :build ]
22
- task :html => [ :build ]
23
- task :text => [ :build ]
22
+ task :doc => [ :compile ]
23
+ task :quiet => [ :compile ]
24
+ task :html => [ :compile ]
25
+ task :text => [ :compile ]
24
26
  end
25
27
 
26
- desc "Make the Makefile for the C extension"
27
- file EXT_MAKEFILE.to_s => EXT_SOURCES do
28
- log "Configuring BlueCloth C extension"
29
- in_subdirectory( EXTDIR ) do
30
- ruby 'extconf.rb'
31
- end
32
- end
33
- CLOBBER.include( EXTDIR + 'mkmf.log', EXTDIR + 'conftest.dSYM', EXT_SO )
34
-
35
- desc "Build the C extension"
36
- task :build => EXT_SO
37
- file EXT_SO => [ EXT_MAKEFILE.to_s, *EXT_SOURCES ] do
38
- in_subdirectory( EXTDIR ) do
39
- sh 'make'
40
- end
28
+ ENV['RUBY_CC_VERSION'] = '1.8.6:1.9.1'
29
+
30
+ Rake::ExtensionTask.new do |ext|
31
+ ext.name = 'bluecloth_ext'
32
+ ext.gem_spec = GEMSPEC
33
+ ext.ext_dir = 'ext'
34
+ ext.lib_dir = 'lib'
35
+ ext.source_pattern = "*.{c,h}"
36
+ ext.cross_compile = true
37
+ ext.cross_platform = %w[i386-mswin32 i386-mingw32]
41
38
  end
42
39
 
43
- desc "Rebuild the C extension"
44
- task :rebuild => [ :clobber, :build ]
45
-
46
-
47
- task :clean do
48
- if EXT_MAKEFILE.exist?
49
- in_subdirectory( EXTDIR ) do
50
- sh 'make clean'
51
- end
52
- end
53
- end
54
-
55
- task :clobber do
56
- if EXT_MAKEFILE.exist?
57
- in_subdirectory( EXTDIR ) do
58
- sh 'make distclean'
59
- end
60
- end
61
- end
62
- CLOBBER.include( EXT_MAKEFILE )
40
+ WINFAT_DIRS = Rake::FileList[ LIBDIR + '{1.8,1.9}' ]
41
+
42
+ CLEAN.include( WINFAT_DIRS )
63
43
 
data/ext/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.4
1
+ 1.5.8
data/ext/bluecloth.c CHANGED
@@ -22,8 +22,7 @@
22
22
  *
23
23
  */
24
24
 
25
- #include "mkdio.h"
26
- #include "ruby.h"
25
+ #include "bluecloth.h"
27
26
 
28
27
  VALUE bluecloth_cBlueCloth;
29
28
  VALUE bluecloth_default_opthash;
@@ -146,7 +145,12 @@ bluecloth_s_allocate( VALUE klass ) {
146
145
  */
147
146
  static VALUE
148
147
  bluecloth_s_discount_version( VALUE klass ) {
148
+ #ifdef HAVE_RUBY_ENCODING_H
149
+ return rb_external_str_new_with_enc( markdown_version, strlen(markdown_version),
150
+ rb_default_external_encoding() );
151
+ #else
149
152
  return rb_str_new2( markdown_version );
153
+ #endif
150
154
  }
151
155
 
152
156
  /* --------------------------------------------------------------
@@ -201,6 +205,9 @@ bluecloth_initialize( int argc, VALUE *argv, VALUE self ) {
201
205
  opthash = text;
202
206
  text = rb_str_new( "", 0 );
203
207
  }
208
+ else {
209
+ text = rb_obj_as_string( text );
210
+ }
204
211
 
205
212
  /* Merge the options hash with the defaults and turn it into a flags int */
206
213
  if ( NIL_P(opthash) ) opthash = rb_hash_new();
@@ -217,6 +224,9 @@ bluecloth_initialize( int argc, VALUE *argv, VALUE self ) {
217
224
  rb_iv_set( self, "@text", textcopy );
218
225
  OBJ_FREEZE( fullhash );
219
226
  rb_iv_set( self, "@options", fullhash );
227
+ #ifdef HAVE_RUBY_ENCODING_H
228
+ rb_enc_copy( self, text );
229
+ #endif
220
230
 
221
231
  OBJ_INFECT( self, text );
222
232
  }
@@ -245,6 +255,9 @@ bluecloth_to_html( VALUE self ) {
245
255
  bluecloth_debug( "Pointer to results: %p, length = %d", output, length );
246
256
  result = rb_str_new( output, length );
247
257
 
258
+ #ifdef HAVE_RUBY_ENCODING_H
259
+ rb_enc_copy( result, self );
260
+ #endif
248
261
  OBJ_INFECT( result, self );
249
262
  return result;
250
263
  } else {
@@ -325,7 +338,8 @@ void Init_bluecloth_ext( void ) {
325
338
 
326
339
  /* The options hash that describes the options in effect when the object was created */
327
340
  rb_define_attr( bluecloth_cBlueCloth, "options", 1, 0 );
328
-
341
+
342
+
329
343
  /* --- Constants ----- */
330
344
 
331
345
  /* Do not process `[]' and remove A tags from the output. */
data/ext/bluecloth.h ADDED
@@ -0,0 +1,19 @@
1
+ /*
2
+ * BlueCloth -- a Ruby implementation of Markdown
3
+ * $Id$
4
+ *
5
+ */
6
+
7
+ #ifndef BLUECLOTH_H
8
+ #define BLUECLOTH_H
9
+
10
+ #include "config.h"
11
+
12
+ #include "mkdio.h"
13
+ #include "ruby.h"
14
+
15
+ #ifdef HAVE_RUBY_ENCODING_H
16
+ # include "ruby/encoding.h"
17
+ #endif
18
+
19
+ #endif
data/ext/config.h CHANGED
@@ -6,6 +6,10 @@
6
6
  #ifndef CONFIG_H_RZLE3ADO
7
7
  #define CONFIG_H_RZLE3ADO
8
8
 
9
+ #ifdef RUBY_EXTCONF_H
10
+ # include RUBY_EXTCONF_H
11
+ #endif
12
+
9
13
  #ifdef HAVE_SRANDOM
10
14
  # define INITRNG(x) srandom((unsigned int)x)
11
15
  #elif HAVE_SRAND
data/ext/cstring.h CHANGED
@@ -60,9 +60,10 @@
60
60
  * macro will work with it.
61
61
  */
62
62
  #define ANCHOR(t) struct { t *text, *end; }
63
+ #define E(t) ((t).end)
63
64
 
64
- #define ATTACH(t, p) ( (t).text ?( ((t).end->next = (p)), ((t).end = (p)) ) \
65
- :( ((t).text = (t).end = (p)) ) )
65
+ #define ATTACH(t, p) ( T(t) ? ( (E(t)->next = (p)), (E(t) = (p)) ) \
66
+ : ( (T(t) = E(t) = (p)) ) )
66
67
 
67
68
  typedef STRING(char) Cstring;
68
69
 
data/ext/extconf.rb CHANGED
@@ -19,7 +19,7 @@ $CPPFLAGS << %Q{ -DVERSION=\\"#{version}\\"}
19
19
 
20
20
  # Add my own debugging hooks if building for me
21
21
  if ENV['DEBUGGING_BUILD']
22
- $CFLAGS << ' -ggdb' << ' -DDEBUG'
22
+ $CFLAGS << ' -ggdb' << ' -DDEBUG'
23
23
  end
24
24
 
25
25
  def fail( *messages )
@@ -43,6 +43,10 @@ end
43
43
 
44
44
  have_header( 'mkdio.h' ) or fail( "missing mkdio.h" )
45
45
 
46
+ # Check for 1.9.xish encoding header
47
+ have_header( 'ruby/encoding.h' )
48
+
49
+ create_header()
46
50
  create_makefile( 'bluecloth_ext' )
47
51
 
48
52
  FileUtils.rm_rf( 'conftest.dSYM' ) # MacOS X cleanup
data/ext/generate.c CHANGED
@@ -632,9 +632,9 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
632
632
 
633
633
  Qstring(tag->link_sfx, f);
634
634
 
635
- if ( tag->WxH && ref->height && ref->width ) {
636
- Qprintf(f," height=\"%d\"", ref->height);
637
- Qprintf(f, " width=\"%d\"", ref->width);
635
+ if ( tag->WxH) {
636
+ if ( ref->height) Qprintf(f," height=\"%d\"", ref->height);
637
+ if ( ref->width) Qprintf(f, " width=\"%d\"", ref->width);
638
638
  }
639
639
 
640
640
  if ( S(ref->title) ) {
@@ -661,44 +661,46 @@ static int
661
661
  linkylinky(int image, MMIOT *f)
662
662
  {
663
663
  int start = mmiottell(f);
664
- int implicit_mark;
665
664
  Cstring name;
666
665
  Footnote key, *ref;
667
666
 
668
667
  int status = 0;
669
668
 
670
669
  CREATE(name);
671
- bzero(&key, sizeof key);
670
+ memset(&key, 0, sizeof key);
672
671
 
673
672
  if ( linkylabel(f, &name) ) {
674
- implicit_mark = mmiottell(f);
675
- eatspace(f);
676
-
677
- switch ( pull(f) ) {
678
- case '(': /* embedded link */
673
+ if ( peek(f,1) == '(' ) {
674
+ pull(f);
679
675
  if ( linkyurl(f, image, &key) )
680
676
  status = linkyformat(f, name, image, &key);
681
- break;
677
+ }
678
+ else {
679
+ int goodlink, implicit_mark = mmiottell(f);
682
680
 
683
- case '[':/* footnote link */
684
- default: /* (undocumented) implicit link */
685
- if ( peek(f, 0) != '[' ) {
681
+ if ( eatspace(f) == '[' ) {
682
+ pull(f); /* consume leading '[' */
683
+ goodlink = linkylabel(f, &key.tag);
684
+ }
685
+ else {
686
+ /* new markdown implicit name syntax doesn't
687
+ * require a second []
688
+ */
686
689
  mmiotseek(f, implicit_mark);
687
- if ( f->flags & MKD_1_COMPAT )
688
- break;
690
+ goodlink = !(f->flags & MKD_1_COMPAT);
689
691
  }
690
- else if ( !linkylabel(f, &key.tag) )
691
- break;
692
692
 
693
- if ( !S(key.tag) ) {
694
- DELETE(key.tag);
695
- T(key.tag) = T(name);
696
- S(key.tag) = S(name);
697
- }
693
+ if ( goodlink ) {
694
+ if ( !S(key.tag) ) {
695
+ DELETE(key.tag);
696
+ T(key.tag) = T(name);
697
+ S(key.tag) = S(name);
698
+ }
698
699
 
699
- if ( ref = bsearch(&key, T(*f->footnotes), S(*f->footnotes),
700
- sizeof key, (stfu)__mkd_footsort) )
701
- status = linkyformat(f, name, image, ref);
700
+ if ( ref = bsearch(&key, T(*f->footnotes), S(*f->footnotes),
701
+ sizeof key, (stfu)__mkd_footsort) )
702
+ status = linkyformat(f, name, image, ref);
703
+ }
702
704
  }
703
705
  }
704
706
 
@@ -867,9 +869,19 @@ maybe_tag_or_link(MMIOT *f)
867
869
 
868
870
  if ( size ) {
869
871
  if ( maybetag || (size >= 3 && strncmp(cursor(f), "!--", 3) == 0) ) {
872
+
873
+ /* It is not a html tag unless we find the closing '>' in
874
+ * the same block.
875
+ */
876
+ while ( (c = peek(f, size+1)) != '>' )
877
+ if ( c == EOF )
878
+ return 0;
879
+ else
880
+ size++;
881
+
870
882
  Qstring(forbidden_tag(f) ? "&lt;" : "<", f);
871
883
  while ( ((c = peek(f, 1)) != EOF) && (c != '>') )
872
- cputc(pull(f), f);
884
+ Qchar(pull(f), f);
873
885
  return 1;
874
886
  }
875
887
  else if ( !isspace(c) && process_possible_link(f, size) ) {
@@ -1276,6 +1288,106 @@ printheader(Paragraph *pp, MMIOT *f)
1276
1288
  }
1277
1289
 
1278
1290
 
1291
+ enum e_alignments { a_NONE, a_CENTER, a_LEFT, a_RIGHT };
1292
+
1293
+ static char* alignments[] = { "", " align=\"center\"", " align=\"left\"",
1294
+ " align=\"right\"" };
1295
+
1296
+ typedef STRING(int) Istring;
1297
+
1298
+ static int
1299
+ splat(Line *p, char *block, Istring align, int force, MMIOT *f)
1300
+ {
1301
+ int first,
1302
+ idx = 0,
1303
+ colno = 0;
1304
+
1305
+ Qstring("<tr>\n", f);
1306
+ while ( idx < S(p->text) ) {
1307
+ first = idx;
1308
+ if ( force && (colno >= S(align)-1) )
1309
+ idx = S(p->text);
1310
+ else
1311
+ while ( (idx < S(p->text)) && (T(p->text)[idx] != '|') )
1312
+ ++idx;
1313
+
1314
+ Qprintf(f, "<%s%s>",
1315
+ block,
1316
+ alignments[ (colno < S(align)) ? T(align)[colno] : a_NONE ]);
1317
+ ___mkd_reparse(T(p->text)+first, idx-first, 0, f);
1318
+ Qprintf(f, "</%s>\n", block);
1319
+ idx++;
1320
+ colno++;
1321
+ }
1322
+ if ( force )
1323
+ while (colno < S(align) ) {
1324
+ Qprintf(f, "<%s></%s>\n", block, block);
1325
+ ++colno;
1326
+ }
1327
+ Qstring("</tr>\n", f);
1328
+ return colno;
1329
+ }
1330
+
1331
+ static int
1332
+ printtable(Paragraph *pp, MMIOT *f)
1333
+ {
1334
+ /* header, dashes, then lines of content */
1335
+
1336
+ Line *hdr, *dash, *body;
1337
+ Istring align;
1338
+ int start;
1339
+ int hcols;
1340
+ char *p;
1341
+
1342
+ if ( !(pp->text && pp->text->next) )
1343
+ return 0;
1344
+
1345
+ hdr = pp->text;
1346
+ dash= hdr->next;
1347
+ body= dash->next;
1348
+
1349
+ /* first figure out cell alignments */
1350
+
1351
+ CREATE(align);
1352
+
1353
+ for (p=T(dash->text), start=0; start < S(dash->text); ) {
1354
+ char first, last;
1355
+ int end;
1356
+
1357
+ last=first=0;
1358
+ for (end=start ; (end < S(dash->text)) && p[end] != '|'; ++ end ) {
1359
+ if ( !isspace(p[end]) ) {
1360
+ if ( !first) first = p[end];
1361
+ last = p[end];
1362
+ }
1363
+ }
1364
+ EXPAND(align) = ( first == ':' ) ? (( last == ':') ? a_CENTER : a_LEFT)
1365
+ : (( last == ':') ? a_RIGHT : a_NONE );
1366
+ start = 1+end;
1367
+ }
1368
+
1369
+ Qstring("<table>\n", f);
1370
+ Qstring("<thead>\n", f);
1371
+ hcols = splat(hdr, "th", align, 0, f);
1372
+ Qstring("</thead>\n", f);
1373
+
1374
+ if ( hcols < S(align) )
1375
+ S(align) = hcols;
1376
+ else
1377
+ while ( hcols > S(align) )
1378
+ EXPAND(align) = a_NONE;
1379
+
1380
+ Qstring("<tbody>\n", f);
1381
+ for ( ; body; body = body->next)
1382
+ splat(body, "td", align, 1, f);
1383
+ Qstring("</tbody>\n", f);
1384
+ Qstring("</table>\n", f);
1385
+
1386
+ DELETE(align);
1387
+ return 1;
1388
+ }
1389
+
1390
+
1279
1391
  static int
1280
1392
  printblock(Paragraph *pp, MMIOT *f)
1281
1393
  {
@@ -1382,6 +1494,7 @@ definitionlist(Paragraph *p, MMIOT *f)
1382
1494
  }
1383
1495
 
1384
1496
  htmlify(p->down, "dd", p->ident, f);
1497
+ Qchar('\n', f);
1385
1498
  }
1386
1499
 
1387
1500
  Qstring("</dl>", f);
@@ -1453,6 +1566,14 @@ display(Paragraph *p, MMIOT *f)
1453
1566
  printheader(p, f);
1454
1567
  break;
1455
1568
 
1569
+ case TABLE:
1570
+ printtable(p, f);
1571
+ break;
1572
+
1573
+ case SOURCE:
1574
+ htmlify(p->down, 0, 0, f);
1575
+ break;
1576
+
1456
1577
  default:
1457
1578
  printblock(p, f);
1458
1579
  break;