Pull to refresh

Comments 42

Эта вот манера постоянно вставлять жирный шрифт довольно-таки сильно затрудняет чтение этого текста.
Встречал и прямо противополжное мнение — что использование смысловых акцентов здорово помогает при чтении при диагонали. Я раньше вот тоже не любил жирные акценты, а сейчас склоняюсь к тому, что и вправду помогает. Одно очевидно — всем не угодишь.
Помогает, конечно. Перебор в данном случае только с концентрацией этих смысловых акцентов.
Но это всё по большому счёту мелочи. Глаза не лопнули, вот и славно.
Во-первых, как Zolushok отметил, в этой статье это ни разу не ускоряет (потому что жирного много в каждом абзаце), а во-вторых, кажется, что акцент должен быть менее заметен, чтобы не мешать читать текст. (У меня лично на каждом жирном слове в голове происходит пафосная пауза и преподавательским тоном диктовка — отвлекает!)
Болд или италик это, наверно, всё-таки личные предпочтения. А замечание по количеству акцентов принято.
Ну и опять же, любые дополнительные выделения в тексте (за исключением строго оговоренных, когда читатель заранее знает, что значит каждый болд или италик), будь то смайлики или разноцветье шрифтов — это компенсация недостаточного владения классическими выразительными средствами письменной речи.

Как и улыбки-скобочки, они несомненно имеют право на жизнь, но как-то так…

Вопрос по сути статьи — скажите, а doxygen вроде бы умеет выдавать выхлоп в docbook-формате. а уж для него всяких генераторов в разных форматов написано немало. Такой вариант чем-то не устроил? Я просто сам давно не крутил всю эту кухню в руках, ибо java/javadoc сейчас наше всё
Ну и опять же, любые дополнительные выделения в тексте (за исключением строго оговоренных, когда читатель заранее знает, что значит каждый болд или италик), будь то смайлики или разноцветье шрифтов — это компенсация недостаточного владения классическими выразительными средствами письменной речи.

А мне кажется, визуальные акценты помогают-таки при просматривании статей по диагонали. Вопрос количества и баланса, конечно, открытый (и во многом субъективный). Но вообще я за акценты. Как говорится, let's agree to disagree :)


Вопрос по сути статьи — скажите, а doxygen вроде бы умеет выдавать выхлоп в docbook-формате. а уж для него всяких генераторов в разных форматов написано немало. Такой вариант чем-то не устроил?

Если честно, то не пробовал генерировать HTML из доксигеновского DocBook выхода. Навскидку не вижу причин, почему это может давать намного лучший результат, чем просто подкрутка CSS и шапок у доксигеновского HTML. Впрочем, если у вас пример красивой документации, полученной таким методом — кидайте, можно будет обсудить более предметно.

зачем себя мучать? добавьте просто стили в консоль браузера

.content strong {
font-weight: normal;
}

либо еще проще — закладку в браузер
javascript:$('.content strong').css('font-weight','normal')
Зачем изобретать новый синтаксис? Будем писать документацию так же, как и раньше!

Затем что если хочется документацию иметь красивую, со сложной связностью и легко расширяемую, то лучше сразу писать доки на Sphinx. А так получается что вы хотите лоск Sphinx и сразу же загоняете себя в рамки Doxygen.


Для себя выбрал другой путь — все документирование на Sphinx для любых исходников, а сбор документации через плагин Sphinx, который построен на механизме autodoc. Вот мой sphinxcontrib-autoanysrc и есть еще куча аналогов.


Плюсы:


  • любые исходники документируй хоть lua, хоть SQL и встраивай UML диаграммы, блок схемы и любые другие навороты Sphinx

Минусы:


  • сигнатуру приходится дублировать руками, но можно и расширить плагин парсер, что не так уже тривиально )
Никаких рамок, только лоск =)

Вы вольны использовать любые конструкции Sphinx внутри комментариев, а от Доксигена брать только синтаксис привязки комментария с документацией к конкретному объекту исходников.

