Skip to content
Open
Show file tree
Hide file tree
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
144 changes: 144 additions & 0 deletions __tests__/xml-to-json.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/**
* @jest-environment jsdom
*/
import { xmlToJson } from "../lib/xmlToJson";

describe("XML to JSON Converter", () => {
describe("Basic conversion", () => {
it("should convert simple XML to JSON", () => {
const xml = "<root><name>test</name></root>";
const result = xmlToJson(xml);
expect(result).toEqual({ root: { name: "test" } });
});

it("should handle nested elements", () => {
const xml = "<root><parent><child>value</child></parent></root>";
const result = xmlToJson(xml);
expect(result).toEqual({
root: { parent: { child: "value" } },
});
});

it("should handle empty elements", () => {
const xml = "<root><empty></empty></root>";
const result = xmlToJson(xml);
expect(result).toEqual({ root: { empty: null } });
});
});

describe("Attribute handling", () => {
it("should convert XML attributes to @attributes object", () => {
const xml = '<root id="123"><name>test</name></root>';
const result = xmlToJson(xml);
expect(result).toEqual({
root: { "@attributes": { id: "123" }, name: "test" },
});
});

it("should handle multiple attributes", () => {
const xml = '<root id="123" class="main" data-test="true"></root>';
const result = xmlToJson(xml);
expect(result).toEqual({
root: {
"@attributes": { id: "123", class: "main", "data-test": "true" },
},
});
});

it("should handle element with only attributes", () => {
const xml = '<root id="123"></root>';
const result = xmlToJson(xml);
expect(result).toEqual({
root: { "@attributes": { id: "123" } },
});
});
});

describe("Array handling", () => {
it("should convert multiple same-named elements to array", () => {
const xml = "<root><item>1</item><item>2</item><item>3</item></root>";
const result = xmlToJson(xml);
expect(result).toEqual({ root: { item: ["1", "2", "3"] } });
});

it("should handle mixed elements with arrays", () => {
const xml =
"<root><name>test</name><item>1</item><item>2</item></root>";
const result = xmlToJson(xml);
expect(result).toEqual({
root: { name: "test", item: ["1", "2"] },
});
});
});

describe("Text content handling", () => {
it("should handle text content with attributes", () => {
const xml = '<root id="1">text content</root>';
const result = xmlToJson(xml);
expect(result).toEqual({
root: { "@attributes": { id: "1" }, "#text": "text content" },
});
});

it("should trim whitespace from text content", () => {
const xml = "<root><name> test </name></root>";
const result = xmlToJson(xml);
expect(result).toEqual({ root: { name: "test" } });
});
});

describe("Error handling", () => {
it("should throw error for invalid XML", () => {
const xml = "<root><unclosed>";
expect(() => xmlToJson(xml)).toThrow("Invalid XML");
});

it("should throw error for malformed XML", () => {
const xml = "not xml at all";
expect(() => xmlToJson(xml)).toThrow("Invalid XML");
});
});

describe("Complex XML structures", () => {
it("should handle deeply nested structures", () => {
const xml =
"<root><level1><level2><level3>deep</level3></level2></level1></root>";
const result = xmlToJson(xml);
expect(result).toEqual({
root: { level1: { level2: { level3: "deep" } } },
});
});

it("should handle real-world XML example", () => {
const xml = `
<users>
<user id="1">
<name>John</name>
<email>john@example.com</email>
</user>
<user id="2">
<name>Jane</name>
<email>jane@example.com</email>
</user>
</users>
`;
const result = xmlToJson(xml);
expect(result).toEqual({
users: {
user: [
{
"@attributes": { id: "1" },
name: "John",
email: "john@example.com",
},
{
"@attributes": { id: "2" },
name: "Jane",
email: "jane@example.com",
},
],
},
});
});
});
});
150 changes: 150 additions & 0 deletions components/seo/MarkdownToHtmlSEO.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import Link from "next/link";

