New Package for HTML Content Rendering, and it works!
This commit is contained in:
parent
2793d9751c
commit
a23452ec20
|
@ -51,7 +51,9 @@
|
||||||
"eslint-plugin-jsx-a11y": "^6.8.0",
|
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||||
"prettier-plugin-astro": "^0.13.0",
|
"prettier-plugin-astro": "^0.13.0",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"@matthiesenxyz/astro-ghostcms": "workspace:*"
|
"@matthiesenxyz/astro-ghostcms": "workspace:*",
|
||||||
|
"@matthiesenxyz/astro-ghostcms-rendercontent": "workspace:*",
|
||||||
|
"node-html-parser": "6.1.12"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify-json/logos": "^1.1.41",
|
"@iconify-json/logos": "^1.1.41",
|
||||||
|
@ -62,6 +64,7 @@
|
||||||
"unocss": "^0.57.7",
|
"unocss": "^0.57.7",
|
||||||
"@eliancodes/brutal-ui": "^0.2.3",
|
"@eliancodes/brutal-ui": "^0.2.3",
|
||||||
"astro-font": "^0.0.72",
|
"astro-font": "^0.0.72",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3",
|
||||||
|
"ultrahtml": "^1.5.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,12 @@ export type Props = {
|
||||||
const { post, settings } = Astro.props as Props;
|
const { post, settings } = Astro.props as Props;
|
||||||
---
|
---
|
||||||
<header class="article-header gh-canvas">
|
<header class="article-header gh-canvas">
|
||||||
<div class="flex justify-between my-4">
|
<div class="flex justify-between">
|
||||||
<section class="flex flex-grow align-middle">
|
<section class="flex flex-grow align-middle">
|
||||||
<div class="text-ctp-overlay2">
|
<div class="text-ctp-overlay2">
|
||||||
{ post.primary_author && (
|
{ post.primary_author && (
|
||||||
<h4 class="text-ctp-teal">Author:
|
<h4 class="text-ctp-teal">Author:
|
||||||
{post.primary_author.name}
|
<a href={`/author/${post.primary_author.slug}`}>{post.primary_author.name}</a>
|
||||||
</h4>
|
</h4>
|
||||||
)}
|
)}
|
||||||
<div class="text-ctp-overlay2">
|
<div class="text-ctp-overlay2">
|
||||||
|
@ -31,6 +31,7 @@ const { post, settings } = Astro.props as Props;
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
<center><h1 class="text-5xl righteous pb-5">{post.title}</h1></center>
|
||||||
{post.feature_image && (
|
{post.feature_image && (
|
||||||
<FeatureImage
|
<FeatureImage
|
||||||
image={post.feature_image}
|
image={post.feature_image}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
import { Code } from "astro/components"
|
||||||
|
import { parse } from "ultrahtml"
|
||||||
|
import { querySelector } from "ultrahtml/selector"
|
||||||
|
|
||||||
|
const html = await Astro.slots.render("default")
|
||||||
|
const ast = await parse(html)
|
||||||
|
const codetag = querySelector(ast,'code')
|
||||||
|
const { children } = codetag
|
||||||
|
const code = children[0].value
|
||||||
|
---
|
||||||
|
<Code code={code} lang={"sh"} theme={"monokai"}/>
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<h1 class="righteous text-4xl">
|
||||||
|
<slot />
|
||||||
|
</h1>
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<h2 class="righteous text-3xl">
|
||||||
|
<slot />
|
||||||
|
</h2>
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<h3 class="righteous text-2xl">
|
||||||
|
<slot />
|
||||||
|
</h3>
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<h4 class="righteous text-1xl">
|
||||||
|
<slot />
|
||||||
|
</h4>
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<h5 class="righteous text-xl">
|
||||||
|
<slot />
|
||||||
|
</h5>
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<h6 class="righteous text-lg">
|
||||||
|
<slot />
|
||||||
|
</h6>
|
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<p class="my-5 text-base"><slot /></p>
|
||||||
|
|
||||||
|
<style is:inline>
|
||||||
|
#ghost p a {
|
||||||
|
color: rgb(0, 123, 247);
|
||||||
|
}
|
||||||
|
#ghost ul li a {
|
||||||
|
color: rgb(0, 123, 247);
|
||||||
|
}
|
||||||
|
#ghost ul li {
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
margin-left: 2rem;
|
||||||
|
list-style: circle;
|
||||||
|
}
|
||||||
|
#ghost ul {
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,8 @@
|
||||||
|
export { default as H1 } from "./H1.astro"
|
||||||
|
export { default as H2 } from "./H2.astro"
|
||||||
|
export { default as H3 } from "./H3.astro"
|
||||||
|
export { default as H4 } from "./H4.astro"
|
||||||
|
export { default as H5 } from "./H5.astro"
|
||||||
|
export { default as H6 } from "./H6.astro"
|
||||||
|
export { default as CodeSlot } from "./CodeSlot.astro"
|
||||||
|
export { default as Paragraph } from "./Paragraph.astro"
|
|
@ -4,6 +4,9 @@ import { getAllPosts, getAllPages, getSettings, invariant } from "@matthiesenxyz
|
||||||
import type { InferGetStaticPropsType } from "astro";
|
import type { InferGetStaticPropsType } from "astro";
|
||||||
import RecentBlogPosts from "../components/generic/RecentBlogPosts.astro";
|
import RecentBlogPosts from "../components/generic/RecentBlogPosts.astro";
|
||||||
import BlogPostHeader from "../components/blog/BlogPostHeader.astro";
|
import BlogPostHeader from "../components/blog/BlogPostHeader.astro";
|
||||||
|
import { GhostRender } from "@matthiesenxyz/astro-ghostcms-rendercontent";
|
||||||
|
import * as C from "../components/ghostrender";
|
||||||
|
import { Card } from "@eliancodes/brutal-ui";
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const [posts, pages, settings] = await Promise.all([getAllPosts(), await getAllPages(), await getSettings()]);
|
const [posts, pages, settings] = await Promise.all([getAllPosts(), await getAllPages(), await getSettings()]);
|
||||||
|
@ -19,11 +22,29 @@ const {post, posts, settings} = Astro.props as Props;
|
||||||
invariant(settings, "Settings are required");
|
invariant(settings, "Settings are required");
|
||||||
---
|
---
|
||||||
<BlogPost title={post.title} description={post.excerpt}>
|
<BlogPost title={post.title} description={post.excerpt}>
|
||||||
<article class='prose-slate w-sm md:w-prose md:prose poppins pl-4'>
|
<article class='w-auto md:w-vmax p-10 poppins'>
|
||||||
|
|
||||||
|
<Card>
|
||||||
<BlogPostHeader post={post} settings={settings} />
|
<BlogPostHeader post={post} settings={settings} />
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<div class="my-5"/>
|
||||||
|
<div id="ghost">
|
||||||
|
<GhostRender
|
||||||
|
content={post.html}
|
||||||
|
components={{
|
||||||
|
h1: C.H1,
|
||||||
|
h2: C.H2,
|
||||||
|
h3: C.H3,
|
||||||
|
h4: C.H4,
|
||||||
|
h5: C.H5,
|
||||||
|
h6: C.H6,
|
||||||
|
pre: C.CodeSlot,
|
||||||
|
p: C.Paragraph,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Fragment set:html={post.html} />
|
|
||||||
</article>
|
</article>
|
||||||
<section class='p-6'>
|
<section class='p-6'>
|
||||||
<RecentBlogPosts posts={posts} settings={settings} />
|
<RecentBlogPosts posts={posts} settings={settings} />
|
||||||
|
|
|
@ -119,3 +119,170 @@ html {
|
||||||
{
|
{
|
||||||
background-color: aliceblue;
|
background-color: aliceblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** GITHUB - Gists */
|
||||||
|
body .gist .highlight {
|
||||||
|
background: #272822;
|
||||||
|
}
|
||||||
|
body .gist .blob-num,
|
||||||
|
body .gist .blob-code-inner,
|
||||||
|
body .gist .pl-s2,
|
||||||
|
body .gist .pl-stj {
|
||||||
|
color: #f8f8f2;
|
||||||
|
}
|
||||||
|
body .gist .pl-c1 {
|
||||||
|
color: #ae81ff;
|
||||||
|
}
|
||||||
|
body .gist .pl-enti {
|
||||||
|
color: #a6e22e;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
body .gist .pl-st {
|
||||||
|
color: #66d9ef;
|
||||||
|
}
|
||||||
|
body .gist .pl-mdr {
|
||||||
|
color: #66d9ef;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
body .gist .pl-ms1 {
|
||||||
|
background: #fd971f;
|
||||||
|
}
|
||||||
|
body .gist .pl-c,
|
||||||
|
body .gist .pl-c span,
|
||||||
|
body .gist .pl-pdc {
|
||||||
|
color: #75715e;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
body .gist .pl-cce,
|
||||||
|
body .gist .pl-cn,
|
||||||
|
body .gist .pl-coc,
|
||||||
|
body .gist .pl-enc,
|
||||||
|
body .gist .pl-ens,
|
||||||
|
body .gist .pl-kos,
|
||||||
|
body .gist .pl-kou,
|
||||||
|
body .gist .pl-mh .pl-pdh,
|
||||||
|
body .gist .pl-mp,
|
||||||
|
body .gist .pl-mp1 .pl-sf,
|
||||||
|
body .gist .pl-mq,
|
||||||
|
body .gist .pl-pde,
|
||||||
|
body .gist .pl-pse,
|
||||||
|
body .gist .pl-pse .pl-s2,
|
||||||
|
body .gist .pl-mp .pl-s3,
|
||||||
|
body .gist .pl-smi,
|
||||||
|
body .gist .pl-stp,
|
||||||
|
body .gist .pl-sv,
|
||||||
|
body .gist .pl-v,
|
||||||
|
body .gist .pl-vi,
|
||||||
|
body .gist .pl-vpf,
|
||||||
|
body .gist .pl-mri,
|
||||||
|
body .gist .pl-va,
|
||||||
|
body .gist .pl-vpu {
|
||||||
|
color: #66d9ef;
|
||||||
|
}
|
||||||
|
body .gist .pl-cos,
|
||||||
|
body .gist .pl-ml,
|
||||||
|
body .gist .pl-pds,
|
||||||
|
body .gist .pl-s,
|
||||||
|
body .gist .pl-s1,
|
||||||
|
body .gist .pl-sol {
|
||||||
|
color: #e6db74;
|
||||||
|
}
|
||||||
|
body .gist .pl-e,
|
||||||
|
body .gist .pl-ef,
|
||||||
|
body .gist .pl-en,
|
||||||
|
body .gist .pl-enf,
|
||||||
|
body .gist .pl-enm,
|
||||||
|
body .gist .pl-entc,
|
||||||
|
body .gist .pl-entm,
|
||||||
|
body .gist .pl-eoac,
|
||||||
|
body .gist .pl-eoac .pl-pde,
|
||||||
|
body .gist .pl-eoi,
|
||||||
|
body .gist .pl-mai .pl-sf,
|
||||||
|
body .gist .pl-mm,
|
||||||
|
body .gist .pl-pdv,
|
||||||
|
body .gist .pl-som,
|
||||||
|
body .gist .pl-sr,
|
||||||
|
body .gist .pl-vo {
|
||||||
|
color: #a6e22e;
|
||||||
|
}
|
||||||
|
body .gist .pl-ent,
|
||||||
|
body .gist .pl-eoa,
|
||||||
|
body .gist .pl-eoai,
|
||||||
|
body .gist .pl-eoai .pl-pde,
|
||||||
|
body .gist .pl-k,
|
||||||
|
body .gist .pl-ko,
|
||||||
|
body .gist .pl-kolp,
|
||||||
|
body .gist .pl-mc,
|
||||||
|
body .gist .pl-mr,
|
||||||
|
body .gist .pl-ms,
|
||||||
|
body .gist .pl-s3,
|
||||||
|
body .gist .pl-smc,
|
||||||
|
body .gist .pl-smp,
|
||||||
|
body .gist .pl-sok,
|
||||||
|
body .gist .pl-sra,
|
||||||
|
body .gist .pl-src,
|
||||||
|
body .gist .pl-sre {
|
||||||
|
color: #f92672;
|
||||||
|
}
|
||||||
|
body .gist .pl-mb,
|
||||||
|
body .gist .pl-pdb {
|
||||||
|
color: #e6db74;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
body .gist .pl-mi,
|
||||||
|
body .gist .pl-pdi {
|
||||||
|
color: #f92672;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
body .gist .pl-pdc1,
|
||||||
|
body .gist .pl-scp {
|
||||||
|
color: #ae81ff;
|
||||||
|
}
|
||||||
|
body .gist .pl-sc,
|
||||||
|
body .gist .pl-sf,
|
||||||
|
body .gist .pl-mo,
|
||||||
|
body .gist .pl-entl {
|
||||||
|
color: #fd971f;
|
||||||
|
}
|
||||||
|
body .gist .pl-mi1,
|
||||||
|
body .gist .pl-mdht {
|
||||||
|
color: #a6e22e;
|
||||||
|
background: rgba(0, 64, 0, .5);
|
||||||
|
}
|
||||||
|
body .gist .pl-md,
|
||||||
|
body .gist .pl-mdhf {
|
||||||
|
color: #f92672;
|
||||||
|
background: rgba(64, 0, 0, .5);
|
||||||
|
}
|
||||||
|
body .gist .pl-mdh,
|
||||||
|
body .gist .pl-mdi {
|
||||||
|
color: #a6e22e;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
body .gist .pl-ib,
|
||||||
|
body .gist .pl-id,
|
||||||
|
body .gist .pl-ii,
|
||||||
|
body .gist .pl-iu {
|
||||||
|
background: #a6e22e;
|
||||||
|
color: #272822;
|
||||||
|
}
|
||||||
|
body .gist .gist-meta {
|
||||||
|
display: block;
|
||||||
|
background: #272727;
|
||||||
|
color: cyan;
|
||||||
|
}
|
||||||
|
body .gist .gist-meta a {
|
||||||
|
color: rgb(109, 172, 235);
|
||||||
|
}
|
||||||
|
body .gist .gist-file {
|
||||||
|
border-width: 0px;
|
||||||
|
border-radius: 0px;
|
||||||
|
border-bottom: 0px;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
body .gist .gist-file .gist-data td{
|
||||||
|
padding: 5px;
|
||||||
|
margin: 5px;
|
||||||
|
border: 0px;
|
||||||
|
border-width: 0px;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Astro GhostCMS Content API HTML Processor
|
||||||
|
|
||||||
|
Render remote GhostCMS HTML in Astro with full control over the output.
|
||||||
|
|
||||||
|
Powered by [`ultrahtml`](https://github.com/natemoo-re/ultrahtml).
|
||||||
|
|
||||||
|
## Rendering Remote Content
|
||||||
|
|
||||||
|
The most basic function of `astro-ghostcms-rendercontent` is to convert a string of HTML to Astro friendly HTML. Use the `GhostRender` component.
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { GhostRender } from "@matthiesenxyz/astro-ghostcms-rendercontent";
|
||||||
|
---
|
||||||
|
|
||||||
|
<Markup content={post.html} />
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customization
|
||||||
|
|
||||||
|
`GhostRender` allows full control over the rendering of output. The `components` option allows you to replace a standard HTML element with a custom component.
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { GhostRender } from "@matthiesenxyz/astro-ghostcms-rendercontent";
|
||||||
|
import Title from '../components/Title.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Render <h1> as custom <Title> component -->
|
||||||
|
<GhostRender content={post.html} components={{ h1: Title }} />
|
||||||
|
```
|
||||||
|
|
||||||
|
For examples on how to setup custom components check [examples](./examples/)
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
import { Code } from "astro/components"
|
||||||
|
import { parse } from "node-html-parser"
|
||||||
|
|
||||||
|
const html = await Astro.slots.render("default")
|
||||||
|
const parsed = parse(html)
|
||||||
|
|
||||||
|
const code = parsed.querySelectorAll('code')
|
||||||
|
---
|
||||||
|
{code.map(item => (
|
||||||
|
<Code lang={"js"} code={item.innerHTML} theme={"dracula"}/>
|
||||||
|
))}
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<h1 class="righteous">
|
||||||
|
<slot />
|
||||||
|
</h1>
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<h2 class="righteous">
|
||||||
|
<slot />
|
||||||
|
</h2>
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<h3 class="righteous">
|
||||||
|
<slot />
|
||||||
|
</h3>
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<h4 class="righteous">
|
||||||
|
<slot />
|
||||||
|
</h4>
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<h5 class="righteous">
|
||||||
|
<slot />
|
||||||
|
</h5>
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<h6 class="righteous">
|
||||||
|
<slot />
|
||||||
|
</h6>
|
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
<p class="my-5"><slot /></p>
|
||||||
|
|
||||||
|
<style is:inline>
|
||||||
|
#ghost p a {
|
||||||
|
color: rgb(0, 123, 247);
|
||||||
|
}
|
||||||
|
#ghost ul li a {
|
||||||
|
color: rgb(0, 123, 247);
|
||||||
|
}
|
||||||
|
#ghost ul li {
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
margin-left: 2rem;
|
||||||
|
list-style: circle;
|
||||||
|
}
|
||||||
|
#ghost ul {
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,8 @@
|
||||||
|
export { default as H1 } from "./H1.astro"
|
||||||
|
export { default as H2 } from "./H2.astro"
|
||||||
|
export { default as H3 } from "./H3.astro"
|
||||||
|
export { default as H4 } from "./H4.astro"
|
||||||
|
export { default as H5 } from "./H5.astro"
|
||||||
|
export { default as H6 } from "./H6.astro"
|
||||||
|
export { default as CodeSlot } from "./CodeSlot.astro"
|
||||||
|
export { default as Paragraph } from "./Paragraph.astro"
|
|
@ -0,0 +1 @@
|
||||||
|
export { default as GhostRender } from './lib/GhostRender.astro';
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
import type { SanitizeOptions } from 'ultrahtml/transformers/sanitize'
|
||||||
|
import { createComponentProxy, html } from './utils';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
content?: string;
|
||||||
|
sanitize?: SanitizeOptions;
|
||||||
|
components?: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const input = Astro.props.content ?? await Astro.slots.render('default');
|
||||||
|
if (!input) {
|
||||||
|
throw new Error('Unable to render <GhostRender> without a content prop or children')
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
const components = createComponentProxy($$result, Astro.props.components);
|
||||||
|
const content = await html(input, { sanitize: Astro.props.sanitize, components });
|
||||||
|
---
|
||||||
|
|
||||||
|
<Fragment set:html={content} />
|
|
@ -0,0 +1 @@
|
||||||
|
/// <reference types="astro/client" />
|
|
@ -0,0 +1,61 @@
|
||||||
|
import { transform } from 'ultrahtml';
|
||||||
|
import { jsx as h } from 'astro/jsx-runtime';
|
||||||
|
import { renderJSX } from 'astro/runtime/server/jsx';
|
||||||
|
import { __unsafeHTML } from 'ultrahtml';
|
||||||
|
import * as entities from "entities";
|
||||||
|
import swap from 'ultrahtml/transformers/swap'
|
||||||
|
|
||||||
|
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||||
|
export function createComponentProxy(result, _components: Record<string, any> = {}) {
|
||||||
|
const components = {};
|
||||||
|
for (const [key, value] of Object.entries(_components)) {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
components[key] = value;
|
||||||
|
} else {
|
||||||
|
components[key] = async (props, children) => {
|
||||||
|
if (key === 'CodeBlock' || key === 'CodeSpan') {
|
||||||
|
props.code = entities.decode(JSON.parse(`"${props.code}"`));
|
||||||
|
}
|
||||||
|
const output = await renderJSX(
|
||||||
|
result,
|
||||||
|
h(value, { ...props, 'set:html': children.value })
|
||||||
|
);
|
||||||
|
return __unsafeHTML(output);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return components;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIndent(ln: string): string {
|
||||||
|
if (ln.trim() === ln) return '';
|
||||||
|
return ln.slice(0, ln.length - ln.trim().length);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dedent(str: string): string {
|
||||||
|
const lns = str.replace(/^[\r\n]+/, '').split('\n');
|
||||||
|
let indent = getIndent(lns[0]);
|
||||||
|
if (indent.length === 0 && lns.length > 1) {
|
||||||
|
indent = getIndent(lns[1]);
|
||||||
|
}
|
||||||
|
return lns
|
||||||
|
.map((ln) => (ln.startsWith(indent) ? ln.slice(indent.length) : ln))
|
||||||
|
.map((ln, i, { length }) => (i === length - 1 ? ln.trim() : ln))
|
||||||
|
.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HTMLOptions {
|
||||||
|
// biome-ignore lint/complexity/noBannedTypes: <explanation>
|
||||||
|
sanitize?: {};
|
||||||
|
// biome-ignore lint/complexity/noBannedTypes: <explanation>
|
||||||
|
components?: {};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function html(
|
||||||
|
input: string,
|
||||||
|
opts: HTMLOptions = {}
|
||||||
|
): Promise<string> {
|
||||||
|
return transform(dedent(input), [
|
||||||
|
swap(opts.components),
|
||||||
|
],)
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"name": "@matthiesenxyz/astro-ghostcms-rendercontent",
|
||||||
|
"type": "module",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/MatthiesenXYZ/astro-ghostcms.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/MatthiesenXYZ/astro-ghostcms/issues",
|
||||||
|
"email": "issues@astro-ghostcms.xyz"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
},
|
||||||
|
"sideEffects": false,
|
||||||
|
"homepage": "https://astro-ghostcms.xyz",
|
||||||
|
"files": [
|
||||||
|
"examples",
|
||||||
|
"lib",
|
||||||
|
"index.ts",
|
||||||
|
"CHANGELOG.md"
|
||||||
|
],
|
||||||
|
"types": "./index.ts",
|
||||||
|
"exports": {
|
||||||
|
".": "./index.ts",
|
||||||
|
"./lib/*": "./lib/*",
|
||||||
|
"./package.json": "./package.json"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"astro-ghostcms"
|
||||||
|
],
|
||||||
|
"author": {
|
||||||
|
"email": "adam@matthiesen.xyz",
|
||||||
|
"name": "Adam Matthiesen - MatthiesenXYZ",
|
||||||
|
"url": "https://matthiesen.xyz"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"entities": "^4.5.0",
|
||||||
|
"ultrahtml": "^1.5.2",
|
||||||
|
"node-html-parser": "6.1.12"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"astro": "4.0.0"
|
||||||
|
}
|
||||||
|
}
|
574
pnpm-lock.yaml
574
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue