feat(markdown): Add syntax highlighting with flutter_highlight

This commit is contained in:
cogwheel0
2025-12-08 00:08:19 +05:30
parent dcca839e35
commit 4903b72753
3 changed files with 60 additions and 4 deletions

View File

@@ -5,6 +5,9 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_highlight/flutter_highlight.dart';
import 'package:flutter_highlight/themes/atom-one-dark.dart';
import 'package:flutter_highlight/themes/github.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_math_fork/flutter_math.dart'; import 'package:flutter_math_fork/flutter_math.dart';
import 'package:gpt_markdown/gpt_markdown.dart'; import 'package:gpt_markdown/gpt_markdown.dart';
@@ -98,7 +101,13 @@ class ConduitMarkdown {
? 'plaintext' ? 'plaintext'
: language.trim(); : language.trim();
// Match GitHub/Atom theme colors for code block container // Map common language aliases to highlight.js recognized names
final highlightLanguage = _mapLanguage(normalizedLanguage);
// Use Atom One Dark for dark mode, GitHub for light mode
final highlightTheme = isDark ? atomOneDarkTheme : githubTheme;
// Match theme colors for code block container
final codeBackground = isDark final codeBackground = isDark
? const Color(0xFF282c34) // Atom One Dark background ? const Color(0xFF282c34) // Atom One Dark background
: const Color(0xFFfafbfc); // GitHub light background : const Color(0xFFfafbfc); // GitHub light background
@@ -135,10 +144,12 @@ class ConduitMarkdown {
SingleChildScrollView( SingleChildScrollView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
padding: const EdgeInsets.all(Spacing.md), padding: const EdgeInsets.all(Spacing.md),
child: SelectableText( child: HighlightView(
code, code,
style: AppTypography.codeStyle.copyWith( language: highlightLanguage,
color: theme.codeText, theme: highlightTheme,
padding: EdgeInsets.zero,
textStyle: AppTypography.codeStyle.copyWith(
fontFamily: AppTypography.monospaceFontFamily, fontFamily: AppTypography.monospaceFontFamily,
), ),
), ),
@@ -148,6 +159,34 @@ class ConduitMarkdown {
); );
} }
/// Maps common language names/aliases to highlight.js recognized names.
static String _mapLanguage(String language) {
final lower = language.toLowerCase();
// Common language aliases mapping
const languageMap = <String, String>{
'js': 'javascript',
'ts': 'typescript',
'py': 'python',
'rb': 'ruby',
'sh': 'bash',
'shell': 'bash',
'zsh': 'bash',
'yml': 'yaml',
'dockerfile': 'docker',
'kt': 'kotlin',
'cs': 'csharp',
'c++': 'cpp',
'objc': 'objectivec',
'objective-c': 'objectivec',
'txt': 'plaintext',
'text': 'plaintext',
'md': 'markdown',
};
return languageMap[lower] ?? lower;
}
static Widget _buildImage( static Widget _buildImage(
BuildContext context, BuildContext context,
Uri uri, Uri uri,

View File

@@ -494,6 +494,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.0" version: "3.0.0"
flutter_highlight:
dependency: "direct main"
description:
name: flutter_highlight
sha256: "7b96333867aa07e122e245c033b8ad622e4e3a42a1a2372cbb098a2541d8782c"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
@@ -709,6 +717,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.2" version: "2.3.2"
highlight:
dependency: transitive
description:
name: highlight
sha256: "5353a83ffe3e3eca7df0abfb72dcf3fa66cc56b953728e7113ad4ad88497cf21"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
hive_ce: hive_ce:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@@ -78,6 +78,7 @@ dependencies:
flutter_svg: ^2.2.3 flutter_svg: ^2.2.3
html_unescape: ^2.0.0 html_unescape: ^2.0.0
home_widget: ^0.8.1 home_widget: ^0.8.1
flutter_highlight: ^0.7.0
# Clipboard functionality is available through flutter/services (part of Flutter SDK) # Clipboard functionality is available through flutter/services (part of Flutter SDK)