Top Method Summary
Options Name Purpose
Append (character) Appends the given value to the output buffer
AppendCodeSpan (longchar) Appends the given value as a code span
AppendEscaped (longchar) Appends the given value with the Markdown special characters escaped
AppendLongchar (longchar) Appends the given longchar value to the output
AppendMarkup (character) Appends the given markup to the output buffer
AppendUrl (longchar) Appends the given value as the destination of a link
INTEGER BacktickFenceLength (longchar, integer) Returns the number of backticks a fence around the given value needs
BeginContent () Writes the separators that are pending in front of the content that is about to be written
CHARACTER BlockPrefix (TextDocument) Returns the line prefix of the block the given document is positioned on
LONGCHAR BuildCodeContent (TextDocument) Returns the literal content of the code block the given document is positioned on
CloseTable () Closes the table that is open at the end of the document
LOGICAL CloseTableCell (TextDocument) Closes the table cell and the table row that are open when the block that is about to be written belongs to another one
INTEGER CopyBytes (memptr, memptr, integer, integer, integer) Copies the given byte range from the source into the target
Flush () Flushes the output buffer into the longchar result
CHARACTER ListDelimiter (TextDocument) Returns the delimiter of the marker of the list item the given document is positioned on
LOGICAL NeedsCodePadding (longchar) Returns if the given code span value has to be padded with a blank at each end
LOGICAL NeedsEscape (integer) Returns if the given byte has to be escaped with a backslash
OpenTableCell (TextDocument) Opens the table row and the table cell of the block that is about to be written
ResetState () Resets the writer state so that an instance could be reused
INTEGER ScanDigits (memptr, integer, integer) Returns the position behind the run of digits that begins at the given position
LONGCHAR Write (TextDocument) Writes the given TextDocument out as Markdown
WriteBlock (TextDocument) Writes one block of the document
WriteCodeBlock (TextDocument) Writes a code block as a fenced code block
WriteDelimiterRowAfterHeader () Writes the delimiter row of the table that is open when the row that was just closed was its first one
WriteImageRun (TextDocument) Writes an embedded image as a data URI
WriteRuns (TextDocument) Writes the runs of the block the given document is positioned on
WriteTextRun (TextDocument) Writes a single text run with the markup of its formatting

Top Constructor Summary
Options Name Purpose
MarkdownWriter () Creates a new MarkdownWriter instance


Method Detail
Top

Append (character)

Purpose: Appends the given value to the output buffer
Notes: Flushes the buffer into the result first when the value would
take it past the CHARACTER limit

Parameters:
pcValue CHARACTER
The value to append
Top

AppendCodeSpan (longchar)

Purpose: Appends the given value as a code span
Notes: The content of a code span is literal, so a backtick in it
cannot be escaped - the fence is made one backtick longer
than the longest run of backticks in the value instead. A
value that begins or ends with a backtick or a blank is
padded with one blank at each end, which the reader strips
again, as CommonMark asks for.

Parameters:
plcValue LONGCHAR
The value to append
Top

AppendEscaped (longchar)

Purpose: Appends the given value with the Markdown special characters
escaped
Notes: The escaping works on the UTF-8 bytes: every character
Markdown gives a meaning to is ASCII, and an ASCII byte never
occurs inside a multi byte UTF-8 sequence, so scanning bytes
cannot cut a character in half. An ABL string operation could
not do this at all - it would collate the value through
-cpinternal.
The characters that only open a block are escaped at the start
of a line only, which is where they would be read as one.
Leading whitespace keeps that state, so that an indented line
is protected as well.

Parameters:
plcValue LONGCHAR
The value to append
Top

AppendLongchar (longchar)

Purpose: Appends the given longchar value to the output
Notes: The text of a run and the data URI of an image can be longer
than the CHARACTER limit on their own, and the text can carry
characters the session code page does not know, so the buffer
is flushed and the value is appended to the LONGCHAR result

Parameters:
plcValue LONGCHAR
The value to append
Top

AppendMarkup (character)

Purpose: Appends the given markup to the output buffer
Notes: Markup is never the start of a line any more - what follows it
cannot open a block

