Skip to content

Commit

Permalink
feat: change segment separator to empty lines only
Browse files Browse the repository at this point in the history
  • Loading branch information
falsandtru committed Dec 8, 2019
1 parent 6fd2325 commit 21aadce
Show file tree
Hide file tree
Showing 13 changed files with 52 additions and 65 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.139.0

- Change segment separator to empty lines only.

## 0.138.1

- Fix end of line processing.
Expand Down
10 changes: 3 additions & 7 deletions markdown.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export namespace MarkdownParser {
BlockParser.MathBlockParser.SegmentParser,
BlockParser.ExtensionParser.SegmentParser,
SourceParser.ContentLineParser,
SourceParser.BlankLineParser,
SourceParser.EmptyLineParser,
], State, Config> {
}
export interface BlockParser extends
Expand All @@ -61,7 +61,7 @@ export namespace MarkdownParser {
export interface NewlineParser extends
Block<'newline'>,
Parser<never, [
SourceParser.BlankLineParser,
SourceParser.EmptyLineParser,
], State, Config> {
}
export interface HorizontalRuleParser extends
Expand Down Expand Up @@ -331,7 +331,7 @@ export namespace MarkdownParser {
], State, Config>,
SourceParser.EmptyLineParser,
Parser<never, [
SourceParser.BlankLineParser,
SourceParser.EmptyLineParser,
SourceParser.ContentLineParser,
], State, Config>,
], State, Config>,
Expand Down Expand Up @@ -829,10 +829,6 @@ export namespace MarkdownParser {
Source<'contentline'>,
Parser<never, [], State, Config> {
}
export interface BlankLineParser extends
Source<'blankline'>,
Parser<never, [], State, Config> {
}
export interface EmptyLineParser extends
Source<'emptyline'>,
Parser<never, [], State, Config> {
Expand Down
4 changes: 2 additions & 2 deletions src/parser/api/parse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ describe('Unit: parser/api/parse', () => {
['<p>a<span class="linebreak"> </span>b</p>']);
assert.deepStrictEqual(
[...parse('a\n\\ \nb').children].map(el => el.outerHTML),
['<p>a</p>', '<p>b</p>']);
['<p>a<br>b</p>']);
assert.deepStrictEqual(
[...parse('a\n\\\nb').children].map(el => el.outerHTML),
['<p>a</p>', '<p>b</p>']);
['<p>a<br>b</p>']);
assert.deepStrictEqual(
[...parse('~~~a\ninvalid\n~~~').children].map(el => el.outerHTML),
['<p class="invalid" data-invalid-syntax="extension" data-invalid-type="syntax">Invalid syntax: Extension: Invalid extension name, attribute, or content.</p>']);
Expand Down
4 changes: 2 additions & 2 deletions src/parser/block/extension/figure.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ExtensionParser } from '../../block';
import { union, sequence, inits, some, block, line, rewrite, surround, match, memoize, convert, trim, configure, fmap } from '../../../combinator';
import { contentline, blankline, emptyline } from '../../source';
import { contentline, emptyline } from '../../source';
import { table } from '../table';
import { codeblock, segment_ as seg_code } from '../codeblock';
import { mathblock, segment_ as seg_math } from '../mathblock';
Expand Down Expand Up @@ -31,7 +31,7 @@ export const segment: FigureParser.SegmentParser = block(match(
]),
emptyline,
union([
blankline,
emptyline,
some(contentline, closer),
]),
]),
Expand Down
5 changes: 2 additions & 3 deletions src/parser/block/newline.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@ describe('Unit: parser/block/newline', () => {

it('invalid', () => {
assert.deepStrictEqual(inspect(parser('')), undefined);
assert.deepStrictEqual(inspect(parser('\\ ')), undefined);
assert.deepStrictEqual(inspect(parser('\\\n')), undefined);
assert.deepStrictEqual(inspect(parser('a')), undefined);
});

it('valid', () => {
assert.deepStrictEqual(inspect(parser(' ')), [[], '']);
assert.deepStrictEqual(inspect(parser('\n')), [[], '']);
assert.deepStrictEqual(inspect(parser('\\ ')), [[], '']);
assert.deepStrictEqual(inspect(parser('\\\n')), [[], '']);
assert.deepStrictEqual(inspect(parser(' \n\\ \\\n')), [[], '']);
});

});
Expand Down
4 changes: 2 additions & 2 deletions src/parser/block/newline.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NewlineParser } from '../block';
import { union, some } from '../../combinator';
import { blankline } from '../source';
import { emptyline } from '../source';

