Skip to content

Commit

Permalink
feat: support line-break (#111)
Browse files Browse the repository at this point in the history
  • Loading branch information
rasendubi committed May 19, 2024
1 parent dbf6452 commit b45baf9
Show file tree
Hide file tree
Showing 12 changed files with 161 additions and 3 deletions.
10 changes: 10 additions & 0 deletions .changeset/quiet-berries-sniff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'uniorg-parse': major
'uniorg-stringify': minor
'uniorg-rehype': minor
'uniorg': minor
---

Support `line-break` in uniorg, uniorg-parse, uniorg-rehype, and uniorg-stringify.

This is a breaking change for uniorg-parse as it may output nodes unknown to downstream users (uniorg-rehype and uniorg-stringify). If you upgrade uniorg-parse, you should also upgrade uniorg-rehype and uniorg-stringify to the corresponding versions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ However, there are a couple of places I haven't finished yet:
- babel-call, inline-babel-call, inline-src-block
- dynamic-block
- target, radio-target
- line-break
- export-snippet
- macro
- switches and parameters in src-block and example-block
- repeater/warning props in timestamp
Expand Down
73 changes: 73 additions & 0 deletions packages/uniorg-parse/src/__snapshots__/parser.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2438,6 +2438,79 @@ children:
value: "."
`;
exports[`org/parser line-break fake line break (must be at end of line) 1`] = `
type: "org-data"
contentsBegin: 0
contentsEnd: 27
children:
- type: "paragraph"
affiliated: {}
contentsBegin: 0
contentsEnd: 27
children:
- type: "text"
value: "some text\\\\"
- type: "entity"
useBrackets: false
name: "not"
latex: "\\\\textlnot{}"
requireLatexMath: false
html: "¬"
ascii: "[angled dash]"
latin1: "¬"
utf8: "¬"
- type: "text"
value: " a line break"
`;
exports[`org/parser line-break fake line break (triple backslash) 1`] = `
type: "org-data"
contentsBegin: 0
contentsEnd: 26
children:
- type: "paragraph"
affiliated: {}
contentsBegin: 0
contentsEnd: 26
children:
- type: "text"
value: "some text\\\\\\\\\\\\\\nnot next line"
`;
exports[`org/parser line-break valid line break 1`] = `
type: "org-data"
contentsBegin: 0
contentsEnd: 22
children:
- type: "paragraph"
affiliated: {}
contentsBegin: 0
contentsEnd: 22
children:
- type: "text"
value: "some text"
- type: "line-break"
- type: "text"
value: "line break"
`;
exports[`org/parser line-break whitespace after \\\\ 1`] = `
type: "org-data"
contentsBegin: 0
contentsEnd: 24
children:
- type: "paragraph"
affiliated: {}
contentsBegin: 0
contentsEnd: 24
children:
- type: "text"
value: "some text"
- type: "line-break"
- type: "text"
value: "line break"
`;
exports[`org/parser links ./ as start of file link 1`] = `
type: "org-data"
contentsBegin: 0
Expand Down
21 changes: 21 additions & 0 deletions packages/uniorg-parse/src/parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1106,4 +1106,25 @@ more text

itParses('fake export snippet, missing backend', '@@<b>@@');
});

describe('line-break', () => {
itParses(
'valid line break',
`some text\\\\
line break`
);

itParses('whitespace after \\\\', `some text\\\\ \nline break`);

itParses(
'fake line break (must be at end of line)',
`some text\\\\not a line break`
);

itParses(
'fake line break (triple backslash)',
`some text\\\\\\
not next line`
);
});
});
18 changes: 17 additions & 1 deletion packages/uniorg-parse/src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
CitationSuffix,
CitationCommonSuffix,
ExportSnippet,
LineBreak,
} from 'uniorg';

import { getOrgEntity } from './entities.js';
Expand Down Expand Up @@ -638,7 +639,9 @@ class Parser {
break;
case '\\':
if (c[1] === '\\') {
// TODO: line break parser
if (restriction.has('line-break')) {
return this.parseLineBreak();
}
} else {
const offset = this.r.offset();
const entity = restriction.has('entity') && this.parseEntity();
Expand Down Expand Up @@ -1707,6 +1710,19 @@ class Parser {
return u('latex-fragment', { value, contents: contents ?? value });
}

private parseLineBreak(): LineBreak | null {
const m = this.r.lookingAt(/\\\\[ \t]*$/m);
if (!m) return null;

// check character before linebreak
this.r.backoff(1);
if (this.r.peek(1) === '\\') return null;

this.r.advance(this.r.line());

return u('line-break');
}

private parseFootnoteReference(): FootnoteReference | null {
const begin = this.r.offset();
const m = this.r.match(footnoteRe);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,12 @@ exports[`org/org-to-hast latex-fragment 1`] = `
`;
exports[`org/org-to-hast line-break 1`] = `
<p>hello<br>world</p>
`;
exports[`org/org-to-hast link 1`] = `
<p><a href="https://example.com">https://example.com</a></p>
Expand Down
6 changes: 6 additions & 0 deletions packages/uniorg-rehype/src/org-to-hast.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,12 @@ either $$ a=+\\sqrt{2} $$ or \\[ a=-\\sqrt{2} \\].`
`[cite/style:common prefix; prefix @key suffix; @key2; common suffix]`
);

hastTest(
'line-break',
`hello\\\\
world`
);

test('respects hProperties', () => {
const s = unified()
.use(orgParse)
Expand Down
3 changes: 3 additions & 0 deletions packages/uniorg-rehype/src/org-to-hast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ const defaultHandlers: Handlers = {
if (org.backEnd !== 'html') return null;
return u('raw', org.value) as any;
},
'line-break': function (org) {
return this.h(org, 'br');
},
};

function renderAsChildren(
Expand Down
12 changes: 12 additions & 0 deletions packages/uniorg-stringify/src/__snapshots__/stringify.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,18 @@ either $$ a=+\\\\sqrt{2} $$ or \\\\[ a=-\\\\sqrt{2} \\\\].
"
`;

exports[`stringify line-break 1`] = `
"hello\\\\\\\\
world!
"
`;

exports[`stringify line-break with trailing whitespace 1`] = `
"hello\\\\\\\\
world!
"
`;

exports[`stringify links angle link 1`] = `
"<http://example.com>
"
Expand Down
7 changes: 7 additions & 0 deletions packages/uniorg-stringify/src/stringify.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,4 +514,11 @@ some text
});

test('handle export-snippet', `@@backend:custom value@@`);

test(
'line-break',
`hello\\\\
world!`
);
test('line-break with trailing whitespace', `hello\\\\ \nworld!`);
});
1 change: 1 addition & 0 deletions packages/uniorg-stringify/src/stringify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export type StringifyOptions = {
const defaultOptions: StringifyOptions = {
handlers: {
'export-snippet': (org) => `@@${org.backEnd}:${org.value}@@`,
'line-break': () => `\\\\\n`,
},
};

Expand Down
5 changes: 5 additions & 0 deletions packages/uniorg/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export type ObjectType =
| LatexFragment
| Entity
| ExportSnippet
| LineBreak
| TableCell;

export type OrgNode = GreaterElementType | ElementType | ObjectType;
Expand Down Expand Up @@ -197,6 +198,10 @@ export interface ExportSnippet extends Node {
value: string;
}

export interface LineBreak extends Node {
type: 'line-break';
}

export interface List extends GreaterElement {
type: 'plain-list';
listType: 'ordered' | 'unordered' | 'descriptive';
Expand Down

0 comments on commit b45baf9

Please sign in to comment.