LCOV - code coverage report
Current view: top level - pepper - core.ts (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 58 116 50.0 %
Date: 2021-03-12 10:43:40 Functions: 5 17 29.4 %

          Line data    Source code
       1             : /**
       2             :  * INFO: Tools to manipulate and render Markdown
       3             :  */
       4             : 
       5           1 : import {expandGlobSync, WalkEntry} from "https://deno.land/std/fs/mod.ts";
       6           1 : import {Remarkable} from '../external/remarkable.js';
       7           1 : import meta from '../external/remarkable-meta.js';
       8           1 : import wikilinks from '../external/remarkable-wikilink.js';
       9           1 : import {remarkablePluginHeadingId} from '../external/remarkable-plugin-heading-id.js';
      10           1 : import hljs from '../external/highlight.js';
      11             : 
      12           1 : let md = new Remarkable({
      13           1 :     html: true,
      14           0 :     highlight: function (str: any, lang: any) {
      15           0 :         if (lang && hljs.getLanguage(lang)) {
      16           0 :             try {
      17           0 :                 return hljs.highlight(lang, str).value;
      18           0 :             } catch (err) {
      19           0 :             }
      20           0 :         }
      21             : 
      22           0 :         try {
      23           0 :             return hljs.highlightAuto(str).value;
      24           0 :         } catch (err) {
      25           0 :         }
      26             : 
      27           0 :         return ''; // use external default escaping
      28           0 :     }
      29           1 : });
      30           1 : md.use(meta);
      31           1 : md.use(wikilinks)
      32           1 : md.use(remarkablePluginHeadingId, {
      33             :     // this option is for create id, optional option, default value is (level, content, idx) => `${content}`
      34           0 :     createId: (
      35           0 :         level: 1 | 2 | 3 | 4 | 5 | 6,
      36           0 :         content: string,
      37           0 :         idx: number
      38           0 :     ) => normaliseLink(content)
      39           1 : })
      40           1 : md.inline.ruler.disable([
      41           1 :     'escape'
      42           1 : ]);
      43             : 
      44           0 : export function createMarkdownTOC(content: string) {
      45           0 :     return content.split("\n")
      46           0 :         .filter(x => x.startsWith("##"))
      47           0 :         .map(x => x.substring(1))
      48           0 :         .map(x => {
      49           0 :             let parts = x.split("# ")
      50           0 :             return parts[0] + '# ' + `<a href="%${normaliseLink(parts[1] == undefined ? "" : parts[1])}">${parts[1]}</a>`
      51           0 :         }).map(x => x.replaceAll("# ", "- ").replaceAll("#", "\t").replaceAll("%", "#"))
      52           0 :         .join("\n")
      53             :     //
      54           0 : }
      55             : 
      56           0 : export function renderMarkdownSnippetAsHTML(snippet: string) {
      57           0 :     let renderer = new Remarkable({"html": true});
      58           0 :     return md.render(snippet)
      59           0 : }
      60             : 
      61           1 : abstract class SourceFile {
      62             :     protected _content: string;
      63             : 
      64             : 
      65           1 :     constructor(content: string) {
      66           4 :         this._content = content;
      67           1 :     }
      68             : 
      69             :     abstract renderToHTML(): string;
      70           1 : }
      71             : 
      72           1 : export class MarkdownFile extends SourceFile {
      73           0 :     get mTime(): Date {
      74           0 :         return this._mTime;
      75           0 :     }
      76           0 :     public get backlinks(): Set<string> {
      77           0 :         return this._backlinks;
      78           0 :     }
      79             : 
      80           0 :     public get title(): string {
      81           0 :         return this._title;
      82           0 :     }
      83             : 
      84           0 :     public get content(): string {
      85           0 :         return this._content;
      86           0 :     }
      87             : 
      88           0 :     public set content(value: string) {
      89           0 :         this._content = value;
      90           0 :     }
      91             : 
      92             :     private readonly _title: string
      93           4 :     private _backlinks: Set<string> = new Set();
      94             :     private readonly _mTime: Date
      95             : 
      96           1 :     constructor(title: string, content: string, mTime: Date) {
      97           4 :         super(content);
      98           4 :         this._title = title
      99           4 :         this._mTime = mTime
     100           1 :     }
     101             : 
     102           0 :     renderToHTML(): string {
     103           0 :         const env = {frontMatter: undefined};
     104           0 :         const result = md.render(this.content, env);
     105             :         // console.log(env);
     106           0 :         return result;
     107           0 :     }
     108           1 : }
     109             : 
     110           4 : function globFiles(path: string, extension: string): Array<WalkEntry> {
     111           4 :     const files = [];
     112           4 :     for (const file of expandGlobSync(`${path}/**/*.${extension}`)) {
     113          13 :         files.push(file);
     114           4 :     }
     115           4 :     return files;
     116           1 : }
     117             : 
     118           0 : export function normaliseLink(title: string): string {
     119           0 :     return title.toLowerCase().replaceAll(" ", "-").replaceAll("'", "").replaceAll("(", "").replaceAll(")", "")
     120           0 : }
     121             : 
     122           1 : export function getAllMardownFiles(path: string): Array<WalkEntry> {
     123           4 :     return globFiles(path, 'md');
     124           1 : }
     125             : 
     126           0 : export function getAllJupyterFiles(path: string): Array<WalkEntry> {
     127           0 :     return globFiles(path, 'ipynb');
     128           0 : }
     129             : 
     130             : export interface Link { // given a link "ThisIsTheReal#Header1|This is the Given"
     131             :     titleName?: string // This is the Given
     132             :     fragment?: string // Header 1
     133             :     realName: string // ThisIsTheReal
     134             : }
     135             : 
     136           1 : export function parseWikiLink(wikilink: string): Link {
     137           5 :     const link: Link = {realName: ""}
     138           5 :     if (wikilink.includes("|")) {
     139           7 :         const parts = wikilink.split("|")
     140           7 :         link.titleName = parts[1]
     141           7 :         link.realName = parts[0]
     142           7 :     } else {
     143           7 :         link.realName = wikilink
     144           5 :     }
     145           5 :     if (link.realName.includes("#")) {
     146           7 :         const parts = link.realName.split("#")
     147           7 :         link.realName = parts[0]
     148           7 :         link.fragment = parts[1]
     149           5 :     }
     150           5 :     if (link.titleName == null) {
     151           7 :         link.titleName = link.realName
     152           5 :     }
     153           5 :     return link
     154           1 : }

Generated by: LCOV version 1.15