Skip to content

QWK.NET ‐ Backtick‐Escaped ANSI

Agent 57951 edited this page Jan 19, 2026 · 1 revision

Backtick-Escaped ANSI Codes: Architectural Decision

QWK.NET detects standard ANSI CSI sequences (ESC followed by '[').

BBS-Specific Encoding Conventions

Many BBS systems used alternative characters to represent ANSI codes in message text, such as:

  • Backtick: `[36m instead of ESC[36m
  • Caret: ^[[36m instead of ESC[36m
  • Other variants specific to BBS software

These conventions are not detected by QWK.NET. They are presentation-layer concerns that belong in viewing/rendering software, not in the format parser.

For Application Developers

If your application needs to detect or render BBS-specific ANSI conventions:

  1. Use QWK.NET to extract message text
  2. Implement your own detection for the conventions you need
  3. Convert or render as appropriate for your use case

Example:

var message = packet.Messages[0];
string messageText = message.Body.RawText;

// Library detection (standard ANSI only)
bool hasStandardAnsi = AnsiEscapeDetector.ContainsAnsiEscapes(
    Encoding.GetEncoding(437).GetBytes(messageText)
);

// Your application detection (BBS conventions)
bool hasBacktickAnsi = messageText.Contains("`[");
bool hasCaretAnsi = messageText.Contains("^[");

// Your application rendering
if (hasBacktickAnsi)
{
    messageText = messageText.Replace("`[", "\x1B[");
}

Decision

Backtick-escaped ANSI detection inside message bodies and other locations is OUT OF SCOPE for QWK.NET library.

This functionality belongs in viewing/presentation software that consumes the library, not in the core library itself.


Rationale

1. Architectural Boundary Violation

The library's purpose is byte-accurate QWK format parsing, not interpretation of content:

IN SCOPE:

  • Parse QWK packet structure
  • Extract message headers and bodies
  • Detect properties defined by QWK specification
  • Report objective byte-level characteristics

OUT OF SCOPE:

  • Interpret message content semantics
  • Render or display messages
  • Convert between encoding conventions
  • Implement BBS-specific presentation logic

Backtick-escaped ANSI is a presentation convention, not a format characteristic.

2. Specification Compliance

QWK Specification Position:

  • Defines message structure (headers, bodies, blocks)
  • Specifies byte 0xE3 as line terminator
  • Does NOT define ANSI handling
  • Does NOT mention backtick substitution

Standard ANSI CSI Sequences:

  • Defined as ESC (0x1B) followed by '['
  • Backtick (0x60) is NOT ESC
  • Detection of backtick-bracket is detecting a different pattern

Conclusion: Detecting backtick-escaped codes means detecting something that:

  1. Is not in the QWK specification
  2. Is not standard ANSI
  3. Is a BBS-specific presentation convention

3. Byte Fidelity Principle

The library's core principle is byte-accurate preservation:

Stored bytes:  60 5B 33 36 6D
Real meaning:  Backtick, '[', '3', '6', 'm'
Library view:  Exactly that - five ASCII characters

Treating backtick as "escaped ESC" requires semantic interpretation beyond byte values. This violates the byte fidelity principle.

4. Separation of Concerns

Library Layer (QWK.NET):

  • Parses QWK packets
  • Extracts structured data
  • Preserves byte content
  • Reports objective properties

Application Layer (Viewer/Reader):

  • Interprets content for display
  • Handles presentation conventions
  • Applies rendering logic
  • Makes semantic decisions

Example analogy:

  • An XML parser doesn't interpret HTML entity references
  • A JSON parser doesn't handle application-specific encoding
  • An HTTP library doesn't parse HTML content

Similarly, QWK.NET shouldn't interpret BBS presentation conventions.

5. Scope Creep Risk

If we add backtick-escaped ANSI detection, where do we stop?

Other BBS conventions we'd need to consider:

  • Caret-escaped codes: ^[[36m
  • Tilde-escaped codes: ~[36m
  • Different brackets: <ESC>36m{ESC}36m
  • PCBoard @X color codes
  • Wildcat! @XX@ codes
  • WWIV heart codes
  • Renegade pipe codes

Each BBS software had its own conventions. The library cannot and should not handle all of them.

6. Performance Impact

Detection adds processing overhead for a feature that:

  • Most users won't need
  • Can't be comprehensive (too many variants)
  • Belongs at a higher layer anyway

7. API Surface Complexity

Adding backtick detection requires:

  • New properties in TextAnalysis
  • New methods in AnsiEscapeDetector
  • New parameters in formatters
  • Documentation of non-standard behaviour
  • Test coverage for edge cases

This complexity serves a narrow use case better handled by consumers.


Example Application Code

Purely as an example, here's how an application could handle this:

Examples/BacktickAnsiDetection.cs:

/// <summary>
/// Example showing how applications can detect and handle BBS-specific
/// ANSI encoding conventions that are outside QWK.NET's scope.
/// </summary>
public static class BacktickAnsiHelper
{
    /// <summary>
    /// Detects backtick-escaped ANSI codes (BBS convention).
    /// </summary>
    public static bool ContainsBacktickEscapedAnsi(string text)
    {
        if (string.IsNullOrEmpty(text))
            return false;

        for (int i = 0; i < text.Length - 1; i++)
        {
            if (text[i] == '`' && text[i + 1] == '[')
                return true;
        }

        return false;
    }

    /// <summary>
    /// Converts backtick-escaped ANSI to standard ANSI for terminal display.
    /// </summary>
    public static string ConvertBacktickToAnsi(string text)
    {
        return text.Replace("`[", "\x1B[");
    }

    /// <summary>
    /// Strips backtick-escaped ANSI codes for plain text display.
    /// </summary>
    public static string StripBacktickAnsi(string text)
    {
        // Implementation left as exercise - similar to AnsiEscapeStripper
        // but looks for `[ instead of ESC[
        throw new NotImplementedException();
    }
}

Benefits of This Approach

1. Maintains Architectural Purity

  • Library stays focused on QWK format
  • No semantic interpretation of content
  • Clear boundary between parsing and presentation

2. Preserves Byte Fidelity

  • Backtick remains backtick
  • No assumptions about intent
  • Original data preserved exactly

3. Respects Specification

  • QWK spec doesn't define backtick behaviour
  • ANSI spec defines ESC, not backtick
  • Library implements what's specified

4. Enables Application Flexibility

  • Applications decide which conventions to support
  • Can handle BBS-specific variants they care about
  • Not forced to process conventions they don't need

5. Reduces Library Complexity

  • No new APIs to maintain
  • No performance overhead for unused features
  • Clearer, more focused codebase

6. Better Separation of Concerns

  • Parsing: QWK.NET's responsibility
  • Rendering: Application's responsibility
  • Clean layer boundary

Addressing the Original Concern

User observation: "The viewer shows ANSI codes but reports zero sequences."

Root cause: Viewer displays the backtick-escaped codes, but library correctly reports zero standard ANSI sequences.

Solution: This is correct library behaviour. The confusion comes from:

  1. Viewer showing raw text (which contains backtick patterns)
  2. User expecting detection of non-standard convention
  3. Library correctly reporting only standard ANSI

Conclusion

Backtick-escaped ANSI detection belongs in applications, not in QWK.NET.

This decision:

  • ✅ Maintains architectural integrity
  • ✅ Respects specification boundaries
  • ✅ Preserves byte fidelity
  • ✅ Enables application flexibility
  • ✅ Reduces library complexity
  • ✅ Separates parsing from presentation

The library should be enhanced with documentation explaining this limitation and providing guidance for applications that need to handle BBS-specific conventions.

Clone this wiki locally