diff --git a/.pubignore b/.pubignore index 90c978b..e10928a 100644 --- a/.pubignore +++ b/.pubignore @@ -1 +1,29 @@ -example/ +# Example build artifacts +example/build/ +example/.dart_tool/ +example/.idea/ + +# Android +example/android/.gradle/ +example/android/captures/ +example/android/gradlew +example/android/gradlew.bat +example/android/local.properties +example/android/key.properties +example/android/**/GeneratedPluginRegistrant.java + +# iOS +example/ios/**/DerivedData/ +example/ios/**/Pods/ +example/ios/**/.symlinks/ +example/ios/**/xcuserdata/ +example/ios/**/.generated/ +example/ios/Flutter/App.framework +example/ios/Flutter/Flutter.framework +example/ios/Flutter/Flutter.podspec +example/ios/Flutter/Generated.xcconfig +example/ios/Flutter/app.flx +example/ios/Flutter/app.zip +example/ios/Flutter/flutter_assets/ +example/ios/Flutter/flutter_export_environment.sh +example/ios/Runner/GeneratedPluginRegistrant.* diff --git a/CHANGELOG.md b/CHANGELOG.md index aadadf8..557c102 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 1.0.7 + +* Improved pub.dev score by making example app source code available in published package +* Updated `.pubignore` to only exclude build artifacts and generated files instead of entire example directory +* Fixed linter warnings by removing unnecessary null default values in `MarkdownStyleSheet` +* Added `CLAUDE.md` documentation for AI-assisted development +* Enhanced README with package history and link to LaTeX support package +* Standardized formatter configuration across project + ## 1.0.6 * Fix cursor behavior when using custom builder for anchor tags. The code now only manages `_linkHandlers` when there is no custom builder for anchor tags, preventing conflicts between the default link recognizer and custom builder widgets. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..9541135 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,106 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Flutter Markdown Plus is a Flutter package that renders Markdown text into Flutter widgets. It's built on top of the Dart `markdown` package and supports GitHub Flavored Markdown by default. The package provides both `Markdown` (with scrolling) and `MarkdownBody` widgets, along with extensive customization options for styling, image handling, and interactive elements. + +## Development Commands + +### Testing +- Run all tests: `flutter test` +- Run tests with coverage: `rm -rf coverage && flutter test` +- Run all tests via test suite: `flutter test test/all.dart` +- Run a single test file: `flutter test test/[test_name].dart` + +### Code Quality +- Format code: `dart format . -l 120` or `sh ./scripts/format.sh` +- Format only staged files: `sh ./scripts/format.sh --only-staged` +- Format with exit-on-change: `sh ./scripts/format.sh --set-exit-if-changed` +- Analyze code: `flutter analyze --no-pub .` +- Full validation: `./validate.sh` (runs clean, pub get, format, analyze, and test) + +### Package Management +- Get dependencies: `flutter pub get` +- Clean build: `flutter clean` + +### Example App +- Run example app: `cd example && flutter run` +- Demos are in `example/lib/demos/` showcasing various features +- Shared widgets in `example/lib/shared/` include reusable demo components and sample custom syntax implementations + +## Architecture + +### Core Components + +**Main Entry Point** (`lib/flutter_markdown_plus.dart`) +- Exports the three main modules: builder, style_sheet, and widget + +**Widget Layer** (`lib/src/widget.dart`) +- `Markdown`: Scrollable markdown widget with padding +- `MarkdownBody`: Non-scrollable markdown widget for embedding +- `MarkdownRaw`: Base widget without Material Design theming +- Callback typedefs for link taps, selection changes, and custom builders + +**Builder Layer** (`lib/src/builder.dart`) +- `MarkdownBuilder`: Converts markdown AST nodes to Flutter widgets +- Handles all markdown elements: headers, paragraphs, lists, tables, images, etc. +- Manages text styling, link handling, and custom element rendering +- Block vs inline element handling with proper nesting + +**Style Layer** (`lib/src/style_sheet.dart`) +- `MarkdownStyleSheet`: Comprehensive theming system +- Integrates with Material Design themes +- Supports custom text styles, colors, decorations, and spacing + +### Platform Abstractions +- `_functions_io.dart`: IO platform implementations +- `_functions_web.dart`: Web platform implementations +- Conditional imports handle platform differences + +### Extension Points + +**Custom Builders** +- `imageBuilder`: Custom image widget rendering +- `checkboxBuilder`: Custom checkbox rendering +- `bulletBuilder`: Custom bullet point rendering + +**Syntax Extensions** +- Supports markdown package's extension system +- Default: GitHub Flavored Markdown +- Can add emoji syntax, custom inline/block syntaxes + +**Selection & Interaction** +- Configurable text selection behavior +- Link tap handling with custom callbacks +- Integration with Flutter's SelectionArea + +## Key Features + +- **Markdown Parsing**: Built on `markdown` package AST +- **Rich Styling**: Material Design integration with custom overrides +- **Image Support**: Network, local, and asset images with `resource:` prefix +- **Table Rendering**: Full table support with custom styling +- **Interactive Elements**: Checkboxes, links with tap handlers +- **Text Selection**: Configurable selection with callbacks +- **Extensibility**: Plugin system for custom syntax and rendering + +## Testing Strategy + +Tests are comprehensive and organized by feature: +- Individual element tests (headers, lists, images, etc.) +- Style sheet testing +- Selection and interaction testing +- Platform compatibility testing +- Mock-based image testing + +The `test/all.dart` file runs the complete test suite. + +## Code Style + +- Line length: 120 characters (configured in `pubspec.yaml`) +- Follows Flutter/Dart team's analysis_options.yaml with minor modifications +- Public API documentation required (`public_member_api_docs`) +- Strict type checking enabled +- Uses `prefer_single_quotes` and other Flutter conventions \ No newline at end of file diff --git a/README.md b/README.md index 00e572c..320ee92 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ # Flutter Markdown [![pub package](https://img.shields.io/pub/v/flutter_markdown_plus.svg)](https://pub.dartlang.org/packages/flutter_markdown_plus) +## About This Package + +`flutter_markdown_plus` is the continuation of the original [`flutter_markdown`](https://pub.dev/packages/flutter_markdown) package that was developed and maintained by Google. As the original package has been discontinued, Foresight Mobile has taken over maintenance of this project to ensure continued support and development for the Flutter community. + +For historical context, see the [original flutter_markdown package](https://pub.dev/packages/flutter_markdown). + +**LaTeX Support:** For LaTeX rendering support, check out the [`flutter_markdown_plus_latex`](https://pub.dev/packages/flutter_markdown_plus_latex) package. + A markdown renderer for Flutter. It supports the [original format](https://daringfireball.net/projects/markdown/), but no inline HTML. @@ -164,3 +172,7 @@ Here are some additional Markdown syntax resources: - [CommonMark Markdown Reference](https://commonmark.org/help/) - [GitHub Guides - Mastering Markdown](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) - [Download PDF cheatsheet version](https://guides.github.com/pdfs/markdown-cheatsheet-online.pdf) + +## Maintainers + +This package is proudly maintained by [Gareth Reese](https://github.com/gazreese) and [Marko Radisavljevic](https://github.com/Prototypev1) for [Foresight Mobile](https://foresightmobile.com/) ([GitHub](https://github.com/foresightmobile/)) diff --git a/analysis_options.yaml b/analysis_options.yaml index 7362355..68be6a0 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -20,6 +20,9 @@ analyzer: # Ignore generated files - '**/*.g.dart' - '**/*.mocks.dart' # Mockito @GenerateMocks + +formatter: + page_width: 120 linter: rules: diff --git a/example/pubspec.lock b/example/pubspec.lock index eb2514f..b522d74 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -68,7 +68,7 @@ packages: path: ".." relative: true source: path - version: "1.0.6" + version: "1.0.7" flutter_test: dependency: "direct dev" description: flutter diff --git a/lib/src/style_sheet.dart b/lib/src/style_sheet.dart index 3b0a240..9927731 100644 --- a/lib/src/style_sheet.dart +++ b/lib/src/style_sheet.dart @@ -143,8 +143,6 @@ class MarkdownStyleSheet { tableColumnWidth: const FlexColumnWidth(), tableCellsPadding: const EdgeInsets.fromLTRB(16, 8, 16, 8), tableCellsDecoration: const BoxDecoration(), - tableHeadCellsPadding: null, - tableHeadCellsDecoration: null, blockquotePadding: const EdgeInsets.all(8.0), blockquoteDecoration: BoxDecoration( color: Colors.blue.shade100, @@ -320,8 +318,6 @@ class MarkdownStyleSheet { tableColumnWidth: const FlexColumnWidth(), tableCellsPadding: const EdgeInsets.fromLTRB(16, 8, 16, 8), tableCellsDecoration: const BoxDecoration(), - tableHeadCellsPadding: null, - tableHeadCellsDecoration: null, blockquotePadding: const EdgeInsets.all(8.0), blockquoteDecoration: BoxDecoration( color: Colors.blue.shade100, diff --git a/pubspec.yaml b/pubspec.yaml index fea572c..351a9d7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ description: A Markdown renderer for Flutter. Create rich text output, formatted with simple Markdown tags. repository: https://github.com/foresightmobile/flutter_markdown_plus issue_tracker: https://github.com/foresightmobile/flutter_markdown_plus/issues -version: 1.0.6 +version: 1.0.7 environment: sdk: ^3.4.0 @@ -28,5 +28,5 @@ topics: - markdown - widgets -dartfmt: - line_length: 120 +formatter: + page_width: 120 diff --git a/test/table_test.dart b/test/table_test.dart index e9242ef..bdfc343 100644 --- a/test/table_test.dart +++ b/test/table_test.dart @@ -606,7 +606,6 @@ void defineTests() { const EdgeInsets cellPadding = EdgeInsets.all(12); final MarkdownStyleSheet style = MarkdownStyleSheet.fromTheme(theme).copyWith( tableCellsPadding: cellPadding, - tableHeadCellsPadding: null, ); await tester.pumpWidget(boilerplate(MarkdownBody(data: data, styleSheet: style))); @@ -657,7 +656,6 @@ void defineTests() { color: Colors.grey.shade100, ); final MarkdownStyleSheet style = MarkdownStyleSheet.fromTheme(theme).copyWith( - tableHeadCellsDecoration: null, tableCellsDecoration: bodyDecoration, );