🎉 initiate project *astro_rewrite*

This commit is contained in:
sindrekjelsrud 2023-07-19 21:31:30 +02:00
parent ffd4d5e86c
commit 2ba37bfbe3
8658 changed files with 2268794 additions and 2538 deletions

View file

@ -0,0 +1,21 @@
/**
* Create an extension for `micromark` to support frontmatter when serializing
* to HTML.
*
* > 👉 **Note**: this makes sure nothing is generated in the output HTML for
* > frontmatter.
*
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {HtmlExtension}
* Extension for `micromark` that can be passed in `htmlExtensions`, to
* support frontmatter when serializing to HTML.
*/
export function frontmatterHtml(
options?: Options | null | undefined
): HtmlExtension
export type CompileContext = import('micromark-util-types').CompileContext
export type Handle = import('micromark-util-types').Handle
export type HtmlExtension = import('micromark-util-types').HtmlExtension
export type TokenType = import('micromark-util-types').TokenType
export type Options = import('../matters.js').Options

View file

@ -0,0 +1,56 @@
/**
* @typedef {import('micromark-util-types').CompileContext} CompileContext
* @typedef {import('micromark-util-types').Handle} Handle
* @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension
* @typedef {import('micromark-util-types').TokenType} TokenType
* @typedef {import('../matters.js').Options} Options
*/
import {matters} from '../matters.js'
/**
* Create an extension for `micromark` to support frontmatter when serializing
* to HTML.
*
* > 👉 **Note**: this makes sure nothing is generated in the output HTML for
* > frontmatter.
*
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {HtmlExtension}
* Extension for `micromark` that can be passed in `htmlExtensions`, to
* support frontmatter when serializing to HTML.
*/
export function frontmatterHtml(options) {
const listOfMatters = matters(options)
/** @type {HtmlExtension['enter']} */
const enter = {}
/** @type {HtmlExtension['exit']} */
const exit = {}
let index = -1
while (++index < listOfMatters.length) {
const type = /** @type {TokenType} */ (listOfMatters[index].type)
enter[type] = start
exit[type] = end
}
return {enter, exit}
/**
* @this {CompileContext}
* @type {Handle}
*/
function start() {
this.buffer()
}
/**
* @this {CompileContext}
* @type {Handle}
*/
function end() {
this.resume()
this.setData('slurpOneLineEnding', true)
}
}

View file

@ -0,0 +1,20 @@
/**
* Create an extension for `micromark` to enable frontmatter syntax.
*
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {Extension}
* Extension for `micromark` that can be passed in `extensions`, to
* enable frontmatter syntax.
*/
export function frontmatter(options?: Options | null | undefined): Extension
export type Construct = import('micromark-util-types').Construct
export type ConstructRecord = import('micromark-util-types').ConstructRecord
export type Extension = import('micromark-util-types').Extension
export type State = import('micromark-util-types').State
export type TokenType = import('micromark-util-types').TokenType
export type TokenizeContext = import('micromark-util-types').TokenizeContext
export type Tokenizer = import('micromark-util-types').Tokenizer
export type Info = import('../matters.js').Info
export type Matter = import('../matters.js').Matter
export type Options = import('../matters.js').Options

View file