Типа:

/*!
	Detailed documentation for ``foo`` with some **reStructuredText** markup.

	Usage:

	.. code:: cpp

		foo ("bar"); // <-- OK
		foo (NULL);  // error, name can't be NULL

	In master conf.py you can add your own Sphinx extensions and then invoke custom directives:

	.. my-custom-directive::

		my-custom-directive-content
 */

 void foo (const char* name);


А вообще по-моему мы сходимся в оценке Sphinx как удачного средства генерации финального варианта документации. Что предлагается в данном продукте — так это автоматическая генерация объявлений и автоматическая же привязка к ним смыслового наполнения документации.
Если мне не изменяет память, картинка — совместное творчество Владимира и его супруги. Раздавалась ограниченным тиражом в этом году на одном из Moscow Python митапов в Москве. У меня в офисе висит :)

Есть еще standardese, попытка создать новую версию генератора документации для C++ проектов. Его автор использует libclang для парсинга С++ кода и добавляет новые директивы в комментарии.

Если они не используют шаблонизатор (а судя по составу репозитория, там есть только CPP и Bash), то наступают на те же самые грабли, что и Doxygen — нельзя хардкодить генерацию HTML.

То есть всё, что они получат в итоге — это Doxygen с Clang в качестве парсера, но с таким же деревянным выходом. Кстати, если не ошибаюсь, автор Doxygen уже начал прикручивать Clang и сам.
If you pass a file that is not a source file, it will be treated as template file and processed. This allows advanced control over the output or writing additional documentation files.

Так что используя простейший язык шаблонов можно в какой-то мере влиять на генерируемый результат. Выходные форматы как и у Doxygen — markdown, html, xml, man, latex.

Посмотрел описание языка шаблонизации — ой, зря они свой язык стали писать, ой зря...


Им бы взять Lua или Python — и то, и другое легко встраивается в плюсовые приложения. Сейчас вся эта кухня с новым языком даёт слишком уж ограниченные возможности по настройке вывода — на неизвестном и неотлаженном языке, без стандартной библиотеки, да ещё и с вырвиглазным синтаксисом (standardese_for, standardese_else_if и т.д.).


Потом, сама идея с опциональностью шаблонов наводит на мысль, что шаблоны эти планируется использовать лишь как дополнение к автосгенерированному дереву объявлений, на внешний вид которого можно повлиять только настроечными переменными — как и в Doxygen.


Вполне возможно, я что-то упсутил, но у них, увы, нет примеров использования этих шаблонов — в репозитории только плюсы, bash и cmake..

> писать всё ручками.
> я глубоко убеждён что [этот способ] в корне неверен. Дело в том, что он порождает документацию, которая всё время [...] отстаёт от объекта документации.

Дело в том, что если сначала пишется API как получится, а потом пост-фактум под него пишется документация, то качество этого API будет стремиться к нулю или даже дальше в минус бесконечность. При правильном подходе, документация пишется на этапе проектирования и всегда опережает код. А код и тесты пишутся уже в соответствии с документацией. При таком подходе, и код будет чище, и если имплементация в результате будет отличаться от документации, тесты это покажут.

> «правильный» подход, состоит в том, чтобы генерировать документацию по исходникам автоматически.
> Специально обученный парсер пробегает по исходникам, вычленяет особым образом оформленные комментарии с документацией.

Какая разница, хранится документация в отдельном файле или в комментариях в файле с исходниками, если она все равно пишется пост-фактум, и никто не заметит, если какие-то ее части не будут соответствовать реализации? Если этап проектирования пропустили и правят код по наитию, скорее всего, интерфейсы будут меняться много раз по ходу работы, и кое-где забудут обновить комментарий с описанием.

