marked#marked TypeScript Examples

The following examples show how to use marked#marked. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: patchnotespage-preload.ts    From Creators.TF-Community-Launcher with MIT License 6 votes vote down vote up
window.addEventListener("DOMContentLoaded", () => {
    fetch("https://raw.githubusercontent.com/CreatorsTF/Creators.TF-Community-Launcher/master/changelog.md").then(async (res) => {
        if (res.status === 200) {
            res.text().then((data) => {
                document.getElementById("patchnotes").innerHTML = marked.parse(data);
            });
        } else {
            const fallbackChangelogLocalFile = fetch("../changelog.md").then((res) => res.text());
            document.getElementById("patchnotes").innerHTML = marked.parse(await fallbackChangelogLocalFile);
        }
    }).catch((err) => {
        console.log("Error fetching the latest changelog! Error: " + err);
    });
});
Example #2
Source File: docs.ts    From WebCord with MIT License 6 votes vote down vote up
// Code highlighting:

marked.setOptions({
    highlight: (code, lang) => {
        if (lang==='') return
        const language = (() => {
            if (lang==='jsonc') return 'json'; // highlight does not support JSONC as JSON alias
            return lang;
        })()
        return highlight(code, {language: language}).value;
    }
})
Example #3
Source File: App.ts    From vscode-todo-md with MIT License 6 votes vote down vote up
marked.Renderer.prototype.link = (href, title = '', text) => {
	let classes = '';
	if (text.startsWith('btn:')) {
		classes = 'btn btn--link';
		text = text.replace(/^btn:/, '');
	}

	if (href?.startsWith('command:')) {
		// let webview handle command Uri links
		return `<a href="${href}" title="${href}" class="${classes}">${text}</a>`;
	} else {
		return `<a data-href="${href}" href="javascript:void(0);" title="${href}" class="${classes}">${text}</a>`;
	}
};
Example #4
Source File: StuntItem.ts    From FateX with MIT License 6 votes vote down vote up
static getActorSheetData(sheetData) {
        if (CONFIG.FateX.global.useMarkdown) {
            for (const stunt of sheetData.stunts) {
                stunt.data.markdown = marked(stunt.data.description);
            }
        }

        for (const stunt of sheetData.stunts) {
            stunt.data.description = TextEditor.enrichHTML(stunt.data.description, {});
        }

        return sheetData;
    }
Example #5
Source File: ReleaseNoteDetails.tsx    From slice-machine with Apache License 2.0 6 votes vote down vote up
ReleaseNoteDetails: React.FC<ReleaseNoteDetailsProps> = ({
  releaseNote,
}) => {
  return (
    <Text
      sx={{
        "h1, h2, h3": {
          fontSize: "16px",
          fontWeight: 600,
          lineHeight: "20px",
        },
        p: {
          fontSize: "14px",
          fontWeight: 400,
          lineHeight: "20px",
        },
        b: {
          fontSize: "14px",
          fontWeight: 600,
          lineHeight: "20px",
        },
        code: {
          color: "code.orange",
        },
        li: {
          listStyleType: "disc",
          marginLeft: "25px",
          paddingLeft: "5px",
        },
      }}
      dangerouslySetInnerHTML={{
        __html: marked.parse(releaseNote),
      }}
    />
  );
}
Example #6
Source File: index.tsx    From reskript with MIT License 6 votes vote down vote up
export default function CaseDescription({currentCase}: Props) {
    if (!currentCase) {
        return <article className="description">未选择用例</article>;
    }

    const markdown = [
        `## ${currentCase.name}`,
        '',
        `- 创建:${currentCase.createAt} (${currentCase.createBy})`,
        `- 最后执行:${currentCase.lastRunAt} (${currentCase.lastRunBy})`,
        '',
        currentCase.description,
    ];
    const html = marked(markdown.join('\n'));

    // eslint-disable-next-line react/no-danger
    return <article className="description markdown-body" dangerouslySetInnerHTML={{__html: html}} />;
}
Example #7
Source File: content.service.ts    From open-source with MIT License 6 votes vote down vote up
compile(markdown: string, decodeHtml = false): string {
    const trimmed = this.trimIndentation(markdown);
    const decoded = decodeHtml ? this.decodeHtml(trimmed) : trimmed;
    const compiled = marked(decoded, {
      renderer: new marked.Renderer(),
      breaks: false,
      gfm: true,
      headerIds: true,
      silent: !isDevMode(),
      smartLists: true,
      smartypants: true,
      xhtml: true,
    });
    return this.sanitizer.sanitize(SecurityContext.HTML, compiled) || '';
  }
