summaryrefslogtreecommitdiff
path: root/ansicat.py
diff options
context:
space:
mode:
Diffstat (limited to 'ansicat.py')
-rwxr-xr-xansicat.py120
1 files changed, 95 insertions, 25 deletions
diff --git a/ansicat.py b/ansicat.py
index fe0e102..af33bb5 100755
--- a/ansicat.py
+++ b/ansicat.py
@@ -106,7 +106,8 @@ def inline_image(img_file,width):
if not os.path.exists(img_file):
return ""
#Chafa is faster than timg inline. Let use that one by default
- inline = None
+ #But we keep a list of "inlines" in case chafa fails
+ inlines = []
ansi_img = ""
#We avoid errors by not trying to render non-image files
if shutil.which("file"):
@@ -120,32 +121,39 @@ def inline_image(img_file,width):
if hasattr(img_obj,"n_frames") and img_obj.n_frames > 1:
# we remove all frames but the first one
img_obj.save(img_file,format="gif",save_all=False)
- inline = "chafa --bg white -s %s -f symbols"
+ inlines.append("chafa --bg white -s %s -f symbols")
elif _NEW_CHAFA:
- inline = "chafa --bg white -t 1 -s %s -f symbols --animate=off"
- if not inline and _NEW_TIMG:
- inline = "timg --frames=1 -p q -g %sx1000"
- if inline:
- cmd = inline%width + " %s"
+ inlines.append("chafa --bg white -t 1 -s %s -f symbols --animate=off")
+ if _NEW_TIMG:
+ inlines.append("timg --frames=1 -p q -g %sx1000")
+ image_success = False
+ while not image_success and len(inlines)>0:
+ cmd = inlines.pop(0)%width + " %s"
try:
ansi_img = run(cmd, parameter=img_file)
+ image_success = True
except Exception as err:
- ansi_img = "***image failed : %s***\n" %err
+ ansi_img = "***IMAGE ERROR***\n%s…\n…%s" %(str(err)[:50],str(err)[-50:])
return ansi_img
def terminal_image(img_file):
#Render by timg is better than old chafa.
# it is also centered
- cmd = None
+ cmds = []
if _NEW_CHAFA:
- cmd = "chafa -C on -d 0 --bg white -t 1 -w 1"
- elif _NEW_TIMG:
- cmd = "timg --loops=1 -C"
+ cmds.append("chafa -C on -d 0 --bg white -t 1 -w 1")
elif _HAS_CHAFA:
- cmd = "chafa -d 0 --bg white -t 1 -w 1"
- if cmd:
- cmd = cmd + " %s"
- run(cmd, parameter=img_file, direct_output=True)
+ cmds.append("chafa -d 0 --bg white -t 1 -w 1")
+ if _NEW_TIMG:
+ cmds.append("timg --loops=1 -C")
+ image_success = False
+ while not image_success and len(cmds) > 0:
+ cmd = cmds.pop(0) + " %s"
+ try:
+ run(cmd, parameter=img_file, direct_output=True)
+ image_success = True
+ except Exception as err:
+ print(err)
# First, we define the different content->text renderers, outside of the rest
@@ -357,15 +365,28 @@ class AbstractRenderer():
# Beware, blocks are not wrapped nor indented and left untouched!
# They are mostly useful for pictures and preformatted text.
- def add_block(self,intext):
+ def add_block(self,intext,theme=None):
# If necessary, we add the title before a block
self._title_first()
# we don’t want to indent blocks
self._endline()
self._disable_indents()
- self.final_text += self.current_indent + intext
- self.new_paragraph = False
- self._endline()
+ #we have to apply the theme for every line in the intext
+ #applying theme to preformatted is controversial as it could change it
+ if theme:
+ block = ""
+ lines = intext.split("\n")
+ for l in lines:
+ self.open_theme(theme)
+ self.last_line += self.current_indent + l
+ self.close_theme(theme)
+ self._endline()
+ self.last_line += "\n"
+ #one thing is sure : we need to keep unthemed blocks for images!
+ else:
+ self.final_text += self.current_indent + intext
+ self.new_paragraph = False
+ self._endline()
self._enable_indents()
def add_text(self,intext):
@@ -633,7 +654,7 @@ class GemtextRenderer(AbstractRenderer):
r.close_theme("preformatted")
elif preformatted:
# infinite line to not wrap preformated
- r.add_block(line+"\n")
+ r.add_block(line+"\n",theme="preformatted")
elif len(line.strip()) == 0:
r.newparagraph(force=True)
elif line.startswith("=>"):
@@ -1077,7 +1098,7 @@ class HtmlRenderer(AbstractRenderer):
toreturn = " " + toreturn
return toreturn
def recursive_render(element,indent="",preformatted=False):
- if element.name == "blockquote":
+ if element.name in ["blockquote", "dd"]:
r.newparagraph()
r.startindent(" ",reverse=" ")
for child in element.children:
@@ -1085,7 +1106,7 @@ class HtmlRenderer(AbstractRenderer):
recursive_render(child,indent="\t")
r.close_theme("blockquote")
r.endindent()
- elif element.name in ["div","p"]:
+ elif element.name in ["div","p","dt"]:
r.newparagraph()
for child in element.children:
recursive_render(child,indent=indent)
@@ -1114,8 +1135,8 @@ class HtmlRenderer(AbstractRenderer):
recursive_render(child,indent=indent,preformatted=True)
elif element.name in ["pre"]:
r.newparagraph()
- r.add_block(element.text)
- r.newparagraph()
+ r.add_block(element.text,theme="preformatted")
+ r.newparagraph(force=True)
elif element.name in ["li"]:
r.startindent(" • ",sub=" ")
for child in element.children:
@@ -1196,6 +1217,52 @@ class HtmlRenderer(AbstractRenderer):
r.add_text(text + link_id)
r.close_theme("image_link")
r.newline()
+
+ elif element.name == "video":
+ poster = element.get("poster")
+ src = element.get("src")
+ for child in element.children:
+ if not src:
+ if child.name == "source":
+ src = child.get("src")
+ text = ""
+ if poster:
+ ansi_img = render_image(poster,width=width,mode=mode)
+ alt = element.get("alt")
+ if alt:
+ alt = sanitize_string(alt)
+ text += "[VIDEO] %s"%alt
+ else:
+ text += "[VIDEO]"
+
+ if poster:
+ if not mode in self.images:
+ self.images[mode] = []
+ poster_url,d = looks_like_base64(poster,self.url)
+ if poster_url:
+ vid_url,d2 = looks_like_base64(src,self.url)
+ self.images[mode].append(poster_url)
+ r.add_block(ansi_img)
+ r.open_theme("image_link")
+ r.center_line()
+ if vid_url and src:
+ links.append(vid_url+" "+text)
+ link_id = " [%s]"%(len(links)+startlinks)
+ r.add_text(text + link_id)
+ else:
+ r.add_text(text)
+ r.close_theme("image_link")
+ r.newline()
+ elif src:
+ vid_url,d = looks_like_base64(src,self.url)
+ links.append(vid_url+" "+text)
+ link_id = " [%s]"%(len(links)+startlinks)
+ r.open_theme("image_link")
+ r.center_line()
+ r.add_text(text + link_id)
+ r.close_theme("image_link")
+ r.newline()
+
elif element.name == "br":
r.newline()
elif element.name not in ["script","style","template"] and type(element) != Comment:
@@ -1288,6 +1355,9 @@ def get_mime(path,url=None):
# If it’s a xml file, consider it as such, regardless of what file thinks
elif path.endswith(".xml"):
mime = "text/xml"
+ # If it doesn’t end with .svg, it is probably an xml, not a SVG file
+ elif "svg" in mime and not path.endswith(".svg"):
+ mime = "text/xml"
#Some xml/html document are considered as octet-stream
if mime == "application/octet-stream":
mime = "text/xml"