textf 1.1.0 copy "textf: ^1.1.0" to clipboard
textf: ^1.1.0 copied to clipboard

Markdown-like text styling for inline text — fully compatible with Flutter’s `Text` widget. Easily replace Text with Textf to add simple formatting.

Textf #

pub package License: MIT style: very good analysis

Markdown-like text styling for inline text — fully compatible with Flutter's Text widget.

What Textf Is #

✅ Inline text formatting only ✅ Works like Text, but supports inline styles ✅ Ideal for i18n / ARB / JSON localized strings ✅ Zero dependencies, minimal footprint

From Text to Textf #

Replace Text with Textf to add simple formatting:

Textf('Hello **Flutter**. Build for ==any screen==!');

image

⚠️ Important: Textf is designed for inline styling only and is not a full Markdown renderer. It doesn't support block elements like lists, headings, or images.

Installation #

Add Textf to your pubspec.yaml:

dependencies:
  textf: ^1.1.0

Then run:

flutter pub get

Getting Started #

import 'package:textf/textf.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Textf(
      'Hello **bold** *italic* ~~strikethrough~~ `code` '
      '++underline++ ==highlight== ^super^ ~sub~ '
      '[Flutter](https://flutter.dev)',
      style: TextStyle(fontSize: 16),
    );
  }
}

image

Supported Formatting #

Format Syntax Result
Bold **bold** or __bold__ bold
Italic *italic* or _italic_ italic
Bold+Italic ***both*** or ___both___ both
Strikethrough ~~strikethrough~~ strikethrough
Underline ++underline++
Highlight ==highlight== highlight
Code `code` code
Link [text](url) Flutter
Superscript ^superscript^ E = mc²
Subscript ~subscript~ H₂O
Placeholder {key} (inserted widget)

Escaping Characters #

Use backslash to display literal formatting characters:

Textf(r'Use \*asterisks\* without formatting');
// Output: Use *asterisks* without formatting

Textf(r'Show a placeholder: \{key}');
// Output: Show a placeholder: {key}

