220 lines
5.9 KiB
Python
220 lines
5.9 KiB
Python
"""
|
|
Silique (https://www.silique.fr)
|
|
Copyright (C) 2024-2026
|
|
|
|
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, Optional
|
|
from html import escape
|
|
|
|
from ..utils import dump, CommonFormatter
|
|
from ..i18n import _
|
|
|
|
|
|
def to_id(path):
|
|
# https://www.w3.org/TR/html4/types.html#type-name
|
|
return "".join(e if e in ["-", "_", ":", "."] or e.isalnum() else ":" for e in path)
|
|
|
|
|
|
class Formatter(CommonFormatter):
|
|
"""The markdown (for github) formatter"""
|
|
|
|
name = "github"
|
|
_tabular_name = "github"
|
|
level = 50
|
|
enter_tabular = "<br/>"
|
|
|
|
def __init__(self, rougailconfig, **kwarg) -> None:
|
|
self.max_line_variable = 0
|
|
self.max_line_description = 0
|
|
super().__init__(rougailconfig, **kwarg)
|
|
|
|
def title(
|
|
self,
|
|
title: str,
|
|
level: int,
|
|
collapse: bool=True,
|
|
) -> str:
|
|
"""Display family name as a title"""
|
|
char = "#"
|
|
return f"{char * level} {title}"
|
|
|
|
def join(
|
|
self,
|
|
lst: List[str],
|
|
) -> str:
|
|
"""Display line in tabular from a list"""
|
|
return self.enter_tabular.join(
|
|
[l.replace("\n", self.enter_tabular) for l in lst]
|
|
)
|
|
|
|
def bold(
|
|
self,
|
|
msg: str,
|
|
) -> str:
|
|
"""Set a text to bold"""
|
|
return f"**{msg}**"
|
|
|
|
def italic(
|
|
self,
|
|
msg: str,
|
|
) -> str:
|
|
"""Set a text to italic"""
|
|
return f"*{msg}*"
|
|
|
|
def delete(
|
|
self,
|
|
msg: str,
|
|
) -> str:
|
|
"""Set a text to deleted"""
|
|
return f"~~{msg}~~"
|
|
|
|
def underline(
|
|
self,
|
|
msg: str,
|
|
) -> str:
|
|
"""Set a text to underline"""
|
|
return f"<ins>{msg}</ins>"
|
|
|
|
def stripped(
|
|
self,
|
|
text: str,
|
|
) -> str:
|
|
"""Return stripped text (as help)"""
|
|
return text.strip().replace("\n", self.enter_tabular)
|
|
|
|
def list(
|
|
self,
|
|
choices: list,
|
|
*,
|
|
inside_tabular: bool = True,
|
|
type_: str = "variable",
|
|
with_enter: bool = True,
|
|
):
|
|
"""Display a liste of element"""
|
|
end = ""
|
|
if type_ == "variable":
|
|
if inside_tabular:
|
|
if with_enter:
|
|
char = first_char = f"{self.enter_tabular}• "
|
|
else:
|
|
first_char = f"• "
|
|
char = f"{self.enter_tabular}{first_char}"
|
|
else:
|
|
first_char = "- "
|
|
char = "\n- "
|
|
else:
|
|
first_char = f"{self.family_informations_starts_list_first()}- "
|
|
char = f"\n{first_char}"
|
|
end = self.family_informations_ends_line()
|
|
ret = ""
|
|
for idx, choice in enumerate(choices):
|
|
if not isinstance(choice, str):
|
|
choice = dump(choice)
|
|
if not idx:
|
|
c = first_char
|
|
else:
|
|
c = char
|
|
ret += end + c + choice
|
|
return ret
|
|
|
|
def family_informations_starts_list_first(self):
|
|
return self.family_informations_starts_line()
|
|
|
|
def prop(
|
|
self,
|
|
prop: str,
|
|
italic: bool,
|
|
delete: bool,
|
|
underline: bool,
|
|
) -> str:
|
|
"""Display property"""
|
|
prop = f"`{prop}`"
|
|
if italic:
|
|
prop = self.italic(prop)
|
|
if delete:
|
|
prop = self.delete(prop)
|
|
if underline:
|
|
prop = self.underline(prop)
|
|
return prop
|
|
|
|
def tabular_header(self, lst):
|
|
"""Manage the header of a tabular"""
|
|
return lst
|
|
return [l + " " * (self.max_line_variable - len(l)) for l in lst]
|
|
|
|
def _yaml(self, _dump: str) -> str:
|
|
"""Dump yaml part of documentation"""
|
|
return f"```yaml\n{_dump}\n```"
|
|
|
|
def link_variable(
|
|
self,
|
|
path: str,
|
|
true_path: str,
|
|
description: str,
|
|
filename: Optional[str],
|
|
) -> str:
|
|
name = to_id(true_path)
|
|
if filename:
|
|
link = f"{filename}#{name}"
|
|
else:
|
|
link = f"#{name}"
|
|
return f'"[{description}]({link})"'
|
|
|
|
def anchor(
|
|
self,
|
|
path: str,
|
|
true_path: str,
|
|
) -> str:
|
|
name = to_id(true_path)
|
|
return f'<a id="{name}" name="{name}">{path}</a>'
|
|
|
|
def link(
|
|
self,
|
|
comment: str,
|
|
link: str,
|
|
underline: bool,
|
|
) -> str:
|
|
"""Add a link"""
|
|
comment = 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_tabular):
|
|
self.max_line_variable = max(self.max_line_variable, len(l) + 1)
|
|
self.max_line_description = self.max_line_variable
|
|
|
|
def to_phrase(self, text: str) -> str:
|
|
return escape(text)
|
|
|
|
def family_informations(self):
|
|
start = self.family_informations_starts_line()
|
|
return start + "[!NOTE]\n" + start + "\n"
|
|
|
|
def family_informations_ends_line(self) -> str:
|
|
return "\\\n"
|
|
|
|
def family_informations_starts_line(self) -> str:
|
|
return "> "
|
|
|
|
def display_family_informations(self, msg) -> str:
|
|
start = self.family_informations_starts_line()
|
|
end = self.family_informations_ends_line()
|
|
return self.family_informations() + end.join([start + m for m in msg])
|