astrale-sharp / typstfmt

Apache License 2.0
253 stars 25 forks source link

[feature request] Add text line wrapping #74

Closed Andrew15-5 closed 1 year ago

Andrew15-5 commented 1 year ago

Right now, long lines (of just text) are not wrapped at the specified max_line_length. As a Neovim user, it is an issue, unless I turn on the line wrapping (but this isn't a preferred way). The same can be said about VS Code (depending on the default settings, which I don't remember).

But "if you can, doesn't mean you should" can be applied in this case, since almost all programming languages talk about line wrapping (probably including LaTeX). Or you can break down long lines of code into smaller chunks, but with text in Typst you can't break it down, so the line wrapping is the only option.

Right now, the code part is wrapped and looks slim, but the text part does not, which makes the source file less pretty and uniform. In my head, wrapping text could get messy, but only in some cases, when you use (a lot of) inline Typst code (at least in LaTeX this is definitely the case). So this feature may not be perfect right away, but it's better than manual line wrapping (or use another 3rd party line wrapping formatter).

The most common use cases are these:

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.

Lorem ipsum dolor sit amet, #sym.suit.heart consectetur _adipiscing_ *elit*, sed #strong[do] eiusmod #text(fill: green)[tempor] incididunt $E = m c^2$ ut labore.

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.
  + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.

- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.

/ Lorem: ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.

Which should be formatted like this (for max_line_length = 80 and indent_space = 2):

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore.

Lorem ipsum dolor sit amet, #sym.suit.heart consectetur _adipiscing_ *elit*, sed
#strong[do] eiusmod #text(fill: green)[tempor] incididunt $E = m c^2$ ut labore.

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
  incididunt ut labore.
  + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
    tempor incididunt ut labore.

- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
  incididunt ut labore.

/ Lorem: ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
  tempor incididunt ut labore.

Note that it's all ASCII characters, but Unicode should be supported, so

In VS Code, the Japanese row with 80 (visible) characters is ~1.66 times longer than English/Russian row:

image

Even if it looks like it uses monospaced font, it doesn't translate well (I wonder why) to Japanese wide characters (not exactly 2 times wider as in Neovim).

We can discuss the case with wide Unicode characters, but for now at least normal width characters should be supported.


Also note that = heading line doesn't support multiline syntax.

I also remembered the fact that there could be many short text lines (which are all from the same paragraph), which are combined, making up a very long line. I think this "combine into 1 line and wrap into multiple lines" approach (way of thinking) is also nice. By this, I mean that the formatter should not only slice/wrap long lines, but also make sure that all lines have the maximum amount of text allowed (by max_line_length). Simple example:

Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magnam aliquam quaerat
voluptatem.
Ut enim aeque
doleamus animo, cum corpore dolemus, fieri.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim aeque
doleamus animo, cum corpore dolemus, fieri.

And returning to the = heading line(s), if it's right on top of the paragraph lines (no empty lines), then it should be ignored/not touched.

Update: missed "correct" formatting for - and / lines (fixed them).

astrale-sharp commented 1 year ago

Absolutly, I've been thinking about this and it should be a thing, the most simple way to implement it (and that'll be my starting point): "if you add this, will the line be too long, yes? break then" where this is a syntactical entity (you can't insert a line between # and my_var for instance.

That's going to be a priority of mine, expect it soon

astrale-sharp commented 1 year ago

I worked a bit on this, it's done but it broke 5 other things, you can see it in a branch i pushed, it's a bit of trouble but it'll happen

astrale-sharp commented 1 year ago

I don't think it's bug free but It should be implemented! I'm releasing a new version as well!