Форум программистов, компьютерный форум, киберфорум
Наши страницы
Mysterious Light
Войти
Регистрация
Восстановить пароль
Оценить эту запись

Построение графа зависимостей файлов вики в разметке Markdown стадартными средствами

Запись от Mysterious Light размещена 08.10.2017 в 23:42
Метки bash, dot, markdown, sed, shell

Есть папка wiki/, в ней есть какие-то файлы, среди которых есть *.md, оформленные в Markdown.
В этих файлах есть ссылки, имеющие вид [текст ссылки](адрес).
Адрес ссылки на другие md-файлы выглядит как обычный относительный путь, но без расширения .md.
Например, если в A/a.md имеется ссылка на файл B/b.md, то он будет оформлен в виде [какой-то текст](../B/b)

Задача:
1) построить граф всех имеющихся файлов с указанием гиперссылок между ними. Включить в этот граф несуществующие файлы, на которые тем не менее имеется ссылка хотя бы в одном существующем.
2) использовать стандартные средства (shell, cp, rm, grep, sed, awk, dot etc)

Первая часть задачи возникла на практике и потому иметь решение важно для меня.

Вторая часть задача обусловлена тем, что мне очень хочется изучить sed и вспомнить shell, а для этого нужна чёткая задача. Данная задача подходит очень хорошо на роль тестовой.

На данный момент я набросал работающее решение, которое я, однако, не нахожу красивым, ввиду того, что
1. используются 5 (пять!) вспомогательных файлов,
2. используется один вспомогательный скрипт,
3. не используется полный потенциал sed, в частности, инструкции i и a и вторичный буфер,
4. используются много простых преобразований потоков вместо нескольких сложных.

Вспомогательный скрипт parse.sh
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/sh
 
# file to parse
file=$1;
 
if [ -e "$file" ];
then
 
  # file's directory
  fdir=$(dirname $file)
 
  # escaped file name
  filestr=$(echo "$file" | sed 's/\//\\\//g');
 
  # find all the references of the form [...](url)
  sed '/\n/{P;D;};/](/s//\n/;s/\(\n[^)]*\))/\1\n/;D' $file |\
  # drop files with extentions and URL with '://'
  grep -v -e "\.[a-zA-Z]*$" | grep -v -e ":\/\/" |\
  # resolve paths
  xargs -n 1 -d "\n" -I url realpath "$fdir/url.md" |\
  # add them to allfiles
  tee -a allfiles.tmp |\
  # return a list of edges of the form (file -> url)
  sed "s/^.*\$/$filestr -> &/"
 
fi
Основной скрипт refGraph.sh, располагается в той же директории, что parse.sh
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/sh
 
# directory to process
dir=wiki;
 
# a list of md-files (full paths)
find $dir -name "*.md" -exec realpath -m {} \; >files.tmp;
 
# a list of all files, including those mentioned in references
cp files.tmp allfiles.tmp;
 
parseScriptPath="$(dirname $0)/parse.sh";
 
# edges
cat files.tmp | uniq | xargs -n 1 -d "\n" sh "$parseScriptPath" >edges.tmp;
 
# replacement rules (md-file -> index) in sed format
sort allfiles.tmp | uniq | sed '=; s/\//\\\//g' |\
  sed 'N; s/\([0-9]*\)\n\(\S*\)/s\/\2\/\1\/g/' >rules.tmp;
 
exec > output.tmp
echo "digraph {";
echo "  graph [rankdir=LR]";
echo "  node [imagescale=true]";
sort allfiles.tmp | uniq |\
  xargs -n 1 -d "\n" realpath --relative-to $dir |\
  sed '=; s/.*/\[label=\"&\"];/' |\
  sed 'N; s/\n/ /';
cat edges.tmp | sed -f rules.tmp | sort | uniq;
echo "}";
 
dot -Tps -o ref.ps output.tmp;
 
rm output.tmp files.tmp allfiles.tmp edges.tmp rules.tmp;
Я создал тему Поиск и печать ссылок в Markdown-файле [sed], в которой задаю какие-то вопросы по sed. По мере просветления буду переписывать этот код, конвергируя к совершенству. в пределе бесконечного времени. может быть.
Размещено в Без категории
Просмотров 370 Комментарии 0
Всего комментариев 0
Комментарии
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru