LINUX.ORG.RU

В каком формате вы пишете документацию к своим проектам?

 


2

4

Интересуюсь потому, что сам подумываю начать писать полноценную. Вопрос задан не в контексте «какие варианты возможны», а в контексте «какие варианты реально используются».

Сам пока поглядываю в сторону markdown, т.к. в нём в нём есть подсветка и можно вставлять картинки. Иногда в этом есть необходимость, т.к. они нагляднее, чем псевдографика.

★★★

Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от eao197

Твой пример - как раз пример отвратительной документации, из-за которой одна строка кода и максимум одна строка комментария превратились в 10 строк нечитаемой каши. Правильно тут было бы так:

/* копирует n байт из src в dest */
void memcpy(void *dest, const void *src, size_t n);
firkax ★★★★★
()
Ответ на: комментарий от firkax

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

  • это не мой пример вообще;
  • смысл модифицированного мной примера в том, чтобы показать, в каком месте еще Doxygen позволяет оставлять документацию к параметрам функции/метода (есть ощущение, что кто-то даже не в курсе, что Doxygen так умеет).
eao197 ★★★★★
()
Ответ на: комментарий от u5er

Мне проще самому с нуля написать так, как я хочу, чем потом за неёронками причёсывать весь выхлоп.

Понимаю) Но все равно, если запаришься с какими-то частями, у тебя есть опция спихнуть это ЛЛМ. Они в общем-то, что им скажешь, то и будут делать.

goingUp ★★★★★
()
Ответ на: комментарий от goingUp

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

u5er ★★★
() автор топика
Ответ на: комментарий от u5er

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

goingUp ★★★★★
()
Последнее исправление: goingUp (всего исправлений: 1)

Обычно - ни в каком. Мне лень и всё равно кроме меня её никто читать не будет. А я и так всё знаю. Если и забуду, то быстрей разобраться по коду, чем читать потенциально устаревший текст.

Но если и пишу, то, конечно, в markdown. Даже странно рассматривать что-либо ещё.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)

У меня прям больших проектов нет. Есть работа, есть разные поделки, но в основном так:

  1. На работе просто пишу в README.md, плюс, страничка на рабочей вики.

  2. Просто текстовый файл в стиле, который у OpenBSD подсмотрел. textwidth = 72, а заголовки следующим образом:

This is a title example
-----------------------

