Syntax highlighting YAML blocks within Pandoc Markdown files

I’m trying to write a syntax for Pandoc Markdown files. My articles in Pandoc Markdown always contain YAML blocks fenced by a pair of triple hyphens ---. Sublime Text syntax-highlights YAML keys and list hyphens nicely within the metadata block.

In the Drafts syntax file though, I haven’t been able to figure out a regex to match YAML keys and list hyphens only within metadata blocks. What I’m looking for is a regex like:

((\w+)(: )(.*))|((\w+)(:)(\s\- )(.*))

But what this regex does is to match any instance of key: value or key: \n- value anywhere in the document. I want it only to match instances within the YAML header. Is this even possible?

1 Like

A bit tricky, but possible. I would create a rule that matches the key: value, but also looks ahead to only only match if there is a --- out ahead of it.

These example example patterns:

[
  {
    "match": "(?s)(\\w+: )([^\\n]+)(?=.*^---)",
    "exclusive": false,
    "comment": "key: value pairs in front matter",
    "captures": {
      "1": {
        "scope": "color.red"
      },
      "2": {
        "scope": "color.green"
      }
    }
  },
  {
    "match": "(?s)(\\w+:\\n)(- )([^\\n]+)(?=.*^---)",
    "exclusive": false,
    "comment": "key: value pairs in front matter",
    "captures": {
      "1": {
        "scope": "color.red"
      },
      "2": {
        "scope": "markup"
      },
      "3": {
        "scope": "color.green"
      }
    }
  }
]

Create results like:

CleanShot 2022-03-18 at 09.40.37@2x

1 Like

Please share this when you have it. YAML metadata blocks are also supported in GitLab-flavored Markdown and Multimarkdown. I regularly include metadata and it would be very useful to have it highlighted.

1 Like

Thanks for this idea! When I plugged the first regex into https://regex101.com/, it threw a “catastrophic backtracking error” at me, so I made one of the quantifiers possessive. Specifically, I had to make

(?s)(\\w+: )([^\\n]+)(?=.*^---)
into
(?s)(\\w+: )([^\\n]++)(?=.*^---)

for it to work. That seemed to do the trick. Except that I then noticed that if I manipulated the string and then re-formed it, the syntax highlighting got messed up. A screen recording to demonstrate:

Screen Recording 2022-03-18 at 10.10.32 PM

Any idea what could be going on? Here are my patterns:


    {
    "match": "^(---\\n)[\\s\\S]+(---\\n)",
    "exclusive": false,
    "comment": "YAML front matter",
    "captures": {
      "0": {
        "scope": "code.block"
        },
      }
    },
    {
    "match": "(?s)(\\w+: )([^\\n]++)(?=.*^---)",
    "exclusive": false,
    "comment": "key: value pairs in YAML front matter",
    "captures": {
      "1": {
        "scope": "code.literal"
      },
      "2": {
        "scope": "code.block"
        }
      }
    },
    {
    "match": "(?s)(\\w+:\\n- )([^\\n]++)(?=.*^---)",
    "exclusive": false,
    "comment": "key: - value pairs in YAML front matter",
    "captures": {
      "1": {
        "scope": "code.literal"
      },
      "2": {
        "scope": "code.block"
        }
      }
    },

…keeping in mind that I have created a theme to go along with this syntax. Thanks!

Well, no replies to this, so I suppose that it must be an issue with Drafts itself. My workaround will be to put the YAML header into a form that’s stably highlightable by Drafts. I’ll have to write a script to normalise the syntax before saving it for processing by Pandoc.

What do you have the rangeExtensionType set as in your syntax? If it is anything other than fullText, maybe try changing it to that and giving it another try.

1 Like

Wow, @sylumer! Setting rangeExtensionType to fullText totally worked! I have no idea why, though. Anyway, I’m looking forward to developing this syntax more fully now. Thank you!!! :champagne:

Read the definition for it in the article on creating syntaxes. It sets out the reasonin that definition.

1 Like