AppSurface Search
API Reference

MarkdownSnippets

Type

Program

Source
Method

Main

Task<int> Main(string[] args)

Process entry point that runs the CLI against the current working directory.

Parameters

  • args
    Command-line arguments passed by the host process.

Returns

The process exit code.

Method

RunAsync

Task<int> RunAsync(string[] args, TextWriter standardOut, TextWriter standardError, string currentDirectory, CancellationToken cancellationToken = default)

Runs the Markdown snippet CLI command contract.

Parameters

  • args
    Command-line arguments. The first argument must be generate , verify , --help , or -h . Command options after generate or verify are parsed by MarkdownSnippetCommandOptions.Parse .
  • standardOut
    Destination for help and successful command output.
  • standardError
    Destination for validation and command failure output.
  • currentDirectory
    Working directory used for option defaults. When --repo-root is omitted, this becomes the repository root; when --document is omitted, the default document is Web/ForgeTrust.RazorWire/README.md under that root.
  • cancellationToken
    Cancellation token for file IO.

Returns

0 for success or help, 1 for invalid input or stale snippets.

Remarks

Relative --repo-root values resolve from currentDirectory ; relative --document values resolve from the resolved repository root. Unknown commands, unknown options, missing option values, invalid snippet directives, unsafe paths, and stale generated blocks are reported as 1 with actionable error text rather than escaping as unhandled exceptions.

Method

IsHelp

bool IsHelp(string argument)

Determines whether an argument requests command help.

Parameters

  • argument
    Argument to inspect.

Returns

true for --help or -h .

Type

MarkdownSnippetCommandOptions

Source
Method

Parse

MarkdownSnippetCommandOptions Parse(string[] args, string currentDirectory)

Parses command options into a repository/document request.

Parameters

  • args
    Only --repo-root <path> and --document <path> are supported.
  • currentDirectory
    Current working directory used by omitted or relative --repo-root .

Returns

Parsed options with full repository and document paths.

Exceptions

  • MarkdownSnippetException
    Thrown when an option is unknown or a required option value is missing.

Remarks

The default repository root is currentDirectory . The default document is Web/ForgeTrust.RazorWire/README.md under the resolved repository root. A rooted --document is allowed at parse time but later rejected by generation/verification when it is outside the repository.

Method

ReadRequiredValue

string ReadRequiredValue(string[] args, ref int index, string argument)

Reads the required value immediately following an option name.

Parameters

  • args
    Complete option argument array.
  • index
    Current option index, advanced to the value index on success.
  • argument
    Option name for diagnostics.

Returns

The raw option value.

Exceptions

  • MarkdownSnippetException
    Thrown when the option has no following non-blank value or the next token looks like another option.
Method

ResolvePath

string ResolvePath(string? value, string baseDirectory, string defaultPath)

Resolves a rooted, relative, or omitted path to a full path.

Parameters

  • value
    Optional user-provided path.
  • baseDirectory
    Directory used for relative values.
  • defaultPath
    Path used when value is omitted.

Returns

A canonical full path.

Type

MarkdownSnippetRequest

Source
Method

GetRepositoryRelativeDocumentPath

string GetRepositoryRelativeDocumentPath()

Gets the document path relative to RepositoryRoot with forward slashes for stable diagnostics and CLI output.

Returns

The repository-relative document path.

Remarks

Request validation ensures the document stays under the repository root before generation or verification uses this value for user-facing messages.

Type

MarkdownSnippetGenerator

Source
Method

GenerateToFileAsync

Task GenerateToFileAsync(MarkdownSnippetRequest request, CancellationToken cancellationToken = default)

Generates the canonical Markdown document and writes it back to disk.

Parameters

  • request
    Repository root and Markdown document to update.
  • cancellationToken
    Cancellation token for file IO.

Exceptions

  • MarkdownSnippetException
    Thrown when the repository/document path is invalid or snippet extraction fails.
Method

GenerateAsync

Task<string> GenerateAsync(MarkdownSnippetRequest request, CancellationToken cancellationToken = default)

