Markdown Design Tests

designmarkdown

This post is a living design reference. Every element below is rendered exactly as it will appear in production — useful for catching contrast issues, spacing problems, or typography quirks before they appear in real posts.


Headings

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Inline Typography

Regular paragraph text. The quick brown fox jumps over the lazy dog.

Bold text and italic text and bold italic text.

Strikethrough text for things that no longer apply.

Inline code snippet within a sentence.

A link to an external site and a link to another post.


Blockquotes

A single-level blockquote. Useful for callouts, epigraphs, and pulled quotes.

Nested blockquotes work too.

This is one level deeper.

And one level deeper still.


Lists

Unordered:

  • First item
  • Second item
    • Nested item
    • Another nested item
      • Deeply nested item
  • Third item

Ordered:

  1. First step
  2. Second step
    1. Sub-step A
    2. Sub-step B
  3. Third step

Task list:

  • Completed task
  • Another completed task
  • Incomplete task
  • Another incomplete task
    • Completed subtask
    • Incomplete subtask

Code Blocks

Plain block with no language:

plain text code block
no syntax highlighting applied

JavaScript:

function greet(name) {
  const message = `Hello, ${name}!`;
  console.log(message);
  return message;
}

greet("world");

TypeScript:

interface Post {
  title: string;
  date: string;
  published: boolean;
}

function getPost(slug: string): Promise<Post> {
  return fetch(`/api/posts/${slug}`).then((r) => r.json());
}

HTML:

<article class="prose">
  <h1>Title</h1>
  <p>A paragraph with <strong>bold</strong> and <em>italic</em> text.</p>
</article>

Ruby:

def palindrome?(str)
  str == str.reverse
end

puts palindrome?("racecar") # => true

CSS:

.prose {
  max-width: 65ch;
  line-height: 1.75;
  color: var(--foreground);
}

Tables

Feature Supported Notes
Headings h1 through h6
Bold / Italic ** and * syntax
Tables GFM extension
Task lists GFM extension
Footnotes Not enabled in this renderer
Wikilinks Obsidian-only syntax

Left-aligned, center-aligned, and right-aligned columns:

Left Center Right
Cell Cell Cell
Longer cell Longer cell Longer cell

Horizontal Rules

Three consecutive hyphens produce a thematic break:



HTML Elements

Foldable content via <details>:

Keyboard keys with <kbd>:

Press Cmd + K to open the command palette. Use Tab to navigate.

Highlighted text with <mark>:

The most important word in this sentence is highlighted for emphasis.


Images

External image with alt text:

A placeholder image representing content


Long-form Prose

The section below tests how extended body copy renders — line length, paragraph spacing, and reading comfort at different font sizes and color themes.


JavaScript is a language that I love which nonetheless has more than its fair share of weird warts. I can live with the strange syntax choices and the various foot-guns that cannot be removed without breaking backwards compatibility. But while I've come to terms with the bad features of JavaScript, I still struggle with the missing features. Consider how equality works in JavaScript:

let x = [1, 2, 3];
let y = [1, 2, 3];
let z = x;

x === y // => false
x === z // => true

Here x !== y because objects are compared with reference equality: x and y have the same contents but refer to different objects. In some cases, this behavior is exactly what you want: x and y may be identical now, but they are not interchangeable in the way that x and z are. If we think of the objects at x and y as locations where state lives, it is crucially important that we can distinguish between these locations.

But in a lot of cases, we just want to know if two objects have the same contents — we want to know if they are structurally equivalent — and JavaScript has no built-in way to answer that. Instead, we have to depend on third-party workarounds, which can have significant file size costs and lack the interoperability of standardized solutions.

Shallow and Deep Equality

The most common approaches to testing structural equality in JavaScript are "shallow" and "deep" equality functions. Shallow equality (as used by "pure components" in React) compares each property in a pair of objects or arrays; if the values of each object's property are equal by reference equality, then the objects are structurally equal. "Deep" equality, as in Node's assert module or Lodash's isEqual, applies this recursively — two objects are deeply equal if the values of each object's property are deeply equal.

However, there are a number of implementation difficulties and edge cases that complicate this:

  • How do you compare objects with circular references?
  • If objects have identical properties but different prototypes, are they equal?
  • How should get/set properties be handled?
  • Should objects compare their non-enumerable properties?
  • Keys in an object are ordered — should that matter for structural equality?

No deep equality function will provide a satisfactory answer for all of these edge cases, which has made TC39 reluctant to standardize. But for the sake of argument, what if the behavior of Lodash's isEqual entered the language as Object.equals? Would that be sufficient?

Equality Protocols

Not quite. ES6 introduced Map and Set; while objects could only support strings as keys, maps and sets could use any object as a key. But maps and sets use reference equality for their keys, which dramatically limits how useful objects-as-keys can be:

let map = new Map();
map.set({ x: 1, y: 2 }, 3);
map.get({ x: 1, y: 2 }); // => undefined

It is not enough to have one function that supports structural equality; it has to permeate the language. Libraries like Immutable.js or Mori that support structural equality do so by implementing their own maps, sets, objects, and arrays that speak a common protocol. JavaScript would probably use a well-known symbol similar to the Iterator protocol:

class Record {
  [Symbol.equals](other) { /* ... */ }
  [Symbol.hashCode]() { /* ... */ }
}

The major problem here is that, to preserve backward compatibility, this would either require new object types or new map and set types. There is also the "moral hazard" of incorrect or inappropriate implementations of equality and hashing — Java, for example, has a notoriously slow and unreliable implementation of URL equality.

Immutable Records

Let's return to the original premises — what does reference equality imply? Consider strings:

class Foo {}
let x = "Foo";
x === Foo.name; // => true

x and Foo.name aren't stored at the same location in memory, but are considered equivalent. Why? Because they are functionally identical; strings that are === equivalent have no distinguishing properties, and there is no scenario where one would ever need to distinguish between one instance of "Foo" from another. Furthermore, two equal strings can never become unequal because they are immutable.

These properties — indistinguishability and immutability — could hold for more complex structures as well. The immutable data structures proposal for JavaScript follows this approach: instead of adding a protocol for comparing arbitrary objects, add data structures that can be functionally identical, and therefore safely compared using ===.

There are a few reasons why this proposal is a better fit for JavaScript than the others:

  1. It introduces new objects but does not change any existing ones, avoiding backwards compatibility issues.
  2. It does not require any new operators, functions, or protocols, because immutable records compare with === and can work as keys in existing maps and sets.
  3. It avoids the edge cases with deep equality because immutable records have no prototype chain and only enumerable "normal" fields.

Conclusions

It's worth noting that none of these proposals are remotely novel. JavaScript users have probably been writing deep equality functions since day one. Equality and hashing protocols are present in nearly every other language created in the last thirty years. Structural equality-by-default for immutable data structures is fundamental to functional programming.

Each of these has been proposed in some form or another for official inclusion in the language, but ultimately dismissed — deep equality for its limitations and unavoidable edge cases, equality and hashing protocols for their complexity and possibility for abuse, and immutability for implementation difficulties and lack of interest.

"JavaScript is a big tent language, and the most JavaScript-y solution would be to adopt all of these approaches."

Frankly, JavaScript must adopt some form of structural equality. The status quo is unacceptable; structural equality is as fundamental a feature to modern programming as closures, dictionaries, or lexical scope.