Zagnieżdżanie listy na podstawie wcięć w łańcuchu znaków - markdown previewer

0

Cześć,

Jak stworzyć listę za pomocą JS z poniższego stringa? Każde wcięcie to kolejne zagnieżdżenie.

- And of course there are lists.
  - Some are bulleted.
     - With different indentation levels.
        - That look like this.

Czy da się w tym przypadku użyć document.createElement ?

Pozdrawiam

0
Michał Stróż napisał(a):

Czy da się w tym przypadku użyć document.createElement ?

  • Czy da się wbić gwoźdź za pomocą mikroskopu elektronowego?
  • Owszem, ale czy nie jest to zbyt kosztowne rozwiązanie?
0

Ok,

Jaki jest w takim razie najbardziej optymalny sposób przerabiania takiego łańcucha znaków?
Warto zaznaczyć, że gdy w danym punkcie listy zostanie wykryty element inline, to należy go w tym miejscu stworzyć.

Pozdrawiam.

0

Moim zdaniem document.createElement da radę, ważne, żeby nie pushować tych zmian od razu do DOM tylko zbudować całe drzewo i na końcu zrobić jakiś append.

Nie chcesz przypadkiem stworzyć jakiegoś "czytnika" Markdown? Tutaj np. https://github.com/developit/snarkdown/blob/master/src/index.js masz gotowca.

0
Markuz napisał(a):

Nie chcesz przypadkiem stworzyć jakiegoś "czytnika" Markdown? Tutaj np. https://github.com/developit/snarkdown/blob/master/src/index.js masz gotowca.

Dzięki za radę. Sprawdziłem ten previewer, ale niestety nie ma zagnieżdżania. Poza tym jakoś dziwnie mi muli komputer i nie wiem czy tylko mi. Tutaj jest strona do wypróbowania: https://snarky.surge.sh/

Natomiast posiedziałem chwilę i wymyśliłem jak mój problem rozwiązać. Wkleję tutaj, może się komuś przyda:

const previewer = document.querySelector('#previewer');
const str = `- And of course there are lists.
  - Some are bulleted.
     - With different indentation levels.
        - That look like this.`;

function setUnorderedList(str, previewer) {
    let strArr = str.split('\n').filter(v => v.trim() !== '');
    let i = 0;

    (function createList(depth, parent = previewer) {
        while (i < strArr.length) {
            const [whiteSigns, data] = strArr[i].split('- ');
            const whiteSignsLength = whiteSigns.length;

            if (whiteSignsLength < depth) {
                break;
            } else if (whiteSignsLength === depth) {
                if (parent.localName === 'li') {
                    parent = parent.parentElement;
                }

                const li = document.createElement('li');
                const content = document.createTextNode(data);
                li.appendChild(content);
                setInlineElement(li);
                parent.appendChild(li);
                i++;
            } else {
                if (parent !== previewer) {
                    parent = parent.lastChild;
                }

                const ul = document.createElement('ul');
                ul.className = 'previewerUnorderedList';
                createList(whiteSignsLength, ul);
                parent.appendChild(ul);
            }
        }
    })(-1);
}

function setInlineElement(element) {
    let txt = element.innerHTML;

    txt = txt.replace(/`.+`/g, (match) => {
        const str = match.slice(1, match.length - 1).trim();
        const signIndex = str.indexOf('`');
        if (signIndex === -1) {
            return `<code class="inlineCode">${str}</code>`;
        } else {
            return match;
        }
    });

    txt = txt.replace(/\*\*.+\*\*/g, (match) => {
        const str = match.slice(2, match.length - 2).trim();
        return `<b class="boldText">${str}</b>`;
    });

    txt = txt.replace(/_.+_/g, (match) => {
        const str = match.slice(1, match.length - 1).trim();
        return `<i class="italicText">${str}</i>`;
    });

    txt = txt.replace(/~~.+~~/g, (match) => {
        const str = match.slice(2, match.length - 2).trim();
        return `<del class="crossedLine">${str}</del>`
    });

    txt = txt.replace(/\[.+]\(.*\)/g, (match) => {
        const href = match.slice(match.indexOf('(') + 1, match.indexOf(')')).trim();
        const val = match.slice(match.indexOf('[') + 1, match.indexOf(']')).trim();
        return `<a class="link" target="_blank" href="${href}">${val}</a>`;
    });

    element.innerHTML = txt;
}

setUnorderedList(str, previewer);

Co sądzicie o takim wykonaniu?

1 użytkowników online, w tym zalogowanych: 0, gości: 1