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: Returns:
The formatted props list. The formatted props list.
""" """
# If there are no props, return an empty string. return format.format_props(*self.special_props, **self.props)
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]
def add_props(self, **kwargs: Optional[Any]) -> Tag: def add_props(self, **kwargs: Optional[Any]) -> Tag:
"""Add props to the tag. """Add props to the tag.

View File

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

View File

@ -327,6 +327,24 @@ def format_prop(
return wrap(prop, "{", check_first=False) 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]: def get_event_handler_parts(handler: EventHandler) -> tuple[str, str]:
"""Get the state and function name of an event handler. """Get the state and function name of an event handler.