Skip to content

Commit

Permalink
fix(ib): Inline HTML tags and support for sub, sup tags (#116)
Browse files Browse the repository at this point in the history
Signed-off-by: Manjot Sidhu <manjot.techie@gmail.com>
  • Loading branch information
manjotsidhu committed Jul 27, 2021
1 parent e8186b6 commit cbc9eb9
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 2 deletions.
24 changes: 24 additions & 0 deletions lib/ui/views/ib/builders/ib_subscript_builder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:markdown/markdown.dart' as md;
import 'package:mobile_app/utils/unicode_map.dart';

class IbSubscriptBuilder extends MarkdownElementBuilder {
@override
Widget visitElementAfter(md.Element element, TextStyle preferredStyle) {
final textContent = element.textContent;

// We don't currently have a way to control the vertical alignment of text spans.
// See https://github.com/flutter/flutter/issues/10906#issuecomment-385723664
// Also, SelectableText for flutter_markdown doesn't supports WidgetSpan

var text = '';
for (var i = 0; i < textContent.length; i++) {
if (UnicodeMap.containsKey(textContent[i])) {
text += UnicodeMap[textContent[i]][1];
}
}

return SelectableText.rich(TextSpan(text: text));
}
}
24 changes: 24 additions & 0 deletions lib/ui/views/ib/builders/ib_superscript_builder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:markdown/markdown.dart' as md;
import 'package:mobile_app/utils/unicode_map.dart';

class IbSuperscriptBuilder extends MarkdownElementBuilder {
@override
Widget visitElementAfter(md.Element element, TextStyle preferredStyle) {
final textContent = element.textContent;

// We don't currently have a way to control the vertical alignment of text spans.
// See https://github.com/flutter/flutter/issues/10906#issuecomment-385723664
// Also, SelectableText for flutter_markdown doesn't supports WidgetSpan

var text = '';
for (var i = 0; i < textContent.length; i++) {
if (UnicodeMap.containsKey(textContent[i])) {
text += UnicodeMap[textContent[i]][0];
}
}

return SelectableText.rich(TextSpan(text: text));
}
}
17 changes: 15 additions & 2 deletions lib/ui/views/ib/ib_page_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ import 'package:mobile_app/ui/views/base_view.dart';
import 'package:mobile_app/ui/views/ib/builders/ib_chapter_contents_builder.dart';
import 'package:mobile_app/ui/views/ib/builders/ib_interaction_builder.dart';
import 'package:mobile_app/ui/views/ib/builders/ib_pop_quiz_builder.dart';
import 'package:mobile_app/ui/views/ib/builders/ib_subscript_builder.dart';
import 'package:mobile_app/ui/views/ib/builders/ib_superscript_builder.dart';
import 'package:mobile_app/ui/views/ib/builders/ib_webview_builder.dart';
import 'package:mobile_app/ui/views/ib/syntaxes/ib_embed_syntax.dart';
import 'package:mobile_app/ui/views/ib/syntaxes/ib_filter_syntax.dart';
import 'package:mobile_app/ui/views/ib/syntaxes/ib_inline_html_syntax.dart';
import 'package:mobile_app/ui/views/ib/syntaxes/ib_liquid_syntax.dart';
import 'package:mobile_app/ui/views/ib/syntaxes/ib_md_tag_syntax.dart';
import 'package:mobile_app/utils/url_launcher.dart';
Expand Down Expand Up @@ -124,6 +127,11 @@ class _IbPageViewState extends State<IbPageView> {
}

Widget _buildMarkdown(IbMd data) {
final _inlineBuilders = {
'sup': IbSuperscriptBuilder(),
'sub': IbSubscriptBuilder(),
};

return MarkdownBody(
data: data.content,
selectable: true,
Expand All @@ -140,15 +148,20 @@ class _IbPageViewState extends State<IbPageView> {
'interaction': IbInteractionBuilder(model: _model),
'quiz': IbPopQuizBuilder(context: context, model: _model),
},
builders: _inlineBuilders,
extensionSet: md.ExtensionSet(
[
IbEmbedSyntax(),
IbFilterSyntax(),
IbMdTagSyntax(),
IbLiquidSyntax(),
...md.ExtensionSet.gitHubFlavored.blockSyntaxes
...md.ExtensionSet.gitHubFlavored.blockSyntaxes,
],
[
IbInlineHtmlSyntax(builders: _inlineBuilders),
md.EmojiSyntax(),
...md.ExtensionSet.gitHubFlavored.inlineSyntaxes,
],
[md.EmojiSyntax(), ...md.ExtensionSet.gitHubFlavored.inlineSyntaxes],
),
styleSheet: MarkdownStyleSheet(
h1: Theme.of(context).textTheme.headline4.copyWith(
Expand Down
22 changes: 22 additions & 0 deletions lib/ui/views/ib/syntaxes/ib_inline_html_syntax.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:markdown/markdown.dart' as md;

class IbInlineHtmlSyntax extends md.InlineSyntax {
Map<String, MarkdownElementBuilder> builders;

IbInlineHtmlSyntax({@required this.builders}) : super(_pattern);

static const String _pattern = r'<(\S*?)[^>]*>(.*?)<\/\1>|<.*?\/>';

@override
bool onMatch(md.InlineParser parser, Match match) {
if (match[1] != null &&
match[2] != null &&
builders.containsKey(match[1].trim())) {
parser.addNode(md.Element.text(match[1].trim(), match[2].trim()));
}

return true;
}
}
83 changes: 83 additions & 0 deletions lib/utils/unicode_map.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/// Unicode Map for Subscript and Subscript character
var UnicodeMap = {
' ': [' ', ' '],
'0': ['\u2070', '\u2080'],
'1': ['\u00B9', '\u2081'],
'2': ['\u00B2', '\u2082'],
'3': ['\u00B3', '\u2083'],
'4': ['\u2074', '\u2084'],
'5': ['\u2075', '\u2085'],
'6': ['\u2076', '\u2086'],
'7': ['\u2077', '\u2087'],
'8': ['\u2078', '\u2088'],
'9': ['\u2079', '\u2089'],
'a': ['\u1d43', '\u2090'],
'b': ['\u1d47', '?'],
'c': ['\u1d9c', '?'],
'd': ['\u1d48', '?'],
'e': ['\u1d49', '\u2091'],
'f': ['\u1da0', '?'],
'g': ['\u1d4d', '?'],
'h': ['\u02b0', '\u2095'],
'i': ['\u2071', '\u1d62'],
'j': ['\u02b2', '\u2c7c'],
'k': ['\u1d4f', '\u2096'],
'l': ['\u02e1', '\u2097'],
'm': ['\u1d50', '\u2098'],
'n': ['\u207f', '\u2099'],
'o': ['\u1d52', '\u2092'],
'p': ['\u1d56', '\u209a'],
'q': ['?', '?'],
'r': ['\u02b3', '\u1d63'],
's': ['\u02e2', '\u209b'],
't': ['\u1d57', '\u209c'],
'u': ['\u1d58', '\u1d64'],
'v': ['\u1d5b', '\u1d65'],
'w': ['\u02b7', '?'],
'x': ['\u02e3', '\u2093'],
'y': ['\u02b8', '?'],
'z': ['?', '?'],
'A': ['\u1d2c', '?'],
'B': ['\u1d2e', '?'],
'C': ['?', '?'],
'D': ['\u1d30', '?'],
'E': ['\u1d31', '?'],
'F': ['?', '?'],
'G': ['\u1d33', '?'],
'H': ['\u1d34', '?'],
'I': ['\u1d35', '?'],
'J': ['\u1d36', '?'],
'K': ['\u1d37', '?'],
'L': ['\u1d38', '?'],
'M': ['\u1d39', '?'],
'N': ['\u1d3a', '?'],
'O': ['\u1d3c', '?'],
'P': ['\u1d3e', '?'],
'Q': ['?', '?'],
'R': ['\u1d3f', '?'],
'S': ['?', '?'],
'T': ['\u1d40', '?'],
'U': ['\u1d41', '?'],
'V': ['\u2c7d', '?'],
'W': ['\u1d42', '?'],
'X': ['?', '?'],
'Y': ['?', '?'],
'Z': ['?', '?'],
'+': ['\u207A', '\u208A'],
'-': ['\u207B', '\u208B'],
'=': ['\u207C', '\u208C'],
'[': ['\u207D', '\u208D'],
']': ['\u207E', '\u208E'],
':alpha': ['\u1d45', '?'],
':beta': ['\u1d5d', '\u1d66'],
':gamma': ['\u1d5e', '\u1d67'],
':delta': ['\u1d5f', '?'],
':epsilon': ['\u1d4b', '?'],
':theta': ['\u1dbf', '?'],
':iota': ['\u1da5', '?'],
':pho': ['?', '\u1d68'],
':phi': ['\u1db2', '?'],
':psi': ['\u1d60', '\u1d69'],
':chi': ['\u1d61', '\u1d6a'],
':coffee': ['\u2615', '\u2615']
};

0 comments on commit cbc9eb9

Please sign in to comment.