Преобразование ссылок уценки из встроенного в ссылку

У меня есть файл журнала изменений, отформатированный с использованием уценки Github.

Первоначально я использовал встроенные ссылки для каждой ссылки, которую мне нужно было добавить, то есть:

This is some [example](http://www.stackru.com) line of text.

Со временем, когда размер файла увеличился, он стал немного грязным, в основном из-за этого способа вставки ссылок.

Я хотел бы преобразовать все ссылки из встроенного в ссылку (см. Описание каждой), то есть преобразовать приведенную выше строку в это:

This is some [example][1] line of text.

[1]: http://www.stackru.com

Поскольку файл довольно большой и содержит много встроенных ссылок, мне было интересно, есть ли какой-нибудь автоматизированный способ сделать это. Я использую Sublime Text 3 для редактирования, но я не смог найти подходящий пакет для этой задачи. Возможно, какое-то умное регулярное выражение?

4 ответа

Решение

Это большое требование!

Я только что создал новую программу Node.js (я знаю, что это не GUI, но, похоже, что-то, что больше людей хотели бы возможности) сделать это на GitHub.

Вот также код:

// node main.js test.md result.md

var fs = require('fs')
fs.readFile(process.argv[2], 'utf8', function (err, markdown) {
    if (err) {
        return console.log(err);
    }
    var counter = 1;
    var matches = {};
    var matcher = /\[.*?\]\((.*?)\)/g;
    while (match = matcher.exec(markdown)) {
        if (!matches[match[1]]) matches[match[1]] = counter++;
    }
    console.log(matches);
    Object.keys(matches).forEach(function(url) {
        var r = new RegExp("(\\[.*?\\])\\(" + url + "\\)", "g");
        markdown = markdown.replace(r, "$1[" + matches[url] + "]");
        markdown += "\n[" + matches[url] + "]: " + url;
    });

    fs.writeFile(process.argv[3], markdown, 'utf8', function (err) {
        if (err) return console.log(err);
    });

});

Сохранить это как mdrelink.py в вашей папке пакетов, и вы можете запустить его с

view.run_command('mdrelink');

из командной консоли.

Я думаю, что я правильно понял порядок - изменение необходимо, потому что в противном случае он испортил бы уже кэшированные индексы следующих элементов. Также следует автоматически пропустить уже использованные номера ссылок. Мой первый Python и мой первый плагин Sublime, поэтому, пожалуйста, будьте осторожны со мной.

import sublime, sublime_plugin

class mdrelinkCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        oldlinks = []
        self.view.find_all("^\s*(\[\d+\]):", sublime.IGNORECASE, "\\1", oldlinks)
        newlinkpos = self.view.find_all("\[.+?\](\(.+?\))")
        orgtext = []
        self.view.find_all("(\[.+?\])\(.+?\)", sublime.IGNORECASE, "\\1", orgtext)
        orglink = []
        self.view.find_all("\[.+?\]\((.+?)\)", sublime.IGNORECASE, "\\1", orglink)
        orglink.reverse()
        self.view.insert(edit, self.view.size(), '\n\n')
        counter = 1
        newnumbers = []
        for r in newlinkpos:
            while '['+str(counter)+']' in oldlinks:
                 counter += 1
            oldlinks.append('['+str(counter)+']')
            line = '[' + str(counter)+']: '+ orglink.pop() + '\n'
            newnumbers.append('  ['+str(counter)+']')
            self.view.insert(edit, self.view.size(), line)
        for r in reversed(newlinkpos):
            self.view.replace(edit, r, orgtext.pop()+newnumbers.pop())

Наткнулся на этот вопрос благодаря Google. Может быть, это может помочь другим:

Мой ответ не относится к Sublime, но если вы уже используете JavaScript (Node), я бы использовал синтаксический анализатор MD и преобразователь CST, например, comment .

Например, чтобы преобразовать все встроенные ссылки в README.mdдля численно возрастающих ссылок в стиле ссылочного стиля вы можете запустить следующее:

      sudo npm install -g remark-reference-links remark-cli
npx remark README.md -o --use reference-links

Или, если вам нужны ссылки в стиле ссылок, полученные из исходного uri :

      sudo npm install -g remark-defsplit remark-cli
npx remark README.md -o --use defsplit

remark-cliх --useвариант плохо сочетается с npx@6, но, возможно, это можно сократить до временного однострочника с npx@7. То же самое может быть достигнуто с некоторой комбинацией плагинов редактора на основе замечаний. Надеюсь, эта информация поможет таким людям, как я, не тратить целый день на сборку ненадежного решения на основе регулярных выражений :)

расширяя ответ @bjfletcher , ниже приведен код, который учитывает любые существующие ссылки.
Ссылка на суть GitHub .

      // node filename.js ReadMe.md RefLinks.md

import * as fs from 'fs'
fs.readFile(process.argv[2], 'utf8', function (err, mainMarkdown) {
    if (err) {
        return console.log(err);
    }
    let newMarkdown = existingRefLinks(mainMarkdown);

    var counter = 1;
    var matches = {};
    var matcher = /\[.*?\]\((.*?)\)/g
    let match;
    while (match = matcher.exec(newMarkdown)) {
        if (!matches[match[1]]) matches[match[1]] = counter++;
    }
    console.log(matches);
    Object.keys(matches).forEach(function (url) {
        var r = new RegExp("(\\[.*?\\])\\(" + url + "\\)", "g");
        newMarkdown = newMarkdown.replace(r, "$1[" + matches[url] + "]");
        newMarkdown += "\n[" + matches[url] + "]: " + url;
    });

    fs.writeFile(process.argv[3], newMarkdown, 'utf8', function (err) {
        if (err) return console.log(err);
    });

});

function existingRefLinks(markdown) {
    let refLinks = {}, match;
    const matcher = /\[(\d)]:\s(.*)/g; // /\[.*?\]\((.*?)\)/g
    while (match = matcher.exec(markdown)) {
        if (!refLinks[match[1]]) refLinks[match[1]] = match[2];
    }
    markdown = markdown.replaceAll(matcher, "")

    Object.keys(refLinks).forEach(function (int) {
        markdown = markdown.replace("][" + int + "]", "](" + refLinks[int] + ")");
    });
    return markdown
}

Обратите внимание, что я предпочитаю использовать ответ @Xunnamius :

      npm install --save-dev remark-reference-links remark-cli
npx remark README.md -o --use reference-links
Другие вопросы по тегам