Skip to content

Commit

Permalink
Support custom styling for code in markdown (#1844)
Browse files Browse the repository at this point in the history
  • Loading branch information
picklelo authored Sep 20, 2023
1 parent 33ee067 commit 3113aec
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 27 deletions.
11 changes: 1 addition & 10 deletions reflex/components/tags/tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,7 @@ def format_props(self) -> List:
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.
Expand Down
44 changes: 27 additions & 17 deletions reflex/components/typography/markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def create(cls, *children, **props) -> 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()
Expand Down Expand Up @@ -118,30 +119,39 @@ def _get_imports(self):
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", " "
)

Expand Down
18 changes: 18 additions & 0 deletions reflex/utils/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 3113aec

Please sign in to comment.