Дальше не читал.
Дело в том, что если сначала пишется API как получится, а потом пост-фактум под него пишется документация, то качество этого API будет стремиться к нулю или даже дальше в минус бесконечность. При правильном подходе, документация пишется на этапе проектирования и всегда опережает код. А код и тесты пишутся уже в соответствии с документацией. При таком подходе, и код будет чище, и если имплементация в результате будет отличаться от документации, тесты это покажут.


Это работает только для сферических проектов в вакууме. На практике же набросанные на этапе проектирования интерфейсы безжалостно корёжатся при столкновениях с действительностью. Добавляются и убираются аргументы, методы и целые классы. Именно поэтому документация должна генерироваться по исходникам, а не быть написана отдельно (заранее или нет).

Какая разница, хранится документация в отдельном файле или в комментариях в файле с исходниками, если она все равно пишется пост-фактум, и никто не заметит, если какие-то ее части не будут соответствовать реализации? Если этап проектирования пропустили и правят код по наитию, скорее всего, интерфейсы будут меняться много раз по ходу работы, и кое-где забудут обновить комментарий с описанием.


Разница очень большая. Безусловно вы правы в том, что при любом подходе смысловой контент документации может отстать от эволюционирующего API. Но вот дерево объявлений в случае с авто-генерацией всегда будет релеванто — в отличие от отдельной документации. Глядя в авто-сгенерированную документацию вы всегда видите, какие аргументы принимает метод и что он возвращает. И всегда можно покликать и попутешествовать по типам, посмотреть, гда есть какие поля, методы, свойства и т.д.

Дальше не читал.


Ваше право.
> Это работает только для сферических проектов в вакууме.
Я тоже так думал в первые несколько лет своей карьеры. Потом понял, что как раз наоборот: без этого нормально не работает ни один проект, для которого вообще имеет смысл писать документацию.
То есть вот прямо так? Ни Гугл, ни Яндекс не работают? Андроиды всякие, Браузеры и тому подобное — тоже плод воображения?

Ню-ню, далеко вы пойдёте с таким подходом.

Да, есть области, где описанные вами подходы работают. В основном с заказным софтом, где если что-то забыли при проектировании — то всё, мыши будут теперь этот кактус есть лет десять, пока их кровавые слёзы кого-нибудь не разжалобят.

Но заказным ПО мир не ограничивается…
Документация это не ТЗ.
Нужно написать ТЗ, потом код, потом документацию.
И хуже того, поддерживать документацию актуальной. При этом новые ТЗ должны быть не подправленными старыми, а описанием новых требований. А документация — подправленной старой. Поэтому иного пути, чем генерить ее по коду — нету. (ну, руками еще можно. Теоретически.)
> Документация это не ТЗ.
А где я говорил иначе?

Порядок действий очень простой: Product spec (чего хочет заказчик) -> Tech Spec (как это реализовать технически в рамках текущей кодовой базы, как меняются архитектура, базы данных, API; как писать все не-тривиальные новые части) -> обновление технической документации -> согласование изменений (до того, как потратили кучу времени на написание кода) -> код -> тестирование на соответствие имплементации и документации.

Если начать писать код до того, как полностью разобрались с задачей или договорились со всеми заинтересованными сторонами, поимеешь кучу косяков и потратишь намного больше времени.

Вся цепочка рассуждений исходит из неверных предположений, что заказчик знает, чего хочет, а с задачей можно полностью разобраться до начала работ.

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

Но судя по комментариям, мое предположение о том, что задачу на каком-то этапе все равно нужно будет понять, является ошибочным.
Вы находите из предположения что у работ есть начало, окончание и заказчик. А для огромного количества ПО нет ни того, ни другого, ни третьего, нет и в помине.

