Гистови у Markdown-у
- ажурирања сајта
Ових дана после мање паузе радим на неколико делова мог сајта, па једва стижем да нешто и напишем о ономе шта додам. Недавно сам тако додао подршку за учитавање гистова у чланке на овом блогу.
За оне који не знају шта су то гистови (gists), ради се о фајловима, или деловима фајлова, са изворним кодом које је могуће делити и чак fork-овати као било који други фајл на GitHub-у. Просто поставите мини-репо са једним или више фајлова и поделите његов УРЛ. Сјајно! 😃
Ова могућност, која је уједно и тест динамичких компонената о којима сам недавно писао, ми је била посебан изазов и уједно извор материјала за учење Nuxt.js-а. Видећемо које су неке од карактеристичних тачака које сам прешао приликом њеног развоја.
Почетак
Рад са гистовима почињемо посетом УРЛ-а https://gist.github.com, где ће они које означимо као јавне бити доступни на адреси облика
https://gist.github.com/[корисничко_име]/[хеш]
Верзији гиста у формату JSON можемо приступити додавањем .json
на крај те
адресе, дакле:
https://gist.github.com/[корисничко_име]/[хеш].json
Простим позивом this.$axios.$get()
или this.$http.$get()
, у зависности од
тога да ли користимо модул axios или http, учитамо тај JSON и
посао је готов, зар не?
Нажалост, то није баш тако. Уколико вам не смета подразумевано HTML
форматирање поља div
насталог JSON објекта, или чињеница да се сви фајлови
заједно налазе у том (скаларном) пољу, и то је довољно. За било шта више,
потребно је учитати гист преко API-ја.
API
За просто учитавање довољно је методом GET приступити УРЛ-у
http://api.github.com/gists/[хеш]
где је [хеш]
хеш код вашег гиста, исти као у претходном случају. Резултат је
опет JSON објекат, али који укључује фајлове у сировом облику као засебна
поља.
Код
Конкретан код сам раздвојио на онај који је оријентисан на податке (Vuex
store) и презентациони (компонента Gist
). Ево најзанимљивијих делова:
<template> | |
<!-- ... --> | |
</template> | |
<script> | |
export default { | |
name: 'Gist', | |
props: { | |
gist: { type: Object, default: () => ({}), required: true }, | |
filename: { type: String, default: '', required: true }, | |
highlightedLine: { type: Number, default: 0, required: false }, | |
}, | |
computed: { | |
gistRawUrl() | |
{ | |
if (!this || !this.gist || !this.gist.files || this.filename.length==0 | |
|| !this.gist.files[this.filename]) | |
{ | |
return null; | |
} | |
return this.gist.files[this.filename].raw_url; | |
}, | |
gistLines() | |
{ | |
if (!this || !this.gist || !this.gist.files || this.filename.length==0 | |
|| !this.gist.files[this.filename]) | |
{ | |
return null; | |
} | |
return this.gist.files[this.filename].content; | |
}, | |
}, | |
methods: { | |
escapeHtml(html) | |
{ | |
return html | |
.replace(/&/g, '&') | |
.replace(/</g, '<') | |
.replace(/>/g, '>') | |
.replace(/"/g, '"') | |
.replace(/'/g, '''); | |
}, | |
formatGistLinesAsHtml(lines) | |
{ | |
let result = ''; | |
if (lines && lines.length>0) | |
{ | |
let linesArray = lines.split('\n'); | |
for (let line in linesArray) | |
{ | |
result += (this.highlightedLine==parseInt(line)+1 ? | |
'<tr class="highlighted-line">\n' : | |
'<tr>\n') + | |
'<td class="blob-num js-line-number" data-line-number="' + | |
(parseInt(line)+1).toString() + '"></td>\n' + | |
'<td class="blob-code blob-code-inner js-file-line">' + | |
this.escapeHtml(linesArray[line]) + | |
'</td>\n' + | |
'</tr>\n'; | |
} | |
} | |
return result; | |
} | |
}, | |
}; | |
</script> | |
<style lang="sass"> | |
@import '~/assets/sass/gist.sass' | |
</style> | |
Gist.vue
је компонента за приказивање гиста која је намењена директном
укључивању у Markdown фајл. Пошто се фајл преко API-ја учитава као чист
текст, даље се са његовим садржајем може радити било шта. На пример, можемо
означити појединачне линије или истаћи жељени keyword. Ова компонента се у
Markdown фајл укључује на следећи начин:
<component :is="extraComponentLoader" | |
:filename="'nuxt.config.js'" | |
:highlighted-line="15" | |
:gist="gist"></component> | |