mirror of
https://github.com/chubin/cheat.sh.git
synced 2026-06-20 21:26:44 +02:00
188 lines
5.0 KiB
Python
188 lines
5.0 KiB
Python
"""
|
|
ANSI frontend.
|
|
|
|
Exports:
|
|
visualize(answer_data, request_options)
|
|
|
|
Format:
|
|
answer_data = {
|
|
'answers': '...',}
|
|
|
|
answers = [answer,...]
|
|
|
|
answer = {
|
|
'topic': '...',
|
|
'topic_type': '...',
|
|
'answer': '...',
|
|
'format': 'ansi|code|markdown|text...',
|
|
}
|
|
|
|
Configuration parameters:
|
|
|
|
frontend.styles
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import re
|
|
|
|
import colored
|
|
from pygments import highlight as pygments_highlight
|
|
from pygments.formatters import (
|
|
Terminal256Formatter,
|
|
) # pylint: disable=no-name-in-module
|
|
|
|
# pylint: disable=wrong-import-position
|
|
sys.path.append(os.path.abspath(os.path.join(__file__, "..")))
|
|
from config import CONFIG
|
|
import languages_data # pylint: enable=wrong-import-position
|
|
|
|
import fmt.internal
|
|
import fmt.comments
|
|
|
|
|
|
def visualize(answer_data, request_options):
|
|
"""
|
|
Renders `answer_data` as ANSI output.
|
|
"""
|
|
answers = answer_data["answers"]
|
|
return _visualize(
|
|
answers, request_options, search_mode=bool(answer_data["keyword"])
|
|
)
|
|
|
|
|
|
ANSI_ESCAPE = re.compile(r"(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]")
|
|
|
|
|
|
def remove_ansi(sometext):
|
|
"""
|
|
Remove ANSI sequences from `sometext` and convert it into plaintext.
|
|
"""
|
|
return ANSI_ESCAPE.sub("", sometext)
|
|
|
|
|
|
def _limited_answer(answer):
|
|
return (
|
|
colored.bg("dark_goldenrod")
|
|
+ colored.fg("yellow_1")
|
|
+ " "
|
|
+ answer
|
|
+ " "
|
|
+ colored.attr("reset")
|
|
+ "\n"
|
|
)
|
|
|
|
|
|
def _colorize_ansi_answer(
|
|
topic,
|
|
answer,
|
|
color_style, # pylint: disable=too-many-arguments
|
|
highlight_all=True,
|
|
highlight_code=False,
|
|
unindent_code=False,
|
|
language=None,
|
|
):
|
|
|
|
color_style = color_style or "native"
|
|
lexer_class = languages_data.LEXER["bash"]
|
|
if "/" in topic:
|
|
if language is None:
|
|
section_name = topic.split("/", 1)[0].lower()
|
|
else:
|
|
section_name = language
|
|
section_name = languages_data.get_lexer_name(section_name)
|
|
lexer_class = languages_data.LEXER.get(section_name, lexer_class)
|
|
if section_name == "php":
|
|
answer = "<?\n%s?>\n" % answer
|
|
|
|
if highlight_all:
|
|
highlight = (
|
|
lambda answer: pygments_highlight(
|
|
answer, lexer_class(), Terminal256Formatter(style=color_style)
|
|
).strip("\n")
|
|
+ "\n"
|
|
)
|
|
else:
|
|
highlight = lambda x: x
|
|
|
|
if highlight_code:
|
|
blocks = fmt.comments.code_blocks(
|
|
answer, wrap_lines=True, unindent_code=(4 if unindent_code else False)
|
|
)
|
|
highlighted_blocks = []
|
|
for block in blocks:
|
|
if block[0] == 1:
|
|
this_block = highlight(block[1])
|
|
else:
|
|
this_block = block[1].strip("\n") + "\n"
|
|
highlighted_blocks.append(this_block)
|
|
|
|
result = "\n".join(highlighted_blocks)
|
|
else:
|
|
result = highlight(answer).lstrip("\n")
|
|
return result
|
|
|
|
|
|
def _visualize(answers, request_options, search_mode=False):
|
|
|
|
highlight = not bool(request_options and request_options.get("no-terminal"))
|
|
color_style = (request_options or {}).get("style", "")
|
|
if color_style not in CONFIG["frontend.styles"]:
|
|
color_style = ""
|
|
|
|
# if there is more than one answer,
|
|
# show the source of the answer
|
|
multiple_answers = len(answers) > 1
|
|
|
|
found = True
|
|
result = ""
|
|
for answer_dict in answers:
|
|
topic = answer_dict["topic"]
|
|
topic_type = answer_dict["topic_type"]
|
|
answer = answer_dict["answer"]
|
|
found = found and not topic_type == "unknown"
|
|
|
|
if multiple_answers and topic != "LIMITED":
|
|
section_name = f"{topic_type}:{topic}"
|
|
|
|
if not highlight:
|
|
result += f"#[{section_name}]\n"
|
|
else:
|
|
result += "".join(
|
|
[
|
|
"\n",
|
|
colored.bg("dark_gray"),
|
|
colored.attr("res_underlined"),
|
|
f" {section_name} ",
|
|
colored.attr("res_underlined"),
|
|
colored.attr("reset"),
|
|
"\n",
|
|
]
|
|
)
|
|
|
|
if answer_dict["format"] in ["ansi", "text"]:
|
|
result += answer
|
|
elif topic == ":firstpage-v1":
|
|
result += fmt.internal.colorize_internal_firstpage_v1(answer)
|
|
elif topic == "LIMITED":
|
|
result += _limited_answer(topic)
|
|
else:
|
|
result += _colorize_ansi_answer(
|
|
topic,
|
|
answer,
|
|
color_style,
|
|
highlight_all=highlight,
|
|
highlight_code=(
|
|
topic_type == "question"
|
|
and not request_options.get("add_comments")
|
|
and not request_options.get("remove_text")
|
|
),
|
|
language=answer_dict.get("filetype"),
|
|
)
|
|
|
|
if request_options.get("no-terminal"):
|
|
result = remove_ansi(result)
|
|
|
|
result = result.strip("\n") + "\n"
|
|
return result, found
|