@ -0,0 +1,411 @@
/**
* @typedef {import('micromark-util-types').Construct} Construct
* @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord
* @typedef {import('micromark-util-types').Extension} Extension
* @typedef {import('micromark-util-types').State} State
* @typedef {import('micromark-util-types').TokenType} TokenType
* @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext
* @typedef {import('micromark-util-types').Tokenizer} Tokenizer
*
* @typedef {import('../matters.js').Info} Info
* @typedef {import('../matters.js').Matter} Matter
* @typedef {import('../matters.js').Options} Options
*/
import {markdownLineEnding, markdownSpace} from 'micromark-util-character'
import {codes} from 'micromark-util-symbol/codes.js'
import {types} from 'micromark-util-symbol/types.js'
import {matters} from '../matters.js'
/**
* Create an extension for `micromark` to enable frontmatter syntax.
*
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {Extension}
* Extension for `micromark` that can be passed in `extensions`, to
* enable frontmatter syntax.
*/
export function frontmatter(options) {
const listOfMatters = matters(options)
/** @type {ConstructRecord} */
const flow = {}
let index = -1
while (++index < listOfMatters.length) {
const matter = listOfMatters[index]
const code = fence(matter, 'open').charCodeAt(0)
const construct = createConstruct(matter)
const existing = flow[code]
if (Array.isArray(existing)) {
existing.push(construct)
} else {
// Never a single object, always an array.
flow[code] = [construct]
}
}
return {flow}
}
/**
* @param {Matter} matter
* @returns {Construct}
*/
function createConstruct(matter) {
const anywhere = matter.anywhere
const frontmatterType = /** @type {TokenType} */ (matter.type)
const fenceType = /** @type {TokenType} */ (frontmatterType + 'Fence')
const sequenceType = /** @type {TokenType} */ (fenceType + 'Sequence')
const valueType = /** @type {TokenType} */ (frontmatterType + 'Value')
const closingFenceConstruct = {tokenize: tokenizeClosingFence, partial: true}
/**
* Fence to look for.
*
* @type {string}
*/
let buffer
let bufferIndex = 0
return {tokenize: tokenizeFrontmatter, concrete: true}
/**
* @this {TokenizeContext}
* @type {Tokenizer}
*/
function tokenizeFrontmatter(effects, ok, nok) {
const self = this
return start
/**
* Start of frontmatter.
*
* ```markdown
* > | ---
* ^
* | title: "Venus"
* | ---
* ```
*
* @type {State}
*/
function start(code) {
const position = self.now()
if (
// Indent not allowed.
position.column === 1 &&
// Normally, only allowed in first line.
(position.line === 1 || anywhere)
) {
buffer = fence(matter, 'open')
bufferIndex = 0
if (code === buffer.charCodeAt(bufferIndex)) {
effects.enter(frontmatterType)
effects.enter(fenceType)
effects.enter(sequenceType)
return openSequence(code)
}
}
return nok(code)
}
/**
* In open sequence.
*
* ```markdown
* > | ---
* ^
* | title: "Venus"
* | ---
* ```
*
* @type {State}
*/
function openSequence(code) {
if (bufferIndex === buffer.length) {
effects.exit(sequenceType)
if (markdownSpace(code)) {
effects.enter(types.whitespace)
return openSequenceWhitespace(code)
}
return openAfter(code)
}
if (code === buffer.charCodeAt(bufferIndex++)) {
effects.consume(code)
return openSequence
}
return nok(code)
}
/**
* In whitespace after open sequence.
*
* ```markdown
* > | ---
* ^
* | title: "Venus"
* | ---
* ```
*
* @type {State}
*/
function openSequenceWhitespace(code) {
if (markdownSpace(code)) {
effects.consume(code)
return openSequenceWhitespace
}
effects.exit(types.whitespace)
return openAfter(code)
}
/**
* After open sequence.
*
* ```markdown
* > | ---
* ^
* | title: "Venus"
* | ---
* ```
*
* @type {State}
*/
function openAfter(code) {
if (markdownLineEnding(code)) {
effects.exit(fenceType)
effects.enter(types.lineEnding)
effects.consume(code)
effects.exit(types.lineEnding)
// Get ready for closing fence.
buffer = fence(matter, 'close')
bufferIndex = 0
return effects.attempt(closingFenceConstruct, after, contentStart)
}
// EOF is not okay.
return nok(code)
}
/**
* Start of content chunk.
*
* ```markdown
* | ---
* > | title: "Venus"
* ^
* | ---
* ```
*
* @type {State}
*/
function contentStart(code) {
if (code === codes.eof || markdownLineEnding(code)) {
return contentEnd(code)
}
effects.enter(valueType)
return contentInside(code)
}
/**
* In content chunk.
*
* ```markdown
* | ---
* > | title: "Venus"
* ^
* | ---
* ```
*
* @type {State}
*/
function contentInside(code) {
if (code === codes.eof || markdownLineEnding(code)) {
effects.exit(valueType)
return contentEnd(code)
}
effects.consume(code)
return contentInside
}
/**
* End of content chunk.
*
* ```markdown
* | ---
* > | title: "Venus"
* ^
* | ---
* ```
*
* @type {State}
*/
function contentEnd(code) {
// Require a closing fence.
if (code === codes.eof) {
return nok(code)
}
// Can only be an eol.
effects.enter(types.lineEnding)
effects.consume(code)
effects.exit(types.lineEnding)
return effects.attempt(closingFenceConstruct, after, contentStart)
}
/**
* After frontmatter.
*
* ```markdown
* | ---
* | title: "Venus"
* > | ---
* ^
* ```
*
* @type {State}
*/
function after(code) {
// `code` must be eol/eof.
effects.exit(frontmatterType)
return ok(code)
}
}
/** @type {Tokenizer} */
function tokenizeClosingFence(effects, ok, nok) {
let bufferIndex = 0
return closeStart
/**
* Start of close sequence.
*
* ```markdown
* | ---
* | title: "Venus"
* > | ---
* ^
* ```
*
* @type {State}
*/
function closeStart(code) {
if (code === buffer.charCodeAt(bufferIndex)) {
effects.enter(fenceType)
effects.enter(sequenceType)
return closeSequence(code)
}
return nok(code)
}
/**
* In close sequence.
*
* ```markdown
* | ---
* | title: "Venus"
* > | ---
* ^
* ```
*
* @type {State}
*/
function closeSequence(code) {
if (bufferIndex === buffer.length) {
effects.exit(sequenceType)
if (markdownSpace(code)) {
effects.enter(types.whitespace)
return closeSequenceWhitespace(code)
}
return closeAfter(code)
}
if (code === buffer.charCodeAt(bufferIndex++)) {
effects.consume(code)
return closeSequence
}
return nok(code)
}
/**
* In whitespace after close sequence.
*
* ```markdown
* > | ---
* | title: "Venus"
* | ---
* ^
* ```
*
* @type {State}
*/
function closeSequenceWhitespace(code) {
if (markdownSpace(code)) {
effects.consume(code)
return closeSequenceWhitespace
}
effects.exit(types.whitespace)
return closeAfter(code)
}
/**
* After close sequence.
*
* ```markdown
* | ---
* | title: "Venus"
* > | ---
* ^
* ```
*
* @type {State}
*/
function closeAfter(code) {
if (code === codes.eof || markdownLineEnding(code)) {
effects.exit(fenceType)
return ok(code)
}
return nok(code)
}
}
}
/**
* @param {Matter} matter
* @param {'open' | 'close'} prop
* @returns {string}
*/
function fence(matter, prop) {
return matter.marker
? pick(matter.marker, prop).repeat(3)
: // @ts-expect-error: Theyre mutually exclusive.
pick(matter.fence, prop)
}
/**
* @param {Info | string} schema
* @param {'open' | 'close'} prop
* @returns {string}
*/
function pick(schema, prop) {
return typeof schema === 'string' ? schema : schema[prop]
}