"""
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 .
"""
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 = "
"
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"{msg}"
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'{path}'
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])