Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
135 changes: 135 additions & 0 deletions fix-mdx-styles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#!/usr/bin/env python3
"""
fix-mdx-styles.py – Perfect JSX style conversion
Fixes:
• style="width: 100%" → style={{ width: "100%" }}
• style="margin: 2rem" → style={{ margin: "2rem" }}
• Handles percentages, px, rem, colors, var(), calc(), etc.
• No extra spaces inside {{ }}
• Works with symlinks and large repos (Layer5 tested)
"""

import re
import sys
from pathlib import Path

DRY_RUN = "--dry" in sys.argv
VERBOSE = "--verbose" in sys.argv or "-v" in sys.argv


def css_value_needs_quotes(value: str) -> bool:
"""
Return True if the CSS value must be wrapped in quotes in JSX.
Examples that DO need quotes: 100%, 2rem, center, relative, "some text"
Examples that DO NOT: 42, 3.14, #fff, var(--color), calc(100% - 20px)
"""
value = value.strip()

# These are safe without quotes
if re.match(r"^(\d+\.?\d*|\.\d+)(px|rem|em|%|vh|vw|deg|grad|rad|turn|s|ms)?$", value, re.I):
return True # 100%, 16px, 2.5rem → needs quotes!
if re.match(r"^(#|rgb|hsl|var\(|calc\(|url\(|inherit|initial|unset|transparent|none|auto)", value, re.I):
return False
if value.isdigit():
return False

# pure numbers like flex: 1
return True # everything else: center, relative, "flex", etc.


def css_to_jsx(css: str) -> str:
css = css.strip()
if not css:
return "{}"
if "{{" in css or "}}" in css:
return css

rules = [r.strip() for r in css.split(";") if r.strip()]
entries = []

for rule in rules:
if ":" not in rule:
continue
key, val = rule.split(":", 1)
key = key.strip()
val = val.strip().rstrip(";").strip()
if not key:
continue

# kebab → camelCase
key = re.sub(r"-([a-zA-Z])", lambda m: m.group(1).upper(), key)

# Quote only when necessary — but % values ALWAYS need quotes
if css_value_needs_quotes(val):
val = f'"{val.replace('"', '\\"')}"'

entries.append(f"{key}: {val}")

return "{ " + ", ".join(entries) + " }" if entries else "{}"


def fix_file(filepath: Path) -> tuple[bool, int]:
try:
text = filepath.read_text(encoding="utf-8")
except Exception as e:
print(f"Skipping {filepath}: {e}")
return False, 0

def repl(match):
css_content = match.group(2)
jsx_obj = css_to_jsx(css_content)
return f"style={{{jsx_obj}}}"

new_text, count = re.subn(
r'style\s*=\s*(["\'])(.+?)\1',
repl,
text,
flags=re.DOTALL
)

if count > 0 and new_text != text:
if not DRY_RUN:
filepath.write_text(new_text, encoding="utf-8")
return True, count
return False, 0


def safe_path(p: Path) -> str:
try:
return p.relative_to(Path.cwd()).as_posix()
except ValueError:
return p.as_posix()


def main():
root = Path(".")
mdx_files = list(root.rglob("*.mdx"))

print(f"Scanning {len(mdx_files)} .mdx files...\n")

changed_files = 0
total_fixes = 0

for file in sorted(mdx_files):
changed, fixes = fix_file(file)
if changed:
changed_files += 1
total_fixes += fixes
status = "(dry run)" if DRY_RUN else "FIXED"
print(f"{status} → {safe_path(file)} ({fixes} style(s))")

print("\n" + "="*60)
print("Conversion Complete!")
print(f" Files scanned : {len(mdx_files)}")
print(f" Files changed : {changed_files}")
print(f" Style fixes : {total_fixes}")

if DRY_RUN:
print("\n DRY RUN — no files were modified.")
print(" Run without --dry to apply changes.")
else:
print("\n All style attributes now use perfect JSX syntax!")


