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:
categorylink
- there are four types of node fields (apart from
typefield which determines node type):titleurldescriptionchildren
- there is only one root
categorynode categorynodes below root node REQUIRE validtitleand may optionally contain other fieldscategorynode CAN have childcategorynodes ORlinknodes - but not both mixed at the same timelinknode REQUIRE validtitleand validurl, CAN have childlinknodes and CANNOT have childcategorynodes
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 descriptionOutput:
{
"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/marklinkuse 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);