Вы как-то говорили на семинаре про циклическое повторение идей... Насчет того, что всегда можно найти аналоги любых новшеств в прошлом. У меня тут большая коллекция старых журналов - знаете, там и вправду столько идей на тему Сети! Некоторые даже не применялись, потому что их еще не заметили... как будто.
(c)
Паутина 2009-12-07 14:24
Прошло достаточно времени после того, как я писал про Аффигительно Большой Файл последний раз. С тех пор накопилось множество новшеств (в частности, я снова сменил систему нотации в файле, что облегчило "ручное управление" и сделало его совместимым с маркдаун системами почти на 100%, но это - отдельный разговор). Однако, главным из этих новшеств было то, что я наконец нашел третий компонент из
формулы urbansheep. Я сделал карту для АБТФ.
Некое подобие карты было у меня и до этого. У меня был отдельный скрипт на питоне, который генерировал на основе АБТФ майндмэп для freemind'а, но при всех преимуществах у этой системы было несколько недостатков:
- "тихоходность" самого freemind (по сравнению с практически мгновенным стартом Vim'а)
- отсутствие возможности перейти от ветки майндмэпа к соответствующей статье в блоге (может в новый fm встроят - там посмотрим)
Начну издалека. В комплекте с Vim я использую TVO - Vim-органайзер, о котором я уже упоминал, причем не один раз. Органайзер ставится поверх Vim и представляет собой очень грамотную настройку его режима фолдинга. Грубо говоря - все статьи "схлопываются" в режиме аутлайнера ориентируясь на количество табов или отступов в строке. На сайте это подробно показано.
Дальше. Мне в руки случайно попалась книга Рассела Сейджа "Профессиональное использование Unix". Издание 1985 года :) Та еще старина. Решил полистать из любопытства - посмотреть как жили древние юниксоиды. Оказалось, интересно жили. Книга полна рецептов "на все случаи жизни", которые дают богатую пищу для размышлений, а главное - подкидывают идеи - в каком направлении мыслить.
Одна из таких идей - утилита tree, которая показывает (точнее - рисует) файловую систему в виде дерева, нарисованного псевдографикой. Идея достаточно простая - чем глубже находится папка или файл в иерархии вложенных папок, тем больше больше она сдвинута в строке. В итоге получается псевдографическое "дерево". У Сейджа это реализовано с помощью шелл-скрипта, в наши времена существует отдельная программа, которую можно себе поставить (sudo apt-get install tree).
Читаю я про эту утилиту - и мне приходит в голову, что можно реализовать ее и для моего АБТФ. Иерархия вполне себе наличествует - записи вложены одна в другую. А получить такую картинку "дерева блога" будет интересно и наглядно... И тут я понимаю - если сделать это не в виде псевдографической картинке, а просто с отступами табуляцией (чем "глубже" заголовок в иерархии - тем больше табов) - то получится аутлайн заголовков блога. Если сохранить его, как .otl и открыть в виме - получится свертвывающаяся и развертывающаяся "модель" блога.
Реализовать это совсем несложно - сейчас у меня самые верхние заголовки имеют один # в заголовке, заголовки второго уровня - ##, третьего - ### и так далее. Достаточно поиском пройти по файлу, скопировать оттуда все заголовки (у которых первым символом в строке стоит '#') и поменять в них # на знак табуляции.
Чтобы сделать скрипт универсальным можно выдавать результат работы не в файл, а на стандартный вывод (в stdin) - попросу печатать его на экран. Тогда его можно будет запускать так:
$ python ztree.py main.txt > main.map.otl
И потом открывать:
$ gvim main.map.otl main.txt
Но этого мало. Хочется, чтобы можно было от конкретной ветки аутлайна перескочить к соответствующей статье в файле. Можно ли это сделать? В принципе реально - номер строки, где находится каждый из заголовков у меня есть, вставить в файл я его могу... но как переключаться? Можно конечно сначала подсматривать номер строки заголовока в аутлайне-карте, потом переключаться в файл блога, набирать <номер строки>G и попадать в нужное место. Но это долго и нудно.
В виме есть команда перехода к файлу - gf. Можно встать курсором на имя файла, набрать gf и - оказаться в нужном файле. С той оговоркой, что этот файл есть в путях (в переменной "path") вима. Но можно ли сделать так, чтобы оказаться сразу в нужной строке?
Закапываюсь в документацию - :h gf и листаю ее по окрестностям. Ага! Есть! Есть такая команда. Если имя файла задано как <имя файла> <номер строки> или <имя файла> : <номер строки>, то по команде gF (то есть не gf, а gF) - вим перейдет к нужному файлу и внутри него прыгнет на нужную строку. То, что нужно. Пишу скрипт на Питоне, который, если ему скормить блог генерирует дерево заголовков и под каждым заголовком пишет строку вида:
Домоводство
| /home/vik/blog/main.txt : 19329
СпискиХранения
| /home/vik/blog/main.txt : 19358
КнижныйШкаф
| /home/vik/blog/main.txt : 19365
Кухня
| /home/vik/blog/main.txt : 19379
Пароварка
| /home/vik/blog/main.txt : 19514
ГочицаСодаДляПосуды
| /home/vik/blog/main.txt : 19537
И так далее.
Скрипт на Питоне, который генерирует карту моего блога выглядит так:
# -*- coding: utf8 -*-
import sys
def main():
# получаем имя обрабатываемого файла
name = sys.argv[1:]
tm = str(name[-1])
# открываем файл и считываем оттуда текст
fh = open(tm,'rb')
line = fh.readlines()
fh.close()
zag = [] # список заголовков
num = [] # номера строк
link = []# сборник линков на заголовки
# проходим по тексту и модифицируем содержимое
for i in range(len(line)):
stroka = line[i]
if stroka[0] == '#':
zag.append(stroka)
num.append(i)
for j in range(len(zag)):
zag[j] = zag[j].replace('#','\t')
link.append(str(zag[j].partition(' ')[0] + '| '+ tm + ' : ' +str(num[j]+1)))
# выдаем в stdout содержимое
for j in range(len(zag)):
print(zag[j]+'\t'+link[j])
print "\t\tдля дневниковой записи:"
print ('\t\t| '+ tm + ' : ' +str(len(line)+1))
print "| vim:foldlevel=1 path+=.,.."
if __name__ == "__main__":
main()
В vimrc у меня прописана следующая строка:
map \mm :!python ztree.py % > otl/%<.otl :e otl/%<.otl
Кроме нее в .vimrc есть две строки:
au BufNewFile,BufRead *.otl map gf gF
au BufNewFile,BufRead *.otl map gF
Они обе при загрузке в память файла .otl - переназначают внутри него gF на gf или просто Enter. Зачем? Для удобной навигации по заголовкам.
Как это работает?
В открытом блоге я нажимаю \mm
Это скармливает скрипту текущий текстовый файл, скрипт генерирует карту, сохраняет ее в подпапку ../otl и сразу же открывает эту карту в виме.
В этой карте заранее прописан моделайн.
vim:foldlevel=1 path+=.,..
Он определяет уровень развертывания аутлайна (все заголовки нулевого и первого уровня) и путь поиска файлов (искать файлы в этой папке и на уровень выше ее). Можно было прописать путь к папке с блогами, но я часто работаю с флэшки и такая форма мне удобнее.
Итак. У меня в виме дополнительным буфером открыта карта блога.
Если я хочу вернуться назад к блогу я всегда могу сделать :bp
Если я хочу найти нужный заголовок - можно использовать поиск по слэшу.
Если мне нужно перейти на заголовок - я становлюсь курсором на строчку под ним (например на | /home/vik/blog/main.txt : 19329) и нажимаю либо gF, либо gf, либо Enter - все это сразу перебрасывает меня на нужное место в блоге.
В любой момент доступна история перемещений (Ctrl+O - назад, Ctrl+I - вперед) и вообще карта лежит в списке буферов отдельным файлом и с ней можно делать все, что заблагорассудится.
P.S.
2010-01-20 13:32 Этот пост я начал писать в начале декабря, когда внедрил систему у себя, потом меня отвлекли от. Так что к этому времени, эта система уже прошла без малого двухмесячную обкатку на практике. Это действительно - "быстрое решение", которое делает работу с АБТФ комфортной и в принципе дополняет систему до того функционала, которого мне жутко не хватало после того как я ушел с WinOrganizer
И еще одно позднее примечание по опыту эксплуатации системы - аутлайнер необязателен на самом деле. Он упрощает работу лично мне, потому, что я к нему давно привык и это - мой инструмент, но на самом деле можно использовать фолдинг - то есть не возится с отступами, а тупо копировать в документ заголовки и их координаты. Но это - при желании можно будет сделать темой отдельного разговора.