Support custom styling for code in markdown (#1844)

This commit is contained in:
Nikhil Rao 2023-09-20 11:40:25 -07:00 committed by GitHub
parent 33ee0675d4
commit 3113aecb30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 27 deletions

View File

@ -51,16 +51,7 @@ class Tag(Base):
Returns:
The formatted props list.
"""
# If there are no props, return an empty string.
if len(self.props) == 0:
return []
# Format all the props.
return [
f"{name}={format.format_prop(prop)}"
for name, prop in sorted(self.props.items())
if prop is not None
] + [str(prop) for prop in self.special_props]
return format.format_props(*self.special_props, **self.props)
def add_props(self, **kwargs: Optional[Any]) -> Tag:
"""Add props to the tag.

View File

@ -91,6 +91,7 @@ class Markdown(Component):
return super().create(src, **props)
def _get_imports(self):
# Import here to avoid circular imports.
from reflex.components.datadisplay.code import Code, CodeBlock
imports = super()._get_imports()
@ -118,30 +119,39 @@ class Markdown(Component):
return imports
def _render(self):
# Import here to avoid circular imports.
from reflex.components.datadisplay.code import Code, CodeBlock
from reflex.components.tags.tag import Tag
def format_props(tag):
return "".join(
Tag(
name="", props=Style(self.custom_styles.get(tag, {}))
).format_props()
)
components = {
tag: f"{{({{node, ...props}}) => <{(component().tag)} {{...props}} {''.join(Tag(name='', props=Style(self.custom_styles.get(tag, {}))).format_props())} />}}"
tag: f"{{({{node, ...props}}) => <{(component().tag)} {{...props}} {format_props(tag)} />}}"
for tag, component in components_by_tag.items()
}
components[
"code"
] = """{({node, inline, className, children, ...props}) =>
{
const match = (className || '').match(/language-(?<lang>.*)/);
return !inline ? (
<Prism
children={String(children).replace(/\n$/, '')}
language={match ? match[1] : ''}
theme={light}
{...props}
/>
) : (
<Code {...props}>
{children}
</Code>
);
}}""".replace(
] = f"""{{({{node, inline, className, children, ...props}}) => {{
const match = (className || '').match(/language-(?<lang>.*)/);
return !inline ? (
<{CodeBlock().tag}
children={{String(children).replace(/\n$/, '')}}
language={{match ? match[1] : ''}}
style={{light}}
{{...props}}
{format_props("pre")}
/>
) : (
<{Code.create().tag} {{...props}} {format_props("code")}>
{{children}}
</{Code.create().tag}>
);
}}}}""".replace(
"\n", " "
)

View File

@ -327,6 +327,24 @@ def format_prop(
return wrap(prop, "{", check_first=False)
def format_props(*single_props, **key_value_props) -> list[str]:
"""Format the tag's props.
Args:
single_props: Props that are not key-value pairs.
key_value_props: Props that are key-value pairs.
Returns:
The formatted props list.
"""
# Format all the props.
return [
f"{name}={format_prop(prop)}"
for name, prop in sorted(key_value_props.items())
if prop is not None
] + [str(prop) for prop in sorted(single_props)]
def get_event_handler_parts(handler: EventHandler) -> tuple[str, str]:
"""Get the state and function name of an event handler.