Rename Markdown util getHeaders() to getHeadings() (#4031)

* Renamed getHeaders() to getHeadings(), according to RFC #208.

* chore: update changeset

* fix: expose MarkdownHeading type from `astro`

Co-authored-by: Félix Sanz <me@felixsanz.com>
Co-authored-by: Nate Moore <nate@astro.build>
This commit is contained in:
Nate Moore 2022-07-23 17:23:15 -05:00 committed by GitHub
parent 1215e731b8
commit 6e27a5fdc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 64 additions and 42 deletions

View file

@ -0,0 +1,6 @@
---
'astro': patch
'@astrojs/markdown-remark': minor
---
**BREAKING** Renamed Markdown utility function `getHeaders()` to `getHeadings()`.

View file

@ -4,14 +4,14 @@ import TableOfContents from "../RightSidebar/TableOfContents.tsx";
const { content, githubEditUrl } = Astro.props;
const title = content.title;
const headers = content.astro.headers;
const headings = content.astro.headings;
---
<article id="article" class="content">
<section class="main-section">
<h1 class="content-title" id="overview">{title}</h1>
<nav class="block sm:hidden">
<TableOfContents client:media="(max-width: 50em)" {headers} />
<TableOfContents client:media="(max-width: 50em)" {headings} />
</nav>
<slot />
</section>

View file

@ -8,7 +8,7 @@ const showMoreSection = CONFIG.COMMUNITY_INVITE_URL || editHref;
{showMoreSection && <h2 class="heading">More</h2>}
<ul>
{editHref && (
<li class={`header-link depth-2`}>
<li class={`heading-link depth-2`}>
<a class="edit-on-github" href={editHref} target="_blank">
<svg
aria-hidden="true"
@ -32,7 +32,7 @@ const showMoreSection = CONFIG.COMMUNITY_INVITE_URL || editHref;
</li>
)}
{CONFIG.COMMUNITY_INVITE_URL && (
<li class={`header-link depth-2`}>
<li class={`heading-link depth-2`}>
<a href={CONFIG.COMMUNITY_INVITE_URL} target="_blank">
<svg
aria-hidden="true"

View file

@ -2,12 +2,12 @@
import TableOfContents from "./TableOfContents.tsx";
import MoreMenu from "./MoreMenu.astro";
const { content, githubEditUrl } = Astro.props;
const headers = content.astro.headers;
const headings = content.astro.headings;
---
<nav class="sidebar-nav" aria-labelledby="grid-right">
<div class="sidebar-nav-inner">
<TableOfContents client:media="(min-width: 50em)" {headers} />
<TableOfContents client:media="(min-width: 50em)" {headings} />
<MoreMenu editHref={githubEditUrl} />
</div>
</nav>

View file

@ -1,11 +1,11 @@
import type { FunctionalComponent } from 'preact';
import { h, Fragment } from 'preact';
import { useState, useEffect, useRef } from 'preact/hooks';
import { MarkdownHeading } from 'astro';
const TableOfContents: FunctionalComponent<{ headers: any[] }> = ({ headers = [] }) => {
const TableOfContents: FunctionalComponent<{ headings: MarkdownHeading[] }> = ({ headings = [] }) => {
const itemOffsets = useRef([]);
const [activeId, setActiveId] = useState<string>(undefined);
useEffect(() => {
const getItemOffsets = () => {
const titles = document.querySelectorAll('article :is(h1, h2, h3, h4)');
@ -27,18 +27,18 @@ const TableOfContents: FunctionalComponent<{ headers: any[] }> = ({ headers = []
<>
<h2 class="heading">On this page</h2>
<ul>
<li class={`header-link depth-2 ${activeId === 'overview' ? 'active' : ''}`.trim()}>
<li class={`heading-link depth-2 ${activeId === 'overview' ? 'active' : ''}`.trim()}>
<a href="#overview">Overview</a>
</li>
{headers
{headings
.filter(({ depth }) => depth > 1 && depth < 4)
.map((header) => (
.map((heading) => (
<li
class={`header-link depth-${header.depth} ${
activeId === header.slug ? 'active' : ''
class={`heading-link depth-${heading.depth} ${
activeId === heading.slug ? 'active' : ''
}`.trim()}
>
<a href={`#${header.slug}`}>{header.text}</a>
<a href={`#${heading.slug}`}>{heading.text}</a>
</li>
))}
</ul>

View file

@ -311,42 +311,42 @@ h2.heading {
margin-bottom: 0.5rem;
}
.header-link {
.heading-link {
font-size: 1rem;
padding: 0.1rem 0 0.1rem 1rem;
border-left: 4px solid var(--theme-divider);
}
.header-link:hover,
.header-link:focus {
.heading-link:hover,
.heading-link:focus {
border-left-color: var(--theme-accent);
color: var(--theme-accent);
}
.header-link:focus-within {
.heading-link:focus-within {
color: var(--theme-text-light);
border-left-color: hsla(var(--color-gray-40), 1);
}
.header-link svg {
.heading-link svg {
opacity: 0.6;
}
.header-link:hover svg {
.heading-link:hover svg {
opacity: 0.8;
}
.header-link a {
.heading-link a {
display: inline-flex;
gap: 0.5em;
width: 100%;
padding: 0.15em 0 0.15em 0;
}
.header-link.depth-3 {
.heading-link.depth-3 {
padding-left: 2rem;
}
.header-link.depth-4 {
.heading-link.depth-4 {
padding-left: 3rem;
}
.header-link a {
.heading-link a {
font: inherit;
color: inherit;
text-decoration: none;

View file

@ -18,7 +18,9 @@ declare module '*.md' {
export const frontmatter: MD['frontmatter'];
export const file: MD['file'];
export const url: MD['url'];
export const getHeaders: MD['getHeaders'];
export const getHeadings: MD['getHeadings'];
/** @deprecated Renamed to `getHeadings()` */
export const getHeaders: () => void;
export const Content: MD['Content'];
export const rawContent: MD['rawContent'];
export const compiledContent: MD['compiledContent'];

View file

@ -1,5 +1,5 @@
import type {
MarkdownHeader,
MarkdownHeading,
MarkdownMetadata,
MarkdownRenderingResult,
RehypePlugins,
@ -16,6 +16,14 @@ import type { AstroConfigSchema } from '../core/config';
import type { ViteConfigWithSSR } from '../core/create-vite';
import type { AstroComponentFactory, Metadata } from '../runtime/server';
export type { SSRManifest } from '../core/app/types';
export type {
MarkdownHeading,
MarkdownMetadata,
MarkdownRenderingResult,
RehypePlugins,
RemarkPlugins,
ShikiConfig,
} from '@astrojs/markdown-remark';
export interface AstroBuiltinProps {
'client:load'?: boolean;
@ -783,7 +791,9 @@ export interface MarkdownInstance<T extends Record<string, any>> {
rawContent(): string;
/** Markdown file compiled to valid Astro syntax. Queryable with most HTML parsing libraries */
compiledContent(): Promise<string>;
getHeaders(): Promise<MarkdownHeader[]>;
getHeadings(): Promise<MarkdownHeading[]>;
/** @deprecated Renamed to `getHeadings()` */
getHeaders(): void;
default: () => Promise<{
metadata: MarkdownMetadata;
frontmatter: MarkdownContent<T>;

View file

@ -123,8 +123,12 @@ export default function markdown({ config }: AstroPluginOptions): Plugin {
return load().then((m) => m.default(...args));
}
Content.isAstroComponentFactory = true;
export function getHeadings() {
return load().then((m) => m.metadata.headings);
}
export function getHeaders() {
return load().then((m) => m.metadata.headers);
console.warn('getHeaders() have been deprecated. Use getHeadings() function instead.');
return load().then((m) => m.metadata.headings);
};`,
map: null,
};

View file

@ -1,7 +1,7 @@
import type { MarkdownRenderingOptions, MarkdownRenderingResult } from './types';
import { loadPlugins } from './load-plugins.js';
import createCollectHeaders from './rehype-collect-headers.js';
import createCollectHeadings from './rehype-collect-headings.js';
import rehypeEscape from './rehype-escape.js';
import rehypeExpressions from './rehype-expressions.js';
import rehypeIslands from './rehype-islands.js';
@ -41,7 +41,7 @@ export async function renderMarkdown(
} = opts;
const input = new VFile({ value: content, path: fileURL });
const scopedClassName = opts.$?.scopedClassName;
const { headers, rehypeCollectHeaders } = createCollectHeaders();
const { headings, rehypeCollectHeadings } = createCollectHeadings();
let parser = unified()
.use(markdown)
@ -94,8 +94,8 @@ export async function renderMarkdown(
parser
.use(
isAstroFlavoredMd
? [rehypeJsx, rehypeExpressions, rehypeEscape, rehypeIslands, rehypeCollectHeaders]
: [rehypeCollectHeaders, rehypeRaw]
? [rehypeJsx, rehypeExpressions, rehypeEscape, rehypeIslands, rehypeCollectHeadings]
: [rehypeCollectHeadings, rehypeRaw]
)
.use(rehypeStringify, { allowDangerousHtml: true });
@ -113,7 +113,7 @@ export async function renderMarkdown(
}
return {
metadata: { headers, source: content, html: result.toString() },
metadata: { headings, source: content, html: result.toString() },
code: result.toString(),
};
}

View file

@ -2,13 +2,13 @@ import Slugger from 'github-slugger';
import { toHtml } from 'hast-util-to-html';
import { visit } from 'unist-util-visit';
import type { MarkdownHeader, RehypePlugin } from './types.js';
import type { MarkdownHeading, RehypePlugin } from './types.js';
export default function createCollectHeaders() {
const headers: MarkdownHeader[] = [];
export default function createCollectHeadings() {
const headings: MarkdownHeading[] = [];
const slugger = new Slugger();
function rehypeCollectHeaders(): ReturnType<RehypePlugin> {
function rehypeCollectHeadings(): ReturnType<RehypePlugin> {
return function (tree) {
visit(tree, (node) => {
if (node.type !== 'element') return;
@ -61,13 +61,13 @@ export default function createCollectHeaders() {
}
}
headers.push({ depth, slug: node.properties.id, text });
headings.push({ depth, slug: node.properties.id, text });
});
};
}
return {
headers,
rehypeCollectHeaders,
headings,
rehypeCollectHeadings,
};
}

View file

@ -44,14 +44,14 @@ export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
isAstroFlavoredMd?: boolean;
}
export interface MarkdownHeader {
export interface MarkdownHeading {
depth: number;
slug: string;
text: string;
}
export interface MarkdownMetadata {
headers: MarkdownHeader[];
headings: MarkdownHeading[];
source: string;
html: string;
}