Generates the canonical Markdown text for all managed snippet blocks.

Parameters

  • request
    Repository root and Markdown document to read.
  • cancellationToken
    Cancellation token for file IO.

Returns

The rewritten Markdown document with \n line endings.

Exceptions

  • MarkdownSnippetException
    Thrown when the document has no managed blocks, a block is malformed, a source path escapes the repository, markers are missing or duplicated, or extracted snippet content is empty.

Remarks

Generation is the mutating workflow used by maintainers after source sample changes. It normalizes document line endings and replaces only managed blocks outside existing Markdown code fences.

Method

VerifyAsync

Task VerifyAsync(MarkdownSnippetRequest request, CancellationToken cancellationToken = default)

Verifies that the checked-in Markdown already matches generated output.

Parameters

  • request
    Repository root and Markdown document to verify.
  • cancellationToken
    Cancellation token for file IO.

Exceptions

  • MarkdownSnippetException
    Thrown when validation fails or the checked-in Markdown is stale.

Remarks

Verification is the CI workflow. It compares canonical generated text to the current document after normalizing line endings, so CRLF checkouts do not fail solely because of platform line-ending conversion.

Method

ValidateRequest

void ValidateRequest(MarkdownSnippetRequest request)

Validates repository/document existence and document containment.

Parameters

  • request
    Request to validate before source files are read.

Exceptions

  • MarkdownSnippetException
    Thrown when the repository root is missing, the document is missing, or the document is outside the repository root.
Type

MarkdownSnippetRewriter

Source

Rewrites managed <!-- appsurface:snippet ... --> blocks in Markdown.

Remarks

A managed block must contain an opening directive, a generated fenced code block, and the exact closing directive <!-- /appsurface:snippet --> . Directives are ignored inside existing Markdown code fences, and the managed closing directive is only recognized outside the generated block's code fence. Supported attributes are id , file , marker , lang , and optional dedent . Attributes must use quoted name="value" syntax. file is repository-relative; rooted paths and .. escapes fail before source files are read. dedent defaults to true , which removes common indentation from extracted non-blank source lines.

Method

Rewrite

string Rewrite(MarkdownSnippetRequest request, string markdown)

Rewrites managed snippet blocks and returns canonical Markdown.

Parameters

  • request
    Repository root and document path used for path resolution and diagnostics.
  • markdown
    Original Markdown text.

Returns

Markdown with generated blocks rendered using \n line endings.

Exceptions

  • MarkdownSnippetException
    Thrown when no managed blocks are present, a directive is malformed, a source file is unsafe or missing, markers are invalid, or a block is not closed.
Method

ParseBlock

MarkdownSnippetBlock ParseBlock(MarkdownSnippetRequest request, string[] lines, ref int index)

Parses one managed snippet block and extracts its replacement content.

Parameters

  • request
    Repository/document request for path resolution and diagnostics.
  • lines
    Normalized Markdown lines.
  • index
    Current opening-line index, advanced to the managed closing line.

Returns

The parsed block with source-backed content.

Exceptions

  • MarkdownSnippetException
    Thrown when attributes are invalid, the source file path is unsafe, source markers are invalid, or the managed block is missing its closing directive.
Method

ParseAttributes

Dictionary<string, string> ParseAttributes(string openingLine, string documentPath, int lineNumber)

Parses and validates quoted directive attributes from an opening line.

Exceptions

  • MarkdownSnippetException
    Thrown for missing --> , duplicate attributes, unsupported attribute syntax, empty attribute sets, or unknown attribute names.
Method

ValidateAttributeNames

void ValidateAttributeNames(IReadOnlyDictionary<string, string> attributes, string documentPath, int lineNumber)

Ensures all directive attribute names are supported by the snippet contract.

Parameters

  • attributes
    Parsed directive attributes.
  • documentPath
    Repository-relative document path for diagnostics.
  • lineNumber
    One-based directive line number.

Exceptions

  • MarkdownSnippetException
    Thrown when any attribute name is unknown.
Method

ReadRequiredAttribute

