initial commit.

This commit is contained in:
Andre Alves Garzia 2022-06-27 18:46:45 +01:00
parent 4868ad84cc
commit a634c207d9
156 changed files with 13025 additions and 18 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.DS_Store

34
.htaccess Normal file
View File

@ -0,0 +1,34 @@
# === image resize configuration
SetEnv IMG_RESIZE_ENABLE true
SetEnv IMG_RESIZE_MAX_WIDTH 640
# === caching configuration
Header set Cache-Control "no-cache"
DirectoryIndex index.gmi
#ErrorDocument 404 /index.gmi
RewriteEngine on
RewriteBase /
# === stop further internal redirects to /cms
RewriteCond %{ENV:REDIRECT_STATUS} ^
RewriteRule ^cms/ - [NC,L]
# === prevent direct access to /theme
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^theme/ - [R=404,NC,L]
# === discard .gmi extensions and redirect
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)\.gmi$ $1 [R=301,NC,L]
# === try .gmi files without extensions
RewriteCond %{REQUEST_FILENAME}.gmi -f
RewriteRule ^ %{REQUEST_URI}.gmi
# === render .gmi files
RewriteCond %{REQUEST_FILENAME} \.gmi$ [NC]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ /cms/render.php%{REQUEST_URI} [E=authbypass,L]

22
LICENSE
View File

@ -1,21 +1,9 @@
MIT License
The MIT License (MIT)
Copyright (c) 2022 Andre Alves Garzia
Copyright © 2022 Sensor Station LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,2 +1,20 @@
# lichen-with-markdown
A fork of Lichen CMS that supports Markdown and Gemtext
A fork of Lichen CMS that supports Markdown and Gemtext.
Find the original Lichen CMS alongside its documentation at:
https://lichen.sensorstation.co/
# License
The original Lichen and this fork are both licensed using MIT License.
# Development
I've been toying with this using the PHP built-in development server:
```
$ php81 -S localhost:8000
```

6
assets/lichen-small.svg Normal file
View File

@ -0,0 +1,6 @@
<svg data-ref="svg" xmlns="http://www.w3.org/2000/svg" class="surface" viewBox="128,128,44,44" width="16" height="16">
<g stroke="black" stroke-linecap="round" fill="none" stroke-width="3">
<path d="M170,130 a40,40 0 0,0 -40,40"></path>
<path d="M170,130 a40,40 0 0,1 -40,40"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 307 B

114
assets/stylesheet.css Normal file
View File

@ -0,0 +1,114 @@
html {
margin: 0;
padding: 0;
-webkit-text-size-adjust: none;
}
body {
margin: 2rem auto;
padding: 0 1rem;
font-family: sans-serif;
background: white;
color: black;
max-width: 72ch;
line-height: 1.5rem;
}
h1,h2,h3 {
color: gray;
margin-bottom: 1rem;
margin-top: 1rem;
font-weight: 300;
line-height: 1.1;
}
h1 {
margin-top: 4rem;
font-size: 3rem;
}
h2 {
margin-top: 3rem;
font-size: 1.8rem;
}
h3 {
margin-top: 2rem;
font-size: 1.2rem;
}
ol, blockquote {
padding-left: 1rem;
margin-left: 1rem;
margin-right: 0;
padding-right: 0;
}
blockquote {
border-left: 1px solid gray;
}
pre {
white-space: pre-wrap;
/*overflow-x: auto;*/
padding: 1rem;
line-height: 1.2;
border: 1px solid lightgray;
border-radius: 4px;
font-family: monospace;
}
ol {
list-style: decimal-leading-zero;
}
ol li {
margin: 0.4rem 0;
}
ol li::marker {
color: lightgray;
}
p {
margin: 0.75rem 0;
}
main a {
display: block;
margin: 0.75rem 0;
position: relative;
padding-left: 2.25ch;
font-weight: bold;
}
main a::before {
content: '➞';
position: absolute;
left: 0;
}
main img, main video, main audio {
display: block;
margin: 1rem auto;
max-width: 100%;
}
main video, main audio {
width: 100%;
}
main video {
border: 1px solid lightgray;
aspect-ratio: 16 / 9;
}
header .back-link {
display: inline-flex;
align-items: center;
color: inherit;
text-decoration: none;
gap: 0.5rem;
line-height: 1;
}
footer {
padding-top: 1rem;
margin-top: 4rem;
border-top: 1px dotted lightgray;
text-align: center;
font-size: 0.75rem;
line-height: 1rem;
}
footer .lichen-plug {
display: block;
margin: 1rem auto;
color: inherit;
text-decoration: none;
}
footer p {
margin: 0.2rem 0;
}

35
cheatsheet.gmi Normal file
View File

@ -0,0 +1,35 @@
# Heading Level 1
## Heading Level 2
### Heading Level 3
> You are not compelled to form any opinion about this matter before you, nor to disturb your peace of mind at all. Things in themselves have no power to extort a verdict from you.
Marcus Aurelius
```ascii-art
░█▀▀░█▀▀░█▀█░█▀▀░█▀█░█▀▄░░░░░
░▀▀█░█▀▀░█░█░▀▀█░█░█░█▀▄░░░░░
░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀░▀░░░░░
░█▀▀░▀█▀░█▀█░▀█▀░▀█▀░█▀█░█▀█░
░▀▀█░░█░░█▀█░░█░░░█░░█░█░█░█░
░▀▀▀░░▀░░▀░▀░░▀░░▀▀▀░▀▀▀░▀░▀░
```
# The Three Stages of Dog Companionship
* Try to clean the hair before it gets in your food.
* Accept that the hair gets in the food and that you need to pull it out.
* Just eat the hair.
# Important Links
=> https://gemini.circumlunar.space/ Gemini Protocol
=> gemini://alex.flounder.online/gemlog/2021-01-08-useless.gmi Gemini is Useless
# An image
=> /assets/lichen-small.svg Lichen

BIN
cms/.DS_Store vendored Normal file

Binary file not shown.

13
cms/.htaccess Normal file
View File

@ -0,0 +1,13 @@
# --- DO NOT DELETE --- #
# This file enables password protection for editing the site.
# Set up an htpasswd file (outside of web root!) and update the path
# setting in the AuthUserFile directive.
# https://httpd.apache.org/docs/current/programs/htpasswd.html
AuthType Basic
AuthName "Protected"
AuthUserFile /home/protected/lichen.htpasswd
Require valid-user
Require all denied
Require env REDIRECT_authbypass

647
cms/edit.php Normal file
View File

@ -0,0 +1,647 @@
<?php
function exception_handler($e) {
http_response_code(500);
echo $e->getMessage();
exit(1);
}
set_exception_handler('exception_handler');
define("EDITABLE_EXTENSIONS", ["gmi", "md"]);
// patch up PATH_INFO in case it is unset
if(!array_key_exists('PATH_INFO', $_SERVER) || $_SERVER['PATH_INFO'] == "") {
$_SERVER['PATH_INFO'] = "/";
}
if(substr($_SERVER['PATH_INFO'],-1,1) === "/") {
$_SERVER['PATH_INFO'] .= "index.md";
}
?>
<?php function render_file($filename, $base) { ?>
<li class="file">
<?php $extension = strtolower(substr(strrchr($filename, '.'), 1)); ?>
<?php if(in_array($extension, EDITABLE_EXTENSIONS)): ?>
<a href="<?php echo "/cms/edit.php".$base.$filename ?>" class="link--editable"><?php echo $filename ?></a>
<?php else: ?>
<a href="<?php echo $base.$filename ?>" target="_blank" class="link--unknown"><?php echo $filename ?></a>
<?php endif; ?>
<div class="actions">
<button title="Insert Link" data-path="<?php echo $base.$filename ?>" onclick="
const el = document.getElementById('content');
let path = this.dataset.path;
if(path.endsWith('.gmi')) path = path.substring(0, path.lastIndexOf('.gmi'));
if(path.endsWith('.md')) path = path.substring(0, path.lastIndexOf('.md'));
const [start, end] = [el.selectionStart, el.selectionEnd];
el.setRangeText(`\n=> ${path} `, start, end, 'end');
document.getElementById('panel_files').classList.toggle('hidden');
document.getElementById('panel_editor').classList.toggle('hidden');
el.focus();
el.dispatchEvent(new Event('input'));
">🔗</button>
<button title="Delete" data-path="<?php echo $base.$filename ?>" onclick="if(confirm('Are you sure you want to delete this file?')) { deleteFile(this.dataset.path).then(() => {this.parentElement.parentElement.remove(); }); }" style="color: red;"></button>
</div>
</li>
<?php } ?>
<?php function render_directory($filename, $base, $depth, $children) { ?>
<?php $_key = $depth == 0 ? '' : $filename."/"; ?>
<li class="directory">
<details data-path="<?php echo $base.$_key ?>" <?php echo $depth == 0 ? 'open' : '' ?>>
<summary>
<span><?php echo $filename ?></span><div class="actions">
<button title="New Page" data-path="<?php echo $base.$_key ?>" onclick="newFile(this.dataset.path);">+ 📄</button>
<button title="New Folder" data-path="<?php echo $base.$_key ?>" onclick="newDir(this.dataset.path).then((el) => { this.parentElement.parentElement.parentElement.querySelector('ol').appendChild(el); });">+ 📁</button>
<button title="Upload" data-path="<?php echo $base.$_key ?>" onclick="uploadContextPath = this.dataset.path; document.getElementById('upload').click();">Upload</button>
<?php if($depth > 0): ?>
<button title="Delete" data-path="<?php echo $base.$filename ?>" onclick="if(confirm('Are you sure you want to delete this directory?')) { deleteFile(this.dataset.path).then(() => {this.parentElement.parentElement.parentElement.remove(); }); }" style="color: red;"></button>
<?php endif; ?>
</div></summary>
<?php render_filetree($children, $base.$_key, $depth + 1) ?>
</details>
</li>
<?php } ?>
<?php function render_filetree($tree, $base, $depth) { ?>
<?php asort($tree); ?>
<ol>
<?php foreach ($tree as $key => $value): ?>
<?php if(is_array($value)): ?>
<?php render_directory($key, $base, $depth, $value); ?>
<?php else: ?>
<?php render_file($value, $base); ?>
<?php endif; ?>
<?php endforeach; ?>
</ol>
<?php } ?>
<?php
function delTree($dir) {
$files = array_diff(scandir($dir), array('.','..'));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
if($_SERVER['REQUEST_METHOD'] === 'PUT') {
$_dest = fopen("..".$_SERVER['PATH_INFO'], "w");
if(!$_dest) {
http_response_code(500);
header('Content-Type: text/plain');
echo 'Could not write file. Check file permissions.';
exit(1);
}
$_src = fopen("php://input", "r");
$written = stream_copy_to_stream($_src, $_dest);
fclose($_dest);
fclose($_src);
http_response_code(204);
exit(0);
} elseif($_SERVER['REQUEST_METHOD'] === 'POST') {
define("RESIZABLE_IMAGE_EXTENSIONS", ["png", "avif", "bmp", "jpg", "jpeg", "gif", "webp"]);
$public_path = null;
$new_basename = str_replace(" ", "_", basename($_SERVER['PATH_INFO']));
$extension = strtolower(pathinfo($_SERVER['PATH_INFO'], PATHINFO_EXTENSION));
if(getenv('IMG_RESIZE_ENABLE') && in_array($extension, RESIZABLE_IMAGE_EXTENSIONS)) {
$max_width = 800;
if(getenv('IMG__RESIZE_MAX_WIDTH')) {
$max_width = intval(getenv('IMG_RESIZE_MAX_WIDTH'));
}
$dest_format = getenv('IMG_RESIZE_FORMAT') ?: "source";
if($dest_format == "source") {
$dest_format = $extension;
}
$img = imagecreatefromstring(file_get_contents("php://input"));
if(imagesx($img) > $max_width) {
$img = imagescale($img, $max_width);
}
// replace extension with new format
$public_path = dirname($_SERVER['PATH_INFO'])."/".basename($new_basename, ".".$extension).".".$dest_format;
$_dest = fopen("..".$public_path, "x");
if(!$_dest) {
http_response_code(400);
header('Content-Type: text/plain');
echo 'File already exists in this directory. Delete it to overwrite.';
exit(1);
}
switch($dest_format) {
case "png":
imagepng($img, $_dest, intval(getenv('IMG_RESIZE_PNG_COMPRESSION') ?: -1));
break;
case "jpg":
case "jpeg":
imagejpeg($img, $_dest, intval(getenv('IMG_RESIZE_JPEG_QUALITY') ?: -1));
break;
case "webp":
imagewebp($img, $_dest, intval(getenv('IMG_RESIZE_WEBP_QUALITY') ?: -1));
break;
case "avif":
imageavif($img, $_dest, intval(getenv('IMG_RESIZE_AVIF_QUALITY') ?: -1), intval(getenv('IMG_RESIZE_AVIF_SPEED') ?: -1));
break;
case "gif":
imagegif($img, $_dest);
break;
case "bmp":
imagewbmp($img, $_dest);
break;
default:
http_response_code(400);
header('Content-Type: text/plain');
echo "Unknown image format: ".$dest_format;
exit(1);
}
fclose($_dest);
} else {
$public_path = dirname($_SERVER['PATH_INFO'])."/".$new_basename;
$_dest = fopen("..".$public_path, "x");
if(!$_dest) {
http_response_code(400);
header('Content-Type: text/plain');
echo 'File already exists in this directory. Delete it to overwrite.';
exit(1);
}
$_src = fopen("php://input", "r");
stream_copy_to_stream($_src, $_dest);
fclose($_dest);
fclose($_src);
}
$base = dirname($public_path);
if(substr($base,-1,1) !== "/") {
$base .= "/";
}
http_response_code(200);
header('Content-Type: text/html');
render_file(basename($public_path), $base);
exit(0);
} elseif($_SERVER['REQUEST_METHOD'] === 'DELETE') {
if($_SERVER['PATH_INFO'] === "" || $_SERVER['PATH_INFO'] === "." || $_SERVER['PATH_INFO'] === "/") {
http_response_code(400);
exit(1);
}
if(is_dir("..".$_SERVER['PATH_INFO'])) {
delTree("..".$_SERVER['PATH_INFO']);
} else {
unlink("..".$_SERVER['PATH_INFO']);
}
http_response_code(204);
exit(0);
} elseif($_SERVER['REQUEST_METHOD'] === 'PATCH') {
mkdir("..".$_SERVER['PATH_INFO']);
http_response_code(200);
header('Content-Type: text/html');
$dir = dirname($_SERVER['PATH_INFO']);
render_directory(basename($_SERVER['PATH_INFO']), $dir, count(explode("/", $dir)), array());
exit(0);
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Lichen</title>
<style>
* {
box-sizing: border-box;
}
body {
height: 100vh;
margin: 0;
padding: 0;
font-family: sans-serif;
}
.container {
height: 100%;
display: flex;
flex-direction: row;
}
.panel {
display: flex;
flex-direction: column;
border-right: 1px solid gray;
min-width: 60ch;
position: relative;
}
.panel .controls {
border-top: 1px solid gray;
padding: 0.5rem;
display: flex;
gap: 0.5rem;
flex-direction: row;
}
textarea {
min-width: 100%;
max-width: 100%;
resize: horizontal;
margin: 0;
padding: 1rem;
outline: none;
border: none;
font-size: 1rem;
font-family: monospace;
}
iframe {
flex-grow: 1;
border: none;
outline: none;
height: 100%;
}
#save {
background: #77d763;
color: white;
text-shadow: 0 1px 0 #2fa62f;
border-radius: 3px;
outline: none;
border: 1px solid #2fa62f;
}
#save:disabled {
opacity: 0.5;
}
#panel_files {
width: 60ch;
}
#help {
font-size: 0.8rem;
font-family: monospace;
border-top: 1px solid gray;
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 1ch 2ch;
padding: 1ch;
}
#files {
overflow-y: auto;
}
#files ol {
list-style: none;
border-left: 1px solid lightgray;
padding-left: 1rem;
font-family: monospace;
user-select: none;
}
#files ol:first-child {
border: none;
padding-right: 1rem;
}
#files a, #files summary > span {
flex-grow: 1;
display: inline-block;
padding: 0.25rem 0.5rem;
padding-left: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
#files details {
width: 100%;
}
#files li.file:hover, #files li.directory summary:hover {
background: #f0f0f0;
}
#files a {
display: list-item;
text-decoration: none;
color: inherit;
}
#files li {
border-bottom: 1px solid white;
}
#files li.file, #files li.directory summary {
display: flex;
flex-direction: row;
}
#files li .actions {
display: flex;
visibility: hidden;
}
#files li.file:hover .actions, #files li.directory summary:hover .actions {
visibility: visible;
}
#files li button {
background: transparent;
border: none;
outline: none;
padding: 0.25rem 0.50rem;
cursor: pointer;
border-left: 1px solid white;
}
#files summary {
cursor: pointer;
}
#files summary::marker {
display: none;
}
#files details > summary::before {
content: '📁 ';
padding: 0.25rem 0.50rem 0.25rem 0;
}
#files details[open] > summary::before {
content: '📂 ';
}
.link--editable::before {
content: '📄 ';
}
.link--unknown::before {
content: '📦 ';
}
.panel .overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #00000080;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 1rem;
gap: 0.5rem;
color: white;
}
@keyframes throb {
0%, 100% { opacity: 0; }
50% { opacity: 1; }
}
.throb {
animation: throb 1s infinite;
}
code {
background: lightgray;
padding: 2px;
border-radius: 2px;
}
.hidden {
display: none !important;
}
</style>
<script>
'use strict';
const REQ_PATH = '<?php echo $_SERVER['PATH_INFO']; ?>';
function debounce(callback, delay) {
let id = null;
return (...args) => {
window.clearTimeout(id);
id = window.setTimeout(() => {
callback.apply(null, args);
}, delay);
};
}
let contentModified = false;
let scrollX = 0;
let scrollY = 0;
async function applyContent() {
const input = document.getElementById('content');
const preview = document.getElementById('preview');
const save = document.getElementById('save');
let contentType = "text/gemini"
save.disabled = !contentModified;
if(contentModified) {
save.innerText = 'Save';
}
try {
scrollY = preview.contentWindow.scrollY;
scrollX = preview.contentWindow.scrollX;
} catch(e) {
// cross-origin content doesn't allow scroll access
// (user may have clicked a link)
}
if (REQ_PATH.indexOf(".md") !== -1) {
contentType == "text/markdown"
}
const res = await fetch('/cms/render.php' + REQ_PATH, {
method: 'POST',
headers: {
'Content-Type': contentType,
},
body: input.value,
});
if(res.status != 200) {
alert('There was an error rendering the page.');
const body = await res.text();
throw new Error(body);
}
preview.addEventListener('load', function() {
preview.contentWindow.scrollTo({top: scrollY, left: scrollX, behavior: 'instant'});
}, {once: true});
preview.srcdoc = await res.text();
}
window.addEventListener('DOMContentLoaded', applyContent, {once: true});
window.addEventListener('DOMContentLoaded', function() {
const onContentInput = debounce(applyContent, 1000);
const input = document.getElementById('content');
input.focus();
input.addEventListener('input', onContentInput);
input.addEventListener('input', function() {
contentModified = true;
});
window.addEventListener('beforeunload', function(event) {
if(!contentModified) return;
event.preventDefault();
return 'Unsaved changes will be lost.';
});
const preview = document.getElementById('preview');
preview.addEventListener('load', function(event) {
// TODO: handle navigation
// console.log(event, event.target.contentWindow.location);
});
}, {once: true});
// --- API --- //
async function saveContent() {
const input = document.getElementById('content');
const button = document.getElementById('save');
let contentType = "text/gemini";
button.disabled = true;
button.innerText = 'Saving...';
if (REQ_PATH.indexOf(".md") !== -1) {
contentType == "text/markdown"
}
const res = await fetch('/cms/edit.php' + REQ_PATH, {
method: 'PUT',
headers: {
'Content-Type': contentType,
},
body: input.value,
});
if(res.status != 204) {
button.disabled = false;
button.innerText = 'Save';
const body = await res.text();
alert('There was an error that prevented the file from being saved.');
throw new Error(body);
} else {
button.disabled = true;
button.innerText = 'Saved';
contentModified = false;
}
}
async function deleteFile(path) {
const res = await fetch('/cms/edit.php' + path, {
method: 'DELETE',
});
if(res.status != 204) {
const body = await res.text();
alert('There was an error deleting the file.');
throw new Error(body);
}
}
function newFile(path) {
let filename = prompt('New page filename:');
if(!filename) return;
if(!filename.endsWith('.gmi') && !filename.endsWith('.md')) filename += '.md';
window.location = '/cms/edit.php' + path + filename;
}
async function newDir(path) {
let filename = prompt('New folder name:');
if(!filename) return;
const res = await fetch('/cms/edit.php' + path + filename, {
method: 'PATCH',
});
if(res.status != 200) {
const body = await res.text();
alert('There was an error creating the folder.');
throw new Error(body);
}
const newSrc = await res.text();
const newNode = new DOMParser().parseFromString(newSrc, 'text/html').body.firstElementChild;
return newNode;
}
let uploadContextPath;
async function handleUpload(event) {
const overlay = document.getElementById('upload-overlay');
overlay.classList.remove('hidden');
try {
const res = await fetch('/cms/edit.php' + uploadContextPath + event.target.files[0].name, {
method: 'POST',
body: event.target.files[0],
});
if(res.status != 200) {
const body = await res.text();
alert('There was an error uploading the file.');
throw new Error(body);
}
const newSrc = await res.text();
const newNode = new DOMParser().parseFromString(newSrc, 'text/html').body.firstElementChild;
document.querySelector(`details[data-path="${uploadContextPath}"] > ol`).appendChild(newNode).scrollIntoView();
} catch(e) {
} finally {
overlay.classList.add('hidden');
}
}
</script>
</head>
<body>
<div class="container">
<div class="panel" id="panel_editor">
<textarea id="content" autocomplete="off" spellcheck="false" style="flex-grow: 1;"><?php
if(file_exists("..".$_SERVER['PATH_INFO'])) {
echo file_get_contents("..".$_SERVER['PATH_INFO']);
}
?></textarea>
<div id="help" class="hidden">
<code># heading<br>## subhead<br>### sub-subhead</code>
<code>* bulleted<br>* list<br>* items</code>
<code>=> https://abc.xyz external link<br>=> /page.gmi internal link<br>=> /image.jpg image alt</code>
<code>```<br>preformatted</br>```</code><br>
<div>
<code>> blockquote</code>
<div>&nbsp;</div>
<a href="https://gemini.circumlunar.space/docs/cheatsheet.gmi" target="_blank">Cheatsheet</a>
</div>
</div>
<div class="controls">
<button id="toggle-files" onclick="document.getElementById('panel_files').classList.toggle('hidden'); document.getElementById('panel_editor').classList.toggle('hidden');">Files</button>
<button id="toggle-cheatsheet" onclick="document.getElementById('help').classList.toggle('hidden');">Help</button>
<span style="flex-grow: 1;"></span>
<button id="save" disabled onclick="saveContent();">Save</button>
</div>
</div>
<div class="panel hidden" id="panel_files">
<nav id="files" style="flex-grow: 1;">
<?php
$directory = new RecursiveDirectoryIterator('../');
$filter = new RecursiveCallbackFilterIterator($directory, function ($current, $key, $iterator) {
if ($current->getFilename()[0] === '.') { // skip hidden files and directories.
return FALSE;
} elseif ($key === '../cms') { // skip `cms` directory
return FALSE;
} elseif ($key === '../theme') { // skip `theme` directory
return FALSE;
}
return TRUE;
});
$iterator = new RecursiveIteratorIterator($filter, RecursiveIteratorIterator::SELF_FIRST);
$fileTree = array();
foreach ($iterator as $fileInfo) {
$path = $fileInfo->isDir()
? array($fileInfo->getFilename() => array())
: array($fileInfo->getFilename());
for ($depth = $iterator->getDepth() - 1; $depth >= 0; $depth--) {
$path = array($iterator->getSubIterator($depth)->current()->getFilename() => $path);
}
$fileTree = array_merge_recursive($fileTree, $path);
}
$fileTree = array(basename(realpath('../')) => $fileTree); // top-level dir
?>
<?php render_filetree($fileTree, "/", 0) ?>
</nav>
<div class="controls">
<button id="toggle-editor" onclick="document.getElementById('panel_files').classList.toggle('hidden'); document.getElementById('panel_editor').classList.toggle('hidden');">Editor</button>
<span style="flex-grow: 1;"></span>
</div>
<div class="overlay hidden" id="upload-overlay">
<p>Uploading<span class="throb"></span></p>
</div>
</div>
<iframe id="preview"></iframe>
</div>
<input type="file" id="upload" class="hidden" onchange="handleUpload(event);">
</body>
</html>