if __name__ == "__main__":
main()
3 changes: 2 additions & 1 deletion src/components/Learn-Components/Pagination/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ const Pagination = ({ TOCData, chapterData, location }) => {
<Button $secondary title="Next Chapter"
className="next-chapter-btn"
$url={`/learn/learning-paths/${chapterData.fields.learnpath}/${chapterData.fields.course}/${getActiveServiceMesh(chapterData)}/${nextChapter}/`}
$external={false} />
$external={false}
/>
</div>
</div>
</PaginationWrapper>)
Expand Down
9 changes: 6 additions & 3 deletions src/components/Learn-Components/QuizModal/quiz-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ const ResultBox = ({ score, resetQuiz,correct, incorrect,total }) => (
<div onClick={resetQuiz}>
<Button $secondary title="Go to Learning Paths"
$url={"/learn/learning-paths"}
$external={false} />
$external={false}
/>
</div>
</div>
</div>
Expand Down Expand Up @@ -118,7 +119,8 @@ const QuestionBox = (props) => {
<div className="quizbox__progress--score quizbox__progress--control" onClick={() => {
props.prevQuestion();
setSelectedAnswer(null);
}}>
}}
>
<BsArrowLeft className="quizbox__progress-control__icon"/>
<label>Previous</label>
</div>
Expand All @@ -127,7 +129,8 @@ const QuestionBox = (props) => {
<div className="quizbox__progress--score quizbox__progress--control" onClick={() => {
props.nextQuestion();
setSelectedAnswer(null);
}}>
}}
>
<label>{props.answers.length === props.questionIndex ? "Finish" : "Next"} </label>
<BsArrowRight className="quizbox__progress-control__icon"/>
</div>
Expand Down
8 changes: 5 additions & 3 deletions src/components/Pricing/PricingAddons/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ export const PricingAddons = ({ isYearly = false, setIsYearly, currency, enterpr
control={<Switch disabled
checked={selectedSubAddOns["academy-theory"] || false}
onChange={(e) => handleSubAddOnToggle("academy-theory", e.target.checked)}
color="primary" />}
color="primary"
/>}
sx={formControlStyles.base}
/>
<FeatureDetails
Expand All @@ -306,7 +307,8 @@ export const PricingAddons = ({ isYearly = false, setIsYearly, currency, enterpr
control={<Switch sx={formControlStyles.switch}
checked={selectedSubAddOns["academy-practical"] || false}
onChange={(e) => handleSubAddOnToggle("academy-practical", e.target.checked)}
color="primary" />}
color="primary"
/>}
sx={formControlStyles.base}
/>
<FeatureDetails
Expand Down Expand Up @@ -395,7 +397,7 @@ export const PricingAddons = ({ isYearly = false, setIsYearly, currency, enterpr
),
})) || [];
})()}
/>
/>
<Box sx={boxStyles.disclaimerSection}>
<Typography variant="body2" sx={typographyStyles.italic}>
Looking for a plan larger than 2,500 learners? Great! <a href="/company/contact">Let us know</a>.
Expand Down
3 changes: 2 additions & 1 deletion src/components/SMI-Table/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ const Table = ({ columns, data, spec }) => {
<React.Fragment key={`row${i}`}>
<tr key={`row${i}`} id={`row${i}`} className="primaryRow" {...row.getRowProps()} onClick={() => {
let e = isCollapsed; e[i] = !isCollapsed[i]; setCollapse([...e]);
}}>
}}
>
<td>
{
(non_functional.find(ele => ele.name.includes(row.original.mesh_name))) ?
Expand Down
3 changes: 2 additions & 1 deletion src/components/TopPromotionalBanner/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ const TopPromotionalBanner = () => {
<>
<TopBannercontainer>
<a href="https://meshery.io/blog/meshery-v07-release-announcement" rel="noreferrer" target="_blank"><p className="content"><img src={Rocket} alt="Five on rocket" /><span>Soar to New Heights with Meshery v0.7.0 &rarr;</span>{/* <span>Try it now &rarr;</span> */}
</p></a>
</p>
</a>
</TopBannercontainer>
</>
);
Expand Down
3 changes: 2 additions & 1 deletion src/components/UpcomingEventCard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ const UpcomingEvents = ({ data }) => {
<div className="blog-slider swiper">
<div style={{
display: "block"
}} className="blog-slider__wrp swiper-wrapper">
}} className="blog-slider__wrp swiper-wrapper"
>