string ReadRequiredAttribute(IReadOnlyDictionary<string, string> attributes, string name, MarkdownSnippetRequest request, int lineNumber)

Reads a required directive attribute and trims its value.

Exceptions

  • MarkdownSnippetException
    Thrown when the attribute is missing or blank.
Method

ReadBooleanAttribute

bool ReadBooleanAttribute(IReadOnlyDictionary<string, string> attributes, string name, bool defaultValue, MarkdownSnippetRequest request, int lineNumber)

Reads an optional boolean directive attribute.

Exceptions

  • MarkdownSnippetException
    Thrown when the value is not a valid boolean.

Remarks

dedent uses this helper with a default of true . Only true and false values accepted by the platform boolean parser are valid.

Method

ValidateId

void ValidateId(string value, string description, MarkdownSnippetRequest request, int lineNumber)

Validates a snippet id or source marker id.

Parameters

  • value
    Candidate id.
  • description
    Diagnostic description of the id role.
  • request
    Request used to name the document in diagnostics.
  • lineNumber
    One-based directive line number.

Exceptions

  • MarkdownSnippetException
    Thrown when the id uses unsupported characters.
Method

ValidateLanguage

void ValidateLanguage(string language, MarkdownSnippetRequest request, int lineNumber)

Validates the Markdown code fence language token.

Parameters

  • language
    Candidate language token.
  • request
    Request used to name the document in diagnostics.
  • lineNumber
    One-based directive line number.

Exceptions

  • MarkdownSnippetException
    Thrown when the language token contains unsupported characters.
Method

FindClosingLine

int FindClosingLine(string[] lines, int startIndex, MarkdownSnippetRequest request, string id)

Finds the managed block closing directive while ignoring text inside Markdown fences.

Parameters

  • lines
    Normalized Markdown lines.
  • startIndex
    Line index immediately after the opening directive.
  • request
    Request used to name the document in diagnostics.
  • id
    Snippet id for diagnostics.

Returns

The line index containing <!-- /appsurface:snippet --> .

Exceptions

  • MarkdownSnippetException
    Thrown when no compatible closing directive is found.
Method

AppendLine

void AppendLine(StringBuilder builder, string line, int index, int lineCount)

Appends one original Markdown line while preserving the canonical final newline shape.

Parameters

  • builder
    Destination builder.
  • line
    Line text without its newline.
  • index
    Current line index.
  • lineCount
    Total line count.
Type

MarkdownCodeFence

Source
Method

TryParse

MarkdownCodeFence? TryParse(string trimmedLine)

Parses a Markdown code fence opener or closer.

Parameters

  • trimmedLine
    Line trimmed of surrounding whitespace.

Returns

A fence when the line begins with at least three backticks or tildes; otherwise null .

Method

IsClosedBy

bool IsClosedBy(string trimmedLine)

Determines whether a trimmed line closes this fence.

Parameters

  • trimmedLine
    Line trimmed of surrounding whitespace.

Returns

true when the line uses the same fence character, has length at least as long as the opener, and contains only that fence character.

Type

MarkdownSnippetBlock

Source
Method

Render

string Render()

Renders a managed block using an automatically sized backtick fence.

Returns

The complete managed block with \n line endings.

Remarks

The fence is one backtick longer than the longest backtick run in the content, with a minimum length of three, so nested Markdown examples stay literal inside the generated block.

Type

MarkdownSnippetSourceExtractor

Source

Extracts source snippets between exact documentation marker lines.

Remarks

Supported marker forms are delegated to MarkdownSnippetMarker : C# line comments, Razor comments, and HTML comments. A marker pair must be unique, ordered as :start then :end , and contain at least one non-blank line. Marker-like text in strings or inline comments is ignored because markers must occupy the whole trimmed line. When dedent is enabled, common leading spaces or tabs across non-blank snippet lines are removed and surrounding blank lines are trimmed.

Method

Extract

string Extract(string source, string markerId, string sourcePath, bool dedent)

Extracts and optionally dedents the snippet for a marker id.

