rougail-output-doc/src/rougail/output_doc/output/console.py

200 lines
5.6 KiB
Python

"""
Silique (https://www.silique.fr)
Copyright (C) 2024-2025
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser 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 Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from typing import List
from ..i18n import _
from ..utils import dump, CommonFormatter
class Formatter(CommonFormatter):
"""The console formatter"""
name = "console"
level = 10
enter_table = "\n"
titles_color = {
"title1": "bright_cyan underline bold",
"title2": "bright_green underline bold",
"title3": "green1 underline bold",
"title4": "green3 underline bold",
"title5": "dark_green underline bold",
}
def __init__(self, rougailconfig, **kwargs) -> None:
from rich.table import Table
from rich.theme import Theme
from rich.console import Console
from rich.syntax import Syntax
self.rich_table = Table
self.rich_console = Console
self.rich_syntaxt = Syntax
self.custom_theme = Theme(self.titles_color)
self.max_line = 0
super().__init__(rougailconfig, **kwargs)
def _run(self, dico: dict, level: int, dico_is_already_treated=False) -> str:
if not dico_is_already_treated:
dico = self.dict_to_dict(dico, level, init=True)
return self.compute(dico)
def compute(self, dico):
if self.rougailconfig["doc.force_true_color_terminal"]:
force_terminal = 'xterm-256color'
else:
force_terminal = None
console = self.rich_console(theme=self.custom_theme, force_terminal=force_terminal)
with console.capture() as capture:
for data in dico:
console.print(data)
return capture.get()
def title(
self,
title: str,
level: int,
) -> str:
"""Display family name as a title"""
space = " " * (2 * (level - 1))
return f"{space}[title{level}]{title}[/title{level}]\n"
def join(
self,
lst: List[str],
) -> str:
"""Display line in table from a list"""
return self.enter_table.join(lst)
def bold(
self,
msg: str,
) -> str:
"""Set a text to bold"""
return f"[bold]{msg}[/bold]"
def italic(
self,
msg: str,
) -> str:
"""Set a text to italic"""
return f"[italic]{msg}[/italic]"
def delete(
self,
msg: str,
) -> str:
"""Set a text to delete"""
return f"[strike]{msg}[/strike]"
def underline(
self,
msg: str,
) -> str:
"""Set a text to underline"""
return f"[underline]{msg}[/underline]"
def stripped(
self,
text: str,
) -> str:
"""Return stripped text (as help)"""
return text
def list(
self,
choices: list,
*,
inside_table: bool=True,
type_: str="variable",
) -> str:
"""Display a liste of element"""
if type_ == "variable":
char = f"{self.enter_table}"
else:
char = f"\n{self.family_informations_starts_line()}"
ret = ""
for choice in choices:
if not isinstance(choice, str):
choice = dump(choice)
ret += char + choice
return ret
def prop(
self,
prop: str,
italic: bool,
delete: bool,
underline: bool,
) -> str:
"""Display property"""
if italic:
prop = self.italic(prop)
if delete:
prop = self.delete(prop)
if underline:
prop = self.underline(prop)
prop = f"[reverse][bold] {prop} [/bold][/reverse]"
return prop
def yaml(self, _dump):
"""Dump yaml part of documentation"""
return self.rich_syntaxt(f'---\n{dump(_dump)}', 'yaml')
def link(
self,
comment: str,
link: str,
underline: bool,
) -> str:
"""Add a link"""
return self.prop(comment, False, False, underline)
# return f"{comment} ({link})"
def columns(
self,
col: List[str],
) -> None:
"""count columns length"""
for line in col:
for l in line.split(self.enter_table):
self.max_line = max(self.max_line, len(l) + 1)
def table(self, with_header: bool = True) -> str:
"""Transform list to a table in string format"""
table = self.rich_table(show_lines=True)
if with_header:
for column in self.table_datas.headers():
table.add_column(column, width=self.max_line)
for data in self.table_datas.get():
table.add_row(*data)
return table
def family_informations(self) -> str:
info = "[blue]" + self.bold(f"🛈 {_('Informations')}") + "[/blue]"
starts_line = self.family_informations_starts_line()
return starts_line + info + "\n" + starts_line
def family_informations_starts_line(self) -> str:
return "[blue]▌ [/blue]"
def family_informations_ends_line(self) -> str:
return "\n"
def end_family_informations(self) -> str:
return "\n"