diff --git a/.env b/.env
index 508c5c4..cf10f3f 100644
--- a/.env
+++ b/.env
@@ -1,2 +1,2 @@
-REACT_APP_MICRO_APP_NAME=micro_app
+REACT_APP_MICRO_APP_NAME=simple_note
GENERATE_SOURCEMAP=false
diff --git a/package.json b/package.json
index 490ce65..eef3e27 100644
--- a/package.json
+++ b/package.json
@@ -55,7 +55,7 @@
"react-app-polyfill": "^1.0.6",
"react-dev-utils": "^10.2.1",
"react-dom": "^16.13.1",
- "react-light-state": "^0.0.12",
+ "react-light-state": "^0.0.15",
"react-router-dom": "^5.2.0",
"resolve": "1.15.0",
"resolve-url-loader": "3.1.1",
diff --git a/src/Root.tsx b/src/Root.tsx
index 990e287..6a8fa66 100644
--- a/src/Root.tsx
+++ b/src/Root.tsx
@@ -1,122 +1,43 @@
-import React, { useState } from "react";
+import React from "react";
import styled from "styled-components";
-import marked from "./marked/marked";
+import { BrowserRouter, Route, Switch } from "react-router-dom";
+import Editor from "./components/Editor";
+import Sidebar from "./components/Sidebar";
+import { useStore, notesSelector } from "./state";
export default function () {
- const [md, setMd] = useState("");
- const onInput = (e: any) => {
- const html = e.target.value;
- const plantText = html.replace(/\n\n/g, "\n").replace(/ /g, " ");
- setMd(plantText);
- };
+ const notes = useStore(notesSelector);
return (
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
-const Overflow = styled.div`
- overflow-y: auto;
- overflow-x: hidden;
- height: 500px;
- width: 500px;
- margin: auto;
-`;
-const Editor = styled.div`
- position: relative;
- width: 500px;
+const Layout = styled.div`
+ display: flex;
height: 100%;
- margin: auto;
- span {
- color: #ff572282;
- }
- code {
- background: #eee;
- border-radius: 5px;
- color: #f44336;
- margin: 0 -5px;
- padding: 0 5px;
- }
- pre {
- background: #eee;
- border-radius: 5px;
- }
- h1,
- h2,
- h3,
- h4,
- h5 {
- // display: inline;
- font-size: 16px;
- margin: 0;
- padding: 0;
- color: #f34d1a;
- span {
- color: #ff572282;
- }
- }
- ul {
- margin: 0;
- padding: 0;
- list-style: none;
- }
- li {
- div {
- display: inline;
- }
- color: #009688;
- }
- span.cb {
- color: #ccc;
- b {
- color: red;
- }
- }
+ background: #f9f9f9;
`;
-const Input = styled.textarea`
- border: none;
- position: absolute;
- background: transparent;
- outline: none;
- color: rgba(0, 0, 0, 0);
- caret-color: #000;
- caret-width: 3px;
- z-index: 10;
- left: 0;
- width: 100%;
- resize: none;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
+const Left = styled.div`
+ border-right: 1px solid #ececec;
+ width: 300px;
`;
-const Display = styled.div`
- position: relative;
- z-index: 9;
+const Right = styled.div`
+ padding: 20px;
+ height: 100%;
`;
diff --git a/src/components/Editor.tsx b/src/components/Editor.tsx
new file mode 100644
index 0000000..9cd30a8
--- /dev/null
+++ b/src/components/Editor.tsx
@@ -0,0 +1,123 @@
+import React, { useState, useEffect } from "react";
+import styled from "styled-components";
+import { useParams } from "react-router-dom";
+import { getContent, updateContent } from "../state";
+import marked from "../marked/marked";
+
+export default function () {
+ const [md, setMd] = useState("");
+ const params = useParams<{ id: string }>();
+ const id = params.id;
+ useEffect(() => {
+ const note = getContent(id);
+ setMd(note?.note || "");
+ }, [id]);
+
+ const onInput = (e: any) => {
+ const html = e.target.value;
+ const plantText = html.replace(/\n\n/g, "\n").replace(/ /g, " ");
+ setMd(plantText);
+ updateContent(id, plantText);
+ };
+ return (
+
+
+
+
+ );
+}
+
+const Editor = styled.div`
+ position: relative;
+ width: 100%;
+ min-width: 500px;
+ height: 100%;
+ margin: auto;
+ span {
+ color: #ff572282;
+ }
+ code {
+ background: #eee;
+ border-radius: 5px;
+ color: #f44336;
+ }
+ pre {
+ background: #eee;
+ border-radius: 5px;
+ margin: 0;
+ }
+ h1,
+ h2,
+ h3,
+ h4,
+ h5 {
+ // display: inline;
+ font-size: 16px;
+ margin: 0;
+ padding: 0;
+ color: #f34d1a;
+ span {
+ color: #ff572282;
+ }
+ }
+ ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ }
+ li {
+ div {
+ display: inline;
+ }
+ color: #009688;
+ }
+ span.cb {
+ color: #ccc;
+ b {
+ color: red;
+ }
+ }
+`;
+const Input = styled.textarea`
+ border: none;
+ position: absolute;
+ background: transparent;
+ outline: none;
+ color: transparent;
+ caret-color: #000;
+ caret-width: 3px;
+ z-index: 10;
+ left: 0;
+ width: 100%;
+ resize: none;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+`;
+const Display = styled.div`
+ border: 2px solid transparent;
+ position: relative;
+ z-index: 9;
+ width: 100%;
+ top: 0;
+ left: 0;
+`;
diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx
new file mode 100644
index 0000000..7704993
--- /dev/null
+++ b/src/components/Sidebar.tsx
@@ -0,0 +1,92 @@
+import React from "react";
+import styled from "styled-components";
+import { useHistory } from "react-router-dom";
+import { Link } from "react-router-dom";
+import { add, Note, deteteNote } from "../state";
+
+export default ({
+ notes,
+ onSelect = () => {},
+}: {
+ notes: Note[];
+ onSelect?: (_id: string) => void;
+}) => {
+ const history = useHistory();
+ return (
+
+
{
+ const id = add();
+ setTimeout(() => {
+ history.push("/" + id);
+ }, 100);
+ }}
+ >
+ New
+
+ {notes.map((note) => (
+
-
+ {note.title}
+ {
+ if (window.confirm("Are you sure")) {
+ deteteNote(note._id!);
+ }
+ }}
+ >
+
+
+
+ ))}
+
+ );
+};
+
+const ButtonNew = styled.div`
+ display: block;
+ font-weight: 600;
+ color: #000;
+ text-decoration: none;
+ font-size: 12px;
+ background: #f6f6f6;
+ cursor: pointer;
+ text-align: center;
+ padding: 5px;
+`;
+const Item = styled(Link)`
+ padding: 10px;
+ font-family: consolas;
+ display: block;
+ text-decoration: none;
+ color: #555;
+ cursor: pointer;
+ border-top: 1px solid #ececec;
+ display: flex;
+ justify-content: space-between;
+ :last-of-type {
+ border-bottom: 1px solid #ececec;
+ }
+ :hover {
+ background: #f5f5f5;
+ }
+`;
+const X = styled.div`
+ border-radius: 5px;
+ font-size: 18px;
+ opacity: 0.3;
+ :hover {
+ opacity: 1;
+ color: #000;
+ background: #ccc;
+ }
+`;
diff --git a/src/index.tsx b/src/index.tsx
index 735ade0..0b8ab68 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -15,6 +15,7 @@ if (process.env.NODE_ENV !== "production") {
(function (AppManager) {
AppManager.register({
appId: process.env.REACT_APP_MICRO_APP_NAME,
+ root: true,
renderRoot: (elementId: string) => {
ReactDOM.render(, document.getElementById(elementId));
},
diff --git a/src/marked/Lexer.js b/src/marked/Lexer.js
index d34aa47..e79d09e 100644
--- a/src/marked/Lexer.js
+++ b/src/marked/Lexer.js
@@ -1,491 +1,577 @@
-const Tokenizer = require('./Tokenizer.js');
-const { defaults } = require('./defaults.js');
-const { block, inline } = require('./rules.js');
-const { repeatString } = require('./helpers.js');
+import Tokenizer from "./Tokenizer";
+import { defaults } from "./defaults.js";
+import { block, inline } from "./rules.js";
+import { repeatString } from "./helpers.js";
/**
* smartypants text replacement
*/
function smartypants(text) {
- return text
- // em-dashes
- .replace(/---/g, '\u2014')
- // en-dashes
- .replace(/--/g, '\u2013')
- // opening singles
- .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
- // closing singles & apostrophes
- .replace(/'/g, '\u2019')
- // opening doubles
- .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
- // closing doubles
- .replace(/"/g, '\u201d')
- // ellipses
- .replace(/\.{3}/g, '\u2026');
+ return (
+ text
+ // em-dashes
+ .replace(/---/g, "\u2014")
+ // en-dashes
+ .replace(/--/g, "\u2013")
+ // opening singles
+ .replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018")
+ // closing singles & apostrophes
+ .replace(/'/g, "\u2019")
+ // opening doubles
+ .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201c")
+ // closing doubles
+ .replace(/"/g, "\u201d")
+ // ellipses
+ .replace(/\.{3}/g, "\u2026")
+ );
}
/**
* mangle email addresses
*/
function mangle(text) {
- let out = '',
- i,
- ch;
-
- const l = text.length;
- for (i = 0; i < l; i++) {
- ch = text.charCodeAt(i);
- if (Math.random() > 0.5) {
- ch = 'x' + ch.toString(16);
+ let out = "",
+ i,
+ ch;
+
+ const l = text.length;
+ for (i = 0; i < l; i++) {
+ ch = text.charCodeAt(i);
+ if (Math.random() > 0.5) {
+ ch = "x" + ch.toString(16);
+ }
+ out += "" + ch + ";";
}
- out += '' + ch + ';';
- }
- return out;
+ return out;
}
/**
* Block Lexer
*/
-module.exports = class Lexer {
- constructor(options) {
- this.tokens = [];
- this.tokens.links = Object.create(null);
- this.options = options || defaults;
- this.options.tokenizer = this.options.tokenizer || new Tokenizer();
- this.tokenizer = this.options.tokenizer;
- this.tokenizer.options = this.options;
- this.tokenizer.lexer = this;
- this.inlineQueue = [];
- this.state = {
- inLink: false,
- inRawBlock: false,
- top: true
- };
-
- const rules = {
- block: block.normal,
- inline: inline.normal
- };
-
- if (this.options.pedantic) {
- rules.block = block.pedantic;
- rules.inline = inline.pedantic;
- } else if (this.options.gfm) {
- rules.block = block.gfm;
- if (this.options.breaks) {
- rules.inline = inline.breaks;
- } else {
- rules.inline = inline.gfm;
- }
+export default class Lexer {
+ constructor(options) {
+ this.tokens = [];
+ this.tokens.links = Object.create(null);
+ this.options = options || defaults;
+ this.options.tokenizer = this.options.tokenizer || new Tokenizer();
+ this.tokenizer = this.options.tokenizer;
+ this.tokenizer.options = this.options;
+ this.tokenizer.lexer = this;
+ this.inlineQueue = [];
+ this.state = {
+ inLink: false,
+ inRawBlock: false,
+ top: true,
+ };
+
+ const rules = {
+ block: block.normal,
+ inline: inline.normal,
+ };
+
+ if (this.options.pedantic) {
+ rules.block = block.pedantic;
+ rules.inline = inline.pedantic;
+ } else if (this.options.gfm) {
+ rules.block = block.gfm;
+ if (this.options.breaks) {
+ rules.inline = inline.breaks;
+ } else {
+ rules.inline = inline.gfm;
+ }
+ }
+ this.tokenizer.rules = rules;
}
- this.tokenizer.rules = rules;
- }
-
- /**
- * Expose Rules
- */
- static get rules() {
- return {
- block,
- inline
- };
- }
-
- /**
- * Static Lex Method
- */
- static lex(src, options) {
- const lexer = new Lexer(options);
- return lexer.lex(src);
- }
-
- /**
- * Static Lex Inline Method
- */
- static lexInline(src, options) {
- const lexer = new Lexer(options);
- return lexer.inlineTokens(src);
- }
-
- /**
- * Preprocessing
- */
- lex(src) {
- src = src
- .replace(/\r\n|\r/g, '\n')
- .replace(/\t/g, ' ');
-
- this.blockTokens(src, this.tokens);
-
- let next;
- while (next = this.inlineQueue.shift()) {
- this.inlineTokens(next.src, next.tokens);
+
+ /**
+ * Expose Rules
+ */
+ static get rules() {
+ return {
+ block,
+ inline,
+ };
}
- return this.tokens;
- }
+ /**
+ * Static Lex Method
+ */
+ static lex(src, options) {
+ const lexer = new Lexer(options);
+ return lexer.lex(src);
+ }
- /**
- * Lexing
- */
- blockTokens(src, tokens = []) {
- if (this.options.pedantic) {
- src = src.replace(/^ +$/gm, '');
+ /**
+ * Static Lex Inline Method
+ */
+ static lexInline(src, options) {
+ const lexer = new Lexer(options);
+ return lexer.inlineTokens(src);
}
- let token, lastToken, cutSrc, lastParagraphClipped;
-
- while (src) {
- if (this.options.extensions
- && this.options.extensions.block
- && this.options.extensions.block.some((extTokenizer) => {
- if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- return true;
- }
- return false;
- })) {
- continue;
- }
-
- // newline
- if (token = this.tokenizer.space(src)) {
- src = src.substring(token.raw.length);
- if (token.type) {
- tokens.push(token);
- }
- continue;
- }
-
- // code
- if (token = this.tokenizer.code(src)) {
- src = src.substring(token.raw.length);
- lastToken = tokens[tokens.length - 1];
- // An indented code block cannot interrupt a paragraph.
- if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
- lastToken.raw += '\n' + token.raw;
- lastToken.text += '\n' + token.text;
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
- } else {
- tokens.push(token);
- }
- continue;
- }
-
- // fences
- if (token = this.tokenizer.fences(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // heading
- if (token = this.tokenizer.heading(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // hr
- if (token = this.tokenizer.hr(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // blockquote
- if (token = this.tokenizer.blockquote(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // list
- if (token = this.tokenizer.list(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // html
- if (token = this.tokenizer.html(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // def
- if (token = this.tokenizer.def(src)) {
- src = src.substring(token.raw.length);
- lastToken = tokens[tokens.length - 1];
- if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
- lastToken.raw += '\n' + token.raw;
- lastToken.text += '\n' + token.raw;
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
- } else if (!this.tokens.links[token.tag]) {
- this.tokens.links[token.tag] = {
- href: token.href,
- title: token.title
- };
- }
- continue;
- }
-
- // table (gfm)
- if (token = this.tokenizer.table(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // lheading
- if (token = this.tokenizer.lheading(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // top-level paragraph
- // prevent paragraph consuming extensions by clipping 'src' to extension start
- cutSrc = src;
- if (this.options.extensions && this.options.extensions.startBlock) {
- let startIndex = Infinity;
- const tempSrc = src.slice(1);
- let tempStart;
- this.options.extensions.startBlock.forEach(function(getStartIndex) {
- tempStart = getStartIndex.call({ lexer: this }, tempSrc);
- if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); }
- });
- if (startIndex < Infinity && startIndex >= 0) {
- cutSrc = src.substring(0, startIndex + 1);
- }
- }
- if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
- lastToken = tokens[tokens.length - 1];
- if (lastParagraphClipped && lastToken.type === 'paragraph') {
- lastToken.raw += '\n' + token.raw;
- lastToken.text += '\n' + token.text;
- this.inlineQueue.pop();
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
- } else {
- tokens.push(token);
- }
- lastParagraphClipped = (cutSrc.length !== src.length);
- src = src.substring(token.raw.length);
- continue;
- }
-
- // text
- if (token = this.tokenizer.text(src)) {
- src = src.substring(token.raw.length);
- lastToken = tokens[tokens.length - 1];
- if (lastToken && lastToken.type === 'text') {
- lastToken.raw += '\n' + token.raw;
- lastToken.text += '\n' + token.text;
- this.inlineQueue.pop();
- this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
- } else {
- tokens.push(token);
- }
- continue;
- }
-
- if (src) {
- const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
- if (this.options.silent) {
- console.error(errMsg);
- break;
- } else {
- throw new Error(errMsg);
+
+ /**
+ * Preprocessing
+ */
+ lex(src) {
+ src = src.replace(/\r\n|\r/g, "\n").replace(/\t/g, " ");
+
+ this.blockTokens(src, this.tokens);
+
+ let next;
+ while ((next = this.inlineQueue.shift())) {
+ this.inlineTokens(next.src, next.tokens);
}
- }
+
+ return this.tokens;
}
- this.state.top = true;
- return tokens;
- }
-
- inline(src, tokens) {
- this.inlineQueue.push({ src, tokens });
- }
-
- /**
- * Lexing/Compiling
- */
- inlineTokens(src, tokens = []) {
- let token, lastToken, cutSrc;
-
- // String with links masked to avoid interference with em and strong
- let maskedSrc = src;
- let match;
- let keepPrevChar, prevChar;
-
- // Mask out reflinks
- if (this.tokens.links) {
- const links = Object.keys(this.tokens.links);
- if (links.length > 0) {
- while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
- if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
- maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
- }
+ /**
+ * Lexing
+ */
+ blockTokens(src, tokens = []) {
+ if (this.options.pedantic) {
+ src = src.replace(/^ +$/gm, "");
}
- }
- }
- // Mask out other blocks
- while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
- maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
+ let token, lastToken, cutSrc, lastParagraphClipped;
+
+ while (src) {
+ if (
+ this.options.extensions &&
+ this.options.extensions.block &&
+ this.options.extensions.block.some((extTokenizer) => {
+ if (
+ (token = extTokenizer.call(
+ { lexer: this },
+ src,
+ tokens
+ ))
+ ) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ return true;
+ }
+ return false;
+ })
+ ) {
+ continue;
+ }
+
+ // newline
+ if ((token = this.tokenizer.space(src))) {
+ src = src.substring(token.raw.length);
+ if (token.type) {
+ tokens.push(token);
+ }
+ continue;
+ }
+
+ // code
+ if ((token = this.tokenizer.code(src))) {
+ src = src.substring(token.raw.length);
+ lastToken = tokens[tokens.length - 1];
+ // An indented code block cannot interrupt a paragraph.
+ if (
+ lastToken &&
+ (lastToken.type === "paragraph" ||
+ lastToken.type === "text")
+ ) {
+ lastToken.raw += "\n" + token.raw;
+ lastToken.text += "\n" + token.text;
+ this.inlineQueue[this.inlineQueue.length - 1].src =
+ lastToken.text;
+ } else {
+ tokens.push(token);
+ }
+ continue;
+ }
+
+ // fences
+ if ((token = this.tokenizer.fences(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // heading
+ if ((token = this.tokenizer.heading(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // hr
+ if ((token = this.tokenizer.hr(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // blockquote
+ if ((token = this.tokenizer.blockquote(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // list
+ if ((token = this.tokenizer.list(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // html
+ if ((token = this.tokenizer.html(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // def
+ if ((token = this.tokenizer.def(src))) {
+ src = src.substring(token.raw.length);
+ lastToken = tokens[tokens.length - 1];
+ if (
+ lastToken &&
+ (lastToken.type === "paragraph" ||
+ lastToken.type === "text")
+ ) {
+ lastToken.raw += "\n" + token.raw;
+ lastToken.text += "\n" + token.raw;
+ this.inlineQueue[this.inlineQueue.length - 1].src =
+ lastToken.text;
+ } else if (!this.tokens.links[token.tag]) {
+ this.tokens.links[token.tag] = {
+ href: token.href,
+ title: token.title,
+ };
+ }
+ continue;
+ }
+
+ // table (gfm)
+ if ((token = this.tokenizer.table(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // lheading
+ if ((token = this.tokenizer.lheading(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // top-level paragraph
+ // prevent paragraph consuming extensions by clipping 'src' to extension start
+ cutSrc = src;
+ if (this.options.extensions && this.options.extensions.startBlock) {
+ let startIndex = Infinity;
+ const tempSrc = src.slice(1);
+ let tempStart;
+ this.options.extensions.startBlock.forEach(function (
+ getStartIndex
+ ) {
+ tempStart = getStartIndex.call({ lexer: this }, tempSrc);
+ if (typeof tempStart === "number" && tempStart >= 0) {
+ startIndex = Math.min(startIndex, tempStart);
+ }
+ });
+ if (startIndex < Infinity && startIndex >= 0) {
+ cutSrc = src.substring(0, startIndex + 1);
+ }
+ }
+ if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
+ lastToken = tokens[tokens.length - 1];
+ if (lastParagraphClipped && lastToken.type === "paragraph") {
+ lastToken.raw += "\n" + token.raw;
+ lastToken.text += "\n" + token.text;
+ this.inlineQueue.pop();
+ this.inlineQueue[this.inlineQueue.length - 1].src =
+ lastToken.text;
+ } else {
+ tokens.push(token);
+ }
+ lastParagraphClipped = cutSrc.length !== src.length;
+ src = src.substring(token.raw.length);
+ continue;
+ }
+
+ // text
+ if ((token = this.tokenizer.text(src))) {
+ src = src.substring(token.raw.length);
+ lastToken = tokens[tokens.length - 1];
+ if (lastToken && lastToken.type === "text") {
+ lastToken.raw += "\n" + token.raw;
+ lastToken.text += "\n" + token.text;
+ this.inlineQueue.pop();
+ this.inlineQueue[this.inlineQueue.length - 1].src =
+ lastToken.text;
+ } else {
+ tokens.push(token);
+ }
+ continue;
+ }
+
+ if (src) {
+ const errMsg = "Infinite loop on byte: " + src.charCodeAt(0);
+ if (this.options.silent) {
+ console.error(errMsg);
+ break;
+ } else {
+ throw new Error(errMsg);
+ }
+ }
+ }
+
+ this.state.top = true;
+ return tokens;
}
- // Mask out escaped em & strong delimiters
- while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) {
- maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);
+ inline(src, tokens) {
+ this.inlineQueue.push({ src, tokens });
}
- while (src) {
- if (!keepPrevChar) {
- prevChar = '';
- }
- keepPrevChar = false;
-
- // extensions
- if (this.options.extensions
- && this.options.extensions.inline
- && this.options.extensions.inline.some((extTokenizer) => {
- if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- return true;
- }
- return false;
- })) {
- continue;
- }
-
- // escape
- if (token = this.tokenizer.escape(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // tag
- if (token = this.tokenizer.tag(src)) {
- src = src.substring(token.raw.length);
- lastToken = tokens[tokens.length - 1];
- if (lastToken && token.type === 'text' && lastToken.type === 'text') {
- lastToken.raw += token.raw;
- lastToken.text += token.text;
- } else {
- tokens.push(token);
- }
- continue;
- }
-
- // link
- if (token = this.tokenizer.link(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // reflink, nolink
- if (token = this.tokenizer.reflink(src, this.tokens.links)) {
- src = src.substring(token.raw.length);
- lastToken = tokens[tokens.length - 1];
- if (lastToken && token.type === 'text' && lastToken.type === 'text') {
- lastToken.raw += token.raw;
- lastToken.text += token.text;
- } else {
- tokens.push(token);
+ /**
+ * Lexing/Compiling
+ */
+ inlineTokens(src, tokens = []) {
+ let token, lastToken, cutSrc;
+
+ // String with links masked to avoid interference with em and strong
+ let maskedSrc = src;
+ let match;
+ let keepPrevChar, prevChar;
+
+ // Mask out reflinks
+ if (this.tokens.links) {
+ const links = Object.keys(this.tokens.links);
+ if (links.length > 0) {
+ while (
+ (match =
+ this.tokenizer.rules.inline.reflinkSearch.exec(
+ maskedSrc
+ )) != null
+ ) {
+ if (
+ links.includes(
+ match[0].slice(match[0].lastIndexOf("[") + 1, -1)
+ )
+ ) {
+ maskedSrc =
+ maskedSrc.slice(0, match.index) +
+ "[" +
+ repeatString("a", match[0].length - 2) +
+ "]" +
+ maskedSrc.slice(
+ this.tokenizer.rules.inline.reflinkSearch
+ .lastIndex
+ );
+ }
+ }
+ }
}
- continue;
- }
-
- // em & strong
- if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // code
- if (token = this.tokenizer.codespan(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // br
- if (token = this.tokenizer.br(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // del (gfm)
- if (token = this.tokenizer.del(src)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // autolink
- if (token = this.tokenizer.autolink(src, mangle)) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // url (gfm)
- if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
- src = src.substring(token.raw.length);
- tokens.push(token);
- continue;
- }
-
- // text
- // prevent inlineText consuming extensions by clipping 'src' to extension start
- cutSrc = src;
- if (this.options.extensions && this.options.extensions.startInline) {
- let startIndex = Infinity;
- const tempSrc = src.slice(1);
- let tempStart;
- this.options.extensions.startInline.forEach(function(getStartIndex) {
- tempStart = getStartIndex.call({ lexer: this }, tempSrc);
- if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); }
- });
- if (startIndex < Infinity && startIndex >= 0) {
- cutSrc = src.substring(0, startIndex + 1);
+ // Mask out other blocks
+ while (
+ (match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) !=
+ null
+ ) {
+ maskedSrc =
+ maskedSrc.slice(0, match.index) +
+ "[" +
+ repeatString("a", match[0].length - 2) +
+ "]" +
+ maskedSrc.slice(
+ this.tokenizer.rules.inline.blockSkip.lastIndex
+ );
}
- }
- if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
- src = src.substring(token.raw.length);
- if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started
- prevChar = token.raw.slice(-1);
- }
- keepPrevChar = true;
- lastToken = tokens[tokens.length - 1];
- if (lastToken && lastToken.type === 'text') {
- lastToken.raw += token.raw;
- lastToken.text += token.text;
- } else {
- tokens.push(token);
+
+ // Mask out escaped em & strong delimiters
+ while (
+ (match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) !=
+ null
+ ) {
+ maskedSrc =
+ maskedSrc.slice(0, match.index) +
+ "++" +
+ maskedSrc.slice(
+ this.tokenizer.rules.inline.escapedEmSt.lastIndex
+ );
}
- continue;
- }
-
- if (src) {
- const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
- if (this.options.silent) {
- console.error(errMsg);
- break;
- } else {
- throw new Error(errMsg);
+
+ while (src) {
+ if (!keepPrevChar) {
+ prevChar = "";
+ }
+ keepPrevChar = false;
+
+ // extensions
+ if (
+ this.options.extensions &&
+ this.options.extensions.inline &&
+ this.options.extensions.inline.some((extTokenizer) => {
+ if (
+ (token = extTokenizer.call(
+ { lexer: this },
+ src,
+ tokens
+ ))
+ ) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ return true;
+ }
+ return false;
+ })
+ ) {
+ continue;
+ }
+
+ // escape
+ if ((token = this.tokenizer.escape(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // tag
+ if ((token = this.tokenizer.tag(src))) {
+ src = src.substring(token.raw.length);
+ lastToken = tokens[tokens.length - 1];
+ if (
+ lastToken &&
+ token.type === "text" &&
+ lastToken.type === "text"
+ ) {
+ lastToken.raw += token.raw;
+ lastToken.text += token.text;
+ } else {
+ tokens.push(token);
+ }
+ continue;
+ }
+
+ // link
+ if ((token = this.tokenizer.link(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // reflink, nolink
+ if ((token = this.tokenizer.reflink(src, this.tokens.links))) {
+ src = src.substring(token.raw.length);
+ lastToken = tokens[tokens.length - 1];
+ if (
+ lastToken &&
+ token.type === "text" &&
+ lastToken.type === "text"
+ ) {
+ lastToken.raw += token.raw;
+ lastToken.text += token.text;
+ } else {
+ tokens.push(token);
+ }
+ continue;
+ }
+
+ // em & strong
+ if ((token = this.tokenizer.emStrong(src, maskedSrc, prevChar))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // code
+ if ((token = this.tokenizer.codespan(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // br
+ if ((token = this.tokenizer.br(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // del (gfm)
+ if ((token = this.tokenizer.del(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // autolink
+ if ((token = this.tokenizer.autolink(src, mangle))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // url (gfm)
+ if (
+ !this.state.inLink &&
+ (token = this.tokenizer.url(src, mangle))
+ ) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+
+ // text
+ // prevent inlineText consuming extensions by clipping 'src' to extension start
+ cutSrc = src;
+ if (
+ this.options.extensions &&
+ this.options.extensions.startInline
+ ) {
+ let startIndex = Infinity;
+ const tempSrc = src.slice(1);
+ let tempStart;
+ this.options.extensions.startInline.forEach(function (
+ getStartIndex
+ ) {
+ tempStart = getStartIndex.call({ lexer: this }, tempSrc);
+ if (typeof tempStart === "number" && tempStart >= 0) {
+ startIndex = Math.min(startIndex, tempStart);
+ }
+ });
+ if (startIndex < Infinity && startIndex >= 0) {
+ cutSrc = src.substring(0, startIndex + 1);
+ }
+ }
+ if ((token = this.tokenizer.inlineText(cutSrc, smartypants))) {
+ src = src.substring(token.raw.length);
+ if (token.raw.slice(-1) !== "_") {
+ // Track prevChar before string of ____ started
+ prevChar = token.raw.slice(-1);
+ }
+ keepPrevChar = true;
+ lastToken = tokens[tokens.length - 1];
+ if (lastToken && lastToken.type === "text") {
+ lastToken.raw += token.raw;
+ lastToken.text += token.text;
+ } else {
+ tokens.push(token);
+ }
+ continue;
+ }
+
+ if (src) {
+ const errMsg = "Infinite loop on byte: " + src.charCodeAt(0);
+ if (this.options.silent) {
+ console.error(errMsg);
+ break;
+ } else {
+ throw new Error(errMsg);
+ }
+ }
}
- }
- }
- return tokens;
- }
-};
+ return tokens;
+ }
+}
diff --git a/src/marked/Parser.js b/src/marked/Parser.js
index a7519f9..3e1c9b7 100644
--- a/src/marked/Parser.js
+++ b/src/marked/Parser.js
@@ -1,286 +1,362 @@
-const Renderer = require('./Renderer.js');
-const TextRenderer = require('./TextRenderer.js');
-const Slugger = require('./Slugger.js');
-const { defaults } = require('./defaults.js');
-const {
- unescape
-} = require('./helpers.js');
+import Renderer from "./Renderer";
+import { defaults } from "./defaults";
+import { unescape } from "./helpers";
+import TextRenderer from "./TextRenderer";
+import Slugger from "./Slugger";
/**
* Parsing & Compiling
*/
-module.exports = class Parser {
- constructor(options) {
- this.options = options || defaults;
- this.options.renderer = this.options.renderer || new Renderer();
- this.renderer = this.options.renderer;
- this.renderer.options = this.options;
- this.textRenderer = new TextRenderer();
- this.slugger = new Slugger();
- }
+export default class Parser {
+ constructor(options) {
+ this.options = options || defaults;
+ this.options.renderer = this.options.renderer || new Renderer();
+ this.renderer = this.options.renderer;
+ this.renderer.options = this.options;
+ this.textRenderer = new TextRenderer();
+ this.slugger = new Slugger();
+ }
- /**
- * Static Parse Method
- */
- static parse(tokens, options) {
- const parser = new Parser(options);
- return parser.parse(tokens);
- }
+ /**
+ * Static Parse Method
+ */
+ static parse(tokens, options) {
+ const parser = new Parser(options);
+ return parser.parse(tokens);
+ }
- /**
- * Static Parse Inline Method
- */
- static parseInline(tokens, options) {
- const parser = new Parser(options);
- return parser.parseInline(tokens);
- }
+ /**
+ * Static Parse Inline Method
+ */
+ static parseInline(tokens, options) {
+ const parser = new Parser(options);
+ return parser.parseInline(tokens);
+ }
- /**
- * Parse Loop
- */
- parse(tokens, top = true) {
- let out = '',
- i,
- j,
- k,
- l2,
- l3,
- row,
- cell,
- header,
- body,
- token,
- ordered,
- start,
- loose,
- itemBody,
- item,
- checked,
- task,
- checkbox,
- ret;
+ /**
+ * Parse Loop
+ */
+ parse(tokens, top = true) {
+ let out = "",
+ i,
+ j,
+ k,
+ l2,
+ l3,
+ row,
+ cell,
+ header,
+ body,
+ token,
+ ordered,
+ start,
+ loose,
+ itemBody,
+ item,
+ checked,
+ task,
+ checkbox,
+ ret;
- const l = tokens.length;
- for (i = 0; i < l; i++) {
- token = tokens[i];
+ const l = tokens.length;
+ for (i = 0; i < l; i++) {
+ token = tokens[i];
- // Run any renderer extensions
- if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
- ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
- if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
- out += ret || '';
- continue;
- }
- }
+ // Run any renderer extensions
+ if (
+ this.options.extensions &&
+ this.options.extensions.renderers &&
+ this.options.extensions.renderers[token.type]
+ ) {
+ ret = this.options.extensions.renderers[token.type].call(
+ { parser: this },
+ token
+ );
+ if (
+ ret !== false ||
+ ![
+ "space",
+ "hr",
+ "heading",
+ "code",
+ "table",
+ "blockquote",
+ "list",
+ "html",
+ "paragraph",
+ "text",
+ ].includes(token.type)
+ ) {
+ out += ret || "";
+ continue;
+ }
+ }
- switch (token.type) {
- case 'space': {
- continue;
- }
- case 'hr': {
- out += this.renderer.hr();
- continue;
- }
- case 'heading': {
- out += this.renderer.heading(
- this.parseInline(token.tokens),
- token.depth,
- unescape(this.parseInline(token.tokens, this.textRenderer)),
- this.slugger);
- continue;
- }
- case 'code': {
- out += this.renderer.code(token.text,
- token.lang,
- token.escaped);
- continue;
- }
- case 'table': {
- header = '';
+ switch (token.type) {
+ case "space": {
+ continue;
+ }
+ case "hr": {
+ out += this.renderer.hr();
+ continue;
+ }
+ case "heading": {
+ out += this.renderer.heading(
+ this.parseInline(token.tokens),
+ token.depth,
+ unescape(
+ this.parseInline(token.tokens, this.textRenderer)
+ ),
+ this.slugger
+ );
+ continue;
+ }
+ case "code": {
+ out += this.renderer.code(
+ token.text,
+ token.lang,
+ token.escaped
+ );
+ continue;
+ }
+ case "table": {
+ header = "";
- // header
- cell = '';
- l2 = token.header.length;
- for (j = 0; j < l2; j++) {
- cell += this.renderer.tablecell(
- this.parseInline(token.header[j].tokens),
- { header: true, align: token.align[j] }
- );
- }
- header += this.renderer.tablerow(cell);
+ // header
+ cell = "";
+ l2 = token.header.length;
+ for (j = 0; j < l2; j++) {
+ cell += this.renderer.tablecell(
+ this.parseInline(token.header[j].tokens),
+ { header: true, align: token.align[j] }
+ );
+ }
+ header += this.renderer.tablerow(cell);
- body = '';
- l2 = token.rows.length;
- for (j = 0; j < l2; j++) {
- row = token.rows[j];
+ body = "";
+ l2 = token.rows.length;
+ for (j = 0; j < l2; j++) {
+ row = token.rows[j];
- cell = '';
- l3 = row.length;
- for (k = 0; k < l3; k++) {
- cell += this.renderer.tablecell(
- this.parseInline(row[k].tokens),
- { header: false, align: token.align[k] }
- );
- }
+ cell = "";
+ l3 = row.length;
+ for (k = 0; k < l3; k++) {
+ cell += this.renderer.tablecell(
+ this.parseInline(row[k].tokens),
+ { header: false, align: token.align[k] }
+ );
+ }
- body += this.renderer.tablerow(cell);
- }
- out += this.renderer.table(header, body);
- continue;
- }
- case 'blockquote': {
- body = this.parse(token.tokens);
- out += this.renderer.blockquote(body);
- continue;
- }
- case 'list': {
- ordered = token.ordered;
- start = token.start;
- loose = token.loose;
- l2 = token.items.length;
+ body += this.renderer.tablerow(cell);
+ }
+ out += this.renderer.table(header, body);
+ continue;
+ }
+ case "blockquote": {
+ body = this.parse(token.tokens);
+ out += this.renderer.blockquote(body);
+ continue;
+ }
+ case "list": {
+ ordered = token.ordered;
+ start = token.start;
+ loose = token.loose;
+ l2 = token.items.length;
- body = '';
- for (j = 0; j < l2; j++) {
- item = token.items[j];
- checked = item.checked;
- task = item.task;
+ body = "";
+ for (j = 0; j < l2; j++) {
+ item = token.items[j];
+ checked = item.checked;
+ task = item.task;
- itemBody = '';
- if (item.task) {
- checkbox = this.renderer.checkbox(checked);
- if (loose) {
- if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
- item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
- if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
- item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
- }
- } else {
- item.tokens.unshift({
- type: 'text',
- text: checkbox
- });
- }
- } else {
- itemBody += checkbox;
- }
- }
+ itemBody = "";
+ if (item.task) {
+ checkbox = this.renderer.checkbox(checked);
+ if (loose) {
+ if (
+ item.tokens.length > 0 &&
+ item.tokens[0].type === "paragraph"
+ ) {
+ item.tokens[0].text =
+ checkbox + " " + item.tokens[0].text;
+ if (
+ item.tokens[0].tokens &&
+ item.tokens[0].tokens.length > 0 &&
+ item.tokens[0].tokens[0].type === "text"
+ ) {
+ item.tokens[0].tokens[0].text =
+ checkbox +
+ " " +
+ item.tokens[0].tokens[0].text;
+ }
+ } else {
+ item.tokens.unshift({
+ type: "text",
+ text: checkbox,
+ });
+ }
+ } else {
+ itemBody += checkbox;
+ }
+ }
- itemBody += this.parse(item.tokens, loose);
- body += this.renderer.listitem(itemBody, task, checked);
- }
+ itemBody += this.parse(item.tokens, loose);
+ body += this.renderer.listitem(itemBody, task, checked);
+ }
- out += this.renderer.list(body, ordered, start);
- continue;
- }
- case 'html': {
- // TODO parse inline content if parameter markdown=1
- out += this.renderer.html(token.text);
- continue;
- }
- case 'paragraph': {
- out += this.renderer.paragraph(this.parseInline(token.tokens));
- continue;
- }
- case 'text': {
- body = token.tokens ? this.parseInline(token.tokens) : token.text;
- while (i + 1 < l && tokens[i + 1].type === 'text') {
- token = tokens[++i];
- body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
- }
- out += top ? this.renderer.paragraph(body) : body;
- continue;
- }
+ out += this.renderer.list(body, ordered, start);
+ continue;
+ }
+ case "html": {
+ // TODO parse inline content if parameter markdown=1
+ out += this.renderer.html(token.text);
+ continue;
+ }
+ case "paragraph": {
+ out += this.renderer.paragraph(
+ this.parseInline(token.tokens)
+ );
+ continue;
+ }
+ case "text": {
+ body = token.tokens
+ ? this.parseInline(token.tokens)
+ : token.text;
+ while (i + 1 < l && tokens[i + 1].type === "text") {
+ token = tokens[++i];
+ body +=
+ "\n" +
+ (token.tokens
+ ? this.parseInline(token.tokens)
+ : token.text);
+ }
+ out += top ? this.renderer.paragraph(body) : body;
+ continue;
+ }
- default: {
- const errMsg = 'Token with "' + token.type + '" type was not found.';
- if (this.options.silent) {
- console.error(errMsg);
- return;
- } else {
- throw new Error(errMsg);
- }
+ default: {
+ const errMsg =
+ 'Token with "' + token.type + '" type was not found.';
+ if (this.options.silent) {
+ console.error(errMsg);
+ return;
+ } else {
+ throw new Error(errMsg);
+ }
+ }
+ }
}
- }
- }
- return out;
- }
+ return out;
+ }
- /**
- * Parse Inline Tokens
- */
- parseInline(tokens, renderer) {
- renderer = renderer || this.renderer;
- let out = '',
- i,
- token,
- ret;
+ /**
+ * Parse Inline Tokens
+ */
+ parseInline(tokens, renderer) {
+ renderer = renderer || this.renderer;
+ let out = "",
+ i,
+ token,
+ ret;
- const l = tokens.length;
- for (i = 0; i < l; i++) {
- token = tokens[i];
+ const l = tokens.length;
+ for (i = 0; i < l; i++) {
+ token = tokens[i];
- // Run any renderer extensions
- if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
- ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
- if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
- out += ret || '';
- continue;
- }
- }
+ // Run any renderer extensions
+ if (
+ this.options.extensions &&
+ this.options.extensions.renderers &&
+ this.options.extensions.renderers[token.type]
+ ) {
+ ret = this.options.extensions.renderers[token.type].call(
+ { parser: this },
+ token
+ );
+ if (
+ ret !== false ||
+ ![
+ "escape",
+ "html",
+ "link",
+ "image",
+ "strong",
+ "em",
+ "codespan",
+ "br",
+ "del",
+ "text",
+ ].includes(token.type)
+ ) {
+ out += ret || "";
+ continue;
+ }
+ }
- switch (token.type) {
- case 'escape': {
- out += renderer.text(token.text);
- break;
- }
- case 'html': {
- out += renderer.html(token.text);
- break;
- }
- case 'link': {
- out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
- break;
- }
- case 'image': {
- out += renderer.image(token.href, token.title, token.text);
- break;
- }
- case 'strong': {
- out += renderer.strong(this.parseInline(token.tokens, renderer));
- break;
- }
- case 'em': {
- out += renderer.em(this.parseInline(token.tokens, renderer));
- break;
- }
- case 'codespan': {
- out += renderer.codespan(token.text);
- break;
- }
- case 'br': {
- out += renderer.br();
- break;
- }
- case 'del': {
- out += renderer.del(this.parseInline(token.tokens, renderer));
- break;
- }
- case 'text': {
- out += renderer.text(token.text);
- break;
- }
- default: {
- const errMsg = 'Token with "' + token.type + '" type was not found.';
- if (this.options.silent) {
- console.error(errMsg);
- return;
- } else {
- throw new Error(errMsg);
- }
+ switch (token.type) {
+ case "escape": {
+ out += renderer.text(token.text);
+ break;
+ }
+ case "html": {
+ out += renderer.html(token.text);
+ break;
+ }
+ case "link": {
+ out += renderer.link(
+ token.href,
+ token.title,
+ this.parseInline(token.tokens, renderer)
+ );
+ break;
+ }
+ case "image": {
+ out += renderer.image(token.href, token.title, token.text);
+ break;
+ }
+ case "strong": {
+ out += renderer.strong(
+ this.parseInline(token.tokens, renderer)
+ );
+ break;
+ }
+ case "em": {
+ out += renderer.em(
+ this.parseInline(token.tokens, renderer)
+ );
+ break;
+ }
+ case "codespan": {
+ out += renderer.codespan(token.text);
+ break;
+ }
+ case "br": {
+ out += renderer.br();
+ break;
+ }
+ case "del": {
+ out += renderer.del(
+ this.parseInline(token.tokens, renderer)
+ );
+ break;
+ }
+ case "text": {
+ out += renderer.text(token.text);
+ break;
+ }
+ default: {
+ const errMsg =
+ 'Token with "' + token.type + '" type was not found.';
+ if (this.options.silent) {
+ console.error(errMsg);
+ return;
+ } else {
+ throw new Error(errMsg);
+ }
+ }
+ }
}
- }
+ return out;
}
- return out;
- }
-};
+}
diff --git a/src/marked/Renderer.js b/src/marked/Renderer.js
index 4a3de53..d544209 100644
--- a/src/marked/Renderer.js
+++ b/src/marked/Renderer.js
@@ -1,163 +1,180 @@
-const { defaults } = require('./defaults.js');
-const {
- cleanUrl,
- escape
-} = require('./helpers.js');
+// const { default } = require('./defaults.js');
+import { defaults } from "./defaults";
+
+import { cleanUrl, escape } from "./helpers";
/**
* Renderer
*/
-module.exports = class Renderer {
- constructor(options) {
- this.options = options || defaults;
- }
-
- code(code, infostring, escaped) {
- const lang = (infostring || '').match(/\S*/)[0];
- if (this.options.highlight) {
- const out = this.options.highlight(code, lang);
- if (out != null && out !== code) {
- escaped = true;
- code = out;
- }
- }
-
- // code = code.replace(/\n$/, '') + '\n';
-
- if (!lang) {
- return '```'
- + (escaped ? code : escape(code, true))
- + '
\n';
- }
-
- return ''
- + (escaped ? code : escape(code, true))
- + '
\n';
- }
-
- blockquote(quote) {
- return '\n' + quote + '
\n';
- }
-
- html(html) {
- return html;
- }
-
- heading(text, level, raw, slugger) {
- if (this.options.headerIds) {
- return '';
- }
- // ignore IDs
- return '' + text + '\n';
- }
-
- hr() {
- return this.options.xhtml ? '
\n' : '
\n';
- }
-
- list(body, ordered, start) {
- const type = ordered ? 'ol' : 'ul',
- startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
- return '<' + type + startatt + '>\n' + body + '' + type + '>\n';
- }
-
- listitem(text) {
- return '- ' + text + '';
- }
-
- checkbox(checked) {
- return checked ? '[x] ' : '[ ] ';
- }
-
- paragraph(text) {
- return '' + text + '
';
- }
-
- table(header, body) {
- if (body) body = '' + body + '';
-
- return '\n'
- + '\n'
- + header
- + '\n'
- + body
- + '
\n';
- }
-
- tablerow(content) {
- return '\n' + content + '
\n';
- }
-
- tablecell(content, flags) {
- const type = flags.header ? 'th' : 'td';
- const tag = flags.align
- ? '<' + type + ' align="' + flags.align + '">'
- : '<' + type + '>';
- return tag + content + '' + type + '>\n';
- }
-
- // span level renderer
- strong(text) {
- return '**' + text + '**';
- }
-
- em(text) {
- return '*' + text + '*';
- }
-
- codespan(text) {
- return '`' + text + '
`';
- }
-
- br() {
- return this.options.xhtml ? '
' : '
';
- }
-
- del(text) {
- return '' + text + '';
- }
-
- link(href, title, text) {
- href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
- if (href === null) {
- return text;
- }
- let out = '' + text + '';
- return out;
- }
-
- image(href, title, text) {
- href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
- if (href === null) {
- return text;
- }
-
- let out = '' : '>';
- return out;
- }
-
- text(text) {
- return text;
- }
-};
+export default class Renderer {
+ constructor(options) {
+ this.options = options || defaults;
+ }
+
+ code(code, infostring, escaped) {
+ const lang = (infostring || "").match(/\S*/)[0];
+ if (this.options.highlight) {
+ const out = this.options.highlight(code, lang);
+ if (out != null && out !== code) {
+ escaped = true;
+ code = out;
+ }
+ }
+
+ // code = code.replace(/\n$/, '') + '\n';
+
+ if (!lang) {
+ return (
+ "```" +
+ (escaped ? code : escape(code, true)) +
+ "
\n"
+ );
+ }
+
+ return (
+ '```' +
+ (escaped ? code : escape(code, true)) +
+ "```
\n"
+ );
+ }
+
+ blockquote(quote) {
+ return "\n" + quote + "
\n";
+ }
+
+ html(html) {
+ return html;
+ }
+
+ heading(text, level, raw, slugger) {
+ if (this.options.headerIds) {
+ return (
+ ""
+ );
+ }
+ // ignore IDs
+ return "" + text + "\n";
+ }
+
+ hr() {
+ return this.options.xhtml ? "
\n" : "
\n";
+ }
+
+ list(body, ordered, start) {
+ const type = ordered ? "ol" : "ul",
+ startatt = ordered && start !== 1 ? ' start="' + start + '"' : "";
+ return "<" + type + startatt + ">\n" + body + "" + type + ">\n";
+ }
+
+ listitem(text) {
+ return "- " + text + "";
+ }
+
+ checkbox(checked) {
+ return checked
+ ? '[x] '
+ : '[ ] ';
+ }
+
+ paragraph(text) {
+ return "" + text + "
";
+ }
+
+ table(header, body) {
+ if (body) body = "" + body + "";
+
+ return (
+ "\n" +
+ "\n" +
+ header +
+ "\n" +
+ body +
+ "
\n"
+ );
+ }
+
+ tablerow(content) {
+ return "\n" + content + "
\n";
+ }
+
+ tablecell(content, flags) {
+ const type = flags.header ? "th" : "td";
+ const tag = flags.align
+ ? "<" + type + ' align="' + flags.align + '">'
+ : "<" + type + ">";
+ return tag + content + "" + type + ">\n";
+ }
+
+ // span level renderer
+ strong(text) {
+ return "**" + text + "**";
+ }
+
+ em(text) {
+ return "*" + text + "*";
+ }
+
+ codespan(text) {
+ return (
+ '`' +
+ text +
+ '
`'
+ );
+ }
+
+ br() {
+ return this.options.xhtml ? "
" : "
";
+ }
+
+ del(text) {
+ return "" + text + "";
+ }
+
+ link(href, title, text) {
+ href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
+ if (href === null) {
+ return text;
+ }
+ let out = '" + text + "";
+ return out;
+ }
+
+ image(href, title, text) {
+ href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
+ if (href === null) {
+ return text;
+ }
+
+ let out = '" : ">";
+ return out;
+ }
+
+ text(text) {
+ return text;
+ }
+}
diff --git a/src/marked/Slugger.js b/src/marked/Slugger.js
index db385f5..9bf9b04 100644
--- a/src/marked/Slugger.js
+++ b/src/marked/Slugger.js
@@ -1,7 +1,7 @@
/**
* Slugger generates header id
*/
-module.exports = class Slugger {
+export default class Slugger {
constructor() {
this.seen = {};
}
diff --git a/src/marked/TextRenderer.js b/src/marked/TextRenderer.js
index 48c36e6..36053df 100644
--- a/src/marked/TextRenderer.js
+++ b/src/marked/TextRenderer.js
@@ -2,7 +2,7 @@
* TextRenderer
* returns only the textual part of the token
*/
-module.exports = class TextRenderer {
+export default class TextRenderer {
// no need for block level renderers
strong(text) {
return text;
diff --git a/src/marked/Tokenizer.js b/src/marked/Tokenizer.js
index 1836820..b42e853 100644
--- a/src/marked/Tokenizer.js
+++ b/src/marked/Tokenizer.js
@@ -1,10 +1,10 @@
-const { defaults } = require('./defaults.js');
-const {
+import { defaults } from './defaults';
+import {
rtrim,
splitCells,
escape,
findClosingBracket
-} = require('./helpers.js');
+} from './helpers';
function outputLink(cap, link, raw, lexer) {
const href = link.href;
@@ -65,7 +65,7 @@ function indentCodeCompensation(raw, text) {
/**
* Tokenizer
*/
-module.exports = class Tokenizer {
+export default class Tokenizer {
constructor(options) {
this.options = options || defaults;
}
diff --git a/src/marked/defaults.js b/src/marked/defaults.js
index a4b451f..127434e 100644
--- a/src/marked/defaults.js
+++ b/src/marked/defaults.js
@@ -1,33 +1,33 @@
function getDefaults() {
- return {
- baseUrl: null,
- breaks: false,
- extensions: null,
- gfm: true,
- headerIds: true,
- headerPrefix: '',
- highlight: null,
- langPrefix: 'language-',
- mangle: true,
- pedantic: false,
- renderer: null,
- sanitize: false,
- sanitizer: null,
- silent: false,
- smartLists: false,
- smartypants: false,
- tokenizer: null,
- walkTokens: null,
- xhtml: false
- };
+ return {
+ baseUrl: null,
+ breaks: false,
+ extensions: null,
+ gfm: true,
+ headerIds: true,
+ headerPrefix: "",
+ highlight: null,
+ langPrefix: "language-",
+ mangle: true,
+ pedantic: false,
+ renderer: null,
+ sanitize: false,
+ sanitizer: null,
+ silent: false,
+ smartLists: false,
+ smartypants: false,
+ tokenizer: null,
+ walkTokens: null,
+ xhtml: false,
+ };
}
function changeDefaults(newDefaults) {
- module.exports.defaults = newDefaults;
+ module.exports.defaults = newDefaults;
}
-
-module.exports = {
- defaults: getDefaults(),
- getDefaults,
- changeDefaults
+const defaults = getDefaults();
+export {
+ defaults,
+ getDefaults,
+ changeDefaults,
};
diff --git a/src/marked/helpers.js b/src/marked/helpers.js
index e0b48d7..378663a 100644
--- a/src/marked/helpers.js
+++ b/src/marked/helpers.js
@@ -248,7 +248,7 @@ function repeatString(pattern, count) {
return result + pattern;
}
-module.exports = {
+export {
escape,
unescape,
edit,
diff --git a/src/marked/marked.js b/src/marked/marked.js
index e91be9e..67f7a91 100644
--- a/src/marked/marked.js
+++ b/src/marked/marked.js
@@ -1,136 +1,131 @@
-const Lexer = require('./Lexer.js');
-const Parser = require('./Parser.js');
-const Tokenizer = require('./Tokenizer.js');
-const Renderer = require('./Renderer.js');
-const TextRenderer = require('./TextRenderer.js');
-const Slugger = require('./Slugger.js');
-const {
- merge,
- checkSanitizeDeprecation,
- escape
-} = require('./helpers.js');
-const {
- getDefaults,
- changeDefaults,
- defaults
-} = require('./defaults.js');
+import Lexer from "./Lexer.js";
+import Parser from "./Parser.js";
+import Tokenizer from "./Tokenizer.js";
+import Renderer from "./Renderer.js";
+import TextRenderer from "./TextRenderer.js";
+import Slugger from "./Slugger.js";
+import { merge, checkSanitizeDeprecation, escape } from "./helpers.js";
+import { getDefaults, changeDefaults, defaults } from "./defaults.js";
/**
* Marked
*/
-function marked(src, opt, callback) {
- // throw error in case of non string input
- if (typeof src === 'undefined' || src === null) {
- throw new Error('marked(): input parameter is undefined or null');
- }
- if (typeof src !== 'string') {
- throw new Error('marked(): input parameter is of type '
- + Object.prototype.toString.call(src) + ', string expected');
- }
-
- if (typeof opt === 'function') {
- callback = opt;
- opt = null;
- }
-
- opt = merge({}, marked.defaults, opt || {});
- checkSanitizeDeprecation(opt);
-
- if (callback) {
- const highlight = opt.highlight;
- let tokens;
+export default function marked(src, opt, callback) {
+ // throw error in case of non string input
+ if (typeof src === "undefined" || src === null) {
+ throw new Error("marked(): input parameter is undefined or null");
+ }
+ if (typeof src !== "string") {
+ throw new Error(
+ "marked(): input parameter is of type " +
+ Object.prototype.toString.call(src) +
+ ", string expected"
+ );
+ }
- try {
- tokens = Lexer.lex(src, opt);
- } catch (e) {
- return callback(e);
+ if (typeof opt === "function") {
+ callback = opt;
+ opt = null;
}
- const done = function(err) {
- let out;
+ opt = merge({}, marked.defaults, opt || {});
+ checkSanitizeDeprecation(opt);
+
+ if (callback) {
+ const highlight = opt.highlight;
+ let tokens;
- if (!err) {
try {
- if (opt.walkTokens) {
- marked.walkTokens(tokens, opt.walkTokens);
- }
- out = Parser.parse(tokens, opt);
+ tokens = Lexer.lex(src, opt);
} catch (e) {
- err = e;
+ return callback(e);
}
- }
-
- opt.highlight = highlight;
- return err
- ? callback(err)
- : callback(null, out);
- };
+ const done = function (err) {
+ let out;
+
+ if (!err) {
+ try {
+ if (opt.walkTokens) {
+ marked.walkTokens(tokens, opt.walkTokens);
+ }
+ out = Parser.parse(tokens, opt);
+ } catch (e) {
+ err = e;
+ }
+ }
- if (!highlight || highlight.length < 3) {
- return done();
- }
+ opt.highlight = highlight;
- delete opt.highlight;
+ return err ? callback(err) : callback(null, out);
+ };
- if (!tokens.length) return done();
+ if (!highlight || highlight.length < 3) {
+ return done();
+ }
- let pending = 0;
- marked.walkTokens(tokens, function(token) {
- if (token.type === 'code') {
- pending++;
- setTimeout(() => {
- highlight(token.text, token.lang, function(err, code) {
- if (err) {
- return done(err);
- }
- if (code != null && code !== token.text) {
- token.text = code;
- token.escaped = true;
+ delete opt.highlight;
+
+ if (!tokens.length) return done();
+
+ let pending = 0;
+ marked.walkTokens(tokens, function (token) {
+ if (token.type === "code") {
+ pending++;
+ setTimeout(() => {
+ highlight(token.text, token.lang, function (err, code) {
+ if (err) {
+ return done(err);
+ }
+ if (code != null && code !== token.text) {
+ token.text = code;
+ token.escaped = true;
+ }
+
+ pending--;
+ if (pending === 0) {
+ done();
+ }
+ });
+ }, 0);
}
+ });
- pending--;
- if (pending === 0) {
- done();
- }
- });
- }, 0);
- }
- });
+ if (pending === 0) {
+ done();
+ }
- if (pending === 0) {
- done();
+ return;
}
- return;
- }
-
- try {
- const tokens = Lexer.lex(src, opt);
- if (opt.walkTokens) {
- marked.walkTokens(tokens, opt.walkTokens);
- }
- return Parser.parse(tokens, opt);
- } catch (e) {
- e.message += '\nPlease report this to https://github.com/markedjs/marked.';
- if (opt.silent) {
- return 'An error occurred:
'
- + escape(e.message + '', true)
- + '
';
+ try {
+ const tokens = Lexer.lex(src, opt);
+ if (opt.walkTokens) {
+ marked.walkTokens(tokens, opt.walkTokens);
+ }
+ return Parser.parse(tokens, opt);
+ } catch (e) {
+ e.message +=
+ "\nPlease report this to https://github.com/markedjs/marked.";
+ if (opt.silent) {
+ return (
+ "An error occurred:
" +
+ escape(e.message + "", true) +
+ "
"
+ );
+ }
+ throw e;
}
- throw e;
- }
}
/**
* Options
*/
-marked.options =
-marked.setOptions = function(opt) {
- merge(marked.defaults, opt);
- changeDefaults(marked.defaults);
- return marked;
+marked.options = marked.setOptions = function (opt) {
+ merge(marked.defaults, opt);
+ changeDefaults(marked.defaults);
+ return marked;
};
marked.getDefaults = getDefaults;
@@ -141,183 +136,212 @@ marked.defaults = defaults;
* Use Extension
*/
-marked.use = function(...args) {
- const opts = merge({}, ...args);
- const extensions = marked.defaults.extensions || { renderers: {}, childTokens: {} };
- let hasExtensions;
-
- args.forEach((pack) => {
- // ==-- Parse "addon" extensions --== //
- if (pack.extensions) {
- hasExtensions = true;
- pack.extensions.forEach((ext) => {
- if (!ext.name) {
- throw new Error('extension name required');
- }
- if (ext.renderer) { // Renderer extensions
- const prevRenderer = extensions.renderers ? extensions.renderers[ext.name] : null;
- if (prevRenderer) {
- // Replace extension with func to run new extension but fall back if false
- extensions.renderers[ext.name] = function(...args) {
- let ret = ext.renderer.apply(this, args);
- if (ret === false) {
- ret = prevRenderer.apply(this, args);
- }
- return ret;
- };
- } else {
- extensions.renderers[ext.name] = ext.renderer;
- }
+marked.use = function (...args) {
+ const opts = merge({}, ...args);
+ const extensions = marked.defaults.extensions || {
+ renderers: {},
+ childTokens: {},
+ };
+ let hasExtensions;
+
+ args.forEach((pack) => {
+ // ==-- Parse "addon" extensions --== //
+ if (pack.extensions) {
+ hasExtensions = true;
+ pack.extensions.forEach((ext) => {
+ if (!ext.name) {
+ throw new Error("extension name required");
+ }
+ if (ext.renderer) {
+ // Renderer extensions
+ const prevRenderer = extensions.renderers
+ ? extensions.renderers[ext.name]
+ : null;
+ if (prevRenderer) {
+ // Replace extension with func to run new extension but fall back if false
+ extensions.renderers[ext.name] = function (...args) {
+ let ret = ext.renderer.apply(this, args);
+ if (ret === false) {
+ ret = prevRenderer.apply(this, args);
+ }
+ return ret;
+ };
+ } else {
+ extensions.renderers[ext.name] = ext.renderer;
+ }
+ }
+ if (ext.tokenizer) {
+ // Tokenizer Extensions
+ if (
+ !ext.level ||
+ (ext.level !== "block" && ext.level !== "inline")
+ ) {
+ throw new Error(
+ "extension level must be 'block' or 'inline'"
+ );
+ }
+ if (extensions[ext.level]) {
+ extensions[ext.level].unshift(ext.tokenizer);
+ } else {
+ extensions[ext.level] = [ext.tokenizer];
+ }
+ if (ext.start) {
+ // Function to check for start of token
+ if (ext.level === "block") {
+ if (extensions.startBlock) {
+ extensions.startBlock.push(ext.start);
+ } else {
+ extensions.startBlock = [ext.start];
+ }
+ } else if (ext.level === "inline") {
+ if (extensions.startInline) {
+ extensions.startInline.push(ext.start);
+ } else {
+ extensions.startInline = [ext.start];
+ }
+ }
+ }
+ }
+ if (ext.childTokens) {
+ // Child tokens to be visited by walkTokens
+ extensions.childTokens[ext.name] = ext.childTokens;
+ }
+ });
}
- if (ext.tokenizer) { // Tokenizer Extensions
- if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
- throw new Error("extension level must be 'block' or 'inline'");
- }
- if (extensions[ext.level]) {
- extensions[ext.level].unshift(ext.tokenizer);
- } else {
- extensions[ext.level] = [ext.tokenizer];
- }
- if (ext.start) { // Function to check for start of token
- if (ext.level === 'block') {
- if (extensions.startBlock) {
- extensions.startBlock.push(ext.start);
- } else {
- extensions.startBlock = [ext.start];
- }
- } else if (ext.level === 'inline') {
- if (extensions.startInline) {
- extensions.startInline.push(ext.start);
- } else {
- extensions.startInline = [ext.start];
- }
+
+ // ==-- Parse "overwrite" extensions --== //
+ if (pack.renderer) {
+ const renderer = marked.defaults.renderer || new Renderer();
+ for (const prop in pack.renderer) {
+ const prevRenderer = renderer[prop];
+ // Replace renderer with func to run extension, but fall back if false
+ renderer[prop] = (...args) => {
+ let ret = pack.renderer[prop].apply(renderer, args);
+ if (ret === false) {
+ ret = prevRenderer.apply(renderer, args);
+ }
+ return ret;
+ };
}
- }
+ opts.renderer = renderer;
}
- if (ext.childTokens) { // Child tokens to be visited by walkTokens
- extensions.childTokens[ext.name] = ext.childTokens;
+ if (pack.tokenizer) {
+ const tokenizer = marked.defaults.tokenizer || new Tokenizer();
+ for (const prop in pack.tokenizer) {
+ const prevTokenizer = tokenizer[prop];
+ // Replace tokenizer with func to run extension, but fall back if false
+ tokenizer[prop] = (...args) => {
+ let ret = pack.tokenizer[prop].apply(tokenizer, args);
+ if (ret === false) {
+ ret = prevTokenizer.apply(tokenizer, args);
+ }
+ return ret;
+ };
+ }
+ opts.tokenizer = tokenizer;
}
- });
- }
-
- // ==-- Parse "overwrite" extensions --== //
- if (pack.renderer) {
- const renderer = marked.defaults.renderer || new Renderer();
- for (const prop in pack.renderer) {
- const prevRenderer = renderer[prop];
- // Replace renderer with func to run extension, but fall back if false
- renderer[prop] = (...args) => {
- let ret = pack.renderer[prop].apply(renderer, args);
- if (ret === false) {
- ret = prevRenderer.apply(renderer, args);
- }
- return ret;
- };
- }
- opts.renderer = renderer;
- }
- if (pack.tokenizer) {
- const tokenizer = marked.defaults.tokenizer || new Tokenizer();
- for (const prop in pack.tokenizer) {
- const prevTokenizer = tokenizer[prop];
- // Replace tokenizer with func to run extension, but fall back if false
- tokenizer[prop] = (...args) => {
- let ret = pack.tokenizer[prop].apply(tokenizer, args);
- if (ret === false) {
- ret = prevTokenizer.apply(tokenizer, args);
- }
- return ret;
- };
- }
- opts.tokenizer = tokenizer;
- }
- // ==-- Parse WalkTokens extensions --== //
- if (pack.walkTokens) {
- const walkTokens = marked.defaults.walkTokens;
- opts.walkTokens = (token) => {
- pack.walkTokens.call(this, token);
- if (walkTokens) {
- walkTokens(token);
+ // ==-- Parse WalkTokens extensions --== //
+ if (pack.walkTokens) {
+ const walkTokens = marked.defaults.walkTokens;
+ opts.walkTokens = (token) => {
+ pack.walkTokens.call(this, token);
+ if (walkTokens) {
+ walkTokens(token);
+ }
+ };
}
- };
- }
- if (hasExtensions) {
- opts.extensions = extensions;
- }
+ if (hasExtensions) {
+ opts.extensions = extensions;
+ }
- marked.setOptions(opts);
- });
+ marked.setOptions(opts);
+ });
};
/**
* Run callback for every token
*/
-marked.walkTokens = function(tokens, callback) {
- for (const token of tokens) {
- callback(token);
- switch (token.type) {
- case 'table': {
- for (const cell of token.header) {
- marked.walkTokens(cell.tokens, callback);
- }
- for (const row of token.rows) {
- for (const cell of row) {
- marked.walkTokens(cell.tokens, callback);
- }
- }
- break;
- }
- case 'list': {
- marked.walkTokens(token.items, callback);
- break;
- }
- default: {
- if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { // Walk any extensions
- marked.defaults.extensions.childTokens[token.type].forEach(function(childTokens) {
- marked.walkTokens(token[childTokens], callback);
- });
- } else if (token.tokens) {
- marked.walkTokens(token.tokens, callback);
+marked.walkTokens = function (tokens, callback) {
+ for (const token of tokens) {
+ callback(token);
+ switch (token.type) {
+ case "table": {
+ for (const cell of token.header) {
+ marked.walkTokens(cell.tokens, callback);
+ }
+ for (const row of token.rows) {
+ for (const cell of row) {
+ marked.walkTokens(cell.tokens, callback);
+ }
+ }
+ break;
+ }
+ case "list": {
+ marked.walkTokens(token.items, callback);
+ break;
+ }
+ default: {
+ if (
+ marked.defaults.extensions &&
+ marked.defaults.extensions.childTokens &&
+ marked.defaults.extensions.childTokens[token.type]
+ ) {
+ // Walk any extensions
+ marked.defaults.extensions.childTokens[token.type].forEach(
+ function (childTokens) {
+ marked.walkTokens(token[childTokens], callback);
+ }
+ );
+ } else if (token.tokens) {
+ marked.walkTokens(token.tokens, callback);
+ }
+ }
}
- }
}
- }
};
/**
* Parse Inline
*/
-marked.parseInline = function(src, opt) {
- // throw error in case of non string input
- if (typeof src === 'undefined' || src === null) {
- throw new Error('marked.parseInline(): input parameter is undefined or null');
- }
- if (typeof src !== 'string') {
- throw new Error('marked.parseInline(): input parameter is of type '
- + Object.prototype.toString.call(src) + ', string expected');
- }
-
- opt = merge({}, marked.defaults, opt || {});
- checkSanitizeDeprecation(opt);
-
- try {
- const tokens = Lexer.lexInline(src, opt);
- if (opt.walkTokens) {
- marked.walkTokens(tokens, opt.walkTokens);
+marked.parseInline = function (src, opt) {
+ // throw error in case of non string input
+ if (typeof src === "undefined" || src === null) {
+ throw new Error(
+ "marked.parseInline(): input parameter is undefined or null"
+ );
}
- return Parser.parseInline(tokens, opt);
- } catch (e) {
- e.message += '\nPlease report this to https://github.com/markedjs/marked.';
- if (opt.silent) {
- return 'An error occurred:
'
- + escape(e.message + '', true)
- + '
';
+ if (typeof src !== "string") {
+ throw new Error(
+ "marked.parseInline(): input parameter is of type " +
+ Object.prototype.toString.call(src) +
+ ", string expected"
+ );
+ }
+
+ opt = merge({}, marked.defaults, opt || {});
+ checkSanitizeDeprecation(opt);
+
+ try {
+ const tokens = Lexer.lexInline(src, opt);
+ if (opt.walkTokens) {
+ marked.walkTokens(tokens, opt.walkTokens);
+ }
+ return Parser.parseInline(tokens, opt);
+ } catch (e) {
+ e.message +=
+ "\nPlease report this to https://github.com/markedjs/marked.";
+ if (opt.silent) {
+ return (
+ "An error occurred:
" +
+ escape(e.message + "", true) +
+ "
"
+ );
+ }
+ throw e;
}
- throw e;
- }
};
/**
@@ -338,5 +362,3 @@ marked.Tokenizer = Tokenizer;
marked.Slugger = Slugger;
marked.parse = marked;
-
-module.exports = marked;
diff --git a/src/marked/rules.js b/src/marked/rules.js
index e99d87b..b6c79fd 100644
--- a/src/marked/rules.js
+++ b/src/marked/rules.js
@@ -1,84 +1,92 @@
-const {
- noopTest,
- edit,
- merge
-} = require('./helpers.js');
+const { noopTest, edit, merge } = require("./helpers.js");
/**
* Block-Level Grammar
*/
const block = {
- newline: /^(?: *(?:\n|$))+/,
- code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
- fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
- hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
- heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
- blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
- list: /^( {0,3}bull)( [^\n]+?)?(?:\n|$)/,
- html: '^ {0,3}(?:' // optional indentation
- + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:\\1>[^\\n]*\\n+|$)' // (1)
- + '|comment[^\\n]*(\\n+|$)' // (2)
- + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
- + '|\\n*|$)' // (4)
- + '|\\n*|$)' // (5)
- + '|?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
- + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
- + '|(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
- + ')',
- def: /^ {0,3}\[(label)\]: *\n? *([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,
- table: noopTest,
- lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,
- // regex template, placeholders will be replaced according to different paragraph
- // interruption rules of commonmark and the original markdown spec:
- _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html| +\n)[^\n]+)*)/,
- text: /^[^\n]+/
+ newline: /^(?: *(?:\n|$))+/,
+ code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
+ fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
+ hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
+ heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
+ blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
+ list: /^( {0,3}bull)( [^\n]+?)?(?:\n|$)/,
+ html:
+ "^ {0,3}(?:" + // optional indentation
+ "<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:\\1>[^\\n]*\\n+|$)" + // (1)
+ "|comment[^\\n]*(\\n+|$)" + // (2)
+ "|<\\?[\\s\\S]*?(?:\\?>\\n*|$)" + // (3)
+ "|\\n*|$)" + // (4)
+ "|\\n*|$)" + // (5)
+ "|?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)" + // (6)
+ "|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)" + // (7) open tag
+ "|(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)" + // (7) closing tag
+ ")",
+ def: /^ {0,3}\[(label)\]: *\n? *([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,
+ table: noopTest,
+ lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,
+ // regex template, placeholders will be replaced according to different paragraph
+ // interruption rules of commonmark and the original markdown spec:
+ _paragraph:
+ /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html| +\n)[^\n]+)*)/,
+ text: /^[^\n]+/,
};
block._label = /(?!\s*\])(?:\\[\[\]]|[^\[\]])+/;
block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
block.def = edit(block.def)
- .replace('label', block._label)
- .replace('title', block._title)
- .getRegex();
+ .replace("label", block._label)
+ .replace("title", block._title)
+ .getRegex();
block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
block.listItemStart = edit(/^( *)(bull) */)
- .replace('bull', block.bullet)
- .getRegex();
+ .replace("bull", block.bullet)
+ .getRegex();
block.list = edit(block.list)
- .replace(/bull/g, block.bullet)
- .replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')
- .replace('def', '\\n+(?=' + block.def.source + ')')
- .getRegex();
-
-block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
- + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
- + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
- + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
- + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
- + '|track|ul';
+ .replace(/bull/g, block.bullet)
+ .replace(
+ "hr",
+ "\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))"
+ )
+ .replace("def", "\\n+(?=" + block.def.source + ")")
+ .getRegex();
+
+block._tag =
+ "address|article|aside|base|basefont|blockquote|body|caption" +
+ "|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption" +
+ "|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe" +
+ "|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option" +
+ "|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr" +
+ "|track|ul";
block._comment = /|$)/;
-block.html = edit(block.html, 'i')
- .replace('comment', block._comment)
- .replace('tag', block._tag)
- .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
- .getRegex();
+block.html = edit(block.html, "i")
+ .replace("comment", block._comment)
+ .replace("tag", block._tag)
+ .replace(
+ "attribute",
+ / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/
+ )
+ .getRegex();
block.paragraph = edit(block._paragraph)
- .replace('hr', block.hr)
- .replace('heading', ' {0,3}#{1,6} ')
- .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
- .replace('blockquote', ' {0,3}>')
- .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
- .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
- .replace('html', '?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
- .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
- .getRegex();
+ .replace("hr", block.hr)
+ .replace("heading", " {0,3}#{1,6} ")
+ .replace("|lheading", "") // setex headings don't interrupt commonmark paragraphs
+ .replace("blockquote", " {0,3}>")
+ .replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n")
+ .replace("list", " {0,3}(?:[*+-]|1[.)]) ") // only lists starting from 1 can interrupt
+ .replace(
+ "html",
+ "?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)"
+ )
+ .replace("tag", block._tag) // pars can be interrupted by type (6) html blocks
+ .getRegex();
block.blockquote = edit(block.blockquote)
- .replace('paragraph', block.paragraph)
- .getRegex();
+ .replace("paragraph", block.paragraph)
+ .getRegex();
/**
* Normal Block Grammar
@@ -91,139 +99,154 @@ block.normal = merge({}, block);
*/
block.gfm = merge({}, block.normal, {
- table: '^ *([^\\n ].*\\|.*)\\n' // Header
- + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align
- + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
+ table:
+ "^ *([^\\n ].*\\|.*)\\n" + // Header
+ " {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?" + // Align
+ "(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)", // Cells
});
block.gfm.table = edit(block.gfm.table)
- .replace('hr', block.hr)
- .replace('heading', ' {0,3}#{1,6} ')
- .replace('blockquote', ' {0,3}>')
- .replace('code', ' {4}[^\\n]')
- .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
- .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
- .replace('html', '?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
- .replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
- .getRegex();
+ .replace("hr", block.hr)
+ .replace("heading", " {0,3}#{1,6} ")
+ .replace("blockquote", " {0,3}>")
+ .replace("code", " {4}[^\\n]")
+ .replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n")
+ .replace("list", " {0,3}(?:[*+-]|1[.)]) ") // only lists starting from 1 can interrupt
+ .replace(
+ "html",
+ "?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)"
+ )
+ .replace("tag", block._tag) // tables can be interrupted by type (6) html blocks
+ .getRegex();
/**
* Pedantic grammar (original John Gruber's loose markdown specification)
*/
block.pedantic = merge({}, block.normal, {
- html: edit(
- '^ *(?:comment *(?:\\n|\\s*$)'
- + '|<(tag)[\\s\\S]+?\\1> *(?:\\n{2,}|\\s*$)' // closed tag
- + '|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
- .replace('comment', block._comment)
- .replace(/tag/g, '(?!(?:'
- + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
- + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
- + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
- .getRegex(),
- def: /^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
- heading: /^(#{1,6})(.*)(?:\n+|$)/,
- fences: noopTest, // fences not supported
- paragraph: edit(block.normal._paragraph)
- .replace('hr', block.hr)
- .replace('heading', ' *#{1,6} *[^\n]')
- .replace('lheading', block.lheading)
- .replace('blockquote', ' {0,3}>')
- .replace('|fences', '')
- .replace('|list', '')
- .replace('|html', '')
- .getRegex()
+ html: edit(
+ "^ *(?:comment *(?:\\n|\\s*$)" +
+ "|<(tag)[\\s\\S]+?\\1> *(?:\\n{2,}|\\s*$)" + // closed tag
+ "|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))"
+ )
+ .replace("comment", block._comment)
+ .replace(
+ /tag/g,
+ "(?!(?:" +
+ "a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub" +
+ "|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)" +
+ "\\b)\\w+(?!:|[^\\w\\s@]*@)\\b"
+ )
+ .getRegex(),
+ def: /^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
+ heading: /^(#{1,6})(.*)(?:\n+|$)/,
+ fences: noopTest, // fences not supported
+ paragraph: edit(block.normal._paragraph)
+ .replace("hr", block.hr)
+ .replace("heading", " *#{1,6} *[^\n]")
+ .replace("lheading", block.lheading)
+ .replace("blockquote", " {0,3}>")
+ .replace("|fences", "")
+ .replace("|list", "")
+ .replace("|html", "")
+ .getRegex(),
});
/**
* Inline-Level Grammar
*/
const inline = {
- escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
- autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
- url: noopTest,
- tag: '^comment'
- + '|^[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
- + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
- + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g.
- + '|^' // declaration, e.g.
- + '|^', // CDATA section
- link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
- reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
- nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
- reflinkSearch: 'reflink|nolink(?!\\()',
- emStrong: {
- lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
- // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right.
- // () Skip orphan delim inside strong (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a
- rDelimAst: /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,
- rDelimUnd: /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
- },
- code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
- br: /^( {2,}|\\)\n(?!\s*$)/,
- del: noopTest,
- text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\[\]\\^_`{|}~])/,
+ autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
+ url: noopTest,
+ tag:
+ "^comment" +
+ "|^[a-zA-Z][\\w:-]*\\s*>" + // self-closing tag
+ "|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>" + // open tag
+ "|^<\\?[\\s\\S]*?\\?>" + // processing instruction, e.g.
+ "|^" + // declaration, e.g.
+ "|^", // CDATA section
+ link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
+ reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
+ nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
+ reflinkSearch: "reflink|nolink(?!\\()",
+ emStrong: {
+ lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
+ // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right.
+ // () Skip orphan delim inside strong (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a
+ rDelimAst:
+ /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,
+ rDelimUnd:
+ /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/, // ^- Not allowed for _
+ },
+ code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
+ br: /^( {2,}|\\)\n(?!\s*$)/,
+ del: noopTest,
+ text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~';
-inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex();
+inline._punctuation = "!\"#$%&'()+\\-.,/:;<=>?@\\[\\]`^{|}~";
+inline.punctuation = edit(inline.punctuation)
+ .replace(/punctuation/g, inline._punctuation)
+ .getRegex();
// sequences em should skip over [title](link), `code`,
inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g;
inline.escapedEmSt = /\\\*|\\_/g;
-inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
+inline._comment = edit(block._comment).replace("(?:-->|$)", "-->").getRegex();
inline.emStrong.lDelim = edit(inline.emStrong.lDelim)
- .replace(/punct/g, inline._punctuation)
- .getRegex();
+ .replace(/punct/g, inline._punctuation)
+ .getRegex();
-inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g')
- .replace(/punct/g, inline._punctuation)
- .getRegex();
+inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, "g")
+ .replace(/punct/g, inline._punctuation)
+ .getRegex();
-inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g')
- .replace(/punct/g, inline._punctuation)
- .getRegex();
+inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, "g")
+ .replace(/punct/g, inline._punctuation)
+ .getRegex();
inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
-inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
+inline._email =
+ /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
inline.autolink = edit(inline.autolink)
- .replace('scheme', inline._scheme)
- .replace('email', inline._email)
- .getRegex();
+ .replace("scheme", inline._scheme)
+ .replace("email", inline._email)
+ .getRegex();
-inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
+inline._attribute =
+ /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
inline.tag = edit(inline.tag)
- .replace('comment', inline._comment)
- .replace('attribute', inline._attribute)
- .getRegex();
+ .replace("comment", inline._comment)
+ .replace("attribute", inline._attribute)
+ .getRegex();
inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
inline.link = edit(inline.link)
- .replace('label', inline._label)
- .replace('href', inline._href)
- .replace('title', inline._title)
- .getRegex();
+ .replace("label", inline._label)
+ .replace("href", inline._href)
+ .replace("title", inline._title)
+ .getRegex();
inline.reflink = edit(inline.reflink)
- .replace('label', inline._label)
- .getRegex();
+ .replace("label", inline._label)
+ .getRegex();
-inline.reflinkSearch = edit(inline.reflinkSearch, 'g')
- .replace('reflink', inline.reflink)
- .replace('nolink', inline.nolink)
- .getRegex();
+inline.reflinkSearch = edit(inline.reflinkSearch, "g")
+ .replace("reflink", inline.reflink)
+ .replace("nolink", inline.nolink)
+ .getRegex();
/**
* Normal Inline Grammar
@@ -236,24 +259,24 @@ inline.normal = merge({}, inline);
*/
inline.pedantic = merge({}, inline.normal, {
- strong: {
- start: /^__|\*\*/,
- middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
- endAst: /\*\*(?!\*)/g,
- endUnd: /__(?!_)/g
- },
- em: {
- start: /^_|\*/,
- middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
- endAst: /\*(?!\*)/g,
- endUnd: /_(?!_)/g
- },
- link: edit(/^!?\[(label)\]\((.*?)\)/)
- .replace('label', inline._label)
- .getRegex(),
- reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
- .replace('label', inline._label)
- .getRegex()
+ strong: {
+ start: /^__|\*\*/,
+ middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+ endAst: /\*\*(?!\*)/g,
+ endUnd: /__(?!_)/g,
+ },
+ em: {
+ start: /^_|\*/,
+ middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
+ endAst: /\*(?!\*)/g,
+ endUnd: /_(?!_)/g,
+ },
+ link: edit(/^!?\[(label)\]\((.*?)\)/)
+ .replace("label", inline._label)
+ .getRegex(),
+ reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
+ .replace("label", inline._label)
+ .getRegex(),
});
/**
@@ -261,30 +284,32 @@ inline.pedantic = merge({}, inline.normal, {
*/
inline.gfm = merge({}, inline.normal, {
- escape: edit(inline.escape).replace('])', '~|])').getRegex(),
- _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
- url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
- _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,
- del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
- text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\(initState, "simplenote", {
+ storageName: "simplenotestore",
+});
+
+const { useStore, setState, getState } = store;
+export { useStore };
+
+export const notesSelector = (state: State) => state.notes;
+
+export const add = () => {
+ const _id = Date.now().toString();
+ setState((state) => ({
+ ...state,
+ notes: [
+ {
+ _id,
+ title: "untitled",
+ },
+ ...state.notes,
+ ],
+ }));
+ return _id;
+};
+
+export const getContent = (_id: string) => {
+ const notes = getState("notes");
+ return notes.find((item) => item._id === _id);
+};
+export const updateContent = (_id: string, note: string) => {
+ setState((state) => {
+ const notes = [...state.notes];
+ const idx = notes.findIndex((item) => item._id === _id);
+ notes[idx].note = note;
+ notes[idx].title = note.split("\n")[0] || "unnamed";
+ return { notes };
+ });
+};
+export const deteteNote = (_id: string) => {
+ setState((state) => {
+ const notes = [...state.notes];
+ const idx = notes.findIndex((item) => item._id === _id);
+ notes.splice(idx, 1);
+ return { notes };
+ });
+};
diff --git a/yarn.lock b/yarn.lock
index f3cb0fd..a66205c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9029,10 +9029,10 @@ react-is@^17.0.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339"
integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==
-react-light-state@^0.0.12:
- version "0.0.12"
- resolved "https://registry.yarnpkg.com/react-light-state/-/react-light-state-0.0.12.tgz#adc3701bb329a3ab6143c36366c0c6d774a6cf3f"
- integrity sha512-dR6KYlxtAvJmnvVc69tyb3C3lBn50l+bjMN9Iw+dI6aU+mCNam5iqwUgwbCVIOhQj+BzU6617wu20Xxc+2hlgQ==
+react-light-state@^0.0.15:
+ version "0.0.15"
+ resolved "https://registry.yarnpkg.com/react-light-state/-/react-light-state-0.0.15.tgz#fdf49843278cb4e581c0360bf73513e473bf4d16"
+ integrity sha512-Ew6CtQ8Bhqk1cxvAbWp9WcAFY8NQwBhV/m2d1G2pAhgf1r1GjzQHyL99w+HH8tobYld/lpHacISq219qEacTcQ==
dependencies:
shallowequal "^1.1.0"