Thanks @PeterJones, I really appreciate your time! I spent a chunk of time yesterday too trying to work out the regex if-then-else functionality before I gave up.
I wouldn’t want to pick up everything that starts with \ because that will pull in a lot of commands that aren’t related to document structure (every command starts with \). For example, here’s my minimum working example with a numbered list in it, and that picks up the \begin{enumerate} and \items:
\documentclass{scrreprt} \begin{document} \chapter{Chapter 1 with sections} \section{1.1} \subsection{1.1.1} Lorem \subsection{1.1.2} ipsum \section{1.2} \begin{enumerate} \item dolor \item sit \item amet \end{enumerate} \chapter{Chapter 2 with no sections} consectetur adipiscing elit. \chapter{Chapter 3 with unnumbered sections} \section*{Heading with no number} Phasellus mollis posuere ante vel tincidunt. \section*{Second heading with no number} Donec faucibus tellus sapien, vitae fringilla nulla bibendum eget. \appendix \chapter{Appendix A} \include{document} \chapter{Appendix B with sections} \section{B.1} Nam mauris nisl, cursus at erat in, \section{B.2} molestie luctus nulla. \end{document}… but picking up the \chapter{} as a function along with the \section{}s is a great workaround!
Here’s what I have now:
<?xml version="1.0" encoding="UTF-8" ?> <!-- ==========================================================================\ | To learn how to make your own language parser, please check the following | link: https://npp-user-manual.org/docs/function-list/ \=========================================================================== --> <NotepadPlus> <functionList> <parser displayName="LaTeX Syntax" id ="latex_class" commentExpr="(?x) (%.*?$) # Comment " > <function mainExpr="(?x) # free-spacing (see `RegEx - Pattern Modifiers`) (?im-s) # ignore case, ^ and $ match start/end of line, dot doesn't match newline \\begin{document} # match start of document " > </function> <classRange mainExpr ="(?x) # free-spacing (see `RegEx - Pattern Modifiers`) (?m) # ^ and $ match at line-breaks (?'CLASS_START' ^\s* # optional leading white space before \chapter \\(chapter\*?) ) (?s:.*?) # whatever, (?= # ...up till \s* # ...optional leading white-space of (?: (?&CLASS_START) # ...next header | (\\end{document}) # ...or end of document ) ) " > <className> <nameExpr expr="(?x) # free-spacing (see `RegEx - Pattern Modifiers`) (?<={) # brace before name .*? # name (?=}) # brace after name " /> </className> <function mainExpr="(?xm-s) # free-spacing (see `RegEx - Pattern Modifiers`) \\(chapter| # match chapter so that even \chapters with no \section appear section| # match \section subsection| # match \subsection )\*?{.*} # match starred and unstarred commands " > <functionName> <funcNameExpr expr=".*"/> </functionName> </function> </classRange> </parser> </functionList> </NotepadPlus>And the result on the sample file:
Screenshot 2025-05-14 094212.png
I modified the classRange mainExpr because I wanted to also match indented \chapter{}s (like I have for the appendices in the new sample file). After that change I found that the last \chapter{} wasn’t being matched with \Z so I changed the alternate search to look for \end{document} instead (which will always appear) and that worked.
Thanks for your help!