Рассмотрите какой-нибудь простой пример: Chrome. Где у вас там будет начало, окончание и кто будет заказчиком?
Описание и код в равной мере продукт для потребления заказчиком, (в отличия от спеков, которые продукт потребления подрядчика). Соответственно, после тех спеки можно писать и то, и другое. Но удобнее сначала код.
А поиметь проблемы можно и согласовав документацию и получив претензии к функциональности, так как «а по описанию мы подумали, что оно иначе выглядеть будет».
> «а по описанию мы подумали, что оно иначе выглядеть будет».
Именно поэтому первым в цепочке стоит product design, который включает в себя описание функциональности и скетчи интерфейсов для пользователя. Пока эти аспекты не согласованы с заказчиком, нет смысла начинать писать код.

Я, наверное, неправильно понял о чем речь в статье. Тут, похоже, собрались разработчики именно «хтонических чудовищ», наподобие одноразовых сайтов-визиток для заказчиков, которые сами не знают, чего хотят и не в состоянии оценить, чего же им в конце концов наваяли. В этой области, конечно, и подходы другие, и опыта построения сложных систем, которые должны by design работать и развиваться в течение многих лет, набраться негде.
Только тогда я не понимаю, откуда в этих сайтах-визитках берутся API, для которых может понадобиться документация, но я много чего не понимаю в вашей кухне.
Ну, сейчас, кажется если штука не интегрируется — то она не нужна. А если интегрируется — то нужен API.
А сложные системы что, прям реально по водопаду живут? и вот прям если через полгода проекта требования поменялись к цвету кнопок, то как в документации согласовали, так и кодим. А как закодим, будем изменения согласовывать.
Или останавливаем разработку на время согласования обновленной документации?

И скетчи — они статика и абстрация. А вот подробностей они могут и не нести. А подробности могут повлечь еще один параметр/значение перечисления в функцию описанного API. Жирность шрифта, например.
> А сложные системы что, прям реально по водопаду живут?

Более-менее. По крайней мере подход «за две недели добавим вот эту фичу, а как добавлять следующую, будем думать потом» работает очень плохо. Приходится много думать и планировать наперед, иногда на год-два вперед. Иначе код за год настолько зарастает костылями, что второй год целиком уходит на разгребание бардака, а не на развитие функционала. Примеров больших проектов, которые через пару лет разработки начали переписывать все с нуля — масса, и часто причина именно в этом: разгрести старый говнокод оказалось дороже, чем написать заново с нормальным планированием.

> если требования поменялись к цвету кнопок, то как в документации согласовали, так и кодим.

Зависит от масштабов изменения. Часто — да, реализуют по предыдущей версии документации, а новую функциональность вносят только в одной из следующих итераций, после согласования новой документации.

> останавливаем разработку на время согласования обновленной документации?

Тоже случается. Если изменение значительное и много чего ломает, то оказывается дешевле заморозить разработку этой фичи или даже всего проекта, пока не будет ясности с требованиями. Продолжать писать код, когда не понятно, что же он должен делать в конце — лишняя трата времени.
Лучше в это время занять программистов всякими низкоприоритетными задачами, которые было бы неплохо сделать, но вечно не хватает времени. В больших проектах таких задач всегда вагон и маленькая тележка.
Руками править отдельно написанную документацию — это просто бессмысленная трата времени. Открыл проект, подправил код. Лезть еще и документацию править? Не проще ли перейти на некое количество строк вверх, подправить doxygen/javadoc документацию и продолжить работать?
Дело в том, что если сначала пишется API как получится, а потом пост-фактум под него пишется документация, то качество этого API будет стремиться к нулю или даже дальше в минус бесконечность.

Дальше не читал (с).

