Deferring to Pandoc is not without its faults. It still requires
processing (eg. horizontal rules turning into 72 dashes). It is
significantly slower and resource hungry.
On the reverse, the markup regexps have improved over time and are able
to handle the task.
Includes:
* Moving them into an independent file
* Using named groups for clarity
* Support for multi-line list items
* Better handling of block markup at start / end of document (eg. hr)
* Better handling of the separation around block items (eg. space around a list)
MathJax loads asynchronously and can alter the height of the document.
Altering the height alters the scroll.
Ensure MathJax is either unused or finished loading before reading
scroll from the preview.
Typing while in preview mode would occasionally lead to a scrolling
glitch, where scroll would briefly be at 0, before jumping to the
location it was supposed to be in in the first case.
This happened due to the async nature of JS calls, in the following
scenario:
1. Load
2. Read started
3. Read finished
4. Read started
5. Load
6. Read finished
The results from op 4 would be invalid due to loading in-between, and
handling the result in 6 would set the wrong scroll value.
This change ensures results are discarded whenever we are waiting for
them and a new load starts.
`path_to_file`'s argument is an absolute path, which already contains a leading `/`. Having an additional slash (ie. `file:////some/path`) actually breaks things, eg. the export flow using local assets.
The problem: When a TextView *with vertical margins set* is resized, it
scrolls upwards automatically. It's not entirely clear why this happens,
but removing the top/bottom margins fixes the issue entirely.
The work-around: enforcing the scroll scale between a resize starting
and the UI becoming idle again. This is a hack, and the experience is
not great (the scroll is visibly unstable for a few ms), but it patches
and old bug in UberWriter.
The better solution: Figuring out how to prevent it from happening,
either by somehow ensuring the TextView does not do this, or by
approaching the layout differently where the margin is not set on the
TextView itself.
This is in preparation for the side-by-side preview, where the editor
needs to become more adaptable. It indirectly fixes#141, as users can
now change the desired line-length, although there is no UI setting for
it.
Scrolling is synced via scroll percentage. This works for most cases,
but breaks down on very large or complex documents. It is consistent
with the approach other editors use (eg. iA Writer), but in the future
we should explore alternatives that don't incur in edge cases.
The syncing itself is done via JavaScript. It could be argued that a
`WebExtension` is the better approach, but it is considerably more
complex for such a simple use case and it would be painful to implement
until UberWriter's build system is updated, since it requires
implementing a C extension.
Fixes#55
Pandoc's conversion to plain text converts horizontal rules to a
sequence of 72 dashes. This update ensures that subsequent dashes
are ignored when counting characters.
The new stats counter is able to count characters, words, sentences, and
reading time.
It does so more accurately than before, by leveraging Pandoc's plain
format, and a few simple regular expressions that besides accuracy, also
improve support for Asian languages. It's all done on a background
thread to avoid hogging the UI.
TextIter must not be reused in between buffer changes. This resulted in
unpredictable behavior when using search and replace. For instance,
in the following string:
This _is_ a _test_ of _search_ and _replace_
Searching for "_" and replacing with "**" sequentially would:
[0] This **is_ a _test_
[1] This ****is a _test_
[2] This ****is a **test_
[2] This ****is a ****test
Replace had similar results.
There were 2 problems.
When pasting very large documents, the height calculations will be
temporarily incorrect while the content is rendered over several frames.
This is addressed by waiting for the UI to be idle to scroll.
Additionally, the scroll time (typically 200ms) needs an adjustment as
well. Starting at 200ms, it now scales linearly with distance, amounting
to roughly 4 seconds with Pandoc's user guide.
This commit adds markup support for code blocks, styling them in a
conservative manner, similar to blockquotes, solely indenting them.
Partially fixes#90
Code-wise, this means marking up around the cursor becomes exponentially
more complex, as a change in one line can affect multiple lines. Solving
it is non-trivial, so the whole document is always marked up.
Marking up the whole document is irrelevant for small to medium
documents, but can incur in a performance penalty for
very large documents (empirical testing: 1M characters takes ~0.15s).
To alleviate this, GLib.idle_add is used to ensure that markup is only
parsed and applied when the UI is idle. Again, small to medium-sized
documents see no difference. For very large documents, markup will be
slightly delayed to allow for a fluid typing experience.
It's important to note that the previous flows frequently used full
document markup: paste, focus mode, and search and replace.
In some extreme cases, doubly parsing (eg. paste + text change).
For very large documents, doing any of these actions would freeze the UI
unconditionally, so in more ways than one this is an upgrade.
Lastly, it's a little overzealous: with over 1M characters the UI itself
struggles more than parsing.
In sum:
* Markup is always applied to the whole document
* The code is simpler
* There is never double work
* Markup is applied when the UI is idle, for a more smooth experience
* Multi-line formatting is now possible to do reliably
Changes include:
* Much better encapsulation of textview/textbuffer, with each isolated
responsibility living independently on its own class/file.
* Less code overall
* Various small fixes around the components involved, such as:
* Indentation of nested lists (fixes#120)
* Unwanted scroll on select all (ctrl+a)
* Removal of unused code around the components involved
* Fixes for scrollbar location, now at the edge of the window
Overall refactoring of how the theme is set, bounding it to the window
instead of the application, which generally makes it easier to listen
for the "style-updated" signal.
The Theme class encapsulates theme handling, by listing default themes
and providing means to access their gtk/web css.
Besides cleaning things up, it makes it easy to support custom themes
in the future. The user just needs to provide two CSS files, and we'll
be able to instantiate and use a Theme from that.
While WebKit2 is loading, it renders a blank (white) page.
This causes it to flash briefly, while the content is not yet loaded.
Waiting for it to finish using the load-change event fixes the issue.
Fixes#112