Skip to content

Commit 32bca49

Browse files
committed
Support for table column spans
1 parent 2b6ebdf commit 32bca49

File tree

6 files changed

+53
-15
lines changed

6 files changed

+53
-15
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ Fixes:
3030
Fix reference link definition label matching in a case when the label ends
3131
with a Unicode character with non-trivial case folding mapping.
3232

33+
* [#29](https://github.com/mity/md4c/issues/29):
34+
Implement Wiky-style ('|2> text |') table cell-span extension.
3335

3436
## Version 0.4.6
3537

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ extensions:
102102

103103
* With the flag `MD_FLAG_TABLES`, GitHub-style tables are supported.
104104

105+
* With the flag `MD_FLAG_TABLE_CELLSPAN`, wiky-style ('|2> text |') table
106+
cell-spans are supported.
107+
105108
* With the flag `MD_FLAG_TASKLISTS`, GitHub-style task lists are supported.
106109

107110
* With the flag `MD_FLAG_STRIKETHROUGH`, strike-through spans are enabled

md2html/md2html.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ static const CMDLINE_OPTION cmdline_options[] = {
208208
{ 0, "fpermissive-www-autolinks", '.', 0 },
209209
{ 0, "fstrikethrough", 'S', 0 },
210210
{ 0, "ftables", 'T', 0 },
211+
{ 0, "ftable-cellspan", 'J', 0 },
211212
{ 0, "ftasklists", 'X', 0 },
212213
{ 0, "funderline", '_', 0 },
213214
{ 0, "fverbatim-entities", 'E', 0 },
@@ -258,6 +259,8 @@ usage(void)
258259
" --fpermissive-email-autolinks\n"
259260
" --fstrikethrough Enable strike-through spans\n"
260261
" --ftables Enable tables\n"
262+
" --ftable-cellspan\n"
263+
" Enable table cell-span extension '|2> text |'\n"
261264
" --ftasklists Enable task lists\n"
262265
" --funderline Enable underline spans\n"
263266
" --fwiki-links Enable wiki links\n"
@@ -322,6 +325,7 @@ cmdline_callback(int opt, char const* value, void* data)
322325
case '@': parser_flags |= MD_FLAG_PERMISSIVEEMAILAUTOLINKS; break;
323326
case 'V': parser_flags |= MD_FLAG_PERMISSIVEAUTOLINKS; break;
324327
case 'T': parser_flags |= MD_FLAG_TABLES; break;
328+
case 'J': parser_flags |= MD_FLAG_TABLE_CELLSPAN; break;
325329
case 'S': parser_flags |= MD_FLAG_STRIKETHROUGH; break;
326330
case 'L': parser_flags |= MD_FLAG_LATEXMATHSPANS; break;
327331
case 'K': parser_flags |= MD_FLAG_WIKILINKS; break;

src/md4c-html.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,15 +312,23 @@ render_open_code_block(MD_HTML* r, const MD_BLOCK_CODE_DETAIL* det)
312312
static void
313313
render_open_td_block(MD_HTML* r, const MD_CHAR* cell_type, const MD_BLOCK_TD_DETAIL* det)
314314
{
315+
MD_CHAR tail[2];
316+
315317
RENDER_VERBATIM(r, "<");
316318
RENDER_VERBATIM(r, cell_type);
317319

318320
switch(det->align) {
319-
case MD_ALIGN_LEFT: RENDER_VERBATIM(r, " align=\"left\">"); break;
320-
case MD_ALIGN_CENTER: RENDER_VERBATIM(r, " align=\"center\">"); break;
321-
case MD_ALIGN_RIGHT: RENDER_VERBATIM(r, " align=\"right\">"); break;
322-
default: RENDER_VERBATIM(r, ">"); break;
321+
case MD_ALIGN_LEFT: RENDER_VERBATIM(r, " align=\"left\""); break;
322+
case MD_ALIGN_CENTER: RENDER_VERBATIM(r, " align=\"center\""); break;
323+
case MD_ALIGN_RIGHT: RENDER_VERBATIM(r, " align=\"right\""); break;
324+
}
325+
if (det->colspan > 1) {
326+
RENDER_VERBATIM(r, " colspan=\"");
327+
tail[0] = '0' + det->colspan;
328+
tail[1] = '\"';
329+
render_verbatim(r, tail, 2);
323330
}
331+
RENDER_VERBATIM(r, ">");
324332
}
325333

326334
static void

src/md4c.c

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4410,24 +4410,22 @@ md_analyze_table_alignment(MD_CTX* ctx, OFF beg, OFF end, MD_ALIGN* align, int n
44104410
static int md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines);
44114411

44124412
static int
4413-
md_process_table_cell(MD_CTX* ctx, MD_BLOCKTYPE cell_type, MD_ALIGN align, OFF beg, OFF end)
4413+
md_process_table_cell(MD_CTX* ctx, MD_BLOCKTYPE cell_type, MD_BLOCK_TD_DETAIL *det, OFF beg, OFF end)
44144414
{
44154415
MD_LINE line;
4416-
MD_BLOCK_TD_DETAIL det;
44174416
int ret = 0;
44184417

44194418
while(beg < end && ISWHITESPACE(beg))
44204419
beg++;
44214420
while(end > beg && ISWHITESPACE(end-1))
44224421
end--;
44234422

4424-
det.align = align;
44254423
line.beg = beg;
44264424
line.end = end;
44274425

4428-
MD_ENTER_BLOCK(cell_type, &det);
4426+
MD_ENTER_BLOCK(cell_type, det);
44294427
MD_CHECK(md_process_normal_block_contents(ctx, &line, 1));
4430-
MD_LEAVE_BLOCK(cell_type, &det);
4428+
MD_LEAVE_BLOCK(cell_type, det);
44314429

44324430
abort:
44334431
return ret;
@@ -4438,6 +4436,10 @@ md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end,
44384436
const MD_ALIGN* align, int col_count)
44394437
{
44404438
MD_LINE line;
4439+
MD_LINE cell;
4440+
MD_BLOCK_TD_DETAIL det;
4441+
4442+
unsigned is_spans;
44414443
OFF* pipe_offs = NULL;
44424444
int i, j, k, n;
44434445
int ret = 0;
@@ -4464,19 +4466,36 @@ md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end,
44644466
MD_MARK* mark = &ctx->marks[i];
44654467
pipe_offs[j++] = mark->end;
44664468
}
4467-
pipe_offs[j++] = end+1;
4469+
pipe_offs[j] = end+1;
44684470

4471+
is_spans = ctx->parser.flags & MD_FLAG_TABLE_CELLSPAN;
44694472
/* Process cells. */
44704473
MD_ENTER_BLOCK(MD_BLOCK_TR, NULL);
44714474
k = 0;
4472-
for(i = 0; i < j-1 && k < col_count; i++) {
4473-
if(pipe_offs[i] < pipe_offs[i+1]-1)
4474-
MD_CHECK(md_process_table_cell(ctx, cell_type, align[k++], pipe_offs[i], pipe_offs[i+1]-1));
4475+
for(i = 0; i < j && k < col_count; i++) {
4476+
cell.beg = pipe_offs[i];
4477+
cell.end = pipe_offs[i+1]-1;
4478+
4479+
if(cell.beg < cell.end) {
4480+
det.colspan = 0;
4481+
if (is_spans && cell.end - cell.beg >= 2 &&
4482+
ISDIGIT(cell.beg) && CH(cell.beg+1) == '>') {
4483+
det.colspan = CH(cell.beg) - '0';
4484+
cell.beg += 2;
4485+
}
4486+
det.align = align[k++];
4487+
MD_CHECK(md_process_table_cell(ctx, cell_type, &det, cell.beg, cell.end));
4488+
if (is_spans && det.colspan > 1)
4489+
k += det.colspan - 1;
4490+
}
44754491
}
44764492
/* Make sure we call enough table cells even if the current table contains
44774493
* too few of them. */
4478-
while(k < col_count)
4479-
MD_CHECK(md_process_table_cell(ctx, cell_type, align[k++], 0, 0));
4494+
det.colspan = 0;
4495+
while(k < col_count) {
4496+
det.align = align[k++];
4497+
MD_CHECK(md_process_table_cell(ctx, cell_type, &det, 0, 0));
4498+
}
44804499
MD_LEAVE_BLOCK(MD_BLOCK_TR, NULL);
44814500

44824501
abort:

src/md4c.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ typedef struct MD_BLOCK_TABLE_DETAIL {
278278
/* Detailed info for MD_BLOCK_TH and MD_BLOCK_TD. */
279279
typedef struct MD_BLOCK_TD_DETAIL {
280280
MD_ALIGN align;
281+
int colspan;
281282
} MD_BLOCK_TD_DETAIL;
282283

283284
/* Detailed info for MD_SPAN_A. */
@@ -316,6 +317,7 @@ typedef struct MD_SPAN_WIKILINK {
316317
#define MD_FLAG_LATEXMATHSPANS 0x1000 /* Enable $ and $$ containing LaTeX equations. */
317318
#define MD_FLAG_WIKILINKS 0x2000 /* Enable wiki links extension. */
318319
#define MD_FLAG_UNDERLINE 0x4000 /* Enable underline extension (and disables '_' for normal emphasis). */
320+
#define MD_FLAG_TABLE_CELLSPAN 0x8000 /* Enable table colspan extension '|2> 2-cell-span |'. */
319321

320322
#define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS)
321323
#define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS)

0 commit comments

Comments
 (0)