Example #8
Source File: renderer.ts    From vscode-docs-view with MIT License 6 votes vote down vote up
public async render(document: vscode.TextDocument, hovers: readonly vscode.Hover[]): Promise<string> {
		const parts = (hovers)
			.flatMap(hover => hover.contents)
			.map(content => this.getMarkdown(content))
			.filter(content => content.length > 0);

		if (!parts.length) {
			return '';
		}

		const markdown = parts.join('\n---\n');

		const highlighter = await this._highlighter.getHighlighter(document);
		return marked(markdown, {
			highlight: highlighter,
			sanitize: true
		});
	}
Example #9
Source File: TaskTitle.ts    From vscode-todo-md with MIT License 5 votes vote down vote up
// ──────────────────────────────────────────────────────────────────────
	render(h: CreateElement) {
		const returnEl = h('span', {}, []);
		const words = this.stuff.split(' ');

		const currentWords = [];

		for (const word of words) {
			if (
				word.length > 1 &&
				(word[0] === '#' || word[0] === '+' || word[0] === '@')
			) {
				const currentWordsAsText = `${currentWords.join(' ')} `;
				currentWords.length = 0;
				returnEl.children?.push(h('span', {
					domProps: {
						innerHTML: marked(currentWordsAsText),
					},
				}));

				let style;
				if (word[0] === '#') {
					style = this.styleForTag(word.slice(1));
				}

				returnEl.children?.push(h('span', {
					class: word[0] === '#' ? 'task__tag' : word[0] === '+' ? 'task__project' : 'task__context',
					style,
					domProps: {
						innerText: word,
					},
					on: {
						click: this.updateFilterValue,
					},
				}));

				returnEl.children?.push(h('span', ' '));
			} else {
				currentWords.push(word);
			}
		}

		const currentWordsAsText = currentWords.join(' ');

		returnEl.children?.push(h('span', {
			domProps: {
				innerHTML: marked(currentWordsAsText),
			},
		}));

		return returnEl;
	}
Example #10
Source File: patchnotespage-preload.ts    From Creators.TF-Community-Launcher with MIT License 5 votes vote down vote up
marked.setOptions({
    breaks: true,
    gfm: true,
    headerIds: false,
    baseUrl: "https://creators.tf/",
    smartypants: true,
    sanitize: false
});
Example #11
Source File: App.ts    From vscode-todo-md with MIT License 5 votes vote down vote up
/**
 * Render paragraph without actual `<p>` tag
 */
marked.Renderer.prototype.paragraph = text => `${text}`;
Example #12
Source File: markdown.pipe.ts    From sba-angular with MIT License 5 votes vote down vote up
transform(value: any): any {
    if (value && value.length > 0) {
      return marked(value);
    }
    return value;
  }
