-
-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Outputting to LaTeX coloring #108
Comments
IDK if this feature belongs in a stdlib but I definitely want it to exist somewhere. |
Loosely related: JuliaLang/julia#35936 |
This reminds me, I have a stashed commit that implements most of diff@@ -212,7 +212,7 @@ function termstyle(io::IO, face::Face, lastface::Face=getface())
ANSI_STYLE_CODES.start_underline,
ANSI_STYLE_CODES.end_underline))
end
- face.strikethrough == lastface.strikethrough || !haskey(Base.current_terminfo, :smxx) ||
+ face.strikethrough == lastface.strikethrough || !haskey(Base.current_terminfo, :enter_strikeout_mode) ||
print(io, ifelse(face.strikethrough === true,
ANSI_STYLE_CODES.start_strikethrough,
ANSI_STYLE_CODES.end_strikethrough))
@@ -295,6 +295,8 @@ function write(io::IO, aio::Base.AnnotatedIOBuffer)
end
end
+
+
"""
A mapping between ANSI named colors and 8-bit colors for use in HTML
representations.
@@ -319,18 +321,16 @@ const HTML_BASIC_COLORS = Dict{Symbol, SimpleColor}(
:bright_cyan => SimpleColor(0x26, 0xc6, 0xda),
:bright_white => SimpleColor(0xf6, 0xf5, 0xf4))
-function htmlcolor(io::IO, color::SimpleColor)
+function hexcolor(io::IO, color::SimpleColor)
if color.value isa Symbol
if color.value === :default
- print(io, "initial")
elseif (fg = get(FACES.current[], color.value, getface()).foreground) != SimpleColor(color.value)
- htmlcolor(io, fg)
+ hexcolor(io, fg)
else
- htmlcolor(io, get(HTML_BASIC_COLORS, color.value, SimpleColor(:default)))
+ hexcolor(io, get(HTML_BASIC_COLORS, color.value, SimpleColor(:default)))
end
else
(; r, g, b) = color.value
- print(io, '#')
r < 0x10 && print(io, '0')
print(io, string(r, base=16))
g < 0x10 && print(io, '0')
@@ -340,6 +340,15 @@ function htmlcolor(io::IO, color::SimpleColor)
end
end
+function htmlcolor(io::IO, color::SimpleColor)
+ if color.value isa Symbol && color.value === :default
+ print(io, "initial")
+ else
+ print(io, '#')
+ hexcolor(io, color)
+ end
+end
+
const HTML_WEIGHT_MAP = Dict{Symbol, Int}(
:thin => 100,
:extralight => 200,
@@ -469,3 +478,113 @@ function show(io::IO, ::MIME"text/html", s::Union{<:AnnotatedString, SubString{<
write(io, take!(buf))
nothing
end
+
+
+
+const TEX_WEIGHT_CODES = Dict{Symbol, String}(
+ :thin => "ul",
+ :extralight => "el",
+ :light => "l",
+ :semilight => "sl",
+ :normal => "m",
+ :medium => "m",
+ :semibold => "sb",
+ :bold => "b",
+ :extrabold => "eb",
+ :black => "ub")
+
+const TEX_SLANT_CODES = Dict{Symbol, String}(
+ :italic => "it",
+ :slanted => "sl",
+ :oblique => "sl"
+)
+
+function texstyle(io::IO, face::Face, lastface::Face=getface())
+ created_group_count = 0
+ if face.font != lastface.font ||
+ face.height != lastface.height ||
+ face.weight != lastface.weight ||
+ face.slant != lastface.slant
+ print(io, '{')
+ created_group_count += 1
+ if face.font != lastface.font
+ # TODO
+ end
+ if face.height != lastface.height
+ height = string(face.height ÷ 10)
+ print(io, "\\fontsize{", height, "pt}{", height, "pt}")
+ end
+ if face.weight != lastface.weight
+ print(io, "\\fontseries{", get(TEX_WEIGHT_CODES, face.weight, "m"), "}")
+ end
+ if face.slant != lastface.slant
+ print(io, "\\fontshape{", get(TEX_SLANT_CODES, face.slant, "n"), "}")
+ end
+ print(io, "\\selectfont ")
+ end
+ foreground, background =
+ ifelse(face.inverse === true,
+ (face.background, face.foreground),
+ (face.foreground, face.background))
+ lastforeground, lastbackground =
+ ifelse(lastface.inverse === true,
+ (lastface.background, lastface.foreground),
+ (lastface.foreground, lastface.background))
+ if background != lastbackground
+ print(io, "\\colorbox[HTML]{")
+ hexcolor(io, background)
+ print(io, "}{")
+ created_group_count += 1
+ end
+ if face.underline != lastface.underline && face.underline !== false
+ print(io, "\\underline{")
+ created_group_count += 1
+ end
+ if face.strikethrough != lastface.strikethrough && face.strikethrough !== false
+ print(io, "\\sout{")
+ created_group_count += 1
+ end
+ if foreground != lastforeground
+ if created_group_count == 0
+ print(io, '{')
+ created_group_count += 1
+ end
+ print(io, "\\color[HTML]{")
+ hexcolor(io, foreground)
+ print(io, "}")
+ end
+ created_group_count
+end
+
+function show(io::IO, ::MIME"text/latex", s::Union{<:AnnotatedString, SubString{<:AnnotatedString}})
+ texescape(str) = replace(str, '\\' => "\\char92{}", '^' => "\\char94{}", "~" => "\\char126{}",
+ r"[\\{}$%&_#]" => s"\\\0")
+ buf = IOBuffer() # Avoid potential overhead in repeatadly printing a more complex IO
+ lastface::Face = getface()
+ groupdepth = 0
+ for (str, styles) in eachregion(s)
+ face = getface(styles)
+ link = let idx=findfirst(==(:link) ∘ first, styles)
+ if !isnothing(idx)
+ string(last(styles[idx]))::String
+ end end
+ !isnothing(link) && print(buf, "\\href{", texescape(link), "}{")
+ if face == getface()
+ print(buf, '}' ^ groupdepth)
+ groupdepth = 0
+ elseif (lastface.background, lastface.underline, lastface.strikethrough) !=
+ (face.background, face.underline, face.strikethrough)
+ # We can't un-inherit backgrounds, underlines, or strikethroughts
+ print(buf, '}' ^ groupdepth)
+ groupdepth = texstyle(buf, face, getface())
+ else
+ groupdepth += texstyle(buf, face, lastface)
+ end
+ print(buf, texescape(str))
+ !isnothing(link) && print(buf, '}')
+ lastface = face
+ end
+ print(buf, '}' ^ groupdepth)
+ write(io, take!(buf))
+ nothing
+end IIRC it's a little bit of elbow grease off actually working well. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
x-ref MilesCranmer/AirspeedVelocity.jl#74
This is probably out-of-scope but I was wondering if there was any way to get a LaTeX-style coloring of text, for use in markdown-like contexts such as on GitHub? For example,$\color{red}\text{this text is shown in red.}$
This is mostly useful for GitHub actions that output GitHub comments – I'd like to control coloring of those via StyledStrings.jl.
The text was updated successfully, but these errors were encountered: