More graceful handling of low linewrap values (#1219)

* behavior outline

* enforce positive initial linewrap

Check column widths

update gitignore

throw error when linewrap too small

simply check for large enough linewrap value

* delete unused error message

* PR feedback

make exception more informative

update check_linewrap signature in src and test

make check_linewrap a free function

* delete unused function

* delete else..pass block

* newline for make format
This commit is contained in:
Suhas 2021-04-10 19:49:56 -04:00 committed by GitHub
parent 1f19bd9f1e
commit dd74b14d76
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 79 additions and 2 deletions

View file

@ -323,6 +323,22 @@ Feature: Custom formats
| basic_folder |
| basic_dayone |
Scenario Outline: Export fancy with small linewrap
Given we use the config "<config>.yaml"
And we use the password "test" if prompted
When we run "jrnl --config-override linewrap 35 --format fancy -3"
Then we should get no error
And the output should be 35 columns wide
Examples: configs
| config |
| basic_onefile |
| basic_encrypted |
| basic_folder |
| basic_dayone |
@todo
Scenario Outline: Exporting fancy
# Needs better emoji support

View file

@ -12,6 +12,14 @@ from behave import given
from behave import then
@then("the output should be {width:d} columns wide")
def check_output_width(context, width):
out = context.stdout_capture.getvalue()
out_lines = out.splitlines()
for line in out_lines:
assert len(line) <= width
@then("the output should be parsable as json")
def check_output_json(context):
out = context.stdout_capture.getvalue()

View file

@ -30,7 +30,15 @@ class JrnlError(Exception):
Removing this file will allow jrnl to save its configuration.
"""
)
),
"LineWrapTooSmallForDateFormat": textwrap.dedent(
"""
The provided linewrap value of {config_linewrap} is too small by {columns} columns
to display the timestamps in the configured time format for journal {journal}.
You can avoid this error by specifying a linewrap value that is larger by at least {columns} in the configuration file or by using --config-override at the command line
"""
),
}
return error_messages[self.error_type].format(**kwargs)

View file

@ -3,6 +3,7 @@
# Copyright (C) 2012-2021 jrnl contributors
# License: https://www.gnu.org/licenses/gpl-3.0.html
from jrnl.exception import JrnlError
from textwrap import TextWrapper
from .text_exporter import TextExporter
@ -14,12 +15,14 @@ class FancyExporter(TextExporter):
names = ["fancy", "boxed"]
extension = "txt"
# Top border of the card
border_a = ""
border_b = ""
border_c = ""
border_d = ""
border_e = ""
border_f = ""
border_g = ""
border_h = ""
border_i = ""
@ -33,16 +36,19 @@ class FancyExporter(TextExporter):
"""Returns a fancy unicode representation of a single entry."""
date_str = entry.date.strftime(entry.journal.config["timeformat"])
linewrap = entry.journal.config["linewrap"] or 78
initial_linewrap = linewrap - len(date_str) - 2
initial_linewrap = max((1, linewrap - len(date_str) - 2))
body_linewrap = linewrap - 2
card = [
cls.border_a + cls.border_b * (initial_linewrap) + cls.border_c + date_str
]
check_provided_linewrap_viability(linewrap, card, entry.journal)
w = TextWrapper(
width=initial_linewrap,
initial_indent=cls.border_g + " ",
subsequent_indent=cls.border_g + " ",
)
title_lines = w.wrap(entry.title)
card.append(
title_lines[0].ljust(initial_linewrap + 1)
@ -74,3 +80,14 @@ class FancyExporter(TextExporter):
def export_journal(cls, journal):
"""Returns a unicode representation of an entire journal."""
return "\n".join(cls.export_entry(entry) for entry in journal)
def check_provided_linewrap_viability(linewrap, card, journal):
if len(card[0]) > linewrap:
width_violation = len(card[0]) - linewrap
raise JrnlError(
"LineWrapTooSmallForDateFormat",
config_linewrap=linewrap,
columns=width_violation,
journal=journal,
)

28
tests/test_export.py Normal file
View file

@ -0,0 +1,28 @@
from jrnl.exception import JrnlError
from jrnl.plugins.fancy_exporter import check_provided_linewrap_viability
import pytest
@pytest.fixture()
def datestr():
yield "2020-10-20 16:59"
def build_card_header(datestr):
top_left_corner = "┎─╮"
content = top_left_corner + datestr
return content
class TestFancy:
def test_too_small_linewrap(self, datestr):
journal = "test_journal"
content = build_card_header(datestr)
total_linewrap = 12
with pytest.raises(JrnlError) as e:
check_provided_linewrap_viability(total_linewrap, [content], journal)
assert e.value.error_type == "LineWrapTooSmallForDateFormat"