Skip to content
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

Resolve Face eagerly when constructing StyledString #99

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 20 additions & 17 deletions src/styledmarkup.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Of course, as usual, the devil is in the details.
module StyledMarkup

using Base: AnnotatedString, annotations, annotatedstring
using ..StyledStrings: Face, SimpleColor
using ..StyledStrings: Face, SimpleColor, getface

export @styled_str, styled

Expand Down Expand Up @@ -325,7 +325,7 @@ function readexpr!(state::State, pos::Int = first(popfirst!(state.s)) + 1)
if isempty(state.s)
styerr!(state,
AnnotatedString("Identifier or parenthesised expression expected after \$ in string",
[(55:55, :face, :warning)]),
[(55:55, :face, getface(:warning))]),
-1, "right here")
return "", pos
end
Expand Down Expand Up @@ -401,7 +401,7 @@ and register it in the active styles list.
"""
function begin_style!(state::State, i::Int, char::Char)
hasvalue = false
newstyles = Vector{Tuple{Int, Int, Union{Symbol, Expr, Tuple{Symbol, Any}}}}()
newstyles = Vector{Tuple{Int, Int, Union{Expr, Tuple{Symbol, Any}}}}()
while read_annotation!(state, i, char, newstyles) end
push!(state.active_styles, reverse!(newstyles))
# Adjust bytes/offset based on how much the index
Expand Down Expand Up @@ -535,9 +535,9 @@ function read_inlineface!(state::State, i::Int, char::Char, newstyles)
valid_options = join(VALID_UNDERLINE_STYLES, ", ", ", or ")
styerr!(state,
AnnotatedString("Invalid underline style '$ustyle_word' (should be $valid_options)",
[(26:25+ncodeunits(ustyle_word), :face, :warning)
[(26:25+ncodeunits(ustyle_word), :face, getface(:warning))
(28+ncodeunits(ustyle_word):39+ncodeunits(ustyle_word)+ncodeunits(valid_options),
:face, :light)]),
:face, getface(:light))]),
-length(ustyle_word) - 3)
end
ustyle = Symbol(ustyle_word)
Expand Down Expand Up @@ -658,24 +658,24 @@ function read_inlineface!(state::State, i::Int, char::Char, newstyles)
else
invalid, lastchar = readsymbol!(state, lastchar)
styerr!(state, AnnotatedString("Invalid height '$invalid', should be a natural number or positive float",
[(17:16+ncodeunits(string(invalid)), :face, :warning)]),
[(17:16+ncodeunits(string(invalid)), :face, getface(:warning))]),
-3)
end
elseif key (:weight, :slant)
v, lastchar = readalph!(state, lastchar)
if key == :weight && v VALID_WEIGHTS
valid_options = join(VALID_WEIGHTS, ", ", ", or ")
styerr!(state, AnnotatedString("Invalid weight '$v' (should be $valid_options)",
[(17:16+ncodeunits(v), :face, :warning),
[(17:16+ncodeunits(v), :face, getface(:warning)),
(19+ncodeunits(v):30+ncodeunits(v)+ncodeunits(valid_options),
:face, :light)]),
:face, getface(:light))]),
-3)
elseif key == :slant && v VALID_SLANTS
valid_options = join(VALID_SLANTS, ", ", ", or ")
styerr!(state, AnnotatedString("Invalid slant '$v' (should be $valid_options)",
[(16:15+ncodeunits(v), :face, :warning),
[(16:15+ncodeunits(v), :face, getface(:warning)),
(18+ncodeunits(v):29+ncodeunits(v)+ncodeunits(valid_options),
:face, :light)]),
:face, getface(:light))]),
-3)
end
Symbol(v) |> if ismacro(state) QuoteNode else identity end
Expand All @@ -702,7 +702,7 @@ function read_inlineface!(state::State, i::Int, char::Char, newstyles)
else
styerr!(state, AnnotatedString(
"Uses unrecognised face key '$key'. Recognised keys are: $(join(VALID_FACE_ATTRS, ", ", ", and "))",
[(29:28+ncodeunits(String(key)), :face, :warning)]),
[(29:28+ncodeunits(String(key)), :face, getface(:warning))]),
-length(str_key) - 2)
end
if ismacro(state) && !any(k -> first(k.args) == key, kwargs)
Expand All @@ -711,7 +711,7 @@ function read_inlineface!(state::State, i::Int, char::Char, newstyles)
push!(kwargs, key => val)
else
styerr!(state, AnnotatedString("Contains repeated face key '$key'",
[(29:28+ncodeunits(String(key)), :face, :warning)]),
[(29:28+ncodeunits(String(key)), :face, getface(:warning))]),
-length(str_key) - 2)
end
isempty(state.s) && styerr!(state, "Incomplete inline face declaration", -1)
Expand All @@ -727,11 +727,11 @@ function read_inlineface!(state::State, i::Int, char::Char, newstyles)
push!(newstyles,
(i, i + state.offset + 1,
if !ismacro(state)
:face, Face(; NamedTuple(kwargs)...)
(:face, Face(; NamedTuple(kwargs)...))
elseif needseval
:((:face, $face))
else
:face, hygienic_eval(state, face)
(:face, hygienic_eval(state, face))
end))
end

Expand Down Expand Up @@ -803,6 +803,7 @@ function read_face_or_keyval!(state::State, i::Int, char::Char, newstyles)
push!(newstyles,
(i, i + state.offset + ncodeunits('{'),
if key isa String && !(value isa Symbol || value isa Expr)
# TODO
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could use some help filling this logic in here

if key might be :face and we want that to display properly, we need to force resolution here too

Symbol(key), value
elseif key isa Expr || key isa Symbol
:(($key, $value))
Expand All @@ -813,9 +814,11 @@ function read_face_or_keyval!(state::State, i::Int, char::Char, newstyles)
push!(newstyles,
(i, i + state.offset + ncodeunits('{'),
if key isa Symbol || key isa Expr
:((:face, $key))
:((:face, $getface($key)))
elseif ismacro(state) # Face symbol
:((:face, $getface($(QuoteNode(Symbol(key))))))
else # Face symbol
:face, Symbol(key)
(:face, getface(Symbol(key)))
end))
end
if isempty(state.s) || last(peek(state.s)) (' ', '\t', '\n', '\r', ',', ':')
Expand Down Expand Up @@ -857,7 +860,7 @@ function run_state_machine!(state::State)
end
for incomplete in Iterators.flatten(state.active_styles)
styerr!(state, AnnotatedString("Unterminated annotation (missing closing '}')",
[(43:43, :face, :warning)]),
[(43:43, :face, getface(:warning))]),
prevind(state.content, first(incomplete)), "starts here")
end
end
Expand Down
Loading