@islands/frontmatter
Advanced tools
Comparing version 0.4.1 to 0.4.2
@@ -57,7 +57,6 @@ var __defProp = Object.defineProperty; | ||
var _a; | ||
const parent = ast; | ||
const nodes = parent.children; | ||
const nodes = ast.children; | ||
const rawMatter = mapFind(nodes, parseFrontmatter) || {}; | ||
const _b = ((_a = options == null ? void 0 : options.extendFrontmatter) == null ? void 0 : _a.call(options, rawMatter, file.path)) || rawMatter, { meta, layout: _ } = _b, frontmatter2 = __objRest(_b, ["meta", "layout"]); | ||
parent.children.unshift(defineConsts(__spreadProps(__spreadValues({}, frontmatter2), { meta, frontmatter: frontmatter2 }))); | ||
ast.children.unshift(defineConsts(__spreadProps(__spreadValues({}, frontmatter2), { meta, frontmatter: frontmatter2 }))); | ||
}; | ||
@@ -75,2 +74,3 @@ }; | ||
type: "mdxjsEsm", | ||
value: "_not_used_", | ||
data: { | ||
@@ -107,3 +107,5 @@ estree: { | ||
kind: "init", | ||
shorthand: true | ||
shorthand: true, | ||
method: false, | ||
computed: false | ||
})) | ||
@@ -250,11 +252,25 @@ }; | ||
// src/utils.ts | ||
var urlPattern = /^(https?:)?\//; | ||
var externalUrlPattern = /^(https?:)?\/\//; | ||
function isAbsolute(url) { | ||
return urlPattern.test(url); | ||
} | ||
function isExternal(url) { | ||
return externalUrlPattern.test(url); | ||
} | ||
function isJsxElement(node) { | ||
return node.type === "mdxJsxTextElement" || node.type === "mdxJsxFlowElement"; | ||
} | ||
function isString(val) { | ||
return typeof val === "string"; | ||
} | ||
// src/remark-mdx-images.ts | ||
var urlPattern = /^(https?:)?\//; | ||
var remarkMdxImages = (options) => (ast, vfile) => { | ||
const parent = ast; | ||
const imports = []; | ||
const imported = new Map(); | ||
visit(parent, (node, index, parent2) => { | ||
visit(ast, (node, index, parent) => { | ||
if (node.type === "image") | ||
return replaceMarkdownImage(node, index, parent2); | ||
return replaceMarkdownImage(node, index, parent); | ||
if (isJsxElement(node) && (node.name === "img" || node.name === "Img" || node.name === "Image")) | ||
@@ -264,3 +280,3 @@ return replaceSrcAttribute(node); | ||
if (imports.length > 0) | ||
parent.children.unshift(...imports); | ||
ast.children.unshift(...imports); | ||
function replaceSrcAttribute(node) { | ||
@@ -277,3 +293,3 @@ for (const attr of node.attributes) { | ||
} | ||
function replaceMarkdownImage(node, index, parent2) { | ||
function replaceMarkdownImage(node, index, parent) { | ||
const src = imageSrcToMdxExpression(node.url); | ||
@@ -290,3 +306,3 @@ if (src) { | ||
}; | ||
parent2.children.splice(index, 1, mdxImage); | ||
parent.children.splice(index, 1, mdxImage); | ||
} | ||
@@ -313,3 +329,3 @@ return SKIP; | ||
var _a; | ||
if (urlPattern.test(url)) | ||
if (isAbsolute(url)) | ||
return; | ||
@@ -323,2 +339,3 @@ let name = imported.get(url); | ||
type: "mdxjsEsm", | ||
value: "_not_used_", | ||
data: { | ||
@@ -347,8 +364,41 @@ estree: { | ||
}; | ||
function isJsxElement(node) { | ||
return node.type === "mdxJsxFlowElement"; | ||
// src/remark-internal-hrefs.ts | ||
import { extname } from "path"; | ||
var remarkInternalHrefs = (options) => { | ||
if (!(options == null ? void 0 : options.prettyUrls)) | ||
return remarkProcessor; | ||
}; | ||
var remarkProcessor = (ast, vfile) => { | ||
visit(ast, (node) => { | ||
if (node.type === "link") { | ||
const { url } = node; | ||
if (url) | ||
node.url = toExplicitHtmlPath(url); | ||
return SKIP; | ||
} | ||
if (isJsxElement(node) && (node.name === "a" || node.name === "Link")) { | ||
replaceHrefAttribute(node); | ||
return SKIP; | ||
} | ||
}); | ||
function replaceHrefAttribute(node) { | ||
for (const attr of node.attributes) { | ||
if (attr.type === "mdxJsxAttribute" && attr.name === "href") { | ||
if (isString(attr.value) && attr.value) | ||
attr.value = toExplicitHtmlPath(attr.value); | ||
break; | ||
} | ||
} | ||
} | ||
}; | ||
function toExplicitHtmlPath(path) { | ||
if (isExternal(path) || extname(path) !== ".html") | ||
return path; | ||
if (path.endsWith("/")) | ||
return path; | ||
if (path.endsWith("/index.html")) | ||
return path.replace(/\/index\.html$/, "/"); | ||
return `${path}.html`; | ||
} | ||
function isString(val) { | ||
return typeof val === "string"; | ||
} | ||
@@ -360,4 +410,4 @@ // src/frontmatter.ts | ||
name: "@islands/frontmatter", | ||
configResolved({ markdown }) { | ||
Object.assign(options, markdown); | ||
configResolved({ markdown, prettyUrls }) { | ||
Object.assign(options, markdown, { prettyUrls }); | ||
}, | ||
@@ -367,3 +417,4 @@ markdown: { | ||
[remarkMdxFrontmatter, options], | ||
[remarkMdxImages, options] | ||
[remarkMdxImages, options], | ||
[remarkInternalHrefs, options] | ||
] | ||
@@ -370,0 +421,0 @@ } |
{ | ||
"name": "@islands/frontmatter", | ||
"version": "0.4.1", | ||
"version": "0.4.2", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "files": [ |
import { remarkMdxFrontmatter, FrontmatterOptions } from './remark-mdx-frontmatter' | ||
import { remarkMdxImages, ImageOptions } from './remark-mdx-images' | ||
import { remarkInternalHrefs, HrefOptions } from './remark-internal-hrefs' | ||
@@ -18,8 +19,8 @@ export type { | ||
export default function IlesFrontmatter (): any { | ||
let options: FrontmatterOptions & ImageOptions = {} | ||
let options: FrontmatterOptions & ImageOptions & HrefOptions = {} | ||
return { | ||
name: '@islands/frontmatter', | ||
configResolved ({ markdown }: any) { | ||
Object.assign(options, markdown) | ||
configResolved ({ markdown, prettyUrls }: any) { | ||
Object.assign(options, markdown, { prettyUrls }) | ||
}, | ||
@@ -30,2 +31,3 @@ markdown: { | ||
[remarkMdxImages, options], | ||
[remarkInternalHrefs, options], | ||
], | ||
@@ -32,0 +34,0 @@ }, |
@@ -1,3 +0,5 @@ | ||
import type { Program, VariableDeclarator } from 'estree' | ||
import type { ObjectExpression } from 'estree' | ||
import type { Pluggable, Plugin } from 'unified' | ||
import type { MDXJSEsm } from 'mdast-util-mdxjs-esm' | ||
import type { Root } from 'mdast' | ||
import type { Node, Data, Parent } from 'unist' | ||
@@ -31,3 +33,3 @@ | ||
*/ | ||
export const remarkMdxFrontmatter: Plugin<[FrontmatterOptions?]> = function (options?: FrontmatterOptions) { | ||
export const remarkMdxFrontmatter: Plugin<[FrontmatterOptions?], Root, Root> = function (options?: FrontmatterOptions) { | ||
const data = this.data() | ||
@@ -46,7 +48,6 @@ | ||
return (ast, file) => { | ||
const parent = ast as Parent | ||
const nodes = parent.children as (Node<Data> & { value: string })[] | ||
const nodes = ast.children as (Node<Data> & { value: string })[] | ||
const rawMatter = mapFind(nodes, parseFrontmatter) || {} | ||
const { meta, layout: _, ...frontmatter } = options?.extendFrontmatter?.(rawMatter, file.path) || rawMatter | ||
parent.children.unshift(defineConsts({ ...frontmatter, meta, frontmatter })) | ||
ast.children.unshift(defineConsts({ ...frontmatter, meta, frontmatter })) | ||
} | ||
@@ -62,5 +63,6 @@ } | ||
function defineConsts (variables: Record<string, any>) { | ||
function defineConsts (variables: Record<string, any>): MDXJSEsm { | ||
return { | ||
type: 'mdxjsEsm', | ||
value: '_not_used_', | ||
data: { | ||
@@ -84,7 +86,7 @@ estree: { | ||
: valueToEstree(value), | ||
} as VariableDeclarator | ||
} | ||
}), | ||
}, | ||
], | ||
} as Program, | ||
}, | ||
}, | ||
@@ -96,3 +98,3 @@ } | ||
// const frontmatter = { title, source } | ||
function shorthandObjectExpression (value: Record<string, any>) { | ||
function shorthandObjectExpression (value: Record<string, any>): ObjectExpression { | ||
return { | ||
@@ -106,4 +108,6 @@ type: 'ObjectExpression', | ||
shorthand: true, | ||
method: false, | ||
computed: false, | ||
})), | ||
} | ||
} |
import type { MDXJsxFlowElement, MDXJsxTextElement, MDXJsxAttribute, MDXJsxAttributeValueExpression } from 'mdast-util-mdx-jsx' | ||
import type { MDXJSEsm } from 'mdast-util-mdxjs-esm' | ||
import type { Image } from 'mdast' | ||
import type { Root, Image } from 'mdast' | ||
import type { Plugin } from 'unified' | ||
@@ -10,3 +10,3 @@ import type { Parent, Node } from 'unist' | ||
const urlPattern = /^(https?:)?\// | ||
import { isAbsolute, isJsxElement, isString } from './utils' | ||
@@ -17,2 +17,4 @@ export interface ImageOptions { | ||
type ImagePlugin = Plugin<[ImageOptions?], Root, Root> | ||
/** | ||
@@ -22,10 +24,9 @@ * A Remark plugin for converting Markdown images to MDX images using imports | ||
*/ | ||
export const remarkMdxImages: Plugin<[ImageOptions?]> = (options?: ImageOptions) => (ast, vfile) => { | ||
const parent = ast as Parent | ||
const imports: Omit<MDXJSEsm, 'value'>[] = [] | ||
export const remarkMdxImages: ImagePlugin = options => (ast, vfile) => { | ||
const imports: MDXJSEsm[] = [] | ||
const imported = new Map<string, string>() | ||
visit(parent, (node, index, parent) => { | ||
visit(ast, (node, index, parent) => { | ||
if (node.type === 'image') | ||
return replaceMarkdownImage(node as Image, index!, parent!) | ||
return replaceMarkdownImage(node, index!, parent!) | ||
@@ -37,5 +38,5 @@ if (isJsxElement(node) && (node.name === 'img' || node.name === 'Img' || node.name === 'Image')) | ||
if (imports.length > 0) | ||
parent.children.unshift(...imports) | ||
ast.children.unshift(...imports) | ||
function replaceSrcAttribute (node: MDXJsxFlowElement) { | ||
function replaceSrcAttribute (node: MDXJsxTextElement | MDXJsxFlowElement) { | ||
for (const attr of node.attributes) { | ||
@@ -89,3 +90,3 @@ if (attr.type === 'mdxJsxAttribute' && attr.name === 'src' && isString(attr.value)) { | ||
function imageSrcToIdentifier (url: string) { | ||
if (urlPattern.test(url)) return | ||
if (isAbsolute(url)) return | ||
@@ -101,2 +102,3 @@ let name = imported.get(url) | ||
type: 'mdxjsEsm', | ||
value: '_not_used_', | ||
data: { | ||
@@ -126,9 +128,1 @@ estree: { | ||
} | ||
function isJsxElement (node: Node): node is MDXJsxFlowElement { | ||
return node.type === 'mdxJsxFlowElement' | ||
} | ||
function isString (val: any): val is string { | ||
return typeof val === 'string' | ||
} |
27039
11
712