Lesson 5 • Markdown (final lesson)
Advanced Markdown Features
By the end of this lesson you'll write GitHub-Flavoured Markdown like a maintainer: footnotes, collapsible sections, escaped characters, raw HTML, anchor-link tables of contents, badges, emoji, and highlighted code — everything a polished README needs.
What You'll Learn
- Add footnotes with [^label] and match references to definitions
- Embed raw HTML (centring, <kbd>, <span style>) inside Markdown
- Escape special characters with \ to show literal symbols
- Build collapsible sections with <details> and <summary>
- Create a table of contents with anchor links, and add shields.io badges
- Use emoji shortcodes and language-tagged code fences for highlighting
💡 Real-World Analogy
Basic Markdown is like a label maker: quick, tidy, perfect for everyday text. GitHub-Flavoured Markdown adds a toolbox — a collapsible drawer (<details>), little reference cards stapled to the back (footnotes), status stickers (badges), and the option to drop in a raw HTML part when the label maker can't do the job. You still write plain text, but now you can build documentation that looks hand-crafted.
1. Footnotes
A footnote lets you add a note without cluttering your sentence. You drop a marker like [^1] where the note belongs (the reference), then define it on its own line as [^1]: text (the definition). The label can be a number or a word — what matters is that the reference and definition use the exact same label. When rendered, the marker becomes a small superscript link, and all the notes collect at the bottom of the page.
Markdown source
Markdown was created in 2004[^1] and is now everywhere[^docs]. You can even put a footnote mid-sentence[^tip] like this. [^1]: The original spec was written by John Gruber. [^docs]: GitHub, Reddit, and Stack Overflow all use it. [^tip]: Labels can be words, not just numbers.
Rendered result
Markdown was created in 2004[1] and is now everywhere[docs].
You can even put a footnote mid-sentence[tip] like this.
- [1] The original spec was written by John Gruber. ↩
- [docs] GitHub, Reddit, and Stack Overflow all use it. ↩
- [tip] Labels can be words, not just numbers. ↩
2. Embedding Raw HTML
Markdown can't do everything — there's no syntax for centring text or colouring a word. When you hit that wall, you can drop raw HTML straight into your Markdown and most renderers (GitHub included) will honour it. Common uses: <p align="center"> to centre a logo, <kbd> to style keyboard keys, <br> for a manual line break, and <span style="..."> for inline colour.
Markdown + HTML source
Markdown is great, but sometimes you need raw HTML. <p align="center"> <strong>Centred text</strong> — Markdown alone can't do this. </p> This text is <span style="color: tomato">tomato-coloured</span> and this is <kbd>Ctrl</kbd> + <kbd>C</kbd> in a keyboard tag. <br> A manual line break above using the <br> tag.
Rendered result
Markdown is great, but sometimes you need raw HTML.
Centred text — Markdown alone can't do this.
This text is tomato-coloured and this is Ctrl + C in a keyboard tag.
A manual line break above using the br tag.
3. Escaping Special Characters
Characters like *, _, #, and ` have special meaning in Markdown. To show them literally instead of triggering formatting, put a backslash \ in front. So \*hello\* displays the asterisks instead of turning the word italic. This is the difference between escaping (show the symbol) and literal (the symbol already would have shown) — you only need a backslash when the character would otherwise be interpreted.
Markdown source
Show literal Markdown by escaping with a backslash \\ :
\\*not italic\\* -> *not italic* (the asterisks stay visible)
\\# not a heading -> # not a heading
\\` not code \\` -> ` not code `
1\\. not a list -> 1. not a list
Characters you can escape: \\ \` * _ {} [] () # + - . ! |Rendered result
Show literal Markdown by escaping with a backslash \ :
*not italic* (the asterisks stay visible)
# not a heading
` not code `
1. not a list
4. Collapsible Sections
A collapsible section hides content behind a clickable label — perfect for long FAQs, solutions, or stack traces. It's raw HTML: wrap the content in <details>, and put the always-visible label in <summary>. The one rule that trips everyone up: leave a blank line after </summary> if you want Markdown (lists, code, bold) to render inside.
Markdown + HTML source
## Troubleshooting <details> <summary>Why won't my footnote render?</summary> The label after `[^` must match **exactly** between the reference and the definition. `[^1]` needs `[^1]:` — not `[^one]:`. You can use **Markdown** inside a collapsed section, including lists and `code`. </details>
Rendered result
Troubleshooting
Why won't my footnote render?
The label after [^ must match exactly between the reference and the definition. [^1] needs [^1]: — not [^one]:.
You can use Markdown inside a collapsed section, including lists and code.
↑ Click the triangle to expand it.
🎯 Your Turn #1: a collapsible FAQ
Fill in the two blanks so the program prints a valid <details> block, then run it. Notice the blank line that lets Markdown render inside.
🎯 Your turn: print a collapsible section
Replace the ___ blanks, run it, then paste the printed source into a GitHub README.
// 🎯 YOUR TURN — build a collapsible FAQ section.
// Fill in each ___ then press "Try it Yourself" to print your Markdown.
const summaryText = "___"; // 👉 the always-visible label, e.g. "Show the answer"
const hiddenText = "___"; // 👉 the text revealed when expanded
console.log("<details>");
console.log("<summary>" + summaryText + "</summary>");
console.log(""); // blank line is REQUIRED for Markdown inside
console.log(hiddenText);
console.log("");
console.log("</
...5. A Table of Contents with Anchor Links
Every heading on GitHub automatically gets an invisible anchor (a link target). You can link to it with [Text](#heading). To work out the anchor: take the heading text, make it lowercase, replace spaces with hyphens, and drop punctuation. So ## FAQ & Support becomes #faq--support (the & is dropped, leaving a double hyphen where the spaces were). String these links into a bullet list and you have a clickable table of contents.
Markdown source
# Project Handbook ## Table of Contents - [Installation](#installation) - [Usage](#usage) - [FAQ & Support](#faq--support) ## Installation ... ## Usage ... ## FAQ & Support ...
Rendered result
Project Handbook
Table of Contents
- Installation
- Usage
- FAQ & Support
Each bullet jumps to the matching heading further down the page.
6. Badges (shields.io)
Those little status pills at the top of READMEs — build passing, MIT license, version 2.1.0 — are just images. shields.io generates them from a URL, and you embed each one with normal image syntax . The static pattern is .../badge/LABEL-MESSAGE-COLOR.
Markdown source
# Awesome Project     Pattern: https://img.shields.io/badge/LABEL-MESSAGE-COLOR
Rendered result
Awesome Project
7. Syntax Highlighting & Emoji
A fenced code block (three backticks) becomes syntax-highlighted when you write the language name right after the opening backticks — python, json, bash, diff, and dozens more. And emoji shortcodes like :tada: render as 🎉 — handy for friendly headings and changelogs.
Markdown source
Tell the fence its language for syntax highlighting:
\`\`\`python
def greet(name):
return f"Hello, {name}!"
\`\`\`
\`\`\`json
{ "name": "ada", "active": true }
\`\`\`
\`\`\`diff
+ added this line
- removed this line
\`\`\`Rendered result
Tell the fence its language for syntax highlighting:
def greet(name): return f"Hello, {name}!"
{ "name": "ada", "active": true }+ added this line - removed this line
Emoji shortcodes
:tada: → 🎉 :rocket: → 🚀 :sparkles: → ✨ :bug: → 🐛 :+1: → 👍 :warning: → ⚠️
Here's a worked example that prints real GFM source you can copy. Run it, read each printed line, then paste it into a GitHub README to watch it render.
Worked example: print GFM source
Prints task lists, a footnote, emoji, and a badge as copy-ready Markdown.
// This program PRINTS GitHub-Flavoured Markdown source so you can
// copy it into a README. The console shows the SOURCE; GitHub shows
// the RENDERED result (checkboxes, footnote links, emoji).
console.log("=== Task lists (recap) ===");
console.log("- [x] Create repository"); // renders as a ticked box
console.log("- [ ] Write the README"); // renders as an empty box
console.log("");
console.log("=== Footnotes ===");
console.log("Markdown is everywhere[^1].");
console.log("[^1]: Used by
...🎯 Your Turn #2: a matching footnote
Fill in the blanks so the reference [^label] and the definition [^label]: use the same label. If they don't match, the footnote link breaks — that's the single most common footnote bug.
🎯 Your turn: print a footnote
Pick a label and a note; the reference and definition must match exactly.
// 🎯 YOUR TURN — add a footnote. The label in the REFERENCE must match
// the label in the DEFINITION exactly, or GitHub won't link them.
const label = "___"; // 👉 pick a label WITHOUT the ^, e.g. note (used as [^note])
const note = "___"; // 👉 the footnote text shown at the bottom of the page
console.log("Markdown supports footnotes[^" + label + "].");
console.log("");
console.log("[^" + label + "]: " + note);
// ✅ Expected printed source (example, label = "note"):
// Markdown su
...One more runnable tour that prints the source for an anchor-link TOC, escaping, raw HTML, and a highlighted fence — all in one place.
Advanced patterns recap
Prints anchor links, escapes, raw HTML, and code-fence tips as source.
// Quick tour of advanced GFM extras (printed as source).
console.log("=== Anchor-link Table of Contents ===");
console.log("- [Setup](#setup) // jumps to the '## Setup' heading");
console.log("- [FAQ & Help](#faq--help)// spaces->-, '&' dropped, lowercased");
console.log("");
console.log("=== Escaping special characters ===");
console.log("Type a literal asterisk: \\*not italic\\*");
console.log("Type a literal hash: \\# not a heading");
console.log("");
console.log("=== Raw HTML
...Common Errors (and the fix)
- My raw HTML vanished. The renderer stripped it for safety (npm, some blog engines, comment fields sanitise HTML). It's not a syntax error — test on GitHub, where most HTML is allowed.
- My footnote isn't a link. The labels don't match.
[^1]in the text must pair with[^1]:in the definition —[^1]and[^one]:won't connect. - My escape shows the backslash too. You escaped a character that wasn't special, e.g.
\a. Only escape Markdown's special characters (\ ` * _ {} [] () # + - . ! |); everywhere else the backslash stays literal. - Bold/lists won't render inside my
<details>. Add a blank line after</summary>. Without it, the Markdown is treated as raw HTML text. - My TOC link goes nowhere. The anchor is wrong. Lowercase the heading, swap spaces for hyphens, drop punctuation:
## My Setup!→#my-setup.
📋 Quick Reference — GFM Extras
| Feature | Syntax |
|---|---|
| Footnote | text[^1] … [^1]: note |
| Escape | \* \# \` \| |
| Raw HTML | <kbd>Ctrl</kbd>, <br> |
| Collapsible | <details><summary>…</summary>…</details> |
| Anchor link | [Setup](#setup) |
| Badge |  |
| Emoji | :tada: :rocket: :+1: |
| Task list | - [ ] todo - [x] done |
| Highlighted code | ```python … ``` |
Mini-Challenge: Build a README Section
No blanks this time — just a brief and an outline. Use console.log to print the source for a small README that combines four things you learned: a title, a badge, a collapsible install section, and a highlighted code fence. Run it, then paste the output into a GitHub README to see it render.
🎯 Mini-Challenge: print a mini README
Print the source for a title, a badge, a <details> install section, and a bash code fence.
// 🎯 MINI-CHALLENGE: print a mini README section
// Build (with console.log) the SOURCE for a small README that includes:
// 1. An H1 title line: # My Tool
// 2. ONE shields.io badge: 
// 3. A collapsible "Install" section using <details>/<summary>
// 4. A fenced \`\`\`bash code block with one install command
//
// ✅ Expected printed source (shape):
// # My Tool
//  — overusing it makes the source hard to read. - 💡 Number footnotes loosely. Labels don't have to be in order;
[^a],[^note],[^99]all work as long as each reference has a matching definition. - 💡 Test the anchor. Unsure of an anchor? Hover the rendered heading on GitHub — it shows a 🔗 with the exact
#anchor. - 💡 Collapse noisy content. Long logs, screenshots, and FAQ answers belong in
<details>so the README stays scannable.
Frequently Asked Questions
Q: Do footnotes and alerts work everywhere?
No. Footnotes, GitHub alerts, and emoji shortcodes are GFM (or GitHub) extensions. Standard Markdown processors may show [^1] or :tada: as plain text. When in doubt, target GitHub.
Q: Is it safe to put raw HTML in Markdown?
On GitHub, basic structural HTML is fine and common. But scripts and many attributes are stripped, and some platforms remove HTML entirely — so don't rely on it for anything that must always appear.
Q: When do I actually need a backslash?
Only when a special character would otherwise be interpreted — e.g. a literal * at the start of a word, or a # at the start of a line. Inside normal prose those characters usually render fine without escaping.
Q: Why won't Markdown render inside my collapsible section?
You need a blank line after </summary>. With it, GitHub parses the inner content as Markdown; without it, the content is treated as raw HTML.
Lesson Complete — and you've finished the course! 🎉
- ✅ Footnotes link a
[^label]reference to a matching[^label]:definition - ✅ Raw HTML fills Markdown's gaps (centring,
<kbd>, colour) — but renderers may strip it - ✅ A backslash
\escapes special characters so they show literally - ✅
<details>/<summary>create collapsible sections (blank line for inner Markdown) - ✅ Anchor links
[Text](#heading)build a clickable table of contents - ✅ shields.io badges, emoji shortcodes, and language-tagged fences polish a README
Where to go next: put it all to work. Write a real README.md for one of your own projects, or revisit the course overview to review earlier lessons. From here, explore a documentation site generator like MkDocs or Docusaurus — they're powered by the exact Markdown you now know. Congratulations on completing the Markdown course! 📝
Sign up for free to track which lessons you've completed and get learning reminders.