Example #13
Source File: markdown_formatted_text.ts    From commonwealth with GNU General Public License v3.0 5 votes vote down vote up
marked.setOptions({
  renderer,
  gfm: true, // use github flavored markdown
  smartypants: true,
  smartLists: true,
  xhtml: true,
});
Example #14
Source File: markdown_formatted_text.ts    From commonwealth with GNU General Public License v3.0 5 votes vote down vote up
renderer = new marked.Renderer()
Example #15
Source File: index.tsx    From moodtracker with MIT License 5 votes vote down vote up
export default function Blog() {
  const [posts, setPosts] = useState<
    { __html: string; dateString: string; title: string }[]
  >([]);
  useEffect(() => {
    Promise.all(
      Object.entries(BLOG_POSTS).map(async ([dateString, post]) => {
        const response = await fetch(String(post.url));
        let text = await response.text();
        if ("imageUrls" in post)
          for (const { pathname } of post.imageUrls)
            text = text.replace(
              pathname.slice(1).replace(/\..+\./, "."),
              pathname
            );
        const __html = marked.parse(text);
        return { __html, dateString, title: post.title };
      })
    ).then(setPosts);
  }, []);

  return (
    <Paper.Group>
      <Paper>
        <h2>Blog</h2>
        <p>Welcome to the MoodTracker blog!</p>
        <p>
          This space is for announcing interesting new features and
          developments. Less exciting stuff like bugfixes, performance
          improvements and minor UI changes won&apos;t get a mention here.
        </p>
        <Version />
      </Paper>
      {posts.length ? (
        posts.map(({ __html, dateString, title }) => (
          <Paper key={dateString}>
            <article itemScope itemType="http://schema.org/BlogPosting">
              <h2>
                {title}
                <SubHeading>
                  <time
                    dateTime={dateString}
                    itemProp="dateCreated datePublished pubdate"
                  >
                    {dateFormatter.format(new Date(dateString))}
                  </time>
                </SubHeading>
              </h2>
              <div dangerouslySetInnerHTML={{ __html }} />
            </article>
          </Paper>
        ))
      ) : (
        <div>
          <Spinner />
        </div>
      )}
    </Paper.Group>
  );
}
Example #16
Source File: createMadrParser.ts    From backstage with Apache License 2.0 5 votes vote down vote up
createMadrParser = (
  options: MadrParserOptions = {},
): AdrParser => {
  const locationTemplate =
    options.locationTemplate ?? DEFAULT_LOCATION_TEMPLATE;
  const dateFormat = options.dateFormat ?? MADR_DATE_FORMAT;

  return async ({ entity, content, path }) => {
    const tokens = marked.lexer(content);
    if (!tokens.length) {
      throw new Error('ADR has no content');
    }

    // First h1 header should contain ADR title
    const adrTitle = (
      tokens.find(
        t => t.type === 'heading' && t.depth === 1,
      ) as marked.Tokens.Heading
    )?.text;

    // First list should contain status & date metadata (if defined)
    const listTokens = (
      tokens.find(t => t.type === 'list') as marked.Tokens.List
    )?.items;
    const adrStatus = listTokens
      .find(t => /^status:/i.test(t.text))
      ?.text.replace(/^status:/i, '')
      .trim()
      .toLocaleLowerCase('en-US');
    const adrDateTime = DateTime.fromFormat(
      listTokens
        .find(t => /^date:/i.test(t.text))
        ?.text.replace(/^date:/i, '')
        .trim() ?? '',
      dateFormat,
    );
    const adrDate = adrDateTime.isValid
      ? adrDateTime.toFormat(MADR_DATE_FORMAT)
      : undefined;

    return {
      title: adrTitle ?? path.replace(/\.md$/, ''),
      text: content,
      status: adrStatus,
      date: adrDate,
      location: applyArgsToFormat(locationTemplate, {
        namespace: entity.metadata.namespace || 'default',
        kind: entity.kind,
        name: entity.metadata.name,
        record: path,
      }),
    };
  };
}
Example #17
Source File: index.ts    From auto-changelog with MIT License 5 votes vote down vote up
async function run() {
  const inputs = await getInputs();

  const octokit = getOctokit(getToken());

  const {
    repo: { owner, repo },
    sha,
  } = context;

  let semver: SemVer.SemVer | null = null;

  if (inputs.semver) {
    semver = SemVer.parse(inputs.releaseName, { includePrerelease: true });

    if (semver == null)
      return setFailed(
        `Expected a semver compatible releaseName, got "${inputs.releaseName}" instead.`,
      );
  }

  let prerelease = false;

  if (semver != null) prerelease = semver.prerelease.length > 0;

  const { sha: tagRef, name: tagName } = await getTagSha({
    octokit,
    owner,
    repo,
    sha,
    semver,
    prerelease,
  });

  let changelog = await generate({
    octokit,
    owner,
    repo,
    sha,
    tagRef,
    inputs,
  });

  if (inputs.mentionNewContributors) {
    const { data } = await octokit.rest.repos.generateReleaseNotes({
      owner,
      repo,
      tag_name: inputs.releaseName,
      previous_tag_name: tagName,
    });

    const tokens = marked.lexer(data.body);

    const index = tokens.findIndex(
      (token) => token.type === "heading" && token.text === "New Contributors",
    );

    const token = tokens[index + 1];

    if (token.type === "list")
      changelog += `\n\n## New Contributors\n${token.raw}\n`;
  }

  if (inputs.includeCompare && tagName != null) {
    changelog += `\n\n**Full Changelog**: https://github.com/${owner}/${repo}/compare/${tagName}...${inputs.releaseName}`;
  }

  info(`-> prerelease: ${prerelease}`);

  setOutput("prerelease", prerelease);

  info(`-> changelog: "${changelog}"`);

  setOutput("changelog", changelog);
}
Example #18
Source File: layerContentPreview.tsx    From prism-frontend with MIT License 5 votes vote down vote up
LayerContentPreview = ({ layerId, classes }: PreviewProps) => {
  const [open, setOpen] = useState(false);
  const [content, setContent] = useState('');
  const contentRef = useRef<HTMLHeadingElement>(null);
  const layer = LayerDefinitions[layerId || 'admin_boundaries'];
  const selectedLayers = useSelector(layersSelector);
  // display if layer without group or main layer in group
  const canDisplayContent = isMainLayer(layerId as string, selectedLayers);
  const hasContent = layer.contentPath?.length;
  const domId = layer.contentPath?.split('#')?.[1];

  marked.use({ sanitizer: DOMPurify.sanitize });

  useLayoutEffect(() => {
    if (contentRef.current !== null) {
      contentRef.current.scrollIntoView({
        behavior: 'smooth',
        block: 'start',
      });
    }
  });

  useEffect(() => {
    const path = `${process.env.PUBLIC_URL}/${layer.contentPath}`;

    if (hasContent) {
      fetch(path)
        .then(response => response.text())
        .then(text => setContent(text));
    }
  }, [hasContent, layer.contentPath]);

  const transform: HTMLReactParserOptions = {
    replace: domNode => {
      if (domNode instanceof Element && domNode.attribs?.id === domId) {
        return React.createElement(
          domNode.name,
          {
            id: domNode.attribs.id,
            ref: contentRef,
          },
          domToReact(domNode.children, transform),
        );
      }
      return domNode;
    },
  };

  return (
    <Grid item>
      <IconButton size="small" className={classes.icon}>
        {canDisplayContent && hasContent && (
          <InfoIcon fontSize="inherit" onClick={() => setOpen(true)} />
        )}
      </IconButton>
      <Dialog
        maxWidth="md"
        open={open}
        keepMounted
        onClose={() => setOpen(false)}
        aria-labelledby="dialog-preview"
      >
        <DialogContent>
          <Typography color="textSecondary">
            {parse(marked(content), transform)}
          </Typography>
        </DialogContent>
      </Dialog>
    </Grid>
  );
}
Example #19
Source File: docs.ts    From WebCord with MIT License 5 votes vote down vote up
function loadMarkdown(mdBody: HTMLElement, mdFile: string) {
    mdBody.innerHTML = sanitize(marked.parse(readFileSync(mdFile).toString()));
}
Example #20
Source File: preview.ts    From xplorer with Apache License 2.0 4 votes vote down vote up
Preview = async (filePath: string): Promise<void> => {
	if (!isTauri) {
		PromptError('Preview unavailable', 'Preview is currently unavailable on Web version');
		return;
	}
	closePreviewFile();

	const previewElement = document.createElement('div');
	previewElement.classList.add('preview');

	const changePreview = (html: string) => {
		if (!html) return;
		previewElement.innerHTML = `
                <div class="preview-header">
                    <span class="preview-path">${getBasename(filePath)}</span>
                    <span class="preview-exit-btn">&times;</span>
                </div>
                ${html}
                `;

		document.querySelector<HTMLElement>('.main-box').scrollTop = 0;
		document.querySelector<HTMLElement>('.main-box').style.overflowY = 'hidden';
		GET_WORKSPACE_ELEMENT(1).classList.toggle('workspace-split');
		GET_WORKSPACE_ELEMENT(1).appendChild(previewElement);
		previewElement.querySelector('.preview-exit-btn').addEventListener('click', () => closePreviewFile());
		return;
	};

	const ext = filePath.split('.').pop().toLowerCase();

	let previewed = true;
	if (ext === 'pdf') {
		changePreview(
			`<object data="${new FileAPI(
				filePath
			).readAsset()}#toolbar=0&navpanes=1" type="application/pdf" class="preview-object"><embed src="${new FileAPI(
				filePath
			).readAsset()}#toolbar=0&navpanes=1" type="application/pdf" /></object>`
		);
	} else if (HTML_TYPE.indexOf(ext) !== -1) {
		changePreview(`<iframe src="${filePath}" title="${filePath}" class="preview-object"></iframe>`);
	} else if (['doc', 'docb', 'docm', 'dot', 'dotm', 'docx', 'rtf'].indexOf(ext) !== -1) {
		const { convertToHtml } = require('./mammoth.browser.min');
		const buf = await new FileAPI(filePath).readBuffer();
		const { value } = await convertToHtml({ arrayBuffer: buf });
		changePreview(`<div class='preview-object' data-type="docx">${eURLify(value)}</div>`);
	} else if (['xlsx', 'xls', 'xlsb', 'xls', 'ods', 'fods', 'csv'].indexOf(ext) !== -1) {
		const xlsxData = xlsx.read(await new FileAPI(filePath).readBuffer(), { type: 'buffer' });
		const parsedData = xlsx.utils.sheet_to_html(xlsxData.Sheets[xlsxData.SheetNames[0]]);
		changePreview(`<div class='preview-object' data-type="xlsx">${URLify(parsedData)}</div>`);
	} else if (IMAGE_TYPES.indexOf(ext) !== -1) {
		changePreview(`<div class="preview-object" data-type="img"><img src="${new FileAPI(filePath).readAsset()}" data-path="${filePath}" /></div>`);
	} else if (VIDEO_TYPES.indexOf(ext) !== -1) {
		changePreview(
			`<div class="preview-object" data-type="video"><video controls="" controlsList="nodownload"><source src="${new FileAPI(
				filePath
			).readAsset()}"></video></div>`
		);
	} else if (AUDIO_TYPES.indexOf(ext) !== -1) {
		changePreview(
			`	
			<div class="preview-object" data-type="audio">
				<audio controls="" controlsList="nodownload">
					<source src="${new FileAPI(filePath).readAsset()}">
				</audio>
			</div>`
		);
	} else if (PLAIN_TEXT.indexOf(ext) !== -1) {
		changePreview(`<div class='preview-object' data-type="txt">${await new FileAPI(filePath).readFile()}</div>`);
	} else if (MARKDOWN_TYPES.indexOf(ext) !== -1) {
		const html = marked(await new FileAPI(filePath).readFile());
		changePreview(`<div class='preview-object' data-type="md">${eURLify(html)}</div>`);
		previewElement.querySelectorAll('img').forEach(async (img) => {
			if (!isValidURL(img.src)) {
				let imgData = new FileAPI(img.src);
				if (!(await imgData.exists())) {
					let imgPath = new URL(img.src).pathname;
					if (imgPath.charAt(0) === '/') imgPath = imgPath.substr(1);
					imgData = new FileAPI(`${getDirname(filePath)}${imgPath}`);
					if (await imgData.exists()) {
						img.src = imgData.readAsset();
					}
				} else {
					img.src = await imgData.readFile();
				}
			}
		});
	} else {
		try {
			const fileData = new FileAPI(filePath);
			const property = await fileData.properties();
			let highlight = true;
			if (property.size > 1024 * 100) {
				const confirm = await ConfirmDialog(
					'File too large',
					'File size is larger than 100kb, proceeding previewing file might crashes Xplorer, do you want to proceed?',
					'Yes'
				);
				if (!confirm) return;
			}
			if (property.size > 1024 * 10) {
				highlight = false;
			}
			const fileText = await fileData.readFile();
			const highlightedCode = hljs.highlightAuto(fileText).value;

			changePreview(
				highlight
					? `<pre class='preview-object' data-type="code"><code>${highlightedCode}</code></pre>`
					: `<div class='preview-object' data-type='txt'>${fileText}</div>`
			);
		} catch (_) {
			previewed = false;
		}
	}

	if (!previewed) PromptError('No preview handler', 'There is no preview handler for this file type yet.');
}
Example #21
Source File: markdown_formatted_text.ts    From commonwealth with GNU General Public License v3.0 4 votes vote down vote up
MarkdownFormattedText: m.Component<
  {
    doc: string;
    hideFormatting?: boolean;
    collapse?: boolean;
    searchTerm?: string;
    openLinksInNewTab?: boolean;
    cutoffText?: number;
  },
  {
    cachedDocWithHighlights: string;
    cachedResultWithHighlights;
  }