154
cms/gemtext.php Normal file
View File

@ -0,0 +1,154 @@
<?php
define("IMAGE_EXTENSIONS", ["png", "apng", "avif", "bmp", "ico", "tif", "tiff", "jpg", "jpeg", "gif", "svg", "webp"]);
define("VIDEO_EXTENSIONS", ["mp4", "m4v", "ogv", "mov", "webm", "mkv"]);
define("AUDIO_EXTENSIONS", ["mp3", "aac", "wav", "flac", "ogg"]);
function gemtext_to_html($file, $generate_headline_ids = true) {
$line_no = 0;
$preformatted = false;
$blockquote_open = false;
$list_open = false;
$list_index = 1;
$last_br = -1;
$title = '';
$body = '';
while(!feof($file)) {
$line_no += 1;
$line_untrimmed = fgets($file);
$line = rtrim($line_untrimmed);
$line_len = strlen($line);
// == PREFORMATTED
if($line_len >= 3 && substr($line, 0, 3) == "```") {
$preformatted = !$preformatted;
if($preformatted) {
if($line_len > 3) {
$body .= "<pre alt=\"".htmlspecialchars(substr($line, 3))."\">\n";
} else {
$body .= "<pre>\n";
}
} else {
$body .= "</pre>\n";
}
continue;
}
if($preformatted) {
$body .= htmlspecialchars($line_untrimmed);
continue;
}
// == LINKS
if(substr($line,0,2) === "=>") {
$line = ltrim($line, "=> \t");
if(strlen($line) == 0) {
continue;
}
$first_space = strpos($line, " ");
$first_tab = strpos($line, "\t");
$link_target = "";
$link_label = "";
if($first_space === false && $first_tab === false) {
$link_target = $line;
$link_label = $line;
} else {
if($first_space === false) $first_space = PHP_INT_MAX;
if($first_tab === false) $first_tab = PHP_INT_MAX;
$parts = [];
if($first_space < $first_tab) {
$parts = explode(" ", $line, 2);
} else {
$parts = explode("\t", $line, 2);
}
$link_target = $parts[0];
$link_label = $parts[1];
}
$extension = strtolower(pathinfo($link_target, PATHINFO_EXTENSION));
if(in_array($extension, IMAGE_EXTENSIONS)) {
$body .= "<img src=\"$link_target\" alt=\"".htmlspecialchars($link_label)."\">\n";
} elseif(in_array($extension, VIDEO_EXTENSIONS)) {
$body .= "<video controls preload=\"none\" src=\"$link_target\"></video>";
} elseif(in_array($extension, AUDIO_EXTENSIONS)) {
$body .= "<audio controls preload=\"none\" src=\"$link_target\"></audio>";
} else {
$body .= "<a href=\"$link_target\" rel=\"noreferrer\">".htmlspecialchars($link_label)."</a>\n";
}
continue;
}
// == HEADLINES
$head_level = 0;
if(substr($line,0,2) === "# ") {
$head_level = 1;
} elseif(substr($line,0,3) === "## ") {
$head_level = 2;
} elseif(substr($line,0,4) === "### ") {
$head_level = 3;
}
if($head_level > 0) {
$line = ltrim($line, "# \t");
if($generate_headline_ids) {
$body .= "<h".$head_level." id=\"".urlencode($line)."\">".htmlspecialchars($line)."</h".$head_level.">\n";
} else {
$body .= "<h".$head_level.">".htmlspecialchars($line)."</h".$head_level.">\n";
}
if($title == "") {
$title = $line;
}
$list_index = 1; # reset
continue;
}
// == BLOCKQUOTES
if(substr($line,0,1) === ">") {
$body .= "<blockquote>".htmlspecialchars(ltrim($line, "> \t"))."</blockquote>\n";
continue;
}
// == LISTS
if(substr($line,0,2) === "* ") {
if(!$list_open) {
$list_open = true;
$body .= "<ol start=\"$list_index\">\n";
}
$line = ltrim($line, "* ");
$body .= "<li>".htmlspecialchars($line)."</li>\n";
$list_index += 1;
continue;
} else if($list_open && substr($line,0,1) !== "*") {
$list_open = false;
$body .= "</ol>\n";
}
// == PARAGRAPHS
if($line_len > 0) {
$body .= "<p>".htmlspecialchars($line)."</p>\n";
} else {
// == WHITESPACE
// only insert <br> after 2 newlines
if($last_br == $line_no - 1) {
$body .= "<br>\n";
}
$last_br = $line_no;
}
}
if($preformatted) {
$preformatted = false;
$body .= "</pre>\n";
}
if($list_open) {
$list_open = false;
$body .= "</ol>\n";
}
return array("body" => $body, "title" => $title);
}
?>

23
cms/markdown.php Normal file
View File

@ -0,0 +1,23 @@
<?php
require_once "vendor/php-markdown-lib-9.1/Michelf/Markdown.inc.php";
use Michelf\Markdown;
function markdown_to_html($file, $generate_headline_ids = true) {
$title = '';
$body = '';
$headings = null;
$source = "";
while(!feof($file)) {
$source = $source . fgets($file);
}
$body = Markdown::defaultTransform($source);
preg_match_all( '|<h[^>]+>(.*)</h[^>]+>|iU', $body, $headings );
return array("body" => $body, "title" => $headings[0]);
}
?>

40
cms/render.php Normal file
View File

@ -0,0 +1,40 @@
<?php
require "./gemtext.php";
require "./markdown.php";
// get the body content
$_src = null;
$path = null;
$ext = null;
$_content = null;
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$_src = fopen("php://input", "r");
$path = $_SERVER['PATH_INFO'];
$ext = pathinfo($path, PATHINFO_EXTENSION);
} else if (isset($_SERVER['REDIRECT_URL'])) {
$path = $_SERVER['REDIRECT_URL'];
$_src = fopen("..".$path, "r") or die("File not found: ".$path);
$ext = pathinfo("..".$path, PATHINFO_EXTENSION);
header("Last-Modified: ".date("r", filemtime("..".$path)));
} else {
$path = ".." . $_SERVER['PATH_INFO'];
$_src = fopen($path, "r") or die("File not found: ".$path);
$ext = pathinfo($path, PATHINFO_EXTENSION);
header("Last-Modified: ".date("r", filemtime($path)));
}
if ($ext == "gmi") {
$_content = gemtext_to_html($_src);
} else if ($ext == "md") {
$_content = markdown_to_html($_src);
}
// pull out variables for convenience
$title = $_content['title'];
$body = $_content['body'];
fclose($_src);
include "../theme/layout.php";
?>

BIN
cms/vendor/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,11 @@
# EditorConfig is awesome: https://EditorConfig.org
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
[*.php]
indent_style = tab
insert_final_newline = true

View File

@ -0,0 +1,3 @@
*~
/composer.lock
/vendor/

View File

@ -0,0 +1,36 @@
build:
environment:
php:
version: '7.4'
nodes:
analysis:
project_setup:
override:
- 'true'
tests:
override:
-
command: 'vendor/bin/phpunit --coverage-clover=clover.xml'
coverage:
file: 'clover.xml'
format: 'clover'
-
command: phpcs-run
use_website_config: true
environment:
node:
version: 6.0.0
tests: true
filter:
excluded_paths:
- 'test/*'
checks:
php: true
coding_style:
php:
indentation:
general:
use_tabs: true
spaces:
around_operators:
concatenation: true

View File

@ -0,0 +1,19 @@
language: php
matrix:
include:
- php: hhvm-3.18
dist: trusty
- php: 7.4
dist: bionic
- php: 8.0
dist: bionic
install:
- composer install --prefer-dist
script:
- vendor/bin/phpunit --log-junit=phpunit.log
notifications:
email: false

View File

@ -0,0 +1,36 @@
PHP Markdown Lib
Copyright (c) 2004-2021 Michel Fortin
<https://michelf.ca/>
All rights reserved.
Based on Markdown
Copyright (c) 2003-2006 John Gruber
<https://daringfireball.net/>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name "Markdown" nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as
is" and any express or implied warranties, including, but not limited
to, the implied warranties of merchantability and fitness for a
particular purpose are disclaimed. In no event shall the copyright owner
or contributors be liable for any direct, indirect, incidental, special,
exemplary, or consequential damages (including, but not limited to,
procurement of substitute goods or services; loss of use, data, or
profits; or business interruption) however caused and on any theory of
liability, whether in contract, strict liability, or tort (including
negligence or otherwise) arising in any way out of the use of this
software, even if advised of the possibility of such damage.

View File

@ -0,0 +1,10 @@
<?php
// Use this file if you cannot use class autoloading. It will include all the
// files needed for the Markdown parser.
//
// Take a look at the PSR-0-compatible class autoloading implementation
// in the Readme.php file if you want a simple autoloader setup.
require_once dirname(__FILE__) . '/MarkdownInterface.php';
require_once dirname(__FILE__) . '/Markdown.php';

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
<?php
// Use this file if you cannot use class autoloading. It will include all the
// files needed for the MarkdownExtra parser.
//
// Take a look at the PSR-0-compatible class autoloading implementation
// in the Readme.php file if you want a simple autoloader setup.
require_once dirname(__FILE__) . '/MarkdownInterface.php';
require_once dirname(__FILE__) . '/Markdown.php';
require_once dirname(__FILE__) . '/MarkdownExtra.php';

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
<?php
// Use this file if you cannot use class autoloading. It will include all the
// files needed for the MarkdownInterface interface.
//
// Take a look at the PSR-0-compatible class autoloading implementation
// in the Readme.php file if you want a simple autoloader setup.
require_once dirname(__FILE__) . '/MarkdownInterface.php';

View File

@ -0,0 +1,38 @@
<?php
/**
* Markdown - A text-to-HTML conversion tool for web writers
*
* @package php-markdown
* @author Michel Fortin <michel.fortin@michelf.com>
* @copyright 2004-2021 Michel Fortin <https://michelf.com/projects/php-markdown/>
* @copyright (Original Markdown) 2004-2006 John Gruber <https://daringfireball.net/projects/markdown/>
*/
namespace Michelf;
/**
* Markdown Parser Interface
*/
interface MarkdownInterface {
/**
* Initialize the parser and return the result of its transform method.
* This will work fine for derived classes too.
*
* @api
*
* @param string $text
* @return string
*/
public static function defaultTransform($text);
/**
* Main function. Performs some preprocessing on the input text
* and pass it through the document gamut.
*
* @api
*
* @param string $text
* @return string
*/
public function transform($text);
}

View File