export default function MarkdownToHtmlSEO() {
return (
<div className="content-wrapper">
<section>
<p>
This free tool quickly converts Markdown to HTML. Ideal for blog
posts, documentation, README files, or web content. Just paste your
Markdown and get clean HTML code. Built with 💜 by the Jam developers.
</p>
</section>

<section>
<h2>How to Use the Markdown to HTML Converter</h2>
<p>
To convert Markdown to HTML, simply paste your Markdown content in the
input field and the HTML output will appear instantly. No signup
required.
</p>
<p>
Our converter supports all standard Markdown syntax including headers,
bold, italic, links, images, code blocks, lists, and more.
</p>
<p>
Need to work with other formats? Check out our{" "}
<Link href="/utilities/json-formatter">JSON Formatter</Link> or{" "}
<Link href="/utilities/xml-to-json">XML to JSON</Link> converter.
</p>
</section>

<section>
<h2>Supported Markdown Syntax</h2>
<ul>
<li>
<b>Headers:</b> <br /> Use # for h1, ## for h2, up to ###### for h6.
</li>
<li>
<b>Bold & Italic:</b> <br /> Use **text** or __text__ for bold,
*text* or _text_ for italic.
</li>
<li>
<b>Links:</b> <br /> Use [link text](url) to create hyperlinks.
</li>
<li>
<b>Images:</b> <br /> Use ![alt text](image-url) to embed images.
</li>
<li>
<b>Code:</b> <br /> Use `inline code` or triple backticks for code
blocks with syntax highlighting.
</li>
<li>
<b>Lists:</b> <br /> Use - or * for unordered lists, numbers for
ordered lists.
</li>
<li>
<b>Blockquotes:</b> <br /> Use &gt; at the start of a line for
quotes.
</li>
</ul>
</section>

<section>
<h2>Benefits of Converting Markdown to HTML</h2>
<p>
Markdown is a lightweight markup language that&apos;s easy to write and
read. HTML (HyperText Markup Language) is the standard language for
creating web pages.
</p>
<ul>
<li>
<b>Web Publishing:</b> <br /> Convert your Markdown documentation or
blog posts directly to HTML for web publishing.
</li>
<li>
<b>Email Content:</b> <br /> Transform Markdown into HTML for rich
email content that displays correctly in all email clients.
</li>
<li>
<b>Documentation:</b> <br /> Convert README files and documentation
written in Markdown to HTML for hosting on websites.
</li>
<li>
<b>Content Management:</b> <br /> Many CMS platforms accept HTML
input, making this converter useful for content migration.
</li>
</ul>
</section>

<section>
<h2>Markdown vs HTML: When to Use Each</h2>
<ul>
<li>
<b>Writing Speed:</b> <br /> Markdown is faster to write and more
readable in its raw form. HTML offers more control over formatting
and layout.
</li>
<li>
<b>Portability:</b> <br /> Markdown files are plain text and work
anywhere. HTML requires a browser or renderer to display properly.
</li>
<li>
<b>Features:</b> <br /> HTML supports advanced features like forms,
tables with styling, and interactive elements. Markdown is simpler
but covers most common formatting needs.
</li>
<li>
<b>Use Cases:</b> <br /> Markdown is perfect for documentation,
README files, and notes. HTML is essential for web pages and
applications.
</li>
</ul>
</section>

<section>
<h2>FAQs</h2>
<ul>
<li>
<b>Can you convert Markdown to HTML?</b> <br /> Yes, our tool
instantly converts Markdown syntax to valid HTML code that you can
use on any website.
</li>
<li>
<b>Is this converter free to use?</b> <br /> Yes, this Markdown to
HTML converter is completely free, open source, and has no ads.
</li>
<li>
<b>Does the converter support code syntax highlighting?</b> <br />{" "}
Yes, fenced code blocks with language specification are converted to
HTML with appropriate class names for syntax highlighting.
</li>
<li>
<b>Is my data secure?</b> <br /> Absolutely. All conversion happens
in your browser. Your data never leaves your device.
</li>
<li>
<b>What Markdown flavors are supported?</b> <br /> Our converter
supports standard Markdown syntax including GitHub Flavored Markdown
features like task lists and strikethrough.
</li>
<li>
<b>Can I use this for large documents?</b> <br /> Yes, the converter
handles documents of any size efficiently since all processing is
done client-side.
</li>
</ul>
</section>
</div>
);
}
Loading