У меня иногда складывается впечатление, что не он служит для нас, а мы служим для этого формата. Поэтому — сэр Markdown.
— Мы знаем, что ныне лежит на весах
И что совершается ныне.
Час мужества пробил на наших часах,
И мужество нас не покинет.
Не страшно под пулями мертвыми лечь,
Не горько остаться без крова.
И мы сохраним тебя, русская речь,
Великое русское слово.
Свободным и чистым тебя пронесем,
И внукам дадим, и от плена спасем —
Навеки.
Добрый вечер, друзья, меня зовут Сергей Бочаров. Я начал со стихотворения Анны Ахматовой «Мужество». Оно было написано в 1942 году, в период Великой Отечественной войны, и уже тогда поэтесса понимала, что вернуть, выстроить разбитые бомбежкой заводы и фабрики будет гораздо легче, чем вернуть духовное богатство, растраченное и фактически растоптанное за годы войны.
Поэзия является одним из немногих средств, которое помогает нам научиться чувствовать прекрасное. Сегодня мы говорим о технической документации — казалось бы, такой далекой области от поэзии, но сохранение прекрасного, сохранение единого стиля очень актуально, особенно при работе с данным форматом. Markdown де факто стал стандартом написания технической документации в мире открытого ПО. И объединил людей разных специальностей.
У меня тяжелая и одновременно приятная миссия. Я хочу, чтобы у вас осталось полное ощущение сборки Markdown-документации в Яндексе, а также поделюсь инструментами, которые мы разработали. Надеюсь, вы тоже будете их использовать в своих проектах.
Инструменты, которые разработаны, написаны на JS, потому что мы в Яндексе любим JavaScript. И вся разработка ведется вокруг этого языка. Тут не стоит расстраиваться, если у вас другая среда разработки или хайповый React — думаю, можно найти аналоги на GitHub.
Наверное, многие задаются вопросом, почему же Markdown стал сэром? Это метафора, и она связана с тем, что мы в Яндексе стараемся роботизировать любой процесс.
Вокруг Markdown тоже разрабатывается большое количество инструментов. На сегодняшний день мы уже разработали очень много инструментов, продолжаем разрабатывать. У меня иногда складывается впечатление, что не он служит для нас, а мы служим для этого формата. Поэтому — сэр Markdown.
![](https://habrastorage.org/webt/xu/wf/z3/xuwfz3jwn-s5hoflvbwwzm_jyw4.jpeg)
В первой глобальной части мы поговорим о том, зачем мы пишем в этом формате, зачем разрабатываем для него какие-то инструменты. Во второй части поговорим более детально на примере нашей библиотеки о том, как сохранять качество контента, как переводить его и как из множества репозиториев собирать один сайт.
Markdown был создан в 2004 году Джоном Грубером и Аароном Шварцом. Идея заключалась в том, чтобы иметь простой текстовый синтаксис и затем его конвертировать в более богатый и валидный HTML.
![](https://habrastorage.org/webt/ji/bd/xd/jibdxd39ayy-6yjh3ajvl5zbn4y.jpeg)
У нас есть заголовок первого уровня, второго уровня и какой-то абзац текста.
Зачем новый формат, когда есть DITA с более богатыми тулзами? Зачем создавать новые инструменты для Markdown? Давайте попробуем ответить вместе.
![](https://habrastorage.org/webt/fp/4s/eu/fp4seufp6pxfjvjktmkundk46uq.jpeg)
У DITA более сложный синтаксис, и для работы с ней желательно иметь определенную среду разработки. Понятно, что это XML-формат, он также открывается в текстовом редакторе. Но SVG тоже в нем открывается, при этом никто там не рисует — все используют Photoshop или Sketch.
Markdown с точностью до наоборот имеет более легкий синтаксис, поэтому он так полюбился многим разработчикам. Как следствие, документация в Markdown пишется и поддерживается техническим писателем с активным участием контрибьюторов и разработчиков, а документация в DITA часто разрабатывается только техническим писателем, активного участия разработчики и контрибьюторы не принимают.
Ярким примером сайта с документацией Markdown является сайт npm, на сегодняшний день он содержит 475 тысяч модулей, и с каждым днем их становится все больше.
![](https://habrastorage.org/webt/we/he/ek/weheekond4lz0tdiremzaiajdmk.jpeg)
Вот самые популярные из них. Если зайти на сайт любого, например Gulp, и перейти в раздел документации, мы сразу попадаем на GitHub, где видим, что API gulp.js описано в Markdown.
![](https://habrastorage.org/webt/b9/q4/hf/b9q4hfwbomzp4iknw3qvtyhy3ns.jpeg)
Поэтому если вы по каким-то причинам еще не используете Markdown или обходите его стороной — пожалуйста, используйте и сделайте ваших разработчиков счастливыми.
Стиль и синтаксис. Предлагаю рассмотреть на примере нашей внутренней библиотеки Лего, суперсекретной. Сейчас продемонстрирую.
![](https://habrastorage.org/webt/wy/e4/ck/wye4ckpre56y4roqhagwckkdwhe.jpeg)
Неожиданно, правда? Все эти блоки различны. Вот блок logo, teaser и т. д. И хранятся они на GitHub, стандарт де факто.
![](https://habrastorage.org/webt/xu/49/um/xu49umgdth6hpkhmkqg9dyws_fo.jpeg)
Здесь есть общее описание библиотеки, также есть директории блоков, и в каждой директории есть описание этого блока. Документацию мы рассматриваем как часть кода, поэтому называем соответствующим именем. Это также удобно в случае замены, search & replace. Когда-то над каждым документом поработал технический писатель. Над англоязычными версиями также поработал переводчик, и в идеале документация, русская и англоязычная версии, должны быть консистентны, то есть структура и содержание у них должны быть одинаковыми.
Над документацией также активно работают сами разработчики, их очень много. Процесс, который мы стараемся выстроить в компании, выглядит следующим образом: разработчик, разработав новую функциональность или новый блок, ставит задачу техническому писателю в виде пул-реквеста или issue.
Технический писатель эту функциональность описывает, после чего отдает на перевод, если нужна языковая версия документа. И все счастливы, но это идеальный мир. А в реальном мире часто ситуация следующая: разработчик сам приходит и вносит правки в документацию.
![](https://habrastorage.org/webt/vh/3r/tn/vh3rtn7qjmuzb0uc5acbsbl9cxa.jpeg)
Здесь мы сталкиваемся с первой проблемой — потерей консистентности. Следующая проблема — также изменяется стиль написания документации.
![](https://habrastorage.org/webt/hh/mi/qy/hhmiqy5w0ocrbtyejai15bvyqr4.jpeg)
Кажется — подумаешь, главное-то, что функциональность описана. Оказывается, нет. После того, как документ написал технический писатель, разработчики были счастливы.
Потом, когда туда со своими коммитами пришли еще несколько десятков разработчиков, они уже подрасстроились и в итоге заплакали. Говорят — нужно переписать документ, он стал непонятный, его невозможно читать, там очень много различных непонятных конструкций, мертвяков, маркеров проблемного текста.
С ними нужно как-то уметь бороться. Технические писатели знают и умеют с ними бороться, а разработчики часто допускают их в документации, и такую документацию некомфортно читать.
![](https://habrastorage.org/webt/lv/ia/cr/lviacrn202a_p8g8b78uvmhizc8.jpeg)
Например, тут всем комфортно? Все понимают, о чем речь? Очевидно, речь идет о git, и такое встречается в нашей документации. Вот более понятный вариант.
![](https://habrastorage.org/webt/ch/hp/xj/chhpxjs9glk_jcj8ostxsubr_vm.jpeg)
Разработчики, которые имеют небольшой опыт работы с GitHub, иногда встречают сложности, когда читают документацию, которую написали гуру-разработчики. Поэтому мы добавляем следующую проблему — сохранение стиля и терминологии. Разработчики очень много коммитят, и технического писателя уже практически не видно, единство стиля нарушено.
![](https://habrastorage.org/webt/ep/rn/xp/eprnxpnnxmiykcqyzo2ckbdaixs.jpeg)
Следующая проблема при таком подходе — у нас нарушается синтаксис. Markdown позволяет писать совершенно по-разному и получать один и тот же результат. У разработчиков технической документации на каждый случай есть договоренность о том, как мы пишем заголовки, списки, вставляем скриншоты и т. д.
Действительно, реальность часто отличается от желаемого, и с этой проблемой тоже нужно уметь бороться. Казалось бы, результат ожидаемый, но если эту проблему не решить сейчас, ее придется решать на этапе сборки. Часто возникает задача — например, найти все заголовки третьего уровня с бэктиками и увеличить на два пикселя. Если мы ее не решаем на этапе линтинга, то придется решать ее на этапе сборки, писать большие скрипты.
![](https://habrastorage.org/webt/sw/b2/qb/swb2qbcahfnv0xkonl47_ltpjr0.jpeg)
Поэтому обавляем следующую проблему — синтаксис Markdown. У нас получилось три основных вызова, с которыми мы боремся. Также у нас есть опенсорсные проекты, в частности БЭМ. У опенсорсных проектов помимо разработчиков, технических писателей и переводчиков есть еще контрибьюторы. Контрибьюторы помогают делать наши продукты лучше, за что мы им благодарны. Их очень много. Они присылают нам свои пул-реквесты, а мы с ними делимся качественным контентом. Поэтому однозначно надо как-то искать пути решения.
![](https://habrastorage.org/webt/qq/tv/p_/qqtvp_rvosqf7zmfuvaiaek0nhu.jpeg)
Следующий раздел посвящен автопроверке, линтингу. Тому, что можно сделать, чтобы как-то научиться согласованно проверять синтаксис Markdown, находить грамматические ошибки и маркеры проблемного текста. Это мой любимый раздел. Считаю, прогрессия линтинга работает на прогрессию технического писателя.
Начнем с инструмента под названием remark-lint. Он позволяет проверять синтаксис и стиль написания. Сам remark находится в открытом доступе, он разработан не нами, мы его используем, у него есть собственный набор правил, их больше 50. Поверх этих правил мы написали свои правила, внесли наш гайд в remark.
![](https://habrastorage.org/webt/s-/sn/dd/s-snddlehkdgvwpqih8vvc2h57a.jpeg)
Как это работает? Допустим, есть тестовый файл с содержанием, есть заголовок первого уровня, второго и какой-то список.
![](https://habrastorage.org/webt/0h/ai/oc/0haiocedpv9bnja3tnxyckmak7w.jpeg)
Мы вводим команду в терминале. Это команда у нас на прекоммите обрабатывается, показываю. Когда технический писатель совершает коммит на GitHub и документ в порядке, выводится сообщение, что ошибок нет. И коммит уходит на GitHub. Предположим, у нас есть ошибки — например, сделаем в первом заголовке его вторым уровнем, а во втором заголовке добавим «Привет» и восклицательный знак. Выполняем ту же команду, и у нас появляется три ошибки.
![](https://habrastorage.org/webt/bz/ts/zm/bztszmyvag1sz-1xvqsuoy4aytw.jpeg)
Прогрессия линтинга работает на прогрессию технического писателя. Технический писатель вспоминает, что мы договорились не ставить восклицательные знаки в заголовках, правит, все отлично. Как же подключаются эти правила? В корне проекта лежит файла remarkrc, в нем мы определяем набор собственных правил (их я сократил) и набор заимствованных правил самого remark.
Следующий инструмент — yaspeller. Он проверяет грамматику и наличие орфографических ошибок в документации. Документация есть на Яндекс.Технологиях — она, кстати, написана в git. Вы можете ее прочитать, там все работает по тому же принципу: есть орфографическая ошибка — выводится сообщение. Контрибьюторы, разработчики, которые пытаются сделать вам пул-реквест, прислать какие-то исправления, они не смогут их прислать с орфографическими ошибками или неточностями в синтаксисе Markdown. Так что эти инструменты очень удобно подключать, и отрабатывают они на прекоммите.
Следующий раздел посвящен переводу. Мы разработали инструмент md2xliff. Переводим мы очень много опенсорсной документации и чуть-чуть внутренней. В случае опенсорсной документации у нас есть контрибьюторы, которые присылают свои пул-реквесты, а чтобы им было удобнее их присылать, мы для них на нашем сайте делаем плашки, в которых предлагаем им пройти по ссылке либо через интерфейс GitHub, либо используя сервис prose.io. Например, они заходят, вносят изменения, нажимают ОК, и к нам прилетает пул-реквест.
Как же все это поддерживать? Допустим, документ написал технический писатель, переводчик его перевел, пришел пользователь — изначально в русскоязычную версию — и что-то там поправил. Как быть с английской версией? Нужно там что-то править или нет? Непонятно. Как искать опечатку, что была исправлена, тоже непонятно. Либо можно пойти на GitHub и там в diff смотреть разницу. Но это та еще задача, нужно же поставить ее переводчику. Необходимо искать решение.
![](https://habrastorage.org/webt/iq/hb/yg/iqhbyg_rywcazqjbi2g10hle-tk.jpeg)
Бывает вторая ситуация. Например, разработчик написал вторую версию библиотеки, и взял не весь документ, не переписал 30 страниц, а тут кусочек удалил, там добавил. И если удалил — непонятно, что делать. Надо идти и как-то сверять это в diff на GitHub.
Как быть? Кажется, это сложная ситуация, при которой выхода нет. Однако если кто-то из вас работал с переводами, он наверняка знает, что есть куча стандартов, и при ближайшем рассмотрении решение выглядит примерно так: есть тестовый файл и какой-то текст документации, который лежит на GitHub. Что нужно сделать? Нужно сгенерировать из него два файла, скелет и XLIFF перевода.
![](https://habrastorage.org/webt/sm/ei/ak/smeiakowlhlhdcefcwoitkpzfdy.jpeg)
![](https://habrastorage.org/webt/p_/an/1z/p_an1zrwwpa5lerbpycpy7gxr1u.jpeg)
Скелет представляет из себя блочное форматирование, то есть мы подменяем куски текста на такие плейсхолдеры с цифрами.
![](https://habrastorage.org/webt/bl/kh/c8/blkhc86qc8tbavqnubvlynz4ue8.jpeg)
XLIFF — специальный формат, он описан, у него есть спецификация, там все просто. Самое главное, что в XLIFF есть юниты, и id юнита соответствует тому сегменту, который мы подменили в скелете.
![](https://habrastorage.org/webt/jy/ga/zm/jygazm_tem4smolxw_z1gmuqh9g.jpeg)
Также в каждом юните есть два тега: source и target. В теге source находится именно тот кусок текста, который мы заменили в скелете, а поле target изначально пустое. Мы отдаем этот XLIFF переводчику. Теперь поле target на выходе заполнено. После перевода делаем обратную генерацию и получаем английскую версию документа.
![](https://habrastorage.org/webt/mr/-_/8m/mr-_8m4c7wds-wddv_wq1skd9tm.jpeg)
![](https://habrastorage.org/webt/tx/a1/qm/txa1qm-tagblgv2a7mpkr2njvrk.jpeg)
При этом перевод у нас никуда не пропадает, а сохраняется в специальном стандартизированном XML-файле TMX. Там лежат два значения: source и target. Как это нам помогает? Возвращаемся к прошлой ситуации. Пришли контрибьюторы, разработчики или другой технический писатель и что-то поправили в исходном документе. В русскоязычной версии, например.
![](https://habrastorage.org/webt/zg/nd/el/zgndelldeunq789qmdt0nq7py7c.jpeg)
Мы по-прежнему генерируем XLIFF, отдаем его переводчику, он применяет ту базу, которая у него сохранена в программе и переводит ровно те сегменты, которые изменились. Он не переводит строки, которые имеют стопроцентное совпадение — они сами автозаменой заменяются. Таким образом, больше нет проблемы искать, что же поменялось. Мы гарантируем, что все строки, которые хоть как-то были изменены, будут видны в переводе. Далее мы генерируем английскую версию документа, все просто. Кажется, что есть готовое решение — просто потому что наверняка они должны быть.
![](https://habrastorage.org/webt/ee/zm/en/eezmenhyo-2-6jndsav1ff405iu.jpeg)
Есть smartcat.ai от ABBYY, есть решение от Google и есть Matecat. Но тотальные недостатки этих решений в том, что они не поддерживают Markdown, у которого нет единого стандарта того, как писать. И они обходят его стороной, поддерживают любые стандартизированные форматы. На прошлой неделе я проверял Markdown в matecat, там все краснеет. Хотя Markdown был простенький.
Возьмем, например, наш инструмент со сложной вложенностью. Если у вас код, внутри него три бэктика, и там есть JSDoc, он со всем справляется на 99%, уровень вложенности может быть любым.
Второй фатальный недостаток этих сервисов — они не интегрируются с GitHub. Мы же хотим, чтобы к нам пользователь пришел через ссылку и что-то поправил, а они не интегрируются.
![](https://habrastorage.org/webt/gg/uk/o-/gguko-tvjsu8m5hpgvwu3wlkumo.jpeg)
Мы все это обсуждали. Когда есть исходный документ на русском, и мы переводим на другой язык, у нас есть определенная пара, жесткая привязанность к русскому языку. Мы работаем над тем, чтобы избавиться от этой привязанности, чтобы мы могли править TMX на лету, независимо от того, куда придет пользователь. Он может прийти в русскую версию, а может в английскую, и мы должны развернуть TMX прямо при генерации. Пока это не решено.
Сборку сайта предлагаю рассмотреть в рамках общего обзора пути Markdown-документа от момента написания до момента выкладки на сайт.
![](https://habrastorage.org/webt/4v/-c/jf/4v-cjf6wh3swsxe-lzckfk3gn5e.jpeg)
Как выглядит рабочий процесс? Предположим, план работ составлен, собрана вся информация. Если говорить о Markdown, здесь важно соблюдать договоренность о синтаксисе. После чего происходит автопроверка, она отрабатывает на прекоммите наши линтинги. Далее документ попадает на GitHub. Если нужна англоязычная версия, мы документ локализуем. После происходит сборка, и там две истории. Одна — когда документ один к одному мапится на страницу, а вторая — когда нужно построить различные инлайновые примеры. В страничку нужно встроить iframe и т. д. У нас есть инструмент, который все это умеет, горшочек. Он умеет подменять ссылки, объединять различные Markdown-документы в один, умеет строить инлайновые примеры. Затем происходит выкладка на сайт.
Зачем вообще нужен сайт? Почему, как на gulp.js, не хранить всю документацию в Markdown?
![](https://habrastorage.org/webt/l3/n4/es/l3n4esakojtwmxos9psvfz84n5c.jpeg)
Ответ очевиден — нужна единая точка входа. У нас больше ста репозиториев, и мы хотим, чтобы эти документы были собраны в одном месте. Также нужны поиск, навигация и живые примеры. Живые примеры выглядят так.
![](https://habrastorage.org/webt/9y/z1/sc/9yz1scwhqx0te8bj9h8eda6mehc.jpeg)
Один и тот же документ на GitHub и на сайте рендерится по-разному. Мы можем открыть его в новом окне, покликать по кнопке, посмотреть ее HTML. Это очень удобно.
![](https://habrastorage.org/webt/t3/rw/fb/t3rwfbzteg-ji9_dixmrpz5zaug.jpeg)
Какие у нас рецепты? Что же делать вам? В первую очередь — определиться с потребностями. Если они схожи с нашими, то ввести ограничения на синтаксис Markdown, следить за терминологией, делать автоматические проверки и использовать Translation Memory. Инструменты: remark-lint, yaspeller, md2xliff. Cпасибо.
Комментарии (20)
Karpion
12.11.2017 16:39+1Как только я прочитал стихотворение, а потом про «духовное богатство» — мне стало понятно, что дальше будет бессмысленный поток сознания. И я не ошибся.
ZigFisher
12.11.2017 23:26То-же в начале пробовал Markdown, но потом перешел на Textile и меня полностью устраивает.
Потихоньку пишу микро-движок, с использованием разметки Textile, который производит обработку страниц прямо в браузере (JS). Для блогов и заметок самое то что надо.poxvuibr
13.11.2017 00:00А я перешёл с маркдауна на org. Маркдаун он хороший, но какой-то уж совсем маленький.
ingumsky
13.11.2017 00:14Спасибо за статью, видно, что это превращённая в текст лекция, но всё равно интересно.
Интересно узнать, какие вы видите решения проблемы с внесением правок в английский текст и последующим возвращением изменений в «апстрим»? Вы вскользь упомянули, что работаете над этим. С учётом того, что процесс работы над переводной документацией обычно однонаправленный (в вашем случае это изменение русского текста и последующий перевод с использованием TM), можно предположить, что вы сейчас пользуетесь диффами, когда разработчик вносит изменения сразу в документацию на английском. Это так? При малом количестве таких правок, проблемы быть не должно (но всё равно есть неудобство), а вот когда такие правки появляются ежедневно и не по одной…
iit
13.11.2017 08:53Markdown на самом деле довольно шикарный формат когда нужно сделать например описание проекта на том-же github. Но постепенно создавая доки я обнаружил что мне не хватает некоторых фичей, тогда я открыл для себя reStructuredText (rst) и он еще более шикарен.
domix32
13.11.2017 11:12А каких фич не хватало?
iit
16.11.2017 07:28В основном возникла проблема со сборкой доков — у меня целая куча папок с md файлами, собирал я все это через MkDocs. Постепенно размер каждого файла вырос и редактировать их стало адово сложно.
reStructuredText позволяет же тупо сделать include одного файла в другой, что позволило разбить исходники доков по одному на модуль — при сборке они будут одним документом,
rst может автоматом создает оглавление на основе заголовков
(yml в MkDocs надо забивать руками) и приятные мелочи вроде создания таблицы из csv меня и подкупили.
OlegUV
13.11.2017 11:13Тоже прошёл примерно такой путь, но потом вернулся на «обычной шикарности» формат MD. Всё-таки, MD поддерживается массой тулзов, вплоть до утюгов, а с RST всё время какие-то нюансы возникают, в итоге на MD получается ощутимо и быстрее и удобнее писать.
Arris
13.11.2017 13:00Долго и упорно пытался использовать маркдаун. Для ведения блога, для написания документации, да вообще для всего.
Раз за разом — проблемы, проблемы, проблемы. Маркдаун хорош для простых текстов и ридми. Но когда нужны суперскрипты, субскрипты, подчеркивания, зачеркивания, обтекания картинок текстом или более сложные, чем "в git favored markdown" таблички — начинаются боль и страдания.
В эти моменты я с тоской вспоминаю язык разметки TiddlyWiki. И задаюсь вопросом — почему язык разметки, созданный 13 лет назад одним человеком — удовлетворяет с лихвой все мои потребности, а язык, над которым те же 13 лет страдает "прогрессивная программерская общественность" — не удовлетворяет?
А ведь я не хочу странного, я хочу записывать документацию и мысли по своим проектам (и они не в IT-сфере) в простом и удобном виде. Для меня простом и удобном. Но — нет, якобы простой и якобы удобный инструмент оказывается слишком простым для моих задач.
В такие моменты я задумываюсь — а не достать ли с полки книжку Кнута и не вспомнить ли TeX?
poxvuibr
13.11.2017 13:49И задаюсь вопросом — почему язык разметки, созданный 13 лет назад одним человеком — удовлетворяет с лихвой все мои потребности, а язык, над которым те же 13 лет страдает "прогрессивная программерская общественность" — не удовлетворяет?
Я подозреваю, что маркдаун был задуман совсем простым форматом для одностраничных текстов и ридми. И, если хочешь большего, то нужно либо радикально расширять маркдаун, либо использовать что-то другое. Радикальное расширение автор делать не хочет. Даже на попытку как-то стандартизировать формат он отреагировал очень эмоционально. А расширение руками большого количества людей чревато фрагментацией. Возможно CommonMark во что-то вырастет, но я не уверен.
В такие моменты я задумываюсь — а не достать ли с полки книжку Кнута и не вспомнить ли TeX?
Очень хорошо вас понимаю, я прошёл через что-то в этом духе. Тоже собирался делать всё в TeX, но наткнулся на org-mode. В результате пока пользуюсь этим форматом, он больше маркдауна. Возможно, если захочу писать книги, то и его не хватит.
ivan386
13.11.2017 20:46Но SVG тоже в нем открывается, при этом никто там не рисует — все используют Photoshop или Sketch.
Я пишу SVG картинки в текстовом редакторе. Так что утверждение про никто неверно.
Svetlyak
14.11.2017 11:15А почему не стали использовать формат reStructured Text? Он хотя и более странно выглядит, чем Маркдаун, но стандартизирован, и для описания документации лучше походит, так как задумывался именно с этой целью.
В reStructured Text заложены возможности для расширения и то как это делается, тоже стандартизировано, в отличии от Markdown, где разработчик каждой библиотеки городит свой велосипед.
roman_kashitsyn
14.11.2017 15:19
voe
а как дела обстоят с экспортом markdown в pdf, doc\x или в odf, какая у вас практика?
poxvuibr
Я не имею к автору никакого отношения, но с маркдауном поковыряться успел. Для экспорта в doc\x или в odf можно использовать pandoc. Он умеет конвертировать любой формат в любой другой (ну не любой, но поддерживает много форматов). Также он может работать с pdf, но нужно поставить немного дополнительного софта. Иногда проще сохранить в odf, а потом из odf сделать pdf средствами OpenOffice.