<Swiper
spaceBetween={50}
Expand Down
3 changes: 2 additions & 1 deletion src/components/service-mesh-patterns-Table/Table.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ const Table = () => {
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column, index) => (
<th key={index} {...column.getHeaderProps()}
className={(column.Header == "Service Mesh Pattern" || column.Header == "Category") ? "table-header" : ""}>
className={(column.Header == "Service Mesh Pattern" || column.Header == "Category") ? "table-header" : ""}
>
<div >
{column.render("Header")}
{(column.Header == "Service Mesh Pattern") ?
Expand Down
3 changes: 2 additions & 1 deletion src/pages/cloud-native-management/catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ export default Catalog;
export const Head = () => {
return <SEO title="Cloud Native Catalog"
description="The Kubernetes and Cloud Native Catalog. Build, share, innovate with CNCF project-curated best practices."
image="/images/meshery-logo-dark-text.webp" />;
image="/images/meshery-logo-dark-text.webp"
/>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ export default Aws;
export const Head = () => {
return <SEO title="AWS Architecture Diagram"
description="Create your own AWS architecture diagrams with Kanvas."
image="/images/meshery-logo-dark-text.webp" />;
image="/images/meshery-logo-dark-text.webp"
/>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ export default Gcp;
export const Head = () => {
return <SEO title="Google Cloud Platform (GCP) Architecture Diagramming"
description="Create your own Google Cloud Platform solution architecture and collaborative, visual diagrams with Kanvas."
image="/images/meshery-logo-dark-text.webp" />;
image="/images/meshery-logo-dark-text.webp"
/>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ export default Kubernetes;
export const Head = () => {
return <SEO title="Kubernetes Architecture Diagram"
description="Create your own Kubernetes diagrams with Kanvas."
image="/images/meshery-logo-dark-text.webp" />;
image="/images/meshery-logo-dark-text.webp"
/>;
};
3 changes: 2 additions & 1 deletion src/pages/cloud-native-management/meshery/getting-started.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ export default MesheryMainPage;
export const Head = () => {
return <SEO title="Meshery Getting Started"
description="How to get started with cloud native management. Adopting and operating your cloud native infrastructure."
image="/images/meshery-logo-dark-text.webp" />;
image="/images/meshery-logo-dark-text.webp"
/>;
};
3 changes: 2 additions & 1 deletion src/pages/cloud-native-management/meshery/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ const Meshery = () => {
export default Meshery;
export const Head = () => {
return <SEO title="Meshery" description="Lifecycle, performance, and configuration management for cloud native infrastructure as code. Manage your Kubernetes clusters visually. Use the catalog of patterns and best practices."
image="/images/meshery-logo-dark-text.webp" />;
image="/images/meshery-logo-dark-text.webp"
/>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export default MesheryOperator;
export const Head = () => {
return <SEO title="Meshery Operator"
description="Meshery Operator is the multi-cluster Kubernetes operator that manages MeshSync and it’s messaging broker."
image="/images/meshery-operator.webp" />;
image="/images/meshery-operator.webp"
/>;
};
3 changes: 2 additions & 1 deletion src/pages/community/meshmates.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ export const Head = () => {
return <SEO title="Meshmates"
description="MeshMates - the Layer5 contributor onboarding program.
MeshMates is a collection of cloud native mentors."
image={seoImage} />;
image={seoImage}
/>;
};
3 changes: 2 additions & 1 deletion src/pages/community/open-source-program.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export default OpenSourcePricingProgramPage;
export const Head = () => {
return <SEO title="Layer5 Open Source Program"
description="Layer5, empowerer of engineers. At Layer5, we believe collaboration enables innovation, and infrastructure enables collaboration."
image="/images/Layer5-overview.svg" />;
image="/images/Layer5-overview.svg"
/>;
};
3 changes: 2 additions & 1 deletion src/pages/company/news.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@ const NewsGridPage = ({ data }) => {
export default NewsGridPage;
export const Head = () => {
return <SEO title="News" description="News and press about Layer5, the cloud native management company.
Layer5 the company behind industry-leading, open source software." />;
Layer5 the company behind industry-leading, open source software."
/>;
};
3 changes: 2 additions & 1 deletion src/pages/docker-extension-meshery.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export default MesheryDocker;
export const Head = () => {
return <SEO title="Docker Extension for Meshery"
description="The Docker Extension for Meshery extends Docker Desktop’s position as the cloud native developer’s go-to Kubernetes environment with collaborative and visual management of their world of multi-cluster Kubernetes."
image="/images/meshery-logo-dark-text.webp" />;
image="/images/meshery-logo-dark-text.webp"
/>;
};
3 changes: 2 additions & 1 deletion src/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export const Head = () => {
};
return (
<SEO title="Layer5" description="An empowerer of engineers, Layer5 helps you extract more value from your infrastructure. Creator and maintainer of cloud native standards. Maker of Meshery, the cloud native manager."
schemaMarkup={schema} />
schemaMarkup={schema}
/>
);
};
export default IndexPage;
3 changes: 2 additions & 1 deletion src/pages/learn/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export default LearnGridPage;
export const Head = () => {
return <SEO title="Learn DevOps and Cloud Native"
description="Learn DevOps and Cloud Native: Kubernetes and all the CNCF projects."
image="/images/workshops.webp" />;
image="/images/workshops.webp"
/>;
};
3 changes: 2 additions & 1 deletion src/pages/learn/learning-paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export default LearningPathsPage;
export const Head = () => {
return <SEO title="DevOps, GitOps, and Cloud Native Learning Paths"
description="Learning Paths offer a structured approach to learning, combining theoretical cloud native knowledge with hands-on, practical experience."
image="/images/workshops.webp" />;
image="/images/workshops.webp"
/>;
};
3 changes: 2 additions & 1 deletion src/pages/pricing/open-source-program.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export default OpenSourcePricingProgramPage;
export const Head = () => {
return <SEO title="Layer5 Open Source Program"
description="Layer5, empowerer of engineers. At Layer5, we believe collaboration enables innovation, and infrastructure enables collaboration."
image="/images/Layer5-overview.svg" />;
image="/images/Layer5-overview.svg"
/>;
};
3 changes: 2 additions & 1 deletion src/pages/products/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export default Products;
export const Head = () => {
return <SEO title="Kubernetes management made collaborative"
description="Layer5, empowerer of engineers. At Layer5, we believe collaboration enables innovation, and infrastructure enables collaboration."
image="/images/Layer5-overview.svg" />;
image="/images/Layer5-overview.svg"
/>;
};
3 changes: 2 additions & 1 deletion src/pages/projects/cloud-native-performance.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export default SMP;
export const Head = () => {
return <SEO title="Cloud Native Performance"
description="Measuring and indexing the performance, overhead, and value of the world's cloud native deployments."
image="/images/smp-dark.webp" />;
image="/images/smp-dark.webp"
/>;
};
Loading
Loading