mirror of
https://github.com/erusev/parsedown.git
synced 2023-08-10 21:13:06 +03:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
0d28808392 | |||
78960cf792 | |||
8f2e9c7cf6 | |||
3eb6d349f0 | |||
859b1b10c1 | |||
08b01a1a29 | |||
1686b2fbff | |||
15a32fcd0e | |||
4aca208f96 | |||
cedf96a64e | |||
9f58363e4b | |||
6b4a459f97 | |||
05bf198d26 | |||
30234a58fa | |||
03ff22c7df |
285
Parsedown.php
285
Parsedown.php
@ -29,7 +29,7 @@ class Parsedown
|
|||||||
function text($text)
|
function text($text)
|
||||||
{
|
{
|
||||||
# make sure no definitions are set
|
# make sure no definitions are set
|
||||||
$this->Definitions = array();
|
$this->DefinitionData = array();
|
||||||
|
|
||||||
# standardize line breaks
|
# standardize line breaks
|
||||||
$text = str_replace("\r\n", "\n", $text);
|
$text = str_replace("\r\n", "\n", $text);
|
||||||
@ -104,6 +104,7 @@ class Parsedown
|
|||||||
'<' => array('Comment', 'Markup'),
|
'<' => array('Comment', 'Markup'),
|
||||||
'=' => array('SetextHeader'),
|
'=' => array('SetextHeader'),
|
||||||
'>' => array('Quote'),
|
'>' => array('Quote'),
|
||||||
|
'[' => array('Reference'),
|
||||||
'_' => array('Rule'),
|
'_' => array('Rule'),
|
||||||
'`' => array('FencedCode'),
|
'`' => array('FencedCode'),
|
||||||
'|' => array('Table'),
|
'|' => array('Table'),
|
||||||
@ -199,21 +200,6 @@ class Parsedown
|
|||||||
|
|
||||||
$marker = $text[0];
|
$marker = $text[0];
|
||||||
|
|
||||||
if (isset($this->DefinitionTypes[$marker]))
|
|
||||||
{
|
|
||||||
foreach ($this->DefinitionTypes[$marker] as $definitionType)
|
|
||||||
{
|
|
||||||
$Definition = $this->{'definition'.$definitionType}($Line, $CurrentBlock);
|
|
||||||
|
|
||||||
if (isset($Definition))
|
|
||||||
{
|
|
||||||
$this->Definitions[$definitionType][$Definition['id']] = $Definition['data'];
|
|
||||||
|
|
||||||
continue 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ~
|
# ~
|
||||||
|
|
||||||
$blockTypes = $this->unmarkedBlockTypes;
|
$blockTypes = $this->unmarkedBlockTypes;
|
||||||
@ -239,7 +225,7 @@ class Parsedown
|
|||||||
|
|
||||||
if ( ! isset($Block['identified']))
|
if ( ! isset($Block['identified']))
|
||||||
{
|
{
|
||||||
$Elements []= $CurrentBlock['element'];
|
$Blocks []= $CurrentBlock;
|
||||||
|
|
||||||
$Block['identified'] = true;
|
$Block['identified'] = true;
|
||||||
}
|
}
|
||||||
@ -263,7 +249,7 @@ class Parsedown
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$Elements []= $CurrentBlock['element'];
|
$Blocks []= $CurrentBlock;
|
||||||
|
|
||||||
$CurrentBlock = $this->paragraph($Line);
|
$CurrentBlock = $this->paragraph($Line);
|
||||||
|
|
||||||
@ -280,13 +266,26 @@ class Parsedown
|
|||||||
|
|
||||||
# ~
|
# ~
|
||||||
|
|
||||||
$Elements []= $CurrentBlock['element'];
|
$Blocks []= $CurrentBlock;
|
||||||
|
|
||||||
unset($Elements[0]);
|
unset($Blocks[0]);
|
||||||
|
|
||||||
# ~
|
# ~
|
||||||
|
|
||||||
$markup = $this->elements($Elements);
|
$markup = '';
|
||||||
|
|
||||||
|
foreach ($Blocks as $Block)
|
||||||
|
{
|
||||||
|
if (isset($Block['hidden']))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$markup .= "\n";
|
||||||
|
$markup .= isset($Block['markup']) ? $Block['markup'] : $this->element($Block['element']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$markup .= "\n";
|
||||||
|
|
||||||
# ~
|
# ~
|
||||||
|
|
||||||
@ -367,9 +366,7 @@ class Parsedown
|
|||||||
if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!')
|
if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!')
|
||||||
{
|
{
|
||||||
$Block = array(
|
$Block = array(
|
||||||
'element' => array(
|
'markup' => $Line['body'],
|
||||||
'text' => $Line['body'],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (preg_match('/-->$/', $Line['text']))
|
if (preg_match('/-->$/', $Line['text']))
|
||||||
@ -388,7 +385,7 @@ class Parsedown
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$Block['element']['text'] .= "\n" . $Line['body'];
|
$Block['markup'] .= "\n" . $Line['body'];
|
||||||
|
|
||||||
if (preg_match('/-->$/', $Line['text']))
|
if (preg_match('/-->$/', $Line['text']))
|
||||||
{
|
{
|
||||||
@ -665,7 +662,7 @@ class Parsedown
|
|||||||
|
|
||||||
#
|
#
|
||||||
# Markup
|
# Markup
|
||||||
|
|
||||||
protected function blockMarkup($Line)
|
protected function blockMarkup($Line)
|
||||||
{
|
{
|
||||||
if ($this->markupEscaped)
|
if ($this->markupEscaped)
|
||||||
@ -673,77 +670,47 @@ class Parsedown
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$attrName = '[a-zA-Z_:][\w:.-]*';
|
if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
|
||||||
$attrValue = '(?:[^"\'=<>`\s]+|".*?"|\'.*?\')';
|
|
||||||
|
|
||||||
preg_match('/^<(\w[\d\w]*)((?:\s'.$attrName.'(?:\s*=\s*'.$attrValue.')?)*)\s*(\/?)>/', $Line['text'], $matches);
|
|
||||||
|
|
||||||
if ( ! $matches or in_array($matches[1], $this->textLevelElements))
|
|
||||||
{
|
{
|
||||||
return;
|
if (in_array($matches[1], $this->textLevelElements))
|
||||||
}
|
|
||||||
|
|
||||||
$Block = array(
|
|
||||||
'depth' => 0,
|
|
||||||
'element' => array(
|
|
||||||
'name' => $matches[1],
|
|
||||||
'text' => null,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
$remainder = substr($Line['text'], strlen($matches[0]));
|
|
||||||
|
|
||||||
if (trim($remainder) === '')
|
|
||||||
{
|
|
||||||
if ($matches[3] or in_array($matches[1], $this->voidElements))
|
|
||||||
{
|
|
||||||
$Block['closed'] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ($matches[3] or in_array($matches[1], $this->voidElements))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
preg_match('/(.*)<\/'.$matches[1].'>\s*$/i', $remainder, $nestedMatches);
|
$Block = array(
|
||||||
|
'name' => $matches[1],
|
||||||
|
'depth' => 0,
|
||||||
|
'markup' => $Line['text'],
|
||||||
|
);
|
||||||
|
|
||||||
if ($nestedMatches)
|
$length = strlen($matches[0]);
|
||||||
|
|
||||||
|
$remainder = substr($Line['text'], $length);
|
||||||
|
|
||||||
|
if (trim($remainder) === '')
|
||||||
{
|
{
|
||||||
$Block['closed'] = true;
|
if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
|
||||||
$Block['element']['text'] = $nestedMatches[1];
|
{
|
||||||
|
$Block['closed'] = true;
|
||||||
|
|
||||||
|
$Block['void'] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$Block['element']['text'] = $remainder;
|
if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
|
||||||
}
|
{
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder))
|
||||||
|
{
|
||||||
|
$Block['closed'] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! $matches[2])
|
|
||||||
{
|
|
||||||
return $Block;
|
return $Block;
|
||||||
}
|
}
|
||||||
|
|
||||||
preg_match_all('/\s('.$attrName.')(?:\s*=\s*('.$attrValue.'))?/', $matches[2], $nestedMatches, PREG_SET_ORDER);
|
|
||||||
|
|
||||||
foreach ($nestedMatches as $nestedMatch)
|
|
||||||
{
|
|
||||||
if ( ! isset($nestedMatch[2]))
|
|
||||||
{
|
|
||||||
$Block['element']['attributes'][$nestedMatch[1]] = '';
|
|
||||||
}
|
|
||||||
elseif ($nestedMatch[2][0] === '"' or $nestedMatch[2][0] === '\'')
|
|
||||||
{
|
|
||||||
$Block['element']['attributes'][$nestedMatch[1]] = substr($nestedMatch[2], 1, - 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$Block['element']['attributes'][$nestedMatch[1]] = $nestedMatch[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $Block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function blockMarkupContinue($Line, array $Block)
|
protected function blockMarkupContinue($Line, array $Block)
|
||||||
@ -753,12 +720,12 @@ class Parsedown
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match('/^<'.$Block['element']['name'].'(?:\s.*[\'"])?\s*>/i', $Line['text'])) # open
|
if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open
|
||||||
{
|
{
|
||||||
$Block['depth'] ++;
|
$Block['depth'] ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match('/(.*?)<\/'.$Block['element']['name'].'>\s*$/i', $Line['text'], $matches)) # close
|
if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close
|
||||||
{
|
{
|
||||||
if ($Block['depth'] > 0)
|
if ($Block['depth'] > 0)
|
||||||
{
|
{
|
||||||
@ -766,29 +733,53 @@ class Parsedown
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$Block['element']['text'] .= "\n";
|
|
||||||
|
|
||||||
$Block['closed'] = true;
|
$Block['closed'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$Block['element']['text'] .= $matches[1];
|
$Block['markup'] .= $matches[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($Block['interrupted']))
|
if (isset($Block['interrupted']))
|
||||||
{
|
{
|
||||||
$Block['element']['text'] .= "\n";
|
$Block['markup'] .= "\n";
|
||||||
|
|
||||||
unset($Block['interrupted']);
|
unset($Block['interrupted']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! isset($Block['closed']))
|
$Block['markup'] .= "\n".$Line['body'];
|
||||||
{
|
|
||||||
$Block['element']['text'] .= "\n".$Line['body'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $Block;
|
return $Block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Reference
|
||||||
|
|
||||||
|
protected function blockReference($Line)
|
||||||
|
{
|
||||||
|
if (preg_match('/^\[(.+?)\]:[ ]*<?(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches))
|
||||||
|
{
|
||||||
|
$id = strtolower($matches[1]);
|
||||||
|
|
||||||
|
$Data = array(
|
||||||
|
'url' => $matches[2],
|
||||||
|
'title' => null,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($matches[3]))
|
||||||
|
{
|
||||||
|
$Data['title'] = $matches[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->DefinitionData['Reference'][$id] = $Data;
|
||||||
|
|
||||||
|
$Block = array(
|
||||||
|
'hidden' => true,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $Block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Table
|
# Table
|
||||||
|
|
||||||
@ -944,31 +935,6 @@ class Parsedown
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
# Definitions
|
|
||||||
#
|
|
||||||
|
|
||||||
protected function definitionReference($Line)
|
|
||||||
{
|
|
||||||
if (preg_match('/^\[(.+?)\]:[ ]*<?(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches))
|
|
||||||
{
|
|
||||||
$Definition = array(
|
|
||||||
'id' => strtolower($matches[1]),
|
|
||||||
'data' => array(
|
|
||||||
'url' => $matches[2],
|
|
||||||
'title' => null,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isset($matches[3]))
|
|
||||||
{
|
|
||||||
$Definition['data']['title'] = $matches[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $Definition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# ~
|
# ~
|
||||||
#
|
#
|
||||||
@ -992,39 +958,25 @@ class Parsedown
|
|||||||
|
|
||||||
protected function element(array $Element)
|
protected function element(array $Element)
|
||||||
{
|
{
|
||||||
$markup = '';
|
$markup = '<'.$Element['name'];
|
||||||
|
|
||||||
if (isset($Element['name']))
|
if (isset($Element['attributes']))
|
||||||
{
|
{
|
||||||
$markup .= '<'.$Element['name'];
|
foreach ($Element['attributes'] as $name => $value)
|
||||||
|
|
||||||
if (isset($Element['attributes']))
|
|
||||||
{
|
{
|
||||||
foreach ($Element['attributes'] as $name => $value)
|
if ($value === null)
|
||||||
{
|
{
|
||||||
if ($value === null)
|
continue;
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$markup .= ' '.$name.'="'.$value.'"';
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($Element['text']))
|
$markup .= ' '.$name.'="'.$value.'"';
|
||||||
{
|
|
||||||
$markup .= '>';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$markup .= ' />';
|
|
||||||
|
|
||||||
return $markup;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($Element['text']))
|
if (isset($Element['text']))
|
||||||
{
|
{
|
||||||
|
$markup .= '>';
|
||||||
|
|
||||||
if (isset($Element['handler']))
|
if (isset($Element['handler']))
|
||||||
{
|
{
|
||||||
$markup .= $this->$Element['handler']($Element['text']);
|
$markup .= $this->$Element['handler']($Element['text']);
|
||||||
@ -1033,12 +985,13 @@ class Parsedown
|
|||||||
{
|
{
|
||||||
$markup .= $Element['text'];
|
$markup .= $Element['text'];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($Element['name']))
|
|
||||||
{
|
|
||||||
$markup .= '</'.$Element['name'].'>';
|
$markup .= '</'.$Element['name'].'>';
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$markup .= ' />';
|
||||||
|
}
|
||||||
|
|
||||||
return $markup;
|
return $markup;
|
||||||
}
|
}
|
||||||
@ -1049,11 +1002,6 @@ class Parsedown
|
|||||||
|
|
||||||
foreach ($Elements as $Element)
|
foreach ($Elements as $Element)
|
||||||
{
|
{
|
||||||
if ($Element === null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$markup .= "\n" . $this->element($Element);
|
$markup .= "\n" . $this->element($Element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1063,7 +1011,7 @@ class Parsedown
|
|||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Spans
|
# Inline Elements
|
||||||
#
|
#
|
||||||
|
|
||||||
protected $InlineTypes = array(
|
protected $InlineTypes = array(
|
||||||
@ -1296,24 +1244,28 @@ class Parsedown
|
|||||||
|
|
||||||
$excerpt = substr($excerpt, 1);
|
$excerpt = substr($excerpt, 1);
|
||||||
|
|
||||||
$Inline = $this->inlineLink($excerpt);
|
$InlineLink = $this->inlineLink($excerpt);
|
||||||
|
|
||||||
if ($Inline === null)
|
if ($InlineLink === null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$Inline['extent'] ++;
|
$Inline = array(
|
||||||
|
'extent' => $InlineLink['extent'] + 1,
|
||||||
$Inline['element'] = array(
|
'element' => array(
|
||||||
'name' => 'img',
|
'name' => 'img',
|
||||||
'attributes' => array(
|
'attributes' => array(
|
||||||
'src' => $Inline['element']['attributes']['href'],
|
'src' => $InlineLink['element']['attributes']['href'],
|
||||||
'alt' => $Inline['element']['text'],
|
'alt' => $InlineLink['element']['text'],
|
||||||
'title' => $Inline['element']['attributes']['title'],
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$Inline['element']['attributes'] += $InlineLink['element']['attributes'];
|
||||||
|
|
||||||
|
unset($Inline['element']['attributes']['href']);
|
||||||
|
|
||||||
return $Inline;
|
return $Inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1371,12 +1323,12 @@ class Parsedown
|
|||||||
$definition = strtolower($Element['text']);
|
$definition = strtolower($Element['text']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! isset($this->Definitions['Reference'][$definition]))
|
if ( ! isset($this->DefinitionData['Reference'][$definition]))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$Definition = $this->Definitions['Reference'][$definition];
|
$Definition = $this->DefinitionData['Reference'][$definition];
|
||||||
|
|
||||||
$Element['attributes']['href'] = $Definition['url'];
|
$Element['attributes']['href'] = $Definition['url'];
|
||||||
$Element['attributes']['title'] = $Definition['title'];
|
$Element['attributes']['title'] = $Definition['title'];
|
||||||
@ -1425,10 +1377,7 @@ class Parsedown
|
|||||||
#
|
#
|
||||||
# ~
|
# ~
|
||||||
|
|
||||||
protected $unmarkedInlineTypes = array(
|
protected $unmarkedInlineTypes = array("\n" => 'Break', '://' => 'Url');
|
||||||
" \n" => 'Break',
|
|
||||||
'://' => 'Url',
|
|
||||||
);
|
|
||||||
|
|
||||||
# ~
|
# ~
|
||||||
|
|
||||||
@ -1552,7 +1501,7 @@ class Parsedown
|
|||||||
# Fields
|
# Fields
|
||||||
#
|
#
|
||||||
|
|
||||||
protected $Definitions;
|
protected $DefinitionData;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Read-only
|
# Read-only
|
||||||
@ -1571,6 +1520,8 @@ class Parsedown
|
|||||||
'_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us',
|
'_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?';
|
||||||
|
|
||||||
protected $voidElements = array(
|
protected $voidElements = array(
|
||||||
'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source',
|
'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source',
|
||||||
);
|
);
|
||||||
|
@ -40,7 +40,7 @@ It'd mean no support for PHP 5.2. Would it be worth it?
|
|||||||
The majority of the CommonMark tests pass. Most of the tests that don't pass deal with cases that are quite extreme. Yet, we are working on them. As CommonMark matures, compliance should improve.
|
The majority of the CommonMark tests pass. Most of the tests that don't pass deal with cases that are quite extreme. Yet, we are working on them. As CommonMark matures, compliance should improve.
|
||||||
|
|
||||||
**Who uses Parsedown?**<br/>
|
**Who uses Parsedown?**<br/>
|
||||||
[phpDocumentor](http://www.phpdoc.org/), [October CMS](http://octobercms.com/), [Bolt CMS](http://bolt.cm/), [Kirby CMS](http://getkirby.com/), [RaspberryPi.org](http://www.raspberrypi.org/) and [more](https://www.versioneye.com/php/erusev:parsedown/references).
|
[phpDocumentor](http://www.phpdoc.org/), [October CMS](http://octobercms.com/), [Bolt CMS](http://bolt.cm/), [Kirby CMS](http://getkirby.com/), [Grav CMS](http://getgrav.org/), [Statamic CMS](http://www.statamic.com/), [RaspberryPi.org](http://www.raspberrypi.org/) and [more](https://www.versioneye.com/php/erusev:parsedown/references).
|
||||||
|
|
||||||
**How can I help?**<br/>
|
**How can I help?**<br/>
|
||||||
Use the project, tell friends about it and if you feel generous, [donate some money](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).
|
Use the project, tell friends about it and if you feel generous, [donate some money](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<hr />
|
<hr>
|
||||||
<p>paragraph</p>
|
<p>paragraph</p>
|
||||||
<hr />
|
<hr/>
|
||||||
<p>paragraph</p>
|
<p>paragraph</p>
|
||||||
<hr />
|
<hr />
|
||||||
<p>paragraph</p>
|
<p>paragraph</p>
|
||||||
<hr class="foo" id="bar" />
|
<hr class="foo" id="bar" />
|
||||||
<p>paragraph</p>
|
<p>paragraph</p>
|
||||||
<hr class="foo" id="bar" />
|
<hr class="foo" id="bar"/>
|
||||||
<p>paragraph</p>
|
<p>paragraph</p>
|
||||||
<hr class="foo" id="bar" />
|
<hr class="foo" id="bar" >
|
||||||
<p>paragraph</p>
|
<p>paragraph</p>
|
Reference in New Issue
Block a user