Skip to content

Commit

Permalink
feat: 🆕 add card & card-grid class name options
Browse files Browse the repository at this point in the history
  • Loading branch information
brklntmhwk committed Oct 31, 2024
1 parent 5399843 commit 9179938
Showing 1 changed file with 129 additions and 120 deletions.
249 changes: 129 additions & 120 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,135 +5,144 @@ import type { LeafDirective } from "mdast-util-directive";
import type { Plugin } from "unified";
import { visit } from "unist-util-visit";
import {
isContainerDirective,
isImage,
isLink,
isParagraph,
isText,
isContainerDirective,
isImage,
isLink,
isParagraph,
isText,
} from "./utils.js";

export type Config = {
customHTMLTags?: {
enabled: boolean;
};
imageContainerClass?: string;
contentContainerClass?: string;
customHTMLTags?: {
enabled: boolean;
};
cardGridClass?: string;
cardClass?: string;
imageContainerClass?: string;
contentContainerClass?: string;
};

export const defaultConfig: Readonly<Config> = {
customHTMLTags: {
enabled: false,
},
imageContainerClass: "image-container",
contentContainerClass: "content-container",
customHTMLTags: {
enabled: false,
},
imageContainerClass: "image-container",
contentContainerClass: "content-container",
};

const remarkCard: Plugin<[Config?], Root> = (config?: Partial<Config>) => {
const mergedConfig = {
...defaultConfig,
...config,
};

const { customHTMLTags, imageContainerClass, contentContainerClass } =
mergedConfig;

return (tree) => {
visit(tree, isContainerDirective, (node) => {
if (node.name !== "card-grid") return;
if (node.children.length === 0) return;

node.data = {
...node.data,
hName: customHTMLTags?.enabled ? "card-grid" : "div",
hProperties: {
...node.attributes,
},
};
});

visit(tree, isContainerDirective, (node) => {
if (node.name !== "card") return;
if (node.children.length === 0) return;

const [firstNode, secondNode, ..._restNodes] = node.children;
if (!isParagraph(firstNode)) return;
if (firstNode.children.length === 0) return;

let cardImageOrLink: PhrasingContent;
let cardContent: PhrasingContent[];
let cardLabel = "";

const imageContainer: LeafDirective = {
type: "leafDirective",
name: "image-container",
data: {
hName: "div",
hProperties: {
className: imageContainerClass,
},
},
children: [],
};

const contentContainer: LeafDirective = {
type: "leafDirective",
name: "content-container",
data: {
hName: "div",
hProperties: {
className: contentContainerClass,
},
},
children: [],
};

if (firstNode.data?.directiveLabel === true) {
if (!isText(firstNode.children[0])) return;

cardLabel = firstNode.children[0].value;

if (!isParagraph(secondNode)) return;
const [imageOrLink, ...restContent] = secondNode.children;
cardImageOrLink = imageOrLink;
cardContent = restContent;
} else {
const [imageOrLink, ...restContent] = firstNode.children;
cardImageOrLink = imageOrLink;
cardContent = restContent;
}

if (isImage(cardImageOrLink)) {
cardImageOrLink.alt = cardImageOrLink.alt || cardLabel;
} else if (isLink(cardImageOrLink)) {
const cardImage = cardImageOrLink.children[0];
if (!isImage(cardImage)) return;

cardImage.alt = cardImage.alt || cardLabel;
} else {
return;
}

imageContainer.children.push(cardImageOrLink);

for (const contentElem of cardContent) {
contentContainer.children.push(contentElem);
}

node.data = {
...node.data,
hName: customHTMLTags?.enabled ? "card" : "div",
hProperties: {
...node.attributes,
},
};
node.children.splice(
0,
Number.POSITIVE_INFINITY,
imageContainer,
contentContainer,
);
});
};
const mergedConfig = {
...defaultConfig,
...config,
};

const {
customHTMLTags,
cardGridClass,
cardClass,
imageContainerClass,
contentContainerClass,
} = mergedConfig;

return (tree) => {
visit(tree, isContainerDirective, (node) => {
if (node.name !== "card-grid") return;
if (node.children.length === 0) return;

node.data = {
...node.data,
hName: customHTMLTags?.enabled ? "card-grid" : "div",
hProperties: {
...node.attributes,
className: cardGridClass || node.attributes?.class || "",
},
};
});

visit(tree, isContainerDirective, (node) => {
if (node.name !== "card") return;
if (node.children.length === 0) return;

const [firstNode, secondNode, ..._restNodes] = node.children;
if (!isParagraph(firstNode)) return;
if (firstNode.children.length === 0) return;

let cardImageOrLink: PhrasingContent;
let cardContent: PhrasingContent[];
let cardLabel = "";

const imageContainer: LeafDirective = {
type: "leafDirective",
name: "image-container",
data: {
hName: "div",
hProperties: {
className: imageContainerClass,
},
},
children: [],
};

const contentContainer: LeafDirective = {
type: "leafDirective",
name: "content-container",
data: {
hName: "div",
hProperties: {
className: contentContainerClass,
},
},
children: [],
};

if (firstNode.data?.directiveLabel === true) {
if (!isText(firstNode.children[0])) return;

cardLabel = firstNode.children[0].value;

if (!isParagraph(secondNode)) return;
const [imageOrLink, ...restContent] = secondNode.children;
cardImageOrLink = imageOrLink;
cardContent = restContent;
} else {
const [imageOrLink, ...restContent] = firstNode.children;
cardImageOrLink = imageOrLink;
cardContent = restContent;
}

if (isImage(cardImageOrLink)) {
cardImageOrLink.alt = cardImageOrLink.alt || cardLabel;
} else if (isLink(cardImageOrLink)) {
const cardImage = cardImageOrLink.children[0];
if (!isImage(cardImage)) return;

cardImage.alt = cardImage.alt || cardLabel;
} else {
return;
}

imageContainer.children.push(cardImageOrLink);

for (const contentElem of cardContent) {
contentContainer.children.push(contentElem);
}

node.data = {
...node.data,
hName: customHTMLTags?.enabled ? "card" : "div",
hProperties: {
...node.attributes,
className: cardClass || node.attributes?.class || "",
},
};
node.children.splice(
0,
Number.POSITIVE_INFINITY,
imageContainer,
contentContainer
);
});
};
};

export default remarkCard;

0 comments on commit 9179938

Please sign in to comment.