@ -0,0 +1,437 @@
PHP Markdown
============
PHP Markdown Lib 1.9.0 - 1 Dec 2019
by Michel Fortin
<https://michelf.ca/>
based on Markdown by John Gruber
<https://daringfireball.net/>
Introduction
------------
This is a library package that includes the PHP Markdown parser and its
sibling PHP Markdown Extra with additional features.
Markdown is a text-to-HTML conversion tool for web writers. Markdown
allows you to write using an easy-to-read, easy-to-write plain text
format, then convert it to structurally valid XHTML (or HTML).
"Markdown" is actually two things: a plain text markup syntax, and a
software tool, originally written in Perl, that converts the plain text
markup to HTML. PHP Markdown is a port to PHP of the original Markdown
program by John Gruber.
* [Full documentation of the Markdown syntax](<https://daringfireball.net/projects/markdown/>)
— Daring Fireball (John Gruber)
* [Markdown Extra syntax additions](<https://michelf.ca/projects/php-markdown/extra/>)
— Michel Fortin
Requirement
-----------
This library package requires PHP 5.3 or later.
Note: The older plugin/library hybrid package for PHP Markdown and
PHP Markdown Extra is no longer maintained but will work with PHP 4.0.5 and
later.
Before PHP 5.3.7, pcre.backtrack_limit defaults to 100 000, which is too small
in many situations. You might need to set it to higher values. Later PHP
releases defaults to 1 000 000, which is usually fine.
Usage
-----
To use this library with Composer, first install it with:
$ composer require michelf/php-markdown
Then include Composer's generated vendor/autoload.php to [enable autoloading]:
require 'vendor/autoload.php';
Without Composer, for autoloading to work, your project needs an autoloader
compatible with PSR-4 or PSR-0. See the included Readme.php file for a minimal
autoloader setup. (If you cannot use autoloading, see below.)
With class autoloading in place:
use Michelf\Markdown;
$my_html = Markdown::defaultTransform($my_text);
Markdown Extra syntax is also available the same way:
use Michelf\MarkdownExtra;
$my_html = MarkdownExtra::defaultTransform($my_text);
If you wish to use PHP Markdown with another text filter function
built to parse HTML, you should filter the text *after* the `transform`
function call. This is an example with [PHP SmartyPants]:
use Michelf\Markdown, Michelf\SmartyPants;
$my_html = Markdown::defaultTransform($my_text);
$my_html = SmartyPants::defaultTransform($my_html);
All these examples are using the static `defaultTransform` static function
found inside the parser class. If you want to customize the parser
configuration, you can also instantiate it directly and change some
configuration variables:
use Michelf\MarkdownExtra;
$parser = new MarkdownExtra;
$parser->fn_id_prefix = "post22-";
$my_html = $parser->transform($my_text);
To learn more, see the full list of [configuration variables].
[enable autoloading]: https://getcomposer.org/doc/01-basic-usage.md#autoloading
[PHP SmartyPants]: https://michelf.ca/projects/php-smartypants/
[configuration variables]: https://michelf.ca/projects/php-markdown/configuration/
### Usage without an autoloader
If you cannot use class autoloading, you can still use `include` or `require`
to access the parser. To load the `Michelf\Markdown` parser, do it this way:
require_once 'Michelf/Markdown.inc.php';
Or, if you need the `Michelf\MarkdownExtra` parser:
require_once 'Michelf/MarkdownExtra.inc.php';
While the plain `.php` files depend on autoloading to work correctly, using the
`.inc.php` files instead will eagerly load the dependencies that would be
loaded on demand if you were using autoloading.
Public API and Versioning Policy
---------------------------------
Version numbers are of the form *major*.*minor*.*patch*.
The public API of PHP Markdown consist of the two parser classes `Markdown`
and `MarkdownExtra`, their constructors, the `transform` and `defaultTransform`
functions and their configuration variables. The public API is stable for
a given major version number. It might get additions when the minor version
number increments.
**Protected members are not considered public API.** This is unconventional
and deserves an explanation. Incrementing the major version number every time
the underlying implementation of something changes is going to give
nonessential version numbers for the vast majority of people who just use the
parser. Protected members are meant to create parser subclasses that behave in
different ways. Very few people create parser subclasses. I don't want to
discourage it by making everything private, but at the same time I can't
guarantee any stable hook between versions if you use protected members.
**Syntax changes** will increment the minor number for new features, and the
patch number for small corrections. A *new feature* is something that needs a
change in the syntax documentation. Note that since PHP Markdown Lib includes
two parsers, a syntax change for either of them will increment the minor
number. Also note that there is nothing perfectly backward-compatible with the
Markdown syntax: all inputs are always valid, so new features always replace
something that was previously legal, although generally nonsensical to do.
Bugs
----
To file bug reports please send email to:
<michel.fortin@michelf.ca>
Please include with your report: (1) the example input; (2) the output you
expected; (3) the output PHP Markdown actually produced.
If you have a problem where Markdown gives you an empty result, first check
that the backtrack limit is not too low by running `php --info | grep pcre`.
See Installation and Requirement above for details.
Development and Testing
-----------------------
Pull requests for fixing bugs are welcome. Proposed new features are
going to be meticulously reviewed -- taking into account backward compatibility,
potential side effects, and future extensibility -- before deciding on
acceptance or rejection.
If you make a pull request that includes changes to the parser please add
tests for what is being changed to the `test/` directory. This can be as
simple as adding a `.text` (input) file with a corresponding `.xhtml`
(output) file to proper category under `./test/resources/`.
Traditionally tests were in a separate repository, [MDTest](https://github.com/michelf/mdtest)
but they are now located here, alongside the source code.
Donations
---------
If you wish to make a donation that will help me devote more time to
PHP Markdown, please visit [michelf.ca/donate].
[michelf.ca/donate]: https://michelf.ca/donate/#!Thanks%20for%20PHP%20Markdown
Version History
---------------
PHP Markdown Lib 1.9.0 (1 Dec 2019)
* Added `fn_backlink_label` configuration variable to put some text in the
`aria-label` attribute.
(Thanks to Sunny Walker for the implementation.)
* Occurances of "`^^`" in `fn_backlink_html`, `fn_backlink_class`,
`fn_backlink_title`, and `fn_backlink_label` will be replaced by the
corresponding footnote number in the HTML output. Occurances of "`%%`" will be
replaced by a number for the reference (footnotes can have multiple references).
(Thanks to Sunny Walker for the implementation.)
* Added configuration variable `omit_footnotes`. When `true` footnotes are not
appended at the end of the generated HTML and the `footnotes_assembled`
variable will contain the HTML for the footnote list, allowing footnotes to be
moved somewhere else on the page.
(Thanks to James K. for the implementation.)
Note: when placing the content of `footnotes_assembled` on the page, consider
adding the attribute `role="doc-endnotes"` to the `<div>` or `<section>` that will
enclose the list of footnotes so they are reachable to accessibility tools the
same way they would be with the default HTML output.
* Fixed deprecation warnings from PHP about usage of curly braces to access
characters in text strings.
(Thanks to Remi Collet and Frans-Willem Post.)
PHP Markdown Lib 1.8.0 (14 Jan 2018)
* Autoloading with Composer now uses PSR-4.
* HTML output for Markdown Extra footnotes now include `role` attributes
with values from [WAI-ARIA](https://www.w3.org/TR/dpub-aria/) to
make them more accessible.
(Thanks to Tobias Bengfort)
* In Markdown Extra, added the `hashtag_protection` configuration variable.
When set to `true` it prevents ATX-style headers with no space after the initial
hash from being interpreted as headers. This way your precious hashtags
are preserved.
(Thanks to Jaussoin Timothée for the implementation.)
PHP Markdown Lib 1.7.0 (29 Oct 2016)
* Added a `hard_wrap` configuration variable to make all newline characters
in the text become `<br>` tags in the HTML output. By default, according
to the standard Markdown syntax these newlines are ignored unless they a
preceded by two spaces. Thanks to Jonathan Cohlmeyer for the implementation.
* Improved the parsing of list items to fix problematic cases that came to
light with the addition of `hard_wrap`. This should have no effect on the
output except span-level list items that ended with two spaces (and thus
ended with a line break).
* Added a `code_span_content_func` configuration variable which takes a
function that will convert the content of the code span to HTML. This can
be useful to implement syntax highlighting. Although contrary to its
code block equivalent, there is no syntax for specifying a language.
Credits to styxit for the implementation.
* Fixed a Markdown Extra issue where two-space-at-end-of-line hard breaks
wouldn't work inside of HTML block elements such as `<p markdown="1">`
where the element expects only span-level content.
* In the parser code, switched to PHPDoc comment format. Thanks to
Robbie Averill for the help.
PHP Markdown Lib 1.6.0 (23 Dec 2015)
Note: this version was incorrectly released as 1.5.1 on Dec 22, a number
that contradicted the versioning policy.
* For fenced code blocks in Markdown Extra, can now set a class name for the
code block's language before the special attribute block. Previously, this
class name was only allowed in the absence of the special attribute block.
* Added a `code_block_content_func` configuration variable which takes a
function that will convert the content of the code block to HTML. This is
most useful for syntax highlighting. For fenced code blocks in Markdown
Extra, the function has access to the language class name (the one outside
of the special attribute block). Credits to Mario Konrad for providing the
implementation.
* The curled arrow character for the backlink in footnotes is now followed
by a Unicode variant selector to prevent it from being displayed in emoji
form on iOS.
Note that in older browsers the variant selector is often interpreted as a
separate character, making it visible after the arrow. So there is now a
also a `fn_backlink_html` configuration variable that can be used to set
the link text to something else. Credits to Dana for providing the
implementation.
* Fixed an issue in MarkdownExtra where long header lines followed by a
special attribute block would hit the backtrack limit an cause an empty
string to be returned.
PHP Markdown Lib 1.5.0 (1 Mar 2015)
* Added the ability start ordered lists with a number different from 1 and
and have that reflected in the HTML output. This can be enabled with
the `enhanced_ordered_lists` configuration variable for the Markdown
parser; it is enabled by default for Markdown Extra.
Credits to Matt Gorle for providing the implementation.
* Added the ability to insert custom HTML attributes with simple values
everywhere an extra attribute block is allowed (links, images, headers).
The value must be unquoted, cannot contains spaces and is limited to
alphanumeric ASCII characters.
Credits to Peter Droogmans for providing the implementation.
* Added a `header_id_func` configuration variable which takes a function
that can generate an `id` attribute value from the header text.
Credits to Evert Pot for providing the implementation.
* Added a `url_filter_func` configuration variable which takes a function
that can rewrite any link or image URL to something different.
PHP Markdown Lib 1.4.1 (4 May 2014)
* The HTML block parser will now treat `<figure>` as a block-level element
(as it should) and no longer wrap it in `<p>` or parse it's content with
the as Markdown syntax (although with Extra you can use `markdown="1"`
if you wish to use the Markdown syntax inside it).
* The content of `<style>` elements will now be left alone, its content
won't be interpreted as Markdown.
* Corrected an bug where some inline links with spaces in them would not
work even when surounded with angle brackets:
[link](<s p a c e s>)
* Fixed an issue where email addresses with quotes in them would not always
have the quotes escaped in the link attribute, causing broken links (and
invalid HTML).
* Fixed the case were a link definition following a footnote definition would
be swallowed by the footnote unless it was separated by a blank line.
PHP Markdown Lib 1.4.0 (29 Nov 2013)
* Added support for the `tel:` URL scheme in automatic links.
<tel:+1-111-111-1111>
It gets converted to this (note the `tel:` prefix becomes invisible):
<a href="tel:+1-111-111-1111">+1-111-111-1111</a>
* Added backtick fenced code blocks to MarkdownExtra, originally from
Github-Flavored Markdown.
* Added an interface called MarkdownInterface implemented by both
the Markdown and MarkdownExtra parsers. You can use the interface if
you want to create a mockup parser object for unit testing.
* For those of you who cannot use class autoloading, you can now
include `Michelf/Markdown.inc.php` or `Michelf/MarkdownExtra.inc.php` (note
the `.inc.php` extension) to automatically include other files required
by the parser.
PHP Markdown Lib 1.3 (11 Apr 2013)
This is the first release of PHP Markdown Lib. This package requires PHP
version 5.3 or later and is designed to work with PSR-0 autoloading and,
optionally with Composer. Here is a list of the changes since
PHP Markdown Extra 1.2.6:
* Plugin interface for WordPress and other systems is no longer present in
the Lib package. The classic package is still available if you need it:
<https://michelf.ca/projects/php-markdown/classic/>
* Added `public` and `protected` protection attributes, plus a section about
what is "public API" and what isn't in the Readme file.
* Changed HTML output for footnotes: now instead of adding `rel` and `rev`
attributes, footnotes links have the class name `footnote-ref` and
backlinks `footnote-backref`.
* Fixed some regular expressions to make PCRE not shout warnings about POSIX
collation classes (dependent on your version of PCRE).
* Added optional class and id attributes to images and links using the same
syntax as for headers:
[link](url){#id .class}
![img](url){#id .class}
It work too for reference-style links and images. In this case you need
to put those attributes at the reference definition:
[link][linkref] or [linkref]
![img][linkref]
[linkref]: url "optional title" {#id .class}
* Fixed a PHP notice message triggered when some table column separator
markers are missing on the separator line below column headers.
* Fixed a small mistake that could cause the parser to retain an invalid
state related to parsing links across multiple runs. This was never
observed (that I know of), but it's still worth fixing.
Copyright and License
---------------------
PHP Markdown Lib
Copyright (c) 2004-2019 Michel Fortin
<https://michelf.ca/>
All rights reserved.
Based on Markdown
Copyright (c) 2003-2005 John Gruber
<https://daringfireball.net/>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the
distribution.
* Neither the name "Markdown" nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as
is" and any express or implied warranties, including, but not limited
to, the implied warranties of merchantability and fitness for a
particular purpose are disclaimed. In no event shall the copyright owner
or contributors be liable for any direct, indirect, incidental, special,
exemplary, or consequential damages (including, but not limited to,
procurement of substitute goods or services; loss of use, data, or
profits; or business interruption) however caused and on any theory of
liability, whether in contract, strict liability, or tort (including
negligence or otherwise) arising in any way out of the use of this
software, even if advised of the possibility of such damage.

View File

@ -0,0 +1,33 @@
<?php
// This file passes the content of the Readme.md file in the same directory
// through the Markdown filter. You can adapt this sample code in any way
// you like.
// Install PSR-4-compatible class autoloader
spl_autoload_register(function($class){
require str_replace('\\', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
});
// If using Composer, use this instead:
//require 'vendor/autoload.php';
// Get Markdown class
use Michelf\Markdown;
// Read file and pass content through the Markdown parser
$text = file_get_contents('Readme.md');
$html = Markdown::defaultTransform($text);
?>
<!DOCTYPE html>
<html>
<head>
<title>PHP Markdown Lib - Readme</title>
</head>
<body>
<?php
// Put HTML content in the document
echo $html;
?>
</body>
</html>

View File

@ -0,0 +1,29 @@
{
"name": "michelf/php-markdown",
"type": "library",
"description": "PHP Markdown",
"homepage": "https://michelf.ca/projects/php-markdown/",
"keywords": ["markdown"],
"license": "BSD-3-Clause",
"authors": [
{
"name": "Michel Fortin",
"email": "michel.fortin@michelf.ca",
"homepage": "https://michelf.ca/",
"role": "Developer"
},
{
"name": "John Gruber",
"homepage": "https://daringfireball.net/"
}
],
"require": {
"php": ">=7.4"
},
"autoload": {
"psr-4": { "Michelf\\": "Michelf/" }
},
"require-dev": {
"phpunit/phpunit": ">= 9.5"
}
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="./test/bootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
>
<testsuites>
<testsuite name="php-markdown Unit Tests">
<directory>./test/unit/</directory>
</testsuite>
<testsuite name="php-markdown Integration Tests">
<directory>./test/integration/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">Michelf</directory>
</whitelist>
</filter>
</phpunit>

View File

@ -0,0 +1,6 @@
<?php
define('TEST_ROOT', __DIR__);
define('TEST_RESOURCES_ROOT', __DIR__ . '/resources');
require_once __DIR__ . '/helpers/MarkdownTestHelper.php';

View File

@ -0,0 +1,267 @@
<?php
use PHPUnit\Framework\TestCase;
class MarkdownTestHelper
{
/**
* Takes an input directory containing .text and .(x)html files, and returns an array
* of .text files and the corresponding output xhtml or html file. Can be used in a unit test data provider.
*
* @param string $directory Input directory
*
* @return array
*/
public static function getInputOutputPaths($directory) {
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
$regexIterator = new RegexIterator(
$iterator,
'/^.+\.text$/',
RecursiveRegexIterator::GET_MATCH
);
$dataValues = array();
/** @var SplFileInfo $inputFile */
foreach ($regexIterator as $inputFiles) {
foreach ($inputFiles as $inputMarkdownPath) {
$xhtml = true;
$expectedHtmlPath = substr($inputMarkdownPath, 0, -4) . 'xhtml';
if (!file_exists($expectedHtmlPath)) {
$expectedHtmlPath = substr($inputMarkdownPath, 0, -4) . 'html';
$xhtml = false;
}
$dataValues[] = array($inputMarkdownPath, $expectedHtmlPath, $xhtml);
}
}
return $dataValues;
}
/**
* Applies PHPUnit's assertSame after normalizing both strings (e.g. ignoring whitespace differences).
* Uses logic found originally in MDTest.
*
* @param string $string1
* @param string $string2
* @param string $message Positive message to print when test fails (e.g. "String1 matches String2")
* @param bool $xhtml
*/
public static function assertSameNormalized($string1, $string2, $message, $xhtml = true) {
$t_result = $string1;
$t_output = $string2;
// DOMDocuments
if ($xhtml) {
$document = new DOMDocument();
$doc_result = $document->loadXML('<!DOCTYPE html>' .
"<html xmlns='http://www.w3.org/1999/xhtml'>" .
"<body>$t_result</body></html>");
$document2 = new DOMDocument();
$doc_output = $document2->loadXML('<!DOCTYPE html>' .
"<html xmlns='http://www.w3.org/1999/xhtml'>" .
"<body>$t_output</body></html>");
if ($doc_result) {
static::normalizeElementContent($document->documentElement, false);
$n_result = $document->saveXML();
} else {
$n_result = '--- Expected Result: XML Parse Error ---';
}
if ($doc_output) {
static::normalizeElementContent($document2->documentElement, false);
$n_output = $document2->saveXML();
} else {
$n_output = '--- Output: XML Parse Error ---';
}
} else {
// '@' suppressors used because some tests have invalid HTML (multiple elements with the same id attribute)
// Perhaps isolate to a separate test and remove this?
$document = new DOMDocument();
$doc_result = @$document->loadHTML($t_result);
$document2 = new DOMDocument();
$doc_output = @$document2->loadHTML($t_output);
if ($doc_result) {
static::normalizeElementContent($document->documentElement, false);
$n_result = $document->saveHTML();
} else {
$n_result = '--- Expected Result: HTML Parse Error ---';
}
if ($doc_output) {
static::normalizeElementContent($document2->documentElement, false);
$n_output = $document2->saveHTML();
} else {
$n_output = '--- Output: HTML Parse Error ---';
}
}
$n_result = preg_replace('{^.*?<body>|</body>.*?$}is', '', $n_result);
$n_output = preg_replace('{^.*?<body>|</body>.*?$}is', '', $n_output);
$c_result = $n_result;
$c_output = $n_output;
$c_result = trim($c_result) . "\n";
$c_output = trim($c_output) . "\n";
// This will throw a test exception if the strings don't exactly match
TestCase::assertSame($c_result, $c_output, $message);
}
/**
* @param DOMElement $element Modifies this element by reference
* @param bool $whitespace_preserve Preserve Whitespace
* @return void
*/
protected static function normalizeElementContent($element, $whitespace_preserve) {
#
# Normalize content of HTML DOM $element. The $whitespace_preserve
# argument indicates that whitespace is significant and shouldn't be
# normalized; it should be used for the content of certain elements like
# <pre> or <script>.
#
$node_list = $element->childNodes;
switch (strtolower($element->nodeName)) {
case 'body':
case 'div':
case 'blockquote':
case 'ul':
case 'ol':
case 'dl':
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
case 'h6':
$whitespace = "\n\n";
break;
case 'table':
$whitespace = "\n";
break;
case 'pre':
case 'script':
case 'style':
case 'title':
$whitespace_preserve = true;
$whitespace = "";
break;
default:
$whitespace = "";
break;
}
foreach ($node_list as $node) {
switch ($node->nodeType) {
case XML_ELEMENT_NODE:
static::normalizeElementContent($node, $whitespace_preserve);
static::normalizeElementAttributes($node);
switch (strtolower($node->nodeName)) {
case 'p':
case 'div':
case 'hr':
case 'blockquote':
case 'ul':
case 'ol':
case 'dl':
case 'li':
case 'address':
case 'table':
case 'dd':
case 'pre':
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
case 'h6':
$whitespace = "\n\n";
break;
case 'tr':
case 'td':
case 'dt':
$whitespace = "\n";
break;
default:
$whitespace = "";
break;
}
if (($whitespace === "\n\n" || $whitespace === "\n") &&
$node->nextSibling &&
$node->nextSibling->nodeType != XML_TEXT_NODE) {
$element->insertBefore(new DOMText($whitespace), $node->nextSibling);
}
break;
case XML_TEXT_NODE:
if (!$whitespace_preserve) {
if (trim($node->data) === "") {
$node->data = $whitespace;
}
else {
$node->data = preg_replace('{\s+}', ' ', $node->data);
}
}
break;
}
}
if (!$whitespace_preserve &&
($whitespace === "\n\n" || $whitespace === "\n")) {
if ($element->firstChild) {
if ($element->firstChild->nodeType == XML_TEXT_NODE) {
$element->firstChild->data =
preg_replace('{^\s+}', "\n", $element->firstChild->data);
}
else {
$element->insertBefore(new DOMText("\n"), $element->firstChild);
}
}
if ($element->lastChild) {
if ($element->lastChild->nodeType == XML_TEXT_NODE) {
$element->lastChild->data =
preg_replace('{\s+$}', "\n", $element->lastChild->data);
}
else {
$element->insertBefore(new DOMText("\n"), null);
}
}
}
}
/**
* @param DOMElement $element Modifies this element by reference
*/
protected static function normalizeElementAttributes (DOMElement $element)
{
#
# Sort attributes by name.
#
// Gather the list of attributes as an array.
$attr_list = array();
foreach ($element->attributes as $attr_node) {
$attr_list[$attr_node->name] = $attr_node;
}
// Sort attribute list by name.
ksort($attr_list);
// Remove then put back each attribute following sort order.
foreach ($attr_list as $attr_node) {
$element->removeAttributeNode($attr_node);
$element->setAttributeNode($attr_node);
}
}
}

View File

@ -0,0 +1,173 @@
<?php
use PHPUnit\Framework\TestCase;
use Michelf\Markdown;
use Michelf\MarkdownExtra;
class PhpMarkdownTest extends TestCase
{
/**
* Returns all php-markdown.mdtest tests
* @return array
*/
public function dataProviderForPhpMarkdown() {
$dir = TEST_RESOURCES_ROOT . '/php-markdown.mdtest';
return MarkdownTestHelper::getInputOutputPaths($dir);
}
/**
* Runs php-markdown.mdtest against Markdown::defaultTransform
*
* @dataProvider dataProviderForPhpMarkdown
*
* @param string $inputPath Input markdown path
* @param string $htmlPath File path of expected transformed output (X)HTML
*
* @param bool $xhtml True if XHTML. Otherwise, HTML is assumed.
*
* @return void
*/
public function testTransformingOfPhpMarkdown($inputPath, $htmlPath, $xhtml = false) {
$inputMarkdown = file_get_contents($inputPath);
$expectedHtml = file_get_contents($htmlPath);
$result = Markdown::defaultTransform($inputMarkdown);
MarkdownTestHelper::assertSameNormalized(
$expectedHtml,
$result,
"Markdown in $inputPath converts exactly to expected $htmlPath",
$xhtml
);
}
/**
* Returns all php-markdown.mdtest tests EXCEPT Emphasis test.
* @return array
*/
public function dataProviderForPhpMarkdownExceptEmphasis()
{
$dir = TEST_RESOURCES_ROOT . '/php-markdown.mdtest';
$allTests = MarkdownTestHelper::getInputOutputPaths($dir);
foreach ($allTests as $index => $test) {
// Because MarkdownExtra treats underscore emphasis differently, this one test has to be excluded
if (preg_match('~/Emphasis\.text$~', $test[0])) {
unset($allTests[$index]);
}
}
return array_values($allTests);
}
/**
* Runs php-markdown.mdtest against MarkdownExtra::defaultTransform
*
* @dataProvider dataProviderForPhpMarkdownExceptEmphasis
*
* @param $inputPath
* @param $htmlPath
* @param bool $xhtml
*/
public function testPhpMarkdownMdTestWithMarkdownExtra($inputPath, $htmlPath, $xhtml = false)
{
$inputMarkdown = file_get_contents($inputPath);
$expectedHtml = file_get_contents($htmlPath);
$result = MarkdownExtra::defaultTransform($inputMarkdown);
MarkdownTestHelper::assertSameNormalized(
$expectedHtml,
$result,
"Markdown in $inputPath converts exactly to expected $htmlPath",
$xhtml
);
}
/**
* @return array
*/
public function dataProviderForMarkdownExtra() {
$dir = TEST_RESOURCES_ROOT . '/php-markdown-extra.mdtest';
return MarkdownTestHelper::getInputOutputPaths($dir);
}
/**
* @dataProvider dataProviderForMarkdownExtra
*
* @param string $inputPath Input markdown path
* @param string $htmlPath File path of expected transformed output (X)HTML
*
* @param bool $xhtml True if XHTML. Otherwise, HTML is assumed.
*
* @return void
*/
public function testTransformingOfMarkdownExtra($inputPath, $htmlPath, $xhtml = false) {
$inputMarkdown = file_get_contents($inputPath);
$expectedHtml = file_get_contents($htmlPath);
$result = MarkdownExtra::defaultTransform($inputMarkdown);
MarkdownTestHelper::assertSameNormalized(
$expectedHtml,
$result,
"Markdown in $inputPath converts exactly to expected $htmlPath",
$xhtml
);
}
/**
* @return array
*/
public function dataProviderForRegularMarkdown()
{
$dir = TEST_RESOURCES_ROOT . '/markdown.mdtest';
return MarkdownTestHelper::getInputOutputPaths($dir);
}
/**
* @dataProvider dataProviderForRegularMarkdown
*
* @param string $inputPath Input markdown path
* @param string $htmlPath File path of expected transformed output (X)HTML
*
* @param bool $xhtml True if XHTML. Otherwise, HTML is assumed.
*
* @return void
*/
public function testTransformingOfRegularMarkdown($inputPath, $htmlPath, $xhtml = false)
{
$inputMarkdown = file_get_contents($inputPath);
$expectedHtml = file_get_contents($htmlPath);
$result = Markdown::defaultTransform($inputMarkdown);
MarkdownTestHelper::assertSameNormalized(
$expectedHtml,
$result,
"Markdown in $inputPath converts exactly to expected $htmlPath",
$xhtml
);
}
/**
* Runs markdown.mdtest against MarkdownExtra::defaultTransform
*
* @dataProvider dataProviderForRegularMarkdown
*
* @param $inputPath
* @param $htmlPath
* @param bool $xhtml
*/
public function testMarkdownMdTestWithMarkdownExtra($inputPath, $htmlPath, $xhtml = false)
{
$inputMarkdown = file_get_contents($inputPath);
$expectedHtml = file_get_contents($htmlPath);
$result = MarkdownExtra::defaultTransform($inputMarkdown);
MarkdownTestHelper::assertSameNormalized(
$expectedHtml,
$result,
"Markdown in $inputPath converts exactly to expected $htmlPath",
$xhtml
);
}
}

View File

@ -0,0 +1,21 @@
AT&T has an ampersand in their name.
AT&amp;T is another way to write it.
This & that.
4 < 5.
6 > 5.
Here's a [link] [1] with an ampersand in the URL.
Here's a link with an amersand in the link text: [AT&T] [2].
Here's an inline [link](/script?foo=1&bar=2).
Here's an inline [link](</script?foo=1&bar=2>).
[1]: http://example.com/?foo=1&bar=2
[2]: http://att.com/ "AT&T"

View File

@ -0,0 +1,17 @@
<p>AT&amp;T has an ampersand in their name.</p>
<p>AT&amp;T is another way to write it.</p>
<p>This &amp; that.</p>
<p>4 &lt; 5.</p>
<p>6 > 5.</p>
<p>Here's a <a href="http://example.com/?foo=1&amp;bar=2">link</a> with an ampersand in the URL.</p>
<p>Here's a link with an amersand in the link text: <a href="http://att.com/" title="AT&amp;T">AT&amp;T</a>.</p>
<p>Here's an inline <a href="/script?foo=1&amp;bar=2">link</a>.</p>
<p>Here's an inline <a href="/script?foo=1&amp;bar=2">link</a>.</p>

View File

@ -0,0 +1,13 @@
Link: <http://example.com/>.
With an ampersand: <http://example.com/?foo=1&bar=2>
* In a list?
* <http://example.com/>
* It should.
> Blockquoted: <http://example.com/>
Auto-links should not occur here: `<http://example.com/>`
or here: <http://example.com/>

View File

@ -0,0 +1,18 @@
<p>Link: <a href="http://example.com/">http://example.com/</a>.</p>
<p>With an ampersand: <a href="http://example.com/?foo=1&amp;bar=2">http://example.com/?foo=1&amp;bar=2</a></p>
<ul>
<li>In a list?</li>
<li><a href="http://example.com/">http://example.com/</a></li>
<li>It should.</li>
</ul>
<blockquote>
<p>Blockquoted: <a href="http://example.com/">http://example.com/</a></p>
</blockquote>
<p>Auto-links should not occur here: <code>&lt;http://example.com/&gt;</code></p>
<pre><code>or here: &lt;http://example.com/&gt;
</code></pre>

View File

@ -0,0 +1,120 @@
These should all get escaped:
Backslash: \\
Backtick: \`
Asterisk: \*
Underscore: \_
Left brace: \{
Right brace: \}
Left bracket: \[
Right bracket: \]
Left paren: \(
Right paren: \)
Greater-than: \>
Hash: \#
Period: \.
Bang: \!
Plus: \+
Minus: \-
These should not, because they occur within a code block:
Backslash: \\
Backtick: \`
Asterisk: \*
Underscore: \_
Left brace: \{
Right brace: \}
Left bracket: \[
Right bracket: \]
Left paren: \(
Right paren: \)
Greater-than: \>
Hash: \#
Period: \.
Bang: \!
Plus: \+
Minus: \-
Nor should these, which occur in code spans:
Backslash: `\\`
Backtick: `` \` ``
Asterisk: `\*`
Underscore: `\_`
Left brace: `\{`
Right brace: `\}`
Left bracket: `\[`
Right bracket: `\]`
Left paren: `\(`
Right paren: `\)`
Greater-than: `\>`
Hash: `\#`
Period: `\.`
Bang: `\!`
Plus: `\+`
Minus: `\-`
These should get escaped, even though they're matching pairs for
other Markdown constructs:
\*asterisks\*
\_underscores\_
\`backticks\`
This is a code span with a literal backslash-backtick sequence: `` \` ``
This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.
This is a tag with backslashes <span attr='\\backslashes\\'>bar</span>.

View File

@ -0,0 +1,118 @@
<p>These should all get escaped:</p>
<p>Backslash: \</p>
<p>Backtick: `</p>
<p>Asterisk: *</p>
<p>Underscore: _</p>
<p>Left brace: {</p>
<p>Right brace: }</p>
<p>Left bracket: [</p>
<p>Right bracket: ]</p>
<p>Left paren: (</p>
<p>Right paren: )</p>
<p>Greater-than: ></p>
<p>Hash: #</p>
<p>Period: .</p>
<p>Bang: !</p>
<p>Plus: +</p>
<p>Minus: -</p>
<p>These should not, because they occur within a code block:</p>
<pre><code>Backslash: \\
Backtick: \`
Asterisk: \*
Underscore: \_
Left brace: \{
Right brace: \}
Left bracket: \[
Right bracket: \]
Left paren: \(
Right paren: \)
Greater-than: \&gt;
Hash: \#
Period: \.
Bang: \!
Plus: \+
Minus: \-
</code></pre>
<p>Nor should these, which occur in code spans:</p>
<p>Backslash: <code>\\</code></p>
<p>Backtick: <code>\`</code></p>
<p>Asterisk: <code>\*</code></p>
<p>Underscore: <code>\_</code></p>
<p>Left brace: <code>\{</code></p>
<p>Right brace: <code>\}</code></p>
<p>Left bracket: <code>\[</code></p>
<p>Right bracket: <code>\]</code></p>
<p>Left paren: <code>\(</code></p>
<p>Right paren: <code>\)</code></p>
<p>Greater-than: <code>\&gt;</code></p>
<p>Hash: <code>\#</code></p>
<p>Period: <code>\.</code></p>
<p>Bang: <code>\!</code></p>
<p>Plus: <code>\+</code></p>
<p>Minus: <code>\-</code></p>
<p>These should get escaped, even though they're matching pairs for
other Markdown constructs:</p>
<p>*asterisks*</p>
<p>_underscores_</p>
<p>`backticks`</p>
<p>This is a code span with a literal backslash-backtick sequence: <code>\`</code></p>
<p>This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.</p>
<p>This is a tag with backslashes <span attr='\\backslashes\\'>bar</span>.</p>

View File

@ -0,0 +1,11 @@
> Example:
>
> sub status {
> print "working";
> }
>
> Or:
>
> sub status {
> return "working";
> }

View File

@ -0,0 +1,15 @@
<blockquote>
<p>Example:</p>
<pre><code>sub status {
print "working";
}
</code></pre>
<p>Or:</p>
<pre><code>sub status {
return "working";
}
</code></pre>
</blockquote>

View File

@ -0,0 +1,14 @@
code block on the first line
Regular text.
code block indented by spaces
Regular text.
the lines in this block
all contain trailing spaces
Regular Text.
code block on the last line

View File

@ -0,0 +1,18 @@
<pre><code>code block on the first line
</code></pre>
<p>Regular text.</p>
<pre><code>code block indented by spaces
</code></pre>
<p>Regular text.</p>
<pre><code>the lines in this block
all contain trailing spaces
</code></pre>
<p>Regular Text.</p>
<pre><code>code block on the last line
</code></pre>

View File

@ -0,0 +1,5 @@
`<test a="` content of attribute `">`
Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span>
Here's how you put `` `backticks` `` in a code span.

View File

@ -0,0 +1,5 @@
<p><code>&lt;test a="</code> content of attribute <code>"&gt;</code></p>
<p>Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span></p>
<p>Here's how you put <code>`backticks`</code> in a code span.</p>

View File

@ -0,0 +1,8 @@
In Markdown 1.0.0 and earlier. Version
8. This line turns into a list item.
Because a hard-wrapped line in the
middle of a paragraph looked like a
list item.
Here's one with a bullet.
* criminey.

View File

@ -0,0 +1,8 @@
<p>In Markdown 1.0.0 and earlier. Version
8. This line turns into a list item.
Because a hard-wrapped line in the
middle of a paragraph looked like a
list item.</p>
<p>Here's one with a bullet.
* criminey.</p>

View File

@ -0,0 +1,67 @@
Dashes:
---
---
---
---
---
- - -
- - -
- - -
- - -
- - -
Asterisks:
***
***
***
***
***
* * *
* * *
* * *
* * *
* * *
Underscores:
___
___
___
___
___
_ _ _
_ _ _
_ _ _
_ _ _
_ _ _

View File

@ -0,0 +1,71 @@
<p>Dashes:</p>
<hr />
<hr />
<hr />
<hr />
<pre><code>---
</code></pre>
<hr />
<hr />
<hr />
<hr />
<pre><code>- - -
</code></pre>
<p>Asterisks:</p>
<hr />
<hr />
<hr />
<hr />
<pre><code>***
</code></pre>
<hr />
<hr />
<hr />
<hr />
<pre><code>* * *
</code></pre>
<p>Underscores:</p>
<hr />
<hr />
<hr />
<hr />
<pre><code>___
</code></pre>
<hr />
<hr />
<hr />
<hr />
<pre><code>_ _ _
</code></pre>

View File

@ -0,0 +1,26 @@
![Alt text](/path/to/img.jpg)
![Alt text](/path/to/img.jpg "Optional title")
Inline within a paragraph: [alt text](/url/).
![alt text](/url/ "title preceded by two spaces")
![alt text](/url/ "title has spaces afterward" )
![alt text](</url/>)
![alt text](</url/> "with a title").
![Empty]()
![this is a stupid URL](http://example.com/(parens).jpg)
![alt text][foo]
[foo]: /url/
![alt text][bar]
[bar]: /url/ "Title here"

View File

@ -0,0 +1,21 @@
<p><img src="/path/to/img.jpg" alt="Alt text" /></p>
<p><img src="/path/to/img.jpg" alt="Alt text" title="Optional title" /></p>
<p>Inline within a paragraph: <a href="/url/">alt text</a>.</p>
<p><img src="/url/" alt="alt text" title="title preceded by two spaces" /></p>
<p><img src="/url/" alt="alt text" title="title has spaces afterward" /></p>
<p><img src="/url/" alt="alt text" /></p>
<p><img src="/url/" alt="alt text" title="with a title" />.</p>
<p><img src="" alt="Empty" /></p>
<p><img src="http://example.com/(parens).jpg" alt="this is a stupid URL" /></p>
<p><img src="/url/" alt="alt text" /></p>
<p><img src="/url/" alt="alt text" title="Title here" /></p>

View File

@ -0,0 +1,30 @@
Simple block on one line:
<div>foo</div>
And nested without indentation:
<div>
<div>
<div>
foo
</div>
<div style=">"/>
</div>
<div>bar</div>
</div>
And with attributes:
<div>
<div id="foo">
</div>
</div>
This was broken in 1.0.2b7:
<div class="inlinepage">
<div class="toggleableend">
foo
</div>
</div>

View File

@ -0,0 +1,30 @@
<p>Simple block on one line:</p>
<div>foo</div>
<p>And nested without indentation:</p>
<div>
<div>
<div>
foo
</div>
<div style=">"/>
</div>
<div>bar</div>
</div>
<p>And with attributes:</p>
<div>
<div id="foo">
</div>
</div>
<p>This was broken in 1.0.2b7:</p>
<div class="inlinepage">
<div class="toggleableend">
foo
</div>
</div>

View File

@ -0,0 +1,72 @@
<p>Here's a simple block:</p>
<div>
foo
</div>
<p>This should be a code block, though:</p>
<pre><code>&lt;div&gt;
foo
&lt;/div&gt;
</code></pre>
<p>As should this:</p>
<pre><code>&lt;div&gt;foo&lt;/div&gt;
</code></pre>
<p>Now, nested:</p>
<div>
<div>
<div>
foo
</div>
</div>
</div>
<p>This should just be an HTML comment:</p>
<!-- Comment -->
<p>Multiline:</p>
<!--
Blah
Blah
-->
<p>Code block:</p>
<pre><code>&lt;!-- Comment --&gt;
</code></pre>
<p>Just plain comment, with trailing spaces on the line:</p>
<!-- foo -->
<p>Code:</p>
<pre><code>&lt;hr /&gt;
</code></pre>
<p>Hr's:</p>
<hr>
<hr/>
<hr />
<hr>
<hr/>
<hr />
<hr class="foo" id="bar" />
<hr class="foo" id="bar"/>
<hr class="foo" id="bar" >

View File

@ -0,0 +1,69 @@
Here's a simple block:
<div>
foo
</div>
This should be a code block, though:
<div>
foo
</div>
As should this:
<div>foo</div>
Now, nested:
<div>
<div>
<div>
foo
</div>
</div>
</div>
This should just be an HTML comment:
<!-- Comment -->
Multiline:
<!--
Blah
Blah
-->
Code block:
<!-- Comment -->
Just plain comment, with trailing spaces on the line:
<!-- foo -->
Code:
<hr />
Hr's:
<hr>
<hr/>
<hr />
<hr>
<hr/>
<hr />
<hr class="foo" id="bar" />
<hr class="foo" id="bar"/>
<hr class="foo" id="bar" >

View File

@ -0,0 +1,13 @@
<p>Paragraph one.</p>
<!-- This is a simple comment -->
<!--
This is another comment.
-->
<p>Paragraph two.</p>
<!-- one comment block -- -- with two comments -->
<p>The end.</p>

View File

@ -0,0 +1,13 @@
Paragraph one.
<!-- This is a simple comment -->
<!--
This is another comment.
-->
Paragraph two.
<!-- one comment block -- -- with two comments -->
The end.

View File

@ -0,0 +1,24 @@
Just a [URL](/url/).
[URL and title](/url/ "title").
[URL and title](/url/ "title preceded by two spaces").
[URL and title](/url/ "title preceded by a tab").
[URL and title](/url/ "title has spaces afterward" ).
[URL wrapped in angle brackets](</url/>).
[URL w/ angle brackets + title](</url/> "Here's the title").
[Empty]().
[With parens in the URL](http://en.wikipedia.org/wiki/WIMP_(computing))
(With outer parens and [parens in url](/foo(bar)))
[With parens in the URL](/foo(bar) "and a title")
(With outer parens and [parens in url](/foo(bar) "and a title"))

View File

@ -0,0 +1,23 @@
<p>Just a <a href="/url/">URL</a>.</p>
<p><a href="/url/" title="title">URL and title</a>.</p>
<p><a href="/url/" title="title preceded by two spaces">URL and title</a>.</p>
<p><a href="/url/" title="title preceded by a tab">URL and title</a>.</p>
<p><a href="/url/" title="title has spaces afterward">URL and title</a>.</p>
<p><a href="/url/">URL wrapped in angle brackets</a>.</p>
<p><a href="/url/" title="Here's the title">URL w/ angle brackets + title</a>.</p>
<p><a href="">Empty</a>.</p>
<p><a href="http://en.wikipedia.org/wiki/WIMP_(computing)">With parens in the URL</a></p>
<p>(With outer parens and <a href="/foo(bar)">parens in url</a>)</p>
<p><a href="/foo(bar)" title="and a title">With parens in the URL</a></p>
<p>(With outer parens and <a href="/foo(bar)" title="and a title">parens in url</a>)</p>

View File

@ -0,0 +1,71 @@
Foo [bar] [1].
Foo [bar][1].
Foo [bar]
[1].
[1]: /url/ "Title"
With [embedded [brackets]] [b].
Indented [once][].
Indented [twice][].
Indented [thrice][].
Indented [four][] times.
[once]: /url
[twice]: /url
[thrice]: /url
[four]: /url
[b]: /url/
* * *
[this] [this] should work
So should [this][this].
And [this] [].
And [this][].
And [this].
But not [that] [].
Nor [that][].
Nor [that].
[Something in brackets like [this][] should work]
[Same with [this].]
In this case, [this](/somethingelse/) points to something else.
Backslashing should suppress \[this] and [this\].
[this]: foo
* * *
Here's one where the [link
breaks] across lines.
Here's another where the [link
breaks] across lines, but with a line-ending space.
[link breaks]: /url/

View File

@ -0,0 +1,52 @@
<p>Foo <a href="/url/" title="Title">bar</a>.</p>
<p>Foo <a href="/url/" title="Title">bar</a>.</p>
<p>Foo <a href="/url/" title="Title">bar</a>.</p>
<p>With <a href="/url/">embedded [brackets]</a>.</p>
<p>Indented <a href="/url">once</a>.</p>
<p>Indented <a href="/url">twice</a>.</p>
<p>Indented <a href="/url">thrice</a>.</p>
<p>Indented [four][] times.</p>
<pre><code>[four]: /url
</code></pre>
<hr />
<p><a href="foo">this</a> should work</p>
<p>So should <a href="foo">this</a>.</p>
<p>And <a href="foo">this</a>.</p>
<p>And <a href="foo">this</a>.</p>
<p>And <a href="foo">this</a>.</p>
<p>But not [that] [].</p>
<p>Nor [that][].</p>
<p>Nor [that].</p>
<p>[Something in brackets like <a href="foo">this</a> should work]</p>
<p>[Same with <a href="foo">this</a>.]</p>
<p>In this case, <a href="/somethingelse/">this</a> points to something else.</p>
<p>Backslashing should suppress [this] and [this].</p>
<hr />
<p>Here's one where the <a href="/url/">link
breaks</a> across lines.</p>
<p>Here's another where the <a href="/url/">link
breaks</a> across lines, but with a line-ending space.</p>

View File

@ -0,0 +1,20 @@
This is the [simple case].
[simple case]: /simple
This one has a [line
break].
This one has a [line
break] with a line-ending space.
[line break]: /foo
[this] [that] and the [other]
[this]: /this
[that]: /that
[other]: /other

View File

@ -0,0 +1,9 @@
<p>This is the <a href="/simple">simple case</a>.</p>
<p>This one has a <a href="/foo">line
break</a>.</p>
<p>This one has a <a href="/foo">line
break</a> with a line-ending space.</p>
<p><a href="/that">this</a> and the <a href="/other">other</a></p>

View File

@ -0,0 +1,7 @@
Foo [bar][].
Foo [bar](/url/ "Title with "quotes" inside").
[bar]: /url/ "Title with "quotes" inside"

View File

@ -0,0 +1,3 @@
<p>Foo <a href="/url/" title="Title with &quot;quotes&quot; inside">bar</a>.</p>
<p>Foo <a href="/url/" title="Title with &quot;quotes&quot; inside">bar</a>.</p>

View File

@ -0,0 +1,306 @@
Markdown: Basics
================
<ul id="ProjectSubmenu">
<li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
<li><a class="selected" title="Markdown Basics">Basics</a></li>
<li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
<li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
<li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
</ul>
Getting the Gist of Markdown's Formatting Syntax
------------------------------------------------
This page offers a brief overview of what it's like to use Markdown.
The [syntax page] [s] provides complete, detailed documentation for
every feature, but Markdown should be very easy to pick up simply by
looking at a few examples of it in action. The examples on this page
are written in a before/after style, showing example syntax and the
HTML output produced by Markdown.
It's also helpful to simply try Markdown out; the [Dingus] [d] is a
web application that allows you type your own Markdown-formatted text
and translate it to XHTML.
**Note:** This document is itself written using Markdown; you
can [see the source for it by adding '.text' to the URL] [src].
[s]: /projects/markdown/syntax "Markdown Syntax"
[d]: /projects/markdown/dingus "Markdown Dingus"
[src]: /projects/markdown/basics.text
## Paragraphs, Headers, Blockquotes ##
A paragraph is simply one or more consecutive lines of text, separated
by one or more blank lines. (A blank line is any line that looks like a
blank line -- a line containing nothing spaces or tabs is considered
blank.) Normal paragraphs should not be intended with spaces or tabs.
Markdown offers two styles of headers: *Setext* and *atx*.
Setext-style headers for `<h1>` and `<h2>` are created by
"underlining" with equal signs (`=`) and hyphens (`-`), respectively.
To create an atx-style header, you put 1-6 hash marks (`#`) at the
beginning of the line -- the number of hashes equals the resulting
HTML header level.
Blockquotes are indicated using email-style '`>`' angle brackets.
Markdown:
A First Level Header
====================
A Second Level Header
---------------------
Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.
The quick brown fox jumped over the lazy
dog's back.
### Header 3
> This is a blockquote.
>
> This is the second paragraph in the blockquote.
>
> ## This is an H2 in a blockquote
Output:
<h1>A First Level Header</h1>
<h2>A Second Level Header</h2>
<p>Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.</p>
<p>The quick brown fox jumped over the lazy
dog's back.</p>
<h3>Header 3</h3>
<blockquote>
<p>This is a blockquote.</p>
<p>This is the second paragraph in the blockquote.</p>
<h2>This is an H2 in a blockquote</h2>
</blockquote>
### Phrase Emphasis ###
Markdown uses asterisks and underscores to indicate spans of emphasis.
Markdown:
Some of these words *are emphasized*.
Some of these words _are emphasized also_.
Use two asterisks for **strong emphasis**.
Or, if you prefer, __use two underscores instead__.
Output:
<p>Some of these words <em>are emphasized</em>.
Some of these words <em>are emphasized also</em>.</p>
<p>Use two asterisks for <strong>strong emphasis</strong>.
Or, if you prefer, <strong>use two underscores instead</strong>.</p>
## Lists ##
Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
`+`, and `-`) as list markers. These three markers are
interchangable; this:
* Candy.
* Gum.
* Booze.
this:
+ Candy.
+ Gum.
+ Booze.
and this:
- Candy.
- Gum.
- Booze.
all produce the same output:
<ul>
<li>Candy.</li>
<li>Gum.</li>
<li>Booze.</li>
</ul>
Ordered (numbered) lists use regular numbers, followed by periods, as
list markers:
1. Red
2. Green
3. Blue
Output:
<ol>
<li>Red</li>
<li>Green</li>
<li>Blue</li>
</ol>
If you put blank lines between items, you'll get `<p>` tags for the
list item text. You can create multi-paragraph list items by indenting
the paragraphs by 4 spaces or 1 tab:
* A list item.
With multiple paragraphs.
* Another item in the list.
Output:
<ul>
<li><p>A list item.</p>
<p>With multiple paragraphs.</p></li>
<li><p>Another item in the list.</p></li>
</ul>
### Links ###
Markdown supports two styles for creating links: *inline* and
*reference*. With both styles, you use square brackets to delimit the
text you want to turn into a link.
Inline-style links use parentheses immediately after the link text.
For example:
This is an [example link](http://example.com/).
Output:
<p>This is an <a href="http://example.com/">
example link</a>.</p>
Optionally, you may include a title attribute in the parentheses:
This is an [example link](http://example.com/ "With a Title").
Output:
<p>This is an <a href="http://example.com/" title="With a Title">
example link</a>.</p>
Reference-style links allow you to refer to your links by names, which
you define elsewhere in your document:
I get 10 times more traffic from [Google][1] than from
[Yahoo][2] or [MSN][3].
[1]: http://google.com/ "Google"
[2]: http://search.yahoo.com/ "Yahoo Search"
[3]: http://search.msn.com/ "MSN Search"
Output:
<p>I get 10 times more traffic from <a href="http://google.com/"
title="Google">Google</a> than from <a href="http://search.yahoo.com/"
title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
title="MSN Search">MSN</a>.</p>
The title attribute is optional. Link names may contain letters,
numbers and spaces, but are *not* case sensitive:
I start my morning with a cup of coffee and
[The New York Times][NY Times].
[ny times]: http://www.nytimes.com/
Output:
<p>I start my morning with a cup of coffee and
<a href="http://www.nytimes.com/">The New York Times</a>.</p>
### Images ###
Image syntax is very much like link syntax.
Inline (titles are optional):
![alt text](/path/to/img.jpg "Title")
Reference-style:
![alt text][id]
[id]: /path/to/img.jpg "Title"
Both of the above examples produce the same output:
<img src="/path/to/img.jpg" alt="alt text" title="Title" />
### Code ###
In a regular paragraph, you can create code span by wrapping text in
backtick quotes. Any ampersands (`&`) and angle brackets (`<` or
`>`) will automatically be translated into HTML entities. This makes
it easy to use Markdown to write about HTML example code:
I strongly recommend against using any `<blink>` tags.
I wish SmartyPants used named entities like `&mdash;`
instead of decimal-encoded entites like `&#8212;`.
Output:
<p>I strongly recommend against using any
<code>&lt;blink&gt;</code> tags.</p>
<p>I wish SmartyPants used named entities like
<code>&amp;mdash;</code> instead of decimal-encoded
entites like <code>&amp;#8212;</code>.</p>
To specify an entire block of pre-formatted code, indent every line of
the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`,
and `>` characters will be escaped automatically.
Markdown:
If you want your page to validate under XHTML 1.0 Strict,
you've got to put paragraph tags in your blockquotes:
<blockquote>
<p>For example.</p>
</blockquote>
Output:
<p>If you want your page to validate under XHTML 1.0 Strict,
you've got to put paragraph tags in your blockquotes:</p>
<pre><code>&lt;blockquote&gt;
&lt;p&gt;For example.&lt;/p&gt;
&lt;/blockquote&gt;
</code></pre>

View File

@ -0,0 +1,314 @@
<h1>Markdown: Basics</h1>
<ul id="ProjectSubmenu">
<li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
<li><a class="selected" title="Markdown Basics">Basics</a></li>
<li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
<li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
<li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
</ul>
<h2>Getting the Gist of Markdown's Formatting Syntax</h2>
<p>This page offers a brief overview of what it's like to use Markdown.
The <a href="/projects/markdown/syntax" title="Markdown Syntax">syntax page</a> provides complete, detailed documentation for
every feature, but Markdown should be very easy to pick up simply by
looking at a few examples of it in action. The examples on this page
are written in a before/after style, showing example syntax and the
HTML output produced by Markdown.</p>
<p>It's also helpful to simply try Markdown out; the <a href="/projects/markdown/dingus" title="Markdown Dingus">Dingus</a> is a
web application that allows you type your own Markdown-formatted text
and translate it to XHTML.</p>
<p><strong>Note:</strong> This document is itself written using Markdown; you
can <a href="/projects/markdown/basics.text">see the source for it by adding '.text' to the URL</a>.</p>
<h2>Paragraphs, Headers, Blockquotes</h2>
<p>A paragraph is simply one or more consecutive lines of text, separated
by one or more blank lines. (A blank line is any line that looks like a
blank line -- a line containing nothing spaces or tabs is considered
blank.) Normal paragraphs should not be intended with spaces or tabs.</p>
<p>Markdown offers two styles of headers: <em>Setext</em> and <em>atx</em>.
Setext-style headers for <code>&lt;h1&gt;</code> and <code>&lt;h2&gt;</code> are created by
"underlining" with equal signs (<code>=</code>) and hyphens (<code>-</code>), respectively.
To create an atx-style header, you put 1-6 hash marks (<code>#</code>) at the
beginning of the line -- the number of hashes equals the resulting
HTML header level.</p>
<p>Blockquotes are indicated using email-style '<code>&gt;</code>' angle brackets.</p>
<p>Markdown:</p>
<pre><code>A First Level Header
====================
A Second Level Header
---------------------
Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.
The quick brown fox jumped over the lazy
dog's back.
### Header 3
&gt; This is a blockquote.
&gt;
&gt; This is the second paragraph in the blockquote.
&gt;
&gt; ## This is an H2 in a blockquote
</code></pre>
<p>Output:</p>
<pre><code>&lt;h1&gt;A First Level Header&lt;/h1&gt;
&lt;h2&gt;A Second Level Header&lt;/h2&gt;
&lt;p&gt;Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.&lt;/p&gt;
&lt;p&gt;The quick brown fox jumped over the lazy
dog's back.&lt;/p&gt;
&lt;h3&gt;Header 3&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a blockquote.&lt;/p&gt;
&lt;p&gt;This is the second paragraph in the blockquote.&lt;/p&gt;
&lt;h2&gt;This is an H2 in a blockquote&lt;/h2&gt;
&lt;/blockquote&gt;
</code></pre>
<h3>Phrase Emphasis</h3>
<p>Markdown uses asterisks and underscores to indicate spans of emphasis.</p>
<p>Markdown:</p>
<pre><code>Some of these words *are emphasized*.
Some of these words _are emphasized also_.
Use two asterisks for **strong emphasis**.
Or, if you prefer, __use two underscores instead__.
</code></pre>
<p>Output:</p>
<pre><code>&lt;p&gt;Some of these words &lt;em&gt;are emphasized&lt;/em&gt;.
Some of these words &lt;em&gt;are emphasized also&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Use two asterisks for &lt;strong&gt;strong emphasis&lt;/strong&gt;.
Or, if you prefer, &lt;strong&gt;use two underscores instead&lt;/strong&gt;.&lt;/p&gt;
</code></pre>
<h2>Lists</h2>
<p>Unordered (bulleted) lists use asterisks, pluses, and hyphens (<code>*</code>,
<code>+</code>, and <code>-</code>) as list markers. These three markers are
interchangable; this:</p>
<pre><code>* Candy.
* Gum.
* Booze.
</code></pre>
<p>this:</p>
<pre><code>+ Candy.
+ Gum.
+ Booze.
</code></pre>
<p>and this:</p>
<pre><code>- Candy.
- Gum.
- Booze.
</code></pre>
<p>all produce the same output:</p>
<pre><code>&lt;ul&gt;
&lt;li&gt;Candy.&lt;/li&gt;
&lt;li&gt;Gum.&lt;/li&gt;
&lt;li&gt;Booze.&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<p>Ordered (numbered) lists use regular numbers, followed by periods, as
list markers:</p>
<pre><code>1. Red
2. Green
3. Blue
</code></pre>
<p>Output:</p>
<pre><code>&lt;ol&gt;
&lt;li&gt;Red&lt;/li&gt;
&lt;li&gt;Green&lt;/li&gt;
&lt;li&gt;Blue&lt;/li&gt;
&lt;/ol&gt;
</code></pre>
<p>If you put blank lines between items, you'll get <code>&lt;p&gt;</code> tags for the
list item text. You can create multi-paragraph list items by indenting
the paragraphs by 4 spaces or 1 tab:</p>
<pre><code>* A list item.
With multiple paragraphs.
* Another item in the list.
</code></pre>
<p>Output:</p>
<pre><code>&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A list item.&lt;/p&gt;
&lt;p&gt;With multiple paragraphs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another item in the list.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<h3>Links</h3>
<p>Markdown supports two styles for creating links: <em>inline</em> and
<em>reference</em>. With both styles, you use square brackets to delimit the
text you want to turn into a link.</p>
<p>Inline-style links use parentheses immediately after the link text.
For example:</p>
<pre><code>This is an [example link](http://example.com/).
</code></pre>
<p>Output:</p>
<pre><code>&lt;p&gt;This is an &lt;a href="http://example.com/"&gt;
example link&lt;/a&gt;.&lt;/p&gt;
</code></pre>
<p>Optionally, you may include a title attribute in the parentheses:</p>
<pre><code>This is an [example link](http://example.com/ "With a Title").
</code></pre>
<p>Output:</p>
<pre><code>&lt;p&gt;This is an &lt;a href="http://example.com/" title="With a Title"&gt;
example link&lt;/a&gt;.&lt;/p&gt;
</code></pre>
<p>Reference-style links allow you to refer to your links by names, which
you define elsewhere in your document:</p>
<pre><code>I get 10 times more traffic from [Google][1] than from
[Yahoo][2] or [MSN][3].
[1]: http://google.com/ "Google"
[2]: http://search.yahoo.com/ "Yahoo Search"
[3]: http://search.msn.com/ "MSN Search"
</code></pre>
<p>Output:</p>
<pre><code>&lt;p&gt;I get 10 times more traffic from &lt;a href="http://google.com/"
title="Google"&gt;Google&lt;/a&gt; than from &lt;a href="http://search.yahoo.com/"
title="Yahoo Search"&gt;Yahoo&lt;/a&gt; or &lt;a href="http://search.msn.com/"
title="MSN Search"&gt;MSN&lt;/a&gt;.&lt;/p&gt;
</code></pre>
<p>The title attribute is optional. Link names may contain letters,
numbers and spaces, but are <em>not</em> case sensitive:</p>
<pre><code>I start my morning with a cup of coffee and
[The New York Times][NY Times].
[ny times]: http://www.nytimes.com/
</code></pre>
<p>Output:</p>
<pre><code>&lt;p&gt;I start my morning with a cup of coffee and
&lt;a href="http://www.nytimes.com/"&gt;The New York Times&lt;/a&gt;.&lt;/p&gt;
</code></pre>
<h3>Images</h3>
<p>Image syntax is very much like link syntax.</p>
<p>Inline (titles are optional):</p>
<pre><code>![alt text](/path/to/img.jpg "Title")
</code></pre>
<p>Reference-style:</p>
<pre><code>![alt text][id]
[id]: /path/to/img.jpg "Title"
</code></pre>
<p>Both of the above examples produce the same output:</p>
<pre><code>&lt;img src="/path/to/img.jpg" alt="alt text" title="Title" /&gt;
</code></pre>
<h3>Code</h3>
<p>In a regular paragraph, you can create code span by wrapping text in
backtick quotes. Any ampersands (<code>&amp;</code>) and angle brackets (<code>&lt;</code> or
<code>&gt;</code>) will automatically be translated into HTML entities. This makes
it easy to use Markdown to write about HTML example code:</p>
<pre><code>I strongly recommend against using any `&lt;blink&gt;` tags.
I wish SmartyPants used named entities like `&amp;mdash;`
instead of decimal-encoded entites like `&amp;#8212;`.
</code></pre>
<p>Output:</p>
<pre><code>&lt;p&gt;I strongly recommend against using any
&lt;code&gt;&amp;lt;blink&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;
&lt;p&gt;I wish SmartyPants used named entities like
&lt;code&gt;&amp;amp;mdash;&lt;/code&gt; instead of decimal-encoded
entites like &lt;code&gt;&amp;amp;#8212;&lt;/code&gt;.&lt;/p&gt;
</code></pre>
<p>To specify an entire block of pre-formatted code, indent every line of
the block by 4 spaces or 1 tab. Just like with code spans, <code>&amp;</code>, <code>&lt;</code>,
and <code>&gt;</code> characters will be escaped automatically.</p>
<p>Markdown:</p>
<pre><code>If you want your page to validate under XHTML 1.0 Strict,
you've got to put paragraph tags in your blockquotes:
&lt;blockquote&gt;
&lt;p&gt;For example.&lt;/p&gt;
&lt;/blockquote&gt;
</code></pre>
<p>Output:</p>
<pre><code>&lt;p&gt;If you want your page to validate under XHTML 1.0 Strict,
you've got to put paragraph tags in your blockquotes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;blockquote&amp;gt;
&amp;lt;p&amp;gt;For example.&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</code></pre>

View File

@ -0,0 +1,888 @@
Markdown: Syntax
================
<ul id="ProjectSubmenu">
<li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
<li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li>
<li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li>
<li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
<li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
</ul>
* [Overview](#overview)
* [Philosophy](#philosophy)
* [Inline HTML](#html)
* [Automatic Escaping for Special Characters](#autoescape)
* [Block Elements](#block)
* [Paragraphs and Line Breaks](#p)
* [Headers](#header)
* [Blockquotes](#blockquote)
* [Lists](#list)
* [Code Blocks](#precode)
* [Horizontal Rules](#hr)
* [Span Elements](#span)
* [Links](#link)
* [Emphasis](#em)
* [Code](#code)
* [Images](#img)
* [Miscellaneous](#misc)
* [Backslash Escapes](#backslash)
* [Automatic Links](#autolink)
**Note:** This document is itself written using Markdown; you
can [see the source for it by adding '.text' to the URL][src].
[src]: /projects/markdown/syntax.text
* * *
<h2 id="overview">Overview</h2>
<h3 id="philosophy">Philosophy</h3>
Markdown is intended to be as easy-to-read and easy-to-write as is feasible.
Readability, however, is emphasized above all else. A Markdown-formatted
document should be publishable as-is, as plain text, without looking
like it's been marked up with tags or formatting instructions. While
Markdown's syntax has been influenced by several existing text-to-HTML
filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4],
[Grutatext] [5], and [EtText] [6] -- the single biggest source of
inspiration for Markdown's syntax is the format of plain text email.
[1]: http://docutils.sourceforge.net/mirror/setext.html
[2]: http://www.aaronsw.com/2002/atx/
[3]: http://textism.com/tools/textile/
[4]: http://docutils.sourceforge.net/rst.html
[5]: http://www.triptico.com/software/grutatxt.html
[6]: http://ettext.taint.org/doc/
To this end, Markdown's syntax is comprised entirely of punctuation
characters, which punctuation characters have been carefully chosen so
as to look like what they mean. E.g., asterisks around a word actually
look like \*emphasis\*. Markdown lists look like, well, lists. Even
blockquotes look like quoted passages of text, assuming you've ever
used email.
<h3 id="html">Inline HTML</h3>
Markdown's syntax is intended for one purpose: to be used as a
format for *writing* for the web.
Markdown is not a replacement for HTML, or even close to it. Its
syntax is very small, corresponding only to a very small subset of
HTML tags. The idea is *not* to create a syntax that makes it easier
to insert HTML tags. In my opinion, HTML tags are already easy to
insert. The idea for Markdown is to make it easy to read, write, and
edit prose. HTML is a *publishing* format; Markdown is a *writing*
format. Thus, Markdown's formatting syntax only addresses issues that
can be conveyed in plain text.
For any markup that is not covered by Markdown's syntax, you simply
use HTML itself. There's no need to preface it or delimit it to
indicate that you're switching from Markdown to HTML; you just use
the tags.
The only restrictions are that block-level HTML elements -- e.g. `<div>`,
`<table>`, `<pre>`, `<p>`, etc. -- must be separated from surrounding
content by blank lines, and the start and end tags of the block should
not be indented with tabs or spaces. Markdown is smart enough not
to add extra (unwanted) `<p>` tags around HTML block-level tags.
For example, to add an HTML table to a Markdown article:
This is a regular paragraph.
<table>
<tr>
<td>Foo</td>
</tr>
</table>
This is another regular paragraph.
Note that Markdown formatting syntax is not processed within block-level
HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an
HTML block.
Span-level HTML tags -- e.g. `<span>`, `<cite>`, or `<del>` -- can be
used anywhere in a Markdown paragraph, list item, or header. If you
want, you can even use HTML tags instead of Markdown formatting; e.g. if
you'd prefer to use HTML `<a>` or `<img>` tags instead of Markdown's
link or image syntax, go right ahead.
Unlike block-level HTML tags, Markdown syntax *is* processed within
span-level tags.
<h3 id="autoescape">Automatic Escaping for Special Characters</h3>
In HTML, there are two characters that demand special treatment: `<`
and `&`. Left angle brackets are used to start tags; ampersands are
used to denote HTML entities. If you want to use them as literal
characters, you must escape them as entities, e.g. `&lt;`, and
`&amp;`.
Ampersands in particular are bedeviling for web writers. If you want to
write about 'AT&T', you need to write '`AT&amp;T`'. You even need to
escape ampersands within URLs. Thus, if you want to link to:
http://images.google.com/images?num=30&q=larry+bird
you need to encode the URL as:
http://images.google.com/images?num=30&amp;q=larry+bird
in your anchor tag `href` attribute. Needless to say, this is easy to
forget, and is probably the single most common source of HTML validation
errors in otherwise well-marked-up web sites.
Markdown allows you to use these characters naturally, taking care of
all the necessary escaping for you. If you use an ampersand as part of
an HTML entity, it remains unchanged; otherwise it will be translated
into `&amp;`.
So, if you want to include a copyright symbol in your article, you can write:
&copy;
and Markdown will leave it alone. But if you write:
AT&T
Markdown will translate it to:
AT&amp;T
Similarly, because Markdown supports [inline HTML](#html), if you use
angle brackets as delimiters for HTML tags, Markdown will treat them as
such. But if you write:
4 < 5
Markdown will translate it to:
4 &lt; 5
However, inside Markdown code spans and blocks, angle brackets and
ampersands are *always* encoded automatically. This makes it easy to use
Markdown to write about HTML code. (As opposed to raw HTML, which is a
terrible format for writing about HTML syntax, because every single `<`
and `&` in your example code needs to be escaped.)
* * *
<h2 id="block">Block Elements</h2>
<h3 id="p">Paragraphs and Line Breaks</h3>
A paragraph is simply one or more consecutive lines of text, separated
by one or more blank lines. (A blank line is any line that looks like a
blank line -- a line containing nothing but spaces or tabs is considered
blank.) Normal paragraphs should not be intended with spaces or tabs.
The implication of the "one or more consecutive lines of text" rule is
that Markdown supports "hard-wrapped" text paragraphs. This differs
significantly from most other text-to-HTML formatters (including Movable
Type's "Convert Line Breaks" option) which translate every line break
character in a paragraph into a `<br />` tag.
When you *do* want to insert a `<br />` break tag using Markdown, you
end a line with two or more spaces, then type return.
Yes, this takes a tad more effort to create a `<br />`, but a simplistic
"every line break is a `<br />`" rule wouldn't work for Markdown.
Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l]
work best -- and look better -- when you format them with hard breaks.
[bq]: #blockquote
[l]: #list
<h3 id="header">Headers</h3>
Markdown supports two styles of headers, [Setext] [1] and [atx] [2].
Setext-style headers are "underlined" using equal signs (for first-level
headers) and dashes (for second-level headers). For example:
This is an H1
=============
This is an H2
-------------
Any number of underlining `=`'s or `-`'s will work.
Atx-style headers use 1-6 hash characters at the start of the line,
corresponding to header levels 1-6. For example:
# This is an H1
## This is an H2
###### This is an H6
Optionally, you may "close" atx-style headers. This is purely
cosmetic -- you can use this if you think it looks better. The
closing hashes don't even need to match the number of hashes
used to open the header. (The number of opening hashes
determines the header level.) :
# This is an H1 #
## This is an H2 ##
### This is an H3 ######
<h3 id="blockquote">Blockquotes</h3>
Markdown uses email-style `>` characters for blockquoting. If you're
familiar with quoting passages of text in an email message, then you
know how to create a blockquote in Markdown. It looks best if you hard
wrap the text and put a `>` before every line:
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
>
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
> id sem consectetuer libero luctus adipiscing.
Markdown allows you to be lazy and only put the `>` before the first
line of a hard-wrapped paragraph:
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.
Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
adding additional levels of `>`:
> This is the first level of quoting.
>
> > This is nested blockquote.
>
> Back to the first level.
Blockquotes can contain other Markdown elements, including headers, lists,
and code blocks:
> ## This is a header.
>
> 1. This is the first list item.
> 2. This is the second list item.
>
> Here's some example code:
>
> return shell_exec("echo $input | $markdown_script");
Any decent text editor should make email-style quoting easy. For
example, with BBEdit, you can make a selection and choose Increase
Quote Level from the Text menu.
<h3 id="list">Lists</h3>
Markdown supports ordered (numbered) and unordered (bulleted) lists.
Unordered lists use asterisks, pluses, and hyphens -- interchangably
-- as list markers:
* Red
* Green
* Blue
is equivalent to:
+ Red
+ Green
+ Blue
and:
- Red
- Green
- Blue
Ordered lists use numbers followed by periods:
1. Bird
2. McHale
3. Parish
It's important to note that the actual numbers you use to mark the
list have no effect on the HTML output Markdown produces. The HTML
Markdown produces from the above list is:
<ol>
<li>Bird</li>
<li>McHale</li>
<li>Parish</li>
</ol>
If you instead wrote the list in Markdown like this:
1. Bird
1. McHale
1. Parish
or even:
3. Bird
1. McHale
8. Parish
you'd get the exact same HTML output. The point is, if you want to,
you can use ordinal numbers in your ordered Markdown lists, so that
the numbers in your source match the numbers in your published HTML.
But if you want to be lazy, you don't have to.
If you do use lazy list numbering, however, you should still start the
list with the number 1. At some point in the future, Markdown may support
starting ordered lists at an arbitrary number.
List markers typically start at the left margin, but may be indented by
up to three spaces. List markers must be followed by one or more spaces
or a tab.
To make lists look nice, you can wrap items with hanging indents:
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.
But if you want to be lazy, you don't have to:
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.
If list items are separated by blank lines, Markdown will wrap the
items in `<p>` tags in the HTML output. For example, this input:
* Bird
* Magic
will turn into:
<ul>
<li>Bird</li>
<li>Magic</li>
</ul>
But this:
* Bird
* Magic
will turn into:
<ul>
<li><p>Bird</p></li>
<li><p>Magic</p></li>
</ul>
List items may consist of multiple paragraphs. Each subsequent
paragraph in a list item must be intended by either 4 spaces
or one tab:
1. This is a list item with two paragraphs. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit. Aliquam hendrerit
mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet
vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
sit amet velit.
2. Suspendisse id sem consectetuer libero luctus adipiscing.
It looks nice if you indent every line of the subsequent
paragraphs, but here again, Markdown will allow you to be
lazy:
* This is a list item with two paragraphs.
This is the second paragraph in the list item. You're
only required to indent the first line. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit.
* Another item in the same list.
To put a blockquote within a list item, the blockquote's `>`
delimiters need to be indented:
* A list item with a blockquote:
> This is a blockquote
> inside a list item.
To put a code block within a list item, the code block needs
to be indented *twice* -- 8 spaces or two tabs:
* A list item with a code block:
<code goes here>
It's worth noting that it's possible to trigger an ordered list by
accident, by writing something like this:
1986. What a great season.
In other words, a *number-period-space* sequence at the beginning of a
line. To avoid this, you can backslash-escape the period:
1986\. What a great season.
<h3 id="precode">Code Blocks</h3>
Pre-formatted code blocks are used for writing about programming or
markup source code. Rather than forming normal paragraphs, the lines
of a code block are interpreted literally. Markdown wraps a code block
in both `<pre>` and `<code>` tags.
To produce a code block in Markdown, simply indent every line of the
block by at least 4 spaces or 1 tab. For example, given this input:
This is a normal paragraph:
This is a code block.
Markdown will generate:
<p>This is a normal paragraph:</p>
<pre><code>This is a code block.
</code></pre>
One level of indentation -- 4 spaces or 1 tab -- is removed from each
line of the code block. For example, this:
Here is an example of AppleScript:
tell application "Foo"
beep
end tell
will turn into:
<p>Here is an example of AppleScript:</p>
<pre><code>tell application "Foo"
beep
end tell
</code></pre>
A code block continues until it reaches a line that is not indented
(or the end of the article).
Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)
are automatically converted into HTML entities. This makes it very
easy to include example HTML source code using Markdown -- just paste
it and indent it, and Markdown will handle the hassle of encoding the
ampersands and angle brackets. For example, this:
<div class="footer">
&copy; 2004 Foo Corporation
</div>
will turn into:
<pre><code>&lt;div class="footer"&gt;
&amp;copy; 2004 Foo Corporation
&lt;/div&gt;
</code></pre>
Regular Markdown syntax is not processed within code blocks. E.g.,
asterisks are just literal asterisks within a code block. This means
it's also easy to use Markdown to write about Markdown's own syntax.
<h3 id="hr">Horizontal Rules</h3>
You can produce a horizontal rule tag (`<hr />`) by placing three or
more hyphens, asterisks, or underscores on a line by themselves. If you
wish, you may use spaces between the hyphens or asterisks. Each of the
following lines will produce a horizontal rule:
* * *
***
*****
- - -
---------------------------------------
_ _ _
* * *
<h2 id="span">Span Elements</h2>
<h3 id="link">Links</h3>
Markdown supports two style of links: *inline* and *reference*.
In both styles, the link text is delimited by [square brackets].
To create an inline link, use a set of regular parentheses immediately
after the link text's closing square bracket. Inside the parentheses,
put the URL where you want the link to point, along with an *optional*
title for the link, surrounded in quotes. For example:
This is [an example](http://example.com/ "Title") inline link.
[This link](http://example.net/) has no title attribute.
Will produce:
<p>This is <a href="http://example.com/" title="Title">
an example</a> inline link.</p>
<p><a href="http://example.net/">This link</a> has no
title attribute.</p>
If you're referring to a local resource on the same server, you can
use relative paths:
See my [About](/about/) page for details.
Reference-style links use a second set of square brackets, inside
which you place a label of your choosing to identify the link:
This is [an example][id] reference-style link.
You can optionally use a space to separate the sets of brackets:
This is [an example] [id] reference-style link.
Then, anywhere in the document, you define your link label like this,
on a line by itself:
[id]: http://example.com/ "Optional Title Here"
That is:
* Square brackets containing the link identifier (optionally
indented from the left margin using up to three spaces);
* followed by a colon;
* followed by one or more spaces (or tabs);
* followed by the URL for the link;
* optionally followed by a title attribute for the link, enclosed
in double or single quotes.
The link URL may, optionally, be surrounded by angle brackets:
[id]: <http://example.com/> "Optional Title Here"
You can put the title attribute on the next line and use extra spaces
or tabs for padding, which tends to look better with longer URLs:
[id]: http://example.com/longish/path/to/resource/here
"Optional Title Here"
Link definitions are only used for creating links during Markdown
processing, and are stripped from your document in the HTML output.
Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links:
[link text][a]
[link text][A]
are equivalent.
The *implicit link name* shortcut allows you to omit the name of the
link, in which case the link text itself is used as the name.
Just use an empty set of square brackets -- e.g., to link the word
"Google" to the google.com web site, you could simply write:
[Google][]
And then define the link:
[Google]: http://google.com/
Because link names may contain spaces, this shortcut even works for
multiple words in the link text:
Visit [Daring Fireball][] for more information.
And then define the link:
[Daring Fireball]: http://daringfireball.net/
Link definitions can be placed anywhere in your Markdown document. I
tend to put them immediately after each paragraph in which they're
used, but if you want, you can put them all at the end of your
document, sort of like footnotes.
Here's an example of reference links in action:
I get 10 times more traffic from [Google] [1] than from
[Yahoo] [2] or [MSN] [3].
[1]: http://google.com/ "Google"
[2]: http://search.yahoo.com/ "Yahoo Search"
[3]: http://search.msn.com/ "MSN Search"
Using the implicit link name shortcut, you could instead write:
I get 10 times more traffic from [Google][] than from
[Yahoo][] or [MSN][].
[google]: http://google.com/ "Google"
[yahoo]: http://search.yahoo.com/ "Yahoo Search"
[msn]: http://search.msn.com/ "MSN Search"
Both of the above examples will produce the following HTML output:
<p>I get 10 times more traffic from <a href="http://google.com/"
title="Google">Google</a> than from
<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
For comparison, here is the same paragraph written using
Markdown's inline link style:
I get 10 times more traffic from [Google](http://google.com/ "Google")
than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
[MSN](http://search.msn.com/ "MSN Search").
The point of reference-style links is not that they're easier to
write. The point is that with reference-style links, your document
source is vastly more readable. Compare the above examples: using
reference-style links, the paragraph itself is only 81 characters
long; with inline-style links, it's 176 characters; and as raw HTML,
it's 234 characters. In the raw HTML, there's more markup than there
is text.
With Markdown's reference-style links, a source document much more
closely resembles the final output, as rendered in a browser. By
allowing you to move the markup-related metadata out of the paragraph,
you can add links without interrupting the narrative flow of your
prose.
<h3 id="em">Emphasis</h3>
Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
emphasis. Text wrapped with one `*` or `_` will be wrapped with an
HTML `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML
`<strong>` tag. E.g., this input:
*single asterisks*
_single underscores_
**double asterisks**
__double underscores__
will produce:
<em>single asterisks</em>
<em>single underscores</em>
<strong>double asterisks</strong>
<strong>double underscores</strong>
You can use whichever style you prefer; the lone restriction is that
the same character must be used to open and close an emphasis span.
Emphasis can be used in the middle of a word:
un*fucking*believable
But if you surround an `*` or `_` with spaces, it'll be treated as a
literal asterisk or underscore.
To produce a literal asterisk or underscore at a position where it
would otherwise be used as an emphasis delimiter, you can backslash
escape it:
\*this text is surrounded by literal asterisks\*
<h3 id="code">Code</h3>
To indicate a span of code, wrap it with backtick quotes (`` ` ``).
Unlike a pre-formatted code block, a code span indicates code within a
normal paragraph. For example:
Use the `printf()` function.
will produce:
<p>Use the <code>printf()</code> function.</p>
To include a literal backtick character within a code span, you can use
multiple backticks as the opening and closing delimiters:
``There is a literal backtick (`) here.``
which will produce this:
<p><code>There is a literal backtick (`) here.</code></p>
The backtick delimiters surrounding a code span may include spaces --
one after the opening, one before the closing. This allows you to place
literal backtick characters at the beginning or end of a code span:
A single backtick in a code span: `` ` ``
A backtick-delimited string in a code span: `` `foo` ``
will produce:
<p>A single backtick in a code span: <code>`</code></p>
<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
With a code span, ampersands and angle brackets are encoded as HTML
entities automatically, which makes it easy to include example HTML
tags. Markdown will turn this:
Please don't use any `<blink>` tags.
into:
<p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>
You can write this:
`&#8212;` is the decimal-encoded equivalent of `&mdash;`.
to produce:
<p><code>&amp;#8212;</code> is the decimal-encoded
equivalent of <code>&amp;mdash;</code>.</p>
<h3 id="img">Images</h3>
Admittedly, it's fairly difficult to devise a "natural" syntax for
placing images into a plain text document format.
Markdown uses an image syntax that is intended to resemble the syntax
for links, allowing for two styles: *inline* and *reference*.
Inline image syntax looks like this:
![Alt text](/path/to/img.jpg)
![Alt text](/path/to/img.jpg "Optional title")
That is:
* An exclamation mark: `!`;
* followed by a set of square brackets, containing the `alt`
attribute text for the image;
* followed by a set of parentheses, containing the URL or path to
the image, and an optional `title` attribute enclosed in double
or single quotes.
Reference-style image syntax looks like this:
![Alt text][id]
Where "id" is the name of a defined image reference. Image references
are defined using syntax identical to link references:
[id]: url/to/image "Optional title attribute"
As of this writing, Markdown has no syntax for specifying the
dimensions of an image; if this is important to you, you can simply
use regular HTML `<img>` tags.
* * *
<h2 id="misc">Miscellaneous</h2>
<h3 id="autolink">Automatic Links</h3>
Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:
<http://example.com/>
Markdown will turn this into:
<a href="http://example.com/">http://example.com/</a>
Automatic links for email addresses work similarly, except that
Markdown will also perform a bit of randomized decimal and hex
entity-encoding to help obscure your address from address-harvesting
spambots. For example, Markdown will turn this:
<address@example.com>
into something like this:
<a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;
&#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;
&#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61;
&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>
which will render in a browser as a clickable link to "address@example.com".
(This sort of entity-encoding trick will indeed fool many, if not
most, address-harvesting bots, but it definitely won't fool all of
them. It's better than nothing, but an address published in this way
will probably eventually start receiving spam.)
<h3 id="backslash">Backslash Escapes</h3>
Markdown allows you to use backslash escapes to generate literal
characters which would otherwise have special meaning in Markdown's
formatting syntax. For example, if you wanted to surround a word with
literal asterisks (instead of an HTML `<em>` tag), you can backslashes
before the asterisks, like this:
\*literal asterisks\*
Markdown provides backslash escapes for the following characters:
\ backslash
` backtick
* asterisk
_ underscore
{} curly braces
[] square brackets
() parentheses
# hash mark
+ plus sign
- minus sign (hyphen)
. dot
! exclamation mark

View File

@ -0,0 +1,942 @@
<h1>Markdown: Syntax</h1>
<ul id="ProjectSubmenu">
<li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
<li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li>
<li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li>
<li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
<li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
</ul>
<ul>
<li><a href="#overview">Overview</a>
<ul>
<li><a href="#philosophy">Philosophy</a></li>
<li><a href="#html">Inline HTML</a></li>
<li><a href="#autoescape">Automatic Escaping for Special Characters</a></li>
</ul></li>
<li><a href="#block">Block Elements</a>
<ul>
<li><a href="#p">Paragraphs and Line Breaks</a></li>
<li><a href="#header">Headers</a></li>
<li><a href="#blockquote">Blockquotes</a></li>
<li><a href="#list">Lists</a></li>
<li><a href="#precode">Code Blocks</a></li>
<li><a href="#hr">Horizontal Rules</a></li>
</ul></li>
<li><a href="#span">Span Elements</a>
<ul>
<li><a href="#link">Links</a></li>
<li><a href="#em">Emphasis</a></li>
<li><a href="#code">Code</a></li>
<li><a href="#img">Images</a></li>
</ul></li>
<li><a href="#misc">Miscellaneous</a>
<ul>
<li><a href="#backslash">Backslash Escapes</a></li>
<li><a href="#autolink">Automatic Links</a></li>
</ul></li>
</ul>
<p><strong>Note:</strong> This document is itself written using Markdown; you
can <a href="/projects/markdown/syntax.text">see the source for it by adding '.text' to the URL</a>.</p>
<hr />
<h2 id="overview">Overview</h2>
<h3 id="philosophy">Philosophy</h3>
<p>Markdown is intended to be as easy-to-read and easy-to-write as is feasible.</p>
<p>Readability, however, is emphasized above all else. A Markdown-formatted
document should be publishable as-is, as plain text, without looking
like it's been marked up with tags or formatting instructions. While
Markdown's syntax has been influenced by several existing text-to-HTML
filters -- including <a href="http://docutils.sourceforge.net/mirror/setext.html">Setext</a>, <a href="http://www.aaronsw.com/2002/atx/">atx</a>, <a href="http://textism.com/tools/textile/">Textile</a>, <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>,
<a href="http://www.triptico.com/software/grutatxt.html">Grutatext</a>, and <a href="http://ettext.taint.org/doc/">EtText</a> -- the single biggest source of
inspiration for Markdown's syntax is the format of plain text email.</p>
<p>To this end, Markdown's syntax is comprised entirely of punctuation
characters, which punctuation characters have been carefully chosen so
as to look like what they mean. E.g., asterisks around a word actually
look like *emphasis*. Markdown lists look like, well, lists. Even
blockquotes look like quoted passages of text, assuming you've ever
used email.</p>
<h3 id="html">Inline HTML</h3>
<p>Markdown's syntax is intended for one purpose: to be used as a
format for <em>writing</em> for the web.</p>
<p>Markdown is not a replacement for HTML, or even close to it. Its
syntax is very small, corresponding only to a very small subset of
HTML tags. The idea is <em>not</em> to create a syntax that makes it easier
to insert HTML tags. In my opinion, HTML tags are already easy to
insert. The idea for Markdown is to make it easy to read, write, and
edit prose. HTML is a <em>publishing</em> format; Markdown is a <em>writing</em>
format. Thus, Markdown's formatting syntax only addresses issues that
can be conveyed in plain text.</p>
<p>For any markup that is not covered by Markdown's syntax, you simply
use HTML itself. There's no need to preface it or delimit it to
indicate that you're switching from Markdown to HTML; you just use
the tags.</p>
<p>The only restrictions are that block-level HTML elements -- e.g. <code>&lt;div&gt;</code>,
<code>&lt;table&gt;</code>, <code>&lt;pre&gt;</code>, <code>&lt;p&gt;</code>, etc. -- must be separated from surrounding
content by blank lines, and the start and end tags of the block should
not be indented with tabs or spaces. Markdown is smart enough not
to add extra (unwanted) <code>&lt;p&gt;</code> tags around HTML block-level tags.</p>
<p>For example, to add an HTML table to a Markdown article:</p>
<pre><code>This is a regular paragraph.
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;Foo&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
This is another regular paragraph.
</code></pre>
<p>Note that Markdown formatting syntax is not processed within block-level
HTML tags. E.g., you can't use Markdown-style <code>*emphasis*</code> inside an
HTML block.</p>
<p>Span-level HTML tags -- e.g. <code>&lt;span&gt;</code>, <code>&lt;cite&gt;</code>, or <code>&lt;del&gt;</code> -- can be
used anywhere in a Markdown paragraph, list item, or header. If you
want, you can even use HTML tags instead of Markdown formatting; e.g. if
you'd prefer to use HTML <code>&lt;a&gt;</code> or <code>&lt;img&gt;</code> tags instead of Markdown's
link or image syntax, go right ahead.</p>
<p>Unlike block-level HTML tags, Markdown syntax <em>is</em> processed within
span-level tags.</p>
<h3 id="autoescape">Automatic Escaping for Special Characters</h3>
<p>In HTML, there are two characters that demand special treatment: <code>&lt;</code>
and <code>&amp;</code>. Left angle brackets are used to start tags; ampersands are
used to denote HTML entities. If you want to use them as literal
characters, you must escape them as entities, e.g. <code>&amp;lt;</code>, and
<code>&amp;amp;</code>.</p>
<p>Ampersands in particular are bedeviling for web writers. If you want to
write about 'AT&amp;T', you need to write '<code>AT&amp;amp;T</code>'. You even need to
escape ampersands within URLs. Thus, if you want to link to:</p>
<pre><code>http://images.google.com/images?num=30&amp;q=larry+bird
</code></pre>
<p>you need to encode the URL as:</p>
<pre><code>http://images.google.com/images?num=30&amp;amp;q=larry+bird
</code></pre>
<p>in your anchor tag <code>href</code> attribute. Needless to say, this is easy to
forget, and is probably the single most common source of HTML validation
errors in otherwise well-marked-up web sites.</p>
<p>Markdown allows you to use these characters naturally, taking care of
all the necessary escaping for you. If you use an ampersand as part of
an HTML entity, it remains unchanged; otherwise it will be translated
into <code>&amp;amp;</code>.</p>
<p>So, if you want to include a copyright symbol in your article, you can write:</p>
<pre><code>&amp;copy;
</code></pre>
<p>and Markdown will leave it alone. But if you write:</p>
<pre><code>AT&amp;T
</code></pre>
<p>Markdown will translate it to:</p>
<pre><code>AT&amp;amp;T
</code></pre>
<p>Similarly, because Markdown supports <a href="#html">inline HTML</a>, if you use
angle brackets as delimiters for HTML tags, Markdown will treat them as
such. But if you write:</p>
<pre><code>4 &lt; 5
</code></pre>
<p>Markdown will translate it to:</p>
<pre><code>4 &amp;lt; 5
</code></pre>
<p>However, inside Markdown code spans and blocks, angle brackets and
ampersands are <em>always</em> encoded automatically. This makes it easy to use
Markdown to write about HTML code. (As opposed to raw HTML, which is a
terrible format for writing about HTML syntax, because every single <code>&lt;</code>
and <code>&amp;</code> in your example code needs to be escaped.)</p>
<hr />
<h2 id="block">Block Elements</h2>
<h3 id="p">Paragraphs and Line Breaks</h3>
<p>A paragraph is simply one or more consecutive lines of text, separated
by one or more blank lines. (A blank line is any line that looks like a
blank line -- a line containing nothing but spaces or tabs is considered
blank.) Normal paragraphs should not be intended with spaces or tabs.</p>
<p>The implication of the "one or more consecutive lines of text" rule is
that Markdown supports "hard-wrapped" text paragraphs. This differs
significantly from most other text-to-HTML formatters (including Movable
Type's "Convert Line Breaks" option) which translate every line break
character in a paragraph into a <code>&lt;br /&gt;</code> tag.</p>
<p>When you <em>do</em> want to insert a <code>&lt;br /&gt;</code> break tag using Markdown, you
end a line with two or more spaces, then type return.</p>
<p>Yes, this takes a tad more effort to create a <code>&lt;br /&gt;</code>, but a simplistic
"every line break is a <code>&lt;br /&gt;</code>" rule wouldn't work for Markdown.
Markdown's email-style <a href="#blockquote">blockquoting</a> and multi-paragraph <a href="#list">list items</a>
work best -- and look better -- when you format them with hard breaks.</p>
<h3 id="header">Headers</h3>
<p>Markdown supports two styles of headers, <a href="http://docutils.sourceforge.net/mirror/setext.html">Setext</a> and <a href="http://www.aaronsw.com/2002/atx/">atx</a>.</p>
<p>Setext-style headers are "underlined" using equal signs (for first-level
headers) and dashes (for second-level headers). For example:</p>
<pre><code>This is an H1
=============
This is an H2
-------------
</code></pre>
<p>Any number of underlining <code>=</code>'s or <code>-</code>'s will work.</p>
<p>Atx-style headers use 1-6 hash characters at the start of the line,
corresponding to header levels 1-6. For example:</p>
<pre><code># This is an H1
## This is an H2
###### This is an H6
</code></pre>
<p>Optionally, you may "close" atx-style headers. This is purely
cosmetic -- you can use this if you think it looks better. The
closing hashes don't even need to match the number of hashes
used to open the header. (The number of opening hashes
determines the header level.) :</p>
<pre><code># This is an H1 #
## This is an H2 ##
### This is an H3 ######
</code></pre>
<h3 id="blockquote">Blockquotes</h3>
<p>Markdown uses email-style <code>&gt;</code> characters for blockquoting. If you're
familiar with quoting passages of text in an email message, then you
know how to create a blockquote in Markdown. It looks best if you hard
wrap the text and put a <code>&gt;</code> before every line:</p>
<pre><code>&gt; This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
&gt; consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
&gt; Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
&gt;
&gt; Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
&gt; id sem consectetuer libero luctus adipiscing.
</code></pre>
<p>Markdown allows you to be lazy and only put the <code>&gt;</code> before the first
line of a hard-wrapped paragraph:</p>
<pre><code>&gt; This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
&gt; Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.
</code></pre>
<p>Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
adding additional levels of <code>&gt;</code>:</p>
<pre><code>&gt; This is the first level of quoting.
&gt;
&gt; &gt; This is nested blockquote.
&gt;
&gt; Back to the first level.
</code></pre>
<p>Blockquotes can contain other Markdown elements, including headers, lists,
and code blocks:</p>
<pre><code>&gt; ## This is a header.
&gt;
&gt; 1. This is the first list item.
&gt; 2. This is the second list item.
&gt;
&gt; Here's some example code:
&gt;
&gt; return shell_exec("echo $input | $markdown_script");
</code></pre>
<p>Any decent text editor should make email-style quoting easy. For
example, with BBEdit, you can make a selection and choose Increase
Quote Level from the Text menu.</p>
<h3 id="list">Lists</h3>
<p>Markdown supports ordered (numbered) and unordered (bulleted) lists.</p>
<p>Unordered lists use asterisks, pluses, and hyphens -- interchangably
-- as list markers:</p>
<pre><code>* Red
* Green
* Blue
</code></pre>
<p>is equivalent to:</p>
<pre><code>+ Red
+ Green
+ Blue
</code></pre>
<p>and:</p>
<pre><code>- Red
- Green
- Blue
</code></pre>
<p>Ordered lists use numbers followed by periods:</p>
<pre><code>1. Bird
2. McHale
3. Parish
</code></pre>
<p>It's important to note that the actual numbers you use to mark the
list have no effect on the HTML output Markdown produces. The HTML
Markdown produces from the above list is:</p>
<pre><code>&lt;ol&gt;
&lt;li&gt;Bird&lt;/li&gt;
&lt;li&gt;McHale&lt;/li&gt;
&lt;li&gt;Parish&lt;/li&gt;
&lt;/ol&gt;
</code></pre>
<p>If you instead wrote the list in Markdown like this:</p>
<pre><code>1. Bird
1. McHale
1. Parish
</code></pre>
<p>or even:</p>
<pre><code>3. Bird
1. McHale
8. Parish
</code></pre>
<p>you'd get the exact same HTML output. The point is, if you want to,
you can use ordinal numbers in your ordered Markdown lists, so that
the numbers in your source match the numbers in your published HTML.
But if you want to be lazy, you don't have to.</p>
<p>If you do use lazy list numbering, however, you should still start the
list with the number 1. At some point in the future, Markdown may support
starting ordered lists at an arbitrary number.</p>
<p>List markers typically start at the left margin, but may be indented by
up to three spaces. List markers must be followed by one or more spaces
or a tab.</p>
<p>To make lists look nice, you can wrap items with hanging indents:</p>
<pre><code>* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.
</code></pre>
<p>But if you want to be lazy, you don't have to:</p>
<pre><code>* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.
</code></pre>
<p>If list items are separated by blank lines, Markdown will wrap the
items in <code>&lt;p&gt;</code> tags in the HTML output. For example, this input:</p>
<pre><code>* Bird
* Magic
</code></pre>
<p>will turn into:</p>
<pre><code>&lt;ul&gt;
&lt;li&gt;Bird&lt;/li&gt;
&lt;li&gt;Magic&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<p>But this:</p>
<pre><code>* Bird
* Magic
</code></pre>
<p>will turn into:</p>
<pre><code>&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Bird&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Magic&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<p>List items may consist of multiple paragraphs. Each subsequent
paragraph in a list item must be intended by either 4 spaces
or one tab:</p>
<pre><code>1. This is a list item with two paragraphs. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit. Aliquam hendrerit
mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet
vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
sit amet velit.
2. Suspendisse id sem consectetuer libero luctus adipiscing.
</code></pre>
<p>It looks nice if you indent every line of the subsequent
paragraphs, but here again, Markdown will allow you to be
lazy:</p>
<pre><code>* This is a list item with two paragraphs.
This is the second paragraph in the list item. You're
only required to indent the first line. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit.
* Another item in the same list.
</code></pre>
<p>To put a blockquote within a list item, the blockquote's <code>&gt;</code>
delimiters need to be indented:</p>
<pre><code>* A list item with a blockquote:
&gt; This is a blockquote
&gt; inside a list item.
</code></pre>
<p>To put a code block within a list item, the code block needs
to be indented <em>twice</em> -- 8 spaces or two tabs:</p>
<pre><code>* A list item with a code block:
&lt;code goes here&gt;
</code></pre>
<p>It's worth noting that it's possible to trigger an ordered list by
accident, by writing something like this:</p>
<pre><code>1986. What a great season.
</code></pre>
<p>In other words, a <em>number-period-space</em> sequence at the beginning of a
line. To avoid this, you can backslash-escape the period:</p>
<pre><code>1986\. What a great season.
</code></pre>
<h3 id="precode">Code Blocks</h3>
<p>Pre-formatted code blocks are used for writing about programming or
markup source code. Rather than forming normal paragraphs, the lines
of a code block are interpreted literally. Markdown wraps a code block
in both <code>&lt;pre&gt;</code> and <code>&lt;code&gt;</code> tags.</p>
<p>To produce a code block in Markdown, simply indent every line of the
block by at least 4 spaces or 1 tab. For example, given this input:</p>
<pre><code>This is a normal paragraph:
This is a code block.
</code></pre>
<p>Markdown will generate:</p>
<pre><code>&lt;p&gt;This is a normal paragraph:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;This is a code block.
&lt;/code&gt;&lt;/pre&gt;
</code></pre>
<p>One level of indentation -- 4 spaces or 1 tab -- is removed from each
line of the code block. For example, this:</p>
<pre><code>Here is an example of AppleScript:
tell application "Foo"
beep
end tell
</code></pre>
<p>will turn into:</p>
<pre><code>&lt;p&gt;Here is an example of AppleScript:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tell application "Foo"
beep
end tell
&lt;/code&gt;&lt;/pre&gt;
</code></pre>
<p>A code block continues until it reaches a line that is not indented
(or the end of the article).</p>
<p>Within a code block, ampersands (<code>&amp;</code>) and angle brackets (<code>&lt;</code> and <code>&gt;</code>)
are automatically converted into HTML entities. This makes it very
easy to include example HTML source code using Markdown -- just paste
it and indent it, and Markdown will handle the hassle of encoding the
ampersands and angle brackets. For example, this:</p>
<pre><code> &lt;div class="footer"&gt;
&amp;copy; 2004 Foo Corporation
&lt;/div&gt;
</code></pre>
<p>will turn into:</p>
<pre><code>&lt;pre&gt;&lt;code&gt;&amp;lt;div class="footer"&amp;gt;
&amp;amp;copy; 2004 Foo Corporation
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</code></pre>
<p>Regular Markdown syntax is not processed within code blocks. E.g.,
asterisks are just literal asterisks within a code block. This means
it's also easy to use Markdown to write about Markdown's own syntax.</p>
<h3 id="hr">Horizontal Rules</h3>
<p>You can produce a horizontal rule tag (<code>&lt;hr /&gt;</code>) by placing three or
more hyphens, asterisks, or underscores on a line by themselves. If you
wish, you may use spaces between the hyphens or asterisks. Each of the
following lines will produce a horizontal rule:</p>
<pre><code>* * *
***
*****
- - -
---------------------------------------
_ _ _
</code></pre>
<hr />
<h2 id="span">Span Elements</h2>
<h3 id="link">Links</h3>
<p>Markdown supports two style of links: <em>inline</em> and <em>reference</em>.</p>
<p>In both styles, the link text is delimited by [square brackets].</p>
<p>To create an inline link, use a set of regular parentheses immediately
after the link text's closing square bracket. Inside the parentheses,
put the URL where you want the link to point, along with an <em>optional</em>
title for the link, surrounded in quotes. For example:</p>
<pre><code>This is [an example](http://example.com/ "Title") inline link.
[This link](http://example.net/) has no title attribute.
</code></pre>
<p>Will produce:</p>
<pre><code>&lt;p&gt;This is &lt;a href="http://example.com/" title="Title"&gt;
an example&lt;/a&gt; inline link.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://example.net/"&gt;This link&lt;/a&gt; has no
title attribute.&lt;/p&gt;
</code></pre>
<p>If you're referring to a local resource on the same server, you can
use relative paths:</p>
<pre><code>See my [About](/about/) page for details.
</code></pre>
<p>Reference-style links use a second set of square brackets, inside
which you place a label of your choosing to identify the link:</p>
<pre><code>This is [an example][id] reference-style link.
</code></pre>
<p>You can optionally use a space to separate the sets of brackets:</p>
<pre><code>This is [an example] [id] reference-style link.
</code></pre>
<p>Then, anywhere in the document, you define your link label like this,
on a line by itself:</p>
<pre><code>[id]: http://example.com/ "Optional Title Here"
</code></pre>
<p>That is:</p>
<ul>
<li>Square brackets containing the link identifier (optionally
indented from the left margin using up to three spaces);</li>
<li>followed by a colon;</li>
<li>followed by one or more spaces (or tabs);</li>
<li>followed by the URL for the link;</li>
<li>optionally followed by a title attribute for the link, enclosed
in double or single quotes.</li>
</ul>
<p>The link URL may, optionally, be surrounded by angle brackets:</p>
<pre><code>[id]: &lt;http://example.com/&gt; "Optional Title Here"
</code></pre>
<p>You can put the title attribute on the next line and use extra spaces
or tabs for padding, which tends to look better with longer URLs:</p>
<pre><code>[id]: http://example.com/longish/path/to/resource/here
"Optional Title Here"
</code></pre>
<p>Link definitions are only used for creating links during Markdown
processing, and are stripped from your document in the HTML output.</p>
<p>Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are <em>not</em> case sensitive. E.g. these two links:</p>
<pre><code>[link text][a]
[link text][A]
</code></pre>
<p>are equivalent.</p>
<p>The <em>implicit link name</em> shortcut allows you to omit the name of the
link, in which case the link text itself is used as the name.
Just use an empty set of square brackets -- e.g., to link the word
"Google" to the google.com web site, you could simply write:</p>
<pre><code>[Google][]
</code></pre>
<p>And then define the link:</p>
<pre><code>[Google]: http://google.com/
</code></pre>
<p>Because link names may contain spaces, this shortcut even works for
multiple words in the link text:</p>
<pre><code>Visit [Daring Fireball][] for more information.
</code></pre>
<p>And then define the link:</p>
<pre><code>[Daring Fireball]: http://daringfireball.net/
</code></pre>
<p>Link definitions can be placed anywhere in your Markdown document. I
tend to put them immediately after each paragraph in which they're
used, but if you want, you can put them all at the end of your
document, sort of like footnotes.</p>
<p>Here's an example of reference links in action:</p>
<pre><code>I get 10 times more traffic from [Google] [1] than from
[Yahoo] [2] or [MSN] [3].
[1]: http://google.com/ "Google"
[2]: http://search.yahoo.com/ "Yahoo Search"
[3]: http://search.msn.com/ "MSN Search"
</code></pre>
<p>Using the implicit link name shortcut, you could instead write:</p>
<pre><code>I get 10 times more traffic from [Google][] than from
[Yahoo][] or [MSN][].
[google]: http://google.com/ "Google"
[yahoo]: http://search.yahoo.com/ "Yahoo Search"
[msn]: http://search.msn.com/ "MSN Search"
</code></pre>
<p>Both of the above examples will produce the following HTML output:</p>
<pre><code>&lt;p&gt;I get 10 times more traffic from &lt;a href="http://google.com/"
title="Google"&gt;Google&lt;/a&gt; than from
&lt;a href="http://search.yahoo.com/" title="Yahoo Search"&gt;Yahoo&lt;/a&gt;
or &lt;a href="http://search.msn.com/" title="MSN Search"&gt;MSN&lt;/a&gt;.&lt;/p&gt;
</code></pre>
<p>For comparison, here is the same paragraph written using
Markdown's inline link style:</p>
<pre><code>I get 10 times more traffic from [Google](http://google.com/ "Google")
than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
[MSN](http://search.msn.com/ "MSN Search").
</code></pre>
<p>The point of reference-style links is not that they're easier to
write. The point is that with reference-style links, your document
source is vastly more readable. Compare the above examples: using
reference-style links, the paragraph itself is only 81 characters
long; with inline-style links, it's 176 characters; and as raw HTML,
it's 234 characters. In the raw HTML, there's more markup than there
is text.</p>
<p>With Markdown's reference-style links, a source document much more
closely resembles the final output, as rendered in a browser. By
allowing you to move the markup-related metadata out of the paragraph,
you can add links without interrupting the narrative flow of your
prose.</p>
<h3 id="em">Emphasis</h3>
<p>Markdown treats asterisks (<code>*</code>) and underscores (<code>_</code>) as indicators of
emphasis. Text wrapped with one <code>*</code> or <code>_</code> will be wrapped with an
HTML <code>&lt;em&gt;</code> tag; double <code>*</code>'s or <code>_</code>'s will be wrapped with an HTML
<code>&lt;strong&gt;</code> tag. E.g., this input:</p>
<pre><code>*single asterisks*
_single underscores_
**double asterisks**
__double underscores__
</code></pre>
<p>will produce:</p>
<pre><code>&lt;em&gt;single asterisks&lt;/em&gt;
&lt;em&gt;single underscores&lt;/em&gt;
&lt;strong&gt;double asterisks&lt;/strong&gt;
&lt;strong&gt;double underscores&lt;/strong&gt;
</code></pre>
<p>You can use whichever style you prefer; the lone restriction is that
the same character must be used to open and close an emphasis span.</p>
<p>Emphasis can be used in the middle of a word:</p>
<pre><code>un*fucking*believable
</code></pre>
<p>But if you surround an <code>*</code> or <code>_</code> with spaces, it'll be treated as a
literal asterisk or underscore.</p>
<p>To produce a literal asterisk or underscore at a position where it
would otherwise be used as an emphasis delimiter, you can backslash
escape it:</p>
<pre><code>\*this text is surrounded by literal asterisks\*
</code></pre>
<h3 id="code">Code</h3>
<p>To indicate a span of code, wrap it with backtick quotes (<code>`</code>).
Unlike a pre-formatted code block, a code span indicates code within a
normal paragraph. For example:</p>
<pre><code>Use the `printf()` function.
</code></pre>
<p>will produce:</p>
<pre><code>&lt;p&gt;Use the &lt;code&gt;printf()&lt;/code&gt; function.&lt;/p&gt;
</code></pre>
<p>To include a literal backtick character within a code span, you can use
multiple backticks as the opening and closing delimiters:</p>
<pre><code>``There is a literal backtick (`) here.``
</code></pre>
<p>which will produce this:</p>
<pre><code>&lt;p&gt;&lt;code&gt;There is a literal backtick (`) here.&lt;/code&gt;&lt;/p&gt;
</code></pre>
<p>The backtick delimiters surrounding a code span may include spaces --
one after the opening, one before the closing. This allows you to place
literal backtick characters at the beginning or end of a code span:</p>
<pre><code>A single backtick in a code span: `` ` ``
A backtick-delimited string in a code span: `` `foo` ``
</code></pre>
<p>will produce:</p>
<pre><code>&lt;p&gt;A single backtick in a code span: &lt;code&gt;`&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;A backtick-delimited string in a code span: &lt;code&gt;`foo`&lt;/code&gt;&lt;/p&gt;
</code></pre>
<p>With a code span, ampersands and angle brackets are encoded as HTML
entities automatically, which makes it easy to include example HTML
tags. Markdown will turn this:</p>
<pre><code>Please don't use any `&lt;blink&gt;` tags.
</code></pre>
<p>into:</p>
<pre><code>&lt;p&gt;Please don't use any &lt;code&gt;&amp;lt;blink&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;
</code></pre>
<p>You can write this:</p>
<pre><code>`&amp;#8212;` is the decimal-encoded equivalent of `&amp;mdash;`.
</code></pre>
<p>to produce:</p>
<pre><code>&lt;p&gt;&lt;code&gt;&amp;amp;#8212;&lt;/code&gt; is the decimal-encoded
equivalent of &lt;code&gt;&amp;amp;mdash;&lt;/code&gt;.&lt;/p&gt;
</code></pre>
<h3 id="img">Images</h3>
<p>Admittedly, it's fairly difficult to devise a "natural" syntax for
placing images into a plain text document format.</p>
<p>Markdown uses an image syntax that is intended to resemble the syntax
for links, allowing for two styles: <em>inline</em> and <em>reference</em>.</p>
<p>Inline image syntax looks like this:</p>
<pre><code>![Alt text](/path/to/img.jpg)
![Alt text](/path/to/img.jpg "Optional title")
</code></pre>
<p>That is:</p>
<ul>
<li>An exclamation mark: <code>!</code>;</li>
<li>followed by a set of square brackets, containing the <code>alt</code>
attribute text for the image;</li>
<li>followed by a set of parentheses, containing the URL or path to
the image, and an optional <code>title</code> attribute enclosed in double
or single quotes.</li>
</ul>
<p>Reference-style image syntax looks like this:</p>
<pre><code>![Alt text][id]
</code></pre>
<p>Where "id" is the name of a defined image reference. Image references
are defined using syntax identical to link references:</p>
<pre><code>[id]: url/to/image "Optional title attribute"
</code></pre>
<p>As of this writing, Markdown has no syntax for specifying the
dimensions of an image; if this is important to you, you can simply
use regular HTML <code>&lt;img&gt;</code> tags.</p>
<hr />
<h2 id="misc">Miscellaneous</h2>
<h3 id="autolink">Automatic Links</h3>
<p>Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:</p>
<pre><code>&lt;http://example.com/&gt;
</code></pre>
<p>Markdown will turn this into:</p>
<pre><code>&lt;a href="http://example.com/"&gt;http://example.com/&lt;/a&gt;
</code></pre>
<p>Automatic links for email addresses work similarly, except that
Markdown will also perform a bit of randomized decimal and hex
entity-encoding to help obscure your address from address-harvesting
spambots. For example, Markdown will turn this:</p>
<pre><code>&lt;address@example.com&gt;
</code></pre>
<p>into something like this:</p>
<pre><code>&lt;a href="&amp;#x6D;&amp;#x61;i&amp;#x6C;&amp;#x74;&amp;#x6F;:&amp;#x61;&amp;#x64;&amp;#x64;&amp;#x72;&amp;#x65;
&amp;#115;&amp;#115;&amp;#64;&amp;#101;&amp;#120;&amp;#x61;&amp;#109;&amp;#x70;&amp;#x6C;e&amp;#x2E;&amp;#99;&amp;#111;
&amp;#109;"&gt;&amp;#x61;&amp;#x64;&amp;#x64;&amp;#x72;&amp;#x65;&amp;#115;&amp;#115;&amp;#64;&amp;#101;&amp;#120;&amp;#x61;
&amp;#109;&amp;#x70;&amp;#x6C;e&amp;#x2E;&amp;#99;&amp;#111;&amp;#109;&lt;/a&gt;
</code></pre>
<p>which will render in a browser as a clickable link to "address@example.com".</p>
<p>(This sort of entity-encoding trick will indeed fool many, if not
most, address-harvesting bots, but it definitely won't fool all of
them. It's better than nothing, but an address published in this way
will probably eventually start receiving spam.)</p>
<h3 id="backslash">Backslash Escapes</h3>
<p>Markdown allows you to use backslash escapes to generate literal
characters which would otherwise have special meaning in Markdown's
formatting syntax. For example, if you wanted to surround a word with
literal asterisks (instead of an HTML <code>&lt;em&gt;</code> tag), you can backslashes
before the asterisks, like this:</p>
<pre><code>\*literal asterisks\*
</code></pre>
<p>Markdown provides backslash escapes for the following characters:</p>
<pre><code>\ backslash
` backtick
* asterisk
_ underscore
{} curly braces
[] square brackets
() parentheses
# hash mark
+ plus sign
- minus sign (hyphen)
. dot
! exclamation mark
</code></pre>

View File

@ -0,0 +1,5 @@
> foo
>
> > bar
>
> foo

View File

@ -0,0 +1,9 @@
<blockquote>
<p>foo</p>
<blockquote>
<p>bar</p>
</blockquote>
<p>foo</p>
</blockquote>

View File

@ -0,0 +1,131 @@
## Unordered
Asterisks tight:
* asterisk 1
* asterisk 2
* asterisk 3
Asterisks loose:
* asterisk 1
* asterisk 2
* asterisk 3
* * *
Pluses tight:
+ Plus 1
+ Plus 2
+ Plus 3
Pluses loose:
+ Plus 1
+ Plus 2
+ Plus 3
* * *
Minuses tight:
- Minus 1
- Minus 2
- Minus 3
Minuses loose:
- Minus 1
- Minus 2
- Minus 3
## Ordered
Tight:
1. First
2. Second
3. Third
and:
1. One
2. Two
3. Three
Loose using tabs:
1. First
2. Second
3. Third
and using spaces:
1. One
2. Two
3. Three
Multiple paragraphs:
1. Item 1, graf one.
Item 2. graf two. The quick brown fox jumped over the lazy dog's
back.
2. Item 2.
3. Item 3.
## Nested
* Tab
* Tab
* Tab
Here's another:
1. First
2. Second:
* Fee
* Fie
* Foe
3. Third
Same thing but with paragraphs:
1. First
2. Second:
* Fee
* Fie
* Foe
3. Third
This was an error in Markdown 1.0.1:
* this
* sub
that

View File

@ -0,0 +1,148 @@
<h2>Unordered</h2>
<p>Asterisks tight:</p>
<ul>
<li>asterisk 1</li>
<li>asterisk 2</li>
<li>asterisk 3</li>
</ul>
<p>Asterisks loose:</p>
<ul>
<li><p>asterisk 1</p></li>
<li><p>asterisk 2</p></li>
<li><p>asterisk 3</p></li>
</ul>
<hr />
<p>Pluses tight:</p>
<ul>
<li>Plus 1</li>
<li>Plus 2</li>
<li>Plus 3</li>
</ul>
<p>Pluses loose:</p>
<ul>
<li><p>Plus 1</p></li>
<li><p>Plus 2</p></li>
<li><p>Plus 3</p></li>
</ul>
<hr />
<p>Minuses tight:</p>
<ul>
<li>Minus 1</li>
<li>Minus 2</li>
<li>Minus 3</li>
</ul>
<p>Minuses loose:</p>
<ul>
<li><p>Minus 1</p></li>
<li><p>Minus 2</p></li>
<li><p>Minus 3</p></li>
</ul>
<h2>Ordered</h2>
<p>Tight:</p>
<ol>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ol>
<p>and:</p>
<ol>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ol>
<p>Loose using tabs:</p>
<ol>
<li><p>First</p></li>
<li><p>Second</p></li>
<li><p>Third</p></li>
</ol>
<p>and using spaces:</p>
<ol>
<li><p>One</p></li>
<li><p>Two</p></li>
<li><p>Three</p></li>
</ol>
<p>Multiple paragraphs:</p>
<ol>
<li><p>Item 1, graf one.</p>
<p>Item 2. graf two. The quick brown fox jumped over the lazy dog's
back.</p></li>
<li><p>Item 2.</p></li>
<li><p>Item 3.</p></li>
</ol>
<h2>Nested</h2>
<ul>
<li>Tab
<ul>
<li>Tab
<ul>
<li>Tab</li>
</ul></li>
</ul></li>
</ul>
<p>Here's another:</p>
<ol>
<li>First</li>
<li>Second:
<ul>
<li>Fee</li>
<li>Fie</li>
<li>Foe</li>
</ul></li>
<li>Third</li>
</ol>
<p>Same thing but with paragraphs:</p>
<ol>
<li><p>First</p></li>
<li><p>Second:</p>
<ul>
<li>Fee</li>
<li>Fie</li>
<li>Foe</li>
</ul></li>
<li><p>Third</p></li>
</ol>
<p>This was an error in Markdown 1.0.1:</p>
<ul>
<li><p>this</p>
<ul><li>sub</li></ul>
<p>that</p></li>
</ul>

View File

@ -0,0 +1,7 @@
***This is strong and em.***
So is ***this*** word.
___This is strong and em.___
So is ___this___ word.

View File

@ -0,0 +1,7 @@
<p><strong><em>This is strong and em.</em></strong></p>
<p>So is <strong><em>this</em></strong> word.</p>
<p><strong><em>This is strong and em.</em></strong></p>
<p>So is <strong><em>this</em></strong> word.</p>

View File

@ -0,0 +1,21 @@
+ this is a list item
indented with tabs
+ this is a list item
indented with spaces
Code:
this code block is indented by one tab
And:
this code block is indented by two tabs
And:
+ this is an example list item
indented with tabs
+ this is an example list item
indented with spaces

View File

@ -0,0 +1,25 @@
<ul>
<li><p>this is a list item
indented with tabs</p></li>
<li><p>this is a list item
indented with spaces</p></li>
</ul>
<p>Code:</p>
<pre><code>this code block is indented by one tab
</code></pre>
<p>And:</p>
<pre><code> this code block is indented by two tabs
</code></pre>
<p>And:</p>
<pre><code>+ this is an example list item
indented with tabs
+ this is an example list item
indented with spaces
</code></pre>

View File

@ -0,0 +1,5 @@
> A list within a blockquote:
>
> * asterisk 1
> * asterisk 2
> * asterisk 3

View File

@ -0,0 +1,8 @@
<blockquote>
<p>A list within a blockquote:</p>
<ul>
<li>asterisk 1</li>
<li>asterisk 2</li>
<li>asterisk 3</li>
</ul>
</blockquote>

View File

@ -0,0 +1,31 @@
Some text about HTML, SGML and HTML4.
Let's talk about the U.S.A., (É.U. or É.-U. d'A. in French).
*[HTML4]: Hyper Text Markup Language version 4
*[HTML]: Hyper Text Markup Language
*[SGML]: Standard Generalized Markup Language
*[U.S.A.]: United States of America
*[É.U.] : États-Unis d'Amérique
*[É.-U. d'A.] : États-Unis d'Amérique
And here we have a CD, some CDs, and some other CD's.
*[CD]: Compact Disk
Let's transfert documents through TCP/IP, using TCP packets.
*[IP]: Internet Protocol
*[TCP]: Transmission Control Protocol
---
Bienvenue sur [CMS](http://www.bidulecms.com "Bidule CMS").
*[CMS]: Content Management System
---
ATCCE
*[ATCCE]: Abbreviation "Testing" Correct 'Character' < Escapes >

View File

@ -0,0 +1,15 @@
<p>Some text about <abbr title="Hyper Text Markup Language">HTML</abbr>, <abbr title="Standard Generalized Markup Language">SGML</abbr> and <abbr title="Hyper Text Markup Language version 4">HTML4</abbr>.</p>
<p>Let's talk about the <abbr title="United States of America">U.S.A.</abbr>, (<abbr title="États-Unis d'Amérique">É.U.</abbr> or <abbr title="États-Unis d'Amérique">É.-U. d'A.</abbr> in French).</p>
<p>And here we have a <abbr title="Compact Disk">CD</abbr>, some CDs, and some other <abbr title="Compact Disk">CD</abbr>'s.</p>
<p>Let's transfert documents through <abbr title="Transmission Control Protocol">TCP</abbr>/<abbr title="Internet Protocol">IP</abbr>, using <abbr title="Transmission Control Protocol">TCP</abbr> packets.</p>
<hr />
<p>Bienvenue sur <a href="http://www.bidulecms.com" title="Bidule CMS"><abbr title="Content Management System">CMS</abbr></a>.</p>
<hr />
<p><abbr title="Abbreviation &quot;Testing&quot; Correct 'Character' &lt; Escapes &gt;">ATCCE</abbr></p>

View File

@ -0,0 +1,69 @@
``` .html
<ul>
<li>Code block first in file</li>
<li>doesn't work under some circumstances</li>
</ul>
```
As above: checking for bad interractions with the HTML block parser:
``` html
<div>
```
Some *markdown* `formatting`.
``` html
</div>
```
Some *markdown*
```
<div>
<html>
```
```
function test();
```
<div markdown="1">
<html>
<title>
</div>
<div markdown="1">
```
<html>
<title>
```
</div>
Two code blocks with no blank line between them:
```
<div>
```
```
<div>
```
Testing *confusion* with code spans at the HTML block parser:
```
<div>```</div>
```
Testing mixing with title code blocks
```
<p>```
~~~
<p>```
```
~~~
<p>```
```
<p>```
~~~

View File

@ -0,0 +1,61 @@
<pre><code class="html">&lt;ul>
&lt;li>Code block first in file&lt;/li>
&lt;li>doesn't work under some circumstances&lt;/li>
&lt;/ul>
</code></pre>
<p>As above: checking for bad interractions with the HTML block parser:</p>
<pre><code class="html">&lt;div>
</code></pre>
<p>Some <em>markdown</em><code>formatting</code>.</p>
<pre><code class="html">&lt;/div>
</code></pre>
<p>Some <em>markdown</em></p>
<pre><code>&lt;div>
&lt;html>
</code></pre>
<pre><code>function test();
</code></pre>
<div>
<pre><code>&lt;html&gt;
&lt;title&gt;
</code></pre>
</div>
<div>
<pre><code>&lt;html&gt;
&lt;title&gt;
</code></pre>
</div>
<p>Two code blocks with no blank line between them:</p>
<pre><code>&lt;div&gt;
</code></pre>
<pre><code>&lt;div&gt;
</code></pre>
<p>Testing <em>confusion</em> with code spans at the HTML block parser:</p>
<pre><code>&lt;div>```&lt;/div>
</code></pre>
<p>Testing mixing with title code blocks</p>
<pre><code>&lt;p>```
~~~
&lt;p>```
</code></pre>
<pre><code>&lt;p>```
```
&lt;p>```
</code></pre>

View File

@ -0,0 +1,123 @@
```
<Fenced>
```
Code block starting and ending with empty lines:
```
<Fenced>
```
Indented code block containing fenced code block sample:
```
<Fenced>
```
Fenced code block with indented code block sample:
```
Some text
Indented code block sample code
```
Fenced code block with long markers:
``````````````````
Fenced
``````````````````
Fenced code block with fenced code block markers of different length in it:
````
In code block
```
Still in code block
`````
Still in code block
````
Fenced code block with Markdown header and horizontal rule:
```
#test
---
```
Fenced code block with link definitions, footnote definition and
abbreviation definitions:
```
[example]: http://example.com/
[^1]: Footnote def
*[HTML]: HyperText Markup Language
```
* In a list item with smalish indent:
`````
#!/bin/sh
#
# Preload driver binary
LD_PRELOAD=libusb-driver.so $0.bin $*
`````
With HTML content.
`````
<b>bold</b>
`````
Bug with block level elements in this case:
```
<div>
</div>
```
Indented code block of a fenced code block:
```
haha!
```
With class:
`````html
<b>bold</b>
`````
````` html
<b>bold</b>
`````
`````.html
<b>bold</b>
`````
````` .html
<b>bold</b>
`````
With extra attribute block:
`````{.html}
<b>bold</b>
`````
````` {.html #codeid}
<b>bold</b>
`````
````` .html{.bold}
<div>
`````
`````` .html {#codeid}
</div>
``````

View File

@ -0,0 +1,109 @@
<pre><code>&lt;Fenced>
</code></pre>
<p>Code block starting and ending with empty lines:</p>
<pre><code><br /><br />&lt;Fenced>
</code></pre>
<p>Indented code block containing fenced code block sample:</p>
<pre><code>```
&lt;Fenced>
```
</code></pre>
<p>Fenced code block with indented code block sample:</p>
<pre><code>Some text
Indented code block sample code
</code></pre>
<p>Fenced code block with long markers:</p>
<pre><code>Fenced
</code></pre>
<p>Fenced code block with fenced code block markers of different length in it:</p>
<pre><code>In code block
```
Still in code block
`````
Still in code block
</code></pre>
<p>Fenced code block with Markdown header and horizontal rule:</p>
<pre><code>#test
---
</code></pre>
<p>Fenced code block with link definitions, footnote definition and
abbreviation definitions:</p>
<pre><code>[example]: http://example.com/
[^1]: Footnote def
*[HTML]: HyperText Markup Language
</code></pre>
<ul>
<li><p>In a list item with smalish indent:</p>
<pre><code>#!/bin/sh
#
# Preload driver binary
LD_PRELOAD=libusb-driver.so $0.bin $*
</code></pre>
</li>
</ul>
<p>With HTML content.</p>
<pre><code>&lt;b>bold&lt;/b>
</code></pre>
<p>Bug with block level elements in this case:</p>
<pre><code> &lt;div>
&lt;/div>
</code></pre>
<p>Indented code block of a fenced code block:</p>
<pre><code>```
haha!
```
</code></pre>
<p>With class:</p>
<pre><code class="html">&lt;b>bold&lt;/b>
</code></pre>
<pre><code class="html">&lt;b>bold&lt;/b>
</code></pre>
<pre><code class="html">&lt;b>bold&lt;/b>
</code></pre>
<pre><code class="html">&lt;b>bold&lt;/b>
</code></pre>
<p>With extra attribute block:</p>
<pre><code class="html">&lt;b>bold&lt;/b>
</code></pre>
<pre><code class="html" id="codeid">&lt;b>bold&lt;/b>
</code></pre>
<pre><code class="html bold">&lt;div>
</code></pre>
<pre><code class="html" id="codeid">&lt;/div>
</code></pre>

View File

@ -0,0 +1,115 @@
A simple definition list:
Term 1
: Definition 1
Term 2
: Definition 2
With multiple terms:
Term 1
Term 2
: Definition 1
Term 3
Term 4
: Definition 2
With multiple definitions:
Term 1
: Definition 1
: Definition 2
Term 2
: Definition 3
: Definition 4
With multiple lines per definition:
Term 1
: Definition 1 line 1 ...
Definition 1 line 2
: Definition 2 line 1 ...
Definition 2 line 2
Term 2
: Definition 3 line 2 ...
Definition 3 line 2
: Definition 4 line 2 ...
Definition 4 line 2
With paragraphs:
Term 1
: Definition 1 (paragraph)
Term 2
: Definition 2 (paragraph)
With multiple paragraphs:
Term 1
: Definition 1 paragraph 1 line 1 ...
Definition 1 paragraph 1 line 2
Definition 1 paragraph 2 line 1 ...
Definition 1 paragraph 2 line 2
Term 2
: Definition 1 paragraph 1 line 1 ...
Definition 1 paragraph 1 line 2 (lazy)
Definition 1 paragraph 2 line 1 ...
Definition 1 paragraph 2 line 2 (lazy)
* * *
A mix:
Term 1
Term 2
: Definition 1 paragraph 1 line 1 ...
Definition 1 paragraph 1 line 2 (lazy)
Definition 1 paragraph 2 line 1 ...
Definition 1 paragraph 2 line 2
: Definition 2 paragraph 1 line 1 ...
Definition 2 paragraph 1 line 2 (lazy)
Term 3
: Definition 3 (no paragraph)
: Definition 4 (no paragraph)
: Definition 5 line 1 ...
Definition 5 line 2 (no paragraph)
: Definition 6 paragraph 1 line 1 ...
Definition 6 paragraph 1 line 2
: Definition 7 (no paragraph)
: Definition 8 paragraph 1 line 1 (forced paragraph) ...
Definition 8 paragraph 1 line 2
Definition 8 paragraph 2 line 1
Term 4
: Definition 9 paragraph 1 line 1 (forced paragraph) ...
Definition 9 paragraph 1 line 2
Definition 9 paragraph 2 line 1
: Definition 10 (no paragraph)
* * *
Special cases:
Term
: code block
as first element of a definition

View File

@ -0,0 +1,155 @@
<p>A simple definition list:</p>
<dl>
<dt>Term 1</dt>
<dd>Definition 1</dd>
<dt>Term 2</dt>
<dd>Definition 2</dd>
</dl>
<p>With multiple terms:</p>
<dl>
<dt>Term 1</dt>
<dt>Term 2</dt>
<dd>Definition 1</dd>
<dt>Term 3</dt>
<dt>Term 4</dt>
<dd>Definition 2</dd>
</dl>
<p>With multiple definitions:</p>
<dl>
<dt>Term 1</dt>
<dd>Definition 1</dd>
<dd>Definition 2</dd>
<dt>Term 2</dt>
<dd>Definition 3</dd>
<dd>Definition 4</dd>
</dl>
<p>With multiple lines per definition:</p>
<dl>
<dt>Term 1</dt>
<dd>Definition 1 line 1 ...
Definition 1 line 2</dd>
<dd>Definition 2 line 1 ...
Definition 2 line 2</dd>
<dt>Term 2</dt>
<dd>Definition 3 line 2 ...
Definition 3 line 2</dd>
<dd>Definition 4 line 2 ...
Definition 4 line 2</dd>
</dl>
<p>With paragraphs:</p>
<dl>
<dt>Term 1</dt>
<dd>
<p>Definition 1 (paragraph)</p>
</dd>
<dt>Term 2</dt>
<dd>
<p>Definition 2 (paragraph)</p>
</dd>
</dl>
<p>With multiple paragraphs:</p>
<dl>
<dt>Term 1</dt>
<dd>
<p>Definition 1 paragraph 1 line 1 ...
Definition 1 paragraph 1 line 2</p>
<p>Definition 1 paragraph 2 line 1 ...
Definition 1 paragraph 2 line 2</p>
</dd>
<dt>Term 2</dt>
<dd>
<p>Definition 1 paragraph 1 line 1 ...
Definition 1 paragraph 1 line 2 (lazy)</p>
<p>Definition 1 paragraph 2 line 1 ...
Definition 1 paragraph 2 line 2 (lazy)</p>
</dd>
</dl>
<hr />
<p>A mix:</p>
<dl>
<dt>Term 1</dt>
<dt>Term 2</dt>
<dd>
<p>Definition 1 paragraph 1 line 1 ...
Definition 1 paragraph 1 line 2 (lazy)</p>
<p>Definition 1 paragraph 2 line 1 ...
Definition 1 paragraph 2 line 2</p>
</dd>
<dd>
<p>Definition 2 paragraph 1 line 1 ...
Definition 2 paragraph 1 line 2 (lazy)</p>
</dd>
<dt>Term 3</dt>
<dd>Definition 3 (no paragraph)</dd>
<dd>Definition 4 (no paragraph)</dd>
<dd>Definition 5 line 1 ...
Definition 5 line 2 (no paragraph)</dd>
<dd>
<p>Definition 6 paragraph 1 line 1 ...
Definition 6 paragraph 1 line 2</p>
</dd>
<dd>Definition 7 (no paragraph)</dd>
<dd>
<p>Definition 8 paragraph 1 line 1 (forced paragraph) ...
Definition 8 paragraph 1 line 2</p>
<p>Definition 8 paragraph 2 line 1</p>
</dd>
<dt>Term 4</dt>
<dd>
<p>Definition 9 paragraph 1 line 1 (forced paragraph) ...
Definition 9 paragraph 1 line 2</p>
<p>Definition 9 paragraph 2 line 1</p>
</dd>
<dd>Definition 10 (no paragraph)</dd>
</dl>
<hr />
<p>Special cases:</p>
<dl>
<dt>Term</dt>
<dd>
<pre><code>code block
as first element of a definition
</code></pre>
</dd>
</dl>

View File

@ -0,0 +1,100 @@
Combined emphasis:
1. ***test test***
2. ___test test___
3. *test **test***
4. **test *test***
5. ***test* test**
6. ***test** test*
7. ***test* test**
8. **test *test***
9. *test **test***
10. _test __test___
11. __test _test___
12. ___test_ test__
13. ___test__ test_
14. ___test_ test__
15. __test _test___
16. _test __test___
17. *test __test__*
18. **test _test_**
19. **_test_ test**
20. *__test__ test*
21. **_test_ test**
22. **test _test_**
23. *test __test__*
24. _test **test**_
25. __test *test*__
26. __*test* test__
27. _**test** test_
28. __*test* test__
29. __test *test*__
30. _test **test**_
Incorrect nesting:
1. *test **test* test**
2. _test __test_ test__
3. **test *test** test*
4. __test _test__ test_
5. *test *test* test*
6. _test _test_ test_
7. **test **test** test**
8. __test __test__ test__
9. _**some text_**
10. *__some text*__
11. **_some text**_
12. *__some text*__
No emphasis:
1. test* test *test
2. test** test **test
3. test_ test _test
4. test__ test __test
Middle-word emphasis (asterisks):
1. *a*b
2. a*b*
3. a*b*c
4. **a**b
5. a**b**
6. a**b**c
Middle-word emphasis (underscore):
1. _a_b
2. a_b_
3. a_b_c
4. __a__b
5. a__b__
6. a__b__c
my_precious_file.txt
## Tricky Cases
E**. **Test** TestTestTest
E**. **Test** Test Test Test
## Overlong emphasis
Name: ____________
Organization: ____
Region/Country: __
_____Cut here_____
____Cut here____
# Regression
_**Note**_: This _is emphasis_.

View File

@ -0,0 +1,106 @@
<p>Combined emphasis:</p>
<ol>
<li><strong><em>test test</em></strong></li>
<li><strong><em>test test</em></strong></li>
<li><em>test <strong>test</strong></em></li>
<li><strong>test <em>test</em></strong></li>
<li><strong><em>test</em> test</strong></li>
<li><em><strong>test</strong> test</em></li>
<li><strong><em>test</em> test</strong></li>
<li><strong>test <em>test</em></strong></li>
<li><em>test <strong>test</strong></em></li>
<li><em>test <strong>test</strong></em></li>
<li><strong>test <em>test</em></strong></li>
<li><strong><em>test</em> test</strong></li>
<li><em><strong>test</strong> test</em></li>
<li><strong><em>test</em> test</strong></li>
<li><strong>test <em>test</em></strong></li>
<li><em>test <strong>test</strong></em></li>
<li><em>test <strong>test</strong></em></li>
<li><strong>test <em>test</em></strong></li>
<li><strong><em>test</em> test</strong></li>
<li><em><strong>test</strong> test</em></li>
<li><strong><em>test</em> test</strong></li>
<li><strong>test <em>test</em></strong></li>
<li><em>test <strong>test</strong></em></li>
<li><em>test <strong>test</strong></em></li>
<li><strong>test <em>test</em></strong></li>
<li><strong><em>test</em> test</strong></li>
<li><em><strong>test</strong> test</em></li>
<li><strong><em>test</em> test</strong></li>
<li><strong>test <em>test</em></strong></li>
<li><em>test <strong>test</strong></em></li>
</ol>
<p>Incorrect nesting:</p>
<ol>
<li>*test <strong>test* test</strong></li>
<li>_test <strong>test_ test</strong></li>
<li><strong>test *test</strong> test*</li>
<li><strong>test _test</strong> test_</li>
<li><em>test *test</em> test*</li>
<li><em>test _test</em> test_</li>
<li><strong>test **test</strong> test**</li>
<li><strong>test __test</strong> test__</li>
<li>_<strong>some text_</strong></li>
<li>*<strong>some text*</strong></li>
<li><strong>_some text</strong>_</li>
<li>*<strong>some text*</strong></li>
</ol>
<p>No emphasis:</p>
<ol>
<li>test* test *test</li>
<li>test** test **test</li>
<li>test_ test _test</li>
<li>test__ test __test</li>
</ol>
<p>Middle-word emphasis (asterisks):</p>
<ol>
<li><em>a</em>b</li>
<li>a<em>b</em></li>
<li>a<em>b</em>c</li>
<li><strong>a</strong>b</li>
<li>a<strong>b</strong></li>
<li>a<strong>b</strong>c</li>
</ol>
<p>Middle-word emphasis (underscore):</p>
<ol>
<li>_a_b</li>
<li>a_b_</li>
<li>a_b_c</li>
<li>__a__b</li>
<li>a__b__</li>
<li>a__b__c</li>
</ol>
<p>my_precious_file.txt</p>
<h2>Tricky Cases</h2>
<p>E**. <strong>Test</strong> TestTestTest</p>
<p>E**. <strong>Test</strong> Test Test Test</p>
<h2>Overlong emphasis</h2>
<p>Name: ____________<br />
Organization: ____<br />
Region/Country: __</p>
<p>_____Cut here_____</p>
<p>____Cut here____</p>
<h1>Regression</h1>
<p><em><strong>Note</strong></em>: This <em>is emphasis</em>.</p>

View File

@ -0,0 +1,70 @@
This is the first paragraph.[^first]
[^first]: This is the first note.
* List item one.[^second]
* List item two.[^third]
[^third]: This is the third note, defined out of order.
[^second]: This is the second note.
[^fourth]: This is the fourth note.
# Header[^fourth]
Some paragraph with a footnote[^1], and another[^2].
[^1]: Content for fifth footnote.
[^2]: Content for sixth footnote spaning on
three lines, with some span-level markup like
_emphasis_, a [link][].
[link]: http://michelf.ca/
Another paragraph with a named footnote[^fn-name].
[^fn-name]:
Footnote beginning on the line next to the marker.
This paragraph should not have a footnote marker since
the footnote is undefined.[^3]
This paragraph has a second footnote marker to footnote number one.[^1]
This paragraph links to a footnote with plenty of
block-level content.[^block]
[^block]:
Paragraph.
* List item
> Blockquote
Code block
This paragraph host the footnote reference within a
footnote test[^reference].
[^reference]:
This footnote has a footnote of its own.[^nested]
[^nested]:
This footnote should appear even though it is referenced
from another footnote. But [^reference] should be litteral
since the footnote with that name has already been used.
- - -
Testing unusual footnote name[^1$^!"'].
[^1$^!"']: Haha!
- - -
Footnotes mixed with images[^image-mixed]
![1800 Travel][img6]
![1830 Travel][img7]
[img6]: images/MGR-1800-travel.jpeg "Travel Speeds in 1800"
[^image-mixed]: Footnote Content
[img7]: images/MGR-1830-travel.jpeg "Travel Speeds in 1830"

View File

@ -0,0 +1,103 @@
<p>This is the first paragraph.<sup id="fnref:first"><a href="#fn:first" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<ul>
<li>List item one.<sup id="fnref:second"><a href="#fn:second" class="footnote-ref" role="doc-noteref">2</a></sup></li>
<li>List item two.<sup id="fnref:third"><a href="#fn:third" class="footnote-ref" role="doc-noteref">3</a></sup></li>
</ul>
<h1>Header<sup id="fnref:fourth"><a href="#fn:fourth" class="footnote-ref" role="doc-noteref">4</a></sup></h1>
<p>Some paragraph with a footnote<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">5</a></sup>, and another<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">6</a></sup>.</p>
<p>Another paragraph with a named footnote<sup id="fnref:fn-name"><a href="#fn:fn-name" class="footnote-ref" role="doc-noteref">7</a></sup>.</p>
<p>This paragraph should not have a footnote marker since
the footnote is undefined.[^3]</p>
<p>This paragraph has a second footnote marker to footnote number one.<sup id="fnref2:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">5</a></sup></p>
<p>This paragraph links to a footnote with plenty of
block-level content.<sup id="fnref:block"><a href="#fn:block" class="footnote-ref" role="doc-noteref">8</a></sup></p>
<p>This paragraph host the footnote reference within a
footnote test<sup id="fnref:reference"><a href="#fn:reference" class="footnote-ref" role="doc-noteref">9</a></sup>.</p>
<hr />
<p>Testing unusual footnote name<sup id="fnref:1$^!&quot;'"><a href="#fn:1$^!&quot;'" class="footnote-ref" role="doc-noteref">10</a></sup>.</p>
<hr />
<p>Footnotes mixed with images<sup id="fnref:image-mixed"><a class="footnote-ref" role="doc-noteref" href="#fn:image-mixed">11</a></sup><img alt="1800 Travel" src="images/MGR-1800-travel.jpeg" title="Travel Speeds in 1800"/><img alt="1830 Travel" src="images/MGR-1830-travel.jpeg" title="Travel Speeds in 1830"/></p>
<div class="footnotes" role="doc-endnotes">
<hr />
<ol>
<li id="fn:first" role="doc-endnote">
<p>This is the first note.&#160;<a href="#fnref:first" class="footnote-backref" role="doc-backlink">&#8617;&#xFE0E;</a></p>
</li>
<li id="fn:second" role="doc-endnote">
<p>This is the second note.&#160;<a href="#fnref:second" class="footnote-backref" role="doc-backlink">&#8617;&#xFE0E;</a></p>
</li>
<li id="fn:third" role="doc-endnote">
<p>This is the third note, defined out of order.&#160;<a href="#fnref:third" class="footnote-backref" role="doc-backlink">&#8617;&#xFE0E;</a></p>
</li>
<li id="fn:fourth" role="doc-endnote">
<p>This is the fourth note.&#160;<a href="#fnref:fourth" class="footnote-backref" role="doc-backlink">&#8617;&#xFE0E;</a></p>
</li>
<li id="fn:1" role="doc-endnote">
<p>Content for fifth footnote.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#8617;&#xFE0E;</a> <a href="#fnref2:1" class="footnote-backref" role="doc-backlink">&#8617;&#xFE0E;</a></p>
</li>
<li id="fn:2" role="doc-endnote">
<p>Content for sixth footnote spaning on
three lines, with some span-level markup like
<em>emphasis</em>, a <a href="http://michelf.ca/">link</a>.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#8617;&#xFE0E;</a></p>
</li>
<li id="fn:fn-name" role="doc-endnote">
<p>Footnote beginning on the line next to the marker.&#160;<a href="#fnref:fn-name" class="footnote-backref" role="doc-backlink">&#8617;&#xFE0E;</a></p>
</li>
<li id="fn:block" role="doc-endnote">
<p>Paragraph.</p>
<ul>
<li>List item</li>
</ul>
<blockquote>
<p>Blockquote</p>
</blockquote>
<pre><code>Code block
</code></pre>
<p><a href="#fnref:block" class="footnote-backref" role="doc-backlink">&#8617;&#xFE0E;</a></p>
</li>
<li id="fn:reference" role="doc-endnote">
<p>This footnote has a footnote of its own.<sup id="fnref:nested"><a href="#fn:nested" class="footnote-ref" role="doc-noteref">12</a></sup>&#160;<a href="#fnref:reference" class="footnote-backref" role="doc-backlink">&#8617;&#xFE0E;</a></p>
</li>
<li id="fn:1$^!&quot;'" role="doc-endnote">
<p>Haha!&#160;<a href="#fnref:1$^!&quot;'" class="footnote-backref" role="doc-backlink">&#8617;&#xFE0E;</a></p>
</li>
<li id="fn:image-mixed" role="doc-endnote">
<p>Footnote Content&#xA0;<a class="footnote-backref" role="doc-backlink" href="#fnref:image-mixed">&#8617;&#xFE0E;</a></p>
</li>
<li id="fn:nested" role="doc-endnote">
<p>This footnote should appear even though it is referenced
from another footnote. But [^reference] should be litteral
since the footnote with that name has already been used.&#160;<a href="#fnref:nested" class="footnote-backref" role="doc-backlink">&#8617;&#xFE0E;</a></p>
</li>
</ol>
</div>

View File

@ -0,0 +1,41 @@
Header {#id1}
======
Header { #id2}
------
### Header {#id3 }
#### Header ## { #id4 }
- - -
Header {.cl}
======
Header { .cl}
------
### Header {.cl }
#### Header ## { .cl }
- - -
Header {.cl.class}
======
Header { .cl .class}
------
### Header {.cl .class }
#### Header ## { .cl.class }
- - -
Header {#id5.cl.class}
======
Header { #id6 .cl .class}
------
### Header {.cl.class#id7 }
#### Header ## { .cl.class#id8 }

View File

@ -0,0 +1,37 @@
<h1 id="id1">Header</h1>
<h2 id="id2">Header</h2>
<h3 id="id3">Header</h3>
<h4 id="id4">Header</h4>
<hr />
<h1 class="cl">Header</h1>
<h2 class="cl">Header</h2>
<h3 class="cl">Header</h3>
<h4 class="cl">Header</h4>
<hr />
<h1 class="cl class">Header</h1>
<h2 class="cl class">Header</h2>
<h3 class="cl class">Header</h3>
<h4 class="cl class">Header</h4>
<hr />
<h1 class="cl class" id="id5">Header</h1>
<h2 class="cl class" id="id6">Header</h2>
<h3 class="cl class" id="id7">Header</h3>
<h4 class="cl class" id="id8">Header</h4>

View File

@ -0,0 +1,110 @@
# Markdown inside code blocks
<div markdown="1">
foo
</div>
<div markdown='1'>
foo
</div>
<div markdown=1>
foo
</div>
<table>
<tr><td markdown="1">test _emphasis_ (span)</td></tr>
</table>
<table>
<tr><td markdown="span">test _emphasis_ (span)</td></tr>
</table>
<table>
<tr><td markdown="block">test _emphasis_ (block)</td></tr>
</table>
## More complicated
<table>
<tr><td markdown="1">
* this is _not_ a list item</td></tr>
<tr><td markdown="span">
* this is _not_ a list item</td></tr>
<tr><td markdown="block">
* this _is_ a list item
</td></tr>
</table>
## With indent
<div>
<div markdown="1">
This text is no code block: if it was, the
closing `<div>` would be too and the HTML block
would be invalid.
Markdown content in HTML blocks is assumed to be
indented the same as the block opening tag.
**This should be the third paragraph after the header.**
</div>
</div>
## Code block with rogue `</div>`s in Markdown code span and block
<div>
<div markdown="1">
This is a code block however:
</div>
Funny isn't it? Here is a code span: `</div>`.
</div>
</div>
<div>
<div markdown="1">
* List item, not a code block
Some text
This is a code block.
</div>
</div>
## No code block in markdown span mode
<p markdown="1">
This is not a code block since Markdown parse paragraph
content as span. Code spans like `</p>` are allowed though.
</p>
<p markdown="1">_Hello_ _world_</p>
<p markdown="1" class="poem">
line 1
line 2
line 3
</p>
## Preserving attributes and tags on more than one line:
<p class="test" markdown="1"
id="12">
Some _span_ content.
</p>
## Header confusion bug
<table class="canvas">
<tr>
<td id="main" markdown="1">Hello World!
============
Hello World!</td>
</tr>
</table>

View File

@ -0,0 +1,131 @@
<h1>Markdown inside code blocks</h1>
<div>
<p>foo</p>
</div>
<div>
<p>foo</p>
</div>
<div>
<p>foo</p>
</div>
<table>
<tr><td>test <em>emphasis</em> (span)</td></tr>
</table>
<table>
<tr><td>test <em>emphasis</em> (span)</td></tr>
</table>
<table>
<tr><td>
<p>test <em>emphasis</em> (block)</p>
</td></tr>
</table>
<h2>More complicated</h2>
<table>
<tr><td>
* this is <em>not</em> a list item</td></tr>
<tr><td>
* this is <em>not</em> a list item</td></tr>
<tr><td>
<ul>
<li>this <em>is</em> a list item</li>
</ul>
</td></tr>
</table>
<h2>With indent</h2>
<div>
<div>
<p>This text is no code block: if it was, the
closing <code>&lt;div&gt;</code> would be too and the HTML block
would be invalid.</p>
<p>Markdown content in HTML blocks is assumed to be
indented the same as the block opening tag.</p>
<p><strong>This should be the third paragraph after the header.</strong></p>
</div>
</div>
<h2>Code block with rogue <code>&lt;/div&gt;</code>s in Markdown code span and block</h2>
<div>
<div>
<p>This is a code block however:</p>
<pre><code>&lt;/div&gt;
</code></pre>
<p>Funny isn't it? Here is a code span: <code>&lt;/div&gt;</code>.</p>
</div>
</div>
<div>
<div>
<ul>
<li>List item, not a code block</li>
</ul>
<p>Some text</p>
<pre><code>This is a code block.
</code></pre>
</div>
</div>
<h2>No code block in markdown span mode</h2>
<p>
This is not a code block since Markdown parse paragraph
content as span. Code spans like <code>&lt;/p&gt;</code> are allowed though.
</p>
<p><em>Hello</em> <em>world</em></p>
<p class="poem">
line 1<br />
line 2<br />
line 3
</p>
<h2>Preserving attributes and tags on more than one line:</h2>
<p class="test"
id="12">
Some <em>span</em> content.
</p>
<h2>Header confusion bug</h2>
<table class="canvas">
<tr>
<td id="main">Hello World!
============
Hello World!</td>
</tr>
</table>

View File

@ -0,0 +1,10 @@
This is an [inline link](/url "title"){.class #inline-link}.
This is a [reference link][refid].
This is an ![inline image](/img "title"){.class #inline-img}.
This is a ![reference image][refid].
[refid]: /path/to/something (Title) { .class #ref data-key=val }

View File

@ -0,0 +1,8 @@
<p>This is an <a href="/url" title="title" class="class" id="inline-link">inline link</a>.</p>
<p>This is a <a href="/path/to/something" title="Title" class="class" id="ref" data-key="val">reference link</a>.</p>
<p>This is an <img alt="inline image" src="/img" title="title" class="class" id="inline-img" />.</p>
<p>This is a <img alt="reference image" src="/path/to/something" title="Title" class="class" id="ref" data-key="val" />.</p>

View File

@ -0,0 +1,113 @@
# Simple tables
Header 1 | Header 2
--------- | ---------
Cell 1 | Cell 2
Cell 3 | Cell 4
With leading pipes:
| Header 1 | Header 2
| --------- | ---------
| Cell 1 | Cell 2
| Cell 3 | Cell 4
With tailing pipes:
Header 1 | Header 2 |
--------- | --------- |
Cell 1 | Cell 2 |
Cell 3 | Cell 4 |
With leading and tailing pipes:
| Header 1 | Header 2 |
| --------- | --------- |
| Cell 1 | Cell 2 |
| Cell 3 | Cell 4 |
* * *
# One-column one-row table
With leading pipes:
| Header
| -------
| Cell
With tailing pipes:
Header |
------- |
Cell |
With leading and tailing pipes:
| Header |
| ------- |
| Cell |
* * *
Table alignement:
| Default | Right | Center | Left |
| --------- |:--------- |:---------:| ---------:|
| Long Cell | Long Cell | Long Cell | Long Cell |
| Cell | Cell | Cell | Cell |
Table alignement (alternate spacing):
| Default | Right | Center | Left |
| --------- | :-------- | :-------: | --------: |
| Long Cell | Long Cell | Long Cell | Long Cell |
| Cell | Cell | Cell | Cell |
* * *
# Empty cells
| Header 1 | Header 2 |
| --------- | --------- |
| A | B |
| C | |
Header 1 | Header 2
--------- | ---------
A | B
| D
* * *
# Missing tailing pipe
Header 1 | Header 2
--------- | --------- |
Cell | Cell |
Cell | Cell |
Header 1 | Header 2 |
--------- | ---------
Cell | Cell |
Cell | Cell |
Header 1 | Header 2 |
--------- | --------- |
Cell | Cell
Cell | Cell |
Header 1 | Header 2 |
--------- | --------- |
Cell | Cell |
Cell | Cell
* * *
# Too many pipes in rows
| Header 1 | Header 2 |
| ---------
| Cell | Cell | Extra cell? |
| Cell | Cell | Extra cell? |

View File

@ -0,0 +1,333 @@
<h1>Simple tables</h1>
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
</tbody>
</table>
<p>With leading pipes:</p>
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
</tbody>
</table>
<p>With tailing pipes:</p>
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
</tbody>
</table>
<p>With leading and tailing pipes:</p>
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
</tbody>
</table>
<hr />
<h1>One-column one-row table</h1>
<p>With leading pipes:</p>
<table>
<thead>
<tr>
<th>Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
</tr>
</tbody>
</table>
<p>With tailing pipes:</p>
<table>
<thead>
<tr>
<th>Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
</tr>
</tbody>
</table>
<p>With leading and tailing pipes:</p>
<table>
<thead>
<tr>
<th>Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
</tr>
</tbody>
</table>
<hr />
<p>Table alignement:</p>
<table>
<thead>
<tr>
<th>Default</th>
<th align="left">Right</th>
<th align="center">Center</th>
<th align="right">Left</th>
</tr>
</thead>
<tbody>
<tr>
<td>Long Cell</td>
<td align="left">Long Cell</td>
<td align="center">Long Cell</td>
<td align="right">Long Cell</td>
</tr>
<tr>
<td>Cell</td>
<td align="left">Cell</td>
<td align="center">Cell</td>
<td align="right">Cell</td>
</tr>
</tbody>
</table>
<p>Table alignement (alternate spacing):</p>
<table>
<thead>
<tr>
<th>Default</th>
<th align="left">Right</th>
<th align="center">Center</th>
<th align="right">Left</th>
</tr>
</thead>
<tbody>
<tr>
<td>Long Cell</td>
<td align="left">Long Cell</td>
<td align="center">Long Cell</td>
<td align="right">Long Cell</td>
</tr>
<tr>
<td>Cell</td>
<td align="left">Cell</td>
<td align="center">Cell</td>
<td align="right">Cell</td>
</tr>
</tbody>
</table>
<hr />
<h1>Empty cells</h1>
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td>B</td>
</tr>
<tr>
<td>C</td>
<td></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td>B</td>
</tr>
<tr>
<td></td>
<td>D</td>
</tr>
</tbody>
</table>
<hr />
<h1>Missing tailing pipe</h1>
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
</table>
<hr />
<h1>Too many pipes in rows</h1>
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell | Extra cell?</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell | Extra cell?</td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,69 @@
~~~ .html
<ul>
<li>Code block first in file</li>
<li>doesn't work under some circumstances</li>
</ul>
~~~
As above: checking for bad interractions with the HTML block parser:
~~~ html
<div>
~~~
Some *markdown* `formatting`.
~~~ html
</div>
~~~
Some *markdown*
~~~
<div>
<html>
~~~
~~~
function test();
~~~
<div markdown="1">
<html>
<title>
</div>
<div markdown="1">
~~~
<html>
<title>
~~~
</div>
Two code blocks with no blank line between them:
~~~
<div>
~~~
~~~
<div>
~~~
Testing *confusion* with markers in the middle:
~~~
<div>~~~</div>
~~~
Testing mixing with title code blocks
~~~
<p>```
```
<p>```
~~~
```
<p>```
~~~
<p>```
```

View File

@ -0,0 +1,61 @@
<pre><code class="html">&lt;ul>
&lt;li>Code block first in file&lt;/li>
&lt;li>doesn't work under some circumstances&lt;/li>
&lt;/ul>
</code></pre>
<p>As above: checking for bad interractions with the HTML block parser:</p>
<pre><code class="html">&lt;div>
</code></pre>
<p>Some <em>markdown</em><code>formatting</code>.</p>
<pre><code class="html">&lt;/div>
</code></pre>
<p>Some <em>markdown</em></p>
<pre><code>&lt;div>
&lt;html>
</code></pre>
<pre><code>function test();
</code></pre>
<div>
<pre><code>&lt;html&gt;
&lt;title&gt;
</code></pre>
</div>
<div>
<pre><code>&lt;html&gt;
&lt;title&gt;
</code></pre>
</div>
<p>Two code blocks with no blank line between them:</p>
<pre><code>&lt;div&gt;
</code></pre>
<pre><code>&lt;div&gt;
</code></pre>
<p>Testing <em>confusion</em> with markers in the middle:</p>
<pre><code>&lt;div>~~~&lt;/div>
</code></pre>
<p>Testing mixing with title code blocks</p>
<pre><code>&lt;p>```
```
&lt;p>```
</code></pre>
<pre><code>&lt;p>```
~~~
&lt;p>```
</code></pre>

Some files were not shown because too many files have changed in this diff Show More