Skip to content

Commit

Permalink
refactor(parser): refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
falsandtru committed Mar 11, 2018
1 parent be3af30 commit f1c648e
Show file tree
Hide file tree
Showing 9 changed files with 32 additions and 16 deletions.
3 changes: 2 additions & 1 deletion src/parser/block/blockquote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { combine, some } from '../../combinator';
import { verify } from './util/verification';
import { block as block_ } from '../source/block';
import { firstline } from '../source/line';
import { block } from '../block';
import { unescsource } from '../source/unescapable';
import { squash } from '../squash';
Expand All @@ -26,7 +27,7 @@ export const blockquote: BlockquoteParser = verify(block_(source => {
p.appendChild(html('blockquote'))
, top);
while (true) {
if (source.split('\n', 1).shift()!.trim() === '') break;
if (firstline(source).trim() === '') break;
const diff = (source.match(syntax) || [indent])[0].length - indent.length;
if (diff > 0) {
bottom = source.slice(0, diff).split('')
Expand Down
5 changes: 3 additions & 2 deletions src/parser/block/dlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { combine, some } from '../../combinator';
import { verify } from './util/verification';
import { block } from '../source/block';
import { firstline } from '../source/line';
import { indexer, defineIndex } from './util/indexer';
import { InlineParser, inline } from '../inline';
import { squash } from '../squash';
Expand All @@ -15,7 +16,7 @@ export const dlist: DListParser = verify(block(source => {
if (!whole) return;
const el = html('dl');
while (true) {
const line = source.split('\n', 1)[0];
const line = firstline(source);
if (line.trim() === '') break;
switch (line.slice(0, 2).trim()) {
case '~': {
Expand All @@ -33,7 +34,7 @@ export const dlist: DListParser = verify(block(source => {
const texts = [line.slice(line.slice(0, 2).trim() === ':' ? 1 : 0)];
source = source.slice(line.length + 1);
while (true) {
const line = source.split('\n', 1)[0];
const line = firstline(source);
if (line.trim() === '' || line.search(separator) === 0) break;
void texts.push(line);
source = source.slice(line.length + 1);
Expand Down
5 changes: 3 additions & 2 deletions src/parser/block/extension/placeholder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { some } from '../../../combinator';
import { verify } from '../util/verification';
import { block as block_ } from '../../source/block';
import { block } from '../../block';
import { firstline } from '../../source/line';
import { unescsource } from '../../source/unescapable';

const syntax = /^(~{3,})([^\n]*)\n(?:[^\n]*\n)*?\1[^\S\n]*(?:\n|$)/;
Expand All @@ -15,11 +16,11 @@ export const placeholder: ExtensionParser.PlaceholderParser = verify(block_(sour
source = source.slice(source.indexOf('\n') + 1);
const lines: string[] = [];
while (true) {
const line = source.split('\n', 1)[0];
const line = firstline(source);
if (line.startsWith(`${bracket}`) && line.trim() === `${bracket}`) break;
void lines.push((some(unescsource)(`${line}\n`) || [[] as Text[]])[0].reduce((acc, n) => acc + n.textContent, ''));
source = source.slice(line.length + 1);
if (source === '') return;
}
return [[message], source.slice(source.split('\n', 1)[0].length + 1)];
return [[message], source.slice(firstline(source).length + 1)];
}));
3 changes: 2 additions & 1 deletion src/parser/block/olist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { verify } from './util/verification';
import { combine, some } from '../../combinator';
import { block } from '../source/block';
import { firstline } from '../source/line';
import { match } from '../source/validation';
import { ulist } from './ulist';
import { indent, fillOListFlag } from './util/indent';
Expand All @@ -19,7 +20,7 @@ export const olist: OListParser = verify(block(source => {
'type': Number.isFinite(+index) ? '1' : index === index.toLowerCase() ? 'a' : 'A',
});
while (true) {
const line = source.split('\n', 1)[0];
const line = firstline(source);
if (line.trim() === '') break;
if (!match(line, '', syntax)) return;
const text = line.slice(line.split(/\s/, 1)[0].length + 1).trim();
Expand Down
5 changes: 3 additions & 2 deletions src/parser/block/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { verify } from './util/verification';
import { some } from '../../combinator';
import { block } from '../source/block';
import { firstline } from '../source/line';
import { inline } from '../inline';
import { squash } from '../squash';
import { html } from 'typed-dom';
Expand Down Expand Up @@ -38,7 +39,7 @@ export const table: TableParser = verify(block(source => {
: aligns[i]));
void table.appendChild(html('tbody'));
while (true) {
const line = source.split('\n', 1)[0];
const line = firstline(source);
if (line.trim() === '') break;
const [cols = [], rest = line] = parse(line) || [];
if (rest.length !== 0) return;
Expand Down Expand Up @@ -66,6 +67,6 @@ function parse(row: string): [DocumentFragment[], string] | undefined {
assert(rest.length < row.length);
row = rest;
void cols.push(squash(col, document.createDocumentFragment()));
if (row.search(rowend) === 0) return [cols, row.slice(row.split('\n')[0].length + 1)];
if (row.search(rowend) === 0) return [cols, row.slice(firstline(row).length + 1)];
}
}
3 changes: 2 additions & 1 deletion src/parser/block/ulist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { verify } from './util/verification';
import { combine, some } from '../../combinator';
import { block } from '../source/block';
import { firstline } from '../source/line';
import { match } from '../source/validation';
import { olist } from './olist';
import { indent, fillOListFlag } from './util/indent';
Expand All @@ -17,7 +18,7 @@ export const ulist: UListParser = verify(block(source => {
if (!whole) return;
const el = html('ul');
while (true) {
const line = source.split('\n', 1)[0];
const line = firstline(source);
if (line.trim() === '') break;
if (!match(line, flag, syntax)) return;
const [text, checkbox = ''] = line.slice(line.split(/\s/, 1)[0].length + 1).trim().match(content)!;
Expand Down
8 changes: 5 additions & 3 deletions src/parser/block/util/indent.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
const syntax = /^\s*/;
import { firstline } from '../../source/line';

const syntax = /^\s*/;

export function indent(source: string): [string, string] | undefined {
const [indent = ''] = source.split('\n', 1)[0].match(syntax) || [];
const [indent = ''] = firstline(source).match(syntax) || [];
if (indent === '') return;
const lines: string[] = [];
let rest = source;
while (true) {
const line = rest.split('\n', 1)[0];
const line = firstline(rest);
if (!line.startsWith(indent)) break;
if (line.slice(indent.length).trim() === '') break;
void lines.push(line.slice(indent.length));
Expand Down
3 changes: 2 additions & 1 deletion src/parser/block/util/verification.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Result } from '../../../combinator';
import { firstline } from '../../source/line';

export function verify<T extends Result<any, any>>(parser: (source: string) => T): (source: string) => T {
return source => {
const result = parser(source);
if (!result) return result;
assert(result[0].length < 2);
if (result[1].split('\n', 1)[0].trim() !== '') return undefined as T;
if (firstline(result[1]).trim() !== '') return undefined as T;
return result;
};
}
13 changes: 10 additions & 3 deletions src/parser/source/line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ export function line<S extends Parser<any, any>[], R>(parser: Parser<R, S>, enti
return source => {
if (source.length === 0) return;
if (force) {
const src = source.split('\n', 1)[0];
const src = firstline(source);
const rst = source.slice(src.length + 1);
const result = line(parser, entire, false)(`${src}${source.length > src.length ? source[src.length] : ''}`);
const result = line(parser, entire, false)(src + (source.length > src.length ? source[src.length] : ''));
return result
? [result[0], result[1] + rst]
: undefined;
Expand All @@ -25,9 +25,16 @@ export function line<S extends Parser<any, any>[], R>(parser: Parser<R, S>, enti
};
}

export function firstline(source: string): string {
const i = source.indexOf('\n');
return i === -1
? source
: source.slice(0, i);
}

export const emptyline: EmptyLineParser = line(s => s.trim() === '' ? [[], ''] : undefined, true, true);
export const nonemptyline: NonemptyLineParser = line(s => s.trim() !== '' ? [[], ''] : undefined, true, true);

const invisible = /^(?:\\?\s)*?\\?$/;
export const visibleline: VisibleLineParser = line(s => s.search(invisible) === -1 ? [[], ''] : undefined, true, true);
export const visibleline: VisibleLineParser = line(s => s.search(invisible) !== 0 ? [[], ''] : undefined, true, true);
export const invisibleline: InvisibleLineParser = line(s => s.search(invisible) === 0 ? [[], ''] : undefined, true, true);

0 comments on commit f1c648e

Please sign in to comment.