Regular paragraph. This command will fix your computer:

        rm -rf /*
  1. Создаю отдельную директорию doc/ и в ней пишу документацию в разметке markdown, но также она собирается в pdf с помощью pandoc. А также добавляю LaTeX преамбулу. Иногда прям в markdown разметку добавляю LaTeX-команды.

  2. В начале программы в комментарии описать, а что собственно программа делает и какие подпрограммы ключевые.

Jullyfish
()
Последнее исправление: Jullyfish (всего исправлений: 1)

Rd, Texinfo.

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

Требования к ним разные. API-документация должна быть мгновенно доступна при работе с кодом; её формат сильно зависит от языка и фреймворков (например, встроенная в R система справки понимает только Rd, хотя есть и трансляторы из других языков в него). Инструкции, которые учат читателя делать конкретные вещи, лучше писать в духе literate programming, чтобы было легко убедиться, что предложенный код действительно работает (опять же, конкретные инструменты зависят от языка и других обстоятельств). А вот документ для вдумчивого чтения можно писать на чём удобно (в том числе что потом будет удобно читать через браузер или даже электронную книгу).

anonymous
()

Для high level документации, общей архитектуре, спецификаций и всему далёкому от кода использую mdBook.

Для API reference, описания конкретных классов (контракты и интерфейсы), coding guidelines и всему связанному с кодом — Doxygen с Doxygen Awesome CSS.

anonymous
()
Ответ на: комментарий от eao197

Нет, твой - ты его сюда принёс и снабдил положительным отзывом. Где ты его достал плевать.

чтобы показать, в каком месте еще Doxygen позволяет оставлять документацию к параметрам функции/метода (есть ощущение, что кто-то даже не в курсе, что Doxygen так умеет).

Да и пусть не в курсе, незачем знать способы испортить код.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Тут вообще комментарии излишни, достаточно самодокументации в коде:

void copyNumBytes(void *to, const void *from, size_t numBytes);

Комментарии нужны, когда алгоритм нетривиальный и надо сделать пометку «ты сюда не ходи - сюда ходи, а то снег башка попадёт!».

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

necromant ★★
()
Последнее исправление: necromant (всего исправлений: 1)
Ответ на: комментарий от firkax

Нет, твой

Для клинических идиотов первоисточник: В каком формате вы пишете документацию к своим проектам? (комментарий)

Да и пусть не в курсе, незачем знать способы испортить код.

Я понимаю, что альтернативная одаренность не позволяет различить два ортогональных друг другу вопроса:

  1. Нужно ли описывать параметры функции/метода?
  2. Как именно можно описывать параметры функции/метода посредством Doxygen?

Но все-таки вопросы это разные. И мой комментарий с модифицированным чужим примером, до которого вы решили доколупаться, относится только ко второму вопросу. Однако вы, почему-то, пытаетесь приписать мне ответ на первый вопрос.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Для клинических идиотов первоисточник

Клинический идиот тут ты. По ссылке совсем другое, никаких мусорных комментариев после каждого аргумента там нет, комментировал я не его а именно твой пример. У него нет «10 строк нечитаемой каши», которые представляет из себя твой вариант. У него нормальная 1 строка кода и раздутый 6-строчный коммент.

Как именно можно описывать параметры функции/метода посредством Doxygen?

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

Однако вы, почему-то, пытаетесь приписать мне ответ на первый вопрос.

Нет, я обсуждал именно отвратительный формат всовывания отдельнострочных комментариев в середину прототипа. Про то, что аргументы по отдельности в таких случаях вообще не надо комментировать, уже выше обсудили и я не считал нужным это повторять.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 5)

Смотря какую документацию. PRD обычно выкатывают просто в гуглдоксах. HLD/LLD пишу изначально в org+plantUML. Потом конвертирую куда надо. Вообще важнее чтобы была платформа для коллаборации (вопросы, правки, интеграция со слаком, таск/баг-трекером и т.д.), а не просто документ.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от firkax

Клинический идиот тут ты.

А я и не отрицаю. Меня больше другое волнует: что в этой теме слишком большая концентрация еще более запущенных случаев.

По ссылке совсем другое

понимать надо (с)

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

Все.

Способ, который ты показал в своём примере - отвратителен

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

преподносить его в качестве «а вот какая крутая фича у doxygen» - идиотизм

По факту, у Doxygen-а это реально крутая штука. Говорю вам как человек, которому по работе пришлось заниматься приведением в норму JavaDoc комментариев, в которых по мере развития проекта описания параметров забывали редактировать. Именно потому, что комментарии к параметрам шли отдельно, а сами параметры – отдельно.

Это антифича, единственное зачем это можно было показать - так это в контексте «смотрите, как не надо делать».

У меня к вам внезапный, но традиционный для моего поведения на LOR-е вопрос: а ваш код где-то в открытом доступе увидеть можно?

eao197 ★★★★★
()
Ответ на: комментарий от eao197

приведением в норму JavaDoc комментариев, в которых по мере развития проекта описания параметров забывали редактировать. Именно потому, что комментарии к параметрам шли отдельно, а сами параметры – отдельно.

Их скорее всего не забывали редактировать, а забивали, т.к. они не нужны. А твой способ «будем тыкать в нос этими комментами всем тем кто посмотрит на список аргументов» выглядит принуждением к выполнению бесполезной работы и насилием над программистами. Побочно засоряя код.

У меня к вам внезапный, но традиционный для моего поведения на LOR-е вопрос: а ваш код где-то в открытом доступе увидеть можно?

Например тут и тут и тут (про просроченный сертификат знаю).

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

Например

Прикольно слушать категорическое мнение о нужности комментариев от человека, творящего вот такое:

/* ret. 0 = ok; -1 = too many headers; -2 = too long header name; -3 = bad header name; -4 = too long header value; -5 = missing ':' */
extern int hh_add(t_http_headers * hh, char const * text) {
  int r;
  unsigned int n;
  char *hname, *hvalue;
  
  if(hh->n>MAX_HEADERS) abort();
  if(hh->n==MAX_HEADERS) return -1;
  r = hh_parse(text, &hname, &hvalue);
  if(r<0) return r;
  n = hh->n++;
  hh->h[n*2] = hname;
  hh->h[n*2+1] = hvalue;
  return 0;
}

