Stylize code blocks as actual boxes with margins.

This commit is contained in:
Denis Kasak 2018-11-13 10:28:44 +01:00 committed by Damir Jelić
parent 141814bb84
commit a6cf2e1527
2 changed files with 75 additions and 20 deletions

View file

@ -37,7 +37,9 @@ from . import globals as G
from .globals import W from .globals import W
from .utils import (string_strikethrough, from .utils import (string_strikethrough,
string_color_and_reset, string_color_and_reset,
color_pair) color_pair,
text_block,
colored_text_block)
try: try:
from HTMLParser import HTMLParser from HTMLParser import HTMLParser
@ -275,7 +277,7 @@ class Formatted(object):
def to_weechat(self): def to_weechat(self):
# TODO BG COLOR # TODO BG COLOR
def add_attribute(string, name, value): def add_attribute(string, name, value, attributes):
if not value: if not value:
return string return string
elif name == "bold": elif name == "bold":
@ -303,23 +305,40 @@ class Formatted(object):
W.string_remove_color(string.replace("\n", ""), "") W.string_remove_color(string.replace("\n", ""), "")
) )
elif name == "code": elif name == "code":
code_color_pair = color_pair(
G.CONFIG.color.untagged_code_fg,
G.CONFIG.color.untagged_code_bg
)
if attributes["preformatted"]:
# code block
try: try:
lexer = get_lexer_by_name(value) lexer = get_lexer_by_name(value)
except ClassNotFound: except ClassNotFound:
return string_color_and_reset( return colored_text_block(
string, string,
color_pair(G.CONFIG.color.untagged_code_fg, margin=2,
G.CONFIG.color.untagged_code_bg)) color_pair=code_color_pair)
try: try:
style = get_style_by_name(G.CONFIG.look.pygments_style) style = get_style_by_name(G.CONFIG.look.pygments_style)
except ClassNotFound: except ClassNotFound:
style = "native" style = "native"
code_block = text_block(string, margin=2)
# highlight adds a newline to the end of the string, remove it # highlight adds a newline to the end of the string, remove it
# from the output # from the output
return highlight(string, lexer, highlighted_code = highlight(
WeechatFormatter(style=style)).rstrip() code_block,
lexer,
WeechatFormatter(style=style)
).rstrip()
return highlighted_code
else:
return string_color_and_reset(string, code_color_pair)
elif name == "fgcolor": elif name == "fgcolor":
return "{color_on}{text}{color_off}".format( return "{color_on}{text}{color_off}".format(
color_on=W.color(value), color_on=W.color(value),
@ -344,7 +363,10 @@ class Formatted(object):
# terminal, but doing it the other way around results in garbage. # terminal, but doing it the other way around results in garbage.
if "strikethrough" in attributes: if "strikethrough" in attributes:
text = add_attribute( text = add_attribute(
text, "strikethrough", attributes["strikethrough"] text,
"strikethrough",
attributes["strikethrough"],
attributes
) )
attributes.pop("strikethrough") attributes.pop("strikethrough")
@ -363,7 +385,7 @@ class Formatted(object):
if key == "code" and not attributes["preformatted"]: if key == "code" and not attributes["preformatted"]:
text = text.strip().replace('\n', ' ') text = text.strip().replace('\n', ' ')
text = add_attribute(text, key, value) text = add_attribute(text, key, value, attributes)
# If we're quoted code add quotation marks now. # If we're quoted code add quotation marks now.
if key == "code" and attributes["quote"]: if key == "code" and attributes["quote"]:

View file

@ -14,7 +14,7 @@
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from __future__ import unicode_literals from __future__ import unicode_literals, division
import time import time
from typing import Any, Dict, List from typing import Any, Dict, List
@ -132,3 +132,36 @@ def color_pair(color_fg, color_bg):
return "{},{}".format(color_fg, color_bg) return "{},{}".format(color_fg, color_bg)
else: else:
return color_fg return color_fg
def text_block(text, margin=0):
"""
Pad block of text with whitespace to form a regular block, optionally
adding a margin.
"""
# add vertical margin
vertical_margin = margin // 2
text = "{}{}{}".format(
"\n" * vertical_margin,
text,
"\n" * vertical_margin
)
lines = text.split("\n")
longest_len = max(len(l) for l in lines) + margin
# pad block and add horizontal margin
text = "\n".join(
"{pre}{line}{post}".format(
pre=" " * margin,
line=l,
post=" " * (longest_len - len(l)))
for l in lines)
return text
def colored_text_block(text, margin=0, color_pair=""):
""" Like text_block, but also colors it."""
return string_color_and_reset(text_block(text, margin=margin), color_pair)