From e7da8c12a0a02708e788deec0a6af262d057a137 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Fri, 25 Oct 2019 06:59:24 +0200 Subject: [PATCH 01/41] Pretty print journal entry titles and dates. Changes appearance of all jrnl viewing commands, such as $ jrnl --short and $ jrnl -n {NUM}. Fix #508 --- jrnl/Entry.py | 9 ++++++--- jrnl/Journal.py | 4 ++-- jrnl/util.py | 13 ++++++++++++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index 1306cef5a..ba2f7dd0e 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -5,7 +5,7 @@ import re import textwrap from datetime import datetime -from .util import split_title +from .util import split_title, bold, colorize_red class Entry: @@ -79,7 +79,10 @@ def pprint(self, short=False): else: indent = "" if not short and self.journal.config['linewrap']: - title = textwrap.fill(date_str + " " + self.title, self.journal.config['linewrap']) + # Color date red and make sure first line of title is bolded + title = textwrap.fill(colorize_red(date_str) + " " + bold(self.title), self.journal.config['linewrap']) + # Make sure all lines after the first are bolded, too + title = "".join([bold(part) + "\n" for part in title.split("\n")]) body = "\n".join([ textwrap.fill( line, @@ -90,7 +93,7 @@ def pprint(self, short=False): for line in self.body.rstrip(" \n").splitlines() ]) else: - title = date_str + " " + self.title.rstrip("\n ") + title = colorize_red(date_str) + " " + bold(self.title.rstrip("\n ")) body = self.body.rstrip("\n ") # Suppress bodies that are just blanks and new lines. diff --git a/jrnl/Journal.py b/jrnl/Journal.py index 72fe94b18..4bbc8e5f4 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -152,12 +152,12 @@ def pprint(self, short=False): for tag in self.search_tags: tagre = re.compile(re.escape(tag), re.IGNORECASE) pp = re.sub(tagre, - lambda match: util.colorize(match.group(0)), + lambda match: util.colorize_cyan(match.group(0)), pp, re.UNICODE) else: pp = re.sub( Entry.Entry.tag_regex(self.config['tagsymbols']), - lambda match: util.colorize(match.group(0)), + lambda match: util.colorize_cyan(match.group(0)), pp ) return pp diff --git a/jrnl/util.py b/jrnl/util.py index bc36ba9b4..e284b8575 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -180,11 +180,22 @@ def get_text_from_editor(config, template=""): return raw -def colorize(string): +def colorize_cyan(string): """Returns the string wrapped in cyan ANSI escape""" return u"\033[36m{}\033[39m".format(string) +def colorize_red(string): + """Returns the string wrapped in red ANSI escape""" + return u"\033[91m{}\033[0m".format(string) + + +def bold(string): + """Returns the string wrapped in bold ANSI escape. Bug / feature that it + also colors the text blue, for some unknown reason.""" + return u"\033[1m{}\033[0m".format(string) + + def slugify(string): """Slugifies a string. Based on public domain code from https://github.com/zacharyvoase/slugify From 1d4bbea6c87eec0be5ace05b428d66bb9d8ccab6 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 26 Oct 2019 00:26:11 +0200 Subject: [PATCH 02/41] Removed extra newline at end of title --- jrnl/Entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index ba2f7dd0e..51a0ea432 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -82,7 +82,7 @@ def pprint(self, short=False): # Color date red and make sure first line of title is bolded title = textwrap.fill(colorize_red(date_str) + " " + bold(self.title), self.journal.config['linewrap']) # Make sure all lines after the first are bolded, too - title = "".join([bold(part) + "\n" for part in title.split("\n")]) + title = "".join([bold(part) + "\n" for part in title.split("\n")]).strip() body = "\n".join([ textwrap.fill( line, From b4bfc2c1383a19dddd6659e09dc2bfa6af8ca688 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 26 Oct 2019 02:23:11 +0200 Subject: [PATCH 03/41] Use ansiwrap to properly wrap strings with ANSI escapes --- features/steps/core.py | 8 +++++--- jrnl/Entry.py | 6 +++--- poetry.lock | 23 ++++++++++++++++++++++- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index 83981d138..1204381e8 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -5,8 +5,10 @@ from jrnl import cli, install, Journal, util, plugins from jrnl import __version__ from dateutil import parser as date_parser +from ansiwrap import strip_color from collections import defaultdict import os +import re import json import yaml import keyring @@ -170,7 +172,7 @@ def check_json_output_path(context, path, value): @then('the output should be "{text}"') def check_output(context, text=None): text = (text or context.text).strip().splitlines() - out = context.stdout_capture.getvalue().strip().splitlines() + out = strip_color(context.stdout_capture.getvalue().strip()).splitlines() assert len(text) == len(out), "Output has {} lines (expected: {})".format(len(out), len(text)) for line_text, line_out in zip(text, out): assert line_text.strip() == line_out.strip(), [line_text.strip(), line_out.strip()] @@ -178,7 +180,7 @@ def check_output(context, text=None): @then('the output should contain "{text}" in the local time') def check_output_time_inline(context, text): - out = context.stdout_capture.getvalue() + out = strip_color(context.stdout_capture.getvalue()) local_tz = tzlocal.get_localzone() utc_time = date_parser.parse(text) local_date = utc_time.astimezone(local_tz).strftime("%Y-%m-%d %H:%M") @@ -189,7 +191,7 @@ def check_output_time_inline(context, text): @then('the output should contain "{text}"') def check_output_inline(context, text=None): text = text or context.text - out = context.stdout_capture.getvalue() + out = strip_color(context.stdout_capture.getvalue()) if isinstance(out, bytes): out = out.decode('utf-8') assert text in out, text diff --git a/jrnl/Entry.py b/jrnl/Entry.py index 51a0ea432..a3fea34dc 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import re -import textwrap +import ansiwrap from datetime import datetime from .util import split_title, bold, colorize_red @@ -80,11 +80,11 @@ def pprint(self, short=False): indent = "" if not short and self.journal.config['linewrap']: # Color date red and make sure first line of title is bolded - title = textwrap.fill(colorize_red(date_str) + " " + bold(self.title), self.journal.config['linewrap']) + title = ansiwrap.fill(colorize_red(date_str) + " " + bold(self.title), self.journal.config['linewrap']) # Make sure all lines after the first are bolded, too title = "".join([bold(part) + "\n" for part in title.split("\n")]).strip() body = "\n".join([ - textwrap.fill( + ansiwrap.fill( line, self.journal.config['linewrap'], initial_indent=indent, diff --git a/poetry.lock b/poetry.lock index e772b2d26..9cfcbe160 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,14 @@ +[[package]] +category = "main" +description = "textwrap, but savvy to ANSI colors and styles" +name = "ansiwrap" +optional = false +python-versions = "*" +version = "0.8.4" + +[package.dependencies] +textwrap3 = ">=0.9.2" + [[package]] category = "dev" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." @@ -356,6 +367,14 @@ optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*" version = "1.12.0" +[[package]] +category = "main" +description = "textwrap from Python 3.6 backport (plus a few tweaks)" +name = "textwrap3" +optional = false +python-versions = "*" +version = "0.9.2" + [[package]] category = "dev" description = "Python Library for Tom's Obvious, Minimal Language" @@ -384,10 +403,11 @@ version = "1.5.1" pytz = "*" [metadata] -content-hash = "9896cf59c7552b6ad95219ee5555c7445a3fab39c2e4f4c6f3d991a36635e44b" +content-hash = "6ff68790de1a4cec0f5a1cf145ecaf3c0028571c2ab8ece0987b0af982096e98" python-versions = "^3.7" [metadata.hashes] +ansiwrap = ["7b053567c88e1ad9eed030d3ac41b722125e4c1271c8a99ade797faff1f49fb1", "ca0c740734cde59bf919f8ff2c386f74f9a369818cdc60efe94893d01ea8d9b7"] appdirs = ["9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", "d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"] asn1crypto = ["2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87", "9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49"] asteval = ["7c81fee6707a7a28e8beae891b858535a7e61f9ce275a0a4cf5f428fbc934cb8"] @@ -424,6 +444,7 @@ pyxdg = ["1948ff8e2db02156c0cccd2529b43c0cff56ebaa71f5f021bbd755bc1419190e", "fe pyyaml = ["0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9", "01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4", "5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8", "5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696", "7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34", "7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9", "87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73", "9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299", "a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b", "b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae", "b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681", "bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41", "f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"] secretstorage = ["20c797ae48a4419f66f8d28fc221623f11fc45b6828f96bdb1ad9990acb59f92", "7a119fb52a88e398dbb22a4b3eb39b779bfbace7e4153b7bc6e5954d86282a8a"] six = ["3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"] +textwrap3 = ["5008eeebdb236f6303dcd68f18b856d355f6197511d952ba74bc75e40e0c3414", "bf5f4c40faf2a9ff00a9e0791fed5da7415481054cef45bb4a3cfb1f69044ae0"] toml = ["229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", "235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e", "f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"] tornado = ["349884248c36801afa19e342a77cc4458caca694b0eda633f5878e458a44cb2c", "398e0d35e086ba38a0427c3b37f4337327231942e731edaa6e9fd1865bbd6f60", "4e73ef678b1a859f0cb29e1d895526a20ea64b5ffd510a2307b5998c7df24281", "559bce3d31484b665259f50cd94c5c28b961b09315ccd838f284687245f416e5", "abbe53a39734ef4aba061fca54e30c6b4639d3e1f59653f0da37a0003de148c7", "c845db36ba616912074c5b1ee897f8e0124df269468f25e4fe21fe72f6edd7a9", "c9399267c926a4e7c418baa5cbe91c7d1cf362d505a1ef898fde44a07c9dd8a5"] tzlocal = ["4ebeb848845ac898da6519b9b31879cf13b6626f7184c496037b818e238f2c4e"] From 75a8249f3881824cc1849d391cd20e6f6ab835e0 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 26 Oct 2019 02:34:06 +0200 Subject: [PATCH 04/41] Add ansiwrap to pyproject.toml --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 1b84acde0..2ea3c75a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ asteval = "^0.9.14" colorama = {version = "^0.4.1",platform = "win32"} python-dateutil = "^2.8" pyyaml = "^5.1" +ansiwrap = "^0.8.4" [tool.poetry.dev-dependencies] behave = "^1.2" From 01db72b9dc34ee40e2987d0e63145e1b304f7f69 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 01:05:06 +0100 Subject: [PATCH 05/41] Allow configuration of colors - Replaced raw escapes with colorama - Added colors key to config - Add checks for validity of color values --- features/steps/core.py | 1 - jrnl/Entry.py | 13 ++++++------ jrnl/Journal.py | 4 ++-- jrnl/install.py | 8 +++++++- jrnl/util.py | 46 +++++++++++++++++++++++++----------------- 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index 1204381e8..ab9b90c6d 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -8,7 +8,6 @@ from ansiwrap import strip_color from collections import defaultdict import os -import re import json import yaml import keyring diff --git a/jrnl/Entry.py b/jrnl/Entry.py index a3fea34dc..18187a435 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -5,7 +5,7 @@ import re import ansiwrap from datetime import datetime -from .util import split_title, bold, colorize_red +from .util import split_title, colorize class Entry: @@ -79,10 +79,10 @@ def pprint(self, short=False): else: indent = "" if not short and self.journal.config['linewrap']: - # Color date red and make sure first line of title is bolded - title = ansiwrap.fill(colorize_red(date_str) + " " + bold(self.title), self.journal.config['linewrap']) - # Make sure all lines after the first are bolded, too - title = "".join([bold(part) + "\n" for part in title.split("\n")]).strip() + # Color date and color / bold title and make sure first line of title is bolded + title = ansiwrap.fill(colorize(date_str, self.journal.config['colors']['date']) + " " + + colorize(self.title, self.journal.config['colors']['title'], bold=True), + self.journal.config['linewrap']) body = "\n".join([ ansiwrap.fill( line, @@ -93,7 +93,8 @@ def pprint(self, short=False): for line in self.body.rstrip(" \n").splitlines() ]) else: - title = colorize_red(date_str) + " " + bold(self.title.rstrip("\n ")) + title = colorize(date_str, self.journal.config['colors']['date']) + " " +\ + colorize(self.title.rstrip("\n"), self.journal.config['colors']['title'], bold=True) body = self.body.rstrip("\n ") # Suppress bodies that are just blanks and new lines. diff --git a/jrnl/Journal.py b/jrnl/Journal.py index 4bbc8e5f4..886045a66 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -152,12 +152,12 @@ def pprint(self, short=False): for tag in self.search_tags: tagre = re.compile(re.escape(tag), re.IGNORECASE) pp = re.sub(tagre, - lambda match: util.colorize_cyan(match.group(0)), + lambda match: util.colorize(match.group(0), "CYAN"), pp, re.UNICODE) else: pp = re.sub( Entry.Entry.tag_regex(self.config['tagsymbols']), - lambda match: util.colorize_cyan(match.group(0)), + lambda match: util.colorize(match.group(0), "CYAN"), pp ) return pp diff --git a/jrnl/install.py b/jrnl/install.py index 5a80562fb..c0fc7dd64 100644 --- a/jrnl/install.py +++ b/jrnl/install.py @@ -12,7 +12,7 @@ from . import __version__ from .Journal import PlainJournal from .EncryptedJournal import EncryptedJournal -from .util import UserAbort +from .util import UserAbort, verify_config import yaml import logging import sys @@ -42,6 +42,7 @@ def module_exists(module_name): else: return True + default_config = { 'version': __version__, 'journals': { @@ -57,6 +58,10 @@ def module_exists(module_name): 'highlight': True, 'linewrap': 79, 'indent_character': '|', + 'colors': { + 'date': 'red', + 'title': 'blue', + }, } @@ -98,6 +103,7 @@ def load_or_install_jrnl(): sys.exit(1) upgrade_config(config) + verify_config(config) return config else: diff --git a/jrnl/util.py b/jrnl/util.py index e284b8575..e96fd2207 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -8,8 +8,8 @@ import os import getpass as gp import yaml +import colorama if "win32" in sys.platform: - import colorama colorama.init() import re import tempfile @@ -30,9 +30,9 @@ TEST = False __cached_tz = None -WARNING_COLOR = "\033[33m" -ERROR_COLOR = "\033[31m" -RESET_COLOR = "\033[0m" +WARNING_COLOR = colorama.Fore.YELLOW +ERROR_COLOR = colorama.Fore.RED +RESET_COLOR = colorama.Fore.RESET # Based on Segtok by Florian Leitner # https://github.com/fnl/segtok @@ -162,6 +162,21 @@ def scope_config(config, journal_name): return config +def verify_config(config): + """ + Ensures the keys set for colors are valid colorama.Fore attributes. + :return: True if all keys are set correctly, False otherwise + """ + all_valid_colors = True + for key, color in config["colors"].items(): + if not getattr(colorama.Fore, color.upper(), None): + # TODO: Not sure whether both of these should stay or not. + print("[{2}ERROR{3}: {0} set to invalid color: {1}]".format(key, color, ERROR_COLOR, RESET_COLOR)) + log.error("Invalid color configuration value for '{0}'.".format(key)) + all_valid_colors = False + return all_valid_colors + + def get_text_from_editor(config, template=""): filehandle, tmpfile = tempfile.mkstemp(prefix="jrnl", text=True, suffix=".txt") with codecs.open(tmpfile, 'w', "utf-8") as f: @@ -180,20 +195,15 @@ def get_text_from_editor(config, template=""): return raw -def colorize_cyan(string): - """Returns the string wrapped in cyan ANSI escape""" - return u"\033[36m{}\033[39m".format(string) - - -def colorize_red(string): - """Returns the string wrapped in red ANSI escape""" - return u"\033[91m{}\033[0m".format(string) - - -def bold(string): - """Returns the string wrapped in bold ANSI escape. Bug / feature that it - also colors the text blue, for some unknown reason.""" - return u"\033[1m{}\033[0m".format(string) +def colorize(string, color, bold=False): + """Returns the string colored with colorama.Fore.color. If the color set + by the user doesn't exist in the colorama.Fore attributes, the colorization + is done with WHITE.""" + color_escape = getattr(colorama.Fore, color.upper(), colorama.Fore.WHITE) + if not bold: + return color_escape + string + colorama.Fore.RESET + else: + return colorama.Style.BRIGHT + color_escape + string + colorama.Style.RESET_ALL def slugify(string): From b2d3fc859e19a0b6f1f86e20a188885b1fa491a3 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 01:15:41 +0100 Subject: [PATCH 06/41] Add color configuration documentation --- docs/advanced.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/advanced.md b/docs/advanced.md index 2a6fd6b41..a9f528e14 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -31,8 +31,9 @@ and can be edited with any plain text editor. - `highlight` if `true`, tags will be highlighted in cyan. - `linewrap` - controls the width of the output. Set to `false` if you don't - want to wrap long lines. + controls the width of the output. Set to `false` if you don't want to wrap long lines. + - `colors` + dictionary that controls the colors used to display journal entries. It has two subkeys, which are: `date` and `title`. Current valid values are: `BLACK`, `RED`, `GREEN`, `YELLOW`, `BLUE`, `MAGENTA`, `CYAN`, and `WHITE`. `colorama.Fore` is used for colorization, and you can find the [docs here](https://github.com/tartley/colorama#colored-output). !!! note Although it seems intuitive to use the `#` From 8053d250f42acad9a13645ec503ec8e4eed2d486 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 01:51:17 +0100 Subject: [PATCH 07/41] Fix broken tests due to config change --- features/data/configs/basic.yaml | 3 +++ features/data/configs/bug153.yaml | 3 +++ features/data/configs/markdown-headings-335.yaml | 3 +++ features/data/configs/tags-216.yaml | 3 +++ features/data/configs/tags-237.yaml | 3 +++ features/data/configs/tags.yaml | 3 +++ 6 files changed, 18 insertions(+) diff --git a/features/data/configs/basic.yaml b/features/data/configs/basic.yaml index 9111b561d..01dd1c0c8 100644 --- a/features/data/configs/basic.yaml +++ b/features/data/configs/basic.yaml @@ -10,3 +10,6 @@ tagsymbols: "@" template: false timeformat: "%Y-%m-%d %H:%M" indent_character: "|" +colors: + date: red + title: green diff --git a/features/data/configs/bug153.yaml b/features/data/configs/bug153.yaml index 765185c3a..6b3096a1f 100644 --- a/features/data/configs/bug153.yaml +++ b/features/data/configs/bug153.yaml @@ -11,3 +11,6 @@ tagsymbols: '@' template: false timeformat: '%Y-%m-%d %H:%M' indent_character: "|" +colors: + date: red + title: green diff --git a/features/data/configs/markdown-headings-335.yaml b/features/data/configs/markdown-headings-335.yaml index dafed64b7..b180fcd35 100644 --- a/features/data/configs/markdown-headings-335.yaml +++ b/features/data/configs/markdown-headings-335.yaml @@ -11,3 +11,6 @@ password: '' tagsymbols: '@' timeformat: '%Y-%m-%d %H:%M' indent_character: "|" +colors: + date: red + title: green diff --git a/features/data/configs/tags-216.yaml b/features/data/configs/tags-216.yaml index 73523c509..37cfa11fe 100644 --- a/features/data/configs/tags-216.yaml +++ b/features/data/configs/tags-216.yaml @@ -11,3 +11,6 @@ password: '' tagsymbols: '@' timeformat: '%Y-%m-%d %H:%M' indent_character: "|" +colors: + date: red + title: green diff --git a/features/data/configs/tags-237.yaml b/features/data/configs/tags-237.yaml index 2b360f6fc..27b662ddb 100644 --- a/features/data/configs/tags-237.yaml +++ b/features/data/configs/tags-237.yaml @@ -11,3 +11,6 @@ password: '' tagsymbols: '@' timeformat: '%Y-%m-%d %H:%M' indent_character: "|" +colors: + date: red + title: green diff --git a/features/data/configs/tags.yaml b/features/data/configs/tags.yaml index 51a2b8b24..bb0c39c15 100644 --- a/features/data/configs/tags.yaml +++ b/features/data/configs/tags.yaml @@ -11,3 +11,6 @@ password: '' tagsymbols: '@' timeformat: '%Y-%m-%d %H:%M' indent_character: "|" +colors: + date: red + title: green From eb1ed3c0cd69cd602b6cbc5ea23d8e4daa01cc10 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 02:49:47 +0100 Subject: [PATCH 08/41] Add tests for colors in configs - Identifying invalid color configs - Upgrading config from no colors -> colors --- features/core.feature | 9 +++++++++ features/data/configs/invalid_color.yaml | 15 +++++++++++++++ features/data/configs/no_colors.yaml | 12 ++++++++++++ features/steps/core.py | 18 ++++++++++++------ features/upgrade.feature | 7 ++++++- 5 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 features/data/configs/invalid_color.yaml create mode 100644 features/data/configs/no_colors.yaml diff --git a/features/core.feature b/features/core.feature index ab86da423..dd072ba42 100644 --- a/features/core.feature +++ b/features/core.feature @@ -58,3 +58,12 @@ Feature: Basic reading and writing to a journal When we run "jrnl -on 2013-06-10 -s" Then the output should be "2013-06-10 15:40 Life is good." + Scenario: Invalid color configuration + Given we use the config "invalid_color.yaml" + When we run "jrnl -on 2013-06-10 -s" + Then the output should be + """ + [ERROR: date set to invalid color: not-a-color] + [ERROR: title set to invalid color: also-not-a-color] + 2013-06-10 15:40 Life is good. + """ diff --git a/features/data/configs/invalid_color.yaml b/features/data/configs/invalid_color.yaml new file mode 100644 index 000000000..4c2c78fc4 --- /dev/null +++ b/features/data/configs/invalid_color.yaml @@ -0,0 +1,15 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: not-a-color + title: also-not-a-color diff --git a/features/data/configs/no_colors.yaml b/features/data/configs/no_colors.yaml new file mode 100644 index 000000000..9111b561d --- /dev/null +++ b/features/data/configs/no_colors.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/simple.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/features/steps/core.py b/features/steps/core.py index ab9b90c6d..fbe8fa080 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -8,6 +8,7 @@ from ansiwrap import strip_color from collections import defaultdict import os +import ast import json import yaml import keyring @@ -234,12 +235,17 @@ def journal_doesnt_exist(context, journal_name="default"): @then('the config should have "{key}" set to "{value}"') @then('the config for journal "{journal}" should have "{key}" set to "{value}"') def config_var(context, key, value, journal=None): - t, value = value.split(":") - value = { - "bool": lambda v: v.lower() == "true", - "int": int, - "str": str - }[t](value) + if not value[0] == "{": + t, value = value.split(":") + value = { + "bool": lambda v: v.lower() == "true", + "int": int, + "str": str + }[t](value) + else: + # Handle value being a dictionary + value = ast.literal_eval(value) + config = util.load_config(install.CONFIG_FILE_PATH) if journal: config = config["journals"][journal] diff --git a/features/upgrade.feature b/features/upgrade.feature index bce026b8c..587102eb8 100644 --- a/features/upgrade.feature +++ b/features/upgrade.feature @@ -13,7 +13,7 @@ Feature: Upgrading Journals from 1.x.x to 2.x.x Scenario: Upgrading a journal encrypted with jrnl 1.x Given we use the config "encrypted_old.json" - When we run "jrnl -n 1" and enter + When we run "jrnl -n 1" and enter """ Y bad doggie no biscuit @@ -21,3 +21,8 @@ Feature: Upgrading Journals from 1.x.x to 2.x.x """ Then we should see the message "Password" and the output should contain "2013-06-10 15:40 Life is good" + + Scenario: Upgrading a config without colors to colors + Given we use the config "no_colors.yaml" + When we run "jrnl -n 1" + Then the config should have "colors" set to "{'date':'red', 'title':'blue'}" From 1a0847b38d5ee79a2fe3f6b7d6381bf2136749fc Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 02:53:37 +0100 Subject: [PATCH 09/41] Add colorama dependency for all platforms --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2ea3c75a1..f25df2919 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ keyring = "^19.0" pytz = "^2019.1" tzlocal = "^1.5" asteval = "^0.9.14" -colorama = {version = "^0.4.1",platform = "win32"} +colorama = "^0.4.1" python-dateutil = "^2.8" pyyaml = "^5.1" ansiwrap = "^0.8.4" From a23a8181068c1b9142a1322b01d3b336a133d4df Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 18:25:57 +0100 Subject: [PATCH 10/41] Allow users to disable colorization of output --- docs/advanced.md | 2 +- jrnl/util.py | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/docs/advanced.md b/docs/advanced.md index a9f528e14..e5f89139f 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -33,7 +33,7 @@ and can be edited with any plain text editor. - `linewrap` controls the width of the output. Set to `false` if you don't want to wrap long lines. - `colors` - dictionary that controls the colors used to display journal entries. It has two subkeys, which are: `date` and `title`. Current valid values are: `BLACK`, `RED`, `GREEN`, `YELLOW`, `BLUE`, `MAGENTA`, `CYAN`, and `WHITE`. `colorama.Fore` is used for colorization, and you can find the [docs here](https://github.com/tartley/colorama#colored-output). + dictionary that controls the colors used to display journal entries. It has two subkeys, which are: `date` and `title`. Current valid values are: `BLACK`, `RED`, `GREEN`, `YELLOW`, `BLUE`, `MAGENTA`, `CYAN`, and `WHITE`. `colorama.Fore` is used for colorization, and you can find the [docs here](https://github.com/tartley/colorama#colored-output). To disable colored output, set the value to `NONE`. !!! note Although it seems intuitive to use the `#` diff --git a/jrnl/util.py b/jrnl/util.py index e96fd2207..806f6d230 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -164,12 +164,15 @@ def scope_config(config, journal_name): def verify_config(config): """ - Ensures the keys set for colors are valid colorama.Fore attributes. + Ensures the keys set for colors are valid colorama.Fore attributes, or "None" :return: True if all keys are set correctly, False otherwise """ all_valid_colors = True for key, color in config["colors"].items(): - if not getattr(colorama.Fore, color.upper(), None): + upper_color = color.upper() + if upper_color == "NONE": + pass + if not getattr(colorama.Fore, upper_color, None): # TODO: Not sure whether both of these should stay or not. print("[{2}ERROR{3}: {0} set to invalid color: {1}]".format(key, color, ERROR_COLOR, RESET_COLOR)) log.error("Invalid color configuration value for '{0}'.".format(key)) @@ -196,10 +199,15 @@ def get_text_from_editor(config, template=""): def colorize(string, color, bold=False): - """Returns the string colored with colorama.Fore.color. If the color set - by the user doesn't exist in the colorama.Fore attributes, the colorization - is done with WHITE.""" - color_escape = getattr(colorama.Fore, color.upper(), colorama.Fore.WHITE) + """Returns the string colored with colorama.Fore.color. If the color set by + the user is "NONE", it returns the string without any modification. Otherwise, + If the color set by the user doesn't exist in the colorama.Fore attributes, + the colorization is done with WHITE.""" + upper_color = color.upper() + if upper_color == "NONE": + return string + + color_escape = getattr(colorama.Fore, upper_color, colorama.Fore.WHITE) if not bold: return color_escape + string + colorama.Fore.RESET else: From c63c999bc7bec295b0aaaec3ab6a41f29b0b09cc Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 18:54:00 +0100 Subject: [PATCH 11/41] Update poetry.lock --- poetry.lock | 88 +++++++++++++++++++---------------------------------- 1 file changed, 32 insertions(+), 56 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9cfcbe160..21d86fb19 100644 --- a/poetry.lock +++ b/poetry.lock @@ -17,25 +17,13 @@ optional = false python-versions = "*" version = "1.4.3" -[[package]] -category = "main" -description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP" -name = "asn1crypto" -optional = false -python-versions = "*" -version = "0.24.0" - [[package]] category = "main" description = "Safe, minimalistic evaluator of python expression using ast module" name = "asteval" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.9.14" - -[package.dependencies] -numpy = "*" -six = "*" +version = "0.9.16" [[package]] category = "dev" @@ -43,7 +31,7 @@ description = "Classes Without Boilerplate" name = "attrs" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "19.1.0" +version = "19.3.0" [[package]] category = "dev" @@ -78,7 +66,7 @@ description = "Foreign Function Interface for Python calling C code." name = "cffi" optional = false python-versions = "*" -version = "1.12.3" +version = "1.13.2" [package.dependencies] pycparser = "*" @@ -94,7 +82,6 @@ version = "7.0" [[package]] category = "main" description = "Cross-platform colored terminal text." -marker = "sys_platform == \"win32\"" name = "colorama" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" @@ -106,10 +93,9 @@ description = "cryptography is a package which provides cryptographic recipes an name = "cryptography" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "2.7" +version = "2.8" [package.dependencies] -asn1crypto = ">=0.21.0" cffi = ">=1.8,<1.11.3 || >1.11.3" six = ">=1.4.1" @@ -127,7 +113,7 @@ description = "the modular source code checker: pep8, pyflakes and co" name = "flake8" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.7.8" +version = "3.7.9" [package.dependencies] entrypoints = ">=0.3.0,<0.4.0" @@ -141,7 +127,7 @@ description = "Clean single-source support for Python 3 and 2" name = "future" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -version = "0.17.1" +version = "0.18.2" [[package]] category = "main" @@ -150,15 +136,15 @@ marker = "sys_platform == \"linux\"" name = "jeepney" optional = false python-versions = ">=3.5" -version = "0.4" +version = "0.4.1" [[package]] category = "dev" -description = "A small but fast and easy to use stand-alone template engine written in pure python." +description = "A very fast and expressive template engine." name = "jinja2" optional = false python-versions = "*" -version = "2.10.1" +version = "2.10.3" [package.dependencies] MarkupSafe = ">=0.23" @@ -169,7 +155,7 @@ description = "Store and access your passwords safely." name = "keyring" optional = false python-versions = ">=3.5" -version = "19.0.2" +version = "19.2.0" [package.dependencies] entrypoints = "*" @@ -231,21 +217,13 @@ click = ">=3.3" livereload = ">=2.5.1" tornado = ">=5.0" -[[package]] -category = "main" -description = "NumPy is the fundamental package for array computing with Python." -name = "numpy" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -version = "1.16.4" - [[package]] category = "dev" description = "parse() is the opposite of format()" name = "parse" optional = false python-versions = "*" -version = "1.12.0" +version = "1.12.1" [[package]] category = "dev" @@ -253,10 +231,10 @@ description = "Simplifies to build parse types based on the parse module" name = "parse-type" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*" -version = "0.4.2" +version = "0.5.2" [package.dependencies] -parse = ">=1.8" +parse = ">=1.8.4" six = ">=1.11" [[package]] @@ -307,8 +285,8 @@ category = "main" description = "Extensions to the standard Python datetime module" name = "python-dateutil" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -version = "2.8.0" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +version = "2.8.1" [package.dependencies] six = ">=1.5" @@ -319,7 +297,7 @@ description = "World timezone definitions, modern and historical" name = "pytz" optional = false python-versions = "*" -version = "2019.1" +version = "2019.3" [[package]] category = "main" @@ -365,7 +343,7 @@ description = "Python 2 and 3 compatibility utilities" name = "six" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*" -version = "1.12.0" +version = "1.13.0" [[package]] category = "main" @@ -403,47 +381,45 @@ version = "1.5.1" pytz = "*" [metadata] -content-hash = "6ff68790de1a4cec0f5a1cf145ecaf3c0028571c2ab8ece0987b0af982096e98" +content-hash = "22be2bc81609baae93ffdee9d5cb4d455d9cae13f56cf10eacc36258a1ea510a" python-versions = "^3.7" [metadata.hashes] ansiwrap = ["7b053567c88e1ad9eed030d3ac41b722125e4c1271c8a99ade797faff1f49fb1", "ca0c740734cde59bf919f8ff2c386f74f9a369818cdc60efe94893d01ea8d9b7"] appdirs = ["9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", "d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"] -asn1crypto = ["2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87", "9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49"] -asteval = ["7c81fee6707a7a28e8beae891b858535a7e61f9ce275a0a4cf5f428fbc934cb8"] -attrs = ["69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", "f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"] +asteval = ["bc71bb4f9ad3ef8ccdc3b9a711e094fb00d768172cb7ff9a15773673aac9e0cc"] +attrs = ["08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"] behave = ["b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86", "ebda1a6c9e5bfe95c5f9f0a2794e01c7098b3dde86c10a95d8621c5907ff6f1c"] black = ["817243426042db1d36617910df579a54f1afd659adb96fc5032fcf4b36209739", "e030a9a28f542debc08acceb273f228ac422798e5215ba2a791a6ddeaaca22a5"] -cffi = ["041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774", "046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d", "066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90", "066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b", "2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63", "300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45", "34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25", "46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3", "4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b", "4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647", "4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016", "50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4", "55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb", "5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753", "59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7", "73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9", "a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f", "a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8", "a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f", "a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc", "ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42", "b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3", "d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909", "d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45", "dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d", "e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512", "e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff", "ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201"] +cffi = ["0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42", "0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04", "135f69aecbf4517d5b3d6429207b2dff49c876be724ac0c8bf8e1ea99df3d7e5", "19db0cdd6e516f13329cba4903368bff9bb5a9331d3410b1b448daaadc495e54", "2781e9ad0e9d47173c0093321bb5435a9dfae0ed6a762aabafa13108f5f7b2ba", "291f7c42e21d72144bb1c1b2e825ec60f46d0a7468f5346841860454c7aa8f57", "2c5e309ec482556397cb21ede0350c5e82f0eb2621de04b2633588d118da4396", "2e9c80a8c3344a92cb04661115898a9129c074f7ab82011ef4b612f645939f12", "32a262e2b90ffcfdd97c7a5e24a6012a43c61f1f5a57789ad80af1d26c6acd97", "3c9fff570f13480b201e9ab69453108f6d98244a7f495e91b6c654a47486ba43", "415bdc7ca8c1c634a6d7163d43fb0ea885a07e9618a64bda407e04b04333b7db", "4424e42199e86b21fc4db83bd76909a6fc2a2aefb352cb5414833c030f6ed71b", "4a43c91840bda5f55249413037b7a9b79c90b1184ed504883b72c4df70778579", "599a1e8ff057ac530c9ad1778293c665cb81a791421f46922d80a86473c13346", "5c4fae4e9cdd18c82ba3a134be256e98dc0596af1e7285a3d2602c97dcfa5159", "5ecfa867dea6fabe2a58f03ac9186ea64da1386af2159196da51c4904e11d652", "62f2578358d3a92e4ab2d830cd1c2049c9c0d0e6d3c58322993cc341bdeac22e", "6471a82d5abea994e38d2c2abc77164b4f7fbaaf80261cb98394d5793f11b12a", "6d4f18483d040e18546108eb13b1dfa1000a089bcf8529e30346116ea6240506", "71a608532ab3bd26223c8d841dde43f3516aa5d2bf37b50ac410bb5e99053e8f", "74a1d8c85fb6ff0b30fbfa8ad0ac23cd601a138f7509dc617ebc65ef305bb98d", "7b93a885bb13073afb0aa73ad82059a4c41f4b7d8eb8368980448b52d4c7dc2c", "7d4751da932caaec419d514eaa4215eaf14b612cff66398dd51129ac22680b20", "7f627141a26b551bdebbc4855c1157feeef18241b4b8366ed22a5c7d672ef858", "8169cf44dd8f9071b2b9248c35fc35e8677451c52f795daa2bb4643f32a540bc", "aa00d66c0fab27373ae44ae26a66a9e43ff2a678bf63a9c7c1a9a4d61172827a", "ccb032fda0873254380aa2bfad2582aedc2959186cce61e3a17abc1a55ff89c3", "d754f39e0d1603b5b24a7f8484b22d2904fa551fe865fd0d4c3332f078d20d4e", "d75c461e20e29afc0aee7172a0950157c704ff0dd51613506bd7d82b718e7410", "dcd65317dd15bc0451f3e01c80da2216a31916bdcffd6221ca1202d96584aa25", "e570d3ab32e2c2861c4ebe6ffcad6a8abf9347432a37608fe1fbd157b3f0036b", "fd43a88e045cf992ed09fa724b5315b790525f2676883a6ea64e3263bae6549d"] click = ["2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", "5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"] colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"] -cryptography = ["24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c", "25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643", "3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216", "41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799", "5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a", "5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9", "72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc", "7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8", "961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53", "96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1", "ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609", "b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292", "cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e", "e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6", "f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed", "f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d"] +cryptography = ["02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c", "1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595", "369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad", "3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651", "44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2", "4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff", "58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d", "6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42", "7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d", "73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e", "7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912", "90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793", "971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13", "a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7", "b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0", "b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879", "d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f", "de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9", "df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2", "ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf", "fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8"] entrypoints = ["589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", "c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"] -flake8 = ["19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548", "8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696"] -future = ["67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8"] -jeepney = ["6089412a5de162c04747f0220f6b2223b8ba660acd041e52a76426ca550e3c70", "f6f8b1428403b4afad04b6b82f9ab9fc426c253d7504c9031c41712a2c01dc74"] -jinja2 = ["065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", "14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b"] -keyring = ["1b74595f7439e4581a11d4f9a12790ac34addce64ca389c86272ff465f5e0b90", "afbfe7bc9bdba69d25c551b0c738adde533d87e0b51ad6bbe332cbea19ad8476"] +flake8 = ["45681a117ecc81e870cbf1262835ae4af5e7a8b08e40b944a8a6e6b895914cfb", "49356e766643ad15072a789a20915d3c91dc89fd313ccd71802303fd67e4deca"] +future = ["b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"] +jeepney = ["13806f91a96e9b2623fd2a81b950d763ee471454aafd9eb6d75dbe7afce428fb", "f6a3f93464a0cf052f4e87da3c8b3ed1e27696758fb9739c63d3a74d9a1b6774"] +jinja2 = ["74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", "9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"] +keyring = ["91037ccaf0c9a112a76f7740e4a416b9457a69b66c2799421581bee710a974b3", "f5bb20ea6c57c2360daf0c591931c9ea0d7660a8d9e32ca84d63273f131ea605"] livereload = ["78d55f2c268a8823ba499305dcac64e28ddeb9a92571e12d543cd304faf5817b", "89254f78d7529d7ea0a3417d224c34287ebfe266b05e67e51facaf82c27f0f66"] markdown = ["2e50876bcdd74517e7b71f3e7a76102050edec255b3983403f1a63e7c8a41e7a", "56a46ac655704b91e5b7e6326ce43d5ef72411376588afa1dd90e881b83c7e8c"] markupsafe = ["00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", "09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", "24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", "62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", "6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", "88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", "98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", "ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", "b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", "ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", "e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"] mccabe = ["ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"] mkdocs = ["17d34329aad75d5de604b9ed4e31df3a4d235afefdc46ce7b1964fddb2e1e939", "8cc8b38325456b9e942c981a209eaeb1e9f3f77b493ad755bfef889b9c8d356a"] -numpy = ["0778076e764e146d3078b17c24c4d89e0ecd4ac5401beff8e1c87879043a0633", "141c7102f20abe6cf0d54c4ced8d565b86df4d3077ba2343b61a6db996cefec7", "14270a1ee8917d11e7753fb54fc7ffd1934f4d529235beec0b275e2ccf00333b", "27e11c7a8ec9d5838bc59f809bfa86efc8a4fd02e58960fa9c49d998e14332d5", "2a04dda79606f3d2f760384c38ccd3d5b9bb79d4c8126b67aff5eb09a253763e", "3c26010c1b51e1224a3ca6b8df807de6e95128b0908c7e34f190e7775455b0ca", "52c40f1a4262c896420c6ea1c6fda62cf67070e3947e3307f5562bd783a90336", "6e4f8d9e8aa79321657079b9ac03f3cf3fd067bf31c1cca4f56d49543f4356a5", "7242be12a58fec245ee9734e625964b97cf7e3f2f7d016603f9e56660ce479c7", "7dc253b542bfd4b4eb88d9dbae4ca079e7bf2e2afd819ee18891a43db66c60c7", "94f5bd885f67bbb25c82d80184abbf7ce4f6c3c3a41fbaa4182f034bba803e69", "a89e188daa119ffa0d03ce5123dee3f8ffd5115c896c2a9d4f0dbb3d8b95bfa3", "ad3399da9b0ca36e2f24de72f67ab2854a62e623274607e37e0ce5f5d5fa9166", "b0348be89275fd1d4c44ffa39530c41a21062f52299b1e3ee7d1c61f060044b8", "b5554368e4ede1856121b0dfa35ce71768102e4aa55e526cb8de7f374ff78722", "cbddc56b2502d3f87fda4f98d948eb5b11f36ff3902e17cb6cc44727f2200525", "d79f18f41751725c56eceab2a886f021d70fd70a6188fd386e29a045945ffc10", "dc2ca26a19ab32dc475dbad9dfe723d3a64c835f4c23f625c2b6566ca32b9f29", "dd9bcd4f294eb0633bb33d1a74febdd2b9018b8b8ed325f861fffcd2c7660bb8", "e8baab1bc7c9152715844f1faca6744f2416929de10d7639ed49555a85549f52", "ec31fe12668af687b99acf1567399632a7c47b0e17cfb9ae47c098644ef36797", "f12b4f7e2d8f9da3141564e6737d79016fe5336cc92de6814eba579744f65b0a", "f58ac38d5ca045a377b3b377c84df8175ab992c970a53332fa8ac2373df44ff7"] -parse = ["1b68657434d371e5156048ca4a0c5aea5afc6ca59a2fea4dd1a575354f617142"] -parse-type = ["6e906a66f340252e4c324914a60d417d33a4bea01292ea9bbf68b4fc123be8c9", "f596bdc75d3dd93036fbfe3d04127da9f6df0c26c36e01e76da85adef4336b3c"] +parse = ["a5fca7000c6588d77bc65c28f3f21bfce03b5e44daa8f9f07c17fe364990d717"] +parse-type = ["089a471b06327103865dfec2dd844230c3c658a4a1b5b4c8b6c16c8f77577f9e", "7f690b18d35048c15438d6d0571f9045cffbec5907e0b1ccf006f889e3a38c0b"] parsedatetime = ["3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b", "9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094"] passlib = ["3d948f64138c25633613f303bcc471126eae67c04d5e3f6b7b8ce6242f8653e0", "43526aea08fa32c6b6dbbbe9963c4c767285b78147b7437597f992812f69d280"] pycodestyle = ["95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", "e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"] pycparser = ["a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"] pyflakes = ["17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", "d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"] -python-dateutil = ["7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", "c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"] -pytz = ["303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda", "d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141"] +python-dateutil = ["73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", "75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"] +pytz = ["1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d", "b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be"] pywin32-ctypes = ["24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942", "9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"] pyxdg = ["1948ff8e2db02156c0cccd2529b43c0cff56ebaa71f5f021bbd755bc1419190e", "fe2928d3f532ed32b39c32a482b54136fe766d19936afc96c8f00645f9da1a06"] pyyaml = ["0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9", "01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4", "5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8", "5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696", "7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34", "7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9", "87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73", "9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299", "a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b", "b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae", "b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681", "bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41", "f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"] secretstorage = ["20c797ae48a4419f66f8d28fc221623f11fc45b6828f96bdb1ad9990acb59f92", "7a119fb52a88e398dbb22a4b3eb39b779bfbace7e4153b7bc6e5954d86282a8a"] -six = ["3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"] +six = ["1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", "30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"] textwrap3 = ["5008eeebdb236f6303dcd68f18b856d355f6197511d952ba74bc75e40e0c3414", "bf5f4c40faf2a9ff00a9e0791fed5da7415481054cef45bb4a3cfb1f69044ae0"] toml = ["229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", "235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e", "f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"] tornado = ["349884248c36801afa19e342a77cc4458caca694b0eda633f5878e458a44cb2c", "398e0d35e086ba38a0427c3b37f4337327231942e731edaa6e9fd1865bbd6f60", "4e73ef678b1a859f0cb29e1d895526a20ea64b5ffd510a2307b5998c7df24281", "559bce3d31484b665259f50cd94c5c28b961b09315ccd838f284687245f416e5", "abbe53a39734ef4aba061fca54e30c6b4639d3e1f59653f0da37a0003de148c7", "c845db36ba616912074c5b1ee897f8e0124df269468f25e4fe21fe72f6edd7a9", "c9399267c926a4e7c418baa5cbe91c7d1cf362d505a1ef898fde44a07c9dd8a5"] From 4b934e36eb1e8647596ca81f987e815e0cda16de Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 19:29:55 +0100 Subject: [PATCH 12/41] Add tag and body color customization options --- jrnl/Entry.py | 2 +- jrnl/Journal.py | 4 ++-- jrnl/install.py | 6 ++++-- jrnl/util.py | 4 +--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index 18187a435..c419cf107 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -106,7 +106,7 @@ def pprint(self, short=False): return "{title}{sep}{body}\n".format( title=title, sep="\n" if has_body else "", - body=body if has_body else "", + body=colorize(body, self.journal.config['colors']['body']) if has_body else "", ) def __repr__(self): diff --git a/jrnl/Journal.py b/jrnl/Journal.py index 886045a66..99c7f2500 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -152,12 +152,12 @@ def pprint(self, short=False): for tag in self.search_tags: tagre = re.compile(re.escape(tag), re.IGNORECASE) pp = re.sub(tagre, - lambda match: util.colorize(match.group(0), "CYAN"), + lambda match: util.colorize(match.group(0), self.config['colors']['tags']), pp, re.UNICODE) else: pp = re.sub( Entry.Entry.tag_regex(self.config['tagsymbols']), - lambda match: util.colorize(match.group(0), "CYAN"), + lambda match: util.colorize(match.group(0), self.config['colors']['tags']), pp ) return pp diff --git a/jrnl/install.py b/jrnl/install.py index c0fc7dd64..a7ff4602a 100644 --- a/jrnl/install.py +++ b/jrnl/install.py @@ -59,8 +59,10 @@ def module_exists(module_name): 'linewrap': 79, 'indent_character': '|', 'colors': { - 'date': 'red', - 'title': 'blue', + 'date': 'none', + 'title': 'none', + 'body': 'none', + 'tags': 'none', }, } diff --git a/jrnl/util.py b/jrnl/util.py index 806f6d230..a3230f10b 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -173,9 +173,7 @@ def verify_config(config): if upper_color == "NONE": pass if not getattr(colorama.Fore, upper_color, None): - # TODO: Not sure whether both of these should stay or not. - print("[{2}ERROR{3}: {0} set to invalid color: {1}]".format(key, color, ERROR_COLOR, RESET_COLOR)) - log.error("Invalid color configuration value for '{0}'.".format(key)) + print("[{2}ERROR{3}: {0} set to invalid color: {1}]".format(key, color, ERROR_COLOR, RESET_COLOR), file=sys.stderr) all_valid_colors = False return all_valid_colors From 94a2b78b6d57a81935f9f1e3f89805c8d4d4c912 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 21:43:00 +0100 Subject: [PATCH 13/41] Fix colorization of tags in title and body --- features/core.feature | 3 +- features/data/configs/basic.yaml | 2 + features/data/configs/bug153.yaml | 2 + features/data/configs/invalid_color.yaml | 2 + .../data/configs/markdown-headings-335.yaml | 2 + features/data/configs/tags-216.yaml | 2 + features/data/configs/tags-237.yaml | 2 + features/data/configs/tags.yaml | 2 + features/upgrade.feature | 2 +- jrnl/Entry.py | 38 ++++++++++++++----- jrnl/Journal.py | 17 +-------- jrnl/util.py | 38 +++++++++++++++++++ 12 files changed, 83 insertions(+), 29 deletions(-) diff --git a/features/core.feature b/features/core.feature index dd072ba42..06afa2acb 100644 --- a/features/core.feature +++ b/features/core.feature @@ -63,7 +63,6 @@ Feature: Basic reading and writing to a journal When we run "jrnl -on 2013-06-10 -s" Then the output should be """ - [ERROR: date set to invalid color: not-a-color] - [ERROR: title set to invalid color: also-not-a-color] 2013-06-10 15:40 Life is good. """ + And we should get no error diff --git a/features/data/configs/basic.yaml b/features/data/configs/basic.yaml index 01dd1c0c8..d249187c3 100644 --- a/features/data/configs/basic.yaml +++ b/features/data/configs/basic.yaml @@ -13,3 +13,5 @@ indent_character: "|" colors: date: red title: green + body: yellow + tags: black diff --git a/features/data/configs/bug153.yaml b/features/data/configs/bug153.yaml index 6b3096a1f..e43cbba8e 100644 --- a/features/data/configs/bug153.yaml +++ b/features/data/configs/bug153.yaml @@ -14,3 +14,5 @@ indent_character: "|" colors: date: red title: green + body: yellow + tags: black diff --git a/features/data/configs/invalid_color.yaml b/features/data/configs/invalid_color.yaml index 4c2c78fc4..25c0e58dc 100644 --- a/features/data/configs/invalid_color.yaml +++ b/features/data/configs/invalid_color.yaml @@ -13,3 +13,5 @@ indent_character: "|" colors: date: not-a-color title: also-not-a-color + body: still-no-color + tags: me-too diff --git a/features/data/configs/markdown-headings-335.yaml b/features/data/configs/markdown-headings-335.yaml index b180fcd35..bb1146757 100644 --- a/features/data/configs/markdown-headings-335.yaml +++ b/features/data/configs/markdown-headings-335.yaml @@ -14,3 +14,5 @@ indent_character: "|" colors: date: red title: green + body: yellow + tags: black diff --git a/features/data/configs/tags-216.yaml b/features/data/configs/tags-216.yaml index 37cfa11fe..d967801cb 100644 --- a/features/data/configs/tags-216.yaml +++ b/features/data/configs/tags-216.yaml @@ -14,3 +14,5 @@ indent_character: "|" colors: date: red title: green + body: yellow + tags: black diff --git a/features/data/configs/tags-237.yaml b/features/data/configs/tags-237.yaml index 27b662ddb..6fc8b8145 100644 --- a/features/data/configs/tags-237.yaml +++ b/features/data/configs/tags-237.yaml @@ -14,3 +14,5 @@ indent_character: "|" colors: date: red title: green + body: yellow + tags: black diff --git a/features/data/configs/tags.yaml b/features/data/configs/tags.yaml index bb0c39c15..0be45a6d5 100644 --- a/features/data/configs/tags.yaml +++ b/features/data/configs/tags.yaml @@ -14,3 +14,5 @@ indent_character: "|" colors: date: red title: green + body: yellow + tags: black diff --git a/features/upgrade.feature b/features/upgrade.feature index 587102eb8..ae1ac931e 100644 --- a/features/upgrade.feature +++ b/features/upgrade.feature @@ -25,4 +25,4 @@ Feature: Upgrading Journals from 1.x.x to 2.x.x Scenario: Upgrading a config without colors to colors Given we use the config "no_colors.yaml" When we run "jrnl -n 1" - Then the config should have "colors" set to "{'date':'red', 'title':'blue'}" + Then the config should have "colors" set to "{'date':'none', 'title':'none', 'body':'none', 'tags':'none'}" diff --git a/jrnl/Entry.py b/jrnl/Entry.py index c419cf107..66f0c9976 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -5,7 +5,7 @@ import re import ansiwrap from datetime import datetime -from .util import split_title, colorize +from .util import split_title, colorize, highlight_tags_maintain_background_color class Entry: @@ -73,16 +73,28 @@ def __unicode__(self): 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']) + if not short and self.journal.config['linewrap']: - # Color date and color / bold title and make sure first line of title is bolded - title = ansiwrap.fill(colorize(date_str, self.journal.config['colors']['date']) + " " + - colorize(self.title, self.journal.config['colors']['title'], bold=True), + # Color date and color / bold title + title = ansiwrap.fill(date_str + " " + + highlight_tags_maintain_background_color(self, + self.title, + self.journal.config['colors']['title'], + bold=True), self.journal.config['linewrap']) + body = highlight_tags_maintain_background_color(self, + self.body.rstrip(" \n"), + self.journal.config['colors']['body'], + bold=False) body = "\n".join([ ansiwrap.fill( line, @@ -90,12 +102,18 @@ def pprint(self, short=False): initial_indent=indent, subsequent_indent=indent, drop_whitespace=True) or indent - for line in self.body.rstrip(" \n").splitlines() + for line in body.splitlines() ]) else: - title = colorize(date_str, self.journal.config['colors']['date']) + " " +\ - colorize(self.title.rstrip("\n"), self.journal.config['colors']['title'], bold=True) - body = self.body.rstrip("\n ") + title = date_str + " " + \ + highlight_tags_maintain_background_color(self, + self.title.rstrip("\n"), + self.journal.config['colors']['title'], + bold=True) + body = highlight_tags_maintain_background_color(self, + self.body.rstrip("\n "), + self.journal.config['colors']['body'], + bold=False) # Suppress bodies that are just blanks and new lines. has_body = len(self.body) > 20 or not all(char in (" ", "\n") for char in self.body) @@ -106,7 +124,7 @@ def pprint(self, short=False): return "{title}{sep}{body}\n".format( title=title, sep="\n" if has_body else "", - body=colorize(body, self.journal.config['colors']['body']) if has_body else "", + body=body if has_body else "", ) def __repr__(self): diff --git a/jrnl/Journal.py b/jrnl/Journal.py index 99c7f2500..4288c0f26 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -145,22 +145,7 @@ def __unicode__(self): def pprint(self, short=False): """Prettyprints the journal's entries""" - sep = "\n" - pp = sep.join([e.pprint(short=short) for e in self.entries]) - if self.config['highlight']: # highlight tags - if self.search_tags: - for tag in self.search_tags: - tagre = re.compile(re.escape(tag), re.IGNORECASE) - pp = re.sub(tagre, - lambda match: util.colorize(match.group(0), self.config['colors']['tags']), - pp, re.UNICODE) - else: - pp = re.sub( - Entry.Entry.tag_regex(self.config['tagsymbols']), - lambda match: util.colorize(match.group(0), self.config['colors']['tags']), - pp - ) - return pp + return "\n".join([e.pprint(short=short) for e in self.entries]) def __repr__(self): return "".format(len(self.entries)) diff --git a/jrnl/util.py b/jrnl/util.py index a3230f10b..1b3e04ac8 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -212,6 +212,44 @@ def colorize(string, color, bold=False): return colorama.Style.BRIGHT + color_escape + string + colorama.Style.RESET_ALL +def highlight_tags_maintain_background_color(entry, text, color, bold=False): + """ + Takes a string and colorizes the tags in it based upon the config value for + color.tags, while colorizing the rest of the text based on color. + :param entry: Entry object, for access to journal config + :param text: Text to be colorized + :param color: Color for non-tag text, passed to colorize() + :param bold: Bold flag text, passed to colorize() + :return: Colorized str + """ + config = entry.journal.config + if config['highlight']: # highlight tags + if entry.journal.search_tags: + for tag in entry.search_tags: + text_split = re.split(re.compile(re.escape(tag), re.IGNORECASE), + text, + flags=re.UNICODE) + text = [colorize(part.strip(), + color, + bold) + if len(part) > 0 and part[0] not in config['tagsymbols'] + else colorize(part.strip(), + config['colors']['tags'], + not bold) + for part in text_split] + else: + text_split = re.split(entry.tag_regex(config['tagsymbols']), text) + text = [colorize(part.strip(), + color, + bold) + if len(part) > 0 and part[0] not in config['tagsymbols'] + else colorize(part.strip(), + config['colors']['tags'], + not bold) + for part in text_split] + return " ".join(text) + + def slugify(string): """Slugifies a string. Based on public domain code from https://github.com/zacharyvoase/slugify From 6f3866cbcf7be65858c9be711fb81b55b0d12166 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 22:38:04 +0100 Subject: [PATCH 14/41] Updated tests to use no color by default --- features/data/configs/basic.yaml | 8 ++++---- features/data/configs/bug153.yaml | 8 ++++---- features/data/configs/markdown-headings-335.yaml | 8 ++++---- features/data/configs/tags-216.yaml | 8 ++++---- features/data/configs/tags-237.yaml | 8 ++++---- features/data/configs/tags.yaml | 8 ++++---- features/data/configs/unreadabledates.yaml | 5 +++++ 7 files changed, 29 insertions(+), 24 deletions(-) diff --git a/features/data/configs/basic.yaml b/features/data/configs/basic.yaml index d249187c3..020bab183 100644 --- a/features/data/configs/basic.yaml +++ b/features/data/configs/basic.yaml @@ -11,7 +11,7 @@ template: false timeformat: "%Y-%m-%d %H:%M" indent_character: "|" colors: - date: red - title: green - body: yellow - tags: black + date: none + title: none + body: none + tags: none diff --git a/features/data/configs/bug153.yaml b/features/data/configs/bug153.yaml index e43cbba8e..a33d2f7b2 100644 --- a/features/data/configs/bug153.yaml +++ b/features/data/configs/bug153.yaml @@ -12,7 +12,7 @@ template: false timeformat: '%Y-%m-%d %H:%M' indent_character: "|" colors: - date: red - title: green - body: yellow - tags: black + date: none + title: none + body: none + tags: none diff --git a/features/data/configs/markdown-headings-335.yaml b/features/data/configs/markdown-headings-335.yaml index bb1146757..6f3968871 100644 --- a/features/data/configs/markdown-headings-335.yaml +++ b/features/data/configs/markdown-headings-335.yaml @@ -12,7 +12,7 @@ tagsymbols: '@' timeformat: '%Y-%m-%d %H:%M' indent_character: "|" colors: - date: red - title: green - body: yellow - tags: black + date: none + title: none + body: none + tags: none diff --git a/features/data/configs/tags-216.yaml b/features/data/configs/tags-216.yaml index d967801cb..576cee3e4 100644 --- a/features/data/configs/tags-216.yaml +++ b/features/data/configs/tags-216.yaml @@ -12,7 +12,7 @@ tagsymbols: '@' timeformat: '%Y-%m-%d %H:%M' indent_character: "|" colors: - date: red - title: green - body: yellow - tags: black + date: none + title: none + body: none + tags: none diff --git a/features/data/configs/tags-237.yaml b/features/data/configs/tags-237.yaml index 6fc8b8145..4ffad3c60 100644 --- a/features/data/configs/tags-237.yaml +++ b/features/data/configs/tags-237.yaml @@ -12,7 +12,7 @@ tagsymbols: '@' timeformat: '%Y-%m-%d %H:%M' indent_character: "|" colors: - date: red - title: green - body: yellow - tags: black + date: none + title: none + body: none + tags: none diff --git a/features/data/configs/tags.yaml b/features/data/configs/tags.yaml index 0be45a6d5..3fe46c449 100644 --- a/features/data/configs/tags.yaml +++ b/features/data/configs/tags.yaml @@ -12,7 +12,7 @@ tagsymbols: '@' timeformat: '%Y-%m-%d %H:%M' indent_character: "|" colors: - date: red - title: green - body: yellow - tags: black + date: none + title: none + body: none + tags: none diff --git a/features/data/configs/unreadabledates.yaml b/features/data/configs/unreadabledates.yaml index 474e7aae5..99304e5ad 100644 --- a/features/data/configs/unreadabledates.yaml +++ b/features/data/configs/unreadabledates.yaml @@ -10,3 +10,8 @@ tagsymbols: "@" template: false timeformat: "%Y-%m-%d %H:%M" indent_character: "|" +colors: + date: none + title: none + body: none + tags: none From 6145682a2986910f8c6f83e1046424f436ffce1e Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 22:39:51 +0100 Subject: [PATCH 15/41] Change pass to continue in verify_config() --- jrnl/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jrnl/util.py b/jrnl/util.py index 1b3e04ac8..670528369 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -171,7 +171,7 @@ def verify_config(config): for key, color in config["colors"].items(): upper_color = color.upper() if upper_color == "NONE": - pass + continue if not getattr(colorama.Fore, upper_color, None): print("[{2}ERROR{3}: {0} set to invalid color: {1}]".format(key, color, ERROR_COLOR, RESET_COLOR), file=sys.stderr) all_valid_colors = False From baa3ffbebd65389508dbca53d9627449794d23e8 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 23:06:55 +0100 Subject: [PATCH 16/41] Better style in Entry.py --- jrnl/Entry.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index 66f0c9976..62ca1ab69 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -84,7 +84,7 @@ def pprint(self, short=False): self.journal.config['colors']['date']) if not short and self.journal.config['linewrap']: - # Color date and color / bold title + # Color date / title and bold title title = ansiwrap.fill(date_str + " " + highlight_tags_maintain_background_color(self, self.title, @@ -102,14 +102,13 @@ def pprint(self, short=False): initial_indent=indent, subsequent_indent=indent, drop_whitespace=True) or indent - for line in body.splitlines() + for line in body.rstrip(" \n").splitlines() ]) else: - title = date_str + " " + \ - highlight_tags_maintain_background_color(self, - self.title.rstrip("\n"), - self.journal.config['colors']['title'], - bold=True) + title = date_str + " " + highlight_tags_maintain_background_color(self, + self.title.rstrip("\n"), + self.journal.config['colors']['title'], + bold=True) body = highlight_tags_maintain_background_color(self, self.body.rstrip("\n "), self.journal.config['colors']['body'], From c3b18181d6987fa6213791d6683e1af37b80e5bd Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Wed, 6 Nov 2019 23:07:11 +0100 Subject: [PATCH 17/41] Reduce code duplication for tag highlighting - Breaks "unreadable date" regression test for unknown reason --- jrnl/util.py | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/jrnl/util.py b/jrnl/util.py index 670528369..30ae80a60 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -215,7 +215,7 @@ def colorize(string, color, bold=False): def highlight_tags_maintain_background_color(entry, text, color, bold=False): """ Takes a string and colorizes the tags in it based upon the config value for - color.tags, while colorizing the rest of the text based on color. + color.tags, while colorizing the rest of the text based on `color`. :param entry: Entry object, for access to journal config :param text: Text to be colorized :param color: Color for non-tag text, passed to colorize() @@ -225,29 +225,26 @@ def highlight_tags_maintain_background_color(entry, text, color, bold=False): config = entry.journal.config if config['highlight']: # highlight tags if entry.journal.search_tags: + search_texts = [] for tag in entry.search_tags: - text_split = re.split(re.compile(re.escape(tag), re.IGNORECASE), - text, - flags=re.UNICODE) - text = [colorize(part.strip(), - color, - bold) - if len(part) > 0 and part[0] not in config['tagsymbols'] - else colorize(part.strip(), - config['colors']['tags'], - not bold) - for part in text_split] + search_texts.append(re.split(re.compile(re.escape(tag), re.IGNORECASE), + text, + flags=re.UNICODE)) else: - text_split = re.split(entry.tag_regex(config['tagsymbols']), text) - text = [colorize(part.strip(), - color, - bold) - if len(part) > 0 and part[0] not in config['tagsymbols'] - else colorize(part.strip(), - config['colors']['tags'], - not bold) - for part in text_split] - return " ".join(text) + search_texts = re.split(entry.tag_regex(config['tagsymbols']), text) + + # TODO: Condense this all into a list comprehension once the broken regression test is fixed. + pretty_printed_entries = [] + for text in search_texts: + pretty_printed_entries.append(" ".join([colorize(part.strip(), + color, + bold) + if len(part) > 0 and part[0] not in config['tagsymbols'] + else colorize(part.strip(), + config['colors']['tags'], + not bold) + for part in text.split()])) + return " ".join(pretty_printed_entries) def slugify(string): From 68305350e46049353174456c96bd3d5f5f6c7a71 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Thu, 7 Nov 2019 04:18:17 +0100 Subject: [PATCH 18/41] Properly colorize tags and print body --- jrnl/Entry.py | 27 +++++++++++++++++++-------- jrnl/util.py | 20 +++++++++++--------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index 62ca1ab69..14b61378a 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -95,15 +95,26 @@ def pprint(self, short=False): self.body.rstrip(" \n"), self.journal.config['colors']['body'], bold=False) - body = "\n".join([ + body_text = [colorize( ansiwrap.fill( line, self.journal.config['linewrap'], initial_indent=indent, subsequent_indent=indent, - drop_whitespace=True) or indent - for line in body.rstrip(" \n").splitlines() - ]) + drop_whitespace=True), + 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 nasty 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 + " " + highlight_tags_maintain_background_color(self, self.title.rstrip("\n"), @@ -134,10 +145,10 @@ def __hash__(self): def __eq__(self, other): if not isinstance(other, Entry) \ - or self.title.strip() != other.title.strip() \ - or self.body.rstrip() != other.body.rstrip() \ - or self.date != other.date \ - or self.starred != other.starred: + or self.title.strip() != other.title.strip() \ + or self.body.rstrip() != other.body.rstrip() \ + or self.date != other.date \ + or self.starred != other.starred: return False return True diff --git a/jrnl/util.py b/jrnl/util.py index 30ae80a60..c9559e597 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -233,17 +233,19 @@ def highlight_tags_maintain_background_color(entry, text, color, bold=False): else: search_texts = re.split(entry.tag_regex(config['tagsymbols']), text) - # TODO: Condense this all into a list comprehension once the broken regression test is fixed. + # TODO: Condense this all into a list comprehension pretty_printed_entries = [] for text in search_texts: - pretty_printed_entries.append(" ".join([colorize(part.strip(), - color, - bold) - if len(part) > 0 and part[0] not in config['tagsymbols'] - else colorize(part.strip(), - config['colors']['tags'], - not bold) - for part in text.split()])) + colorized_parts = [colorize(part.strip(), + color, + bold) + if len(part) > 0 and part[0] not in config['tagsymbols'] + else colorize(part.strip(), + config['colors']['tags'], + not bold) + for part in text.strip().split(" ")] + + pretty_printed_entries.append(" ".join(colorized_parts)) return " ".join(pretty_printed_entries) From 82d3c65d828777cf6b07a53d5b766c2f6c298427 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Thu, 7 Nov 2019 04:27:31 +0100 Subject: [PATCH 19/41] Reformatting and clean up --- jrnl/Entry.py | 38 +++++++++++++++++++------------------- jrnl/util.py | 9 ++++----- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index 14b61378a..b23086e27 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -5,7 +5,7 @@ import re import ansiwrap from datetime import datetime -from .util import split_title, colorize, highlight_tags_maintain_background_color +from .util import split_title, colorize, highlight_tags_with_background_color class Entry: @@ -86,15 +86,15 @@ def pprint(self, short=False): if not short and self.journal.config['linewrap']: # Color date / title and bold title title = ansiwrap.fill(date_str + " " + - highlight_tags_maintain_background_color(self, - self.title, - self.journal.config['colors']['title'], - bold=True), + highlight_tags_with_background_color(self, + self.title, + self.journal.config['colors']['title'], + bold=True), self.journal.config['linewrap']) - body = highlight_tags_maintain_background_color(self, - self.body.rstrip(" \n"), - self.journal.config['colors']['body'], - bold=False) + body = highlight_tags_with_background_color(self, + self.body.rstrip(" \n"), + self.journal.config['colors']['body'], + bold=False) body_text = [colorize( ansiwrap.fill( line, @@ -106,8 +106,8 @@ def pprint(self, short=False): 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 nasty hack here to make sure the - # beginning of each line has the indent character, and it's colored + # 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. @@ -116,14 +116,14 @@ def pprint(self, short=False): else line for line in body_text]) else: - title = date_str + " " + highlight_tags_maintain_background_color(self, - self.title.rstrip("\n"), - self.journal.config['colors']['title'], - bold=True) - body = highlight_tags_maintain_background_color(self, - self.body.rstrip("\n "), - self.journal.config['colors']['body'], - bold=False) + title = date_str + " " + highlight_tags_with_background_color(self, + self.title.rstrip("\n"), + self.journal.config['colors']['title'], + bold=True) + body = highlight_tags_with_background_color(self, + self.body.rstrip("\n "), + self.journal.config['colors']['body'], + bold=False) # Suppress bodies that are just blanks and new lines. has_body = len(self.body) > 20 or not all(char in (" ", "\n") for char in self.body) diff --git a/jrnl/util.py b/jrnl/util.py index c9559e597..14de8dfc3 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -212,7 +212,7 @@ def colorize(string, color, bold=False): return colorama.Style.BRIGHT + color_escape + string + colorama.Style.RESET_ALL -def highlight_tags_maintain_background_color(entry, text, color, bold=False): +def highlight_tags_with_background_color(entry, text, color, bold=False): """ Takes a string and colorizes the tags in it based upon the config value for color.tags, while colorizing the rest of the text based on `color`. @@ -233,17 +233,16 @@ def highlight_tags_maintain_background_color(entry, text, color, bold=False): else: search_texts = re.split(entry.tag_regex(config['tagsymbols']), text) - # TODO: Condense this all into a list comprehension pretty_printed_entries = [] for text in search_texts: - colorized_parts = [colorize(part.strip(), + colorized_parts = (colorize(part.strip(), color, bold) - if len(part) > 0 and part[0] not in config['tagsymbols'] + if part and part[0] not in config['tagsymbols'] else colorize(part.strip(), config['colors']['tags'], not bold) - for part in text.strip().split(" ")] + for part in text.strip().split(" ")) pretty_printed_entries.append(" ".join(colorized_parts)) return " ".join(pretty_printed_entries) From 6ce83c7aa179664d0ed5b93155f33f597ffa60f5 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Thu, 7 Nov 2019 04:49:01 +0100 Subject: [PATCH 20/41] Replace list comprehension with generator --- jrnl/util.py | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/jrnl/util.py b/jrnl/util.py index 14de8dfc3..dae66a070 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -222,30 +222,32 @@ def highlight_tags_with_background_color(entry, text, color, bold=False): :param bold: Bold flag text, passed to colorize() :return: Colorized str """ + def colorized_text_generator(fragments): + """Efficiently generate colorized tags / text from text fragments. + :param fragments: List of strings representing parts of entry (tag or word).""" + # Taken from @shobrook. Thanks, buddy :) + for fragment in fragments: + for part in fragment.strip().split(" "): + if part and part[0] not in config['tagsymbols']: + yield colorize(part.strip(), color, bold) + else: + yield colorize(part.strip(), config['colors']['tags'], not bold) + config = entry.journal.config if config['highlight']: # highlight tags if entry.journal.search_tags: - search_texts = [] + text_fragments = [] for tag in entry.search_tags: - search_texts.append(re.split(re.compile(re.escape(tag), re.IGNORECASE), - text, - flags=re.UNICODE)) + text_fragments.append(re.split(re.compile(re.escape(tag), re.IGNORECASE), + text, + flags=re.UNICODE)) else: - search_texts = re.split(entry.tag_regex(config['tagsymbols']), text) - - pretty_printed_entries = [] - for text in search_texts: - colorized_parts = (colorize(part.strip(), - color, - bold) - if part and part[0] not in config['tagsymbols'] - else colorize(part.strip(), - config['colors']['tags'], - not bold) - for part in text.strip().split(" ")) - - pretty_printed_entries.append(" ".join(colorized_parts)) - return " ".join(pretty_printed_entries) + text_fragments = re.split(entry.tag_regex(config['tagsymbols']), text) + + return " ".join(colorized_text_generator(text_fragments)) + + else: + return text def slugify(string): From 89c43664deaa6ee6238d625f77a7a173e9a9bb40 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Thu, 7 Nov 2019 22:26:20 +0100 Subject: [PATCH 21/41] Handle invalid colors by not using a color --- docs/advanced.md | 2 +- jrnl/util.py | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/advanced.md b/docs/advanced.md index e5f89139f..2c14f84d2 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -33,7 +33,7 @@ and can be edited with any plain text editor. - `linewrap` controls the width of the output. Set to `false` if you don't want to wrap long lines. - `colors` - dictionary that controls the colors used to display journal entries. It has two subkeys, which are: `date` and `title`. Current valid values are: `BLACK`, `RED`, `GREEN`, `YELLOW`, `BLUE`, `MAGENTA`, `CYAN`, and `WHITE`. `colorama.Fore` is used for colorization, and you can find the [docs here](https://github.com/tartley/colorama#colored-output). To disable colored output, set the value to `NONE`. + dictionary that controls the colors used to display journal entries. It has two subkeys, which are: `date` and `title`. Current valid values are: `BLACK`, `RED`, `GREEN`, `YELLOW`, `BLUE`, `MAGENTA`, `CYAN`, and `WHITE`. `colorama.Fore` is used for colorization, and you can find the [docs here](https://github.com/tartley/colorama#colored-output). To disable colored output, set the value to `NONE`. If you set the value of any color subkey to an invalid color, no color will be used. !!! note Although it seems intuitive to use the `#` diff --git a/jrnl/util.py b/jrnl/util.py index dae66a070..d4196f505 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -198,14 +198,12 @@ def get_text_from_editor(config, template=""): def colorize(string, color, bold=False): """Returns the string colored with colorama.Fore.color. If the color set by - the user is "NONE", it returns the string without any modification. Otherwise, - If the color set by the user doesn't exist in the colorama.Fore attributes, - the colorization is done with WHITE.""" - upper_color = color.upper() - if upper_color == "NONE": + the user is "NONE" or the color doesn't exist in the colorama.Fore attributes, + it returns the string without any modification.""" + color_escape = getattr(colorama.Fore, color.upper(), None) + if not color_escape: return string - color_escape = getattr(colorama.Fore, upper_color, colorama.Fore.WHITE) if not bold: return color_escape + string + colorama.Fore.RESET else: From 41fb8d45ebcbdf10b957b2c5bba56a8bc0eba108 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Thu, 7 Nov 2019 22:26:46 +0100 Subject: [PATCH 22/41] Process ANSI escapes properly with behave --- features/steps/core.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index fbe8fa080..a6e3c9fa9 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -5,8 +5,8 @@ from jrnl import cli, install, Journal, util, plugins from jrnl import __version__ from dateutil import parser as date_parser -from ansiwrap import strip_color from collections import defaultdict +from codecs import encode, decode import os import ast import json @@ -167,12 +167,22 @@ def check_json_output_path(context, path, value): struct = struct[node] assert struct == value, struct +def process_ANSI_escapes(text): + """Escapes and 'unescapes' a string with ANSI escapes so that behave stdout + comparisons work properly. This will render colors, and works with unicode + characters. https://stackoverflow.com/a/57192592 + :param str text: The text to be escaped and unescaped + :return: Colorized / escaped text + :rtype: str + """ + return decode(encode(text, 'latin-1', 'backslashreplace'), 'unicode-escape') + @then('the output should be') @then('the output should be "{text}"') def check_output(context, text=None): text = (text or context.text).strip().splitlines() - out = strip_color(context.stdout_capture.getvalue().strip()).splitlines() + out = process_ANSI_escapes(context.stdout_capture.getvalue().strip()).splitlines() assert len(text) == len(out), "Output has {} lines (expected: {})".format(len(out), len(text)) for line_text, line_out in zip(text, out): assert line_text.strip() == line_out.strip(), [line_text.strip(), line_out.strip()] @@ -180,7 +190,7 @@ def check_output(context, text=None): @then('the output should contain "{text}" in the local time') def check_output_time_inline(context, text): - out = strip_color(context.stdout_capture.getvalue()) + out = process_ANSI_escapes(context.stdout_capture.getvalue()) local_tz = tzlocal.get_localzone() utc_time = date_parser.parse(text) local_date = utc_time.astimezone(local_tz).strftime("%Y-%m-%d %H:%M") @@ -191,7 +201,7 @@ def check_output_time_inline(context, text): @then('the output should contain "{text}"') def check_output_inline(context, text=None): text = text or context.text - out = strip_color(context.stdout_capture.getvalue()) + out = process_ANSI_escapes(context.stdout_capture.getvalue()) if isinstance(out, bytes): out = out.decode('utf-8') assert text in out, text From e9bfe4dcacf54cac4758d70e6b752adf41000c41 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Thu, 7 Nov 2019 23:38:58 +0100 Subject: [PATCH 23/41] Fixed the 'spaces after tags directly next to punctuation' bug Broke processing of tags next to any punctuation at all --- jrnl/util.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/jrnl/util.py b/jrnl/util.py index d4196f505..a4ba89e1a 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -17,6 +17,7 @@ import codecs import unicodedata import shlex +from string import punctuation import logging log = logging.getLogger(__name__) @@ -222,14 +223,17 @@ def highlight_tags_with_background_color(entry, text, color, bold=False): """ def colorized_text_generator(fragments): """Efficiently generate colorized tags / text from text fragments. - :param fragments: List of strings representing parts of entry (tag or word).""" - # Taken from @shobrook. Thanks, buddy :) + Taken from @shobrook. Thanks, buddy :) + :param fragments: List of strings representing parts of entry (tag or word). + :rtype: List of tuples + :returns [(colorized_str, original_str)]""" for fragment in fragments: for part in fragment.strip().split(" "): + part = part.strip() if part and part[0] not in config['tagsymbols']: - yield colorize(part.strip(), color, bold) - else: - yield colorize(part.strip(), config['colors']['tags'], not bold) + yield (colorize(part, color, bold), part) + elif part: + yield (colorize(part, config['colors']['tags'], not bold), part) config = entry.journal.config if config['highlight']: # highlight tags @@ -242,8 +246,17 @@ def colorized_text_generator(fragments): else: text_fragments = re.split(entry.tag_regex(config['tagsymbols']), text) - return " ".join(colorized_text_generator(text_fragments)) + final_text = "" + previous_piece = "" + for colorized_piece, piece in colorized_text_generator(text_fragments): + if piece in punctuation and previous_piece[0] not in config['tagsymbols']: + final_text = final_text.strip() + colorized_piece + else: + final_text += colorized_piece + " " + previous_piece = piece + + return final_text else: return text From dd81c7dbed2f9c3182003c594658864a62ed52c0 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Fri, 8 Nov 2019 01:25:00 +0100 Subject: [PATCH 24/41] Closer to working tag colorization but not perfect --- jrnl/util.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/jrnl/util.py b/jrnl/util.py index a4ba89e1a..915f50ccd 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -249,10 +249,13 @@ def colorized_text_generator(fragments): final_text = "" previous_piece = "" for colorized_piece, piece in colorized_text_generator(text_fragments): - if piece in punctuation and previous_piece[0] not in config['tagsymbols']: - final_text = final_text.strip() + colorized_piece + # If it's punctuation and the previous word was a tag, add it directly after the tag. + # TODO: This logic seems flawed... + if piece in punctuation and previous_piece[0] in config['tagsymbols']: + final_text = final_text.lstrip() + colorized_piece else: - final_text += colorized_piece + " " + # Otherwise just append it. + final_text += " " + colorized_piece previous_piece = piece From acc754e3373a3b139b4b465927b011830af4d686 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Fri, 8 Nov 2019 01:48:24 +0100 Subject: [PATCH 25/41] Add tests printing for multiline journals Fix #717 --- features/core.feature | 13 +++++++++++++ features/data/configs/multiline.yaml | 17 +++++++++++++++++ features/data/journals/multiline.journal | 5 +++++ 3 files changed, 35 insertions(+) create mode 100644 features/data/configs/multiline.yaml create mode 100644 features/data/journals/multiline.journal diff --git a/features/core.feature b/features/core.feature index 06afa2acb..61cba8c95 100644 --- a/features/core.feature +++ b/features/core.feature @@ -13,6 +13,19 @@ Feature: Basic reading and writing to a journal | But I'm better. """ + Scenario: Printing a journal that has multiline entries + Given we use the config "multiline.yaml" + When we run "jrnl -n 1" + Then we should get no error + and the output should be + """ + 2013-06-09 15:39 Multiple line entry. + | This is the first line. + | This line doesn't have any ending punctuation + | + | There is a blank line above this. + """ + Scenario: Writing an entry from command line Given we use the config "basic.yaml" When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa." diff --git a/features/data/configs/multiline.yaml b/features/data/configs/multiline.yaml new file mode 100644 index 000000000..aa35b3f5f --- /dev/null +++ b/features/data/configs/multiline.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/multiline.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/features/data/journals/multiline.journal b/features/data/journals/multiline.journal new file mode 100644 index 000000000..294ed141b --- /dev/null +++ b/features/data/journals/multiline.journal @@ -0,0 +1,5 @@ +[2013-06-09 15:39] Multiple line entry. +This is the first line. +This line doesn't have any ending punctuation + +There is a blank line above this. From 99426cecd2c0442879c15a982afd5a5796bef70b Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Fri, 8 Nov 2019 01:49:16 +0100 Subject: [PATCH 26/41] Correctly indent first line of multiline entry --- jrnl/util.py | 1 + 1 file changed, 1 insertion(+) diff --git a/jrnl/util.py b/jrnl/util.py index 915f50ccd..07db329a0 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -256,6 +256,7 @@ def colorized_text_generator(fragments): else: # Otherwise just append it. final_text += " " + colorized_piece + final_text = final_text.lstrip() previous_piece = piece From b6f6b290e34c9fb943936bb00abff252c7b6ec41 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Fri, 8 Nov 2019 01:55:08 +0100 Subject: [PATCH 27/41] Add test for multiline entries with tags --- features/core.feature | 15 +++++++++++++++ features/data/configs/multiline-tags.yaml | 17 +++++++++++++++++ features/data/journals/multiline-tags.journal | 7 +++++++ 3 files changed, 39 insertions(+) create mode 100644 features/data/configs/multiline-tags.yaml create mode 100644 features/data/journals/multiline-tags.journal diff --git a/features/core.feature b/features/core.feature index 61cba8c95..99d933aed 100644 --- a/features/core.feature +++ b/features/core.feature @@ -26,6 +26,21 @@ Feature: Basic reading and writing to a journal | There is a blank line above this. """ + Scenario: Printing a journal that has multiline entries with tags + Given we use the config "multiline-tags.yaml" + When we run "jrnl -n 1" + Then we should get no error + and the output should be + """ + [2013-06-09 15:39] Multiple @line entry with @tags. + | Tag with @punctuation. afterwards + | @TagOnLineAloneWithOutPunctuation + | @TagOnLineAloneWithPunctuation. + | Text before @tag. And After. + | @hi. Hello + | hi Hello + """ + Scenario: Writing an entry from command line Given we use the config "basic.yaml" When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa." diff --git a/features/data/configs/multiline-tags.yaml b/features/data/configs/multiline-tags.yaml new file mode 100644 index 000000000..033aaa27d --- /dev/null +++ b/features/data/configs/multiline-tags.yaml @@ -0,0 +1,17 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/multiline-tags.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" +colors: + date: none + title: none + body: none + tags: none diff --git a/features/data/journals/multiline-tags.journal b/features/data/journals/multiline-tags.journal new file mode 100644 index 000000000..1fb8706fb --- /dev/null +++ b/features/data/journals/multiline-tags.journal @@ -0,0 +1,7 @@ +[2013-06-09 15:39] Multiple @line entry with @tags. +Tag with @punctuation. afterwards +@TagOnLineAloneWithOutPunctuation +@TagOnLineAloneWithPunctuation. +Text before @tag. And After. +@hi. Hello +hi Hello \ No newline at end of file From 95b23d433c124de685a1bd9891fdff8f1edb308a Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Fri, 8 Nov 2019 07:26:37 +0100 Subject: [PATCH 28/41] Remove redundant UNICODE flag --- jrnl/Entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index b23086e27..001eae186 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -51,7 +51,7 @@ def tags(self): @staticmethod def tag_regex(tagsymbols): - pattern = r'(?u)(?:^|\s)([{tags}][-+*#/\w]+)'.format(tags=tagsymbols) + pattern = r'(?:^|\s)([{tags}][-+*#/\w]+)'.format(tags=tagsymbols) return re.compile(pattern, re.UNICODE) def _parse_tags(self): From 77472261deca658174f9bac97fa3403278a5baec Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Fri, 8 Nov 2019 20:53:05 +0100 Subject: [PATCH 29/41] Progress towards proper tag colorization and body formatting --- jrnl/Entry.py | 3 ++- jrnl/util.py | 15 +++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index 001eae186..cda0d8e47 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -51,7 +51,8 @@ def tags(self): @staticmethod def tag_regex(tagsymbols): - pattern = r'(?:^|\s)([{tags}][-+*#/\w]+)'.format(tags=tagsymbols) + # pattern = r'(?:^|\s)([{tags}][-+*#/\w]+)'.format(tags=tagsymbols) + pattern = r'(? Date: Sat, 9 Nov 2019 04:10:46 +0100 Subject: [PATCH 30/41] Fix newline colorization bug Debug code left intact since there are more bugs to fix :/ --- jrnl/util.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/jrnl/util.py b/jrnl/util.py index 8d3951a63..25c56d957 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -17,7 +17,7 @@ import codecs import unicodedata import shlex -from string import punctuation +from string import punctuation, whitespace import logging log = logging.getLogger(__name__) @@ -197,6 +197,10 @@ def get_text_from_editor(config, template=""): return raw +def text_debug(msg, text): + print(f"{msg} : {repr(text)}") + + def colorize(string, color, bold=False): """Returns the string colored with colorama.Fore.color. If the color set by the user is "NONE" or the color doesn't exist in the colorama.Fore attributes, @@ -228,8 +232,7 @@ def colorized_text_generator(fragments): :rtype: List of tuples :returns [(colorized_str, original_str)]""" for fragment in fragments: - for part in fragment.lstrip().split(" "): - # part = part.strip() + for part in fragment.lstrip(" ").lstrip("\t").split(" "): if part and part[0] not in config['tagsymbols']: yield (colorize(part, color, bold), part) elif part: @@ -248,21 +251,24 @@ def colorized_text_generator(fragments): final_text = "" previous_piece = "" - # [print("FRAG: '" + repr(frag) + "'") for frag in text_fragments] + [text_debug("FRAG BEFORE COLORIZED_GEN", frag) for frag in text_fragments] for colorized_piece, piece in colorized_text_generator(text_fragments): # If it's punctuation and the previous word was a tag, add it directly after the tag. # TODO: This logic seems flawed... - if piece in punctuation and previous_piece[0] in config['tagsymbols']: - # print("PUNCT, POST TAG: '" + colorized_piece + "'") + text_debug("PIECE", piece) + if all(char in punctuation + whitespace for char in piece) \ + or previous_piece.endswith("\n") \ + or (previous_piece and previous_piece[0] in config['tagsymbols']): + text_debug("ALL PUNCT OR POST TAG", colorized_piece) final_text += colorized_piece else: # Otherwise just append it. - # print("NOT PUNCT OR NOT POST TAG: '" + colorized_piece + "'") + text_debug("NOT PUNCT OR NOT POST TAG", colorized_piece) final_text += " " + colorized_piece final_text = final_text.lstrip() previous_piece = piece - # print("DONE") + print("DONE") return final_text.lstrip() else: return text From 09c0cccad25cd31cb6066010d0484e4ea13624e2 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 9 Nov 2019 05:30:59 +0100 Subject: [PATCH 31/41] And now the space just ends up before the tag instead of after it --- jrnl/util.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jrnl/util.py b/jrnl/util.py index 25c56d957..2b959f66f 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -231,12 +231,12 @@ def colorized_text_generator(fragments): :param fragments: List of strings representing parts of entry (tag or word). :rtype: List of tuples :returns [(colorized_str, original_str)]""" - for fragment in fragments: - for part in fragment.lstrip(" ").lstrip("\t").split(" "): - if part and part[0] not in config['tagsymbols']: - yield (colorize(part, color, bold), part) - elif part: - yield (colorize(part, config['colors']['tags'], not bold), part) + for part in fragments: + # part = part.rstrip() + if part and part[0] not in config['tagsymbols']: + yield (colorize(part, color, bold), part) + elif part: + yield (colorize(part, config['colors']['tags'], not bold), part) config = entry.journal.config if config['highlight']: # highlight tags From c65c78c4eb9aad913a8b0a5effbca5bde940d141 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 9 Nov 2019 05:52:00 +0100 Subject: [PATCH 32/41] Fix assertion syntax warning --- features/steps/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/core.py b/features/steps/core.py index a6e3c9fa9..d8f00bc5c 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -118,7 +118,7 @@ def has_error(context): @then('we should get no error') def no_error(context): - assert context.exit_status is 0, context.exit_status + assert context.exit_status == 0, context.exit_status @then('the output should be parsable as json') From fcc64fa885057ec10da53e8289db3a48c4efef31 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 9 Nov 2019 05:52:17 +0100 Subject: [PATCH 33/41] Moved tag test to tagging.feature file --- features/core.feature | 15 --------------- features/tagging.feature | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/features/core.feature b/features/core.feature index 99d933aed..61cba8c95 100644 --- a/features/core.feature +++ b/features/core.feature @@ -26,21 +26,6 @@ Feature: Basic reading and writing to a journal | There is a blank line above this. """ - Scenario: Printing a journal that has multiline entries with tags - Given we use the config "multiline-tags.yaml" - When we run "jrnl -n 1" - Then we should get no error - and the output should be - """ - [2013-06-09 15:39] Multiple @line entry with @tags. - | Tag with @punctuation. afterwards - | @TagOnLineAloneWithOutPunctuation - | @TagOnLineAloneWithPunctuation. - | Text before @tag. And After. - | @hi. Hello - | hi Hello - """ - Scenario: Writing an entry from command line Given we use the config "basic.yaml" When we run "jrnl 23 july 2013: A cold and stormy day. I ate crisps on the sofa." diff --git a/features/tagging.feature b/features/tagging.feature index 2cbf7ce11..8b4cefb7a 100644 --- a/features/tagging.feature +++ b/features/tagging.feature @@ -82,3 +82,19 @@ Feature: Tagging """ @thought : 2 """ + + + Scenario: Printing a journal that has multiline entries with tags + Given we use the config "multiline-tags.yaml" + When we run "jrnl -n 1" + Then we should get no error + and the output should be + """ + 2013-06-09 15:39 Multiple @line entry with @tags. + | Tag with @punctuation. afterwards + | @TagOnLineAloneWithOutPunctuation + | @TagOnLineAloneWithPunctuation. + | Text before @tag. And After. + | @hi. Hello + | hi Hello + """ \ No newline at end of file From f218374bf19bad4d41f88c521b6f39ae3d4b3c13 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 9 Nov 2019 05:58:34 +0100 Subject: [PATCH 34/41] Strip out debug code and clean up --- jrnl/Entry.py | 1 - jrnl/util.py | 25 ++++++++----------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index cda0d8e47..82d09c9d6 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -51,7 +51,6 @@ def tags(self): @staticmethod def tag_regex(tagsymbols): - # pattern = r'(?:^|\s)([{tags}][-+*#/\w]+)'.format(tags=tagsymbols) pattern = r'(? Date: Sat, 9 Nov 2019 06:17:15 +0100 Subject: [PATCH 35/41] Bold datetimes in title --- jrnl/Entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index 82d09c9d6..576889da4 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -81,7 +81,7 @@ def pprint(self, short=False): indent = "" date_str = colorize(self.date.strftime(self.journal.config['timeformat']), - self.journal.config['colors']['date']) + self.journal.config['colors']['date'], bold=True) if not short and self.journal.config['linewrap']: # Color date / title and bold title From ea4692208709a7c33b7dc2921c0807d8b369811f Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sat, 9 Nov 2019 06:27:32 +0100 Subject: [PATCH 36/41] Bold all titles Fix #720 --- jrnl/Entry.py | 10 ++++------ jrnl/util.py | 8 ++++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index 576889da4..0a34dafe2 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -89,12 +89,11 @@ def pprint(self, short=False): highlight_tags_with_background_color(self, self.title, self.journal.config['colors']['title'], - bold=True), + is_title=True), self.journal.config['linewrap']) body = highlight_tags_with_background_color(self, self.body.rstrip(" \n"), - self.journal.config['colors']['body'], - bold=False) + self.journal.config['colors']['body']) body_text = [colorize( ansiwrap.fill( line, @@ -119,11 +118,10 @@ def pprint(self, short=False): title = date_str + " " + highlight_tags_with_background_color(self, self.title.rstrip("\n"), self.journal.config['colors']['title'], - bold=True) + is_title=True) body = highlight_tags_with_background_color(self, self.body.rstrip("\n "), - self.journal.config['colors']['body'], - bold=False) + self.journal.config['colors']['body']) # Suppress bodies that are just blanks and new lines. has_body = len(self.body) > 20 or not all(char in (" ", "\n") for char in self.body) diff --git a/jrnl/util.py b/jrnl/util.py index ab58c3ccd..fff8238d6 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -210,14 +210,14 @@ def colorize(string, color, bold=False): return colorama.Style.BRIGHT + color_escape + string + colorama.Style.RESET_ALL -def highlight_tags_with_background_color(entry, text, color, bold=False): +def highlight_tags_with_background_color(entry, text, color, is_title=False): """ Takes a string and colorizes the tags in it based upon the config value for color.tags, while colorizing the rest of the text based on `color`. :param entry: Entry object, for access to journal config :param text: Text to be colorized :param color: Color for non-tag text, passed to colorize() - :param bold: Bold flag text, passed to colorize() + :param is_title: Boolean flag indicating if the text is a title or not :return: Colorized str """ def colorized_text_generator(fragments): @@ -228,9 +228,9 @@ def colorized_text_generator(fragments): :returns [(colorized_str, original_str)]""" for part in fragments: if part and part[0] not in config['tagsymbols']: - yield (colorize(part, color, bold), part) + yield (colorize(part, color, bold=is_title), part) elif part: - yield (colorize(part, config['colors']['tags'], not bold), part) + yield (colorize(part, config['colors']['tags'], bold=True), part) config = entry.journal.config if config['highlight']: # highlight tags From 09802cc0885914e8f628a723b21ca77bc5130855 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sun, 17 Nov 2019 00:49:17 +0100 Subject: [PATCH 37/41] Remove PY2 and PY3 constants --- jrnl/util.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/jrnl/util.py b/jrnl/util.py index bd04605b8..781196629 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -17,8 +17,6 @@ log = logging.getLogger(__name__) -PY3 = sys.version_info[0] == 3 -PY2 = sys.version_info[0] == 2 STDIN = sys.stdin STDERR = sys.stderr STDOUT = sys.stdout From 8c9b0405867f714210ea539e77ffdfa7619c9206 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sun, 17 Nov 2019 00:53:25 +0100 Subject: [PATCH 38/41] Fix regression in features/steps/core.py --- features/steps/core.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index a700ceb2f..c81cc9719 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -218,8 +218,6 @@ def check_output_time_inline(context, text): def check_output_inline(context, text=None): text = text or context.text out = process_ANSI_escapes(context.stdout_capture.getvalue()) - if isinstance(out, bytes): - out = out.decode('utf-8') assert text in out, text From f2bf1ff900a87695e45db6194bf521226eb3f9c2 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Sun, 17 Nov 2019 00:56:01 +0100 Subject: [PATCH 39/41] Fix tag_regex --- jrnl/Entry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index df1a38783..dcf06852c 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -49,8 +49,8 @@ def tags(self): @staticmethod def tag_regex(tagsymbols): - pattern = r'(? Date: Sun, 17 Nov 2019 01:01:04 +0100 Subject: [PATCH 40/41] Remove redundant re.UNICODE flag --- jrnl/Entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jrnl/Entry.py b/jrnl/Entry.py index dcf06852c..4bebbe313 100755 --- a/jrnl/Entry.py +++ b/jrnl/Entry.py @@ -49,7 +49,7 @@ def tags(self): @staticmethod def tag_regex(tagsymbols): - pattern = fr'(?u)(? Date: Sun, 17 Nov 2019 01:04:43 +0100 Subject: [PATCH 41/41] Remove extraneous code --- jrnl/util.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/jrnl/util.py b/jrnl/util.py index 781196629..096f50b7d 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -17,12 +17,6 @@ log = logging.getLogger(__name__) -STDIN = sys.stdin -STDERR = sys.stderr -STDOUT = sys.stdout -TEST = False -__cached_tz = None - WARNING_COLOR = colorama.Fore.YELLOW ERROR_COLOR = colorama.Fore.RED RESET_COLOR = colorama.Fore.RESET