docs: remove some h4s from the table of contents

pull/5679/head
Geoff Rich 5 years ago
parent 67587f3506
commit 8e3b6e4992

@ -24,7 +24,7 @@ All three sections — script, styles and markup — are optional.
A `<script>` block contains JavaScript that runs when a component instance is created. Variables declared (or imported) at the top level are 'visible' from the component's markup. There are four additional rules: A `<script>` block contains JavaScript that runs when a component instance is created. Variables declared (or imported) at the top level are 'visible' from the component's markup. There are four additional rules:
#### 1. `export` creates a component prop #### 1. `export` creates a component prop { data-toc-ignore }
--- ---
@ -85,7 +85,7 @@ You can use reserved words as prop names.
</script> </script>
``` ```
#### 2. Assignments are 'reactive' #### 2. Assignments are 'reactive' { data-toc-ignore }
--- ---
@ -107,7 +107,7 @@ Because Svelte's reactivity is based on assignments, using array methods like `.
</script> </script>
``` ```
#### 3. `$:` marks a statement as reactive #### 3. `$:` marks a statement as reactive { data-toc-ignore }
--- ---
@ -143,7 +143,7 @@ If a statement consists entirely of an assignment to an undeclared variable, Sve
</script> </script>
``` ```
#### 4. Prefix stores with `$` to access their values #### 4. Prefix stores with `$` to access their values { data-toc-ignore }
--- ---
@ -172,7 +172,7 @@ Local variables (that do not represent store values) must *not* have a `$` prefi
</script> </script>
``` ```
#### Store contract #### Store contract { data-toc-ignore }
```js ```js
store = { subscribe: (subscription: (value: any) => void) => (() => void), set?: (value: any) => void } store = { subscribe: (subscription: (value: any) => void) => (() => void), set?: (value: any) => void }

@ -3,6 +3,7 @@ import path from 'path';
import { SLUG_PRESERVE_UNICODE, SLUG_SEPARATOR } from '../../../config'; import { SLUG_PRESERVE_UNICODE, SLUG_SEPARATOR } from '../../../config';
import { extract_frontmatter, extract_metadata, link_renderer } from '@sveltejs/site-kit/utils/markdown.js'; import { extract_frontmatter, extract_metadata, link_renderer } from '@sveltejs/site-kit/utils/markdown.js';
import { make_session_slug_processor } from '@sveltejs/site-kit/utils/slug'; import { make_session_slug_processor } from '@sveltejs/site-kit/utils/slug';
import { extract_attributes } from '../../utils/attributes';
import { highlight } from '../../utils/highlight'; import { highlight } from '../../utils/highlight';
import marked from 'marked'; import marked from 'marked';
@ -85,6 +86,10 @@ export default function() {
renderer.heading = (text, level, rawtext) => { renderer.heading = (text, level, rawtext) => {
let slug; let slug;
let extracted = extract_attributes(text, rawtext);
text = extracted.text;
rawtext = extracted.raw;
const match = /<a href="([^"]+)"[^>]*>(.+)<\/a>/.exec(text); const match = /<a href="([^"]+)"[^>]*>(.+)<\/a>/.exec(text);
if (match) { if (match) {
slug = match[1]; slug = match[1];
@ -93,7 +98,8 @@ export default function() {
slug = make_slug(rawtext); slug = make_slug(rawtext);
} }
if (level === 3 || level === 4) { const tocIgnore = 'data-toc-ignore' in extracted.attrs;
if ((level === 3 || level === 4) && !tocIgnore) {
const title = text const title = text
.replace(/<\/?code>/g, '') .replace(/<\/?code>/g, '')
.replace(/\.(\w+)(\((.+)?\))?/, (m, $1, $2, $3) => { .replace(/\.(\w+)(\((.+)?\))?/, (m, $1, $2, $3) => {
@ -106,8 +112,8 @@ export default function() {
} }
return ` return `
<h${level}> <h${level} ${extracted.attrstring}>
<span id="${slug}" class="offset-anchor" ${level > 4 ? 'data-scrollignore' : ''}></span> <span id="${slug}" class="offset-anchor" ${level > 4 || tocIgnore ? 'data-scrollignore' : ''}></span>
<a href="docs#${slug}" class="anchor" aria-hidden="true"></a> <a href="docs#${slug}" class="anchor" aria-hidden="true"></a>
${text} ${text}
</h${level}>`; </h${level}>`;

@ -0,0 +1,61 @@
const ATTRS_REGEX = /^(.+)\s+\{(.+)\}$/;
/**
* Extracts attributes from markdown text to be applied to the resulting HTML.
* @example
* // returns {
* // text: 'Heading',
* // raw: '<code>Heading</code>',
* // attrs: { id: 'important', class: 'red', test: 'true' },
* // attrstring: 'id="important" class="red" test="true"'
* // }
* extract_attributes(
* 'Heading { #important .red test=true }',
* '<code>Heading</code> { #important .red test=true }'
* );
* ```
* @param {string} text
* @param {string} raw
*/
export function extract_attributes(text, raw) {
try {
const textMatch = text.match(ATTRS_REGEX);
const rawMatch = raw && raw.match(ATTRS_REGEX);
const attrs = textMatch ? parse_attributes(textMatch[2]) : {};
return {
text: textMatch ? textMatch[1] : text,
raw: rawMatch ? rawMatch[1] : raw,
attrs,
attrstring: Object.keys(attrs).map(key => `${key}="${attrs[key].trim()}"`).join(' ')
}
} catch (err) {
console.log(err);
return {
text,
raw,
attrs: {},
attrstring: ''
};
}
}
function parse_attributes(raw_attributes) {
const attributes = raw_attributes.split(' ');
const result = { };
attributes.forEach(attr => {
if (!attr) return;
if (attr.startsWith('#')) {
result.id = attr.substring(1);
} else if (attr.startsWith('.')) {
if (!result.class) {
result.class = '';
}
result.class += attr.substring(1) + ' ';
} else {
let [key, value = ''] = attr.split('=');
result[key] = value;
}
})
return result;
}
Loading…
Cancel
Save