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).
- there are two types of nodes:
category
link
- there are four types of node fields (apart from
type
field which determines node type):title
url
description
children
- there is only one root
category
node category
nodes below root node REQUIRE validtitle
and may optionally contain other fieldscategory
node CAN have childcategory
nodes ORlink
nodes - but not both mixed at the same timelink
node REQUIRE validtitle
and validurl
, CAN have childlink
nodes and CANNOT have childcategory
nodes
Here 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);