# Semantic Markdown Spec (Alpha Draft) [TOC] ## Introduction ### What is Semantic Markdown? Semantic Markdown is a plain-text format for writing documents that embed machine-readable data. The documents are easy to author and both human and machine-readable, so that the structured data contained within these documents is available to tools and applications. Technically speaking, Semantic Markdown is _"RDFa Lite for Markdown"_ and aims at enhancing the HTML generated from Markdown with [RDFa Lite] attributes. Design Rationale: - Embed RDFa-like semantic annotation within Markdown - Ability to mix unstructured human-text with machine-readable data in JSON-LD-like lists - Ability to semantically annotate an existing plain Markdown document with semantic annotations - Keep human-readability to a maximum ### About this document :::warning This document is in early draft stage ! ::: ### Providing feedback Interested in joining the idea or providing feedback? 1. Annotate this document with ideas 2. Join us on the [Semantic Markdown Matrix discussion channel](https://matrix.to/#/#semantic-markdown:matrix.virtual-assembly.org), e.g. using a client like Riot.im at https://riot.im/app/#/room/#semantic-markdown:matrix.virtual-assembly.org 3. Modify the document directly after your proposals were discussed ## Semantic Markdown at a glance Semantic annotations are declared within curly braces `{...}`. ### Annotation types Semantic Markdown provides 3 types of annotations: - annotating text with a type/class: Annotation starting with a `.` indicates a type/class, and generate RDFa `typeof` attribute: `{.foaf:Person}` - annotating text with a property: Annotation without leading marker indicates a property, and generate RDFa `property` attribute: `{foaf:name}` - annotating text with a subject identifier: Annotation starting with a `=` indicates an IRI of a known entity, and generate RDF `resource` attribute: `{=wdt:Q42}` ### Paragraph example ```markdown My name is [Manu Sporny]{:name} and you can give me a ring via [1-800-555-0199]{:telephone}. ![](http://manu.sporny.org/images/manu.png){:image} My favorite animal is the [Liger]{ov:preferredAnimal}. {=<#manu> .:Person} {schema}: @default {ov}: http://open.vocab.org/terms/ ``` Would produce the following HTML+RDFa: ```html
My name is Manu Sporny and you can give me a ring via 1-800-555-0199. My favorite animal is the Liger.
``` Notice how IRI namespace "schema" is implicitly resolved from its listing at [RDFa Core Initial Context] ### Title and list example ```markdown ## {.schema:Event schema:name} ## Specification meeting * Date: [11/10]{schema:startDate} * Place: [Our office, Street name, Paris]{schema:location} * Meeting participants: {schema:attendee} * Alice * Bob * [Tim](https://www.wikidata.org/wiki/Q80) * Description: Some information not annotated ## Launch party (TODO) {schema}: @default ``` Would produce the following HTML+RDFa: ```html(TODO)
My name is Manu Sporny
My name is Manu [Sporny]
My name is [Manu Sporny] {schema:name}
My name is Manu Sporny{schema:name}
You can give me a ring.
You can give me a ring {=#manu}.
``` Notice how second paragraph has punctuation *after* the hints. Similarly for a list: ```markdown - Thomas Francart {foaf:name} - 39 {foaf:age} - Semantic Web Consultant {rdfs:comment} ``` Would produce the following HTML+RDFa: ```htmlMy name is Manu Sporny, and you can give me a ring.
My name is Thomas Francart.
``` Notice how second header and succeeding paragraph is wrapped with a div tag, whereas third header is omitted because it is not a *descendant* but a *sibling*. ### Block-siblings scope Hints in a header or list block with no non-whitespace characters before or after the hints, followed by a block of same type and level, applies individually to each following block of same type and level, until any block of a lower level. ```markdown # People ## {.schema:Person} ## Manu Sporny My name is Manu Sporny. ## Thomas Francart My name is Thomas Francart. # Animals ``` Would produce the following HTML+RDFa: ```htmlMy name is Manu Sporny.
My name is Thomas Francart.
My name is Manu Sporny.
My name is Thomas Francart.
I once read this:My name is Manu Sporny.
You can give me a ring.
Should I call him?
My name is Manu Sporny and you can give me a ring via 1-800-555-0199.
``` ## Semantic Markdown and other Markdown extensions ### Attributes extension See [PHP Markdown extra special attributes](https://michelf.ca/projects/php-markdown/extra/#spe-attr) and [Pandoc's header attributes](https://pandoc.org/MANUAL.html#heading-identifiers): Semantic Markdown uses similar syntax, but either with different leading character "=" or "keywords" containing a colon. Extract from PHP Markdown extra documentation: > With Markdown Extra, you can set the id and class attribute on certain elements using an attribute block. For instance, put the desired id prefixed by a hash inside curly brackets after the header at the end of the line, like this: > > ```markdown > Header 1 {#header1} > ======== > >## Header 2 ## {#header2} >``` >Then you can create links to different parts of the same document like this: > > ```markdown > [Link back to header 1](#header1) > ``` >To add a class name, which can be used as a hook for a style sheet, use a dot like this: >```markdown >## The Site ## {.main} >``` >You can also add custom attributes having simple values by specifying the attribute name, followed by an equal sign, followed by the value (which cannot contain spaces at this time): >```markdown >## Le Site ## {lang=fr} >``` >The id, multiple class names, and other custom attributes can be combined by putting them all into the same special attribute block: >```markdown >## Le Site ## {.main .shine #the-site lang=fr} >``` >At this time, special attribute blocks can be used with > - headers, > - fenced code blocks > - links, and > - images. ### spans See Pandoc [bracketed spans](https://pandoc.org/MANUAL.html#divs-and-spans) #### span example ```markdown Meeting with [Bob]{.foaf:Person} ``` Would produce the following HTML+RDFa: ```htmlMeeting with Bob
``` ### blocks #### block example Annotations declared as a an initial separate block applies to all siblings by introducing a surrounding `We are preparing the 2020 Music Festival !
We are preparing the 2020 Music Festival !
``` ### Extend the extensions: use attributes at other places #### Set attributes on lists ```markdown - {foaf:member} - member 1 - member 2 - something else - member 3 ``` #### Set attributes on list items ```markdown - item 1 {foaf:member} - item 2 {foaf:member} - item 3 {foaf:member} ``` #### Set attributes on inlines ```markdown Thomas is _39_{foaf:age}. ``` ### Define a "property attribute" An attribute without `.`, without `#` and that is not a key-value pair should be recognized as a property name, e.g. `{foaf:name}`. ### Define a "subject attribute" An attribute beginning with the `=` sign indicates a subject IRI, equivalent to an `resource=xxx` property, e.g. `{=wdt:Q42}` is equivalent to `Thomas is 39
``` Same with `_`, `*` or `**`. ### Annotate with 2 properties It should be possible to annotate with 2 properties ```markdown - Name: Alice {foaf:name rdfs:label} - Age: 23 {foaf:age} ``` Should yield ```html - Name: Alice - Age: 23 ``` ## Annotate the subject of properties ### Use a class attribute (RDFa "typeof" attribute) ```markdown # Le site {.foaf:Document} ``` Would produce the following HTML+RDFa: ```His name is Douglas Adams
``` But beware that if one hint is broken then the whole annotation is passed through as-is, e.g. if using an undefined prefix: ```markdown His name is [Douglas Adams]{.foaf:Person =wdt:Q42} ``` Should produce the following HTML+RDFa ```htmlHis name is [Douglas Adams]{.foaf:Person =wdt:Q42}
``` ## Where to find the current subject? RDFa relies on a mechanism to indicate the [_current subject_ of the annotation](https://www.w3.org/TR/rdfa-core/#setting-the-current-subject). Semantic Markdown aims at having an equivalent mechanism. Intuitively, the current subject is the resource annotated in the "closest ancestor" of a property annotation. ### Current span subject Used to indicate that a certain inline portion of a sentence is about an entity. ```markdown [Tim Berners Lee]{=wdt:Q80} invented the web. {wdt}: http://www.wikidata.org/prop/direct/ ``` Should yield ```htmlTim Berners Lee invented the web.
``` ### Current paragraph subject Used to indicate that a whole paragraph is about an entity. The annotation is at the end of the paragraph for readability. ```markdown Tim Berners Lee invented the web. {=wdt:Q80} {wdt}: http://www.wikidata.org/prop/direct/ ``` Should yield ```htmlTim Berners Lee invented the web.
``` ### Current list subject Used to indicate that a whole list describes an entity. The annotation should be sought at the end of the line preceding the list. ```markdown {=wdt:Q80} - Name: [Tim Berner's Lee]{foaf:name} - ISNI: [0000 0000 7866 6209]{wd:P213} {wdt}: http://www.wikidata.org/prop/direct/ {wd}: http://www.wikidata.org/entity/ ``` Should yield ```htmlThe web was invented by this geek:
She is 23 and lives in Berlin
Tim Berners Lee invented the web.
He now works on Solid.
Tim Berners Lee invented the web.
He now works on Solid.
A paragraphe after the div ended.
``` ## Declaring prefixes Declare [prefix definitions](#Prefix-definition-syntax), anywhere in the document, preferably at the end to ease readability. ```markdown {.schema:Event} * Date: [10/11/2019]{schema:startDate} * Location: [somewhere]{ex:good_place} {schema}: http://schema.org/ {rdfs}: http://www.w3.org/2000/01/rdf-schema# {ex}: http://example.org/ ``` Should yield ```htmlMy name is Alice
``` :::danger FIXME : The default namespace should make it possible to annotate the document without using a prefix at all. Instead of giving the default both a prefix name _and_ a special annotation, I suggest using `@default` as the prefix itself. ```markdown My name is [Alice]{name}. {@default}: http://example.org/ ``` Would produce the following HTML+RDFa: ```htmlMy name is Alice
``` ::: ### Common prefixes are implicitly defined All prefixes predefined in [RDFa Core Initial Context] can be used without explicitly defining them. ```markdown My name is [Alice]{schema:name}. ``` Would produce the following HTML+RDFa: ```htmlMy name is Alice
``` ## Referring to a IRI ### Absolute IRI reference with <> `Meeting with [Bob]{.Thomas is 39
``` #### IRI written directly as key ```markdown - foaf:name: Thomas Francart - foaf:age = 39 - rdfs:comment: Semantic Web Consultant ``` Should yield ```html