Inline Images / Small bugfixes
This commit is contained in:
parent
fccc925740
commit
394929861d
19
README.md
19
README.md
|
@ -1,6 +1,23 @@
|
||||||
|
|
||||||
|
![](subwrite-logo.png)
|
||||||
|
|
||||||
|
|
||||||
# subwrite
|
# subwrite
|
||||||
|
|
||||||
A Ridiculously Personalized Markdown Editor
|
A Ridiculously Personalized Markdown Editor by Sarah Jamie Lewis.
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
![](subwrite.png)
|
![](subwrite.png)
|
||||||
|
|
||||||
|
![](subwrite-spellcheck.png)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Reorderable Table of Contents / Section View
|
||||||
|
- Spellchecking / Custom Dictionary
|
||||||
|
- Inline Image Previews
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Open an issue or submit a PR!
|
||||||
|
|
|
@ -7,6 +7,7 @@ enum AnnotationType {
|
||||||
error,
|
error,
|
||||||
todo,
|
todo,
|
||||||
note,
|
note,
|
||||||
|
image,
|
||||||
}
|
}
|
||||||
|
|
||||||
class LineAnnotation {
|
class LineAnnotation {
|
||||||
|
|
|
@ -44,6 +44,15 @@ class LineFile extends ChangeNotifier {
|
||||||
(value) {
|
(value) {
|
||||||
spellchecker = value;
|
spellchecker = value;
|
||||||
status = "dictionary loaded";
|
status = "dictionary loaded";
|
||||||
|
|
||||||
|
status = "spellchecking document";
|
||||||
|
updateStatus(0.0);
|
||||||
|
notifyListeners();
|
||||||
|
spellCheckAll().then((value) {
|
||||||
|
status = "spellchecking complete";
|
||||||
|
updateStatus(1.0);
|
||||||
|
notifyListeners();
|
||||||
|
});
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -227,6 +236,7 @@ class LineFile extends ChangeNotifier {
|
||||||
status = "spellchecking document";
|
status = "spellchecking document";
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
updateStatus(0.0);
|
updateStatus(0.0);
|
||||||
|
|
||||||
spellCheckAll().then((value) {
|
spellCheckAll().then((value) {
|
||||||
status = "spellcheck complete";
|
status = "spellcheck complete";
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
@ -259,6 +269,9 @@ class LineFile extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
parse();
|
parse();
|
||||||
|
spellcheck(cursor.line - 1).then((value) {
|
||||||
|
notifyListeners();
|
||||||
|
});
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,6 +426,12 @@ class LineFile extends ChangeNotifier {
|
||||||
dotAll: true,
|
dotAll: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final _imageRegex = RegExp(
|
||||||
|
r'!\[([^\[]*)\]\((.*)\)',
|
||||||
|
caseSensitive: false,
|
||||||
|
dotAll: true,
|
||||||
|
);
|
||||||
|
|
||||||
List<Section> sections = List.empty(growable: true);
|
List<Section> sections = List.empty(growable: true);
|
||||||
|
|
||||||
Future<void> spellcheck(int i) async {
|
Future<void> spellcheck(int i) async {
|
||||||
|
@ -555,6 +574,11 @@ class LineFile extends ChangeNotifier {
|
||||||
.add(LineAnnotation(SourceLink(path, lineStart: backingLines[i].lineNumber, colStart: 0, colEnd: line.text.length + 1, lineEnd: i), "markdown", AnnotationType.highlight, "code"));
|
.add(LineAnnotation(SourceLink(path, lineStart: backingLines[i].lineNumber, colStart: 0, colEnd: line.text.length + 1, lineEnd: i), "markdown", AnnotationType.highlight, "code"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var imageMatch = _imageRegex.matchAsPrefix(line.text);
|
||||||
|
if (imageMatch != null) {
|
||||||
|
backingLines[i].annotations.add(LineAnnotation(SourceLink(path, lineStart: backingLines[i].lineNumber, lineEnd: i), "markdown", AnnotationType.image, imageMatch.group(2)!));
|
||||||
|
}
|
||||||
|
|
||||||
_boldRegex.allMatches(backingLines[i].text).forEach((match) {
|
_boldRegex.allMatches(backingLines[i].text).forEach((match) {
|
||||||
backingLines[i]
|
backingLines[i]
|
||||||
.annotations
|
.annotations
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
|
@ -54,6 +55,11 @@ class LineInfo extends ChangeNotifier {
|
||||||
|
|
||||||
sidebarContent.addAll(icons);
|
sidebarContent.addAll(icons);
|
||||||
|
|
||||||
|
LineAnnotation? image;
|
||||||
|
if (annotations.any((element) => element.annotationType == AnnotationType.image)) {
|
||||||
|
image = annotations.firstWhere((element) => element.annotationType == AnnotationType.image);
|
||||||
|
}
|
||||||
|
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
var usableSize = (constraints.maxWidth - gutterWidth - rightMargin - leftMargin).floorToDouble();
|
var usableSize = (constraints.maxWidth - gutterWidth - rightMargin - leftMargin).floorToDouble();
|
||||||
|
@ -79,18 +85,39 @@ class LineInfo extends ChangeNotifier {
|
||||||
|
|
||||||
var idealHeight = (lineHeight * (1.0 + ((text.length * charWidth) / usableSize).floorToDouble())).ceilToDouble();
|
var idealHeight = (lineHeight * (1.0 + ((text.length * charWidth) / usableSize).floorToDouble())).ceilToDouble();
|
||||||
|
|
||||||
var highlightedLineContainer = Container(
|
if (cursorStart != null || image == null) {
|
||||||
padding: EdgeInsets.zero,
|
var highlightedLineContainer = Container(
|
||||||
margin: EdgeInsets.only(right: rightMargin, top: 0, bottom: 0, left: leftMargin),
|
padding: EdgeInsets.zero,
|
||||||
decoration: BoxDecoration(
|
margin: EdgeInsets.only(right: rightMargin, top: 0, bottom: 0, left: leftMargin),
|
||||||
color: backgroundStyle.backgroundColor,
|
decoration: BoxDecoration(
|
||||||
),
|
color: backgroundStyle.backgroundColor,
|
||||||
width: usableSize,
|
),
|
||||||
height: idealHeight,
|
width: usableSize,
|
||||||
child: highlightedLine,
|
height: idealHeight,
|
||||||
);
|
child: highlightedLine,
|
||||||
|
);
|
||||||
|
|
||||||
stackElements.add(highlightedLineContainer);
|
stackElements.add(highlightedLineContainer);
|
||||||
|
} else {
|
||||||
|
var file = File(image.type);
|
||||||
|
idealHeight = 250;
|
||||||
|
var imageContainer = Container(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
margin: EdgeInsets.only(right: rightMargin, top: 0, bottom: 0, left: leftMargin),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: backgroundStyle.backgroundColor,
|
||||||
|
),
|
||||||
|
width: usableSize,
|
||||||
|
child: Image.file(
|
||||||
|
file,
|
||||||
|
height: idealHeight,
|
||||||
|
width: usableSize / 2.0,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
filterQuality: FilterQuality.high,
|
||||||
|
cacheHeight: idealHeight.floor(),
|
||||||
|
));
|
||||||
|
stackElements.add(imageContainer);
|
||||||
|
}
|
||||||
|
|
||||||
if (cursorStart != null) {
|
if (cursorStart != null) {
|
||||||
var maxCharsBeforeWrapping = (usableSize / charWidth).floorToDouble();
|
var maxCharsBeforeWrapping = (usableSize / charWidth).floorToDouble();
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 131 KiB |
BIN
subwrite.png
BIN
subwrite.png
Binary file not shown.
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 129 KiB |
Loading…
Reference in New Issue