diff --git a/MarkdownExtra.php b/MarkdownExtra.php
index eedcf77..c20614e 100644
--- a/MarkdownExtra.php
+++ b/MarkdownExtra.php
@@ -2,6 +2,7 @@
namespace cebe\markdown;
+use cebe\markdown\block\FooterTrait;
use cebe\markdown\block\TableTrait;
// work around https://github.com/facebook/hhvm/issues/1120
@@ -19,6 +20,7 @@ class MarkdownExtra extends Markdown
// include block element parsing using traits
use block\TableTrait;
use block\FencedCodeTrait;
+ use block\FooterTrait;
// include inline element parsing using traits
// TODO
@@ -60,8 +62,6 @@ class MarkdownExtra extends Markdown
// TODO implement definition lists
- // TODO implement footnotes
-
// TODO implement Abbreviations
diff --git a/block/FooterTrait.php b/block/FooterTrait.php
new file mode 100644
index 0000000..d215284
--- /dev/null
+++ b/block/FooterTrait.php
@@ -0,0 +1,154 @@
+
+ * @copyright 1997-2021 Pan Russian solovov.ru
+ */
+
+namespace cebe\markdown\block;
+
+
+trait FooterTrait
+{
+
+ protected $footnotes = [];
+ protected $footnoteNum = 1;
+
+ /**
+ * @param $text
+ * @return string
+ */
+ public function parse($text)
+ {
+ $absy = $this->parseBlocks(explode("\n", $text));
+
+ foreach ($absy as $block) {
+ if ($block[0] == 'footnote') {
+ $block['num'] = $this->footnoteNum;
+ $this->footnotes[] = $block;
+ $this->footnoteNum++;
+ }
+ }
+ $markup = parent::parse($text);
+ $markup = $this->applyFooter($markup, $this->footnotes);
+
+ return $markup;
+ }
+
+ /**
+ * @param $content
+ * @param $blocks
+ * @return string
+ */
+ protected function applyFooter($content, $blocks)
+ {
+ foreach ($blocks as $block) {
+ $number = $block['num'] . ". ";
+ $link = '';
+ $text = $this->renderAbsy($block['content']);
+ $text = $this->renderAbsy($this->parseInline($text));
+ $text = substr_replace($text, $number, 3, 0);
+ $text = substr_replace($text, $link, -5, 0);
+
+ $content .= '' . $text . "\n";
+ }
+ return $content;
+ }
+
+ /**
+ * Parses a footnote link indicated by `[^`.
+ * @marker [^
+ * @param $text
+ * @return array
+ */
+ protected function parseFootnoteLink($text)
+ {
+ if (preg_match('/^\[\^(.+?)\]/', $text, $matches)) {
+ return [
+ ['footnoteLink', $matches[1]],
+ strlen($matches[0])
+ ];
+ }
+ return [['text', $text[0]], 1];
+ }
+
+ /**
+ * @param $block
+ * @return string
+ */
+ protected function renderFootnoteLink($block)
+ {
+ $footnoteId = $block[1];
+ $num = 0;
+ $found = false;
+ foreach ($this->footnotes as $footnote) {
+ $num ++;
+ if ($footnote['id']==$footnoteId) {
+ $found = true;
+ break;
+ }
+ }
+ if (!$found)
+ $num = '?';
+
+ $text = htmlspecialchars($block[1], ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8');
+ return '';
+ }
+
+ /**
+ * identify a line as the beginning of a footnote block
+ *
+ * @param $line
+ * @return false|int
+ */
+ protected function identifyFootnoteList($line)
+ {
+ return preg_match('/^\[\^(.+?)\]:/', $line);
+ }
+
+ /**
+ * Consume lines for a footnote
+ */
+ protected function consumeFootnoteList($lines, $current)
+ {
+ $id = '';
+ $content = [];
+ $count = count($lines);
+ for ($i = $current; $i < $count; $i++) {
+ $line = $lines[$i];
+
+ if ($id == '') {
+ if (preg_match('/^\[\^(.+?)\]:[ \t]+/', $line, $matches)) {
+ $id = $matches[1];
+ $str = substr($line, strlen($matches[0]));
+ $content[] = $str;
+ }
+ } else if (strlen(trim($line)) == 0) {
+ break;
+ } else {
+ $content[] = ltrim($line);
+ }
+ }
+
+ $block = ['footnote', 'id' => $id, 'content' => $this->parseBlocks($content)];
+
+ return [$block, $i];
+ }
+
+ /**
+ * @param $block
+ * @return string
+ */
+ protected function renderFootnote($block)
+ {
+ return '';
+ }
+
+
+}
\ No newline at end of file
diff --git a/tests/extra-data/footernote.md b/tests/extra-data/footernote.md
new file mode 100644
index 0000000..cd47d7f
--- /dev/null
+++ b/tests/extra-data/footernote.md
@@ -0,0 +1,3 @@
+The implementation focus is to be fast (see benchmark) and extensible [^1]
+
+[^1]: See [benchmark](https://github.com/kzykhys/Markbench#readme).
\ No newline at end of file
diff --git a/tests/extra-data/foternote.html b/tests/extra-data/foternote.html
new file mode 100644
index 0000000..85d2a0c
--- /dev/null
+++ b/tests/extra-data/foternote.html
@@ -0,0 +1,6 @@
+The implementation focus is to be fast (see benchmark) and extensible
+
+
+1. See benchmark.
+
+
\ No newline at end of file