Pretty print journal entries (#692)

* Pretty print journal entry titles and dates.

Changes appearance of all jrnl viewing commands, such as $ jrnl --short and
$ jrnl -n {NUM}.

Fix #508

* Removed extra newline at end of title

* Use ansiwrap to properly wrap strings with ANSI escapes

* Add ansiwrap to pyproject.toml

* Allow configuration of colors

- Replaced raw escapes with colorama
- Added colors key to config
- Add checks for validity of color values

* Add color configuration documentation

* Fix broken tests due to config change

* Add tests for colors in configs

- Identifying invalid color configs
- Upgrading config from no colors -> colors

* Add colorama dependency for all platforms

* Allow users to disable colorization of output

* Update poetry.lock

* Add tag and body color customization options

* Fix colorization of tags in title and body

* Updated tests to use no color by default

* Change pass to continue in verify_config()

* Better style in Entry.py

* Reduce code duplication for tag highlighting

- Breaks "unreadable date" regression test for unknown reason

* Properly colorize tags and print body

* Reformatting and clean up

* Replace list comprehension with generator

* Handle invalid colors by not using a color

* Process ANSI escapes properly with behave

* Fixed the 'spaces after tags directly next to punctuation' bug

Broke processing of tags next to any punctuation at all

* Closer to working tag colorization but not perfect

* Add tests printing for multiline journals

Fix #717

* Correctly indent first line of multiline entry

* Add test for multiline entries with tags

* Remove redundant UNICODE flag

* Progress towards proper tag colorization and body formatting

* Fix newline colorization bug

Debug code left intact since there are more bugs to fix :/

* And now the space just ends up before the tag instead of after it

* Fix assertion syntax warning

* Moved tag test to tagging.feature file

* Strip out debug code and clean up

* Bold datetimes in title

* Bold all titles

Fix #720

* Remove PY2 and PY3 constants

* Fix regression in features/steps/core.py

* Fix tag_regex

* Remove redundant re.UNICODE flag

* Remove extraneous code
This commit is contained in:
Aaron Lichtman 2019-11-19 04:56:57 +01:00
parent 6985de2844
commit 9e5d160bbd
24 changed files with 835 additions and 119 deletions

View file

@ -1,9 +1,9 @@
#!/usr/bin/env python
import re
import textwrap
import ansiwrap
from datetime import datetime
from .util import split_title
from .util import split_title, colorize, highlight_tags_with_background_color
class Entry:
@ -49,7 +49,7 @@ class Entry:
@staticmethod
def tag_regex(tagsymbols):
pattern = fr"(?u)(?:^|\s)([{tagsymbols}][-+*#/\w]+)"
pattern = fr"(?<!\S)([{tagsymbols}][-+*#/\w]+)"
return re.compile(pattern)
def _parse_tags(self):
@ -73,31 +73,77 @@ class Entry:
def pprint(self, short=False):
"""Returns a pretty-printed version of the entry.
If short is true, only print the title."""
date_str = self.date.strftime(self.journal.config["timeformat"])
# Handle indentation
if self.journal.config["indent_character"]:
indent = self.journal.config["indent_character"].rstrip() + " "
else:
indent = ""
date_str = colorize(
self.date.strftime(self.journal.config["timeformat"]),
self.journal.config["colors"]["date"],
bold=True,
)
if not short and self.journal.config["linewrap"]:
title = textwrap.fill(
date_str + " " + self.title, self.journal.config["linewrap"]
# Color date / title and bold title
title = ansiwrap.fill(
date_str
+ " "
+ highlight_tags_with_background_color(
self,
self.title,
self.journal.config["colors"]["title"],
is_title=True,
),
self.journal.config["linewrap"],
)
body = "\n".join(
[
textwrap.fill(
body = highlight_tags_with_background_color(
self, self.body.rstrip(" \n"), self.journal.config["colors"]["body"]
)
body_text = [
colorize(
ansiwrap.fill(
line,
self.journal.config["linewrap"],
initial_indent=indent,
subsequent_indent=indent,
drop_whitespace=True,
)
or indent
for line in self.body.rstrip(" \n").splitlines()
),
self.journal.config["colors"]["body"],
)
or indent
for line in body.rstrip(" \n").splitlines()
]
# ansiwrap doesn't handle lines with only the "\n" character and some
# ANSI escapes properly, so we have this hack here to make sure the
# beginning of each line has the indent character and it's colored
# properly. textwrap doesn't have this issue, however, it doesn't wrap
# the strings properly as it counts ANSI escapes as literal characters.
# TL;DR: I'm sorry.
body = "\n".join(
[
colorize(indent, self.journal.config["colors"]["body"]) + line
if not ansiwrap.strip_color(line).startswith(indent)
else line
for line in body_text
]
)
else:
title = date_str + " " + self.title.rstrip("\n ")
body = self.body.rstrip("\n ")
title = (
date_str
+ " "
+ highlight_tags_with_background_color(
self,
self.title.rstrip("\n"),
self.journal.config["colors"]["title"],
is_title=True,
)
)
body = highlight_tags_with_background_color(
self, self.body.rstrip("\n "), self.journal.config["colors"]["body"]
)
# Suppress bodies that are just blanks and new lines.
has_body = len(self.body) > 20 or not all(