Как предполагается сразу написать сразу документацию, а потом под нее подгонять код? Нет, ну это понятно в случае с библиотеками, подключаемыми ресурсами. Но на живом проекте такое попросту нереально. Допустим даже, с использованием такого подхода сделали продукт. Состоялся релиз. Получили фидбек от пользователей. Посидели, поговорили, подумали что добавить, что убрать, что поменять. Окей, составили тех-спецификацию. Насколько Вы уверены в том, что она просто вот возьмет и идеально с учетом всех хотелок ляжет на архитектуру? Я обычно уверен процента на 2-3 и редко ошибаюсь. Как правило, это пустая трата времени, по крайней мере на больших продуктах. Мелочевка одноразовая — тут не вопрос. Но там как правило и документация не сильно нужна. А в серьезных проектах, которые из многих модулей состоят — вот так просто взять и составить документацию по всем API и тех. задание по ней — это анрил. Нужна еще целая куча согласований по ходу разработки. Кому-то нужны данные в таком виде, кому-то в таком. На берегу в больших проектах редко получается договориться.
Мой опыт говорит как раз об обратном: если сразу задуматься, что нужно сделать, кому какие данные и в каком формате нужны, как изменения затрагивают разные части проекта, — то можно написать детальную документацию на всё, согласовать изменение со всеми заинтересованными сторонами, а потом отдать написание кода джунам, потому что эта задача становится тривиальной.
И наоборот — если сразу влезть в код и начать что-то менять без того, чтобы предварительно подумать, то получится игра в перетягивание одеяла: что-то поменяли, что-то от этого сломалось, его починили, но сломалось что-то другое, неделю рефакторили какой-то модуль, но потом оказалось, что он теперь не состыкуется с каким-то другим, и нужно откатывать все изменения… В результате вся та же работа по согласованию все равно будет делаться, только в процессе тратится куча лишнего времени на написание и переписывание кода, а что-то, что сломалось, может остаться незамеченным.
Сроки при этом растягиваются на порядок (и их становится невозможно нормально оценить заранее, что приводит к срывам и кранчам со всеми вытекающими), а качество всей системы заметно страдает (что еще больше усугубляет ситуацию). И чем больше проект, тем сильнее все это проявляется.

> а потом под нее подгонять код?
Писать код по спецификации, да. Намного проще и на порядок-два быстрее, чем по-ковбойски бросаться в написание кода без предварительного включения головы.

> вот так просто взять и составить документацию по всем API и тех. задание по ней — это анрил
Как раз наоборот, написать весь код так, чтобы все работало и не было костылей на каждом шагу без предварительного планирования — анрил.

Но я уже выше писал, что, похоже, неправильно оценил вид проектов, с которыми местная публика в основном работает, а в вашей кухне я не разбираюсь. Возможно, в вашем случае мой опыт и неприменим.
Но даже если умолчальный доксигеновский HTML и устраивает кого-то с визуальной точки зрения (а серьёзно, есть такие, кому он и вправду нравится эстетически? напишите в комментариях!), очень часто хочется поменять и настроить что-то выходящее за рамки подкручивания CSS — например, упечь объявления в <pre> и расставить отступы и пробелы в соответствии с принятым в данной конкретной библиотеке coding-style.
Дефолтный вывод докигена ужастен (от слов «ужас» и «жесть»). Настолько что когда я первый раз увидел что он сгенерил, то сразу пошел искать возможные альтернативные инструменты. Но не найдя ничего более функционального с точки зрения именно процесса создания и поддержания актуальной документации из исходных файлов (равно как из любых других дополнительных источников документирования проекта), пришлось обратиться к правке HTML_STYLESHEET чтобы привести вывод в более менее приличный вид, и LAYOUT_FILE для того чтобы подкорректировать структуру документации сделав её более понятной, чтобы некоторые дефолтно генерируемые разделы не вводили пользователя в состояние фрустрации.

Пример: линк. Собственно сам веб-сайт doxygen сгенерирован doxygen.

Это подводит нас ко второй, более фундаментальной проблеме Doxygen...
Проблем у доксигена полно, да. Но по функциональности и возможностям настройки обработки исходников C/C++ для генерации документации он пока не имеет равных. Он может быть и «деревянный» у себя внутри, но в конце концов после изучения и настройки работает и делает то что нужно: генерирует актуальную полноценную документацию из исходников и прочих файлов описания с минимальными трудозатратами на поддержку собственно документирования в исходниках рядом с актуальным кодом.