Parameters:
pcValue CHARACTER
The markup to append
Top

AppendUrl (longchar)

Purpose: Appends the given value as the destination of a link
Notes: A destination holding whitespace is written in angle brackets,
which is the only form that can carry it; the characters that
would end the destination are escaped in both forms

Parameters:
plcValue LONGCHAR
The destination to append
Top

INTEGER BacktickFenceLength (longchar, integer)

Purpose: Returns the number of backticks a fence around the given value
needs
Notes: One more than the longest run of backticks the value carries,
and never less than the given minimum

Parameters:
plcValue LONGCHAR
The value the fence goes around
piMinimum INTEGER
The smallest fence that is acceptable
Returns INTEGER
The number of backticks of the fence
Top

BeginContent ()

Purpose: Writes the separators that are pending in front of the content
that is about to be written
Notes: Called by the two methods every piece of content goes through,
so that a separator which nothing follows is never written

Top

CHARACTER BlockPrefix (TextDocument)

Purpose: Returns the line prefix of the block the given document is
positioned on
Notes: A heading carries one number sign per level, a list item two
blanks per nesting level and its marker. A numbered item
carries its own number (SCL-5858): the reader takes the number
of the first item of a list as its start number, and the
numbers of the items behind it are the ones a reader of the
Markdown source expects to see.

Parameters:
poDocument Consultingwerk.Util.DocumentConverter.TextDocument
The TextDocument positioned on the block to write
Returns CHARACTER
The character with the prefix, without the blank that separates it from the content
Top

LONGCHAR BuildCodeContent (TextDocument)

Purpose: Returns the literal content of the code block the given
document is positioned on
Notes: A line break run becomes a line ending, so that the lines of
the code block end up inside the fence

Parameters:
poDocument Consultingwerk.Util.DocumentConverter.TextDocument
The TextDocument positioned on the code block to write
Returns LONGCHAR
The longchar with the content, fixed to UTF-8
Top

CloseTable ()

Purpose: Closes the table that is open at the end of the document
Notes:

Top

LOGICAL CloseTableCell (TextDocument)

Purpose: Closes the table cell and the table row that are open when the
block that is about to be written belongs to another one
Notes: Returns whether the block continues the table that is open. A
further cell or a further row is separated from what came
before it by the pipes and the line ending this method and
OpenTableCell write, not by the blank line that separates two
blocks - which is why the caller asks before writing that
blank line.

Parameters:
poDocument Consultingwerk.Util.DocumentConverter.TextDocument
The TextDocument positioned on the block to write
Returns LOGICAL
TRUE when the block continues the table that is open
Top

INTEGER CopyBytes (memptr, memptr, integer, integer, integer)

Purpose: Copies the given byte range from the source into the target
Notes:

Parameters:
pmSource MEMPTR
The memptr to copy from
pmTarget MEMPTR
The memptr to copy to
piFrom INTEGER
The position of the first byte to copy
piTo INTEGER
The position of the last byte to copy
piOut INTEGER
The position in the target to copy to
Returns INTEGER
The position in the target behind what was copied
Top

Flush ()

Purpose: Flushes the output buffer into the longchar result
Notes:

Top

CHARACTER ListDelimiter (TextDocument)

Purpose: Returns the delimiter of the marker of the list item the given
document is positioned on
Notes: The hyphen for a bulleted item. An ordered item takes the
period, and the closing parenthesis only where its list
directly follows another ordered list on the same level - the
second list of two adjacent ones, which CommonMark would
otherwise read as one list, and the third takes the period
again. The model tells where a list starts
(TextDocument:StartsNewList); StartsNewList); the numbering type cannot be
expressed and is dropped (SCL-5858).

Parameters:
poDocument Consultingwerk.Util.DocumentConverter.TextDocument
The TextDocument positioned on the list item to write
Returns CHARACTER
The character with the delimiter
Top

LOGICAL NeedsCodePadding (longchar)

Purpose: Returns if the given code span value has to be padded with a
blank at each end
Notes: CommonMark strips one leading and one trailing blank from a
code span when it carries both, which is how a value that
begins or ends with a backtick or a blank is written

