Move the Markdown component to its own package (#3986)
* Move the Markdown component to its own package * Update the examples * Updated lockfile * Use is:raw * Add a main field * Update the formatting of the readme * Rename to @astrojs/markdown-component
This commit is contained in:
parent
d13afad272
commit
bccd88f0eb
116 changed files with 1392 additions and 719 deletions
22
.changeset/wild-socks-drive.md
Normal file
22
.changeset/wild-socks-drive.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
'astro': minor
|
||||
'@astrojs/markdown-component': minor
|
||||
---
|
||||
|
||||
Move the Markdown component to its own package
|
||||
|
||||
This change moves the Markdown component into its own package where it will be maintained separately. All that needs to change from a user's perspective is the import statement:
|
||||
|
||||
```astro
|
||||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
---
|
||||
```
|
||||
|
||||
Becomes:
|
||||
|
||||
```astro
|
||||
---
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
---
|
||||
```
|
|
@ -27,7 +27,6 @@ const { content } = Astro.props;
|
|||
<header>
|
||||
<nav class="nav">
|
||||
<a href="/">Home</a>
|
||||
<a href="/about">About</a>
|
||||
</nav>
|
||||
</header>
|
||||
<slot />
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
---
|
||||
import { Markdown } from "astro/components";
|
||||
import MainLayout from "../layouts/main.astro";
|
||||
---
|
||||
|
||||
<MainLayout content={{ title: "About" }}>
|
||||
<Markdown>
|
||||
# About
|
||||
|
||||
Sint ullamco sint ut irure laborum occaecat anim minim tempor enim dolore reprehenderit Lorem. Sit qui nisi in quis ut consequat minim. Ad commodo officia nisi culpa proident duis culpa eu reprehenderit incididunt do fugiat proident tempor. Et velit dolor aliqua dolor ipsum. Sunt eiusmod amet enim ut.
|
||||
|
||||
Sint ullamco sint ut irure laborum occaecat anim minim tempor enim dolore reprehenderit Lorem. Sit qui nisi in quis ut consequat minim. Ad commodo officia nisi culpa proident duis culpa eu reprehenderit incididunt do fugiat proident tempor. Et velit dolor aliqua dolor ipsum. Sunt eiusmod amet enim ut.
|
||||
|
||||
## My story
|
||||
|
||||
Sint ullamco sint ut irure laborum occaecat anim minim tempor enim dolore reprehenderit Lorem. Sit qui nisi in quis ut consequat minim. Ad commodo officia nisi culpa proident duis culpa eu reprehenderit incididunt do fugiat proident tempor. Et velit dolor aliqua dolor ipsum. Sunt eiusmod amet enim ut.
|
||||
|
||||
Sint ullamco sint ut irure laborum occaecat anim minim tempor enim dolore reprehenderit Lorem. Sit qui nisi in quis ut consequat minim. Ad commodo officia nisi culpa proident duis culpa eu reprehenderit incididunt do fugiat proident tempor. Et velit dolor aliqua dolor ipsum. Sunt eiusmod amet enim ut.
|
||||
</Markdown>
|
||||
</MainLayout>
|
|
@ -8,5 +8,4 @@ npm init astro -- --template with-markdown-shiki
|
|||
|
||||
This example showcases Astro's [built-in Markdown support](https://docs.astro.build/en/guides/markdown-content/).
|
||||
|
||||
- `src/pages/index.astro` uses Astro's `<Markdown>` component.
|
||||
- `src/pages/other.md` is a treated as a page entrypoint and uses a `layout`.
|
||||
- `src/pages/index.md` is a treated as a page entrypoint and uses a `layout`.
|
||||
|
|
19
examples/with-markdown/.gitignore
vendored
19
examples/with-markdown/.gitignore
vendored
|
@ -1,19 +0,0 @@
|
|||
# build output
|
||||
dist/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
|
@ -1,2 +0,0 @@
|
|||
# Expose Astro dependencies for `pnpm` users
|
||||
shamefully-hoist=true
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"startCommand": "npm start",
|
||||
"env": {
|
||||
"ENABLE_CJS_IMPORTS": true
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
# Astro Example: Markdown
|
||||
|
||||
```
|
||||
npm init astro -- --template with-markdown
|
||||
```
|
||||
|
||||
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/with-markdown)
|
||||
|
||||
This example showcases Astro's [built-in Markdown support](https://docs.astro.build/en/guides/markdown-content/).
|
||||
|
||||
- `src/pages/index.astro` uses Astro's `<Markdown>` component.
|
||||
- `src/pages/other.md` is a treated as a page entrypoint and uses a `layout`.
|
|
@ -1,11 +0,0 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import preact from '@astrojs/preact';
|
||||
import react from '@astrojs/react';
|
||||
import svelte from '@astrojs/svelte';
|
||||
import vue from '@astrojs/vue';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
// Enable many frameworks to support all different kinds of components.
|
||||
integrations: [preact(), react(), svelte(), vue()],
|
||||
});
|
|
@ -1,26 +0,0 @@
|
|||
{
|
||||
"name": "@example/with-markdown",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/markdown-remark": "^0.12.0",
|
||||
"@astrojs/preact": "^0.5.2",
|
||||
"@astrojs/react": "^0.4.2",
|
||||
"@astrojs/svelte": "^0.4.1",
|
||||
"@astrojs/vue": "^0.4.1",
|
||||
"astro": "^1.0.0-beta.73"
|
||||
},
|
||||
"dependencies": {
|
||||
"preact": "^10.7.3",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"svelte": "^3.48.0",
|
||||
"vue": "^3.2.37"
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB |
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"infiniteLoopProtection": true,
|
||||
"hardReloadOnChange": false,
|
||||
"view": "browser",
|
||||
"template": "node",
|
||||
"container": {
|
||||
"port": 3000,
|
||||
"startScript": "start",
|
||||
"node": "14"
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import { h, Fragment } from 'preact';
|
||||
import { useState } from 'preact/hooks';
|
||||
|
||||
/** a counter written in Preact */
|
||||
export default function PreactCounter({ children }) {
|
||||
const [count, setCount] = useState(0);
|
||||
const add = () => setCount((i) => i + 1);
|
||||
const subtract = () => setCount((i) => i - 1);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="counter">
|
||||
<button onClick={subtract}>-</button>
|
||||
<pre>{count}</pre>
|
||||
<button onClick={add}>+</button>
|
||||
</div>
|
||||
<div className="children">{children}</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
import React, { useState } from 'react';
|
||||
|
||||
/** a counter written in React */
|
||||
export default function ReactCounter({ children }) {
|
||||
const [count, setCount] = useState(0);
|
||||
const add = () => setCount((i) => i + 1);
|
||||
const subtract = () => setCount((i) => i - 1);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="counter">
|
||||
<button onClick={subtract}>-</button>
|
||||
<pre>{count}</pre>
|
||||
<button onClick={add}>+</button>
|
||||
</div>
|
||||
<div className="children">{children}</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
|
||||
<script>
|
||||
let children;
|
||||
let count = 0;
|
||||
|
||||
function add() {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
function subtract() {
|
||||
count -= 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="counter">
|
||||
<button on:click={subtract}>-</button>
|
||||
<pre>{ count }</pre>
|
||||
<button on:click={add}>+</button>
|
||||
</div>
|
||||
<div class="children">
|
||||
<slot />
|
||||
</div>
|
|
@ -1,27 +0,0 @@
|
|||
<template>
|
||||
<div class="counter">
|
||||
<button @click="subtract()">-</button>
|
||||
<pre>{{ count }}</pre>
|
||||
<button @click="add()">+</button>
|
||||
</div>
|
||||
<div class="children">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from 'vue';
|
||||
export default {
|
||||
setup() {
|
||||
const count = ref(0);
|
||||
const add = () => (count.value = count.value + 1);
|
||||
const subtract = () => (count.value = count.value - 1);
|
||||
|
||||
return {
|
||||
count,
|
||||
add,
|
||||
subtract,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
import "../styles/global.css";
|
||||
|
||||
const { content } = Astro.props;
|
||||
---
|
||||
|
||||
<html lang={content.lang || "en"}>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
|
||||
<title>{content.title}</title>
|
||||
</head>
|
||||
<body>
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
|
@ -1,19 +0,0 @@
|
|||
---
|
||||
import { Markdown } from "astro/components";
|
||||
import Layout from "../layouts/main.astro";
|
||||
|
||||
const title = `External Markdown`;
|
||||
const content = `Markdown *content* to render`;
|
||||
---
|
||||
|
||||
<Layout content={{ title }}>
|
||||
<main>
|
||||
<div>
|
||||
<Markdown {content}>
|
||||
|
||||
</Markdown>
|
||||
<p>Some other stuff</p>
|
||||
</div>
|
||||
<p>Lastly...</p>
|
||||
</main>
|
||||
</Layout>
|
|
@ -1,65 +0,0 @@
|
|||
---
|
||||
// Component Imports
|
||||
import { Markdown } from "astro/components";
|
||||
import Layout from "../layouts/main.astro";
|
||||
import ReactCounter from "../components/ReactCounter.jsx";
|
||||
import PreactCounter from "../components/PreactCounter.tsx";
|
||||
import VueCounter from "../components/VueCounter.vue";
|
||||
import SvelteCounter from "../components/SvelteCounter.svelte";
|
||||
|
||||
// Component Script:
|
||||
// You can write any JavaScript/TypeScript that you'd like here.
|
||||
// It will run during the build, but never in the browser.
|
||||
// All variables are available to use in the HTML template below.
|
||||
const title = "Astro Markdown";
|
||||
const variable = "content";
|
||||
const items = ["A", "B", "C"];
|
||||
|
||||
// Full Astro Component Syntax:
|
||||
// https://docs.astro.build/core-concepts/astro-components/
|
||||
---
|
||||
|
||||
<Layout content={{ title }}>
|
||||
<Markdown>
|
||||
# Introducing {title}
|
||||
|
||||
**Astro Markdown** brings native Markdown support to HTML!
|
||||
|
||||
> It's inspired by [`MDX`](https://mdxjs.com/) and powered by [`remark`](https://github.com/remarkjs/remark).
|
||||
|
||||
The best part? It comes with all the Astro features you expect.
|
||||
|
||||
[Other example](./other)
|
||||
|
||||
## Embed framework components
|
||||
|
||||
<ReactCounter client:visible />
|
||||
<PreactCounter client:visible />
|
||||
<VueCounter client:visible />
|
||||
<SvelteCounter client:visible />
|
||||
|
||||
## Use Expressions
|
||||
|
||||
You can use any {variable} in scope and use JavaScript for templating ({items.join(', ')})
|
||||
|
||||
## Oh yeah...
|
||||
|
||||
<ReactCounter client:visible>
|
||||
|
||||
🤯 It's also _recursive_!
|
||||
|
||||
### Markdown can be embedded in any child component
|
||||
|
||||
</ReactCounter>
|
||||
|
||||
## Code
|
||||
|
||||
Should work!
|
||||
|
||||
```js
|
||||
import Something from "./another";
|
||||
|
||||
const thing = new Something();
|
||||
```
|
||||
</Markdown>
|
||||
</Layout>
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
title: Some Markdown Page
|
||||
layout: ../layouts/main.astro
|
||||
---
|
||||
|
||||
# Code
|
||||
|
||||
```js
|
||||
var foo = 'bar';
|
||||
|
||||
function doSomething() {
|
||||
return foo;
|
||||
}
|
||||
```
|
||||
|
||||
# Paragraph
|
||||
|
||||
text here.
|
|
@ -1,70 +0,0 @@
|
|||
pre,
|
||||
code {
|
||||
color: #d4d4d4;
|
||||
font-size: 14px;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
line-height: 1.5;
|
||||
direction: ltr;
|
||||
white-space: pre;
|
||||
text-align: left;
|
||||
text-shadow: none;
|
||||
word-break: normal;
|
||||
word-spacing: normal;
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre::selection,
|
||||
code::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
pre,
|
||||
code {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 0.5rem 0 16px;
|
||||
padding: 0.8rem 1rem 0.9rem;
|
||||
overflow: auto;
|
||||
background: #282a36;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 0.1em 0.3em;
|
||||
color: #db4c69;
|
||||
background: #f9f2f4;
|
||||
border-radius: 0.3em;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
pre.astro-code > code {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
* Line highlighting
|
||||
*/
|
||||
pre[data-line] {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
body {
|
||||
max-width: 900px;
|
||||
margin: auto;
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
// Enable top-level await, and other modern ESM features.
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
// Enable node-style module resolution, for things like npm package imports.
|
||||
"moduleResolution": "node",
|
||||
// Enable JSON imports.
|
||||
"resolveJsonModule": true,
|
||||
// Enable stricter transpilation for better output.
|
||||
"isolatedModules": true,
|
||||
// Add type definitions for our Astro runtime.
|
||||
"types": ["astro/client"]
|
||||
}
|
||||
}
|
|
@ -1,3 +1,2 @@
|
|||
export { default as Code } from './Code.astro';
|
||||
export { default as Debug } from './Debug.astro';
|
||||
export { default as Markdown } from './Markdown.astro';
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"test:e2e:match": "playwright test -g"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/compiler": "^0.19.0",
|
||||
"@astrojs/compiler": "^0.20.0",
|
||||
"@astrojs/language-server": "^0.20.0",
|
||||
"@astrojs/markdown-remark": "^0.12.0",
|
||||
"@astrojs/prism": "0.6.1",
|
||||
|
|
|
@ -34,15 +34,4 @@ describe('Astro Markdown plugins', () => {
|
|||
// teste 2: Added .title to h1
|
||||
expect($('#hello-world').hasClass('title')).to.equal(true);
|
||||
});
|
||||
|
||||
it('Can render Astro <Markdown> with plugins', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: Added a TOC
|
||||
expect($('.toc')).to.have.lengthOf(1);
|
||||
|
||||
// teste 2: Added .title to h1
|
||||
expect($('#hello-world').hasClass('title')).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -23,20 +23,6 @@ describe('Astro Markdown Shiki', () => {
|
|||
expect($('pre').attr().style).to.equal('background-color: #0d1117; overflow-x: auto;');
|
||||
});
|
||||
|
||||
it('Can render Astro <Markdown> with shiki', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// There should be no HTML from Prism
|
||||
expect($('.token')).to.have.lengthOf(0);
|
||||
|
||||
expect($('pre')).to.have.lengthOf(2);
|
||||
|
||||
expect($('span.line')).to.have.lengthOf(2);
|
||||
expect($('span.line').get(0).children).to.have.lengthOf(1);
|
||||
expect($('span.line').get(1).children).to.have.lengthOf(5);
|
||||
});
|
||||
|
||||
it('Can render diff syntax with "user-select: none"', async () => {
|
||||
const html = await fixture.readFile('/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
@ -63,15 +49,6 @@ describe('Astro Markdown Shiki', () => {
|
|||
expect($('pre').hasClass('astro-code')).to.equal(true);
|
||||
expect($('pre').attr().style).to.equal('background-color: #ffffff; overflow-x: auto;');
|
||||
});
|
||||
|
||||
it('<Markdown /> component', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('pre')).to.have.lengthOf(1);
|
||||
expect($('pre').hasClass('astro-code')).to.equal(true);
|
||||
expect($('pre').attr().style).to.equal('background-color: #ffffff; overflow-x: auto;');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Custom theme', async () => {
|
||||
|
@ -90,15 +67,6 @@ describe('Astro Markdown Shiki', () => {
|
|||
expect($('pre').hasClass('astro-code')).to.equal(true);
|
||||
expect($('pre').attr().style).to.equal('background-color: #FDFDFE; overflow-x: auto;');
|
||||
});
|
||||
|
||||
it('<Markdown /> component', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('pre')).to.have.lengthOf(1);
|
||||
expect($('pre').hasClass('astro-code')).to.equal(true);
|
||||
expect($('pre').attr().style).to.equal('background-color: #FDFDFE; overflow-x: auto;');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -125,21 +93,6 @@ describe('Astro Markdown Shiki', () => {
|
|||
'<span style="color: #c9d1d9">This language does not exist</span>'
|
||||
);
|
||||
});
|
||||
|
||||
it('<Markdown /> component', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
const segments = $('.line').get(6).children;
|
||||
expect(segments).to.have.lengthOf(3);
|
||||
expect(segments[0].attribs.style).to.be.equal('color: #C9D1D9');
|
||||
expect(segments[1].attribs.style).to.be.equal('color: #79C0FF');
|
||||
|
||||
const unknownLang = $('.line').last().html();
|
||||
expect(unknownLang).to.be.equal(
|
||||
'<span style="color: #c9d1d9">This language does not exist</span>'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Wrap', () => {
|
||||
|
@ -160,14 +113,6 @@ describe('Astro Markdown Shiki', () => {
|
|||
expect($('pre')).to.have.lengthOf(1);
|
||||
expect($('pre').attr('style')).to.equal(style);
|
||||
});
|
||||
|
||||
it('<Markdown /> component', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('pre').get(0).attribs.style).to.equal(style);
|
||||
expect($('pre').get(1).attribs.style).to.equal(style);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -187,14 +132,6 @@ describe('Astro Markdown Shiki', () => {
|
|||
expect($('pre')).to.have.lengthOf(1);
|
||||
expect($('pre').attr('style')).to.equal(style);
|
||||
});
|
||||
|
||||
it('<Markdown /> component', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('pre').get(0).attribs.style).to.equal(style);
|
||||
expect($('pre').get(1).attribs.style).to.equal(style);
|
||||
});
|
||||
});
|
||||
|
||||
describe('wrap = null', () => {
|
||||
|
@ -213,13 +150,5 @@ describe('Astro Markdown Shiki', () => {
|
|||
expect($('pre')).to.have.lengthOf(1);
|
||||
expect($('pre').attr('style')).to.equal(style);
|
||||
});
|
||||
|
||||
it('<Markdown /> component', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('pre').get(0).attribs.style).to.equal(style);
|
||||
expect($('pre').get(1).attribs.style).to.equal(style);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,17 +12,6 @@ describe('Astro Markdown', () => {
|
|||
await fixture.build();
|
||||
});
|
||||
|
||||
it('Can load markdown pages with Astro', async () => {
|
||||
const html = await fixture.readFile('/post/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: There is a div added in markdown
|
||||
expect($('#first').length).to.be.ok;
|
||||
|
||||
// test 2: There is a div added via a component from markdown
|
||||
expect($('#test').length).to.be.ok;
|
||||
});
|
||||
|
||||
it('Can parse JSX expressions in markdown pages', async () => {
|
||||
const html = await fixture.readFile('/jsx-expressions/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
@ -99,13 +88,6 @@ describe('Astro Markdown', () => {
|
|||
expect(html).not.to.match(new RegExp('/src/scripts/test.js'));
|
||||
});
|
||||
|
||||
it('Can load more complex jsxy stuff', async () => {
|
||||
const html = await fixture.readFile('/complex/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('#test').text()).to.equal('Hello world');
|
||||
});
|
||||
|
||||
it('Empty code blocks do not fail', async () => {
|
||||
const html = await fixture.readFile('/empty-code/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
@ -117,143 +99,11 @@ describe('Astro Markdown', () => {
|
|||
expect($('pre')[1].children).to.have.lengthOf(0);
|
||||
});
|
||||
|
||||
it('Runs code blocks through syntax highlighter', async () => {
|
||||
const html = await fixture.readFile('/code/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: There are child spans in code blocks
|
||||
expect($('code span').length).greaterThan(0);
|
||||
});
|
||||
|
||||
it('Scoped styles should not break syntax highlight', async () => {
|
||||
const html = await fixture.readFile('/scopedStyles-code/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: <pre> tag has correct shiki class
|
||||
expect($('pre').hasClass('astro-code')).to.equal(true);
|
||||
|
||||
// test 2: inline styles are still applied
|
||||
expect($('pre').is('[style]')).to.equal(true);
|
||||
|
||||
// test 3: There are styled child spans in code blocks
|
||||
expect($('pre code span').length).to.be.greaterThan(0);
|
||||
expect($('pre code span').is('[style]')).to.equal(true);
|
||||
});
|
||||
|
||||
function isAstroScopedClass(cls) {
|
||||
return /^astro-.*/.test(cls);
|
||||
}
|
||||
|
||||
it('Scoped styles should be applied to syntax highlighted lines', async () => {
|
||||
const html = await fixture.readFile('/scopedStyles-code/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: the "pre" tag receives scoped style
|
||||
const preClassList = $('pre').attr('class').split(/\s+/);
|
||||
expect(preClassList.length).to.equal(2);
|
||||
const preAstroClass = preClassList.find(isAstroScopedClass);
|
||||
expect(Boolean(preAstroClass)).to.equal(true);
|
||||
|
||||
// test 2: each "span" line receives scoped style
|
||||
const spanClassList = $('pre code span').attr('class').split(/\s+/);
|
||||
expect(spanClassList.length).to.equal(2);
|
||||
const spanAstroClass = spanClassList.find(isAstroScopedClass);
|
||||
expect(Boolean(spanAstroClass)).to.equal(true);
|
||||
});
|
||||
|
||||
it('Renders correctly when deeply nested on a page', async () => {
|
||||
const html = await fixture.readFile('/deep/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: Rendered all children
|
||||
expect($('#deep').children()).to.have.lengthOf(3);
|
||||
|
||||
// tests 2–4: Only rendered title in each section
|
||||
expect($('.a').children()).to.have.lengthOf(1);
|
||||
expect($('.b').children()).to.have.lengthOf(1);
|
||||
expect($('.c').children()).to.have.lengthOf(1);
|
||||
|
||||
// test 5–7: Rendered title in correct section
|
||||
expect($('.a > h2').text()).to.equal('A');
|
||||
expect($('.b > h2').text()).to.equal('B');
|
||||
expect($('.c > h2').text()).to.equal('C');
|
||||
});
|
||||
|
||||
it('Renders dynamic content though the content attribute', async () => {
|
||||
const html = await fixture.readFile('/external/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: Rendered markdown content
|
||||
expect($('#outer')).to.have.lengthOf(1);
|
||||
|
||||
// test 2: Nested markdown content
|
||||
expect($('#inner')).to.have.lengthOf(1);
|
||||
|
||||
// test 3: Scoped class passed down
|
||||
expect($('#inner').is('[class]')).to.equal(true);
|
||||
});
|
||||
|
||||
it('Renders curly braces correctly', async () => {
|
||||
const html = await fixture.readFile('/braces/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: Rendered curly braces markdown content
|
||||
expect($('code')).to.have.lengthOf(3);
|
||||
|
||||
// test 2: Rendered curly braces markdown content
|
||||
expect($('code:first-child').text()).to.equal('({})');
|
||||
|
||||
// test 3: Rendered curly braces markdown content
|
||||
expect($('code:nth-child(2)').text()).to.equal('{...props}');
|
||||
|
||||
// test 4: Rendered curly braces markdown content
|
||||
expect($('code:last-child').text()).to.equal('{/* JavaScript */}');
|
||||
});
|
||||
|
||||
it('Does not close parent early when using content attribute (#494)', async () => {
|
||||
const html = await fixture.readFile('/close/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test <Markdown content /> closed div#target early
|
||||
expect($('#target').children()).to.have.lengthOf(2);
|
||||
});
|
||||
|
||||
it('Can render markdown with --- for horizontal rule', async () => {
|
||||
const html = await fixture.readFile('/dash/index.html');
|
||||
expect(!!html).to.equal(true);
|
||||
});
|
||||
|
||||
it('Can render markdown content prop (#1259)', async () => {
|
||||
const html = await fixture.readFile('/content/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test Markdown rendered correctly via content prop
|
||||
expect($('h1').text()).to.equal('Foo');
|
||||
});
|
||||
|
||||
it("doesn't occurs TypeError when no elements", async () => {
|
||||
const html = await fixture.readFile('/no-elements/index.html');
|
||||
// render html without error
|
||||
expect(html).to.be.ok;
|
||||
});
|
||||
|
||||
it('can render nested list correctly', async () => {
|
||||
const html = await fixture.readFile('/nested-list/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
/**
|
||||
* - list
|
||||
* - list
|
||||
*/
|
||||
expect($('#target > ul > li').children()).to.have.lengthOf(1);
|
||||
expect($('#target > ul > li > ul > li').text()).to.equal('nested list');
|
||||
/**
|
||||
* 1. Hello
|
||||
* 1. nested hello
|
||||
*/
|
||||
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'));
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
const content = '# Foo';
|
||||
---
|
||||
|
||||
<Markdown content={content} />
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
---
|
||||
|
||||
<Markdown></Markdown>
|
|
@ -1,14 +0,0 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
---
|
||||
|
||||
<html>
|
||||
<head><title>Testing</title></head>
|
||||
<body>
|
||||
<Markdown>
|
||||
# Something
|
||||
|
||||
else here
|
||||
</Markdown>
|
||||
</body>
|
||||
</html>
|
|
@ -31,10 +31,4 @@ describe('Markdown pages in SSR', () => {
|
|||
const $ = cheerioLoad(html);
|
||||
expect($('#subheading').text()).to.equal('Subheading');
|
||||
});
|
||||
|
||||
it('Renders the Markdown component correctly', async () => {
|
||||
const html = await fetchHTML('/page');
|
||||
const $ = cheerioLoad(html);
|
||||
expect($('#something')).to.have.lengthOf(1);
|
||||
});
|
||||
});
|
||||
|
|
31
packages/markdown/component/package.json
Normal file
31
packages/markdown/component/package.json
Normal file
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"name": "@astrojs/markdown-component",
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"author": "withastro",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/withastro/astro.git",
|
||||
"directory": "packages/markdown/component"
|
||||
},
|
||||
"bugs": "https://github.com/withastro/astro/issues",
|
||||
"homepage": "https://astro.build",
|
||||
"main": "./Markdown.astro",
|
||||
"exports": {
|
||||
".": {
|
||||
"astro": "./Markdown.astro"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha --exit --timeout 20000"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "workspace:*",
|
||||
"chai": "^4.3.6",
|
||||
"cheerio": "^1.0.0-rc.11",
|
||||
"mocha": "^9.2.2",
|
||||
"@types/mocha": "^9.1.1"
|
||||
},
|
||||
"keywords": ["astro", "astro-component"]
|
||||
}
|
17
packages/markdown/component/readme.md
Normal file
17
packages/markdown/component/readme.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
# @astrojs/markdown
|
||||
|
||||
This package brings legacy support for the `<Markdown />` component to all Astro projects.
|
||||
|
||||
> The `<Markdown />` component does not work in SSR. Consider [importing Markdown content](https://docs.astro.build/en/guides/markdown-content/#importing-markdown) instead.
|
||||
:::
|
||||
|
||||
```astro
|
||||
---
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
---
|
||||
<Markdown>
|
||||
# Markdown syntax is now supported! **Yay!**
|
||||
</Markdown>
|
||||
```
|
||||
|
||||
See our [Markdown Guide](https://docs.astro.build/en/guides/markdown-content/) for more info.
|
|
@ -0,0 +1,37 @@
|
|||
import { expect } from 'chai';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import addClasses from './fixtures/astro-markdown-plugins/add-classes.mjs';
|
||||
|
||||
describe('Astro Markdown plugins', () => {
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/astro-markdown-plugins/',
|
||||
markdown: {
|
||||
remarkPlugins: [
|
||||
'remark-code-titles',
|
||||
['rehype-autolink-headings', { behavior: 'prepend' }],
|
||||
],
|
||||
rehypePlugins: [
|
||||
'rehype-slug',
|
||||
['rehype-toc', { headings: ['h2', 'h3'] }],
|
||||
[addClasses, { 'h1,h2,h3': 'title' }],
|
||||
],
|
||||
},
|
||||
});
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('Can render Astro <Markdown> with plugins', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: Added a TOC
|
||||
expect($('.toc')).to.have.lengthOf(1);
|
||||
|
||||
// teste 2: Added .title to h1
|
||||
expect($('#hello-world').hasClass('title')).to.equal(true);
|
||||
});
|
||||
});
|
147
packages/markdown/component/test/astro-markdown-shiki.test.js
Normal file
147
packages/markdown/component/test/astro-markdown-shiki.test.js
Normal file
|
@ -0,0 +1,147 @@
|
|||
import { expect } from 'chai';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
describe('Astro Markdown Shiki', () => {
|
||||
describe('Render shiki', () => {
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({ root: './fixtures/astro-markdown-shiki/normal/' });
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('Can render Astro <Markdown> with shiki', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// There should be no HTML from Prism
|
||||
expect($('.token')).to.have.lengthOf(0);
|
||||
|
||||
expect($('pre')).to.have.lengthOf(2);
|
||||
|
||||
expect($('span.line')).to.have.lengthOf(2);
|
||||
expect($('span.line').get(0).children).to.have.lengthOf(1);
|
||||
expect($('span.line').get(1).children).to.have.lengthOf(5);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Themes', () => {
|
||||
describe('Integrated theme', async () => {
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({ root: './fixtures/astro-markdown-shiki/themes-integrated/' });
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('<Markdown /> component', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('pre')).to.have.lengthOf(1);
|
||||
expect($('pre').hasClass('astro-code')).to.equal(true);
|
||||
expect($('pre').attr().style).to.equal('background-color: #ffffff; overflow-x: auto;');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Custom theme', async () => {
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({ root: './fixtures/astro-markdown-shiki/themes-custom/' });
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('<Markdown /> component', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('pre')).to.have.lengthOf(1);
|
||||
expect($('pre').hasClass('astro-code')).to.equal(true);
|
||||
expect($('pre').attr().style).to.equal('background-color: #FDFDFE; overflow-x: auto;');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Custom langs', () => {
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({ root: './fixtures/astro-markdown-shiki/langs/' });
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('<Markdown /> component', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
const segments = $('.line').get(6).children;
|
||||
expect(segments).to.have.lengthOf(3);
|
||||
expect(segments[0].attribs.style).to.be.equal('color: #C9D1D9');
|
||||
expect(segments[1].attribs.style).to.be.equal('color: #79C0FF');
|
||||
|
||||
const unknownLang = $('.line').last().html();
|
||||
expect(unknownLang).to.be.equal(
|
||||
'<span style="color: #c9d1d9">This language does not exist</span>'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Wrap', () => {
|
||||
describe('wrap = true', () => {
|
||||
const style =
|
||||
'background-color: #0d1117; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;';
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({ root: './fixtures/astro-markdown-shiki/wrap-true/' });
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('<Markdown /> component', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('pre').get(0).attribs.style).to.equal(style);
|
||||
expect($('pre').get(1).attribs.style).to.equal(style);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('wrap = false', () => {
|
||||
const style = 'background-color: #0d1117; overflow-x: auto;';
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({ root: './fixtures/astro-markdown-shiki/wrap-false/' });
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('<Markdown /> component', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('pre').get(0).attribs.style).to.equal(style);
|
||||
expect($('pre').get(1).attribs.style).to.equal(style);
|
||||
});
|
||||
});
|
||||
|
||||
describe('wrap = null', () => {
|
||||
const style = 'background-color: #0d1117';
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({ root: './fixtures/astro-markdown-shiki/wrap-null/' });
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('<Markdown /> component', async () => {
|
||||
const html = await fixture.readFile('/astro/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('pre').get(0).attribs.style).to.equal(style);
|
||||
expect($('pre').get(1).attribs.style).to.equal(style);
|
||||
});
|
||||
});
|
||||
});
|
350
packages/markdown/component/test/astro-markdown.test.js
Normal file
350
packages/markdown/component/test/astro-markdown.test.js
Normal file
|
@ -0,0 +1,350 @@
|
|||
import { expect } from 'chai';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { loadFixture, fixLineEndings } from './test-utils.js';
|
||||
|
||||
describe('Astro Markdown', () => {
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/astro-markdown/',
|
||||
});
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('Can load markdown pages with Astro', async () => {
|
||||
const html = await fixture.readFile('/post/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: There is a div added in markdown
|
||||
expect($('#first').length).to.be.ok;
|
||||
|
||||
// test 2: There is a div added via a component from markdown
|
||||
expect($('#test').length).to.be.ok;
|
||||
});
|
||||
|
||||
it('Can parse JSX expressions in markdown pages', async () => {
|
||||
const html = await fixture.readFile('/jsx-expressions/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('h2').html()).to.equal('Blog Post with JSX expressions');
|
||||
|
||||
expect(html).to.contain('JSX at the start of the line!');
|
||||
for (let listItem of ['test-1', 'test-2', 'test-3']) {
|
||||
expect($(`#${listItem}`).html()).to.equal(`${listItem}`);
|
||||
}
|
||||
});
|
||||
|
||||
it('Can handle slugs with JSX expressions in markdown pages', async () => {
|
||||
const html = await fixture.readFile('/slug/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('h1').attr('id')).to.equal('my-blog-post');
|
||||
});
|
||||
|
||||
it('Can handle code elements without extra spacing', async () => {
|
||||
const html = await fixture.readFile('/code-element/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
$('code').each((_, el) => {
|
||||
expect($(el).html()).to.equal($(el).html().trim());
|
||||
});
|
||||
});
|
||||
|
||||
it('Can handle namespaced components in markdown', async () => {
|
||||
const html = await fixture.readFile('/namespace/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('h1').text()).to.equal('Hello Namespace!');
|
||||
expect($('button').length).to.equal(1);
|
||||
});
|
||||
|
||||
it('Correctly handles component children in markdown pages (#3319)', async () => {
|
||||
const html = await fixture.readFile('/children/index.html');
|
||||
|
||||
expect(html).not.to.contain('<p></p>');
|
||||
});
|
||||
|
||||
it('Can handle HTML comments in markdown pages', async () => {
|
||||
const html = await fixture.readFile('/comment/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('h1').text()).to.equal('It works!');
|
||||
});
|
||||
|
||||
it('Prevents `*/` sequences from breaking HTML comments (#3476)', async () => {
|
||||
const html = await fixture.readFile('/comment-with-js/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('h1').text()).to.equal('It still works!');
|
||||
});
|
||||
|
||||
it('Can handle HTML comments in inline code', async () => {
|
||||
const html = await fixture.readFile('/comment-with-js/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('p code').text()).to.equal('<!-- HTML comments in code -->');
|
||||
});
|
||||
|
||||
it('Can handle HTML comments in code fences', async () => {
|
||||
const html = await fixture.readFile('/comment-with-js/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('pre > code').text()).to.equal('<!-- HTML comments in code fence -->');
|
||||
});
|
||||
|
||||
// https://github.com/withastro/astro/issues/3254
|
||||
it('Can handle scripts in markdown pages', async () => {
|
||||
const html = await fixture.readFile('/script/index.html');
|
||||
expect(html).not.to.match(new RegExp('/src/scripts/test.js'));
|
||||
});
|
||||
|
||||
it('Can load more complex jsxy stuff', async () => {
|
||||
const html = await fixture.readFile('/complex/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('#test').text()).to.equal('Hello world');
|
||||
});
|
||||
|
||||
it('Empty code blocks do not fail', async () => {
|
||||
const html = await fixture.readFile('/empty-code/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: There is not a `<code>` in the codeblock
|
||||
expect($('pre')[0].children).to.have.lengthOf(1);
|
||||
|
||||
// test 2: The empty `<pre>` failed to render
|
||||
expect($('pre')[1].children).to.have.lengthOf(0);
|
||||
});
|
||||
|
||||
it('Runs code blocks through syntax highlighter', async () => {
|
||||
const html = await fixture.readFile('/code/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: There are child spans in code blocks
|
||||
expect($('code span').length).greaterThan(0);
|
||||
});
|
||||
|
||||
it('Scoped styles should not break syntax highlight', async () => {
|
||||
const html = await fixture.readFile('/scopedStyles-code/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: <pre> tag has correct shiki class
|
||||
expect($('pre').hasClass('astro-code')).to.equal(true);
|
||||
|
||||
// test 2: inline styles are still applied
|
||||
expect($('pre').is('[style]')).to.equal(true);
|
||||
|
||||
// test 3: There are styled child spans in code blocks
|
||||
expect($('pre code span').length).to.be.greaterThan(0);
|
||||
expect($('pre code span').is('[style]')).to.equal(true);
|
||||
});
|
||||
|
||||
function isAstroScopedClass(cls) {
|
||||
return /^astro-.*/.test(cls);
|
||||
}
|
||||
|
||||
it('Scoped styles should be applied to syntax highlighted lines', async () => {
|
||||
const html = await fixture.readFile('/scopedStyles-code/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: the "pre" tag receives scoped style
|
||||
const preClassList = $('pre').attr('class').split(/\s+/);
|
||||
expect(preClassList.length).to.equal(2);
|
||||
const preAstroClass = preClassList.find(isAstroScopedClass);
|
||||
expect(Boolean(preAstroClass)).to.equal(true);
|
||||
|
||||
// test 2: each "span" line receives scoped style
|
||||
const spanClassList = $('pre code span').attr('class').split(/\s+/);
|
||||
expect(spanClassList.length).to.equal(2);
|
||||
const spanAstroClass = spanClassList.find(isAstroScopedClass);
|
||||
expect(Boolean(spanAstroClass)).to.equal(true);
|
||||
});
|
||||
|
||||
it('Renders correctly when deeply nested on a page', async () => {
|
||||
const html = await fixture.readFile('/deep/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: Rendered all children
|
||||
expect($('#deep').children()).to.have.lengthOf(3);
|
||||
|
||||
// tests 2–4: Only rendered title in each section
|
||||
expect($('.a').children()).to.have.lengthOf(1);
|
||||
expect($('.b').children()).to.have.lengthOf(1);
|
||||
expect($('.c').children()).to.have.lengthOf(1);
|
||||
|
||||
// test 5–7: Rendered title in correct section
|
||||
expect($('.a > h2').text()).to.equal('A');
|
||||
expect($('.b > h2').text()).to.equal('B');
|
||||
expect($('.c > h2').text()).to.equal('C');
|
||||
});
|
||||
|
||||
it('Renders dynamic content though the content attribute', async () => {
|
||||
const html = await fixture.readFile('/external/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: Rendered markdown content
|
||||
expect($('#outer')).to.have.lengthOf(1);
|
||||
|
||||
// test 2: Nested markdown content
|
||||
expect($('#inner')).to.have.lengthOf(1);
|
||||
|
||||
// test 3: Scoped class passed down
|
||||
expect($('#inner').is('[class]')).to.equal(true);
|
||||
});
|
||||
|
||||
it('Renders curly braces correctly', async () => {
|
||||
const html = await fixture.readFile('/braces/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: Rendered curly braces markdown content
|
||||
expect($('code')).to.have.lengthOf(3);
|
||||
|
||||
// test 2: Rendered curly braces markdown content
|
||||
expect($('code:first-child').text()).to.equal('({})');
|
||||
|
||||
// test 3: Rendered curly braces markdown content
|
||||
expect($('code:nth-child(2)').text()).to.equal('{...props}');
|
||||
|
||||
// test 4: Rendered curly braces markdown content
|
||||
expect($('code:last-child').text()).to.equal('{/* JavaScript */}');
|
||||
});
|
||||
|
||||
it('Does not close parent early when using content attribute (#494)', async () => {
|
||||
const html = await fixture.readFile('/close/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test <Markdown content /> closed div#target early
|
||||
expect($('#target').children()).to.have.lengthOf(2);
|
||||
});
|
||||
|
||||
it('Can render markdown with --- for horizontal rule', async () => {
|
||||
const html = await fixture.readFile('/dash/index.html');
|
||||
expect(!!html).to.equal(true);
|
||||
});
|
||||
|
||||
it('Can render markdown content prop (#1259)', async () => {
|
||||
const html = await fixture.readFile('/content/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test Markdown rendered correctly via content prop
|
||||
expect($('h1').text()).to.equal('Foo');
|
||||
});
|
||||
|
||||
it("doesn't occurs TypeError when no elements", async () => {
|
||||
const html = await fixture.readFile('/no-elements/index.html');
|
||||
// render html without error
|
||||
expect(html).to.be.ok;
|
||||
});
|
||||
|
||||
it('can render nested list correctly', async () => {
|
||||
const html = await fixture.readFile('/nested-list/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
/**
|
||||
* - list
|
||||
* - list
|
||||
*/
|
||||
expect($('#target > ul > li').children()).to.have.lengthOf(1);
|
||||
expect($('#target > ul > li > ul > li').text()).to.equal('nested list');
|
||||
/**
|
||||
* 1. Hello
|
||||
* 1. nested hello
|
||||
*/
|
||||
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 />`
|
||||
);
|
||||
});
|
||||
|
||||
it('Allows referencing Vite env var names in markdown (#3412)', async () => {
|
||||
const html = await fixture.readFile('/vite-env-vars/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// test 1: referencing an existing var name
|
||||
expect($('code').eq(0).text()).to.equal('import.meta.env.SITE');
|
||||
expect($('li').eq(0).text()).to.equal('import.meta.env.SITE');
|
||||
expect($('code').eq(3).text()).to.contain('site: import.meta.env.SITE');
|
||||
expect($('blockquote').text()).to.contain('import.meta.env.SITE');
|
||||
|
||||
// test 2: referencing a non-existing var name
|
||||
expect($('code').eq(1).text()).to.equal('import.meta.env.TITLE');
|
||||
expect($('li').eq(1).text()).to.equal('import.meta.env.TITLE');
|
||||
expect($('code').eq(3).text()).to.contain('title: import.meta.env.TITLE');
|
||||
expect($('blockquote').text()).to.contain('import.meta.env.TITLE');
|
||||
|
||||
// test 3: referencing `import.meta.env` itself (without any var name)
|
||||
expect($('code').eq(2).text()).to.equal('import.meta.env');
|
||||
expect($('li').eq(2).text()).to.equal('import.meta.env');
|
||||
expect($('code').eq(3).text()).to.contain('// Use Vite env vars with import.meta.env');
|
||||
expect($('blockquote').text()).to.match(/import\.meta\.env\s*$/);
|
||||
});
|
||||
|
||||
it('Escapes HTML tags in code blocks', async () => {
|
||||
const html = await fixture.readFile('/code-in-md/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('code').eq(0).html()).to.equal('<script>');
|
||||
expect($('blockquote').length).to.equal(1);
|
||||
expect($('code').eq(1).html()).to.equal('</script>');
|
||||
expect($('pre').html()).to.contain('>This should also work without any problems.<');
|
||||
});
|
||||
|
||||
it('Allows defining slot contents in component children', async () => {
|
||||
const html = await fixture.readFile('/slots/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
const slots = $('article').eq(0);
|
||||
expect(slots.find('> .fragmentSlot > div').text()).to.contain('1:');
|
||||
expect(slots.find('> .fragmentSlot > div + p').text()).to.contain('2:');
|
||||
expect(slots.find('> .pSlot > p[title="hello"]').text()).to.contain('3:');
|
||||
expect(slots.find('> .defaultSlot').html()).to.match(
|
||||
new RegExp(
|
||||
`<div>4: Div in default slot</div>` +
|
||||
// Optional extra paragraph due to the line breaks between components
|
||||
`(<p></p>)?` +
|
||||
`<p>5: Paragraph in fragment in default slot</p>` +
|
||||
// Optional whitespace due to the line breaks between components
|
||||
`[\s\n]*` +
|
||||
`6: Regular text in default slot`
|
||||
)
|
||||
);
|
||||
|
||||
const nestedSlots = $('article').eq(1);
|
||||
expect(nestedSlots.find('> .fragmentSlot').html()).to.contain('1:');
|
||||
expect(nestedSlots.find('> .pSlot > p').text()).to.contain('2:');
|
||||
expect(nestedSlots.find('> .defaultSlot > article').text().replace(/\s+/g, ' ')).to.equal(
|
||||
`
|
||||
3: nested fragmentSlot
|
||||
4: nested pSlot
|
||||
5: nested text in default slot
|
||||
`.replace(/\s+/g, ' ')
|
||||
);
|
||||
|
||||
expect($('article').eq(3).text().replace(/[^❌]/g, '')).to.equal('❌❌❌');
|
||||
|
||||
expect($('article').eq(4).text().replace(/[^❌]/g, '')).to.equal('❌❌❌');
|
||||
});
|
||||
|
||||
it('Generate the right props for the layout', async () => {
|
||||
const html = await fixture.readFile('/layout-props/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect($('#title').text()).to.equal('Hello world!');
|
||||
expect($('#url').text()).to.equal('/layout-props');
|
||||
expect($('#file').text()).to.match(/.*\/layout-props.md$/);
|
||||
});
|
||||
});
|
18
packages/markdown/component/test/fixtures/astro-markdown-plugins/add-classes.mjs
vendored
Normal file
18
packages/markdown/component/test/fixtures/astro-markdown-plugins/add-classes.mjs
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { selectAll } from 'hast-util-select';
|
||||
|
||||
export default (additions) => {
|
||||
const adders = Object.entries(additions).map(adder);
|
||||
return (node) => adders.forEach((a) => a(node));
|
||||
};
|
||||
|
||||
const adder = ([selector, className]) => {
|
||||
const writer = write(className);
|
||||
return (node) => selectAll(selector, node).forEach(writer);
|
||||
};
|
||||
|
||||
const write =
|
||||
(className) =>
|
||||
({ properties }) => {
|
||||
if (!properties.className) properties.className = className;
|
||||
else properties.className += ` ${className}`;
|
||||
};
|
7
packages/markdown/component/test/fixtures/astro-markdown-plugins/astro.config.mjs
vendored
Normal file
7
packages/markdown/component/test/fixtures/astro-markdown-plugins/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import preact from '@astrojs/preact';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [preact()],
|
||||
});
|
12
packages/markdown/component/test/fixtures/astro-markdown-plugins/package.json
vendored
Normal file
12
packages/markdown/component/test/fixtures/astro-markdown-plugins/package.json
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "@test/astro-markdown-component-plugins",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/preact": "workspace:*",
|
||||
"@astrojs/markdown-component": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"hast-util-select": "^5.0.2",
|
||||
"rehype-slug": "^5.0.1"
|
||||
}
|
||||
}
|
10
packages/markdown/component/test/fixtures/astro-markdown-plugins/src/layouts/content.astro
vendored
Normal file
10
packages/markdown/component/test/fixtures/astro-markdown-plugins/src/layouts/content.astro
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
import Layout from '../layouts/content.astro';
|
||||
---
|
||||
|
19
packages/markdown/component/test/fixtures/astro-markdown-shiki/langs/astro.config.mjs
vendored
Normal file
19
packages/markdown/component/test/fixtures/astro-markdown-shiki/langs/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
const riGrammar = JSON.parse(
|
||||
String.raw`{"name":"rinfo","patterns":[{"include":"#lf-rinfo"}],"repository":{"lf-rinfo":{"patterns":[{"include":"#control"},{"include":"#operator"},{"include":"#strings"},{"include":"#number"},{"include":"#comment"},{"include":"#literal"}]},"control":{"patterns":[{"name":"keyword.control.ri","match":"\\b(si|mientras|repetir)\\b"},{"name":"keyword.other.ri","match":"\\b(programa|robots|areas|variables|comenzar|fin)\\b"},{"name":"support.function.other.ri","match":"\\b(tomarFlor|HayFlorEnLaBolsa|HayFlorEnLaEsquina|depositarFlor|HayPapelEnLaBolsa|HayPapelEnLaEsquina|tomarPapel|depositarPapel)\\b"}]},"operator":{"comment":"Captures operators and also puts them in different sub-groups that further describe them","patterns":[{"match":"\\+|-|\\*|/","name":"keyword.operator.arithmetic.ri"},{"match":"<|>|<=|>=|=|<>|!=","name":"keyword.operator.comparison.ri"},{"match":"\\b(Pos|Informar|Leer|Iniciar|AsignarArea|AreaC)\\b","name":"support.function.arithmetic.ri"},{"match":":=","name":"keyword.operator.assign.ri"},{"match":"(&|~)","name":"support.function.logical.ri"}]},"strings":{"name":"string.quoted.double.ri","beginCaptures":{"0":{"name":"string.quoted.double.begin.ri"}},"endCaptures":{"0":{"name":"string.quoted.double.end.ri"}},"begin":"\"","end":"\"","patterns":[{"name":"constant.character.escape.ri","match":"\\\\."}]},"comment":{"patterns":[{"name":"comment.block.ri","begin":"{","end":"}","patterns":[{"include":"#comment"}]}]},"literal":{"patterns":[{"name":"constant.language.ri","match":"\\b(verdadero|falso|boolean|numero)\\b"}]},"number":{"patterns":[{"comment":"Captures decimal numbers, with the negative sign being considered an operator","match":"(-)?(?:((?:\\b\\d+(?:\\.\\d*)?|\\.\\d+)(?:\\b|e-?\\d+\\b)%?)|(\\$[0-9]+\\b))","captures":{"1":{"name":"keyword.operator.arithmetic.ri"},"2":{"name":"constant.numeric.decimal.ri"},"3":{"name":"constant.numeric.hex.ri"}}}]}},"scopeName":"source.rinfo"}`
|
||||
);
|
||||
|
||||
export default {
|
||||
markdown: {
|
||||
syntaxHighlight: 'shiki',
|
||||
shikiConfig: {
|
||||
langs: [
|
||||
{
|
||||
id: 'rinfo',
|
||||
scopeName: 'source.rinfo',
|
||||
grammar: riGrammar,
|
||||
aliases: ['ri'],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/langs/package.json
vendored
Normal file
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/langs/package.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/astro-markdown-skiki-langs",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/markdown-component": "workspace:*"
|
||||
}
|
||||
}
|
10
packages/markdown/component/test/fixtures/astro-markdown-shiki/langs/src/layouts/content.astro
vendored
Normal file
10
packages/markdown/component/test/fixtures/astro-markdown-shiki/langs/src/layouts/content.astro
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
import Layout from '../layouts/content.astro';
|
||||
---
|
||||
|
5
packages/markdown/component/test/fixtures/astro-markdown-shiki/normal/astro.config.mjs
vendored
Normal file
5
packages/markdown/component/test/fixtures/astro-markdown-shiki/normal/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
export default {
|
||||
markdown: {
|
||||
syntaxHighlight: 'shiki',
|
||||
},
|
||||
}
|
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/normal/package.json
vendored
Normal file
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/normal/package.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/astro-markdown-skiki-normal",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/markdown-component": "workspace:*"
|
||||
}
|
||||
}
|
10
packages/markdown/component/test/fixtures/astro-markdown-shiki/normal/src/layouts/content.astro
vendored
Normal file
10
packages/markdown/component/test/fixtures/astro-markdown-shiki/normal/src/layouts/content.astro
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
import Layout from '../layouts/content.astro';
|
||||
---
|
||||
|
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/package.json
vendored
Normal file
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/package.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/astro-markdown-component-shiki",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/markdown-component": "workspace:*"
|
||||
}
|
||||
}
|
10
packages/markdown/component/test/fixtures/astro-markdown-shiki/themes-custom/astro.config.mjs
vendored
Normal file
10
packages/markdown/component/test/fixtures/astro-markdown-shiki/themes-custom/astro.config.mjs
vendored
Normal file
File diff suppressed because one or more lines are too long
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/themes-custom/package.json
vendored
Normal file
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/themes-custom/package.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/astro-markdown-skiki-themes-custom",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/markdown-component": "workspace:*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
import Layout from '../layouts/content.astro';
|
||||
---
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
export default {
|
||||
markdown: {
|
||||
syntaxHighlight: 'shiki',
|
||||
shikiConfig: { theme: 'github-light' },
|
||||
},
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/astro-markdown-skiki-themes-integrated",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/markdown-component": "workspace:*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
import Layout from '../layouts/content.astro';
|
||||
---
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
layout: ../layouts/content.astro
|
||||
---
|
||||
|
||||
# Hello world
|
||||
|
||||
```yaml
|
||||
apiVersion: v3
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: rss-site
|
||||
labels:
|
||||
app: web
|
||||
spec:
|
||||
containers:
|
||||
- name: front-end
|
||||
image: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
- name: rss-reader
|
||||
image: nickchase/rss-php-nginx:v1
|
||||
ports:
|
||||
- containerPort: 88
|
||||
```
|
6
packages/markdown/component/test/fixtures/astro-markdown-shiki/wrap-false/astro.config.mjs
vendored
Normal file
6
packages/markdown/component/test/fixtures/astro-markdown-shiki/wrap-false/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
export default {
|
||||
markdown: {
|
||||
syntaxHighlight: 'shiki',
|
||||
shikiConfig: { wrap: false },
|
||||
},
|
||||
}
|
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/wrap-false/package.json
vendored
Normal file
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/wrap-false/package.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/astro-markdown-skiki-wrap-false",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/markdown-component": "workspace:*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
import Layout from '../layouts/content.astro';
|
||||
---
|
||||
|
6
packages/markdown/component/test/fixtures/astro-markdown-shiki/wrap-null/astro.config.mjs
vendored
Normal file
6
packages/markdown/component/test/fixtures/astro-markdown-shiki/wrap-null/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
export default {
|
||||
markdown: {
|
||||
syntaxHighlight: 'shiki',
|
||||
shikiConfig: { wrap: null },
|
||||
},
|
||||
}
|
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/wrap-null/package.json
vendored
Normal file
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/wrap-null/package.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/astro-markdown-skiki-wrap-null",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/markdown-component": "workspace:*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
import Layout from '../layouts/content.astro';
|
||||
---
|
||||
|
6
packages/markdown/component/test/fixtures/astro-markdown-shiki/wrap-true/astro.config.mjs
vendored
Normal file
6
packages/markdown/component/test/fixtures/astro-markdown-shiki/wrap-true/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
export default {
|
||||
markdown: {
|
||||
syntaxHighlight: 'shiki',
|
||||
shikiConfig: { wrap: true },
|
||||
},
|
||||
}
|
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/wrap-true/package.json
vendored
Normal file
9
packages/markdown/component/test/fixtures/astro-markdown-shiki/wrap-true/package.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/astro-markdown-skiki-wrap-true",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/markdown-component": "workspace:*"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
import Layout from '../layouts/content.astro';
|
||||
---
|
||||
|
9
packages/markdown/component/test/fixtures/astro-markdown/astro.config.mjs
vendored
Normal file
9
packages/markdown/component/test/fixtures/astro-markdown/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import preact from '@astrojs/preact';
|
||||
import svelte from "@astrojs/svelte";
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [preact(), svelte()],
|
||||
site: 'https://astro.build/',
|
||||
});
|
11
packages/markdown/component/test/fixtures/astro-markdown/package.json
vendored
Normal file
11
packages/markdown/component/test/fixtures/astro-markdown/package.json
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "@test/astro-markdown-component",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/preact": "workspace:*",
|
||||
"@astrojs/svelte": "workspace:*",
|
||||
"@astrojs/markdown-component": "workspace:*",
|
||||
"astro": "workspace:*"
|
||||
}
|
||||
}
|
7
packages/markdown/component/test/fixtures/astro-markdown/src/components/Counter.jsx
vendored
Normal file
7
packages/markdown/component/test/fixtures/astro-markdown/src/components/Counter.jsx
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { h } from 'preact';
|
||||
import { useState } from 'preact/hooks';
|
||||
|
||||
export default function () {
|
||||
const [count, setCount] = useState(0);
|
||||
return <button onClick={() => setCount(count + 1)}>{count}</button>;
|
||||
}
|
5
packages/markdown/component/test/fixtures/astro-markdown/src/components/Example.jsx
vendored
Normal file
5
packages/markdown/component/test/fixtures/astro-markdown/src/components/Example.jsx
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { h } from 'preact';
|
||||
|
||||
export default function () {
|
||||
return <div id="test">Testing</div>;
|
||||
}
|
5
packages/markdown/component/test/fixtures/astro-markdown/src/components/Hello.jsx
vendored
Normal file
5
packages/markdown/component/test/fixtures/astro-markdown/src/components/Hello.jsx
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { h } from 'preact';
|
||||
|
||||
export default function ({ name }) {
|
||||
return <div id="test">Hello {name}</div>;
|
||||
}
|
13
packages/markdown/component/test/fixtures/astro-markdown/src/components/SlotComponent.astro
vendored
Normal file
13
packages/markdown/component/test/fixtures/astro-markdown/src/components/SlotComponent.astro
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
<article>
|
||||
<section class="fragmentSlot">
|
||||
<slot name="fragmentSlot">❌ Missing content for slot "fragmentSlot"</slot>
|
||||
</section>
|
||||
|
||||
<section class="pSlot">
|
||||
<slot name="pSlot">❌ Missing content for slot "pSlot"</slot>
|
||||
</section>
|
||||
|
||||
<section class="defaultSlot">
|
||||
<slot>❌ Missing content for default slot</slot>
|
||||
</section>
|
||||
</article>
|
11
packages/markdown/component/test/fixtures/astro-markdown/src/components/SvelteButton.svelte
vendored
Normal file
11
packages/markdown/component/test/fixtures/astro-markdown/src/components/SvelteButton.svelte
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
<script>
|
||||
let cool = false
|
||||
</script>
|
||||
|
||||
<button on:click={() => cool = true}>This is cool right? {cool}</button>
|
||||
|
||||
<style>
|
||||
button {
|
||||
background: green;
|
||||
}
|
||||
</style>
|
20
packages/markdown/component/test/fixtures/astro-markdown/src/components/TextBlock.jsx
vendored
Normal file
20
packages/markdown/component/test/fixtures/astro-markdown/src/components/TextBlock.jsx
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { h } from 'preact';
|
||||
|
||||
const TextBlock = ({
|
||||
title,
|
||||
children,
|
||||
noPadding = false,
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className={`${
|
||||
noPadding ? "" : "md:px-2 lg:px-4"
|
||||
} flex-1 prose prose-headings:font-grotesk`}
|
||||
>
|
||||
<h3>{title}</h3>
|
||||
<p>{children}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TextBlock;
|
5
packages/markdown/component/test/fixtures/astro-markdown/src/components/index.js
vendored
Normal file
5
packages/markdown/component/test/fixtures/astro-markdown/src/components/index.js
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import Counter from './Counter';
|
||||
|
||||
export default {
|
||||
Counter
|
||||
}
|
3
packages/markdown/component/test/fixtures/astro-markdown/src/content/code-element.md
vendored
Normal file
3
packages/markdown/component/test/fixtures/astro-markdown/src/content/code-element.md
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
This should have `nospace` around it.
|
||||
|
||||
This should have <code class="custom-class">nospace</code> around it.
|
6
packages/markdown/component/test/fixtures/astro-markdown/src/imported-md/plain.md
vendored
Normal file
6
packages/markdown/component/test/fixtures/astro-markdown/src/imported-md/plain.md
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
---
|
||||
|
||||
## Plain jane
|
||||
|
||||
I am plain markdown!
|
17
packages/markdown/component/test/fixtures/astro-markdown/src/imported-md/with-components.md
vendored
Normal file
17
packages/markdown/component/test/fixtures/astro-markdown/src/imported-md/with-components.md
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
setup: |
|
||||
import Counter from '../components/Counter.jsx'
|
||||
import Hello from '../components/Hello.jsx'
|
||||
import SvelteButton from '../components/SvelteButton.svelte'
|
||||
---
|
||||
|
||||
## With components
|
||||
|
||||
### Non-hydrated
|
||||
|
||||
<Hello name="Astro Naut" />
|
||||
|
||||
### Hydrated
|
||||
|
||||
<Counter client:load />
|
||||
<SvelteButton client:load />
|
10
packages/markdown/component/test/fixtures/astro-markdown/src/layouts/content.astro
vendored
Normal file
10
packages/markdown/component/test/fixtures/astro-markdown/src/layouts/content.astro
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
17
packages/markdown/component/test/fixtures/astro-markdown/src/layouts/layout-props.astro
vendored
Normal file
17
packages/markdown/component/test/fixtures/astro-markdown/src/layouts/layout-props.astro
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
interface Props {
|
||||
url: string;
|
||||
file: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
const { title, url, file } = Astro.props.content as Props;
|
||||
---
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<div id="title">{title}</div>
|
||||
<div id="url">{url}</div>
|
||||
<div id="file">{file}</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,10 +1,10 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
const title = 'My Blog Post';
|
||||
const description = 'This is a post about some stuff.';
|
||||
---
|
||||
|
||||
<Markdown>
|
||||
<Markdown is:raw>
|
||||
## Interesting Topic
|
||||
|
||||
`({})`
|
12
packages/markdown/component/test/fixtures/astro-markdown/src/pages/children.md
vendored
Normal file
12
packages/markdown/component/test/fixtures/astro-markdown/src/pages/children.md
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
setup: import TextBlock from '../components/TextBlock'
|
||||
---
|
||||
{/* https://github.com/withastro/astro/issues/3319 */}
|
||||
|
||||
<TextBlock title="Hello world!" noPadding>
|
||||
<ul class="not-prose">
|
||||
<li>A</li>
|
||||
<li>B</li>
|
||||
<li>C</li>
|
||||
</ul>
|
||||
</TextBlock>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
const content = `Markdown *content* to render`;
|
||||
---
|
||||
|
7
packages/markdown/component/test/fixtures/astro-markdown/src/pages/code-element.astro
vendored
Normal file
7
packages/markdown/component/test/fixtures/astro-markdown/src/pages/code-element.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
const content = await Astro.glob('../content/*.md');
|
||||
---
|
||||
|
||||
<div>
|
||||
{content.map(({ Content }) => <Content />)}
|
||||
</div>
|
16
packages/markdown/component/test/fixtures/astro-markdown/src/pages/code-in-md.md
vendored
Normal file
16
packages/markdown/component/test/fixtures/astro-markdown/src/pages/code-in-md.md
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Inline code blocks
|
||||
|
||||
`<script>` tags in **Astro** components are now built,
|
||||
bundled and optimized by default.
|
||||
|
||||
> Markdown formatting still works between tags in inline code blocks.
|
||||
|
||||
We can also use closing `</script>` tags without any problems.
|
||||
|
||||
# Fenced code blocks
|
||||
|
||||
```html
|
||||
<body>
|
||||
<div>This should also work without any problems.</div>
|
||||
</body>
|
||||
```
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
const title = 'My Blog Post';
|
||||
const description = 'This is a post about some stuff.';
|
||||
---
|
23
packages/markdown/component/test/fixtures/astro-markdown/src/pages/comment-with-js.md
vendored
Normal file
23
packages/markdown/component/test/fixtures/astro-markdown/src/pages/comment-with-js.md
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!--
|
||||
HTML comments with */ inside!
|
||||
-->
|
||||
|
||||
<!--
|
||||
```js
|
||||
/**
|
||||
* It even works inside nested fenced code blocks!
|
||||
*/
|
||||
function test() {
|
||||
/* Yay */
|
||||
return 'Nice!';
|
||||
}
|
||||
```
|
||||
-->
|
||||
|
||||
```
|
||||
<!-- HTML comments in code fence -->
|
||||
```
|
||||
|
||||
`<!-- HTML comments in code -->`
|
||||
|
||||
# It still works!
|
2
packages/markdown/component/test/fixtures/astro-markdown/src/pages/comment.md
vendored
Normal file
2
packages/markdown/component/test/fixtures/astro-markdown/src/pages/comment.md
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
<!-- HTML comments! -->
|
||||
# It works!
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
import Layout from '../layouts/content.astro';
|
||||
import Hello from '../components/Hello.jsx';
|
||||
import Counter from '../components/Counter.jsx';
|
6
packages/markdown/component/test/fixtures/astro-markdown/src/pages/content.astro
vendored
Normal file
6
packages/markdown/component/test/fixtures/astro-markdown/src/pages/content.astro
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
const content = '# Foo';
|
||||
---
|
||||
|
||||
<Markdown content={content} />
|
14
packages/markdown/component/test/fixtures/astro-markdown/src/pages/dash.md
vendored
Normal file
14
packages/markdown/component/test/fixtures/astro-markdown/src/pages/dash.md
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
title: My Blog Post
|
||||
layout: ../layouts/content.astro
|
||||
---
|
||||
|
||||
## Title
|
||||
|
||||
Hello world
|
||||
|
||||
With this in the body ---
|
||||
|
||||
## Another
|
||||
|
||||
more content
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
import Layout from '../layouts/content.astro';
|
||||
import Hello from '../components/Hello.jsx';
|
||||
import Counter from '../components/Counter.jsx';
|
20
packages/markdown/component/test/fixtures/astro-markdown/src/pages/empty-code.md
vendored
Normal file
20
packages/markdown/component/test/fixtures/astro-markdown/src/pages/empty-code.md
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: My Blog Post
|
||||
layout: ../layouts/content.astro
|
||||
---
|
||||
|
||||
## Title
|
||||
|
||||
Hello world
|
||||
|
||||
With this in the body ---
|
||||
|
||||
## Another
|
||||
|
||||
more content
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
<pre></pre>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Markdown from '@astrojs/markdown-component';
|
||||
|
||||
const outer = `# Outer`;
|
||||
const inner = `## Inner`;
|
||||
|
@ -16,4 +16,4 @@ const inner = `## Inner`;
|
|||
|
||||
<Markdown content={inner} />
|
||||
</Markdown>
|
||||
</div>
|
||||
</div>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue