Skip to content

Commit

Permalink
fix: handle attributes in nested components
Browse files Browse the repository at this point in the history
  • Loading branch information
farnabaz committed Mar 21, 2024
1 parent c7fa71b commit 0f71503
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 43 deletions.
12 changes: 4 additions & 8 deletions src/from-markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,15 +258,11 @@ export default (opts: RemarkMDCOptions = {}) => {
this.resume() // Drop EOLs

let stackTop = this.stack[this.stack.length - 1]
if (stackTop.type === 'paragraph') {
// select last inline component
stackTop = stackTop.children[stackTop.children.length - 1]
}

// Add attributes to last child of fragment
// Example: `[![Nuxt](https://nuxtjs.org/design-kit/colored-logo.svg){.nest}](https://nuxtjs.org)`
if (stackTop.type === 'fragment') {
stackTop = stackTop.children[stackTop.children.length - 1]
if (stackTop.type !== 'textComponent' || stackTop.name === 'span') {
while (!stackTop.position?.end && stackTop.children?.length > 0) {
stackTop = stackTop.children[stackTop.children.length - 1]
}
}

(stackTop as any).attributes = cleaned
Expand Down
30 changes: 30 additions & 0 deletions src/mdast-util-to-markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,36 @@ function track (options_) {
}
}

export function inlineContainerFlow (parent, context, safeOptions = {}) {
const indexStack = context.indexStack
const children = parent.children || []
const tracker = track(safeOptions)
/** @type {Array<string>} */
const results = []
let index = -1

indexStack.push(-1)

while (++index < children.length) {
const child = children[index]

indexStack[indexStack.length - 1] = index

results.push(
tracker.move(
context.handle(child, parent, context, {
before: '',
after: '',
...tracker.current()
})
)
)
}

indexStack.pop()

return results.join('')
}
// import { containerFlow } from 'mdast-util-to-markdown/lib/util/container-flow.js'
/**
* @param {Parent} parent
Expand Down
26 changes: 0 additions & 26 deletions src/micromark-extension/tokenize-span.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ import { markdownSpace } from 'micromark-util-character'
import type { Effects, State, Code, TokenizeContext } from 'micromark-util-types'
import { Codes } from './constants'
import createLabel from './factory-label'
import createAttributes from './factory-attributes'

const label: any = { tokenize: tokenizeLabel, partial: true }
const gfmCheck: any = { tokenize: checkGfmTaskCheckbox, partial: true }
const doubleBracketCheck: any = { tokenize: checkDoubleBracket, partial: true }
const attributes: any = { tokenize: tokenizeAttributes, partial: true }

function tokenize (this: TokenizeContext, effects: Effects, ok: State, nok: State) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
Expand Down Expand Up @@ -46,10 +44,6 @@ function tokenize (this: TokenizeContext, effects: Effects, ok: State, nok: Stat
if (code === Codes.openingParentheses || code === Codes.openingSquareBracket) {
return nok(code)
}
// Attempt parsing attributes
if (code === Codes.openingCurlyBracket) {
return effects.attempt(attributes, exitOK, exitOK)(code)
}

return exitOK(code)
}
Expand Down Expand Up @@ -117,23 +111,3 @@ function checkDoubleBracket (effects: Effects, ok: State, nok: State) {
return ok(code)
}
}

function tokenizeAttributes (effects: Effects, ok: State, nok: State) {
// Always a `{`
return createAttributes(
effects,
ok,
nok,
'componentTextAttributes',
'componentTextAttributesMarker',
'componentTextAttribute',
'componentTextAttributeId',
'componentTextAttributeClass',
'componentTextAttributeName',
'componentTextAttributeInitializerMarker',
'componentTextAttributeValueLiteral',
'componentTextAttributeValue',
'componentTextAttributeValueMarker',
'componentTextAttributeValueData'
)
}
14 changes: 7 additions & 7 deletions src/to-markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* License: MIT (https://github.com/syntax-tree/mdast-util-directive/blob/main/license)
*/
import { stringifyEntitiesLight } from 'stringify-entities'
import type { Parents } from 'mdast-util-to-markdown/lib/types'
import type { Parents } from 'mdast'
import { type State, type Info, type Unsafe, defaultHandlers } from 'mdast-util-to-markdown'
import { containerFlow, containerPhrasing, checkQuote } from './mdast-util-to-markdown'
import { containerFlow, containerPhrasing, checkQuote, inlineContainerFlow } from './mdast-util-to-markdown'
import { stringifyFrontMatter } from './frontmatter'
import type { RemarkMDCOptions } from './types'
import { NON_UNWRAPPABLE_TYPES } from './utils'
Expand Down Expand Up @@ -45,9 +45,9 @@ export default (opts: RemarkMDCOptions = {}) => {
node.children = [
{
type: node.mdc.unwrapped as any,
children: node.children.filter(child => !NON_UNWRAPPABLE_TYPES.includes(child.type))
children: node.children.filter((child: Parents) => !NON_UNWRAPPABLE_TYPES.includes(child.type))
},
...node.children.filter(child => NON_UNWRAPPABLE_TYPES.includes(child.type))
...node.children.filter((child: Parents) => NON_UNWRAPPABLE_TYPES.includes(child.type))
]
}
}
Expand Down Expand Up @@ -95,9 +95,9 @@ export default (opts: RemarkMDCOptions = {}) => {
let value = prefix + (node.name || '') + label(node, context)

const attributesText = attributes(node, context)
const fmAttributes = node.fmAttributes || {}
const fmAttributes: Record<string, string> = node.fmAttributes || {}

if ((value + attributesText).length > 80 || Object.keys(fmAttributes).length > 0 || node.children?.some(child => child.type === 'componentContainerSection')) {
if ((value + attributesText).length > 80 || Object.keys(fmAttributes).length > 0 || node.children?.some((child: Parents) => child.type === 'componentContainerSection')) {
Object.assign(fmAttributes, (node as any).attributes)
} else {
value += attributesText
Expand Down Expand Up @@ -234,7 +234,7 @@ export default (opts: RemarkMDCOptions = {}) => {

function content (node: any, context: State) {
const content = inlineComponentLabel(node) ? Object.assign({}, node, { children: node.children.slice(1) }) : node
return containerFlow(content, context)
return node.type === 'textComponent' ? inlineContainerFlow(content, context) : containerFlow(content, context)
}

function inlineComponentLabel (node: any) {
Expand Down
238 changes: 238 additions & 0 deletions test/__snapshots__/attributes.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,244 @@ exports[`Attributes > link 1`] = `
}
`;

exports[`Attributes > nested 1`] = `
{
"children": [
{
"children": [
{
"attributes": {
"style": "color: green",
},
"children": [
{
"position": {
"end": {
"column": 8,
"line": 1,
"offset": 7,
},
"start": {
"column": 2,
"line": 1,
"offset": 1,
},
},
"type": "text",
"value": "Hello ",
},
{
"attributes": {
"class": "x",
},
"children": [
{
"position": {
"end": {
"column": 14,
"line": 1,
"offset": 13,
},
"start": {
"column": 9,
"line": 1,
"offset": 8,
},
},
"type": "text",
"value": "World",
},
],
"data": {
"hName": "span",
"hProperties": {
"class": "x",
},
},
"fmAttributes": {},
"name": "span",
"position": {
"end": {
"column": 15,
"line": 1,
"offset": 14,
},
"start": {
"column": 8,
"line": 1,
"offset": 7,
},
},
"type": "textComponent",
},
],
"position": {
"end": {
"column": 28,
"line": 1,
"offset": 27,
},
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
"title": null,
"type": "link",
"url": "/world",
},
],
"position": {
"end": {
"column": 50,
"line": 1,
"offset": 49,
},
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
"type": "paragraph",
},
],
"position": {
"end": {
"column": 50,
"line": 1,
"offset": 49,
},
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
"type": "root",
}
`;

exports[`Attributes > nested2 1`] = `
{
"children": [
{
"children": [
{
"attributes": {
"style": "color: green",
},
"children": [
{
"position": {
"end": {
"column": 8,
"line": 1,
"offset": 7,
},
"start": {
"column": 2,
"line": 1,
"offset": 1,
},
},
"type": "text",
"value": "Hello ",
},
{
"attributes": {
"class": "x",
},
"children": [
{
"position": {
"end": {
"column": 14,
"line": 1,
"offset": 13,
},
"start": {
"column": 9,
"line": 1,
"offset": 8,
},
},
"type": "text",
"value": "World",
},
],
"position": {
"end": {
"column": 23,
"line": 1,
"offset": 22,
},
"start": {
"column": 8,
"line": 1,
"offset": 7,
},
},
"title": null,
"type": "link",
"url": "/world",
},
],
"data": {
"hName": "span",
"hProperties": {
"style": "color: green",
},
},
"fmAttributes": {},
"name": "span",
"position": {
"end": {
"column": 28,
"line": 1,
"offset": 27,
},
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
"type": "textComponent",
},
],
"position": {
"end": {
"column": 50,
"line": 1,
"offset": 49,
},
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
"type": "paragraph",
},
],
"position": {
"end": {
"column": 50,
"line": 1,
"offset": 49,
},
"start": {
"column": 1,
"line": 1,
"offset": 0,
},
},
"type": "root",
}
`;

exports[`Attributes > strong 1`] = `
{
"children": [
Expand Down
Loading

0 comments on commit 0f71503

Please sign in to comment.