/* ret. 0 = ok; -2 = too long header name; -3 = bad header name; -4 = too long header value; -5 = missing ':' */
extern int hh_parse(char const * text, char * * r_name, char * * r_value) {
  unsigned int n, ow;
  char c;
  char name[MAX_HEADER_NAME];
  char *hname, *hvalue;
  size_t vlen;
  
  while(*text==' ' || *text=='\t') text++;
  for(n=0; n<MAX_HEADER_NAME; n++) {
    c = text[n];
    if(!c) return -5;
    if(c==':') break;
    name[n] = c;
  }
  if(n==MAX_HEADER_NAME) return -2;
  text += n+1;
  while(n && (name[n-1]==' ' || name[n-1]=='\t')) n--;
  name[n] = 0;
  if(!n) return -3;
  for(n=ow=0; c=name[n]; n++) {
    if(c=='_' || c=='-') { name[n]='-'; ow=0; continue; }
    if(c>='A' && c<='Z') { if(ow) name[n]=c-'A'+'a'; ow=1; continue; }
    if(c>='a' && c<='z') { if(!ow) name[n]=c-'a'+'A'; ow=1; continue; }
    if(c>='0' && c<='9') { ow=1; continue; }
    return -3;
  }
  while(*text==' ' || *text=='\t') text++;
  if(strlen(text)>=MAX_HEADER_VALUE) return -4;
  hname = fcl_strdup_check(name);
  hvalue = fcl_strdup_check(text);
  vlen = strlen(hvalue);
  while(vlen && (hvalue[vlen-1]==' ' || hvalue[vlen-1]=='\t')) hvalue[--vlen] = 0;
  *r_name = hname;
  *r_value = hvalue;
  return 0;
}

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

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Этот вполне хороший код, не надо левых наездов. И комментарий полезный, в отличие от «src это исходная память». И упрощу тебе поиски: как раз в fproxy, единственном из тех трёх ссылок, плохой код есть, но он в основном в файлах handle/inc.*.c

И кстати, по теме, во всех трёх ссылках так или иначе есть документация, нигде она не doxygen-подобная, и в двух из трёх - даже не содержит справочников по хедерам.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)

Комментарии в коде проще всего поддерживать. Отдельные документы в txt или markdown. Если нужно прям сайт сгенерировать, когда-то давно использовал rst. Собственно можно прям цепочку выстроить каменты/txt < markdown < rst по нарастанию сложности формата и его возможностей.

начать писать полноценную

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

neumond ★★
()
Ответ на: комментарий от firkax

Этот вполне хороший код

Это криптограмма без каких-либо пояснений, в которой без поллитры не разобраться. Да еще и с экономией на пробелах.

И комментарий полезный

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

#define HH_PARSE_OK (0)
#define HH_PARSE_TOO_MANY_HEADERS (-1)
#define HH_PARSE_NAME_TOO_LONG (-2)
#define HH_PARSE_BAD_NAME (-3)
#define HH_PARSE_VALUE_TOO_LONG (-4)
#define HH_PARSE_NO_COLON (-5)

...
  for(n=0; n<MAX_HEADER_NAME; n++) {
    c = text[n];
    if(!c) return HH_PARSE_NO_COLON;
    if(c==':') break;
    name[n] = c;
  }
  if(n==MAX_HEADER_NAME) return HH_PARSE_BAD_NAME;
eao197 ★★★★★
()
Ответ на: комментарий от firkax

Это ровно то, о чём я тебе в своё время говорил ;) Да, ты можешь одним взглядом увидеть весть алгоритм, но человек, который первый раз видит твой код, будет плеваться. Так оно и вышло.

u5er ★★★
() автор топика
Ответ на: комментарий от anonymous

и не значит, что код плохой, просто автору норм например, все эти пет проекты одиночные переоценены как что-то возвышающее автора над серой массой

anonymous
()
Ответ на: комментарий от anonymous

еще и abort посреди функции

К этому abort-у меньше всего претензий, он должен отловить ситуацию, в которой продолжать работать в принципе нельзя.

Другое дело, что это очень похоже на перестраховку и вряд ли данный if когда-нибудь сработает. Поэтому большой вопрос «а насколько данная перестраховка оправдана?»

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Это криптограмма без каких-либо пояснений, в которой без поллитры не разобраться. Да еще и с экономией на пробелах.

Пояснение, как использовать есть. Сам код вполне читабельный и очевидный.

Это комментарий, которого не должно было быть в принципе

Угу.