> = {
  view: (vnode) => {
    const {
      doc,
      hideFormatting,
      collapse,
      searchTerm,
      openLinksInNewTab,
      cutoffText,
    } = vnode.attrs;
    if (!doc) return;
    renderer.link = (href, title, text) => {
      return `<a ${
        href.indexOf('://commonwealth.im/') !== -1 && 'target="_blank"'
      } ${
        openLinksInNewTab ? 'target="_blank"' : ''
      } href="${href}">${text}</a>`;
    };

    // if we're showing highlighted search terms, render the doc once, and cache the result
    if (searchTerm) {
      // TODO: Switch trim system to match QFT component
      if (JSON.stringify(doc) !== vnode.state.cachedDocWithHighlights) {
        const unsanitized = marked.parse(doc.toString());
        const sanitized = DOMPurify.sanitize(unsanitized, {
          ALLOWED_TAGS: ['a'],
          ADD_ATTR: ['target'],
        });
        const vnodes = m.trust(sanitized);
        const root = document.createElement('div');
        m.render(root, vnodes);
        const textToHighlight = root.innerText
          .replace(/\n/g, ' ')
          .replace(/\ +/g, ' ');
        const chunks = findAll({
          searchWords: [searchTerm.trim()],
          textToHighlight,
        });
        vnode.state.cachedDocWithHighlights = JSON.stringify(doc);
        vnode.state.cachedResultWithHighlights = chunks.map(
          ({ end, highlight, start }, index) => {
            const middle = 15;
            const subString = textToHighlight.substr(start, end - start);
            let text = smartTruncate(
              subString,
              chunks.length <= 1 ? 150 : 40 + searchTerm.trim().length,
              chunks.length <= 1
                ? {}
                : index === 0
                ? { position: 0 }
                : index === chunks.length - 1
                ? {}
                : { position: middle }
            );
            if (subString[subString.length - 1] === ' ') {
              text += ' ';
            }
            if (subString[0] === ' ') {
              text = ` ${text}`;
            }
            return highlight ? m('mark', text) : m('span', text);
          }
        );
      }
      return m(
        '.MarkdownFormattedText',
        {
          class: collapse ? 'collapsed' : '',
        },
        vnode.state.cachedResultWithHighlights
      );
    }

    let truncatedDoc = doc;
    if (cutoffText)
      truncatedDoc = doc.slice(
        0,
        doc.split('\n', cutoffText).join('\n').length
      );
    const unsanitized = marked.parse(truncatedDoc.toString());
    const sanitized = hideFormatting
      ? DOMPurify.sanitize(unsanitized, {
          ALLOWED_TAGS: ['a'],
          ADD_ATTR: ['target'],
        })
      : DOMPurify.sanitize(unsanitized, {
          USE_PROFILES: { html: true },
          ADD_ATTR: ['target'],
        });
    const results = m.trust(sanitized);

    return m(
      '.MarkdownFormattedText',
      {
        class: collapse ? 'collapsed' : '',
      },
      results
    );
  },
}