Совершенно верно — как средство разбора и вытаскивания документирующих комментариев он пока не имеет равных. Кроме того, когда допилится интеграция с Clang (а то сейчас она какая-то уж слишком экспериментальная), этих самых равных и искать никакого смысла не будет.


А сделать красивый вывод по информации, полученной Доксигеном — в этом и есть вся соль предлагаемого мной проекта. Доксиген умеет доставать информацию из исходников. Sphinx умеет генерировать красивый — и, что главное, настраиваемый, — HTML. Doxyrest — мост между этими двумя товарищами.

В чём разница между поддержанием документации в отдельном файле или в коде?

По личному опыту документация Doxygen совершенно бестолкова. Гораздо полезнее абстрактная документация описывающая общую идею и щедро расставленные обычные текстовые комментарии, чем бессмысленные аннотации аргументов, для нормального чтения которых код ещё надо прогнать через утилиту в отдельный файл. Не говоря уж о том, что менять такой код — тоже удовольствия мало.

Хотя подозреваю всё это может неплохо работать в случае закрытых проприетарных библиотек, которые поставляются клиентам.
Так что мешает подключить файлы с абстрактным описанием в документацию doxygen, а обычные комментарии в коде с минимальными усилиями превратить в doxy-комментарии? Бессмысленные аннотации объявлений генерируются doxygen автоматом и это может быть отключено, тогда doxygen выведет только то, что было реально задокументировано.

Всё правильно. А в случае с использованием Doxyrest, отдельные страницы с абстрактным описанием — это будут просто .rst файлы, скармливаемые Sphinx напрямую.

И сейчас в случае с doxygen это просто файлы Markdown скармливаемые doxygen напрямую. И это в результате может стать не просто отдельной самостоятельной страницей в документации, но в них можно указать какие отрывки текста должны появиться в какой странице или в какой раздел («модуль» в терминах doxygen) добавиться к автоматически сгенерированной документации кода. (К сожалению вот только локализовать место вывода до конкретной функции-члена класса нельзя.)

Ну я собственно и не противопоставлял — просто сказал, что и с Doxyrest тоже можно создавать самостоятельные страницы с документацией как обычные .rst файлы. И конечно, и с Doxygen, и с Doxyrest из этих самостоятельных страниц можно ссылаться на авто-сгенерированные страницы API.


Другое дело что Doxyrest перекладывает всю работу по созданию финальной красивой HTML страницы на инструмент, который прекрасно с этим справляется (значительно лучше, чем Doxygen). Вот и всё.

В чём разница между поддержанием документации в отдельном файле или в коде?

Я уже писал выше — при авто-генерации документации имеется гарантия релевантности всех объявлений. Вы можете побегать по API, посмотреть какие аргументы принимаются, что возвращается, какие есть поля и т.д.


По личному опыту документация Doxygen совершенно бестолкова.

Бестолковость абсолютного большинства примеров Доксигеновской документации, действительно имеет место быть. Но это проблема конкретного контента, а не подхода, согласитесь? Можно ведь взять и написать толковую документацию, а не просто: open открывает, get возвращает. Но у меня есть смелая теория, почему сейчас всё обстоит именно так.


Разработчики не хотят тратить усилия на написание толковых комментариев, потому что — барабанная дробь — конечная Доксигеновская документация всё равно будет выглядеть как говно!


Исправить это — и есть главная цель проекта Doxyrest.

Разработчики не хотят тратить усилия на написание толковых комментариев, потому что — барабанная дробь — конечная Доксигеновская документация всё равно будет выглядеть как говно!

Я вам больше скажу: разработчики в принципе не любят документацию писать.

Что правда то правда. Тогда я переформулирую:


Даже в тех (редких) случаях, когда разработчики и рады были бы написать нечто толковое в документации, их останавливает то, что… и дальше по тексту ;)

Sign up to leave a comment.

Articles