Escapable characters: *, _, ~, `, [, ], (, ), {, }, \


🆕 Widget Placeholders #

Insert any InlineSpan (such as WidgetSpan or TextSpan) using named placeholders:

Textf(
  'Built with {flutter} and {dart}. Made with {love}.',
  placeholders: {
    'flutter': WidgetSpan(child: Image.asset('flutter.png', width: 16)),
    'dart': WidgetSpan(child: Image.asset('dart.png', width: 16)),
    'love': WidgetSpan(child: Icon(Icons.favorite, color: Colors.red, size: 16)),
  },
)

image

Key points:

  • Keys must be alphanumeric or underscores: {icon}, {my_image}, {step1}
  • Missing keys render as literal text (e.g., {missing}) — no crashes
  • Works inside formatting: **{icon}** and links: [Click {icon}](url)
  • Escape with backslash: \{key} renders as {key}

Customization with TextfOptions #

Wrap your widgets with TextfOptions to customize formatting styles:

TextfOptions(
  // Style overrides
  boldStyle: TextStyle(fontWeight: FontWeight.w900, color: Colors.orange),
  italicStyle: TextStyle(fontStyle: FontStyle.italic, color: Colors.purple),
  codeStyle: TextStyle(fontFamily: 'JetBrains Mono', backgroundColor: Colors.grey.shade200),

  // Link behavior
  linkStyle: TextStyle(color: Colors.teal, decoration: TextDecoration.none),
  linkHoverStyle: TextStyle(color: Colors.teal, decoration: TextDecoration.underline),
  onLinkTap: (url, displayText) => launchUrl(Uri.parse(url)),
  onLinkHover: (url, displayText, {required isHovering}) => debugPrint('Hover: $isHovering'),

  child: Textf('**Bold** *italic* `code` [link](https://example.com)'),
)

image

Available Style Options #

Option Description
boldStyle Style for **bold** text
italicStyle Style for *italic* text
boldItalicStyle Style for ***bold italic*** text
strikethroughStyle Style for ~~strikethrough~~ text
underlineStyle Style for ++underline++ text
highlightStyle Style for ==highlight== text
codeStyle Style for `code` text
superscriptStyle Style for ^super^ text
subscriptStyle Style for ~sub~ text
linkStyle Style for links (normal state)
linkHoverStyle Style for links (hover state)
Option Description
onLinkTap Callback when a link is tapped: (String url, String displayText)
onLinkHover Callback on hover state change: (String url, String displayText, {required bool isHovering})
linkMouseCursor Mouse cursor for links (default: SystemMouseCursors.click)
linkAlignment Vertical alignment of link widgets (default: PlaceholderAlignment.baseline)

Script Options #

Option Description Default
scriptFontSizeFactor Font size multiplier for super/subscripts 0.6
superscriptBaselineFactor Vertical offset factor for superscripts -0.4
subscriptBaselineFactor Vertical offset factor for subscripts 0.2

Inheritance #

TextfOptions inherits through the widget tree. Styles are merged — a parent's color combines with a child's font weight:

TextfOptions(
  boldStyle: TextStyle(color: Colors.red),  // Parent: red color
  child: TextfOptions(
    boldStyle: TextStyle(fontWeight: FontWeight.w900),  // Child: heavy weight
    child: Textf('**This is red AND heavy**'),
  ),
)

SelectionArea Support #

Textf works with Flutter's SelectionArea for text selection:

SelectionArea(
  child: Textf('Select **this** text!'),
)

Note: Due to links being rendered as WidgetSpan elements, text selection cannot span across interactive links. This is a Flutter limitation, not a Textf bug.


Performance #

Textf is designed for performance:

  • O(N) Linear Parsing — Single-pass tokenization scales linearly with text length
  • Smart Caching — Parsed results are cached and reused across rebuilds
  • Intelligent Invalidation — Cache only clears when text, style, theme, or options actually change
  • Memory Efficient — LRU cache with configurable limits prevents memory bloat

Cache Management #

For advanced use cases, you can manually clear the global parse cache:

// Clear all cached parse results
Textf.clearCache();

This is rarely needed — the cache automatically manages itself using LRU eviction.


Accessibility #

Textf respects Flutter's accessibility standards:

  1. Text Scaling — Fully respects MediaQuery.textScalerOf(context) and system accessibility settings
  2. Screen Readers — Links are wrapped in Semantics widgets with link: true for TalkBack/VoiceOver
  3. RTL Support — Bidirectional text and RTL languages work correctly

Why Textf? #

Feature Textf Full Markdown Packages
Bundle size Tiny Large
Dependencies Zero Multiple
Parse complexity O(N) Often O(N²) or worse
API familiarity Identical to Text Custom widgets
Block elements
Use case Inline formatting Document rendering

About the Name #

The name "Textf" is inspired by C's printf (print formatted). Similarly, Textf (Text formatted) provides simple, efficient text formatting for Flutter.


Features #

  • ✅ Bold, Italic, Bold+Italic
  • ✅ Strikethrough, Underline, Highlight
  • ✅ Inline Code with theme-aware styling
  • ✅ Superscript and Subscript
  • ✅ Links with hover effects and callbacks
  • ✅ Widget Placeholders via {key} syntax
  • ✅ Nested formatting (up to 2 levels)
  • ✅ Customizable styles via TextfOptions
  • ✅ Theme-aware defaults
  • ✅ RTL language support
  • ✅ Smart caching for performance
  • ✅ Full Text widget API compatibility

Limitations #

Limitation Reason
No block elements Textf is for inline formatting only — no headings, lists, quotes, or images
Max 2 nesting levels **bold _italic_** works, deeper nesting renders as plain text
Selection across links Links use WidgetSpan, so selection can't span across them (Flutter limitation)

When to Use Textf #

✅ Use Textf for:

  • Chat messages and comments
  • UI labels and captions
  • Internationalized strings with formatting
  • Performance-critical text rendering
  • Simple inline formatting needs

❌ Don't use Textf for:

  • Full Markdown documents
  • HTML rendering
  • Content with headings, lists, or tables
  • Documents requiring text selection across links

API Reference #

See the full API documentation on pub.dev.


Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

License #

This project is licensed under the MIT License — see the LICENSE file for details.

40
likes
160
points
227
downloads
screenshot

Publisher

verified publisherphilippgerber.li

Weekly Downloads

Markdown-like text styling for inline text — fully compatible with Flutter’s `Text` widget. Easily replace Text with Textf to add simple formatting.

Repository (GitHub)
View/report issues

Topics

#text #widget #markdown #formatting

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on textf