Spaces:
Sleeping
Sleeping
""" | |
ASCII Comment‑Banner Generator (Gradio) | |
Features | |
-------- | |
- Choose any comment style (full list from the supplied table) | |
- Set total width (characters) and total height (lines) | |
- Horizontal alignment : left / centre / right | |
- Vertical alignment : top / centre / bottom | |
- Border filler : '-', '=', '^' or any custom string | |
- Returns a ready‑to‑paste multi‑line comment banner. | |
""" | |
import gradio as gr | |
from itertools import cycle | |
# ---------------------------------------------------------------------- | |
# 1️⃣ Mapping from UI‑friendly names → (start_delim, end_delim) | |
# ---------------------------------------------------------------------- | |
COMMENT_STYLES: dict[str, tuple[str, str]] = { | |
# ----- single‑line comment families --------------------------------- | |
"# (sh, Python, Ruby, etc.)": ("#", "#"), | |
"// (C‑family, JavaScript, Go, Rust…)": ("//", "//"), | |
"; (MASM/TASM, Lisp families)": (";", ";"), | |
"-- (SQL, Haskell, Ada, VHDL…)": ("--", "--"), | |
"% (MATLAB/Octave, LaTeX)": ("%", "%"), | |
"' (VB, VBA, VB.NET)": ("'", "'"), | |
"` (legacy shell)": ("`", "`"), | |
"REM (Batch files)": ("REM", "REM"), | |
":: (Batch hack, works in PowerShell)": ("::", "::"), | |
";; (Racket, Scheme, Clojure read‑time comment)": (";;", ";;"), | |
# ----- block‑only comment families --------------------------------- | |
"<!-- … --> (HTML / XML)": ("<!--", "-->"), | |
"/* … */ (C‑style block)": ("/*", "*/"), | |
"\"\"\" … \"\"\" (Python doc‑string, Elixir multi‑line string)": ('"""', '"""'), | |
"--[[ … ]]" + " (Lua block comment)": ("--[[", "]]"), | |
"#= … =# (Julia block comment)": ("#=", "=#"), | |
"#| … |# (Clojure / CLisp / Racket block)": ("#|", "|#"), | |
"<# … #> (PowerShell block comment)": ("<#", "#>"), | |
"=begin … =end (Ruby block comment)": ("=begin", "=end"), | |
# ----- languages that have both line‑ and block‑styles ------------- | |
"# (Python line comment)": ("#", "#"), | |
"\"\"\" (Python triple‑quote doc‑string)": ('"""', '"""'), | |
"# (Ruby line comment)": ("#", "#"), | |
"=begin/=end (Ruby block comment)": ("=begin", "=end"), | |
"REM (PowerShell line comment)": ("#", "#"), | |
"<# … #> (PowerShell block comment)": ("<#", "#>"), | |
# ----- extra / special cases --------------------------------------- | |
"' (SQL single‑quote comment – rarely used)": ("'", "'"), | |
"-- (Ada line comment)": ("--", "--"), | |
"-- (COBOL comment – column 7)": ("--", "--"), | |
"` (Tcl comment – back‑tick rarely used)": ("`", "`"), | |
"/* … */ (CSS / Less / Sass SCSS)": ("/*", "*/"), | |
"/* … */ (GraphQL SDL – same as C‑style)": ("/*", "*/"), | |
"# (PowerShell line comment – alias for '--')": ("#", "#"), | |
# ----- more block‑style families (HTML‑like) ----------------------- | |
"<!-- … --> (Markdown – HTML comment inside MD)": ("<!--", "-->"), | |
"<!-- … --> (Asciidoc comment)": ("<!--", "-->"), | |
} | |
# ---------------------------------------------------------------------- | |
# 2️⃣ Helper – repeat a pattern so it exactly matches a given length | |
# ---------------------------------------------------------------------- | |
def _repeat_pattern(pattern: str, length: int) -> str: | |
"""Return *pattern* repeated/cycled until *length* characters are filled.""" | |
if not pattern: | |
pattern = "-" # safe fallback | |
return "".join(c for _, c in zip(range(length), cycle(pattern))) | |
# ---------------------------------------------------------------------- | |
# 3️⃣ Core – create the banner | |
# ---------------------------------------------------------------------- | |
def make_banner( | |
text: str, | |
width: int = 80, | |
height: int = 5, | |
h_align: str = "both", # left / both / right | |
v_align: str = "both", # top / both / bottom | |
style: str = "# (sh, Python, Ruby, etc.)", | |
filler: str = "-", # what to repeat on the top/bottom border | |
) -> str: | |
""" | |
Build a comment banner. | |
Parameters | |
---------- | |
text, width, height, h_align, v_align, style – see docstring above. | |
filler : str | |
String that will be repeated (cycled) on the top and bottom border. | |
Any length is accepted. | |
""" | |
# ------------------- 1️⃣ Resolve comment delimiters ------------------- | |
try: | |
start, end = COMMENT_STYLES[style] | |
except KeyError as exc: | |
raise ValueError(f"Unsupported comment style: {style!r}") from exc | |
# ------------------- 2️⃣ Usable width --------------------------------- | |
# pattern: <start>␣<content>␣<end> | |
usable = width - (len(start) + len(end) + 4) # 4 = two spaces + two delimiters | |
if usable < 1: # safety – enlarge if needed | |
usable = 1 | |
width = len(start) + len(end) + 5 | |
# ------------------- 3️⃣ Build line types ---------------------------- | |
border_line = f"{start} " + _repeat_pattern(filler, usable) + f" {end}" | |
# horizontal alignment of the inner text | |
if h_align == "left": | |
inner = text.ljust(usable) | |
elif h_align == "right": | |
inner = text.rjust(usable) | |
else: # centre (default) | |
inner = text.center(usable) | |
text_line = f"{start} " + inner + f" {end}" | |
empty_line = f"{start} " + (" " * usable) + f" {end}" | |
# ------------------- 4️⃣ Vertical padding --------------------------- | |
if height < 3: | |
height = 3 | |
pad_total = height - 3 # lines that are not border / text | |
if v_align == "top": | |
pad_top, pad_bottom = 0, pad_total | |
elif v_align == "bottom": | |
pad_top, pad_bottom = pad_total, 0 | |
else: # centre (default) | |
pad_top = pad_total // 2 | |
pad_bottom = pad_total - pad_top | |
# ------------------- 5️⃣ Assemble ------------------------------- | |
lines = [border_line] # top border | |
lines += [empty_line] * pad_top # upper padding | |
lines.append(text_line) # caption line | |
lines += [empty_line] * pad_bottom # lower padding | |
lines.append(border_line) # bottom border | |
return "\n".join(lines) | |
# ---------------------------------------------------------------------- | |
# 4️⃣ Helper – decide which filler string to actually use | |
# ---------------------------------------------------------------------- | |
def _resolve_filler(preset: str, custom: str) -> str: | |
"""Return the string that should be repeated on the border.""" | |
if preset == "custom": | |
return custom or "-" # fall back to dash if custom empty | |
return preset # '-', '=', '^', … | |
# ---------------------------------------------------------------------- | |
# 5️⃣ Gradio UI | |
# ---------------------------------------------------------------------- | |
# First we build the component list – this is needed so we can refer to it | |
# later when we wrap the function that handles the custom filler. | |
input_components = [ | |
gr.Textbox(label="Banner text", | |
placeholder="Enter your caption here…", | |
lines=1), | |
gr.Slider(minimum=20, maximum=200, step=2, value=80, | |
label="Total width (characters)"), | |
gr.Slider(minimum=3, maximum=30, step=1, value=3, | |
label="Total height (lines)"), | |
gr.Dropdown(choices=["left", "both", "right"], | |
value="both", | |
label="Horizontal alignment"), | |
gr.Dropdown(choices=["top", "both", "bottom"], | |
value="both", | |
label="Vertical alignment"), | |
gr.Dropdown(choices=sorted(COMMENT_STYLES.keys()), | |
value="# (sh, Python, Ruby, etc.)", | |
label="Comment style"), | |
gr.Dropdown(choices=["-", "=", "^", "custom"], | |
value="-", | |
label="Border filler (preset)"), | |
gr.Textbox(label="Custom filler (used only when preset = ‘custom’)", | |
placeholder="e.g. *~* – leave empty for default ‘-’", | |
lines=1), | |
] | |
output_component = gr.Textbox(label="Generated ASCII banner", | |
lines=14, | |
interactive=False) | |
def _gradio_wrapper( | |
text, width, height, | |
h_align, v_align, style, | |
filler_preset, filler_custom | |
): | |
"""Wrapper called by Gradio – resolves the custom filler first.""" | |
filler = _resolve_filler(filler_preset, filler_custom) | |
return make_banner( | |
text=text, | |
width=width, | |
height=height, | |
h_align=h_align, | |
v_align=v_align, | |
style=style, | |
filler=filler, | |
) | |
demo = gr.Interface( | |
fn=_gradio_wrapper, | |
inputs=input_components, | |
outputs=output_component, | |
title="🖼️ ASCII Comment‑Banner Generator", | |
description=( | |
"Create ready‑to‑paste comment blocks for dozens of programming languages. " | |
"Pick width, height, horizontal & vertical alignment, any comment style, " | |
"and the character(s) that will form the top/bottom border (preset ‘-’, ‘=’, ‘^’, " | |
"or a custom string)." | |
), | |
examples=[ | |
# text w h h‑align v‑align style filler preset custom | |
[ | |
"DATA & TRAINING CONFIGURATION PROCESSING", | |
80, 5, "both", "both", "# (sh, Python, Ruby, etc.)", "-", "", | |
], | |
[ | |
"WELCOME TO MY PROJECT", | |
60, 7, "left", "top", "// (C‑family, JavaScript, Go, Rust…)", "=", "", | |
], | |
[ | |
"⚡️ QUICK START", | |
70, 4, "right", "bottom", "/* … */ (C‑style block)", "^", "", | |
], | |
[ | |
"CUSTOM FILLER EXAMPLE", | |
70, 5, "both", "both", "# (sh, Python, Ruby, etc.)", "custom", "*~*", | |
], | |
[ | |
"HTML HEADER", | |
70, 5, "both", "top", "<!-- … --> (HTML / XML)", "-", "", | |
], | |
[ | |
"POWER‑SHELL MODULE", | |
70, 5, "both", "bottom", "<# … #> (PowerShell block comment)", "-", "", | |
], | |
], | |
allow_flagging="never", | |
) | |
if __name__ == "__main__": | |
# `share=True` will give you a public URL (optional) | |
demo.launch() |