digraph blockstate { /* rankdir=LR; */ node [shape = circle, fontsize = 18]; edge [fontsize = 18]; init [label = "", shape=none, height = .0, width = .0]; start; emptyBlock [label = "empty block"]; nonEmptyBlock [label = "non-empty block"]; lineBreakTag [label = "line break tag"]; atLeastTwoLineBreakTags [label = ">=2 line break tags"]; emptyBlockWithAtLeastTwoPreviousLineBreakTags [label = "empty block w/ >=2 prev line break tags"]; beginListItem [label = "begin list item"]; endListItem [label = "end list item"]; listItemContent [label = "list item content"]; lineBreakTagInListItemContent [label = "line break tag in list item content"]; atLeastTwoLineBreakTagsInListItemContent [label = ">= 2 line break tags in list item content"]; preformattedStart [label = "preformatted start"]; preformattedEmptyBlock [label = "preformatted empty block"]; preformattedNonEmptyBlock [label = "preformatted non-empty block"]; preformattedLineBreak [label = "preformatted line break"]; preformattedAtLeastTwoLineBreaks [label = "preformatted >=2 line breaks"]; afterPreStartTag [label = "after
 start tag"];
	afterPreStartTagWithLeadingWhitespace [label = "after 
 start tag w/ leading whitespace"];
	preformattedNonEmptyBlockWithTrailingWhitespace [label = "preformatted non-empty block w/ trailing whitespace"];
	preformattedEmptyBlockWithLeadingWhitespace [label = "preformatted empty block w/ leading whitespace"];

	init -> start;
	start -> start [label = "whitespace (skip)\n
(skip)\n
\nstart/end block"]; start -> nonEmptyBlock [label = "non-whitespace"]; start -> preformattedStart [label = "
 (depth = 1)"];
	start -> beginListItem [label = "
  • "]; nonEmptyBlock -> nonEmptyBlock [label = "non-newline"]; nonEmptyBlock -> emptyBlock [label = "start/end block"]; nonEmptyBlock -> lineBreakTag [label = "
    or \\n (append to tmp)"]; nonEmptyBlock -> beginListItem [label = "
  • "]; nonEmptyBlock -> endListItem [label = "
  • "]; emptyBlock -> nonEmptyBlock [label = "non-whitespace (block break)"]; emptyBlock -> emptyBlock [label = "whitespace (skip)\n
    \n
    \nstart/end block"]; emptyBlock -> afterPreStartTag [label = "
     (depth = 1)"];
    	emptyBlock -> beginListItem [label = "
  • "]; emptyBlock -> endListItem [label = "
  • "]; lineBreakTag -> lineBreakTag [label = "whitespace (append to tmp)"]; lineBreakTag -> atLeastTwoLineBreakTags [label = "
    or \\n (append to tmp)"]; lineBreakTag -> emptyBlock [label = "start/end block (clear tmp)"]; lineBreakTag -> nonEmptyBlock [label = "non-whitespace (emit tmp)"]; atLeastTwoLineBreakTags -> atLeastTwoLineBreakTags [label = "whitespace or
    (append to tmp)"]; atLeastTwoLineBreakTags -> nonEmptyBlock [label = "non-whitespace (emit tmp)"]; atLeastTwoLineBreakTags -> emptyBlockWithAtLeastTwoPreviousLineBreakTags [label = "start/end block"]; emptyBlockWithAtLeastTwoPreviousLineBreakTags -> emptyBlockWithAtLeastTwoPreviousLineBreakTags [label = "whitespace (skip)\n
    \n
    \nstart/end block"]; emptyBlockWithAtLeastTwoPreviousLineBreakTags -> nonEmptyBlock [label = "non-whitespace (emit tmp)"]; emptyBlockWithAtLeastTwoPreviousLineBreakTags -> afterPreStartTagWithLeadingWhitespace [label = "
     (depth = 1)"];
    	beginListItem -> beginListItem [label = "
  • \nwhitespace (skip)\n
    \nstart/end block"]; beginListItem -> listItemContent [label = "non-whitespace"]; beginListItem -> endListItem [label = "
  • "]; beginListItem -> afterPreStartTagWithLeadingWhitespace [label = "
    "];
    	endListItem -> endListItem [label = "whitespace (skip)\n"];
    	endListItem -> beginListItem [label = "
  • (line break)"]; endListItem -> emptyBlock [label = "start/end block"]; endListItem -> listItemContent [label = "non-whitespace (line break, indent)"]; endListItem -> lineBreakTagInListItemContent [label = "
    (append to tmp)"]; listItemContent -> listItemContent [label = "non-whitespace"]; listItemContent -> beginListItem [label = "
  • (line break)"]; listItemContent -> lineBreakTagInListItemContent [label = "
    (append to tmp)"]; listItemContent -> emptyBlock [label = "start/end block"]; listItemContent -> endListItem [label = "
  • "]; lineBreakTagInListItemContent -> lineBreakTagInListItemContent [label = "whitespace (append to tmp)"]; lineBreakTagInListItemContent -> emptyBlock [label = "start/end block (clear tmp)"]; lineBreakTagInListItemContent -> beginListItem [label = "
  • (emit tmp, line break)"]; lineBreakTagInListItemContent -> listItemContent [label = "non-whitespace (emit tmp)"]; lineBreakTagInListItemContent -> atLeastTwoLineBreakTagsInListItemContent [label = "
    or \\n (append to tmp)"]; lineBreakTagInListItemContent -> endListItem [label = "
  • (clear tmp)"]; atLeastTwoLineBreakTagsInListItemContent -> atLeastTwoLineBreakTagsInListItemContent [label = "whitespace or
    (append to tmp)"]; atLeastTwoLineBreakTagsInListItemContent -> beginListItem [label = "
  • (emit tmp, line break)"]; atLeastTwoLineBreakTagsInListItemContent -> emptyBlockWithAtLeastTwoPreviousLineBreakTags [label = "start/end block"]; atLeastTwoLineBreakTagsInListItemContent -> listItemContent [label = "non-whitespace (emit tmp)"]; atLeastTwoLineBreakTagsInListItemContent -> endListItem [label = "
  • (clear tmp)"]; afterPreStartTag -> preformattedLineBreak [label = "
    (append to tmp, append block break to tmp)"]; afterPreStartTag -> preformattedNonEmptyBlock [label = "non \\n (block break)"]; afterPreStartTag -> preformattedEmptyBlock [label = "\\n (skip)\nstart/end block"]; preformattedLineBreak -> preformattedNonEmptyBlock [label = "non-whitespace (emit tmp)"]; preformattedLineBreak -> preformattedNonEmptyBlockWithTrailingWhitespace [label = "other whitespace (append to tmp)"]; preformattedLineBreak -> preformattedAtLeastTwoLineBreaks [label = "\\n or
    (append to tmp)"]; preformattedAtLeastTwoLineBreaks -> preformattedAtLeastTwoLineBreaks [label = "\\n or
    (append to tmp)"]; preformattedAtLeastTwoLineBreaks -> preformattedNonEmptyBlock [label = "non \\n or
    (emit tmp)"]; preformattedAtLeastTwoLineBreaks -> preformattedEmptyBlockWithLeadingWhitespace [label = "start/end block"]; preformattedEmptyBlockWithLeadingWhitespace -> preformattedEmptyBlockWithLeadingWhitespace [label = "whitespace (append to tmp)\nstart/end block\n
    if depth>1&&tmp.count>=2 (depth - 1, remove 1 from tmp)"]; preformattedEmptyBlockWithLeadingWhitespace -> preformattedLineBreak [label = "\\n or
    (append to tmp)"]; preformattedEmptyBlockWithLeadingWhitespace -> afterPreStartTagWithLeadingWhitespace [label = "
     (depth + 1)"];
    	preformattedEmptyBlockWithLeadingWhitespace -> preformattedEmptyBlock [label = "
    if depth>1&&tmp.count<2 (depth - 1, remove 1 from tmp)"]; preformattedEmptyBlockWithLeadingWhitespace -> emptyBlock [label = "
    if depth<=1 (clear tmp)"]; preformattedEmptyBlock -> preformattedEmptyBlock [label = "start/end block\n
    if depth>1 (depth - 1)"]; preformattedEmptyBlock -> afterPreStartTag [label = "
     (depth + 1"];
    	preformattedEmptyBlock -> preformattedNonEmptyBlock [label = "non-whitespace (block break)"];
    	preformattedEmptyBlock -> preformattedEmptyBlockWithLeadingWhitespace [label = "whitespace (append to tmp)"];
    	preformattedEmptyBlock -> preformattedLineBreak [label = "
    (append to tmp)"]; preformattedNonEmptyBlock -> preformattedNonEmptyBlock [label = "non-whitespace"]; preformattedNonEmptyBlock -> preformattedLineBreak [label = "\\n or
    (append to tmp)"]; preformattedNonEmptyBlock -> preformattedNonEmptyBlockWithTrailingWhitespace [label = "other whitespace (append to tmp)"]; preformattedNonEmptyBlock -> preformattedEmptyBlock [label = "start/end block"]; preformattedNonEmptyBlockWithTrailingWhitespace -> preformattedNonEmptyBlockWithTrailingWhitespace [label = "whitespace (append to tmp)"]; preformattedNonEmptyBlockWithTrailingWhitespace -> preformattedNonEmptyBlock [label = "non-whitespace (emit tmp)"]; preformattedNonEmptyBlockWithTrailingWhitespace -> preformattedLineBreak [label = "\\n or
    (append to tmp)"]; preformattedNonEmptyBlockWithTrailingWhitespace -> preformattedEmptyBlockWithLeadingWhitespace [label = "start/end block (append block break to tmp)"]; afterPreStartTagWithLeadingWhitespace -> preformattedNonEmptyBlock [label = "non-whitespace (emit tmp)"]; afterPreStartTagWithLeadingWhitespace -> preformattedEmptyBlockWithLeadingWhitespace [label = "\\n (skip)\nother whitespace (append to tmp)\n
    (append to tmp)\nstart/end block"]; preformattedStart -> preformattedStart [label = "
     (depth + 1)\n
    if depth>1 (depth - 1)\n\\n or
    (skip)\nstart/end block"]; preformattedStart -> start [label = "
    if depth<=1"]; preformattedStart -> preformattedNonEmptyBlock [label = "non \\n"]; }