Skip to content

Instantly share code, notes, and snippets.

@F4Jonatas
Last active August 9, 2025 13:44
Show Gist options
  • Select an option

  • Save F4Jonatas/01cecb84c1e504fee5eef59f573114bf to your computer and use it in GitHub Desktop.

Select an option

Save F4Jonatas/01cecb84c1e504fee5eef59f573114bf to your computer and use it in GitHub Desktop.
<%Python Printing Template%>
# -*- coding: utf-8 -*
# LICENSE
# Apache License 2.0
import re
import types
from typing import Pattern as regex
###
# <% Printing Template %>
# Simple string printing - template.
# Sometimes, I need to display text with colors and styles,
# but without having to add a complex library to my project.
# With that in mind, I created this simple and straightforward solution
# to display text with colors and styles using only a basic template string.
#
# Unlike rich, it is more flexible to use and does not require the installation of additional libraries.
#
# As there are still improvements to be made, I left an option to debug the process being done, for future analysis.
# Any improvements or suggestions are welcome.
#
#
# printt(
# template [string/required] Text template to print.
# sep [string/optional] Printed between objects. Default: " ".
# end [string/optional] Appended to the end of the statement. Default: "\n".
# file [object/optional] An object with write(string) method. Default: sys.stdout.
# flush [boolean/optional] (Py >= 3.3) Default: False.
# debug [boolean/optional] Show the process being performed in each template. Default: False.
# )
#
# Text Color: use c or color
# printt( '<%color:#ff5555 Any Message%>' )
#
# Background Color: use f or fill
# printt( '<%fill:56,56,56 Any Message%>' )
#
# Bold Style: use b or bold
# printt( '<%bold Any Message%>' )
#
# Italic Style: use i or italic.
# printt( '<%italic Any Message%>' )
#
# Dim Style: use d or dim.
# printt( '<%dim Any Message%>' )
#
# Underline Style: use u or underline.
# printt( '<%underline Any Message%>' )
#
# Blink Style: use blink.
# printt( '<%blink Any Message%>' )
#
# Conceal Style: use conceal.
# printt( '<%conceal Any Message%>' )
#
# Strike Style: use s or strike.
# printt( '<%strike Any Message%>' )
#
# Reverse Style: use r or reverse.
# printt( '<%reverse Any Message%>' )
#
# ANSI Code: use @. ANSI cannot be combined.
# printt( '<%@0;32 Any Message%>' )
#
# Any attribute can be combined with "-". Except for the ANSI code.
# printt( '<%u-i-f:56,56,56-c:#ff5555 Any Message%>' )
###
class printt:
# Constants
__match: regex = re.compile( r'(<%\s*[^\x00]+)([\x00]+)' )
__keys : regex = re.compile( r'(?i)(?<=%)\s*([@vitafcundermbolsk-]*)(\s*(\d+;\d+)|:\s*(((?P<hex1>#[a-f\d]+)|(?P<rgb1>\d{1,3},\d{1,3},\d{1,3}))(?P<second>[corfil-]+:((?P<hex2>#[a-f\d]+)|(?P<rgb2>\d{1,3},\d{1,3},\d{1,3})))?))?\s?' )
__key2 : regex = re.compile( r'(?i)-(?P<key>[corfil]+):((?P<hex>#[a-f\d]+)|(?P<rgb>\d{1,3},\d{1,3},\d{1,3}))' )
__ctype: regex = re.compile( r'(?i)[#,]')
@staticmethod
def extractcor( self, color: str ) -> list | tuple:
tipo: str = self.__ctype.search( color ).group(0)
if tipo == ',':
return color.split( ',' )
elif tipo == '#':
color : str = color.lstrip( '#' )
lv : str = len( color )
color : tuple = tuple( int( color[ i:i + lv // 3 ], 16 ) for i in range( 0, lv, lv // 3 ))
return (
str( color[0] ),
str( color[1] ),
str( color[2] )
)
# Loop through all templates
@staticmethod
def loop( self, template: str, debug: bool = False ):
# template = repr( template )
for find in self.__match.finditer( re.sub( '%>', chr(0), template )):
# temp = repr().encode('unicode_escape').decode()
template = re.sub( '\x00', '', re.sub(
re.escape( find.group(1) + '%>' ),
self.parser( self, find.group(0), debug ),
template
))
if self.__keys.findall( template ):
template = self.loop( self, template, debug )
return template
@staticmethod
def parser( self, template: str, debug: bool = False ) -> str:
text : str = template[:-1]
keywords : list = self.__keys.search( text )
kwordlist: regex = keywords.group(1).split( '-' )
exist : bool = False
# Combine Fill and Color
if keywords.group( 'second' ):
kwordlist.append(
self.__key2.search( keywords.group( 'second' )) \
.group( 'key' )
)
if debug:
print( f'[TEMPLATE INPUT UNICODE]', f'`{ text.encode( 'unicode_escape' ).decode() }%>`\n', sep = '\n' )
print( f'[MATCH TEMPLATE AND CHANGE CLOSE TEMPLATE]', template, '', sep = '\n' )
if keywords and keywords.group(0) != '':
print( f'[KEYWORDS]', keywords.groups(), '', sep = '\n' )
# ANSI Code
if '@' in kwordlist:
# Convert to raw string and remove single quotes.
text: str = repr( text[ keywords.span()[1]: ])[1:-1]
# text = re.escape( text[ keywords.span()[1]: ] )
if debug:
print( f'[TEXT FOUNDED]', f'`{ text.encode( 'unicode_escape' ).decode() }`\n', sep = '\n' )
print( f'[CODE ANSI FOUNDED]', 'Code ANSI: ' + keywords.group(2), '', sep = '\n' )
print( f'[PARSED TEMPLATE]', f'`\033[{ keywords.group(2) }m{text}\033[0m`\n-----\n', sep = '\n' )
return f'\033[{ keywords.group(2) }m{text}\033[0m'
else:
# Remove open template.
text: str = re.sub( fr'^(<%{ keywords.group(0) })|^(<%)', '', text )
if debug:
print( f'[TEXT FOUNDED]', f'`{text}`\n', sep = '\n' )
if 's' in kwordlist or 'strike' in kwordlist:
exist: bool = True
text : str = '\033[9m' + text
if 'conceal' in kwordlist:
exist: bool = True
text : str = '\033[8m' + text
if 'r' in kwordlist or 'reverse' in kwordlist:
exist: bool = True
text : str = '\033[7m' + text
if 'blink' in kwordlist:
exist: bool = True
text : str = '\033[5m' + text
if 'u' in kwordlist or 'underline' in kwordlist:
exist: bool = True
text : str = '\033[4m' + text
if 'i' in kwordlist or 'italic' in kwordlist:
exist: bool = True
text : str = '\033[3m' + text
if 'd' in kwordlist or 'dim' in kwordlist:
exist: bool = True
text : str = '\033[2m' + text
if 'b' in kwordlist or 'bold' in kwordlist:
exist: bool = True
text : str = '\033[1m' + text
if 'f' in kwordlist or 'fill' in kwordlist:
exist: bool = True
# Check if there is a second color and if the second color is fill in.
if keywords.group( 'second' ) and 'f' in self.__key2.search( keywords.group( 'second' )).group( 'key' ):
cor = keywords.group( 'hex2' ) or keywords.group( 'rgb2' )
else:
cor = keywords.group( 'hex1' ) or keywords.group( 'rgb1' )
cor = self.extractcor( self, cor )
if cor:
if debug == True:
print( f'[FILL COLOR FOUNDED]', cor, '', sep = '\n' )
text = '\033[48;2;{0[0]};{0[1]};{0[2]}m'.format( cor ) + text
if 'c' in kwordlist or 'color' in kwordlist:
exist: bool = True
if keywords.group( 'second' ) and 'c' in self.__key2.search( keywords.group( 'second' )).group( 'key' ):
cor = keywords.group( 'hex2' ) or keywords.group( 'rgb2' )
else:
cor = keywords.group( 'hex1' ) or keywords.group( 'rgb1' )
cor = self.extractcor( self, cor )
if cor:
if debug:
print( f'[TEXT COLOR FOUNDED]', cor, '', sep = '\n' )
text = '\033[38;2;{0[0]};{0[1]};{0[2]}m'.format( cor ) + text
# If there are no keywords, simply return the template.
if not exist:
text: str = template[:-1] + '%>'
else:
if debug:
print( f'[PARSED TEMPLATE]', f'`\033[{ text }\033[0m`\n-----\n', sep = '\n' )
return text + '\033[0m'
def __init__( self, template: str, debug: bool = False, **args ):
template = self.loop( self, template, debug )
print( template, **args )
if __name__ == '__main__':
# Testing the printt
printt( '<%color:#ff5555 Any "Font Color" Message%>' )
printt( '<%fill:56,56,56 Any "Background Color" Message%>' )
printt( '<%bold Any "Bold" Message%>' )
printt( '<%italic Any "Italic" Message%>' )
printt( '<%dim Any "Dim" Message%>' )
printt( '<%underline Any "Underline" Message%>' )
printt( '<%blink Any "Blink" Message%>' )
printt( '<%conceal Any "Conceal" Message%>' )
printt( '<%strike Any "Strike" Message%>' )
printt( '<%reverse Any "Reverse" Message%>' )
printt( '<%@0;32 Any "ANSI Code" Message%>' )
printt( '<%u-i-c:#ff5555-f:56,56,56 Any "Combined" Message%>' )
printt( '<%u-i-c:255,255,255-f:#ff5555 Any "Combined" Message%>' )
printt( 'Founded <%b-i-fill:80,16,40 14 backups <%i-c:#cf8a00 of 39 <%s apps%>%>%>...' )
printt( r'<%@0;36 Transmission/2.77 D:\Download%>' )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment