summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/nasty-tigers-sip.md5
-rw-r--r--packages/astro/env.d.ts2
-rw-r--r--packages/astro/src/@types/astro.ts4
-rw-r--r--packages/astro/src/vite-plugin-markdown/index.ts23
-rw-r--r--packages/astro/test/astro-markdown.test.js14
-rw-r--r--packages/astro/test/fixtures/astro-markdown/src/pages/raw-content.json.js10
-rw-r--r--packages/astro/test/test-utils.js4
7 files changed, 55 insertions, 7 deletions
diff --git a/.changeset/nasty-tigers-sip.md b/.changeset/nasty-tigers-sip.md
new file mode 100644
index 000000000..7325f6ccb
--- /dev/null
+++ b/.changeset/nasty-tigers-sip.md
@@ -0,0 +1,5 @@
+---
+'astro': minor
+---
+
+Add content parsing helpers to imported markdown files. This exposes both the raw markdown content when using rawContent() and the parsed Astro syntax when using compiledContent()
diff --git a/packages/astro/env.d.ts b/packages/astro/env.d.ts
index d9dfe741a..4f40def88 100644
--- a/packages/astro/env.d.ts
+++ b/packages/astro/env.d.ts
@@ -20,6 +20,8 @@ declare module '*.md' {
export const url: MD['url'];
export const getHeaders: MD['getHeaders'];
export const Content: MD['Content'];
+ export const rawContent: MD['rawContent'];
+ export const compiledContent: MD['compiledContent'];
const load: MD['default'];
export default load;
diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts
index 31f9e98f3..dfd85e9b0 100644
--- a/packages/astro/src/@types/astro.ts
+++ b/packages/astro/src/@types/astro.ts
@@ -753,6 +753,10 @@ export interface MarkdownInstance<T extends Record<string, any>> {
file: string;
url: string | undefined;
Content: AstroComponentFactory;
+ /** raw Markdown file content, excluding frontmatter */
+ rawContent(): string;
+ /** Markdown file compiled to valid Astro syntax. Queryable with most HTML parsing libraries */
+ compiledContent(): Promise<string>;
getHeaders(): Promise<MarkdownHeader[]>;
default: () => Promise<{
metadata: MarkdownMetadata;
diff --git a/packages/astro/src/vite-plugin-markdown/index.ts b/packages/astro/src/vite-plugin-markdown/index.ts
index b3c916bcd..997648a6b 100644
--- a/packages/astro/src/vite-plugin-markdown/index.ts
+++ b/packages/astro/src/vite-plugin-markdown/index.ts
@@ -82,28 +82,33 @@ export default function markdown({ config }: AstroPluginOptions): Plugin {
const { fileId, fileUrl } = getFileInfo(id, config);
const source = await fs.promises.readFile(fileId, 'utf8');
- const { data: frontmatter } = matter(source);
+ const { data: frontmatter, content: rawContent } = matter(source);
return {
code: `
// Static
export const frontmatter = ${JSON.stringify(frontmatter)};
export const file = ${JSON.stringify(fileId)};
export const url = ${JSON.stringify(fileUrl)};
-
+ export function rawContent() {
+ return ${JSON.stringify(rawContent)};
+ }
+ export async function compiledContent() {
+ return load().then((m) => m.compiledContent());
+ }
export function $$loadMetadata() {
- return load().then((m) => m.$$metadata)
+ return load().then((m) => m.$$metadata);
}
// Deferred
export default async function load() {
return (await import(${JSON.stringify(fileId + MARKDOWN_CONTENT_FLAG)}));
- };
+ }
export function Content(...args) {
- return load().then((m) => m.default(...args))
+ return load().then((m) => m.default(...args));
}
Content.isAstroComponentFactory = true;
export function getHeaders() {
- return load().then((m) => m.metadata.headers)
+ return load().then((m) => m.metadata.headers);
};`,
map: null,
};
@@ -171,6 +176,12 @@ ${setup}`.trim();
tsResult = `\nexport const metadata = ${JSON.stringify(metadata)};
export const frontmatter = ${JSON.stringify(content)};
+export function rawContent() {
+ return ${JSON.stringify(markdownContent)};
+}
+export function compiledContent() {
+ return ${JSON.stringify(renderResult.metadata.html)};
+}
${tsResult}`;
// Compile from `.ts` to `.js`
diff --git a/packages/astro/test/astro-markdown.test.js b/packages/astro/test/astro-markdown.test.js
index 525522316..d98dabe18 100644
--- a/packages/astro/test/astro-markdown.test.js
+++ b/packages/astro/test/astro-markdown.test.js
@@ -1,6 +1,6 @@
import { expect } from 'chai';
import * as cheerio from 'cheerio';
-import { loadFixture } from './test-utils.js';
+import { loadFixture, fixLineEndings } from './test-utils.js';
describe('Astro Markdown', () => {
let fixture;
@@ -233,4 +233,16 @@ describe('Astro Markdown', () => {
expect($('#target > ol > li').children()).to.have.lengthOf(1);
expect($('#target > ol > li > ol > li').text()).to.equal('nested hello');
});
+
+ it('Exposes raw markdown content', async () => {
+ const { raw } = JSON.parse(await fixture.readFile('/raw-content.json'));
+
+ expect(fixLineEndings(raw)).to.equal(`\n## With components\n\n### Non-hydrated\n\n<Hello name="Astro Naut" />\n\n### Hydrated\n\n<Counter client:load />\n<SvelteButton client:load />\n`);
+ });
+
+ it('Exposes HTML parser for raw markdown content', async () => {
+ const { compiled } = JSON.parse(await fixture.readFile('/raw-content.json'));
+
+ expect(fixLineEndings(compiled)).to.equal(`<h2 id="with-components">With components</h2>\n<h3 id="non-hydrated">Non-hydrated</h3>\n<Hello name="Astro Naut" />\n<h3 id="hydrated">Hydrated</h3>\n<Counter client:load />\n<SvelteButton client:load />`);
+ })
});
diff --git a/packages/astro/test/fixtures/astro-markdown/src/pages/raw-content.json.js b/packages/astro/test/fixtures/astro-markdown/src/pages/raw-content.json.js
new file mode 100644
index 000000000..21be533e1
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-markdown/src/pages/raw-content.json.js
@@ -0,0 +1,10 @@
+import { rawContent, compiledContent } from '../imported-md/with-components.md';
+
+export async function get() {
+ return {
+ body: JSON.stringify({
+ raw: rawContent(),
+ compiled: await compiledContent(),
+ }),
+ }
+}
diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js
index afac6e250..01e924a78 100644
--- a/packages/astro/test/test-utils.js
+++ b/packages/astro/test/test-utils.js
@@ -254,3 +254,7 @@ export async function cliServerLogSetup(flags = [], cmd = 'dev') {
}
export const isWindows = os.platform() === 'win32';
+
+export function fixLineEndings(str) {
+ return str.replace(/\r\n/g, '\n');
+}