export const newline: NewlineParser = some(union([blankline]));
export const newline: NewlineParser = some(union([emptyline]));
5 changes: 5 additions & 0 deletions src/parser/block/paragraph.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ describe('Unit: parser/block/paragraph', () => {
it('basic', () => {
assert.deepStrictEqual(inspect(parser('a')), [['<p>a</p>'], '']);
assert.deepStrictEqual(inspect(parser('ab')), [['<p>ab</p>'], '']);
assert.deepStrictEqual(inspect(parser('a\\')), [['<p>a</p>'], '']);
assert.deepStrictEqual(inspect(parser('a ')), [['<p>a</p>'], '']);
assert.deepStrictEqual(inspect(parser('a \n')), [['<p>a</p>'], '']);
assert.deepStrictEqual(inspect(parser('a\n')), [['<p>a</p>'], '']);
assert.deepStrictEqual(inspect(parser('a\nb')), [['<p>a<br>b</p>'], '']);
assert.deepStrictEqual(inspect(parser('a\n\\')), [['<p>a</p>'], '']);
assert.deepStrictEqual(inspect(parser('a\n\\\n')), [['<p>a</p>'], '']);
assert.deepStrictEqual(inspect(parser('a\\ ')), [['<p>a</p>'], '']);
assert.deepStrictEqual(inspect(parser('a\\ \n')), [['<p>a</p>'], '']);
assert.deepStrictEqual(inspect(parser('a\\\n')), [['<p>a</p>'], '']);
assert.deepStrictEqual(inspect(parser('a\\\nb')), [['<p>a<span class="linebreak"> </span>b</p>'], '']);
assert.deepStrictEqual(inspect(parser('*a\\\n*')), [['<p><em>a</em></p>'], '']);
Expand Down
36 changes: 22 additions & 14 deletions src/parser/block/paragraph.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { ParagraphParser } from '../block';
import { subsequence, some, block, rewrite, trim, fmap } from '../../combinator';
import { subsequence, some, block, rewrite, convert, trim, fmap } from '../../combinator';
import { mention } from './paragraph/mention';
import { inline } from '../inline';
import { contentline } from '../source';
import { defrag, isVisible } from '../util';
import { concat } from 'spica/concat';
import { html, define } from 'typed-dom';

export const paragraph: ParagraphParser = block(fmap(
const blankline = /^(?:\\?\s)*\\?(?:\n|$)/gm;

export const paragraph: ParagraphParser = block(fmap(convert(
source => source.replace(blankline, ''),
some(subsequence([
fmap(
some(mention),
Expand All @@ -17,19 +20,24 @@ export const paragraph: ParagraphParser = block(fmap(
some(contentline, '>'),
defrag(trim(some(inline)))),
ns => concat(ns, [html('br')])),
])),
ns => [html('p', format(ns))].map(el =>
isVisible(el)
? el
: define(el, {
class: 'invalid',
'data-invalid-syntax': 'paragraph',
'data-invalid-type': 'visibility',
}))));
]))),
ns =>
ns.length > 0
? [html('p', format(ns))].map(el =>
isVisible(el)
? el
: define(el, {
class: 'invalid',
'data-invalid-syntax': 'paragraph',
'data-invalid-type': 'visibility',
}))
: []));

function format<T extends Node[]>(ns: T): T {
ns[ns.length - 1]?.nodeName === 'BR' && void ns.pop();
assert(!(ns[0] instanceof HTMLBRElement));
assert(!(ns[ns.length - 1] instanceof HTMLBRElement));
assert(ns.length > 1);
assert(ns[ns.length - 1] instanceof HTMLBRElement);
void ns.pop();
assert(ns.length > 0);
assert(ns[ns.length - 1] instanceof HTMLBRElement === false);
return ns;
}
2 changes: 1 addition & 1 deletion src/parser/segment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ describe('Unit: parser/segment', () => {
assert.deepStrictEqual(segment('a\nb\n\n'), ['a\nb\n', '\n']);
assert.deepStrictEqual(segment('a\nb\n\n\n'), ['a\nb\n', '\n\n']);
assert.deepStrictEqual(segment('a\nb\n\nc\n\nd'), ['a\nb\n', '\n', 'c\n', '\n', 'd']);
assert.deepStrictEqual(segment('a\n\\\nb'), ['a\n\\\nb']);
assert.deepStrictEqual(segment('a '), ['a ']);
assert.deepStrictEqual(segment(' a'), [' a']);
assert.deepStrictEqual(segment(' a '), [' a ']);
Expand All @@ -33,7 +34,6 @@ describe('Unit: parser/segment', () => {
assert.deepStrictEqual(segment('a\n\n\n\n '), ['a\n', '\n\n\n ']);
assert.deepStrictEqual(segment('a\n\n\n\n\n '), ['a\n', '\n\n\n\n ']);
assert.deepStrictEqual(segment('a\n\n\n\n\n\n '), ['a\n', '\n\n\n\n\n ']);
assert.deepStrictEqual(segment('a\n\\\nb'), ['a\n', '\\\n', 'b']);
});

it('codeblock', () => {
Expand Down
4 changes: 2 additions & 2 deletions src/parser/segment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { union, some, exec } from '../combinator';
import { segment as codeblock } from './block/codeblock';
import { segment as mathblock } from './block/mathblock';
import { segment as extension } from './block/extension';
import { contentline, blankline } from './source';
import { contentline, emptyline } from './source';
import { normalize } from './api/normalization';

import SegmentParser = MarkdownParser.SegmentParser;
Expand All @@ -13,7 +13,7 @@ const parser: SegmentParser = union([
mathblock,
extension,
some(contentline),
some(blankline),
some(emptyline),
]);

export function segment(source: string): string[] {
Expand Down
3 changes: 1 addition & 2 deletions src/parser/source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export import EscapableSourceParser = SourceParser.EscapableSourceParser;
export import UnescapableSourceParser = SourceParser.UnescapableSourceParser;
export import CharParser = SourceParser.CharParser;
export import ContentLineParser = SourceParser.ContentLineParser;
export import BlankLineParser = SourceParser.BlankLineParser;
export import EmptyLineParser = SourceParser.EmptyLineParser;
export import AnyLineParser = SourceParser.AnyLineParser;

Expand All @@ -16,4 +15,4 @@ export { newline } from './source/newline';
export { escsource } from './source/escapable';
export { unescsource } from './source/unescapable';
export { char } from './source/char';
export { contentline, blankline, emptyline, anyline } from './source/line';
export { contentline, emptyline, anyline } from './source/line';
29 changes: 4 additions & 25 deletions src/parser/source/line.test.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,7 @@
import { blankline, contentline } from './line';
import { contentline } from './line';
import { inspect } from '../../debug.test';

describe('Unit: parser/source/line', () => {
describe('blankline', () => {
const parser = (source: string) => blankline(source, {}, {});

it('invalid', () => {
assert.deepStrictEqual(inspect(parser('')), undefined);
assert.deepStrictEqual(inspect(parser('ab')), undefined);
assert.deepStrictEqual(inspect(parser('ab\n')), undefined);
assert.deepStrictEqual(inspect(parser('ab \n')), undefined);
});

it('valid', () => {
assert.deepStrictEqual(inspect(parser('\n')), [[], '']);
assert.deepStrictEqual(inspect(parser('\n ')), [[], ' ']);
assert.deepStrictEqual(inspect(parser('\n\n')), [[], '\n']);
assert.deepStrictEqual(inspect(parser(' ')), [[], '']);
assert.deepStrictEqual(inspect(parser(' \n')), [[], '']);
assert.deepStrictEqual(inspect(parser(' \n\n')), [[], '\n']);
assert.deepStrictEqual(inspect(parser('\\\n')), [[], '']);
assert.deepStrictEqual(inspect(parser('\\ \\\n')), [[], '']);
assert.deepStrictEqual(inspect(parser('\\ \\ \\\n')), [[], '']);
});

});

describe('contentline', () => {
const parser = (source: string) => contentline(source, {}, {});

Expand All @@ -46,6 +22,9 @@ describe('Unit: parser/source/line', () => {
assert.deepStrictEqual(inspect(parser(' a \n')), [[], '']);
assert.deepStrictEqual(inspect(parser('ab')), [[], '']);
assert.deepStrictEqual(inspect(parser('a\nb')), [[], 'b']);
assert.deepStrictEqual(inspect(parser('\\\n')), [[], '']);
assert.deepStrictEqual(inspect(parser('\\ \\\n')), [[], '']);
assert.deepStrictEqual(inspect(parser('\\ \\ \\\n')), [[], '']);
});

});
Expand Down
7 changes: 2 additions & 5 deletions src/parser/source/line.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { AnyLineParser, EmptyLineParser, BlankLineParser, ContentLineParser } from '../source';
import { AnyLineParser, EmptyLineParser, ContentLineParser } from '../source';
import { line } from '../../combinator';

export const anyline: AnyLineParser = line(() => [[], ''], false);
export const emptyline: EmptyLineParser = line(s => s.trim() === '' ? [[], ''] : undefined, false);

const invisible = /^(?:\\?\s)*\\?$/;
export const blankline: BlankLineParser = line(s => invisible.test(s) ? [[], ''] : undefined, false);
export const contentline: ContentLineParser = line(s => !invisible.test(s) ? [[], ''] : undefined, false);
export const contentline: ContentLineParser = line(s => s.trim() !== '' ? [[], ''] : undefined, false);

0 comments on commit 21aadce

Please sign in to comment.