siefkenj / unified-latex

Utilities for parsing and manipulating LaTeX ASTs with the Unified.js framework
MIT License
91 stars 24 forks source link

Parse setting macros like `lineskip` #111

Open rrrnld opened 3 months ago

rrrnld commented 3 months ago

How would I parse macros like this?

\topskip=40pt
\parskip=10pt
\parindent=0pt
\baselineskip=15pt

I have tried this:

const macrosWithSetting: {
  signature?: string
  argumentParser: ArgumentParser
} = {
  argumentParser: (nodes, startPos) => {
    // parses things like `\lineskip=-\baselineskip`
    // nodes[startPos] is the equality sign
    const value = nodes[startPos + 1]
    const args = [
      value, // value or "-"
      ...(value.type === 'string' && value.content === '-' // actual value if value === '-'
        ? [nodes[startPos + 2]]
        : []),
    ].map((n) => arg(n))
    return {
      args,
      nodesRemoved: args.length,
    }
  },
}

But it doesn't to collect the arguments / remove them from the AST.

siefkenj commented 3 months ago

In your function you should actually mutate the array by using .splice on nodes. That is why nodesRemoved is important, so that the caller knows how the array changed.

If you check in the linters, there should be some code that detects = followed by units that you could use.