Skip to content

Commit

Permalink
Merge pull request #6 from siefkenj/md
Browse files Browse the repository at this point in the history
Markdown and Vite Support
  • Loading branch information
siefkenj authored Oct 2, 2023
2 parents 680040e + 40eb898 commit 45cf71c
Show file tree
Hide file tree
Showing 15 changed files with 4,836 additions and 17,073 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

# production
/build
/dist

# misc
.DS_Store
Expand Down
7 changes: 4 additions & 3 deletions public/index.html → index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Playground for pretty-printing latex code"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="apple-touch-icon" href="/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="manifest" href="/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Expand All @@ -39,5 +39,6 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
21,643 changes: 4,627 additions & 17,016 deletions package-lock.json

Large diffs are not rendered by default.

85 changes: 39 additions & 46 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,60 @@
"private": true,
"homepage": "./",
"dependencies": {
"@codemirror/lang-html": "^6.4.6",
"@codemirror/lang-html": "6.4.6",
"@codemirror/lang-javascript": "^6.2.1",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/language": "^6.9.0",
"@codemirror/lang-markdown": "^6.2.1",
"@codemirror/language": "^6.9.1",
"@codemirror/legacy-modes": "^6.3.3",
"@codemirror/view": "^6.17.1",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.4.3",
"@types/katex": "^0.16.2",
"@uiw/react-codemirror": "^4.21.13",
"@unified-latex/unified-latex-lint": "^1.4.1",
"@unified-latex/unified-latex-prettier": "^1.4.1",
"@unified-latex/unified-latex-to-hast": "^1.4.1",
"@unified-latex/unified-latex-util-parse": "^1.4.1",
"@unified-latex/unified-latex-util-pegjs": "^1.4.0",
"@unified-latex/unified-latex-util-pgfkeys": "^1.4.0",
"@unified-latex/unified-latex-util-print-raw": "^1.4.0",
"@unified-latex/unified-latex-util-replace": "^1.4.0",
"@unified-latex/unified-latex-util-split": "^1.4.0",
"@codemirror/view": "^6.21.0",
"@types/katex": "^0.16.3",
"@uiw/react-codemirror": "^4.21.18",
"@unified-latex/unified-latex-lint": "^1.5.0",
"@unified-latex/unified-latex-prettier": "^2.4.2",
"@unified-latex/unified-latex-to-hast": "^1.5.0",
"@unified-latex/unified-latex-to-mdast": "^1.5.0",
"@unified-latex/unified-latex-util-parse": "^1.4.2",
"@unified-latex/unified-latex-util-pegjs": "^1.4.2",
"@unified-latex/unified-latex-util-pgfkeys": "^1.4.2",
"@unified-latex/unified-latex-util-print-raw": "^1.4.2",
"@unified-latex/unified-latex-util-replace": "^1.4.2",
"@unified-latex/unified-latex-util-split": "^1.4.2",
"color": "^4.2.3",
"comlink": "^4.4.1",
"easy-peasy": "^5.2.0",
"easy-peasy": "^6.0.3",
"globalthis": "^1.0.3",
"katex": "^0.16.8",
"mdast-util-to-markdown": "^2.1.0",
"mdast-util-to-string": "^4.0.0",
"parse-entities": "^4.0.1",
"pegjs": "0.10.0",
"prettier": "^2.8.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "^5.0.1",
"react-select": "^5.7.0",
"react-markdown": "^9.0.0",
"react-select": "^5.7.5",
"react-split-pane": "github:techfreaque/react-split-pane",
"typescript": "^4.9.5",
"rehype-katex": "^7.0.0",
"remark-gfm": "^4.0.0",
"remark-math": "^6.0.0",
"remark-stringify": "^10.0.3",
"unified": "^10.1.2",
"vfile": "^5.3.6",
"web-vitals": "^3.1.1",
"worker-loader": "^3.0.8",
"workerize-loader": "^2.0.2"
"vfile": "^6.0.1",
"web-vitals": "^3.5.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
"devDependencies": {
"@vitejs/plugin-react": "^4.1.0",
"typescript": "^5.2.2",
"vite": "^4.4.9",
"vite-plugin-svgr": "^4.1.0",
"vite-tsconfig-paths": "^4.2.1"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
"scripts": {
"start": "vite",
"build": "vite build"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
"prettier": {
"tabWidth": 4
}
}
6 changes: 6 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Editor } from "./components/editor";
import { FormattedDisplay } from "./components/formatted-display";
import { JsonDisplay } from "./components/json-display";
import { PrettierDocDisplay } from "./components/prettier-doc-display";
import { MarkdownView } from "./components/markdown-view";

function App() {
const currDisplay = useStoreState((state) => state.activeView);
Expand All @@ -23,6 +24,7 @@ function App() {
const setApplyLints = useStoreActions((a) => a.setApplyLints);
const texParsed = useStoreState((state) => state.parsed);
const htmlRender = useStoreState((state) => state.html);
const markdownRender = useStoreState((state) => state.markdown);
const lints = useStoreState((state) => state.lintDescs);

const [showLints, setShowLints] = React.useState(false);
Expand Down Expand Up @@ -51,6 +53,9 @@ function App() {
if (currDisplay === "html") {
rightPanel = <HtmlView htmlInput={htmlRender} />;
}
if (currDisplay === "markdown") {
rightPanel = <MarkdownView mdast={markdownRender} />;
}

return (
<div className="App">
Expand Down Expand Up @@ -78,6 +83,7 @@ function App() {
</option>
<option value="debug">Debug View</option>
<option value="html">HTML View</option>
<option value="markdown">Markdown View</option>
</select>{" "}
<label>
Show Lints:{" "}
Expand Down
17 changes: 16 additions & 1 deletion src/async-worker/parsing-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@ import * as Ast from "@unified-latex/unified-latex-types";
// @ts-ignore
import Prettier from "prettier/esm/standalone.mjs";
import { prettierPluginLatex } from "@unified-latex/unified-latex-prettier";
import { parse } from "@unified-latex/unified-latex-util-parse";
import {
parse,
unifiedLatexFromString,
} from "@unified-latex/unified-latex-util-parse";
import { convertToHtml } from "@unified-latex/unified-latex-to-hast";
import { unifiedLatexToMdast } from "@unified-latex/unified-latex-to-mdast";
import { decorateArrayForPegjs } from "@unified-latex/unified-latex-util-pegjs";
import { unified } from "unified";
import { toMarkdown } from "mdast-util-to-markdown";

// @ts-ignore
import peg from "pegjs";
Expand Down Expand Up @@ -83,6 +89,15 @@ const exposed = {
let output = parse(texInput);
return convertToHtml(output);
},
formatAsMarkdown(texInput: string, options = {}) {
let ast = unified()
.use(unifiedLatexFromString)
.use(unifiedLatexToMdast).parse( texInput);
let mdast = unified().use(unifiedLatexToMdast).runSync(ast);
let output= toMarkdown(mdast as any);
//console.log(output, mdast)
return output;
},
parse(texInput: string, options = {}) {
const output = parse(texInput);
return output;
Expand Down
2 changes: 1 addition & 1 deletion src/async-worker/worker-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as Comlink from "comlink";
//import Worker from "worker-loader!"
/* eslint-disable import/no-webpack-loader-syntax */
//@ts-ignore
import workerFactory from "workerize-loader!./parsing-worker.ts";
import workerFactory from "./parsing-worker?worker";
import { Exposed } from "./parsing-worker";

const rawWorker = new workerFactory();
Expand Down
4 changes: 3 additions & 1 deletion src/components/html-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ReactSplitPane from "react-split-pane";
// @ts-ignore
import Prettier from "prettier/esm/standalone.mjs";
import htmlParser from "prettier/parser-html";
import "./latex-html.css";

import { useCodeMirror } from "@uiw/react-codemirror";
import { html } from "@codemirror/lang-html";
Expand Down Expand Up @@ -44,7 +45,7 @@ export function HtmlSourceDisplay() {

return (
<div
style={{ flex: "1 1 auto", height: "100%", width: "100%" }}
style={{ flex: "1 1 auto", height: "100%", width: "100%"}}
ref={editorRef}
/>
);
Expand Down Expand Up @@ -95,6 +96,7 @@ function KatexRenderedHtml({ source }: { source: string }) {
<div
ref={renderedRef}
className="html-render-container"
style={{margin: "0.5em"}}
dangerouslySetInnerHTML={{ __html: source }}
></div>
);
Expand Down
29 changes: 29 additions & 0 deletions src/components/latex-html.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

.minipage {
text-align: left;
}

.section-paragraph {
font-size: unset;
margin-bottom: 0;
margin-top: unset;
}
.section-paragraph ~ p {
margin-top: .3em;
}

.phantom {
visibility: hidden;
}

.environment.example {
border-left: 5px solid rgb(0, 0, 200);
background-color: rgba(0,0,0,.05);
padding-left: 5px;
}

.environment.theorem {
border-left: 5px solid rgb(100, 0, 200);
background-color: rgba(0,0,0,.05);
padding-left: 5px;
}
69 changes: 69 additions & 0 deletions src/components/markdown-view.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from "react";
import "katex/dist/katex.min.css";
import ReactSplitPane from "react-split-pane";

import { useCodeMirror } from "@uiw/react-codemirror";
import { html } from "@codemirror/lang-html";
import { markdown } from "@codemirror/lang-markdown";
import { useStoreState } from "../store/hooks";
import { toMarkdown } from "mdast-util-to-markdown";
import Markdown from "react-markdown";
import rehypeKatex from "rehype-katex";
import remarkMath from "remark-math";
import remarkGfm from "remark-gfm";
import type * as Mdast from "mdast";

export function MarkdownSourceDisplay() {
const editorRef = React.useRef<HTMLDivElement>(null);
const markdownInput = useStoreState((state) => state.markdown);
const formattedMarkdown = markdownInput;

useCodeMirror({
container: editorRef.current,
value: formattedMarkdown,
extensions: [markdown()],
readOnly: true,
height: "100%",
basicSetup: {
lineNumbers: false,
foldGutter: true,
highlightActiveLine: false,
},
});

return (
<div
style={{ flex: "1 1 auto", height: "100%", width: "100%" }}
ref={editorRef}
/>
);
}

/**
* Wrapper around ReactSplitPlane so that typescript stops complaining.
*/
function SplitPane({ children, ...rest }: React.PropsWithChildren<any>) {
return <ReactSplitPane {...rest}>{children}</ReactSplitPane>;
}

function RenderedMarkdown({ source }: { source: string }) {
return (
<Markdown
remarkPlugins={[remarkMath]}
rehypePlugins={[rehypeKatex, remarkGfm]}
>
{source}
</Markdown>
);
}

export function MarkdownView({ mdast, ...rest }: { mdast: string }) {
return (
<SplitPane split="horizontal" defaultSize="50%">
<div className="code-container">
<MarkdownSourceDisplay />
</div>
<RenderedMarkdown source={mdast} />
</SplitPane>
);
}
4 changes: 2 additions & 2 deletions src/linter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const lintAll = (tree: Ast.Node | Ast.Node[]) => {
for (const lint of Object.values(lints)) {
processor = processor.use(lint as any);
}
processor.runSync(tree, file);
processor.runSync(tree, file as any);
const messages = file.messages.map((m) => ({ description: ""+m }));
return messages;
};
Expand All @@ -59,6 +59,6 @@ export const getLints = (tree: Ast.Node | Ast.Node[], source?: string) => {
for (const lint of Object.values(lints)) {
processor = processor.use(lint as any);
}
processor.runSync(tree, file);
processor.runSync(tree, file as any);
return file.messages.map(m => Object.assign({}, m))
};
15 changes: 13 additions & 2 deletions src/store/model.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import { Action, Computed, Thunk } from "easy-peasy";
import { ParseError } from "../async-worker/errors";
import { VFile } from "vfile";
import * as Ast from "@unified-latex/unified-latex-types";
import type * as Ast from "@unified-latex/unified-latex-types";
import type * as Mdast from "mdast";

type ActiveView = "formatted" | "ast" | "json" | "doc" | "debug" | "html";
type ActiveView =
| "formatted"
| "ast"
| "json"
| "doc"
| "debug"
| "html"
| "markdown";

export interface StoreModel {
activeView: ActiveView;
Expand All @@ -28,6 +36,9 @@ export interface StoreModel {
html: string;
setHtml: Action<StoreModel, string>;

markdown: string;
setMarkdown: Action<StoreModel, string>;

parseError: ParseError | string | null;
setParseError: Action<StoreModel, ParseError | string | null>;

Expand Down
Loading

0 comments on commit 45cf71c

Please sign in to comment.