Skip to content

Commit

Permalink
feat: inline text attributes with []{} syntax (#471)
Browse files Browse the repository at this point in the history
* feat: inline text attributes with `[]{}` syntax

* docs: add text attributes syntax

* Update docs/content/2.writing/2.syntax.md

Co-authored-by: Sébastien Chopin <[email protected]>

* fix: cleanup & typo

Co-authored-by: Sébastien Chopin <[email protected]>
  • Loading branch information
farnabaz and atinux authored Jun 21, 2021
1 parent aba83a5 commit c7cb42b
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 13 deletions.
16 changes: 16 additions & 0 deletions docs/content/2.writing/2.syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,19 @@ Inline components are used to put components in the middle of any Markdown block
:button-link[A button link]{bold}
::
::


## Text Attributes

Text attributes are useful for highlighting and modifying part of paragraph. The syntax is nearly similar to inline components and markdown links syntax.

::code-group

```md [Code]
Hello [World]{.text-primary-500}!
```

::code-block{label="Preview" preview}
Hello [World]{.text-primary-500}!
::
::
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,23 @@ export const Codes = {
/**
* '['
*/
openningSquareBracket: 91,
openingSquareBracket: 91,
/**
* ']'
*/
closingSquareBracket: 93,
/**
* '{'
*/
openningCurlyBracket: 123,
openingCurlyBracket: 123,
/**
* '('
*/
openingParentheses: 40,
/**
* ')'
*/
closingParentheses: 41,
/**
* '_'
*/
Expand Down
13 changes: 10 additions & 3 deletions src/core/parser/markdown/directive/micromark-directive/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
// https://github.com/micromark/micromark-extension-directive/blob/main/lib/syntax.js

import directiveSpan from './tokenize-directive-span'
import directiveInline from './tokenize-directive-inline'
import directiveContainer from './tokenize-directive-container'
import directiveContainerIndented from './tokenize-directive-container-indented'
import { Codes } from './constants'

export default function directive() {
return {
text: { 58: directiveInline },
flow: { 58: [directiveContainer, directiveInline] },
text: {
[Codes.colon]: directiveInline,
[Codes.openingSquareBracket]: [directiveSpan]
},
flow: {
[Codes.colon]: [directiveContainer, directiveInline]
},
flowInitial: {
'-2': directiveContainerIndented,
'-1': directiveContainerIndented,
32: directiveContainerIndented
[Codes.space]: directiveContainerIndented
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,11 @@ function tokenize(effects: Effects, ok: Okay, nok: NotOkay) {
}

function afterName(code: number) {
return code === Codes.openningSquareBracket
? effects.attempt(label, afterLabel, afterLabel)(code)
: afterLabel(code)
return code === Codes.openingSquareBracket ? effects.attempt(label, afterLabel, afterLabel)(code) : afterLabel(code)
}

function afterLabel(code: number) {
return code === Codes.openningCurlyBracket
return code === Codes.openingCurlyBracket
? effects.attempt(attributes, afterAttributes, afterAttributes)(code)
: afterAttributes(code)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ function tokenize(effects: Effects, ok: Okay, nok: NotOkay) {
}

// Check for label
if (code === Codes.openningSquareBracket) {
if (code === Codes.openingSquareBracket) {
return effects.attempt(label, afterLabel, afterLabel)(code)
}

// Check for attributes
if (code === Codes.openningCurlyBracket) {
if (code === Codes.openingCurlyBracket) {
return effects.attempt(attributes, afterAttributes, afterAttributes)(code)
}

Expand All @@ -53,7 +53,7 @@ function tokenize(effects: Effects, ok: Okay, nok: NotOkay) {

function afterAttributes(code: number) {
// Check for label after attributes
if (code === Codes.openningSquareBracket) {
if (code === Codes.openingSquareBracket) {
return effects.attempt(label, afterLabel, afterLabel)(code)
}

Expand All @@ -62,7 +62,7 @@ function tokenize(effects: Effects, ok: Okay, nok: NotOkay) {

function afterLabel(code: number) {
// Check for attributes after label
if (code === Codes.openningCurlyBracket) {
if (code === Codes.openingCurlyBracket) {
return effects.attempt(attributes, exit, exit)(code)
}
return exit(code)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Effects, Okay, NotOkay } from 'micromark/dist/shared-types'
import { Codes } from './constants'
import createAttributes from './factory-attributes'
import createLabel from './factory-label'

const label: any = { tokenize: tokenizeLabel, partial: true }
const attributes: any = { tokenize: tokenizeAttributes, partial: true }

function tokenize(effects: Effects, ok: Okay, nok: NotOkay) {
return start

function start(code: number) {
if (code !== Codes.openingSquareBracket) {
throw new Error('expected `[`')
}

effects.enter('directiveTextSpan')
return effects.attempt(label, afterLabel, nok)(code)
}

function afterLabel(code: number) {
// Check for attributes after label
if (code === Codes.openingCurlyBracket) {
return effects.attempt(attributes, exit, nok)(code)
}
return nok(code)
}

function exit(code: number) {
effects.exit('directiveTextSpan')
return ok(code)
}
}

/**
* Labels starts with `[` and ends with `]`
*/
function tokenizeLabel(effects: Effects, ok: Okay, nok: NotOkay) {
return createLabel(effects, ok, nok, 'directiveTextLabel', 'directiveTextLabelMarker', 'directiveTextLabelString')
}

/**
* Attributes starts with `{` and ends with `}`
*/
function tokenizeAttributes(effects: Effects, ok: Okay, nok: NotOkay) {
return createAttributes(
effects,
ok,
nok,
'directiveTextAttributes',
'directiveTextAttributesMarker',
'directiveTextAttribute',
'directiveTextAttributeId',
'directiveTextAttributeClass',
'directiveTextAttributeName',
'directiveTextAttributeInitializerMarker',
'directiveTextAttributeValueLiteral',
'directiveTextAttributeValue',
'directiveTextAttributeValueMarker',
'directiveTextAttributeValueData'
)
}

export default {
tokenize
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const enter = {
directiveLeafAttributes: enterAttributes,

directiveText: enterText,
directiveTextSpan: enterTextSpan,
directiveTextAttributes: enterAttributes
}
const exit = {
Expand Down Expand Up @@ -44,6 +45,7 @@ const exit = {
directiveLeafName: exitName,

directiveText: exitToken,
directiveTextSpan: exitToken,
directiveTextAttributeClassValue: exitAttributeClassValue,
directiveTextAttributeIdValue: exitAttributeIdValue,
directiveTextAttributeName: exitAttributeName,
Expand Down Expand Up @@ -109,6 +111,10 @@ function enterLeaf(token: Token) {
enterToken.call(this, 'leafDirective', token)
}

function enterTextSpan(token: Token) {
this.enter({ type: 'textDirective', name: 'span', attributes: {}, children: [] }, token)
}

function enterText(token: Token) {
enterToken.call(this, 'textDirective', token)
}
Expand Down

1 comment on commit c7cb42b

@vercel
Copy link

@vercel vercel bot commented on c7cb42b Jun 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.