Parameters

  • source
    Source file text.
  • markerId
    Marker id without :start or :end .
  • sourcePath
    Repository-relative source path for diagnostics.
  • dedent
    Whether to remove common indentation from extracted lines.

Returns

Extracted snippet content with \n line endings.

Exceptions

  • MarkdownSnippetException
    Thrown when start/end markers are missing, duplicated, reversed, or enclose only blank content.
Method

Dedent

string Dedent(string[] lines)

Removes common indentation from snippet lines.

Parameters

  • lines
    Snippet lines between markers.

Returns

Dedented snippet text with surrounding blank lines trimmed.

Remarks

Only non-blank lines contribute to the minimum indent. Indentation counts both spaces and tabs as one character because snippets preserve source text rather than reformatting it.

Method

CountIndent

int CountIndent(string line)

Counts leading spaces and tabs on a source line.

Parameters

  • line
    Line to inspect.

Returns

The number of leading indentation characters.

Type

MarkdownSnippetMarker

Source
Method

IsValidId

bool IsValidId(string value)

Determines whether a snippet id is safe for marker and directive use.

Parameters

  • value
    Candidate id.

Returns

true when the id starts with an ASCII letter or digit and then uses only letters, digits, _ , - , or . .

Method

TryParse

MarkdownSnippetMarkerKind TryParse(string line, string markerId)

Parses a whole-line source snippet marker.

Parameters

  • line
    Source line to inspect. A UTF-8 BOM on the first line is ignored.
  • markerId
    Expected marker id.

Returns

The marker kind, or MarkdownSnippetMarkerKind.None .

Remarks

Valid marker forms are exactly // docs:snippet id:start , @* docs:snippet id:start *@ , and <!-- docs:snippet id:start --> , with matching :end variants. Whitespace may surround the whole line but not the inner marker text.

Method

IsMarker

bool IsMarker(string trimmed, string markerId, string markerKind)

Matches one exact marker form for a marker id and kind.

Parameters

  • trimmed
    Source line trimmed of surrounding whitespace and any leading BOM.
  • markerId
    Expected marker id.
  • markerKind
    Expected marker kind, usually start or end .

Returns

true when the line is an exact supported comment marker.

Type

MarkdownFence

Source
Method

Create

string Create(string content)

Creates a Markdown backtick fence that safely contains the supplied content.

Parameters

  • content
    Snippet content to wrap.

Returns

At least three backticks, or one more than the longest run in content .

Type

MarkdownSnippetPath

Source
Method

ResolveRepositoryFilePath

string ResolveRepositoryFilePath(string repositoryRoot, string repositoryRelativePath, string description)

Resolves a repository-relative source file path and enforces repository containment.

Parameters

  • repositoryRoot
    Repository root directory.
  • repositoryRelativePath
    Source path from a snippet directive.
  • description
    Human-readable path description for diagnostics.

Returns

The full source file path.

Exceptions

  • MarkdownSnippetException
    Thrown when the path is rooted, escapes the repository root, or points to a missing file.

Remarks

Snippet file attributes must be repository-relative so generated documentation is portable across machines and CI checkouts.

Method

TryGetRepositoryRelativePath

bool TryGetRepositoryRelativePath(string repositoryRoot, string path, out string relativePath)

Converts a path to a repository-relative path when it is safely contained in the repository.

Parameters

  • repositoryRoot
    Repository root directory.
  • path
    Candidate full or relative path.
  • relativePath
    Repository-relative path with forward slashes when successful.

Returns

true when path is inside repositoryRoot , is not the root itself, and does not cross a reparse-point segment.

Remarks

The containment check starts with lexical path normalization, then walks the repository-relative path segments and rejects symlinks or other reparse points before file IO can follow them outside the repository.

Method

ContainsReparsePointSegment

bool ContainsReparsePointSegment(string fullRoot, string relativePath)

Determines whether any existing path segment below the repository root is a reparse point.

Parameters

  • fullRoot
    Canonical repository root path.
  • relativePath
    Repository-relative candidate path with forward slashes.

Returns

true when an inspected segment is a symlink or other reparse point.