Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add code block support #175

Merged
merged 1 commit into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,6 @@ article img {
}

/*
removed dthis one from typography.js
removed this one from typography.js
p *:last-child{margin-bottom:0;}
*/
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createRoot } from "react-dom/client";
import Container from "./container";
import "./index-compiled.css"; // generated by tailwindcss; see package.jsons scripts
import "./typography.css";
import "./prism-code-theme.css";
import { HashRouter } from "react-router-dom";
import "mobx-react-lite/batchingForReactDom";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ELEMENT_OL,
ELEMENT_UL,
ELEMENT_CODE_BLOCK,
ELEMENT_CODE_LINE,
} from "@udecode/plate"; // todo: sub-package which has only elements?

export type Decoration = {
Expand Down Expand Up @@ -75,7 +76,7 @@ function createSlateNode(node: mdast.Content, deco: Decoration): SlateNode[] {
case "html":
return [createHtml(node)];
case "code":
return [createCode(node)];
return [createCodeBlock(node)];
case "yaml":
return [createYaml(node)];
case "toml":
Expand Down Expand Up @@ -256,15 +257,26 @@ function createHtml(node: mdast.HTML) {
};
}

export type Code = ReturnType<typeof createCode>;
export type Code = ReturnType<typeof createCodeBlock>;

function createCodeBlock(node: mdast.Code) {
const { value, lang, meta } = node;

// MDAST represents code blocks as a single string; our Plate code block represents
// internal code as a code_line element. Ostensibly this should be each line, but
// the PlateDOM seems to convert the full text to a single code_line element when it is modified.
// Unclear if this is a bug or a feature; making multiple lines here, but it may not be necessary.
// See the reverse transformation in slate-to-mdast.ts - createCode
const codeLines = value.split("\n").map((line, index, array) => {
const isLastLine = index === array.length - 1;
return { type: ELEMENT_CODE_LINE, text: isLastLine ? line : line + "\n" };
});

function createCode(node: mdast.Code) {
const { type, value, lang, meta } = node;
return {
type: ELEMENT_CODE_BLOCK,
lang,
meta,
children: [{ text: value }],
children: codeLines,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,25 +379,30 @@ function createHtml(node: SlateNodes.Html): mdast.HTML {
};
}

/**
* Convert a Slate/Plate code block ("code_block") to an MDAST code block ("code").
*/
function createCode(node: SlateNodes.Code): mdast.Code {
const { lang, meta } = node;

// The slateInternal.Code type says its children are text nodes. However the
// Plate code block is giving wrapping each of those in a `code_line` element.
// Plate code block is wrapping each of those in a `code_line` element.
// MDAST (seems to) expect just text in its code block element. This code
// implements that.
// implements that. See the reverse transformation in mdast-to-slate.ts - createCodeBlock
// SNode.texts returns a generator that yields [{text: "foo"}, path] for each line
// which looks like: [ { type: code_line, children : { text: ''}}]
// TODO: Update Plate, then change the node's type
const value = Array.from(SNode.texts(node))
const text = Array.from(SNode.texts(node))
.map((item) => item[0].text)
.join("\n");
.join("\n")
// Remove trailing newlines
.replace(/\n+$/, "\n");

return {
type: "code",
lang,
meta,
value,
value: text,
};
}

Expand Down
Loading
Loading