-
Notifications
You must be signed in to change notification settings - Fork 0
QWK.NET ‐ Backtick‐Escaped ANSI
QWK.NET detects standard ANSI CSI sequences (ESC followed by '[').
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.
If your application needs to detect or render BBS-specific ANSI conventions:
- Use QWK.NET to extract message text
- Implement your own detection for the conventions you need
- 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[");
}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.
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.
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:
- Is not in the QWK specification
- Is not standard ANSI
- Is a BBS-specific presentation convention
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.
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.
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.
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
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.
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();
}
}- Library stays focused on QWK format
- No semantic interpretation of content
- Clear boundary between parsing and presentation
- Backtick remains backtick
- No assumptions about intent
- Original data preserved exactly
- QWK spec doesn't define backtick behaviour
- ANSI spec defines ESC, not backtick
- Library implements what's specified
- Applications decide which conventions to support
- Can handle BBS-specific variants they care about
- Not forced to process conventions they don't need
- No new APIs to maintain
- No performance overhead for unused features
- Clearer, more focused codebase
- Parsing: QWK.NET's responsibility
- Rendering: Application's responsibility
- Clean layer boundary
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:
- Viewer showing raw text (which contains backtick patterns)
- User expecting detection of non-standard convention
- Library correctly reporting only standard ANSI
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.