Implementation
void toolbarFormat(
TextEditingController data, String type, FocusNode focusNode) {
final int selectStart = data.selection.start;
final int selectEnd = data.selection.end;
switch (type) {
case "H1":
final RegExpMatch? match = RegExp("^(#){1,6} ")
.firstMatch(data.text.substring(selectStart, selectEnd));
if (match != null) {
/* cancel header */
data.text =
"${data.text.substring(0, selectStart)}# ${data.text.substring(selectStart + (match.end - match.start), data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 2,
extentOffset: selectEnd - (match.end - match.start - 2));
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}# ${data.text.substring(selectStart, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 2, extentOffset: selectEnd + 2);
focusNode.requestFocus();
}
break;
case "H2":
final RegExpMatch? match = RegExp("^(#){1,6} ")
.firstMatch(data.text.substring(selectStart, selectEnd));
if (match != null) {
/* cancel header */
data.text =
"${data.text.substring(0, selectStart)}## ${data.text.substring(selectStart + (match.end - match.start), data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 3,
extentOffset: selectEnd - (match.end - match.start - 3));
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}## ${data.text.substring(selectStart, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 3, extentOffset: selectEnd + 3);
focusNode.requestFocus();
}
break;
case "H3":
final RegExpMatch? match = RegExp("^(#){1,6} ")
.firstMatch(data.text.substring(selectStart, selectEnd));
if (match != null) {
/* cancel header */
data.text =
"${data.text.substring(0, selectStart)}### ${data.text.substring(selectStart + (match.end - match.start), data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 4,
extentOffset: selectEnd - (match.end - match.start - 4));
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}### ${data.text.substring(selectStart, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 4, extentOffset: selectEnd + 4);
focusNode.requestFocus();
}
break;
case "H4":
final RegExpMatch? match = RegExp("^(#){1,6} ")
.firstMatch(data.text.substring(selectStart, selectEnd));
if (match != null) {
/* cancel header */
data.text =
"${data.text.substring(0, selectStart)}#### ${data.text.substring(selectStart + (match.end - match.start), data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 5,
extentOffset: selectEnd - (match.end - match.start - 5));
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}#### ${data.text.substring(selectStart, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 5, extentOffset: selectEnd + 5);
focusNode.requestFocus();
}
break;
case "H5":
final RegExpMatch? match = RegExp("^(#){1,6} ")
.firstMatch(data.text.substring(selectStart, selectEnd));
if (match != null) {
data.text =
"${data.text.substring(0, selectStart)}##### ${data.text.substring(selectStart + (match.end - match.start), data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 6,
extentOffset: selectEnd - (match.end - match.start - 6));
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}##### ${data.text.substring(selectStart, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 6, extentOffset: selectEnd + 6);
focusNode.requestFocus();
}
break;
case "H6":
final RegExpMatch? match = RegExp("^(#){1,6} ")
.firstMatch(data.text.substring(selectStart, selectEnd));
if (match != null) {
data.text =
"${data.text.substring(0, selectStart)}###### ${data.text.substring(selectStart + (match.end - match.start), data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 7,
extentOffset: selectEnd - (match.end - match.start - 7));
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}###### ${data.text.substring(selectStart, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 7, extentOffset: selectEnd + 7);
focusNode.requestFocus();
}
break;
case "Bold":
final String destination = data.text.substring(selectStart, selectEnd);
final RegExpMatch? match =
RegExp(r"\*\*(.*?)\*\*").firstMatch(destination);
if (match != null) {
data.text = data.text.substring(0, selectStart + match.start) +
destination.substring(match.start + 2, match.end - 2) +
data.text.substring(
selectEnd - destination.length + match.end, data.text.length);
data.selection = TextSelection(
baseOffset: selectStart, extentOffset: selectEnd - 4);
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}**${data.text.substring(selectStart, selectEnd)}**${data.text.substring(selectEnd, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart, extentOffset: selectEnd + 4);
focusNode.requestFocus();
}
break;
case "Del":
final String destination = data.text.substring(selectStart, selectEnd);
final RegExpMatch? match = RegExp("~~(.*?)~~").firstMatch(destination);
if (match != null) {
data.text = data.text.substring(0, selectStart + match.start) +
destination.substring(match.start + 2, match.end - 2) +
data.text.substring(
selectEnd - destination.length + match.end, data.text.length);
data.selection = TextSelection(
baseOffset: selectStart, extentOffset: selectEnd - 4);
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}~~${data.text.substring(selectStart, selectEnd).replaceFirst("\n", " ")}~~${data.text.substring(selectEnd, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 2, extentOffset: selectEnd + 2);
focusNode.requestFocus();
}
break;
case "Italic":
final String destination = data.text.substring(selectStart, selectEnd);
final RegExpMatch? match = RegExp("_(.*?)_").firstMatch(destination);
if (match != null) {
data.text = data.text.substring(0, selectStart + match.start) +
destination.substring(match.start + 1, match.end - 1) +
data.text.substring(
selectEnd - destination.length + match.end, data.text.length);
data.selection = TextSelection(
baseOffset: selectStart, extentOffset: selectEnd - 2);
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}_${data.text.substring(selectStart, selectEnd).replaceFirst("\n", " ")}_${data.text.substring(selectEnd, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart, extentOffset: selectEnd + 2);
focusNode.requestFocus();
}
break;
case "Link":
data.text =
"${data.text.substring(0, selectStart)}[](${data.text.substring(selectStart, selectEnd).trimRight()})${data.text.substring(selectEnd, data.text.length)}";
data.selection =
TextSelection.fromPosition(TextPosition(offset: selectStart + 1));
focusNode.requestFocus();
break;
case "Check":
final String destination = data.text.substring(selectStart, selectEnd);
final RegExpMatch? match =
RegExp(r"^(- \[ \] )").firstMatch(destination);
if (match != null) {
data.text =
"${data.text.substring(0, selectStart)}${data.text.substring(selectStart + (match.end - match.start), data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart,
extentOffset: selectEnd - (match.end - match.start));
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}- [ ] ${data.text.substring(selectStart, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 6, extentOffset: selectEnd + 6);
focusNode.requestFocus();
}
break;
case "Uncheck":
final String destination = data.text.substring(selectStart, selectEnd);
final RegExpMatch? matcha =
RegExp(r"^(- \[x\] )").firstMatch(destination);
final RegExpMatch? matchA =
RegExp(r"^(- \[X\] )").firstMatch(destination);
if (matchA != null) {
data.text =
"${data.text.substring(0, selectStart)}${data.text.substring(selectStart + (matchA.end - matchA.start), data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart,
extentOffset: selectEnd - (matchA.end - matchA.start));
focusNode.requestFocus();
} else if (matcha != null) {
data.text =
"${data.text.substring(0, selectStart)}${data.text.substring(selectStart + (matcha.end - matcha.start), data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart,
extentOffset: selectEnd - (matcha.end - matcha.start));
} else {
data.text =
"${data.text.substring(0, selectStart)}- [x] ${data.text.substring(selectStart, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 6, extentOffset: selectEnd + 6);
focusNode.requestFocus();
}
break;
case "Photo":
data.text =
"${data.text.substring(0, selectStart)}.trimRight()})${data.text.substring(selectEnd, data.text.length)}";
data.selection =
TextSelection.fromPosition(TextPosition(offset: selectStart + 2));
focusNode.requestFocus();
break;
case "Code":
final String destination = data.text.substring(selectStart, selectEnd);
final RegExpMatch? match =
RegExp(r"```[.\s\S]+```").firstMatch(destination);
if (match != null) {
data.text = data.text.substring(0, selectStart + match.start) +
destination.substring(match.start + 3, match.end - 3) +
data.text.substring(
selectEnd - destination.length + match.end, data.text.length);
data.selection = TextSelection(
baseOffset: selectStart, extentOffset: selectEnd - 6);
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}```\n${data.text.substring(selectStart, selectEnd)}\n```${data.text.substring(selectEnd, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 4, extentOffset: selectEnd + 4);
focusNode.requestFocus();
}
break;
case "BulletList":
final String destination = data.text.substring(selectStart, selectEnd);
final RegExpMatch? match = RegExp("- ").firstMatch(destination);
if (match != null) {
data.text = data.text.substring(0, selectStart + match.start) +
destination.substring(match.start + 2, match.end) +
data.text.substring(
selectEnd - destination.length + match.end, data.text.length);
data.selection = TextSelection(
baseOffset: selectStart, extentOffset: selectEnd - 2);
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}- ${data.text.substring(selectStart, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 2, extentOffset: selectEnd + 2);
focusNode.requestFocus();
}
break;
case "NumbertList":
final String destination = data.text.substring(selectStart, selectEnd);
final Iterable<RegExpMatch> match =
RegExp(r"(?:[0-9]+\.)").allMatches(destination);
if (match.isEmpty) {
data.text =
"${data.text.substring(0, selectStart)}1. ${data.text.substring(selectStart, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 3, extentOffset: selectEnd + 3);
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectEnd)}\n${int.parse(destination.substring(match.last.start).trimLeft()[0]) + 1}. ${data.text.substring(selectEnd, data.text.length)}";
data.selection =
TextSelection.fromPosition(TextPosition(offset: selectEnd + 4));
focusNode.requestFocus();
}
break;
case "Divider":
data.text =
"${data.text.substring(0, selectStart)}---${data.text.substring(selectEnd, data.text.length)}";
data.selection =
TextSelection.fromPosition(TextPosition(offset: selectStart + 3));
focusNode.requestFocus();
break;
case "Quote":
final String destination = data.text.substring(selectStart, selectEnd);
final Iterable<RegExpMatch> match =
RegExp("^>.*").allMatches(destination);
if (match.isEmpty) {
data.text =
"${data.text.substring(0, selectStart)}> ${data.text.substring(selectStart, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart + 2, extentOffset: selectEnd + 2);
focusNode.requestFocus();
} else {
data.text =
"${data.text.substring(0, selectStart)}${data.text.substring(selectStart + 2, data.text.length)}";
data.selection = TextSelection(
baseOffset: selectStart, extentOffset: selectEnd - 2);
focusNode.requestFocus();
}
break;
default:
data.selection =
TextSelection(baseOffset: selectStart, extentOffset: selectEnd - 2);
focusNode.requestFocus();
}
}