Skip to content

Commit

Permalink
enable new notebook button and fix highlighting
Browse files Browse the repository at this point in the history
  • Loading branch information
menduz committed Aug 22, 2020
1 parent 215401c commit 66f01a0
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 185 deletions.
6 changes: 3 additions & 3 deletions docs/index.js

Large diffs are not rendered by default.

186 changes: 186 additions & 0 deletions src/components/Markdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import React, {
useRef,
useCallback,
ReactNode,
MouseEvent as ReactMouseEvent,
useState,
useEffect,
useLayoutEffect,
} from "react";
import { graphviz } from "@hpcc-js/wasm";
import type * as monacoEditor from "monaco-editor/esm/vs/editor/editor.api";
import { DownloadSvg } from "./DownloadSvg";
import { SequenceDiagram } from "src/diagrams";
declare var monaco: typeof monacoEditor;

var escapeReplacements: Record<string, string> = {
amp: "&",
lt: "<",
gt: ">",
quot: '"',
"#39": "'",
};

function unescape(token: { text: string }) {
return token.text.replace(/&(amp|lt|gt|quot|#39);/g, function (_, r) {
return escapeReplacements[r];
});
}

function Code($: { language: string; code: string }) {
const theRef = useRef<HTMLPreElement>(null);
const [language, setLanguage] = useState<string>("txt");
const [code, setCode] = useState<string>("");

useLayoutEffect(() => {
if (theRef.current) {
monaco.editor
.colorize(code || "", language || "text", {
tabSize: 2,
})
.then(
($) => {
theRef.current!.innerHTML = $;
},
(e) => {
debugger;
console.error(e);
}
);
}
}, [theRef, code, language]);

useEffect(() => {
if ($.code != code) setCode($.code);
if ($.language != language) setLanguage($.language);
});

return (
<pre ref={theRef} className="vs">
{code}
</pre>
);
}

function Dot(props: { code: string }) {
const [html, setHtml] = useState("Loading...");
const [error, setError] = useState<string>();

useEffect(() => {
graphviz
.dot(props.code, "svg", { wasmFolder: "wasm" })
.then(($) => {
setError("");
setHtml($);
})
.catch((e) => {
setError(e.message);
});
}, [props.code]);

return (
<>
{error && <pre>{error}</pre>}

<DownloadSvg dangerouslySetInnerHTML={{ __html: html }} />
</>
);
}

export function renderMarkdown($: marked.Token, key: number = 0): any {
if ("type" in $) {
if ($.type === "heading") {
switch ($.depth) {
case 1:
return <h1 key={key}>{unescape($)}</h1>;
case 2:
return <h2 key={key}>{unescape($)}</h2>;
case 3:
return <h3 key={key}>{unescape($)}</h3>;
case 4:
return <h4 key={key}>{unescape($)}</h4>;
case 5:
return <h5 key={key}>{unescape($)}</h5>;
default:
return <h6 key={key}>{unescape($)}</h6>;
}
} else if ($.type === "code") {
if ($.lang == "sequence") {
return <SequenceDiagram key={key} input={unescape($) || ""} />;
} else if ($.lang == "dot") {
return <Dot key={key} code={unescape($) || ""} />;
}
return <Code key={key} language={$.lang || ""} code={unescape($)!} />;
} else if ($.type === "paragraph") {
if ("tokens" in $) {
return <p key={key}>{($ as any).tokens.map(renderMarkdown)}</p>;
}
return <p key={key}>{unescape($)}</p>;
} else if ($.type === "blockquote") {
if ("tokens" in $) {
return (
<blockquote key={key}>
{($ as any).tokens.map(renderMarkdown)}
</blockquote>
);
}
return <blockquote key={key}>{unescape($)}</blockquote>;
} else if ($.type === "em") {
if ("tokens" in $) {
return <em key={key}>{($ as any).tokens.map(renderMarkdown)}</em>;
}
return <em key={key}>{unescape($)}</em>;
} else if ($.type === "strong") {
if ("tokens" in $) {
return <b key={key}>{($ as any).tokens.map(renderMarkdown)}</b>;
}
return <b key={key}>{unescape($)}</b>;
} else if ($.type === "html") {
return <span key={key}>{JSON.stringify($.raw, null, 2)}</span>;
} else if ($.type === "text") {
if ("tokens" in $) {
return <span key={key}>{($ as any).tokens.map(renderMarkdown)}</span>;
}
return <span key={key}>{unescape($)}</span>;
} else if ($.type === "codespan") {
return <code key={key}>{unescape($)}</code>;
} else if ($.type === "link") {
return <span key={key}>{unescape($)}</span>;
} else if ($.type === "space") {
return <div key={key} className="my-2" />;
} else if ($.type === "escape") {
return <span key={key}>{unescape($)}</span>;
} else if ($.type === "hr") {
return <hr key={key} />;
} else if ($.type === "list_item") {
if ("tokens" in $) {
return <li key={key}>{($ as any).tokens.map(renderMarkdown)}</li>;
}
return <li key={key}>{unescape($)}</li>;
} else if (($.type as any) === "list") {
const l = $ as marked.Tokens.List;
if (l.ordered) {
return (
<ol key={key} start={(l.start as any) as number}>
{l.items.map(renderMarkdown)}
</ol>
);
}
return <ul key={key}>{l.items.map(renderMarkdown)}</ul>;
} else {
return (
<span key={key} style={{ color: "red!important" }}>
{process.env.NODE_ENV == "production"
? $.raw
: JSON.stringify($, null, 2)}
</span>
);
}
}

return (
<code key={key} style={{ color: "orange!important" }}>
{JSON.stringify($, null, 2)}
</code>
);
}
8 changes: 6 additions & 2 deletions src/diagrams.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { injectScript } from "./helpers";
import React, { useEffect, useRef, useState } from "react";
import { DownloadSvg } from "./components/DownloadSvg";

export const monospaceFont = `Menlo, Monaco, "Courier New", monospace`
export const monospaceFont = `Menlo, Monaco, "Courier New", monospace`;

const font = `14px ${monospaceFont}`;

Expand Down Expand Up @@ -684,7 +684,11 @@ export function SequenceDiagram(props: { input: string; className?: string }) {

if (!error) {
return (
<div className={className} style={{ width, height }} ref={divRef}>
<div
className={className}
style={{ width, height: height + 32 /* download button height */ }}
ref={divRef}
>
<RenderDiagram diagram={diagram} />
</div>
);
Expand Down
18 changes: 18 additions & 0 deletions src/firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import app from "firebase/app";
import "firebase/auth";
import "firebase/database";
import "firebase/analytics";
import future from "fp-future";

// Your web app's Firebase configuration
let firebaseConfig = {
Expand Down Expand Up @@ -77,5 +78,22 @@ export function logException(error: Error | string) {
export function logPageView(page_location: string, page_path: string) {
app.analytics!().logEvent("page_view", { page_location, page_path } as any);
}
declare var Firepad: any;

export async function newNotebookWithContent(content: string) {
const ret = future<{succeed: boolean, ref: app.database.Reference, data: any, owner: string}>();
let owner =
(app.auth().currentUser && app.auth().currentUser!.uid) || "anonymous";

const ref = newNotebook(owner);

const headless = new Firepad.Headless(ref);

headless.setText(content, function (data: any, succeed: boolean) {
ret.resolve({ ref, data, succeed, owner });
});

return ret;
}

globalThis["firebase"] = app;
Loading

0 comments on commit 66f01a0

Please sign in to comment.