Parameters:
plcValue LONGCHAR
The value of the code span
Returns LOGICAL
TRUE when the value needs the padding
Top

LOGICAL NeedsEscape (integer)

Purpose: Returns if the given byte has to be escaped with a backslash
Notes: The inline markup characters are escaped wherever they stand;
the number sign, the two bullet markers and the block quote
marker only at the start of a line

Parameters:
piByte INTEGER
The byte value to test
Returns LOGICAL
TRUE when the byte needs a backslash in front of it
Top

OpenTableCell (TextDocument)

Purpose: Opens the table row and the table cell of the block that is
about to be written
Notes:

Parameters:
poDocument Consultingwerk.Util.DocumentConverter.TextDocument
The TextDocument positioned on the block to write
Top

ResetState ()

Purpose: Resets the writer state so that an instance could be reused
Notes:

Top

INTEGER ScanDigits (memptr, integer, integer)

Purpose: Returns the position behind the run of digits that begins at
the given position
Notes: Returns the given position when there is no digit there

Parameters:
pmSource MEMPTR
The memptr to scan
piFrom INTEGER
The position to start scanning at
piTo INTEGER
The position of the last byte that may be scanned
Returns INTEGER
The position of the first byte that is not a digit
Top

LONGCHAR Write (TextDocument)

Purpose: Writes the given TextDocument out as Markdown
Notes: An empty document yields an empty value, never the unknown
value, and the result never ends with a line ending

Parameters:
poDocument Consultingwerk.Util.DocumentConverter.TextDocument
The TextDocument to write out
Returns LONGCHAR
The longchar with the Markdown document
Top

WriteBlock (TextDocument)

Purpose: Writes one block of the document
Notes: The prefix of a heading and of a list item is written first;
the blank behind it is only written when the block carries
content, so that an empty heading does not end in a blank

Parameters:
poDocument Consultingwerk.Util.DocumentConverter.TextDocument
The TextDocument positioned on the block to write
Top

WriteCodeBlock (TextDocument)

Purpose: Writes a code block as a fenced code block
Notes: The content of a code block is literal, so neither the
character formatting of its runs nor any escaping applies to
it. An embedded image cannot be written inside a fence and is
dropped.

Parameters:
poDocument Consultingwerk.Util.DocumentConverter.TextDocument
The TextDocument positioned on the code block to write
Top

WriteDelimiterRowAfterHeader ()

Purpose: Writes the delimiter row of the table that is open when the
row that was just closed was its first one
Notes: A pipe table has to carry a delimiter row behind its first
row - without it the lines are not a table at all - so the
first row of every table becomes its header row. A table whose
first row was not a header row in the model therefore gains
one on the way through Markdown, and comes back unchanged from
the second pass on.

Top

WriteImageRun (TextDocument)

Purpose: Writes an embedded image as a data URI
Notes: The alternative text is always the word image, so that
reading the document back and writing it out again yields
the same bytes

Parameters:
poDocument Consultingwerk.Util.DocumentConverter.TextDocument
The TextDocument positioned on the image run to write
Top

WriteRuns (TextDocument)

Purpose: Writes the runs of the block the given document is positioned on
Notes: A line break becomes a hard line break in a paragraph and a
blank in a heading or a list item, which are single line
constructs

Parameters:
poDocument Consultingwerk.Util.DocumentConverter.TextDocument
The TextDocument positioned on the block to write
Top

WriteTextRun (TextDocument)

Purpose: Writes a single text run with the markup of its formatting
Notes: The hyperlink is the outermost construct, then strong,
emphasis, strikethrough and the code span innermost - the
same nesting order the HTML writer uses

Parameters:
poDocument Consultingwerk.Util.DocumentConverter.TextDocument
The TextDocument positioned on the run to write


Constructor Detail
Top

MarkdownWriter ()

Purpose: Creates a new MarkdownWriter instance
Notes: The result is fixed to UTF-8 here rather than in Write,
because FIX-CODEPAGE can only be applied to a LONGCHAR that
has no value yet



©2006-2026 Consultingwerk Ltd.         info@consultingwerk.de         http://www.consultingwerk.de       19.09.2026 10:19:20