Гистови у Markdown-у

19.11.2019

Ових дана после мање паузе радим на неколико делова мог сајта, па једва стижем да нешто и напишем о ономе шта додам. Недавно сам тако додао подршку за учитавање гистова у чланке на овом блогу.

За оне који не знају шта су то гистови (gists), ради се о фајловима, или деловима фајлова, са изворним кодом које је могуће делити и чак fork-овати као било који други фајл на GitHub-у. Просто поставите мини-репо са једним или више фајлова и поделите његов УРЛ. Сјајно! :smiley:

Ова могућност, која је уједно и тест динамичких компонената о којима сам недавно писао, ми је била посебан изазов и уједно извор материјала за учење 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>


Generated by slweb © 2020-2024 Strahinya Radich.