diff --git a/.gitignore b/.gitignore index 374deb4b..73aa79d1 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,6 @@ coverage.xml .coverage .vscode/tasks.json todo.txt + +tags +.vimrc \ No newline at end of file diff --git a/features/format.feature b/features/format.feature index 77d36d71..20a4adc5 100644 --- a/features/format.feature +++ b/features/format.feature @@ -302,9 +302,9 @@ Feature: Custom formats Scenario Outline: Export fancy with small linewrap Given we use the config ".yaml" And we use the password "test" if prompted - When we run "jrnl --config-override linewrap 12 --format fancy -3" + When we run "jrnl --config-override linewrap 35 --format fancy -3" Then we should get no error - And the output should be "12" columns wide + And the output should be 35 columns wide Examples: configs | config | diff --git a/features/steps/export_steps.py b/features/steps/export_steps.py index f885591c..6ffd89af 100644 --- a/features/steps/export_steps.py +++ b/features/steps/export_steps.py @@ -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() diff --git a/jrnl/exception.py b/jrnl/exception.py index 82a562a0..9c161992 100644 --- a/jrnl/exception.py +++ b/jrnl/exception.py @@ -30,7 +30,21 @@ 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 + to display the timestamps in the configured time format. + """ + ), + "LineWrapTooSmallForFancy": textwrap.dedent( + """ + The provided linewrap value of {config_linewrap} is too small + to properly format journal contents in fancy/boxed format. + Either provide a larger value for the linewrap or display the + journal in another format. + """ + ), } return error_messages[self.error_type].format(**kwargs) diff --git a/jrnl/plugins/fancy_exporter.py b/jrnl/plugins/fancy_exporter.py index 74cc6958..af6c19da 100644 --- a/jrnl/plugins/fancy_exporter.py +++ b/jrnl/plugins/fancy_exporter.py @@ -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,18 @@ 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 ] + cls.check_linewrap(linewrap, card) 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) @@ -70,6 +75,13 @@ class FancyExporter(TextExporter): card.append(cls.border_l + cls.border_b * body_linewrap + cls.border_m) return "\n".join(card) + @classmethod + def check_linewrap(cls, linewrap, card): + if len(card[0]) > linewrap: + raise JrnlError("LineWrapTooSmallForDateFormat", config_linewrap=linewrap) + else: + pass + @classmethod def export_journal(cls, journal): """Returns a unicode representation of an entire journal.""" diff --git a/tests/test_export.py b/tests/test_export.py new file mode 100644 index 00000000..6419acb8 --- /dev/null +++ b/tests/test_export.py @@ -0,0 +1,39 @@ +from jrnl.exception import JrnlError +from jrnl.plugins.fancy_exporter import FancyExporter + + +import pytest + + +@pytest.fixture() +def datestr(): + + yield "2020-10-20 16:59" + + +from textwrap import TextWrapper + + +def provide_date_wrapper(initial_linewrap): + wrapper = TextWrapper( + width=initial_linewrap, initial_indent=" ", subsequent_indent=" " + ) + return wrapper + + +def build_card_header(datestr): + top_left_corner = "┎─╮" + content = top_left_corner + datestr + return content + + +class TestFancy: + def test_too_small_linewrap(self, datestr): + + content = build_card_header(datestr) + + total_linewrap = 12 + + with pytest.raises(JrnlError) as e: + FancyExporter.check_linewrap(total_linewrap, [content]) + assert e.value.error_type == "LineWrapTooSmallForDateFormat"