print("befoul is a wrapper around colorful. All the normal things should work.")
print(f"Like the simple attributes to {bf.bold}turn bold on{bf.no_bold} and off again.")
print("As well as calling as a function", bf.underlined("to get a wrapped string"), "that resets at its end.")
print(f"But because balancing {{('')}} is {bf.orange('annoying')},")
print(f"we hack up an {bf.bold_orangeRed:alternative!}")
print(f"""\
Everything in a {bf.italic_underlined:replacement field} that comes after a {bf.bold_blinkrapid::} is
a {bf.underlined_italic:format spec}. Well, it's supposed to be, anyway.
But format specs may contain spaces and {bf.underlined:even
newlines}! {bf.mediumAquamarine:No quotes required.}
""")
print(f"""F-strings even {bf.bold_chocolate:let us {bf.underlined_darkOliveGreen:nest} one level} deep.""")
print("""Good old {bf.bold_chocolate:format() {bf.underlined_darkOliveGreen:can nest} {how_many}} as well.""".format(bf=bf, how_many='once'))
from types import SimpleNamespace
adlibs = SimpleNamespace(
occupation="artist",
who="you",
code="an expression",
i18n="internationalization"
)
print(f"""\
An {bf.underlined(adlibs.occupation)} like {adlibs.who} still uses the () syntax for expressions.
Or perhaps {bf.underlined | adlibs.who} prefer the pipe syntax?
You might use one style with both {bf.bold(adlibs.code): and text} in the same field!
I haven't tried this with {bf.bold|adlibs.i18n: templates}. Might take some explaining.
""")
em = bf.underlined_darkOrchid
show = 'illustrate'
print(f"""\
This isn't specific to {em:befoul}, but I thought I should {em|show} that if you use
the {em:same} style {em:over} and {em & bf.bold:over} again, you don't have to {em:rebuild
it} every time! Keep it in a {em & bf.inversed:variable!{bf.on_deepPink:!}!}
""")
print(f"""\
There's one thing left we haven't talked about. What if you had been planning
on using that format spec — for formatting???
The format spec isn't as important for text as it is for other types, but you
still might have been using it to justify text
║{'center':^40}║
║{' or left':<20}{'and right ':>20}║
""")
from textwrap import dedent
SPEC_SEPARATOR = r'\a'
print(f"""Befoul will split your format spec on {bf.bold|SPEC_SEPARATOR}.
The first part will be treated as text as we've been doing,
but everything after {bf.bold|SPEC_SEPARATOR} it'll use as a traditional string format spec.
Colorful's support for this is a bit buggy at the moment, as we see in this example rendered
with correct formatting in no color, and too-small fields with color:
""")
# TODO: link to existing bug about format spec
# TODO: file PR for with_setup not passing new colormode,
# setup doing 'if colormode' instead of 'if none'
for colormode in (bf.NO_COLORS, bf.TRUE_COLORS):
with bf.with_setup(colormode) as c:
c.colormode = colormode
print(dedent(f"""
colors={c.colormode}
╔{'═'*40}╗
║{c.bold:THINGS\a^40}║
║{c.underlined: Thing One\a<20}{c.red:1000 \a>20}║
"""))
See #37. I expect that's fixable without upsetting the implementation too much.
import datetime
now = datetime.datetime.now()
# TODO: file bug about cf.bold(1) + cf.bold(2) orig_string vs styled_string discrepancy
n = 12
print(f"""\
Take advantage of nesting: {bf.bold:today is {now:%A}}
If you do need to replace in the format string before applying style: {bf.bold | f"{now:%{n}A}"}
""")
# In order for {bf.bold|now:%A} to work, we'd need lazy evaluation:
# 1. x.setStyle(bold)
# 2. x.setValue(now)
# 3. x.setFormat('%A')
# 4. x.style.render(x.value.format(x.fmt))
#
# and how would split-fmt apply?
# you'd need {bf.bold|now:%A⧸tail⧸tailFmt}
# and then would you do
# - format(value) + format(tail)
# - format(format(value) + tail)