papis: Extend papis-show to use rich output

Papis show can now show output styled by python-rich if it
is in the environment. Otherwise falls back to normal
console printing.
Added more information to output (journal, volume, issue,
type, doi) but also added `-s` switch which returns to
old single-line behavior for copying to other programs.
This commit is contained in:
Marty Oehme 2023-08-25 16:25:54 +02:00
parent 4994e9782d
commit bda8a3d6f6
Signed by: Marty
GPG Key ID: EDBF2ED917B2EF6A
1 changed files with 113 additions and 3 deletions

View File

@ -1,6 +1,116 @@
#!/usr/bin/env bash
#!/usr/bin/env python
# papis-short-help: Display pretty human-readable document overview
#
# TODO strip {} from bibtex entries to really pretty print
# Takes a query and displays the metadata of the results. Uses
# python-rich to display pretty panels if it exists in the environment,
# otherwise displays regular text.
# Can be invoked with -s to display single-line results better for
# pasting into other documents.
papis -l "${PAPIS_LIB}" list --format "{doc[author]} ({doc[year]}). {doc[title]}." "$@"
import argparse
from importlib.util import find_spec
from papis import database
from papis.database.base import Database
from papis.document import Document
from dataclasses import dataclass, field
parser = argparse.ArgumentParser()
parser.add_argument(
"--short", "-s", help="only display single-line quick info", action="store_true"
)
parser.add_argument(
"--url",
dest="identifier",
help="display identifier (doi, isbn, url) or not",
action=argparse.BooleanOptionalAction,
default=True,
)
parser.add_argument("query", nargs="*", help="the query to search for")
args = parser.parse_args()
@dataclass
class DocInfo:
author: str = ""
title: str = ""
year: str = ""
journal: str = ""
volume: str = ""
issue: str = ""
pages: str = ""
publisher: str = ""
tags: list = field(default_factory=lambda: [])
dtype: str = ""
identifier: str = ""
doi: str = ""
@staticmethod
def from_Document(doc: Document):
t: list[str] | str = doc.get("tags", "")
tags = (
t.replace(";", ",").replace(" ", "").split(",") if isinstance(t, str) else t
)
return DocInfo(
author=doc.get("author", ""),
title=doc.get("title", ""),
year=doc.get("year", ""),
journal=doc.get("journal", ""),
volume=doc.get("volume", ""),
issue=doc.get("issue", ""),
pages=doc.get("pages", ""),
publisher=doc.get("publisher", ""),
tags=tags,
dtype=doc.get("type", ""),
identifier=doc.get("doi", doc.get("isbn", doc.get("url", ""))),
)
def main(db: Database, args) -> None:
query = " ".join(args.query)
docs: list[Document] = db.query(query)
for doc in docs:
info = DocInfo.from_Document(doc)
if args.short:
print_short(info, with_identifier=args.identifier)
else:
print_info(info, with_identifier=args.identifier)
def print_short(doc: DocInfo, with_identifier: bool = True) -> None:
print(
f"{doc.author} ({doc.year}). {doc.title}. "
f"{doc.identifier if with_identifier else ''}\n"
)
def print_info(doc: DocInfo, with_identifier: bool = True) -> None:
if find_spec("rich"):
from rich import print as richprint
from rich.panel import Panel
info: str = (
f"[red]{doc.author}[/red] ({doc.year}) "
f"[steel_blue]\\[{doc.dtype}][/steel_blue]\n"
f"[bold]{doc.title}[/bold]\n"
f"{doc.journal} ({doc.volume}/{doc.issue}){doc.pages} - {doc.publisher}\n"
f"[grey69]{[tag for tag in doc.tags]} "
)
if with_identifier:
info += f"[link={doc.identifier}]{doc.identifier}[/link][/grey69]"
richprint(Panel(info, expand=False))
else:
info: str = (
f"{doc.author} ({doc.year}) "
f"[{doc.dtype}]\n"
f"{doc.title}\n"
f"{doc.journal} ({doc.volume}/{doc.issue}){doc.pages} - {doc.publisher}\n"
f"{[tag for tag in doc.tags]} "
f"{doc.identifier}"
if with_identifier
else ""
)
print(f"{info}\n---")
if __name__ == "__main__":
main(database.get(), args)