I have a Markdown file which contains release notes. For example:
## 1.0.0
### New
#### Added new language support
### Fixed
#### This is fixed
#### This is fixed
### Changed
#### Something changed
### Feature
#### New Feature Added
## 2.0.0
### New
#### Added new language support
In my HTML, I would like loop over the release notes for all new releases. I have queried the document in the page like so:
<template>
<changelog :article="article"/>
</template>
<script lang="ts">
import Vue from "vue";
export default Vue.extend({
async asyncData({ $content }) {
const article = await $content("changelogs/iOS/changelog").fetch();
return { article };
},
watchQuery: true,
});
</script>
In my component, I have:
<template>
<article :document="article">
</template>
The parse result of the content is stored in article.body.children[]
. Each child contains the following node data:
tag
- HTML tag (e.g., h2
, h3
)type
- Element type (e.g., element
, text
)value
- Element value (the text contents)props
- Extra props data, including id
children[]
- Child nodesYou could use that info to parse the nodes into a convenient data structure that stores release info, such as:
title
from the text
child of h2
id
from props
of h2
changes[]
to hold the change lines, each containing:
id
from props
of h4
type
from the text
child of h3
text
from the text
child of h4
const elems = article.body.children.filter(node => node.type === 'element')
let rel = {}
let type = ''
for (const node of elems) {
if (node.tag === 'h2') {
rel = {
id: node.props.id,
title: node.children.find(c => c.type === 'text').value,
changes: []
}
this.releases.push(rel)
} else if (node.tag === 'h3') {
type = node.children.find(c => c.type === 'text').value
} else if (node.tag === 'h4') {
rel.changes.push({
id: node.props.id,
type,
text: node.children.find(c => c.type === 'text').value,
})
}
}
Then, use v-for
to render the list of release info parsed above.
<article v-for="rel of releases" :key="rel.id">
<h3 class="title">{{ rel.title }}</h3>
<section class="change" v-for="change in rel.changes" :key="change.id">
<div class="type" :class="change.type">{{ change.type }}</div>
<div class="text">{{ change.text }}</div>
</section>
</article>