A simple standard allowing embedding (and parsing) categorized lists of links inside Markdown files.
Marklink was born as an attempt to standardize various awesome lists of links available on GitHub.
Every Markdown document with embedded well-formed Marklink sections can be parsed by Marklink parser into tree-like JSON structure with categories and links. This JSON data structure is described by schema file (see marklink.schema.json for reference). Schema file allows JSON structure to be validated (see JSON Schema for reference).
category
link
type
field which
determines node type):
title
url
description
children
category
nodecategory
nodes below root node REQUIRE valid title
and may optionally
contain other fieldscategory
node CAN have child category
nodes OR link
nodes - but not
both mixed at the same timelink
node REQUIRE valid title
and valid url
, CAN have child link
nodes and
CANNOT have child category
nodesHere are some examples how Markdown fragments are parsed by Marklink parser into
JSON data (see tests/
directory for more).
Input:
- [Link A](http://a.example.com) - Link A description
- [Link B](http://b.example.com) - Link B description with [link](http://link.example.com)
Output:
{
"type": "category",
"children": [
{
"type": "link",
"title": "Link A",
"url": "http://a.example.com",
"description": "Link A description"
},
{
"type": "link",
"title": "Link B",
"url": "http://b.example.com",
"description": "Link B description with [link](http://link.example.com)"
}
]
}
Input:
## Category A
Category A description
### Sub-category A
- Sub-sub-category A
- [Link A](http://a.example.com) - Link A description
- [Link B](http://b.example.com) - Link B description with [link](http://link.example.com)
- [Link C](http://c.example.com) - Link C description
Output:
{
"type": "category",
"children": [
{
"type": "category",
"title": "Category A",
"description": "Category A description",
"children": [
{
"type": "category",
"title": "Sub-category A",
"children": [
{
"type": "category",
"title": "Sub-sub-category A",
"children": [
{
"type": "link",
"title": "Link A",
"url": "http://a.example.com",
"description": "Link A description"
},
{
"type": "link",
"title": "Link B",
"url": "http://b.example.com",
"description": "Link B description with [link](http://link.example.com)",
"children": [
{
"type": "link",
"title": "Link C",
"url": "http://c.example.com",
"description": "Link C description",
}
]
}
]
}
]
}
]
}
]
}
By default Marklink parser will parse whole document unless it finds following markers:
<!-- marklink:start -->
- [Link A](http://a.example.com) - Link A description
- [Link B](http://b.example.com) - Link B description with [link](http://link.example.com)
<!-- marklink:end -->
In that case only content between markers will be parsed.
Initial Markling parser implementation is available as a service.
https://awesomelist.kminek.pl/marklink
curl --request POST \
--url https://awesomelist.kminek.pl/api/markdown \
--header 'cache-control: no-cache' \
--header 'content-type: application/json' \
--data '{"input": "- [Link A](http://a.example.com) - Link A description\n- [Link B](http://b.example.com) - Link B description with [link](http://link.example.com)"}'
composer require kminek/marklink
use Kminek\Marklink\ParserService;
$markdown = <<<MARKDOWN
- [Link A](http://a.example.com) - Link A description
- [Link B](http://b.example.com) - Link B description with [link](http://link.example.com)
MARKDOWN;
$parser = new ParserService;
$result = $parser->parse($markdown);