2021-05-17 14:56:30 +05:30
|
|
|
import { linkify } from "./linkify/linkify.js";
|
|
|
|
|
2021-05-17 20:39:23 +05:30
|
|
|
/**
|
|
|
|
* Parse text into parts such as newline, links and text.
|
|
|
|
* @param {string} body A string to parse into parts
|
|
|
|
* @returns {MessageBody} Parsed result
|
|
|
|
*/
|
2021-05-17 14:56:30 +05:30
|
|
|
export function parsePlainBody(body) {
|
|
|
|
const parts = [];
|
|
|
|
const lines = body.split("\n");
|
|
|
|
|
|
|
|
// create callback outside of loop
|
|
|
|
const linkifyCallback = (text, isLink) => {
|
|
|
|
if (isLink) {
|
|
|
|
parts.push(new LinkPart(text, text));
|
|
|
|
} else {
|
|
|
|
parts.push(new TextPart(text));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
for (let i = 0; i < lines.length; i += 1) {
|
|
|
|
const line = lines[i];
|
|
|
|
if (line.length) {
|
2021-05-18 14:26:56 +05:30
|
|
|
linkify(line, linkifyCallback);
|
2021-05-17 14:56:30 +05:30
|
|
|
}
|
|
|
|
const isLastLine = i >= (lines.length - 1);
|
|
|
|
if (!isLastLine) {
|
|
|
|
parts.push(new NewLinePart());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return new MessageBody(body, parts);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function stringAsBody(body) {
|
|
|
|
return new MessageBody(body, [new TextPart(body)]);
|
|
|
|
}
|
|
|
|
|
2021-07-01 12:49:01 +05:30
|
|
|
class HeaderBlock {
|
|
|
|
constructor(level, inlines) {
|
|
|
|
this.level = level;
|
|
|
|
this.inlines = inlines;
|
|
|
|
}
|
|
|
|
|
|
|
|
get type() { return "header"; }
|
|
|
|
isBlock() { return true; }
|
|
|
|
}
|
|
|
|
|
|
|
|
class CodeBlock {
|
|
|
|
constructor(text) {
|
|
|
|
this.text = text;
|
|
|
|
}
|
|
|
|
|
|
|
|
get type() { return "codeblock"; }
|
|
|
|
isBlock() { return true; }
|
|
|
|
}
|
|
|
|
|
2021-05-17 14:56:30 +05:30
|
|
|
class NewLinePart {
|
|
|
|
get type() { return "newline"; }
|
2021-07-01 12:49:01 +05:30
|
|
|
isBlock() { return false; }
|
|
|
|
}
|
|
|
|
|
|
|
|
class EmphPart {
|
|
|
|
constructor(wraps) {
|
|
|
|
this.wraps = wraps;
|
|
|
|
}
|
|
|
|
|
|
|
|
get type() { return "emph"; }
|
|
|
|
isBlock() { return false; }
|
|
|
|
}
|
|
|
|
|
|
|
|
class CodePart {
|
|
|
|
constructor(wraps) {
|
|
|
|
this.wraps = wraps;
|
|
|
|
}
|
|
|
|
|
|
|
|
get type() { return "code"; }
|
|
|
|
isBlock() { return false; }
|
2021-05-17 14:56:30 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
class LinkPart {
|
|
|
|
constructor(url, text) {
|
|
|
|
this.url = url;
|
|
|
|
this.text = text;
|
|
|
|
}
|
|
|
|
|
|
|
|
get type() { return "link"; }
|
2021-07-01 12:49:01 +05:30
|
|
|
isBlock() { return false; }
|
2021-05-17 14:56:30 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
class TextPart {
|
|
|
|
constructor(text) {
|
|
|
|
this.text = text;
|
|
|
|
}
|
|
|
|
|
|
|
|
get type() { return "text"; }
|
2021-07-01 12:49:01 +05:30
|
|
|
isBlock() { return false; }
|
2021-05-17 14:56:30 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
class MessageBody {
|
|
|
|
constructor(sourceString, parts) {
|
2021-05-17 16:15:55 +05:30
|
|
|
this.sourceString = sourceString;
|
|
|
|
this.parts = parts;
|
2021-05-17 14:56:30 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function tests() {
|
|
|
|
|
|
|
|
function test(assert, input, output) {
|
|
|
|
assert.deepEqual(parsePlainBody(input), new MessageBody(input, output));
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
// Tests for text
|
|
|
|
"Text only": assert => {
|
|
|
|
const input = "This is a sentence";
|
|
|
|
const output = [new TextPart(input)];
|
|
|
|
test(assert, input, output);
|
|
|
|
},
|
|
|
|
|
|
|
|
"Text with newline": assert => {
|
|
|
|
const input = "This is a sentence.\nThis is another sentence.";
|
|
|
|
const output = [
|
|
|
|
new TextPart("This is a sentence."),
|
|
|
|
new NewLinePart(),
|
|
|
|
new TextPart("This is another sentence.")
|
|
|
|
];
|
|
|
|
test(assert, input, output);
|
|
|
|
},
|
|
|
|
|
|
|
|
"Text with newline & trailing newline": assert => {
|
|
|
|
const input = "This is a sentence.\nThis is another sentence.\n";
|
|
|
|
const output = [
|
|
|
|
new TextPart("This is a sentence."),
|
|
|
|
new NewLinePart(),
|
|
|
|
new TextPart("This is another sentence."),
|
|
|
|
new NewLinePart()
|
|
|
|
];
|
|
|
|
test(assert, input, output);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|