๐ A powerful text format conversion library for Delphi and Lazarus
Overview โข Features โข Installation โข Quick Start โข Formats โข Architecture โข API โข Playground โข Extending โข FAQ
TextBridge4D is a versatile text format conversion library that uses an Abstract Syntax Tree (AST) to seamlessly convert between different markup formats. The AST-based approach ensures accurate and lossless conversions while providing an extensible architecture for adding new formats.
- ๐ณ AST-Based: Uses a tree structure for accurate format conversion
- ๐ Plugin Architecture: Easily add new formats without modifying core code
- ๐ฏ Simple API: One-line conversions with the fluent interface
- ๐ฆ Zero Dependencies: Pure Pascal implementation
- ๐ Legacy Support: Compatible with Delphi 6+ and Lazarus/FreePascal
- ๐ฎ Interactive Playground: Full demo application included for testing and visualization
TextBridge4D/
โโโ src/ # Library source code
โ โโโ TextBridge4D.pas # Main library unit (Core API + AST)
โ โโโ TextBridge4D.Interfaces.pas # Interface definitions
โ โโโ TextBridge4D.Base.pas # Abstract base classes & utilities
โ โโโ TextBridge4D.Enums.pas # Enumerations & constants
โ โโโ TextBridge4D.BBCode.pas # BBCode format implementation
โ โโโ TextBridge4D.HTML.pas # HTML format implementation
โ โโโ TextBridge4D.Markdown.pas # Markdown format implementation
โ โโโ TextBridge4D.RichText.pas # RTF format implementation
โ โโโ TextBridge4D.PlainText.pas # Plain text format implementation
โโโ playground/ # Demo application
โ โโโ DemoPlayground.dpr # Project file
โ โโโ uMain.pas # Main form with interactive conversion
โโโ README.md # English documentation
โโโ README.pt-BR.md # Portuguese documentation
| Feature | Description |
|---|---|
| Multi-Format Support | BBCode, HTML, Markdown, RTF, and Plain Text |
| Bidirectional Conversion | Convert from any format to any other format |
| Rich Text Formatting | Bold, italic, underline, strikethrough, colors, sizes, fonts |
| Structural Elements | Paragraphs, headers, lists (ordered/unordered), code blocks, quotes |
| Media Support | Links with URLs, images with alt text |
| Extensible | Create custom format handlers easily |
| Thread-Safe Registration | Format handlers can be registered safely |
- Clone or download this repository:
git clone https://github.com/weslleycapelari/TextBridge4D.git-
Add the
srcfolder to your project's search path:- Delphi: Project โ Options โ Delphi Compiler โ Search Path
- Lazarus: Project โ Project Options โ Compiler Options โ Paths โ Other unit files
-
Add the desired units to your uses clause:
uses
TextBridge4D, // Main library (required)
TextBridge4D.BBCode, // BBCode support
TextBridge4D.HTML, // HTML support
TextBridge4D.Markdown, // Markdown support
TextBridge4D.RichText, // RTF support
TextBridge4D.PlainText; // Plain text supportboss install github.com/weslleycapelari/TextBridge4DThe simplest way to convert text between formats:
uses
TextBridge4D, TextBridge4D.BBCode, TextBridge4D.HTML;
var
LResult: String;
begin
// Convert BBCode to HTML
LResult := TTextBridge4D.Convert('[b]Hello[/b] [i]World[/i]', ttBBCode, ttHTML);
// Result: <strong>Hello</strong> <em>World</em>
// Convert Markdown to BBCode
LResult := TTextBridge4D.Convert('**Bold** and _Italic_', ttMarkdown, ttBBCode);
// Result: [b]Bold[/b] and [i]Italic[/i]
end;For more control, use the fluent interface:
var
LBridge: TTextBridge4D;
LResult: String;
begin
LBridge := TTextBridge4D.New
.Parse('[b]Welcome[/b] to [color=red]TextBridge4D[/color]', ttBBCode);
LResult := LBridge.Render(ttHTML);
// Result: <strong>Welcome</strong> to <span style="color:red;">TextBridge4D</span>
LResult := LBridge.Render(ttMarkdown);
// Result: **Welcome** to TextBridge4D
LBridge.Free;
end;Create formatted documents using the AST directly:
var
LDoc: TTextBridge4D;
LParagraph: TTextBridge4D;
LResult: String;
begin
LDoc := TTextBridge4D.New;
try
// Add a paragraph with formatted text
LParagraph := LDoc.AddChild(ntParagraph);
LParagraph.AddChild(ntBold).AddChild(ntText, 'Important: ');
LParagraph.AddChild(ntText, 'This is a ');
LParagraph.AddChild(ntItalic).AddChild(ntText, 'demonstration');
// Add a link
with LDoc.AddChild(ntLink) do
begin
SetAttribute('href', 'https://github.com');
AddChild(ntText, 'Visit GitHub');
end;
// Render to different formats
LResult := LDoc.Render(ttHTML);
// <p><strong>Important: </strong>This is a <em>demonstration</em></p>
// <a href="https://github.com">Visit GitHub</a>
finally
LDoc.Free;
end;
end;Forum-style markup language using square brackets.
| Element | BBCode Syntax |
|---|---|
| Bold | [b]text[/b] |
| Italic | [i]text[/i] |
| Underline | [u]text[/u] |
| Strikethrough | [s]text[/s] |
| Color | [color=red]text[/color] or [color=#FF0000]text[/color] |
| Size | [size=14]text[/size] |
| Font | [font=Arial]text[/font] |
| Link | [url=https://...]text[/url] or [url]https://...[/url] |
| Image | [img]url[/img] or [img=alt text]url[/img] |
| Quote | [quote]text[/quote] |
| Code | [code]text[/code] |
| List | [list][*]item1[*]item2[/list] |
Standard web markup language.
| Element | HTML Syntax |
|---|---|
| Bold | <strong>text</strong> or <b>text</b> |
| Italic | <em>text</em> or <i>text</i> |
| Underline | <u>text</u> |
| Strikethrough | <s>text</s> or <del>text</del> |
| Color | <span style="color:red;">text</span> |
| Size | <span style="font-size:14px;">text</span> |
| Font | <span style="font-family:Arial;">text</span> |
| Link | <a href="https://...">text</a> |
| Image | <img src="url" alt="text" /> |
| Quote | <blockquote>text</blockquote> |
| Code | <pre><code>text</code></pre> |
| Headers | <h1>text</h1> through <h6>text</h6> |
| List | <ul><li>item</li></ul> or <ol><li>item</li></ol> |
Lightweight markup language for plain text formatting.
| Element | Markdown Syntax |
|---|---|
| Bold | **text** or __text__ |
| Italic | *text* or _text_ |
| Bold + Italic | ***text*** |
| Strikethrough | ~~text~~ |
| Link | [text](url) |
| Image |  |
| Quote | > text |
| Code (inline) | `text` |
| Code (block) | ```text``` |
| Headers | # H1 through ###### H6 |
| Unordered List | - item or * item |
| Ordered List | 1. item |
| Horizontal Rule | --- or *** |
Document format used by word processors.
| Feature | Support |
|---|---|
| Text formatting | Full (bold, italic, underline, strikethrough) |
| Colors | Dynamic color table generation |
| Font sizes | Half-point conversion |
| Fonts | Font table with Arial and Courier New |
| Hyperlinks | HYPERLINK field syntax |
| Lists | Visual bullet simulation |
| Paragraphs | \par control word |
โ ๏ธ Note: RTF parsing is limited. The current implementation returns raw text. Full RTF parsing requires a complete state machine and may be added in future versions.
Extracts text content without any formatting.
-
AST (Abstract Syntax Tree)
- Central data structure for all conversions
- Each node (
TTextBridge4D) represents a document element - Supports hierarchical nesting of elements
- Type-safe node list (
TBNodeList) with automatic memory management
-
Interface-Based Format System
- All formatters implement
ITextBridgeFormatinterface - Formatters registered at initialization via
RegisterFormat - Dynamic format lookup using
GetFormat(TBTextType) - Thread-safe registration mechanism
- All formatters implement
-
Two-Phase Conversion
- Phase 1 (Parse): Format A โ AST
- Phase 2 (Render): AST โ Format B
- AST can be rendered to multiple formats without re-parsing
- Enables format-agnostic processing of documents
- Abstract Factory: Format registration and creation
- Template Method:
TTextBridgeFormatBasedefines parsing/rendering structure - Facade:
TTextBridge4Dprovides simple interface to complex system - Composite: AST nodes form tree structure
- Strategy: Different formatters implement same interface
- Delphi 6+ Support: No modern features required
- Lazarus/FreePascal: Full compatibility with FPC mode
- No Dependencies: Pure RTL implementation
- Memory Safe: Automatic cleanup via
TObjectListownership - String Builder: Custom implementation for older Delphi versions
- Parsing: O(n) where n = input length
- Rendering: O(m) where m = AST node count
- Memory: O(m) for AST storage
- Reusability: Parse once, render multiple times
| Method | Description |
|---|---|
New: TTextBridge4D |
Creates a new root node instance |
Convert(AText, AFrom, ATo): String |
One-step conversion between formats |
RegisterFormat(AFormat: ITextBridgeFormat) |
Registers a format handler |
GetFormat(AType: TBTextType): ITextBridgeFormat |
Retrieves a registered format handler |
| Method | Description |
|---|---|
Parse(AText, AFormat): TTextBridge4D |
Parses text and returns self |
Render(AFormat): String |
Renders the AST to the specified format |
AddChild(AType): TTextBridge4D |
Adds a child node and returns it |
AddChild(AType, AValue): TTextBridge4D |
Adds a child with text value |
SetAttribute(AKey, AValue): TTextBridge4D |
Sets an attribute (fluent) |
HasAttribute(AKey): Boolean |
Checks if attribute exists |
Clear |
Removes all children |
| Property | Type | Description |
|---|---|---|
NodeType |
TBNodeType |
The type of this node |
Value |
String |
Text content (for ntText nodes) |
Children |
TList |
List of child nodes |
Parent |
TTextBridge4D |
Parent node reference |
Attributes[Key] |
String |
Access to node attributes |
TBNodeType = (
ntRoot, // Document root
ntText, // Plain text content
ntParagraph, // Paragraph block
ntBold, // Bold formatting
ntItalic, // Italic formatting
ntUnderline, // Underline formatting
ntStrike, // Strikethrough
ntLink, // Hyperlink (href attribute)
ntImage, // Image (src, alt attributes)
ntColor, // Text color (color attribute)
ntSize, // Font size (size attribute)
ntFont, // Font family (face attribute)
ntList, // List container (ordered attribute)
ntListItem, // List item
ntCode, // Code block
ntQuote, // Block quote
ntHeader, // Header (level attribute: 1-6)
ntLineBreak, // Line break
ntHorizontalRule // Horizontal line
);TBTextType = (
ttUnknown, // Unknown format
ttBBCode, // BBCode format
ttHTML, // HTML format
ttMarkdown, // Markdown format
ttRichText, // RTF format
ttPlainText // Plain text
);To add support for a new format, create a class that inherits from TTextBridgeFormatBase:
unit TextBridge4D.CustomFormat;
interface
uses
TextBridge4D.Enums,
TextBridge4D.Interfaces,
TextBridge4D,
TextBridge4D.Base;
type
TTextBridgeCustomFormat = class(TTextBridgeFormatBase)
protected
function DoParse(const AText: String): TTextBridge4D; override;
function DoRender(ARoot: TTextBridge4D): String; override;
public
function GetFormatType: TBTextType; override;
function GetFormatName: String; override;
end;
implementation
function TTextBridgeCustomFormat.GetFormatType: TBTextType;
begin
Result := ttCustom; // Add to TBTextType enum
end;
function TTextBridgeCustomFormat.GetFormatName: String;
begin
Result := 'Custom';
end;
function TTextBridgeCustomFormat.DoParse(const AText: String): TTextBridge4D;
begin
Result := TTextBridge4D.New;
// Implement parsing logic
// Build AST from input text
end;
function TTextBridgeCustomFormat.DoRender(ARoot: TTextBridge4D): String;
begin
// Implement rendering logic
// Traverse AST and generate output
end;
initialization
TTextBridge4D.RegisterFormat(TTextBridgeCustomFormat.Create);
end.- Parsing: Build the AST by creating nodes for each formatting element
- Rendering: Traverse the AST recursively, outputting the appropriate syntax
- Attributes: Use
SetAttribute/HasAttributefor element properties - Self-Closing: Handle elements like images and line breaks specially
The project includes a complete interactive demonstration application located in the playground folder. This application allows you to:
- Real-time Conversion: Convert text between any supported formats instantly
- AST Visualization: View the generated Abstract Syntax Tree structure
- Multiple Output Views:
- Raw code output
- Rich text preview (for RTF)
- HTML preview in browser
- AST tree structure
- Performance Metrics: See parsing time, rendering time, and conversion speed
- Example Templates: Pre-loaded examples for testing different features
- Auto-convert: Optional automatic conversion as you type
- Format Swapping: Quickly swap input and output formats
- Open
playground/DemoPlayground.dprin Delphi - Compile and run the application
- Select input and output formats
- Type or paste text in the input area
- Click "Convert" or enable auto-convert
- View results in different tabs
The playground is an invaluable tool for:
- Testing new format implementations
- Debugging parser issues by viewing the AST
- Understanding how different formats are converted
- Measuring performance with different document sizes
- Creating examples for documentation
var
LPost: String;
LEmail: String;
begin
LPost := '[b]Announcement[/b]'#13#10 +
'Please check the [url=https://example.com]new features[/url].'#13#10 +
'[quote]This is amazing![/quote]';
LEmail := TTextBridge4D.Convert(LPost, ttBBCode, ttHTML);
end;var
LReadme: String;
LForum: String;
begin
LReadme := '# Project Title'#13#10 +
'**Features:**'#13#10 +
'- Feature 1'#13#10 +
'- Feature 2';
LForum := TTextBridge4D.Convert(LReadme, ttMarkdown, ttBBCode);
end;var
LHtml: String;
LSearchText: String;
begin
LHtml := '<h1>Welcome</h1><p>This is <strong>important</strong> content.</p>';
LSearchText := TTextBridge4D.Convert(LHtml, ttHTML, ttPlainText);
// Result: Welcome This is important content.
end;A: Yes! Simply use TTextBridge4D.Convert('[b]text[/b]', ttBBCode, ttHTML). The AST is handled internally.
A: Format registration is thread-safe, but AST instances should not be shared between threads. Create separate instances per thread.
A: Absolutely! Create a class inheriting from TTextBridgeFormatBase, implement the required methods, and register it with RegisterFormat.
A: Full RTF parsing requires a complex state machine. The current implementation extracts text content. Full support is planned for future versions.
A: Wrap conversion calls in try-except blocks and catch ETextBridgeParseError for parsing errors and ETextBridgeRenderError for rendering errors.
A: Yes, custom attributes are preserved in the AST. However, they may be lost when rendering to formats that don't support them.
A: Yes, full Unicode support is available. All string handling uses Delphi's native string type.
A: Fork the repository, make your changes following the coding standards, and submit a pull request. See the Contributing section for details.
Planned features for future releases:
- Full RTF Parsing: Complete RTF document parser with state machine
- Extended Markdown: GitHub-flavored Markdown support (tables, task lists)
- XML/DOCX Support: Microsoft Word document format
- LaTeX Output: Mathematical and scientific document support
- Streaming Parser: Handle large documents with limited memory
- Validation Framework: Configurable validation rules for AST
- CSS Styling: Advanced HTML styling support
- Performance Optimizations: Faster parsing for large documents
- Unit Tests: Comprehensive test coverage
- CI/CD Integration: Automated testing and release pipeline
TextBridge4D is perfect for:
- Forum Systems: Convert between BBCode (for storage) and HTML (for display)
- Content Management: Store content in one format, display in multiple formats
- Documentation Tools: Convert Markdown documentation to HTML or RTF
- Email Systems: Convert rich forum posts or HTML to plain text
- Text Editors: Allow users to import/export content in different formats
- Search Indexing: Extract plain text from formatted documents
- Cross-Platform Content: Share formatted content between different systems
- API Responses: Convert stored markup to client's preferred format
Contributions are welcome! Please feel free to submit a Pull Request. For detailed guidelines, see CONTRIBUTING.md.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
- Use English for all documentation and comments
- Follow naming conventions (see CONTRIBUTING.md for details)
- Target Delphi 6+ compatibility
- Include comprehensive documentation
- Test with the playground application
For more information, see our Contributing Guide.
This project is licensed under the MIT License - see the LICENSE file for details.
For a complete list of changes and version history, see CHANGELOG.md.
- CRITICAL: Fixed memory corruption in
AddChildmethod when moving nodes between parents - CRITICAL: Fixed HTML parser failure with '>' character inside quoted attributes
- Added
ExtractChildmethod for safe node removal without destruction - Added
FindTagClosefunction with quote-aware state machine for HTML parsing - Improved
ExtractAttributeto validate whole words and handle spaces/entities - Added
Sniffmethod for auto-detection of text formats with confidence scoring - Added
DetectFormatclass method for automatic format detection - All formatters now support format auto-detection (BBCode, HTML, Markdown, RTF, PlainText)
- Complete refactoring with improved English documentation
- Enhanced naming conventions following best practices
- Added comprehensive XML documentation comments
- Improved Delphi 6+ and Lazarus/FreePascal compatibility
- Added interactive playground application with AST visualization
- Added HTML format support with full parsing capabilities
- Performance improvements and better error handling
- Complete test suite with example templates
- Initial release
- Core AST-based conversion engine
- BBCode, Markdown, RTF, and PlainText support
- Basic HTML rendering (parse-only)
- Interface-based format registration system
Weslley Capelari
- GitHub: @weslleycapelari
- Inspired by the need for cross-format text conversion in Delphi applications
- Thanks to the Delphi and Lazarus communities
Made with โค๏ธ for the Delphi community