sublimehq / sublime_text

Issue tracker for Sublime Text
https://www.sublimetext.com
810 stars 39 forks source link

Printing doesn't respect "indent_subsequent_lines" setting #5463

Open Snackhole opened 2 years ago

Snackhole commented 2 years ago

Description of the bug

If indent_subsequent_lines is set to true (which is the default setting) and you print a plain text file with indented lines long enough to be wrapped, the subsequent wrapped lines are not indented as expected.

Screenshot 2022-06-23 121951

Steps to reproduce

  1. Start ST in safe mode.
  2. Type an indented line that is long enough to be wrapped both in ST and when printed, while indent_subsequent_lines is set to true.
  3. Print the file.

Expected behavior

The subsequent lines of the wrapped line should be indented to the same depth as the start of the line, as is displayed in ST itself due to the indent_subsequent_lines setting.

Actual behavior

The subsequent lines are not wrapped.

Sublime Text build number

4125

Operating system & version

Windows 10 and Kubuntu 20.04 LTS

(Linux) Desktop environment and/or window manager

KDE

Additional information

It appears that the print function works by generating an HTML file and sending it to the browser to be printed; so to fix this, what would need to happen is that the generated HTML is altered to respect the indent_subsequent_lines setting.

Currently, the print feature dumps the entire text of the file into a single <div> with inline CSS containing white-space: pre-wrap;, and all line breaks replaced with <br>. I suspect that, if it is agreed that this indentation behavior is a bug, the text would have to be split into multiple <div> elements on a per-line basis, with the number of leading tabs and spaces counted, an appropriate ch value for padding-left set in the CSS for each element, and the leading and trailing whitespace stripped from the actual line, with only line breaks for empty lines being replaced with <br> elements. (I assume the appropriate ch value for any given sequence of tabs and spaces could be determined using whatever code is used to render tabs and spaces in ST in the first place. I also assume the existing print code can remain in place for when indent_subsequent_lines is set to false.)

For example, take the following text:

     This line starts with two spaces, a tab, and another space, and is rendered in ST as being indented 5 spaces, since the tab in the middle counts as two spaces due to tab stops.

    This line of text is indented with 4 spaces and long enough to be wrapped, but the printed version does not indent the subsequent lines as expected.

This line of text is not indented and long enough to be wrapped, and the rest of this sentence is present to make it sufficiently long to be part of the example.

ST currently generates the following HTML to print this text:

<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta charset="UTF-8"></head><body><div style="white-space:pre-wrap;font-family:Consolas;color:#d8dee9;background-color:#303841;-moz-tab-size:4;tab-size:4;">     This line starts with two spaces, a tab, and another space, and is rendered in ST as being indented 5 spaces, since the tab in the middle counts as two spaces due to tab stops.<br><br>    This line of text is indented with 4 spaces and long enough to be wrapped, but the printed version does not indent the subsequent lines as expected.<br><br>This line of text is not indented and long enough to be wrapped, and the rest of this sentence is present to make it sufficiently long to be part of the example.</div><script>window.print()</script></body></html>

If printing respected indent_subsequent_lines: true, it might instead generate HTML like this:

<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta charset="UTF-8"></head><body><div style="white-space:pre-wrap;font-family:Consolas;color:#d8dee9;background-color:#303841;-moz-tab-size:4;tab-size:4;"><div style="padding-left:5ch;">This line starts with two spaces, a tab, and another space, and is rendered in ST as being indented 5 spaces, since the tab in the middle counts as two spaces due to tab stops.</div><br><div style="padding-left:4ch;">This line of text is indented with 4 spaces and long enough to be wrapped, but the printed version does not indent the subsequent lines as expected.</div><br><div style="padding-left:0ch;">This line of text is not indented and long enough to be wrapped, and the rest of this sentence is present to make it sufficiently long to be part of the example.</div></div><script>window.print()</script></body></html>

As a side note, since the font used is monospace, I believe the fact that padding-left: 4ch and tab-size: 4 refer to different characters to determine the rendered width shouldn't matter. The ch unit refers to the width of 0, and tab-size uses the width of the space character, but for a monospace font those are the same value anyway.

OpenGL context information

No response

Snackhole commented 2 years ago

I've created a package, with reference to html_print.py, that fixes this behavior. Attached is a zip file containing the package and the source code. It's pretty messy code since I had to work with the existing output of view.export_to_html instead of being able to edit the way the export is created in the first place. I expect there are probably bugs I wasn't able to suss out and more efficient ways of implementing it, but I've verified it seems to work with .txt files well enough for my purposes.

Better HTML Print Source.zip

Though this package solves my own problem for now, I do hope that this behavior is adopted in a future release.