{
    "content": [
        {
            "type": "text",
            "text": "# Text::Balanced (info)\n\n## NAME\n\nText::Balanced - Extract delimited text sequences from strings.\n\n## SYNOPSIS\n\nuse Text::Balanced qw (\nextractdelimited\nextractbracketed\nextractquotelike\nextractcodeblock\nextractvariable\nextracttagged\nextractmultiple\ngendelimitedpat\ngenextracttagged\n);\n# Extract the initial substring of $text that is delimited by\n# two (unescaped) instances of the first character in $delim.\n($extracted, $remainder) = extractdelimited($text,$delim);\n# Extract the initial substring of $text that is bracketed\n# with a delimiter(s) specified by $delim (where the string\n# in $delim contains one or more of '(){}[]<>').\n($extracted, $remainder) = extractbracketed($text,$delim);\n# Extract the initial substring of $text that is bounded by\n# an XML tag.\n($extracted, $remainder) = extracttagged($text);\n# Extract the initial substring of $text that is bounded by\n# a C<BEGIN>...C<END> pair. Don't allow nested C<BEGIN> tags\n($extracted, $remainder) =\nextracttagged($text,\"BEGIN\",\"END\",undef,{bad=>[\"BEGIN\"]});\n# Extract the initial substring of $text that represents a\n# Perl \"quote or quote-like operation\"\n($extracted, $remainder) = extractquotelike($text);\n# Extract the initial substring of $text that represents a block\n# of Perl code, bracketed by any of character(s) specified by $delim\n# (where the string $delim contains one or more of '(){}[]<>').\n($extracted, $remainder) = extractcodeblock($text,$delim);\n# Extract the initial substrings of $text that would be extracted by\n# one or more sequential applications of the specified functions\n# or regular expressions\n@extracted = extractmultiple($text,\n[ \\&extractbracketed,\n\\&extractquotelike,\n\\&someotherextractorsub,\nqr/[xyz]*/,\n'literal',\n]);\n# Create a string representing an optimized pattern (a la Friedl)\n# that matches a substring delimited by any of the specified characters\n# (in this case: any type of quote or a slash)\n$patstring = gendelimitedpat(q{'\"`/});\n# Generate a reference to an anonymous sub that is just like extracttagged\n# but pre-compiled and optimized for a specific pair of tags, and\n# consequently much faster (i.e. 3 times faster). It uses qr// for better\n# performance on repeated calls.\n$extracthead = genextracttagged('<HEAD>','</HEAD>');\n($extracted, $remainder) = $extracthead->($text);\n\n## DESCRIPTION\n\nThe various \"extract...\" subroutines may be used to extract a\ndelimited substring, possibly after skipping a specified prefix string.\nBy default, that prefix is optional whitespace (\"/\\s*/\"), but you can\nchange it to whatever you wish (see below).\n\n## Sections\n\n- **Text::Balanced(3perl)  Perl Programmers Reference Guide  Text::Balanced(3perl)**\n- **NAME**\n- **SYNOPSIS**\n- **DESCRIPTION**\n- **DIAGNOSTICS**\n- **EXPORTS**\n- **KNOWN BUGS**\n- **FEEDBACK**\n- **AVAILABILITY**\n- **INSTALLATION**\n- **AUTHOR**\n- **COPYRIGHT**\n- **LICENCE**\n- **VERSION**\n- **DATE**\n- **HISTORY**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "Text::Balanced",
        "section": "",
        "mode": "info",
        "summary": "Text::Balanced - Extract delimited text sequences from strings.",
        "synopsis": "use Text::Balanced qw (\nextractdelimited\nextractbracketed\nextractquotelike\nextractcodeblock\nextractvariable\nextracttagged\nextractmultiple\ngendelimitedpat\ngenextracttagged\n);\n# Extract the initial substring of $text that is delimited by\n# two (unescaped) instances of the first character in $delim.\n($extracted, $remainder) = extractdelimited($text,$delim);\n# Extract the initial substring of $text that is bracketed\n# with a delimiter(s) specified by $delim (where the string\n# in $delim contains one or more of '(){}[]<>').\n($extracted, $remainder) = extractbracketed($text,$delim);\n# Extract the initial substring of $text that is bounded by\n# an XML tag.\n($extracted, $remainder) = extracttagged($text);\n# Extract the initial substring of $text that is bounded by\n# a C<BEGIN>...C<END> pair. Don't allow nested C<BEGIN> tags\n($extracted, $remainder) =\nextracttagged($text,\"BEGIN\",\"END\",undef,{bad=>[\"BEGIN\"]});\n# Extract the initial substring of $text that represents a\n# Perl \"quote or quote-like operation\"\n($extracted, $remainder) = extractquotelike($text);\n# Extract the initial substring of $text that represents a block\n# of Perl code, bracketed by any of character(s) specified by $delim\n# (where the string $delim contains one or more of '(){}[]<>').\n($extracted, $remainder) = extractcodeblock($text,$delim);\n# Extract the initial substrings of $text that would be extracted by\n# one or more sequential applications of the specified functions\n# or regular expressions\n@extracted = extractmultiple($text,\n[ \\&extractbracketed,\n\\&extractquotelike,\n\\&someotherextractorsub,\nqr/[xyz]*/,\n'literal',\n]);\n# Create a string representing an optimized pattern (a la Friedl)\n# that matches a substring delimited by any of the specified characters\n# (in this case: any type of quote or a slash)\n$patstring = gendelimitedpat(q{'\"`/});\n# Generate a reference to an anonymous sub that is just like extracttagged\n# but pre-compiled and optimized for a specific pair of tags, and\n# consequently much faster (i.e. 3 times faster). It uses qr// for better\n# performance on repeated calls.\n$extracthead = genextracttagged('<HEAD>','</HEAD>');\n($extracted, $remainder) = $extracthead->($text);",
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "Text::Balanced(3perl)  Perl Programmers Reference Guide  Text::Balanced(3perl)",
                "lines": 1,
                "subsections": []
            },
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SYNOPSIS",
                "lines": 71,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 891,
                "subsections": []
            },
            {
                "name": "DIAGNOSTICS",
                "lines": 109,
                "subsections": []
            },
            {
                "name": "EXPORTS",
                "lines": 18,
                "subsections": []
            },
            {
                "name": "KNOWN BUGS",
                "lines": 3,
                "subsections": []
            },
            {
                "name": "FEEDBACK",
                "lines": 20,
                "subsections": []
            },
            {
                "name": "AVAILABILITY",
                "lines": 12,
                "subsections": []
            },
            {
                "name": "INSTALLATION",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "AUTHOR",
                "lines": 5,
                "subsections": []
            },
            {
                "name": "COPYRIGHT",
                "lines": 6,
                "subsections": []
            },
            {
                "name": "LICENCE",
                "lines": 5,
                "subsections": []
            },
            {
                "name": "VERSION",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "DATE",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "HISTORY",
                "lines": 3,
                "subsections": []
            }
        ],
        "sections": {
            "Text::Balanced(3perl)  Perl Programmers Reference Guide  Text::Balanced(3perl)": {
                "content": "",
                "subsections": []
            },
            "NAME": {
                "content": "Text::Balanced - Extract delimited text sequences from strings.\n",
                "subsections": []
            },
            "SYNOPSIS": {
                "content": "use Text::Balanced qw (\nextractdelimited\nextractbracketed\nextractquotelike\nextractcodeblock\nextractvariable\nextracttagged\nextractmultiple\ngendelimitedpat\ngenextracttagged\n);\n\n# Extract the initial substring of $text that is delimited by\n# two (unescaped) instances of the first character in $delim.\n\n($extracted, $remainder) = extractdelimited($text,$delim);\n\n# Extract the initial substring of $text that is bracketed\n# with a delimiter(s) specified by $delim (where the string\n# in $delim contains one or more of '(){}[]<>').\n\n($extracted, $remainder) = extractbracketed($text,$delim);\n\n# Extract the initial substring of $text that is bounded by\n# an XML tag.\n\n($extracted, $remainder) = extracttagged($text);\n\n# Extract the initial substring of $text that is bounded by\n# a C<BEGIN>...C<END> pair. Don't allow nested C<BEGIN> tags\n\n($extracted, $remainder) =\nextracttagged($text,\"BEGIN\",\"END\",undef,{bad=>[\"BEGIN\"]});\n\n# Extract the initial substring of $text that represents a\n# Perl \"quote or quote-like operation\"\n\n($extracted, $remainder) = extractquotelike($text);\n\n# Extract the initial substring of $text that represents a block\n# of Perl code, bracketed by any of character(s) specified by $delim\n# (where the string $delim contains one or more of '(){}[]<>').\n\n($extracted, $remainder) = extractcodeblock($text,$delim);\n\n# Extract the initial substrings of $text that would be extracted by\n# one or more sequential applications of the specified functions\n# or regular expressions\n\n@extracted = extractmultiple($text,\n[ \\&extractbracketed,\n\\&extractquotelike,\n\\&someotherextractorsub,\nqr/[xyz]*/,\n'literal',\n]);\n\n# Create a string representing an optimized pattern (a la Friedl)\n# that matches a substring delimited by any of the specified characters\n# (in this case: any type of quote or a slash)\n\n$patstring = gendelimitedpat(q{'\"`/});\n\n# Generate a reference to an anonymous sub that is just like extracttagged\n# but pre-compiled and optimized for a specific pair of tags, and\n# consequently much faster (i.e. 3 times faster). It uses qr// for better\n# performance on repeated calls.\n\n$extracthead = genextracttagged('<HEAD>','</HEAD>');\n($extracted, $remainder) = $extracthead->($text);\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "The various \"extract...\" subroutines may be used to extract a\ndelimited substring, possibly after skipping a specified prefix string.\nBy default, that prefix is optional whitespace (\"/\\s*/\"), but you can\nchange it to whatever you wish (see below).\n\nThe substring to be extracted must appear at the current \"pos\" location\nof the string's variable (or at index zero, if no \"pos\" position is\ndefined).  In other words, the \"extract...\" subroutines don't extract\nthe first occurrence of a substring anywhere in a string (like an\nunanchored regex would). Rather, they extract an occurrence of the\nsubstring appearing immediately at the current matching position in the\nstring (like a \"\\G\"-anchored regex would).\n\nGeneral Behaviour in List Contexts\nIn a list context, all the subroutines return a list, the first three\nelements of which are always:\n\n[0] The extracted string, including the specified delimiters.  If the\nextraction fails \"undef\" is returned.\n\n[1] The remainder of the input string (i.e. the characters after the\nextracted string). On failure, the entire string is returned.\n\n[2] The skipped prefix (i.e. the characters before the extracted\nstring).  On failure, \"undef\" is returned.\n\nNote that in a list context, the contents of the original input text\n(the first argument) are not modified in any way.\n\nHowever, if the input text was passed in a variable, that variable's\n\"pos\" value is updated to point at the first character after the\nextracted text. That means that in a list context the various\nsubroutines can be used much like regular expressions. For example:\n\nwhile ( $next = (extractquotelike($text))[0] )\n{\n# process next quote-like (in $next)\n}\n\nGeneral Behaviour in Scalar and Void Contexts\nIn a scalar context, the extracted string is returned, having first\nbeen removed from the input text. Thus, the following code also\nprocesses each quote-like operation, but actually removes them from\n$text:\n\nwhile ( $next = extractquotelike($text) )\n{\n# process next quote-like (in $next)\n}\n\nNote that if the input text is a read-only string (i.e. a literal), no\nattempt is made to remove the extracted text.\n\nIn a void context the behaviour of the extraction subroutines is\nexactly the same as in a scalar context, except (of course) that the\nextracted substring is not returned.\n\nA Note About Prefixes\nPrefix patterns are matched without any trailing modifiers (\"/gimsox\"\netc.)  This can bite you if you're expecting a prefix specification\nlike '.*?(?=<H1>)' to skip everything up to the first <H1> tag. Such a\nprefix pattern will only succeed if the <H1> tag is on the current\nline, since . normally doesn't match newlines.\n\nTo overcome this limitation, you need to turn on /s matching within the\nprefix pattern, using the \"(?s)\" directive: '(?s).*?(?=<H1>)'\n\nFunctions\n\"extractdelimited\"\nThe \"extractdelimited\" function formalizes the common idiom of\nextracting a single-character-delimited substring from the start of\na string. For example, to extract a single-quote delimited string,\nthe following code is typically used:\n\n($remainder = $text) =~ s/\\A('(\\\\.|[^'])*')//s;\n$extracted = $1;\n\nbut with \"extractdelimited\" it can be simplified to:\n\n($extracted,$remainder) = extractdelimited($text, \"'\");\n\n\"extractdelimited\" takes up to four scalars (the input text, the\ndelimiters, a prefix pattern to be skipped, and any escape\ncharacters) and extracts the initial substring of the text that is\nappropriately delimited. If the delimiter string has multiple\ncharacters, the first one encountered in the text is taken to\ndelimit the substring.  The third argument specifies a prefix\npattern that is to be skipped (but must be present!) before the\nsubstring is extracted.  The final argument specifies the escape\ncharacter to be used for each delimiter.\n\nAll arguments are optional. If the escape characters are not\nspecified, every delimiter is escaped with a backslash (\"\\\").  If\nthe prefix is not specified, the pattern '\\s*' - optional\nwhitespace - is used. If the delimiter set is also not specified,\nthe set \"/[\"'`]/\" is used. If the text to be processed is not\nspecified either, $ is used.\n\nIn list context, \"extractdelimited\" returns a array of three\nelements, the extracted substring (including the surrounding\ndelimiters), the remainder of the text, and the skipped prefix (if\nany). If a suitable delimited substring is not found, the first\nelement of the array is the empty string, the second is the\ncomplete original text, and the prefix returned in the third\nelement is an empty string.\n\nIn a scalar context, just the extracted substring is returned. In a\nvoid context, the extracted substring (and any prefix) are simply\nremoved from the beginning of the first argument.\n\nExamples:\n\n# Remove a single-quoted substring from the very beginning of $text:\n\n$substring = extractdelimited($text, \"'\", '');\n\n# Remove a single-quoted Pascalish substring (i.e. one in which\n# doubling the quote character escapes it) from the very\n# beginning of $text:\n\n$substring = extractdelimited($text, \"'\", '', \"'\");\n\n# Extract a single- or double- quoted substring from the\n# beginning of $text, optionally after some whitespace\n# (note the list context to protect $text from modification):\n\n($substring) = extractdelimited $text, q{\"'};\n\n# Delete the substring delimited by the first '/' in $text:\n\n$text = join '', (extractdelimited($text,'/','[^/]*')[2,1];\n\nNote that this last example is not the same as deleting the first\nquote-like pattern. For instance, if $text contained the string:\n\n\"if ('./cmd' =~ m/$UNIXCMD/s) { $cmd = $1; }\"\n\nthen after the deletion it would contain:\n\n\"if ('.$UNIXCMD/s) { $cmd = $1; }\"\n\nnot:\n\n\"if ('./cmd' =~ ms) { $cmd = $1; }\"\n\nSee \"extractquotelike\" for a (partial) solution to this problem.\n\n\"extractbracketed\"\nLike \"extractdelimited\", the \"extractbracketed\" function takes up\nto three optional scalar arguments: a string to extract from, a\ndelimiter specifier, and a prefix pattern. As before, a missing\nprefix defaults to optional whitespace and a missing text defaults\nto $. However, a missing delimiter specifier defaults to\n'{}()[]<>' (see below).\n\n\"extractbracketed\" extracts a balanced-bracket-delimited substring\n(using any one (or more) of the user-specified delimiter brackets:\n'(..)', '{..}', '[..]', or '<..>'). Optionally it will also respect\nquoted unbalanced brackets (see below).\n\nA \"delimiter bracket\" is a bracket in list of delimiters passed as\n\"extractbracketed\"'s second argument. Delimiter brackets are\nspecified by giving either the left or right (or both!) versions of\nthe required bracket(s). Note that the order in which two or more\ndelimiter brackets are specified is not significant.\n\nA \"balanced-bracket-delimited substring\" is a substring bounded by\nmatched brackets, such that any other (left or right) delimiter\nbracket within the substring is also matched by an opposite (right\nor left) delimiter bracket at the same level of nesting. Any type\nof bracket not in the delimiter list is treated as an ordinary\ncharacter.\n\nIn other words, each type of bracket specified as a delimiter must\nbe balanced and correctly nested within the substring, and any\nother kind of (\"non-delimiter\") bracket in the substring is\nignored.\n\nFor example, given the string:\n\n$text = \"{ an '[irregularly :-(] {} parenthesized >:-)' string }\";\n\nthen a call to \"extractbracketed\" in a list context:\n\n@result = extractbracketed( $text, '{}' );\n\nwould return:\n\n( \"{ an '[irregularly :-(] {} parenthesized >:-)' string }\" , \"\" , \"\" )\n\nsince both sets of '{..}' brackets are properly nested and evenly\nbalanced.  (In a scalar context just the first element of the array\nwould be returned. In a void context, $text would be replaced by an\nempty string.)\n\nLikewise the call in:\n\n@result = extractbracketed( $text, '{[' );\n\nwould return the same result, since all sets of both types of\nspecified delimiter brackets are correctly nested and balanced.\n\nHowever, the call in:\n\n@result = extractbracketed( $text, '{([<' );\n\nwould fail, returning:\n\n( undef , \"{ an '[irregularly :-(] {} parenthesized >:-)' string }\"  );\n\nbecause the embedded pairs of '(..)'s and '[..]'s are \"cross-\nnested\" and the embedded '>' is unbalanced. (In a scalar context,\nthis call would return an empty string. In a void context, $text\nwould be unchanged.)\n\nNote that the embedded single-quotes in the string don't help in\nthis case, since they have not been specified as acceptable\ndelimiters and are therefore treated as non-delimiter characters\n(and ignored).\n\nHowever, if a particular species of quote character is included in\nthe delimiter specification, then that type of quote will be\ncorrectly handled.  for example, if $text is:\n\n$text = '<A HREF=\">>>>\">link</A>';\n\nthen\n\n@result = extractbracketed( $text, '<\">' );\n\nreturns:\n\n( '<A HREF=\">>>>\">', 'link</A>', \"\" )\n\nas expected. Without the specification of \"\"\" as an embedded\nquoter:\n\n@result = extractbracketed( $text, '<>' );\n\nthe result would be:\n\n( '<A HREF=\">', '>>>\">link</A>', \"\" )\n\nIn addition to the quote delimiters \"'\", \"\"\", and \"`\", full Perl\nquote-like quoting (i.e. q{string}, qq{string}, etc) can be\nspecified by including the letter 'q' as a delimiter. Hence:\n\n@result = extractbracketed( $text, '<q>' );\n\nwould correctly match something like this:\n\n$text = '<leftop: conj /and/ conj>';\n\nSee also: \"extractquotelike\" and \"extractcodeblock\".\n\n\"extractvariable\"\n\"extractvariable\" extracts any valid Perl variable or variable-\ninvolved expression, including scalars, arrays, hashes, array\naccesses, hash look-ups, method calls through objects, subroutine\ncalls through subroutine references, etc.\n\nThe subroutine takes up to two optional arguments:\n\n1.  A string to be processed ($ if the string is omitted or\n\"undef\")\n\n2.  A string specifying a pattern to be matched as a prefix (which\nis to be skipped). If omitted, optional whitespace is skipped.\n\nOn success in a list context, an array of 3 elements is returned.\nThe elements are:\n\n[0] the extracted variable, or variablish expression\n\n[1] the remainder of the input text,\n\n[2] the prefix substring (if any),\n\nOn failure, all of these values (except the remaining text) are\n\"undef\".\n\nIn a scalar context, \"extractvariable\" returns just the complete\nsubstring that matched a variablish expression. \"undef\" is returned\non failure. In addition, the original input text has the returned\nsubstring (and any prefix) removed from it.\n\nIn a void context, the input text just has the matched substring\n(and any specified prefix) removed.\n\n\"extracttagged\"\n\"extracttagged\" extracts and segments text between (balanced)\nspecified tags.\n\nThe subroutine takes up to five optional arguments:\n\n1.  A string to be processed ($ if the string is omitted or\n\"undef\")\n\n2.  A string specifying a pattern to be matched as the opening tag.\nIf the pattern string is omitted (or \"undef\") then a pattern\nthat matches any standard XML tag is used.\n\n3.  A string specifying a pattern to be matched at the closing tag.\nIf the pattern string is omitted (or \"undef\") then the closing\ntag is constructed by inserting a \"/\" after any leading bracket\ncharacters in the actual opening tag that was matched (not the\npattern that matched the tag). For example, if the opening tag\npattern is specified as '{{\\w+}}' and actually matched the\nopening tag \"{{DATA}}\", then the constructed closing tag would\nbe \"{{/DATA}}\".\n\n4.  A string specifying a pattern to be matched as a prefix (which\nis to be skipped). If omitted, optional whitespace is skipped.\n\n5.  A hash reference containing various parsing options (see below)\n\nThe various options that can be specified are:\n\n\"reject => $listref\"\nThe list reference contains one or more strings specifying\npatterns that must not appear within the tagged text.\n\nFor example, to extract an HTML link (which should not contain\nnested links) use:\n\nextracttagged($text, '<A>', '</A>', undef, {reject => ['<A>']} );\n\n\"ignore => $listref\"\nThe list reference contains one or more strings specifying\npatterns that are not to be treated as nested tags within the\ntagged text (even if they would match the start tag pattern).\n\nFor example, to extract an arbitrary XML tag, but ignore\n\"empty\" elements:\n\nextracttagged($text, undef, undef, undef, {ignore => ['<[^>]*/>']} );\n\n(also see \"gendelimitedpat\" below).\n\n\"fail => $str\"\nThe \"fail\" option indicates the action to be taken if a\nmatching end tag is not encountered (i.e. before the end of the\nstring or some \"reject\" pattern matches). By default, a failure\nto match a closing tag causes \"extracttagged\" to immediately\nfail.\n\nHowever, if the string value associated with <reject> is \"MAX\",\nthen \"extracttagged\" returns the complete text up to the point\nof failure.  If the string is \"PARA\", \"extracttagged\" returns\nonly the first paragraph after the tag (up to the first line\nthat is either empty or contains only whitespace characters).\nIf the string is \"\", the default behaviour (i.e. failure) is\nreinstated.\n\nFor example, suppose the start tag \"/para\" introduces a\nparagraph, which then continues until the next \"/endpara\" tag\nor until another \"/para\" tag is encountered:\n\n$text = \"/para line 1\\n\\nline 3\\n/para line 4\";\n\nextracttagged($text, '/para', '/endpara', undef,\n{reject => '/para', fail => MAX );\n\n# EXTRACTED: \"/para line 1\\n\\nline 3\\n\"\n\nSuppose instead, that if no matching \"/endpara\" tag is found,\nthe \"/para\" tag refers only to the immediately following\nparagraph:\n\n$text = \"/para line 1\\n\\nline 3\\n/para line 4\";\n\nextracttagged($text, '/para', '/endpara', undef,\n{reject => '/para', fail => MAX );\n\n# EXTRACTED: \"/para line 1\\n\"\n\nNote that the specified \"fail\" behaviour applies to nested tags\nas well.\n\nOn success in a list context, an array of 6 elements is returned.\nThe elements are:\n\n[0] the extracted tagged substring (including the outermost tags),\n\n[1] the remainder of the input text,\n\n[2] the prefix substring (if any),\n\n[3] the opening tag\n\n[4] the text between the opening and closing tags\n\n[5] the closing tag (or \"\" if no closing tag was found)\n\nOn failure, all of these values (except the remaining text) are\n\"undef\".\n\nIn a scalar context, \"extracttagged\" returns just the complete\nsubstring that matched a tagged text (including the start and end\ntags). \"undef\" is returned on failure. In addition, the original\ninput text has the returned substring (and any prefix) removed from\nit.\n\nIn a void context, the input text just has the matched substring\n(and any specified prefix) removed.\n\n\"genextracttagged\"\n\"genextracttagged\" generates a new anonymous subroutine which\nextracts text between (balanced) specified tags. In other words, it\ngenerates a function identical in function to \"extracttagged\".\n\nThe difference between \"extracttagged\" and the anonymous\nsubroutines generated by \"genextracttagged\", is that those\ngenerated subroutines:\n\no   do not have to reparse tag specification or parsing options\nevery time they are called (whereas \"extracttagged\" has to\neffectively rebuild its tag parser on every call);\n\no   make use of the new qr// construct to pre-compile the regexes\nthey use (whereas \"extracttagged\" uses standard string\nvariable interpolation to create tag-matching patterns).\n\nThe subroutine takes up to four optional arguments (the same set as\n\"extracttagged\" except for the string to be processed). It returns\na reference to a subroutine which in turn takes a single argument\n(the text to be extracted from).\n\nIn other words, the implementation of \"extracttagged\" is exactly\nequivalent to:\n\nsub extracttagged\n{\nmy $text = shift;\n$extractor = genextracttagged(@);\nreturn $extractor->($text);\n}\n\n(although \"extracttagged\" is not currently implemented that way).\n\nUsing \"genextracttagged\" to create extraction functions for\nspecific tags is a good idea if those functions are going to be\ncalled more than once, since their performance is typically twice\nas good as the more general-purpose \"extracttagged\".\n\n\"extractquotelike\"\n\"extractquotelike\" attempts to recognize, extract, and segment any\none of the various Perl quotes and quotelike operators (see\nperlop(3)) Nested backslashed delimiters, embedded balanced bracket\ndelimiters (for the quotelike operators), and trailing modifiers\nare all caught. For example, in:\n\nextractquotelike 'q # an octothorpe: \\# (not the end of the q!) #'\n\nextractquotelike '  \"You said, \\\"Use sed\\\".\"  '\n\nextractquotelike ' s{([A-Z]{1,8}\\.[A-Z]{3})} /\\L$1\\E/; '\n\nextractquotelike ' tr/\\\\\\/\\\\\\\\/\\\\\\//ds; '\n\nthe full Perl quotelike operations are all extracted correctly.\n\nNote too that, when using the /x modifier on a regex, any comment\ncontaining the current pattern delimiter will cause the regex to be\nimmediately terminated. In other words:\n\n'm /\n(?i)            # CASE INSENSITIVE\n[a-z]          # LEADING ALPHABETIC/UNDERSCORE\n[a-z0-9]*       # FOLLOWED BY ANY NUMBER OF ALPHANUMERICS\n/x'\n\nwill be extracted as if it were:\n\n'm /\n(?i)            # CASE INSENSITIVE\n[a-z]          # LEADING ALPHABETIC/'\n\nThis behaviour is identical to that of the actual compiler.\n\n\"extractquotelike\" takes two arguments: the text to be processed\nand a prefix to be matched at the very beginning of the text. If no\nprefix is specified, optional whitespace is the default. If no text\nis given, $ is used.\n\nIn a list context, an array of 11 elements is returned. The\nelements are:\n\n[0] the extracted quotelike substring (including trailing\nmodifiers),\n\n[1] the remainder of the input text,\n\n[2] the prefix substring (if any),\n\n[3] the name of the quotelike operator (if any),\n\n[4] the left delimiter of the first block of the operation,\n\n[5] the text of the first block of the operation (that is, the\ncontents of a quote, the regex of a match or substitution or\nthe target list of a translation),\n\n[6] the right delimiter of the first block of the operation,\n\n[7] the left delimiter of the second block of the operation (that\nis, if it is a \"s\", \"tr\", or \"y\"),\n\n[8] the text of the second block of the operation (that is, the\nreplacement of a substitution or the translation list of a\ntranslation),\n\n[9] the right delimiter of the second block of the operation (if\nany),\n\n[10]\nthe trailing modifiers on the operation (if any).\n\nFor each of the fields marked \"(if any)\" the default value on\nsuccess is an empty string.  On failure, all of these values\n(except the remaining text) are \"undef\".\n\nIn a scalar context, \"extractquotelike\" returns just the complete\nsubstring that matched a quotelike operation (or \"undef\" on\nfailure). In a scalar or void context, the input text has the same\nsubstring (and any specified prefix) removed.\n\nExamples:\n\n# Remove the first quotelike literal that appears in text\n\n$quotelike = extractquotelike($text,'.*?');\n\n# Replace one or more leading whitespace-separated quotelike\n# literals in $ with \"<QLL>\"\n\ndo { $ = join '<QLL>', (extractquotelike)[2,1] } until $@;\n\n# Isolate the search pattern in a quotelike operation from $text\n\n($op,$pat) = (extractquotelike $text)[3,5];\nif ($op =~ /[ms]/)\n{\nprint \"search pattern: $pat\\n\";\n}\nelse\n{\nprint \"$op is not a pattern matching operation\\n\";\n}\n\n\"extractquotelike\"\n\"extractquotelike\" can successfully extract \"here documents\" from\nan input string, but with an important caveat in list contexts.\n\nUnlike other types of quote-like literals, a here document is\nrarely a contiguous substring. For example, a typical piece of code\nusing here document might look like this:\n\n<<'EOMSG' || die;\nThis is the message.\nEOMSG\nexit;\n\nGiven this as an input string in a scalar context,\n\"extractquotelike\" would correctly return the string\n\"<<'EOMSG'\\nThis is the message.\\nEOMSG\", leaving the string \" ||\ndie;\\nexit;\" in the original variable. In other words, the two\nseparate pieces of the here document are successfully extracted and\nconcatenated.\n\nIn a list context, \"extractquotelike\" would return the list\n\n[0] \"<<'EOMSG'\\nThis is the message.\\nEOMSG\\n\" (i.e. the full\nextracted here document, including fore and aft delimiters),\n\n[1] \" || die;\\nexit;\" (i.e. the remainder of the input text,\nconcatenated),\n\n[2] \"\" (i.e. the prefix substring -- trivial in this case),\n\n[3] \"<<\" (i.e. the \"name\" of the quotelike operator)\n\n[4] \"'EOMSG'\" (i.e. the left delimiter of the here document,\nincluding any quotes),\n\n[5] \"This is the message.\\n\" (i.e. the text of the here document),\n\n[6] \"EOMSG\" (i.e. the right delimiter of the here document),\n\n[7..10]\n\"\" (a here document has no second left delimiter, second text,\nsecond right delimiter, or trailing modifiers).\n\nHowever, the matching position of the input variable would be set\nto \"exit;\" (i.e. after the closing delimiter of the here document),\nwhich would cause the earlier \" || die;\\nexit;\" to be skipped in\nany sequence of code fragment extractions.\n\nTo avoid this problem, when it encounters a here document whilst\nextracting from a modifiable string, \"extractquotelike\" silently\nrearranges the string to an equivalent piece of Perl:\n\n<<'EOMSG'\nThis is the message.\nEOMSG\n|| die;\nexit;\n\nin which the here document is contiguous. It still leaves the\nmatching position after the here document, but now the rest of the\nline on which the here document starts is not skipped.\n\nTo prevent <extractquotelike> from mucking about with the input in\nthis way (this is the only case where a list-context\n\"extractquotelike\" does so), you can pass the input variable as an\ninterpolated literal:\n\n$quotelike = extractquotelike(\"$var\");\n\n\"extractcodeblock\"\n\"extractcodeblock\" attempts to recognize and extract a balanced\nbracket delimited substring that may contain unbalanced brackets\ninside Perl quotes or quotelike operations. That is,\n\"extractcodeblock\" is like a combination of \"extractbracketed\"\nand \"extractquotelike\".\n\n\"extractcodeblock\" takes the same initial three parameters as\n\"extractbracketed\": a text to process, a set of delimiter brackets\nto look for, and a prefix to match first. It also takes an optional\nfourth parameter, which allows the outermost delimiter brackets to\nbe specified separately (see below).\n\nOmitting the first argument (input text) means process $ instead.\nOmitting the second argument (delimiter brackets) indicates that\nonly '{' is to be used.  Omitting the third argument (prefix\nargument) implies optional whitespace at the start.  Omitting the\nfourth argument (outermost delimiter brackets) indicates that the\nvalue of the second argument is to be used for the outermost\ndelimiters.\n\nOnce the prefix and the outermost opening delimiter bracket have\nbeen recognized, code blocks are extracted by stepping through the\ninput text and trying the following alternatives in sequence:\n\n1.  Try and match a closing delimiter bracket. If the bracket was\nthe same species as the last opening bracket, return the\nsubstring to that point. If the bracket was mismatched, return\nan error.\n\n2.  Try to match a quote or quotelike operator. If found, call\n\"extractquotelike\" to eat it. If \"extractquotelike\" fails,\nreturn the error it returned. Otherwise go back to step 1.\n\n3.  Try to match an opening delimiter bracket. If found, call\n\"extractcodeblock\" recursively to eat the embedded block. If\nthe recursive call fails, return an error. Otherwise, go back\nto step 1.\n\n4.  Unconditionally match a bareword or any other single character,\nand then go back to step 1.\n\nExamples:\n\n# Find a while loop in the text\n\nif ($text =~ s/.*?while\\s*\\{/{/)\n{\n$loop = \"while \" . extractcodeblock($text);\n}\n\n# Remove the first round-bracketed list (which may include\n# round- or curly-bracketed code blocks or quotelike operators)\n\nextractcodeblock $text, \"(){}\", '[^(]*';\n\nThe ability to specify a different outermost delimiter bracket is\nuseful in some circumstances. For example, in the Parse::RecDescent\nmodule, parser actions which are to be performed only on a\nsuccessful parse are specified using a \"<defer:...>\" directive. For\nexample:\n\nsentence: subject verb object\n<defer: {$::theVerb = $item{verb}} >\n\nParse::RecDescent uses \"extractcodeblock($text, '{}<>')\" to\nextract the code within the \"<defer:...>\" directive, but there's a\nproblem.\n\nA deferred action like this:\n\n<defer: {if ($count>10) {$count--}} >\n\nwill be incorrectly parsed as:\n\n<defer: {if ($count>\n\nbecause the \"less than\" operator is interpreted as a closing\ndelimiter.\n\nBut, by extracting the directive using\n\"extractcodeblock($text,'{}',undef,'<>')\" the '>' character is\nonly treated as a delimited at the outermost level of the code\nblock, so the directive is parsed correctly.\n\n\"extractmultiple\"\nThe \"extractmultiple\" subroutine takes a string to be processed\nand a list of extractors (subroutines or regular expressions) to\napply to that string.\n\nIn an array context \"extractmultiple\" returns an array of\nsubstrings of the original string, as extracted by the specified\nextractors.  In a scalar context, \"extractmultiple\" returns the\nfirst substring successfully extracted from the original string. In\nboth scalar and void contexts the original string has the first\nsuccessfully extracted substring removed from it. In all contexts\n\"extractmultiple\" starts at the current \"pos\" of the string, and\nsets that \"pos\" appropriately after it matches.\n\nHence, the aim of a call to \"extractmultiple\" in a list context is\nto split the processed string into as many non-overlapping fields\nas possible, by repeatedly applying each of the specified\nextractors to the remainder of the string. Thus \"extractmultiple\"\nis a generalized form of Perl's \"split\" subroutine.\n\nThe subroutine takes up to four optional arguments:\n\n1.  A string to be processed ($ if the string is omitted or\n\"undef\")\n\n2.  A reference to a list of subroutine references and/or qr//\nobjects and/or literal strings and/or hash references,\nspecifying the extractors to be used to split the string. If\nthis argument is omitted (or \"undef\") the list:\n\n[\nsub { extractvariable($[0], '') },\nsub { extractquotelike($[0],'') },\nsub { extractcodeblock($[0],'{}','') },\n]\n\nis used.\n\n3.  An number specifying the maximum number of fields to return. If\nthis argument is omitted (or \"undef\"), split continues as long\nas possible.\n\nIf the third argument is N, then extraction continues until N\nfields have been successfully extracted, or until the string\nhas been completely processed.\n\nNote that in scalar and void contexts the value of this\nargument is automatically reset to 1 (under \"-w\", a warning is\nissued if the argument has to be reset).\n\n4.  A value indicating whether unmatched substrings (see below)\nwithin the text should be skipped or returned as fields. If the\nvalue is true, such substrings are skipped. Otherwise, they are\nreturned.\n\nThe extraction process works by applying each extractor in sequence\nto the text string.\n\nIf the extractor is a subroutine it is called in a list context and\nis expected to return a list of a single element, namely the\nextracted text. It may optionally also return two further\narguments: a string representing the text left after extraction\n(like $' for a pattern match), and a string representing any prefix\nskipped before the extraction (like $` in a pattern match). Note\nthat this is designed to facilitate the use of other Text::Balanced\nsubroutines with \"extractmultiple\". Note too that the value\nreturned by an extractor subroutine need not bear any relationship\nto the corresponding substring of the original text (see examples\nbelow).\n\nIf the extractor is a precompiled regular expression or a string,\nit is matched against the text in a scalar context with a leading\n'\\G' and the gc modifiers enabled. The extracted value is either $1\nif that variable is defined after the match, or else the complete\nmatch (i.e. $&).\n\nIf the extractor is a hash reference, it must contain exactly one\nelement.  The value of that element is one of the above extractor\ntypes (subroutine reference, regular expression, or string).  The\nkey of that element is the name of a class into which the\nsuccessful return value of the extractor will be blessed.\n\nIf an extractor returns a defined value, that value is immediately\ntreated as the next extracted field and pushed onto the list of\nfields.  If the extractor was specified in a hash reference, the\nfield is also blessed into the appropriate class,\n\nIf the extractor fails to match (in the case of a regex extractor),\nor returns an empty list or an undefined value (in the case of a\nsubroutine extractor), it is assumed to have failed to extract.  If\nnone of the extractor subroutines succeeds, then one character is\nextracted from the start of the text and the extraction subroutines\nreapplied. Characters which are thus removed are accumulated and\neventually become the next field (unless the fourth argument is\ntrue, in which case they are discarded).\n\nFor example, the following extracts substrings that are valid Perl\nvariables:\n\n@fields = extractmultiple($text,\n[ sub { extractvariable($[0]) } ],\nundef, 1);\n\nThis example separates a text into fields which are quote\ndelimited, curly bracketed, and anything else. The delimited and\nbracketed parts are also blessed to identify them (the \"anything\nelse\" is unblessed):\n\n@fields = extractmultiple($text,\n[\n{ Delim => sub { extractdelimited($[0],q{'\"}) } },\n{ Brack => sub { extractbracketed($[0],'{}') } },\n]);\n\nThis call extracts the next single substring that is a valid Perl\nquotelike operator (and removes it from $text):\n\n$quotelike = extractmultiple($text,\n[\nsub { extractquotelike($[0]) },\n], undef, 1);\n\nFinally, here is yet another way to do comma-separated value\nparsing:\n\n@fields = extractmultiple($csvtext,\n[\nsub { extractdelimited($[0],q{'\"}) },\nqr/([^,]+)(.*)/,\n],\nundef,1);\n\nThe list in the second argument means: \"Try and extract a ' or \"\ndelimited string, otherwise extract anything up to a comma...\".\nThe undef third argument means: \"...as many times as possible...\",\nand the true value in the fourth argument means \"...discarding\nanything else that appears (i.e. the commas)\".\n\nIf you wanted the commas preserved as separate fields (i.e. like\nsplit does if your split pattern has capturing parentheses), you\nwould just make the last parameter undefined (or remove it).\n\n\"gendelimitedpat\"\nThe \"gendelimitedpat\" subroutine takes a single (string) argument\nand\n> builds a Friedl-style optimized regex that matches a string\ndelimited by any one of the characters in the single argument. For\nexample:\n\ngendelimitedpat(q{'\"})\n\nreturns the regex:\n\n(?:\\\"(?:\\\\\\\"|(?!\\\").)*\\\"|\\'(?:\\\\\\'|(?!\\').)*\\')\n\nNote that the specified delimiters are automatically quotemeta'd.\n\nA typical use of \"gendelimitedpat\" would be to build special\npurpose tags for \"extracttagged\". For example, to properly ignore\n\"empty\" XML elements (which might contain quoted strings):\n\nmy $emptytag = '<(' . gendelimitedpat(q{'\"}) . '|.)+/>';\n\nextracttagged($text, undef, undef, undef, {ignore => [$emptytag]} );\n\n\"gendelimitedpat\" may also be called with an optional second\nargument, which specifies the \"escape\" character(s) to be used for\neach delimiter.  For example to match a Pascal-style string (where\n' is the delimiter and '' is a literal ' within the string):\n\ngendelimitedpat(q{'},q{'});\n\nDifferent escape characters can be specified for different\ndelimiters.  For example, to specify that '/' is the escape for\nsingle quotes and '%' is the escape for double quotes:\n\ngendelimitedpat(q{'\"},q{/%});\n\nIf more delimiters than escape chars are specified, the last escape\nchar is used for the remaining delimiters.  If no escape char is\nspecified for a given specified delimiter, '\\' is used.\n\n\"delimitedpat\"\nNote that \"gendelimitedpat\" was previously called\n\"delimitedpat\".  That name may still be used, but is now\ndeprecated.\n",
                "subsections": []
            },
            "DIAGNOSTICS": {
                "content": "In a list context, all the functions return \"(undef,$originaltext)\" on\nfailure. In a scalar context, failure is indicated by returning \"undef\"\n(in this case the input text is not modified in any way).\n\nIn addition, on failure in any context, the $@ variable is set.\nAccessing \"$@->{error}\" returns one of the error diagnostics listed\nbelow.  Accessing \"$@->{pos}\" returns the offset into the original\nstring at which the error was detected (although not necessarily where\nit occurred!)  Printing $@ directly produces the error message, with\nthe offset appended.  On success, the $@ variable is guaranteed to be\n\"undef\".\n\nThe available diagnostics are:\n\n\"Did not find a suitable bracket: \"%s\"\"\nThe delimiter provided to \"extractbracketed\" was not one of\n'()[]<>{}'.\n\n\"Did not find prefix: /%s/\"\nA non-optional prefix was specified but wasn't found at the start\nof the text.\n\n\"Did not find opening bracket after prefix: \"%s\"\"\n\"extractbracketed\" or \"extractcodeblock\" was expecting a\nparticular kind of bracket at the start of the text, and didn't\nfind it.\n\n\"No quotelike operator found after prefix: \"%s\"\"\n\"extractquotelike\" didn't find one of the quotelike operators \"q\",\n\"qq\", \"qw\", \"qx\", \"s\", \"tr\" or \"y\" at the start of the substring it\nwas extracting.\n\n\"Unmatched closing bracket: \"%c\"\"\n\"extractbracketed\", \"extractquotelike\" or \"extractcodeblock\"\nencountered a closing bracket where none was expected.\n\n\"Unmatched opening bracket(s): \"%s\"\"\n\"extractbracketed\", \"extractquotelike\" or \"extractcodeblock\" ran\nout of characters in the text before closing one or more levels of\nnested brackets.\n\n\"Unmatched embedded quote (%s)\"\n\"extractbracketed\" attempted to match an embedded quoted\nsubstring, but failed to find a closing quote to match it.\n\n\"Did not find closing delimiter to match '%s'\"\n\"extractquotelike\" was unable to find a closing delimiter to match\nthe one that opened the quote-like operation.\n\n\"Mismatched closing bracket: expected \"%c\" but found \"%s\"\"\n\"extractbracketed\", \"extractquotelike\" or \"extractcodeblock\"\nfound a valid bracket delimiter, but it was the wrong species. This\nusually indicates a nesting error, but may indicate incorrect\nquoting or escaping.\n\n\"No block delimiter found after quotelike \"%s\"\"\n\"extractquotelike\" or \"extractcodeblock\" found one of the\nquotelike operators \"q\", \"qq\", \"qw\", \"qx\", \"s\", \"tr\" or \"y\" without\na suitable block after it.\n\n\"Did not find leading dereferencer\"\n\"extractvariable\" was expecting one of '$', '@', or '%' at the\nstart of a variable, but didn't find any of them.\n\n\"Bad identifier after dereferencer\"\n\"extractvariable\" found a '$', '@', or '%' indicating a variable,\nbut that character was not followed by a legal Perl identifier.\n\n\"Did not find expected opening bracket at %s\"\n\"extractcodeblock\" failed to find any of the outermost opening\nbrackets that were specified.\n\n\"Improperly nested codeblock at %s\"\nA nested code block was found that started with a delimiter that\nwas specified as being only to be used as an outermost bracket.\n\n\"Missing second block for quotelike \"%s\"\"\n\"extractcodeblock\" or \"extractquotelike\" found one of the\nquotelike operators \"s\", \"tr\" or \"y\" followed by only one block.\n\n\"No match found for opening bracket\"\n\"extractcodeblock\" failed to find a closing bracket to match the\noutermost opening bracket.\n\n\"Did not find opening tag: /%s/\"\n\"extracttagged\" did not find a suitable opening tag (after any\nspecified prefix was removed).\n\n\"Unable to construct closing tag to match: /%s/\"\n\"extracttagged\" matched the specified opening tag and tried to\nmodify the matched text to produce a matching closing tag (because\nnone was specified). It failed to generate the closing tag, almost\ncertainly because the opening tag did not start with a bracket of\nsome kind.\n\n\"Found invalid nested tag: %s\"\n\"extracttagged\" found a nested tag that appeared in the \"reject\"\nlist (and the failure mode was not \"MAX\" or \"PARA\").\n\n\"Found unbalanced nested tag: %s\"\n\"extracttagged\" found a nested opening tag that was not matched by\na corresponding nested closing tag (and the failure mode was not\n\"MAX\" or \"PARA\").\n\n\"Did not find closing tag\"\n\"extracttagged\" reached the end of the text without finding a\nclosing tag to match the original opening tag (and the failure mode\nwas not \"MAX\" or \"PARA\").\n",
                "subsections": []
            },
            "EXPORTS": {
                "content": "The following symbols are, or can be, exported by this module:\n\nDefault Exports\nNone.\n\nOptional Exports\n\"extractdelimited\", \"extractbracketed\", \"extractquotelike\",\n\"extractcodeblock\", \"extractvariable\", \"extracttagged\",\n\"extractmultiple\", \"gendelimitedpat\", \"genextracttagged\",\n\"delimitedpat\".\n\nExport Tags\n\":ALL\"\n\"extractdelimited\", \"extractbracketed\", \"extractquotelike\",\n\"extractcodeblock\", \"extractvariable\", \"extracttagged\",\n\"extractmultiple\", \"gendelimitedpat\", \"genextracttagged\",\n\"delimitedpat\".\n",
                "subsections": []
            },
            "KNOWN BUGS": {
                "content": "See\n<https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=Text-Balanced>.\n",
                "subsections": []
            },
            "FEEDBACK": {
                "content": "Patches, bug reports, suggestions or any other feedback is welcome.\n\nPatches can be sent as GitHub pull requests at\n<https://github.com/steve-m-hay/Text-Balanced/pulls>.\n\nBug reports and suggestions can be made on the CPAN Request Tracker at\n<https://rt.cpan.org/Public/Bug/Report.html?Queue=Text-Balanced>.\n\nCurrently active requests on the CPAN Request Tracker can be viewed at\n<https://rt.cpan.org/Public/Dist/Display.html?Status=Active;Queue=Text-Balanced>.\n\nPlease test this distribution.  See CPAN Testers Reports at\n<https://www.cpantesters.org/> for details of how to get involved.\n\nPrevious test results on CPAN Testers Reports can be viewed at\n<https://www.cpantesters.org/distro/T/Text-Balanced.html>.\n\nPlease rate this distribution on CPAN Ratings at\n<https://cpanratings.perl.org/rate/?distribution=Text-Balanced>.\n",
                "subsections": []
            },
            "AVAILABILITY": {
                "content": "The latest version of this module is available from CPAN (see \"CPAN\" in\nperlmodlib for details) at\n\n<https://metacpan.org/release/Text-Balanced> or\n\n<https://www.cpan.org/authors/id/S/SH/SHAY/> or\n\n<https://www.cpan.org/modules/by-module/Text/>.\n\nThe latest source code is available from GitHub at\n<https://github.com/steve-m-hay/Text-Balanced>.\n",
                "subsections": []
            },
            "INSTALLATION": {
                "content": "See the INSTALL file.\n",
                "subsections": []
            },
            "AUTHOR": {
                "content": "Damian Conway <damian@conway.org <mailto:damian@conway.org>>.\n\nSteve Hay <shay@cpan.org <mailto:shay@cpan.org>> is now maintaining\nText::Balanced as of version 2.03.\n",
                "subsections": []
            },
            "COPYRIGHT": {
                "content": "Copyright (C) 1997-2001 Damian Conway.  All rights reserved.\n\nCopyright (C) 2009 Adam Kennedy.\n\nCopyright (C) 2015, 2020 Steve Hay.  All rights reserved.\n",
                "subsections": []
            },
            "LICENCE": {
                "content": "This module is free software; you can redistribute it and/or modify it\nunder the same terms as Perl itself, i.e. under the terms of either the\nGNU General Public License or the Artistic License, as specified in the\nLICENCE file.\n",
                "subsections": []
            },
            "VERSION": {
                "content": "Version 2.04\n",
                "subsections": []
            },
            "DATE": {
                "content": "11 Dec 2020\n",
                "subsections": []
            },
            "HISTORY": {
                "content": "See the Changes file.\n\nperl v5.34.0                      2026-06-23             Text::Balanced(3perl)",
                "subsections": []
            }
        }
    }
}