#define HH_PARSE_OK (0)
...
... через 500 строк
...
extern int hh_parse(char const * text, char * * r_name, char * * r_value) {

Как предлагаешь догадываться, какие значения могут возвращаться?

monk ★★★★★
()
Ответ на: комментарий от anonymous

еще и abort посреди функции(

Это нормально для проверки порчи данных. Если данные в программе из-за UB или битой памяти пришли в невозможное состояние, лучше прервать выполнение, чем пытаться сделать что-то ещё.

monk ★★★★★
()
Ответ на: комментарий от anonymous

К примеру взять исходники PostgreSQLи попробовать понять его архитектуру всего проекта и подсистем без документации можно? Можно.

Оно не ООП, поэтому так тяжело понять код без документации. Лучше потрать время на рефакторинг в ООП коде. Потратить время на грамотное название пакетов, классов и методов. Вместо написания документации.

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

Если пол года своей жизни на это потратить.

Если ты не специалист по разработке СУБД, ты основную часть времени потратишь на понимание архитектуры и алгоритмов работы СУБД. Дальше, при наличии ООП кода конечно, ты код любой СУБД будешь махом считывать без всяких комментариев.

Поэтому документация не нужна. В крайнем случае код можно скормить OpenAI.

foror ★★★★★
()
Последнее исправление: foror (всего исправлений: 1)
Ответ на: комментарий от foror

Вот, кстати, коментарии из postgresql:

/* allocate city table memory */
	kid = alloc_chromo(root, pool->string_length);
	city_table = alloc_city_table(root, pool->string_length);

Полный идиотизм, это ещё наверное в книгах для студентов пишут, что так делать нельзя.

foror ★★★★★
()
Ответ на: комментарий от monk

Пояснение, как использовать есть.

Пальцем покажете? Мне вот, например, из прототипа hh_parse не очевидно, что сохраненные в r_name/r_value указатели подлежат освобождению вызывающей стороной.

Сам код вполне читабельный и очевидный.

А ваш код на Си где-то в открытом доступе можно увидеть? Чтобы проверить предположение, что ваш код не сильно по качеству отличается.

Что до очевидного, то мне лично пришлось долго вкуривать что делает вот этот фрагмент:

  for(n=ow=0; c=name[n]; n++) {
    if(c=='_' || c=='-') { name[n]='-'; ow=0; continue; }
    if(c>='A' && c<='Z') { if(ow) name[n]=c-'A'+'a'; ow=1; continue; }
    if(c>='a' && c<='z') { if(!ow) name[n]=c-'a'+'A'; ow=1; continue; }
    if(c>='0' && c<='9') { ow=1; continue; }
    return -3;
  }

Будь перед этим куском комментарий, поясняющий, что здесь пытаются преобразовать имена вида «HEADER_name_WiTh_SeVeRaL-WORDs» в «Header-Name-With-Several-Words», времени на изучение кода потребовалось бы меньше. При этом я не уверен, что данный кусок кода делает именно это и делает это правильно. А что означает имя переменной ow так и осталось для меня загадкой.

Так что, боюсь, очевидным этот код является только для LOR-овских надмозгов.

Как предлагаешь догадываться, какие значения могут возвращаться?

Во-первых, это же Си-шка, пользующие до сих пор Си-шку должны страдать. По определению.

Во-вторых, вы, видимо, не прочитали очень важный фрагмент «в самом примитивном виде, хотя бы вот так». Лучше было бы сделать enum. Но, опять-таки, это же Си-шка, в которой даже enum-ы недоделанные. C++ный enum class подошел бы гораздо лучше.

Но теперь встречный вопрос: вы реально считаете, что комментарий, в котором перечислены целочисленные значения, и эти же целочисленные значения захардкожены в теле функции – это норм?

eao197 ★★★★★
()
Ответ на: комментарий от monk

Если данные в программе из-за UB или битой памяти пришли в невозможное состояние,

Да-да-да. Очень разумно верить в том, что из-за UB или битой памяти еще можно проверять.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Что до очевидного, то мне лично пришлось долго вкуривать что делает вот этот фрагмент:

Справедливости ради, стоит отметить, что этот код написан в write-only стиле.

u5er ★★★
() автор топика
Ответ на: комментарий от u5er

Справедливости ради, стоит отметить, что этот код написан в write-only стиле.

Если firkax пишет код в write-only стиле, то его мнение о том, как код нужно комментировать тем более ничего не стоит.

eao197 ★★★★★
()
  1. В html. Есть возможность сделать это страницами сайта. Изначально соблюдать одинаковый стиль, тогда в любой момент можно преобразовать это в текст или во что угодно.
  2. Собственный Markdown, собственная разметка, с помощью которой можно преобразовать в любой формат. Требует меньше телодвижений. Как пример справка AutoIt3 и PureBasic создана именно в таком собственном формате, при написании не требуется создавать шапку html, закрывать блоки. Если редактор поддерживает создание синтаксиса (подсветка, автозавершение), то можно легко манипулировать этим, а потом сделать код конвертации в любой формат html, Markdown, RTF или просто удалить теги, сделав текстом.
AZJIO
()