docs: update docs (#2928)

Co-authored-by: Steven <steven@ceriously.com>
This commit is contained in:
Tony Brix 2023-08-10 21:25:40 -06:00 committed by GitHub
parent f10fc84b80
commit 71cc7b9d8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 232 additions and 281 deletions

View File

@ -1,6 +1,7 @@
import { promises } from 'fs';
import { join, dirname, parse, format } from 'path';
import { parse as marked } from './lib/marked.esm.js';
import { Marked } from './lib/marked.esm.js';
import { markedHighlight } from 'marked-highlight';
import { HighlightJS } from 'highlight.js';
import titleize from 'titleize';
@ -12,6 +13,12 @@ const outputDir = join(cwd, 'public');
const templateFile = join(inputDir, '_document.html');
const isUppercase = str => /[A-Z_]+/.test(str);
const getTitle = str => str === 'INDEX' ? '' : titleize(str.replace(/_/g, ' ')) + ' - ';
const marked = new Marked(markedHighlight((code, language) => {
if (!language) {
return highlightAuto(code).value;
}
return highlight(code, { language }).value;
}));
async function init() {
console.log('Cleaning up output directory ' + outputDir);
@ -38,14 +45,7 @@ async function build(currentDir, tmpl) {
let buffer = await readFile(filename);
const parsed = parse(filename);
if (parsed.ext === '.md' && isUppercase(parsed.name)) {
const html = marked(buffer.toString('utf8'), {
highlight: (code, language) => {
if (!language) {
return highlightAuto(code).value;
}
return highlight(code, { language }).value;
}
});
const html = marked.parse(buffer.toString('utf8'));
buffer = Buffer.from(tmpl
.replace('<!--{{title}}-->', getTitle(parsed.name))
.replace('<!--{{content}}-->', html),

View File

@ -200,7 +200,6 @@ Users are anyone using Marked in some fashion, without them, there's no reason f
|Individual or Organization |Website |Project |Submitted by |
|:--------------------------|:-----------------------|:------------------------------------|:---------------------------------------------------|
|MarkedJS |https://marked.js.org |https://github.com/markedjs/marked |The marked committers |
|Altilunium |https://md.altilunium.my.id|https://github.com/altilunium/md |Altilunium |
To be listed: All fields are optional. Contact any of the committers or, more timely, submit a pull request with the following (using the first row as an example):

View File

@ -10,14 +10,14 @@
- [ ] Run `npm run build:reset` to remove changes to compiled files.
- [ ] Submit a Pull Request.
## Design principles
<h2 id="design-principles">Design principles</h2>
Marked tends to favor following the SOLID set of software design and development principles; mainly the [single responsibility](https://en.wikipedia.org/wiki/Single_responsibility_principle) and [open/closed principles](https://en.wikipedia.org/wiki/Open/closed_principle):
- **Single responsibility:** Marked, and the components of Marked, have the single responsibility of converting Markdown strings into HTML.
- **Open/closed:** Marked favors giving developers the means to easily extend the library and its components over changing Marked's behavior through configuration options.
## Priorities
<h2 id="priorities">Priorities</h2>
We think we have our priorities sorted to build quality in.
@ -33,7 +33,7 @@ The following table lists the ticket type labels we use when there is work to be
|NFU - new feature (user requested) |A capability Marked does not currently provide but has been requested by users of Marked. |
|NFE - new feature (should be an extension) |A capability Marked does not currently provide and is not part of a spec. |
## Test early, often, and everything
<h2 id="test-early-often-and-everything">Test early, often, and everything</h2>
We try to write test cases to validate output (writing tests based on the [supported specifications](/#specifications)) and minimize regression (writing tests for issues fixed). Therefore, if you would like to contribute, some things you should know regarding the test harness.

View File

@ -1,4 +1,4 @@
## Marked instance
<h2 id="instance">Marked instance</h2>
By default, Marked stores options and extensions in the global scope. That means changing the options in one script will also change the options in another script since they share the same instance.

View File

@ -38,6 +38,7 @@
<li>
<a href="/using_advanced">Advanced Usage</a>
<ul>
<li><a href="/using_advanced#instance">Instance</a></li>
<li><a href="/using_advanced#options">Options</a></li>
<li><a href="/using_advanced#extensions">Known Extensions</a></li>
<li><a href="/using_advanced#inline">Inline Markdown</a></li>

View File

@ -1,99 +1,125 @@
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
/*!
Theme: GitHub
Description: Light theme as seen on github.com
Author: github.com
Maintainer: @Hirse
Updated: 2021-05-15
Outdated base version: https://github.com/primer/github-syntax-light
Current colors taken from GitHub's CSS
*/
pre {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
}
.hljs-comment,
.hljs-quote {
color: #998;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
color: #333;
font-weight: bold;
}
.hljs-number,
.hljs-literal,
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
color: #008080;
}
.hljs-string,
.hljs-doctag {
color: #d14;
}
.hljs-title,
.hljs-section,
.hljs-selector-id {
color: #900;
font-weight: bold;
}
.hljs-subst {
font-weight: normal;
}
.hljs-type,
.hljs-class .hljs-title {
color: #458;
font-weight: bold;
}
.hljs-tag,
.hljs-name,
.hljs-attribute {
color: #000080;
font-weight: normal;
}
.hljs-regexp,
.hljs-link {
color: #009926;
}
.hljs-symbol,
.hljs-bullet {
color: #990073;
}
.hljs-built_in,
.hljs-builtin-name {
color: #0086b3;
}
.hljs-meta {
color: #999;
font-weight: bold;
}
.hljs-deletion {
background: #fdd;
}
.hljs-addition {
background: #dfd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs {
color: #24292e;
background: #ffffff;
}
.hljs-doctag,
.hljs-keyword,
.hljs-meta .hljs-keyword,
.hljs-template-tag,
.hljs-template-variable,
.hljs-type,
.hljs-variable.language_ {
/* prettylights-syntax-keyword */
color: #d73a49;
}
.hljs-title,
.hljs-title.class_,
.hljs-title.class_.inherited__,
.hljs-title.function_ {
/* prettylights-syntax-entity */
color: #6f42c1;
}
.hljs-attr,
.hljs-attribute,
.hljs-literal,
.hljs-meta,
.hljs-number,
.hljs-operator,
.hljs-variable,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-id {
/* prettylights-syntax-constant */
color: #005cc5;
}
.hljs-regexp,
.hljs-string,
.hljs-meta .hljs-string {
/* prettylights-syntax-string */
color: #032f62;
}
.hljs-built_in,
.hljs-symbol {
/* prettylights-syntax-variable */
color: #e36209;
}
.hljs-comment,
.hljs-code,
.hljs-formula {
/* prettylights-syntax-comment */
color: #6a737d;
}
.hljs-name,
.hljs-quote,
.hljs-selector-tag,
.hljs-selector-pseudo {
/* prettylights-syntax-entity-tag */
color: #22863a;
}
.hljs-subst {
/* prettylights-syntax-storage-modifier-import */
color: #24292e;
}
.hljs-section {
/* prettylights-syntax-markup-heading */
color: #005cc5;
font-weight: bold;
}
.hljs-bullet {
/* prettylights-syntax-markup-list */
color: #735c0f;
}
.hljs-emphasis {
/* prettylights-syntax-markup-italic */
color: #24292e;
font-style: italic;
}
.hljs-strong {
/* prettylights-syntax-markup-bold */
color: #24292e;
font-weight: bold;
}
.hljs-addition {
/* prettylights-syntax-markup-inserted */
color: #22863a;
background-color: #f0fff4;
}
.hljs-deletion {
/* prettylights-syntax-markup-deleted */
color: #b31d28;
background-color: #ffeef0;
}
.hljs-char.escape_,
.hljs-link,
.hljs-params,
.hljs-property,
.hljs-punctuation,
.hljs-tag {
/* purposely ignored */
}

View File

@ -95,36 +95,23 @@ pre {
background-color: #f6f8fa;
border-radius: 3px;
position: relative;
max-width: 680px;
}
code:not([class]) {
pre code {
max-width: 680px;
overflow: auto;
display: block;
}
:not(pre) > code {
padding: 0.2em 0.4em;
margin: 0;
font-size: 85%;
background-color: rgba(27,31,35,0.05);
background-color: #f6f8fa;
border-radius: 3px;
}
.github-corner:hover .octo-arm {
animation:octocat-wave 560ms ease-in-out;
}
@keyframes octocat-wave {
0%,100%{transform:rotate(0)}
20%,60%{transform:rotate(-25deg)}
40%,80%{transform:rotate(10deg)}
}
@media (max-width:500px) {
.github-corner:hover .octo-arm {
animation:none
}
.github-corner .octo-arm {
animation:octocat-wave 560ms ease-in-out;
}
}
.div-copy {
position: absolute;
top: 0;
@ -151,22 +138,22 @@ code:not([class]) {
.div-copy .tooltip-copy::before {
content: "Copied";
position: absolute;
/* vertically center */
top: 50%;
transform: translateY(-50%);
/* move to right */
right: 100%;
margin-right: 5px; /* and add a small left margin */
/* basic styles */
padding: 2px 7px;
border-radius: 5px;
background: #444;
color: #fff;
text-align: center;
opacity: 0; /* hide by default */
transition: opacity .3s;
}
@ -178,20 +165,20 @@ code:not([class]) {
.div-copy .tooltip-copy::after {
content: "";
position: absolute;
/* position tooltip correctly */
right: 100%;
margin-right: -5px;
/* vertically center */
top: 50%;
transform: translateY(-50%);
/* the arrow */
border-style: solid;
border-width: 2px 2px 5px 8px;
border-color: transparent transparent transparent #444;
opacity: 0;
transition: opacity .3s;
}

View File

@ -74,3 +74,7 @@ header h1 {
border-color: red;
background-color: #FEE
}
#responseTime {
display: inline-block;
}

View File

@ -1,12 +1,3 @@
/* globals marked, unfetch, ES6Promise, Promise */ // eslint-disable-line no-redeclare
if (!window.Promise) {
window.Promise = ES6Promise;
}
if (!window.fetch) {
window.fetch = unfetch;
}
onunhandledrejection = function(e) {
throw e.reason;
};
@ -16,7 +7,6 @@ const $mainElem = document.querySelector('#main');
const $markdownElem = document.querySelector('#markdown');
const $markedVerElem = document.querySelector('#markedVersion');
const $commitVerElem = document.querySelector('#commitVersion');
let $markedVer = document.querySelector('#markedCdn');
const $optionsElem = document.querySelector('#options');
const $outputTypeElem = document.querySelector('#outputType');
const $inputTypeElem = document.querySelector('#inputType');
@ -34,9 +24,8 @@ let inputDirty = true;
let $activeOutputElem = null;
const search = searchToObject();
const markedVersions = {
master: 'https://cdn.jsdelivr.net/gh/markedjs/marked/marked.min.js'
master: 'https://cdn.jsdelivr.net/gh/markedjs/marked'
};
const markedVersionCache = {};
let delayTime = 1;
let checkChangeTimeout = null;
let markedWorker;
@ -109,7 +98,7 @@ function setInitialVersion() {
.then(function(json) {
for (let i = 0; i < json.versions.length; i++) {
const ver = json.versions[i];
markedVersions[ver] = 'https://cdn.jsdelivr.net/npm/marked@' + ver + '/marked.min.js';
markedVersions[ver] = 'https://cdn.jsdelivr.net/npm/marked@' + ver;
const opt = document.createElement('option');
opt.textContent = ver;
opt.value = ver;
@ -122,7 +111,7 @@ function setInitialVersion() {
return res.json();
})
.then(function(json) {
markedVersions.master = 'https://cdn.jsdelivr.net/gh/markedjs/marked@' + json[0].sha + '/marked.min.js';
markedVersions.master = 'https://cdn.jsdelivr.net/gh/markedjs/marked@' + json[0].sha;
})
.catch(function() {
// do nothing
@ -265,7 +254,7 @@ function addCommitVersion(value, text, commit) {
if (markedVersions[value]) {
return;
}
markedVersions[value] = 'https://cdn.jsdelivr.net/gh/markedjs/marked@' + commit + '/marked.min.js';
markedVersions[value] = 'https://cdn.jsdelivr.net/gh/markedjs/marked@' + commit;
const opt = document.createElement('option');
opt.textContent = text;
opt.value = value;
@ -285,15 +274,10 @@ function getPrCommit(pr) {
}
function setDefaultOptions() {
if (window.Worker) {
return messageWorker({
task: 'defaults',
version: markedVersions[$markedVerElem.value]
});
} else {
const defaults = marked.getDefaults();
setOptions(defaults);
}
return messageWorker({
task: 'defaults',
version: markedVersions[$markedVerElem.value]
});
}
function setOptions(opts) {
@ -325,39 +309,6 @@ function searchToObject() {
return obj;
}
function isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]';
}
function jsonString(input, level) {
level = level || 0;
if (isArray(input)) {
if (input.length === 0) {
return '[]';
}
const items = [];
let i;
if (!isArray(input[0]) && typeof input[0] === 'object' && input[0] !== null) {
for (i = 0; i < input.length; i++) {
items.push(' '.repeat(2 * level) + jsonString(input[i], level + 1));
}
return '[\n' + items.join('\n') + '\n]';
}
for (i = 0; i < input.length; i++) {
items.push(jsonString(input[i], level));
}
return '[' + items.join(', ') + ']';
} else if (typeof input === 'object' && input !== null) {
const props = [];
for (const prop in input) {
props.push(prop + ':' + jsonString(input[prop], level));
}
return '{' + props.join(', ') + '}';
} else {
return JSON.stringify(input);
}
}
function getScrollSize() {
const e = $activeOutputElem;
@ -391,32 +342,12 @@ function updateLink() {
}
function updateVersion() {
if (window.Worker) {
handleInput();
return Promise.resolve();
}
let promise;
if (markedVersionCache[$markedVerElem.value]) {
promise = Promise.resolve(markedVersionCache[$markedVerElem.value]);
} else {
promise = fetch(markedVersions[$markedVerElem.value])
.then(function(res) { return res.text(); })
.then(function(text) {
markedVersionCache[$markedVerElem.value] = text;
return text;
});
}
return promise.then(function(text) {
const script = document.createElement('script');
script.textContent = text;
$markedVer.parentNode.replaceChild(script, $markedVer);
$markedVer = script;
}).then(handleInput);
handleInput();
return Promise.resolve();
}
function checkForChanges() {
if (inputDirty && $markedVerElem.value !== 'commit' && $markedVerElem.value !== 'pr' && (typeof marked !== 'undefined' || window.Worker)) {
if (inputDirty && $markedVerElem.value !== 'commit' && $markedVerElem.value !== 'pr') {
inputDirty = false;
updateLink();
@ -436,35 +367,13 @@ function checkForChanges() {
const hash = version + markdown + optionsString;
if (lastInput !== hash) {
lastInput = hash;
if (window.Worker) {
delayTime = 100;
messageWorker({
task: 'parse',
version,
markdown,
options
});
} else {
const startTime = new Date();
const lexed = marked.lexer(markdown, options);
const lexedList = jsonString(lexed);
const parsed = marked.parser(lexed, options);
const endTime = new Date();
$previewElem.classList.remove('error');
$htmlElem.classList.remove('error');
$lexerElem.classList.remove('error');
const scrollPercent = getScrollPercent();
setParsed(parsed, lexedList);
setScrollPercent(scrollPercent);
delayTime = endTime - startTime;
setResponseTime(delayTime);
if (delayTime < 50) {
delayTime = 50;
} else if (delayTime > 500) {
delayTime = 1000;
}
}
delayTime = 100;
messageWorker({
task: 'parse',
version,
markdown,
options
});
}
}
checkChangeTimeout = window.setTimeout(checkForChanges, delayTime);
@ -484,6 +393,10 @@ function setResponseTime(ms) {
suffix = 's';
}
$responseTimeElem.textContent = amount + suffix;
$responseTimeElem.animate([
{ transform: 'scale(1.2)' },
{ transform: 'scale(1)' }
], 200);
}
function setParsed(parsed, lexed) {

View File

@ -8,8 +8,12 @@
<body>
<a href="https://github.com/markedjs/marked">
<img class="github-ribbon" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub">
</a>
<svg width="80" height="80" viewBox="0 0 250 250" style="fill:#202020; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
</svg>
</a>
<header>
<a href="../">
@ -74,10 +78,7 @@
</div>
</div>
</div>
<script id="markedCdn"></script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise/dist/es6-promise.js"></script>
<script src="https://cdn.jsdelivr.net/npm/unfetch/dist/unfetch.umd.js"></script>
<script src="./demo.js"></script>
<script src="./demo.js" type="module"></script>
</body>
</html>

View File

@ -1,18 +1,7 @@
/* globals marked, unfetch, ES6Promise, Promise */ // eslint-disable-line no-redeclare
if (!self.Promise) {
self.importScripts('https://cdn.jsdelivr.net/npm/es6-promise/dist/es6-promise.js');
self.Promise = ES6Promise;
}
if (!self.fetch) {
self.importScripts('https://cdn.jsdelivr.net/npm/unfetch/dist/unfetch.umd.js');
self.fetch = unfetch;
}
const versionCache = {};
let currentVersion;
onunhandledrejection = function(e) {
onunhandledrejection = (e) => {
throw e.reason;
};
@ -20,13 +9,14 @@ onmessage = function(e) {
if (e.data.version === currentVersion) {
parse(e);
} else {
loadVersion(e.data.version).then(function() {
loadVersion(e.data.version).then(() => {
parse(e);
});
}
};
function getDefaults() {
const marked = versionCache[currentVersion];
let defaults = {};
if (typeof marked.getDefaults === 'function') {
defaults = marked.getDefaults();
@ -71,6 +61,7 @@ function parse(e) {
break;
}
case 'parse': {
const marked = versionCache[currentVersion];
const options = mergeOptions(e.data.options);
const startTime = new Date();
const lexed = marked.lexer(e.data.markdown, options);
@ -121,22 +112,40 @@ function jsonString(input, level) {
function loadVersion(ver) {
let promise;
if (versionCache[ver]) {
promise = Promise.resolve(versionCache[ver]);
promise = Promise.resolve();
} else {
promise = fetch(ver)
.then(function(res) { return res.text(); })
.then(function(text) {
versionCache[ver] = text;
return text;
promise = import(ver + '/lib/marked.esm.js')
.catch(() => {
return fetch(ver + '/marked.min.js')
.then(function(res) { return res.text(); })
.then(function(text) {
try {
// eslint-disable-next-line no-new-func
Function(text)();
} catch (err) {
throw new Error('No esm or min build');
}
return (globalThis || global).marked;
});
})
.then((marked) => {
if (!marked) {
throw Error('No marked');
} else if (marked.marked) {
versionCache[ver] = marked.marked;
} else if (marked.default) {
versionCache[ver] = marked.default;
} else if (marked.parse) {
versionCache[ver] = marked;
} else {
throw new Error('Cannot find marked');
}
});
}
return promise.then(function(text) {
try {
// eslint-disable-next-line no-new-func
Function(text)();
} catch (err) {
throw new Error('Cannot load that version of marked');
}
return promise.then(() => {
currentVersion = ver;
}).catch((err) => {
console.error(err);
throw new Error('Cannot load that version of marked');
});
}

10
package-lock.json generated
View File

@ -33,6 +33,7 @@
"highlight.js": "^11.8.0",
"jasmine": "^5.1.0",
"markdown-it": "13.0.1",
"marked-highlight": "^2.0.4",
"node-fetch": "^3.3.2",
"recheck": "^4.4.5",
"rollup": "^3.27.0",
@ -5046,6 +5047,15 @@
"node": ">= 12"
}
},
"node_modules/marked-highlight": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/marked-highlight/-/marked-highlight-2.0.4.tgz",
"integrity": "sha512-hnm+rY3p+DQlSd2uY3zSXec+1kq5x9lD3+PWOMz0ROcil4Btcbt///Fto52jqWWt7XBGiTRk+1+w2rGfx2U2Sw==",
"dev": true,
"peerDependencies": {
"marked": "^4 || ^5 || ^6 || ^7"
}
},
"node_modules/marked-terminal": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-5.1.1.tgz",

View File

@ -65,6 +65,7 @@
"highlight.js": "^11.8.0",
"jasmine": "^5.1.0",
"markdown-it": "13.0.1",
"marked-highlight": "^2.0.4",
"node-fetch": "^3.3.2",
"recheck": "^4.4.5",
"rollup": "^3.27.0",