Commit bb126f00 authored by Bram Schoenmakers's avatar Bram Schoenmakers

Merge pull request #60 from mruwek/ls-format

Adjust `PrettyPrinterFormatFilter` to achieve current `topydo ls` output (and more)
parents 8650033b 7120f866
......@@ -31,6 +31,7 @@ setup(
url = "https://github.com/bram85/topydo",
install_requires = [
'six >= 1.9.0',
'arrow',
],
extras_require = {
':sys_platform=="win32"': ['colorama>=0.2.5'],
......
......@@ -195,7 +195,7 @@ class ListCommandTest(CommandTest):
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.output, "| 3| (C) Baz @Context1 +Project1 key:value id:1\n| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n")
self.assertEqual(self.output, "| 3| (C) Baz @Context1 +Project1 id:1 key:value\n| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n")
self.assertEqual(self.errors, "")
def test_list20(self):
......
......@@ -15,7 +15,7 @@ auto_creation_date = 1
hide_tags = id,p,ical
indent = 0
list_limit = -1
list_format = |%i| (%p) %s
list_format = |%I| %x %c %{(}p{)} %s %k
[tags]
tag_start = t
......
......@@ -69,7 +69,7 @@ class _Config:
'hide_tags': 'id,p,ical',
'indent': '0',
'list_limit': '-1',
'list_format': '|%i| (%p) %s',
'list_format': '|%I| %x %c %{(}p{)} %s %k',
},
'tags': {
......@@ -111,7 +111,7 @@ class _Config:
self.config = {}
self.cp = configparser.ConfigParser()
self.cp = configparser.RawConfigParser()
for section in self.defaults:
self.cp.add_section(section)
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
""" Ulities for formatting output with "list_format" option."""
import arrow
def filler(p_str, p_len):
"""
Returns p_str preceded by additional spaces if p_str is shorter than p_len.
"""
to_fill = p_len - len(p_str)
return to_fill*' ' + p_str
def humanize_date(p_datetime):
now = arrow.now()
date = now.replace(day=p_datetime.day, month=p_datetime.month, year=p_datetime.year)
return date.humanize()
......@@ -22,6 +22,7 @@ from six import u
from topydo.lib.Colors import NEUTRAL_COLOR, Colors
from topydo.lib.Config import config
from topydo.lib.ListFormat import filler, humanize_date
class PrettyPrinterFilter(object):
......@@ -139,20 +140,29 @@ class PrettyPrinterFormatFilter(PrettyPrinterFilter):
'c': lambda t: t.creation_date().isoformat() if t.creation_date() else '',
# relative creation date
'C': lambda t: '#', # TODO: humanized creation date
'C': lambda t: humanize_date(t.creation_date()) if t.creation_date() else '',
# absolute due date
'd': lambda t: t.due_date().isoformat() if t.due_date() else '',
# relative due date
'D': lambda t: '#', # TODO: humanized due date
'D': lambda t: humanize_date(t.due_date()) if t.due_date() else '',
# todo ID
'i': lambda t: str(self.todolist.number(t)),
# todo ID pre-filled with 1 or 2 spaces if its length is <3
'I': lambda t: filler(str(self.todolist.number(t)), 3),
# list of tags (spaces)
'K': lambda t: ' '.join(['{}:{}'.format(tag, value)
for tag, value in sorted(p_todo.tags())]),
'K': lambda t: ' '.join([u('{}:{}').format(tag, value)
for tag, value in sorted(p_todo.tags()) if
tag not in config().hidden_tags()]),
# list of tags (spaces) without due: and t:
'k': lambda t: ' '.join([u('{}:{}').format(tag, value)
for tag, value in sorted(p_todo.tags()) if
tag not in config().hidden_tags() + [config().tag_start(), config().tag_due()]]),
# priority
'p': lambda t: t.priority() if t.priority() else '',
......@@ -164,7 +174,10 @@ class PrettyPrinterFormatFilter(PrettyPrinterFilter):
't': lambda t: t.start_date().isoformat() if t.start_date() else '',
# relative start date
'T': lambda t: '#', # TODO: humanized start date
'T': lambda t: humanize_date(t.start_date()) if t.start_date() else '',
# completed
'x': lambda t: 'x ' + t.completion_date().isoformat() if t.is_completed() else '',
# literal %
'%': lambda _: '%',
......@@ -173,7 +186,39 @@ class PrettyPrinterFormatFilter(PrettyPrinterFilter):
p_todo_str = self.format
for placeholder, getter in placeholders.items():
p_todo_str = re.sub(r'%\[?{}\]?'.format(placeholder), getter(p_todo), p_todo_str)
return p_todo_str
repl = getter(p_todo)
pattern = (r'(?P<start>.*)'
r'%(?P<before>{{.+?}})?'
r'\[?(?P<placeholder>{})\]?'
r'(?P<after>{{.+?}})?'
r'(?P<whitespace>\s)*'
r'(?P<end>.*)').format(placeholder)
match = re.match(pattern, p_todo_str)
if match:
if repl == '':
p_todo_str = re.sub(pattern, match.group('start') + match.group('end'), p_todo_str)
else:
def strip_braces(p_matchobj):
try:
before = p_matchobj.group('before').strip('{}')
except AttributeError:
before = ''
placeholder = p_matchobj.group('placeholder')
try:
after = p_matchobj.group('after').strip('{}')
except AttributeError:
after = ''
whitespace = p_matchobj.group('whitespace') or ''
start = p_matchobj.group('start') or ''
end = p_matchobj.group('end') or ''
return start + before + '%' + placeholder + after + whitespace + end
p_todo_str = re.sub(pattern, strip_braces, p_todo_str)
p_todo_str = re.sub(r'%{}'.format(placeholder), repl, p_todo_str)
return p_todo_str.rstrip()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment