Package groovy.markdown

# Class MarkdownSlurper

java.lang.Object
groovy.markdown.MarkdownSlurper

@Incubating public class MarkdownSlurper extends Object
Parses CommonMark Markdown into a `MarkdownDocument` backed by nested lists and maps.

Usage:

     def doc = new groovy.markdown.MarkdownSlurper().parseText('# Hello')
     assert doc.headings[0].text == 'Hello'

GFM-style tables are supported via an optional extension. Call `enableTables(true)` after adding `org.commonmark:commonmark-ext-gfm-tables` to the runtime classpath.

## Untrusted input

Prefer parsing Markdown from trusted sources. Like the sibling `JsonSlurper` and `XmlSlurper`, this is a convenience parser, not a security boundary, and the safest posture is not to feed it attacker-controlled input. If you must, bound the input by size yourself before parsing and treat the parsed result defensively.

As a backstop for that case, a small but deeply nested document — which could otherwise drive a recursive parse into a `StackOverflowError` — is reported as a `MarkdownRuntimeException` rather than a raw `Error`. There are two independent vectors, on opposite sides of the CommonMark boundary, and both are covered:

- Block/container nesting (e.g. `'>' * 50000`). CommonMark parses blocks iteratively and returns a very deep tree; the overflow would happen in this slurper's own recursive walk. `maxNestingDepth` bounds this at parse time (via CommonMark's `maxOpenBlockParsers`) and rejects any document nested deeper than the limit.
- Inline emphasis nesting (e.g. `('*' * 50000) + 'a' + ('*' * 50000)`). Bounded at parse time via CommonMark's `maxInlineNesting` (aligned with `maxNestingDepth`); over-limit nesting is degraded to plain text and the resulting tree is then rejected by the same depth check used for blocks. A `StackOverflowError` catch remains as a last-resort backstop if the limit is disabled.

This nesting cap is a robustness backstop, not a licence to treat the parser as hardened.

Since:
  6.0.0

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final int`
  `DEFAULT_MAX_NESTING_DEPTH`
  Default maximum nesting depth of block/inline elements accepted before a `MarkdownRuntimeException` is thrown.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `MarkdownSlurper()`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `MarkdownSlurper`
  `enableTables(boolean enable)`
  Enable GFM-style tables.
  `int`
  `getMaxNestingDepth()`
  Returns the maximum block/container and inline nesting depth the parser will accept.
  `MarkdownDocument`
  `parse(File file)`
  Parses Markdown content from a file.
  `MarkdownDocument`
  `parse(InputStream stream)`
  Parses Markdown content from an input stream.
  `MarkdownDocument`
  `parse(Reader reader)`
  Parses Markdown content from a reader.
  `MarkdownDocument`
  `parse(Path path)`
  Parses Markdown content from a path.
  `MarkdownDocument`
  `parseText(String md)`
  Parses Markdown text into a `MarkdownDocument`.
  `void`
  `setMaxNestingDepth(int maxNestingDepth)`
  Sets the maximum block/container and inline nesting depth.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Field Details

  - ### DEFAULT_MAX_NESTING_DEPTH

    public static final int DEFAULT_MAX_NESTING_DEPTH
    Default maximum nesting depth of block/inline elements accepted before a `MarkdownRuntimeException` is thrown. Matches the default nesting cap of the sibling `JsonSlurper`.
    See Also:
      - Constant Field Values

- ## Constructor Details

  - ### MarkdownSlurper

    public MarkdownSlurper()

- ## Method Details

  - ### getMaxNestingDepth

    public int getMaxNestingDepth()
    Returns the maximum block/container and inline nesting depth the parser will accept.
    Returns:
      the maximum nesting depth, or a value `<= 0` when the limit is disabled

  - ### setMaxNestingDepth

    public void setMaxNestingDepth(int maxNestingDepth)
    Sets the maximum block/container and inline nesting depth. Over-limit nesting is bounded at parse time (via CommonMark's `maxOpenBlockParsers` and `maxInlineNesting`) and rejected with a `MarkdownRuntimeException`. A value of `0` or less disables the limit (CommonMark's caps are raised to `Integer.MAX_VALUE`); a `StackOverflowError` from pathological input is still reported as a `MarkdownRuntimeException`.
    Parameters:
      `maxNestingDepth` - maximum number of nested elements to allow

  - ### enableTables

    public MarkdownSlurper enableTables(boolean enable)
    Enable GFM-style tables. Requires `commonmark-ext-gfm-tables` on the classpath.
    Parameters:
      `enable` - whether to enable table parsing
    Returns:
      this slurper for chaining
    Throws:
      `MarkdownRuntimeException` - if `enable` is true but the extension jar is missing

  - ### parseText

    public MarkdownDocument parseText(String md)
    Parses Markdown text into a `MarkdownDocument`.
    Parameters:
      `md` - the Markdown text to parse
    Returns:
      the parsed document, or an empty document when the input is null or empty

  - ### parse

    public MarkdownDocument parse(Reader reader)
    Parses Markdown content from a reader.
    Parameters:
      `reader` - the reader supplying Markdown content
    Returns:
      the parsed document

  - ### parse

    public MarkdownDocument parse(InputStream stream)
    Parses Markdown content from an input stream. The caller remains responsible for closing the stream.
    Parameters:
      `stream` - the input stream supplying Markdown content
    Returns:
      the parsed document

  - ### parse

    public MarkdownDocument parse(File file) throws IOException
    Parses Markdown content from a file.
    Parameters:
      `file` - the file to read
    Returns:
      the parsed document
    Throws:
      `IOException` - if the file cannot be read

  - ### parse

    public MarkdownDocument parse(Path path) throws IOException
    Parses Markdown content from a path.
    Parameters:
      `path` - the path to read
    Returns:
      the parsed document
    Throws:
      `IOException` - if the path cannot be read