Подтвердить что ты не робот

Многострочные Clojure docstrings

Я заметил, что в большинстве случаев многострочные docstrings Clojure отформатированы вручную, в том числе в clojure.core. Пример из https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj:

(defn flatten
  "Takes any nested combination of sequential things (lists, vectors,
  etc.) and returns their contents as a single, flat sequence.
  (flatten nil) returns an empty sequence."
  {:added "1.2"
   :static true}
  [x]
  (filter (complement sequential?)
          (rest (tree-seq sequential? seq x))))

Это кажется странным, так как это означает, что разные docstrings будут иметь разные длины переноса строки и т.д., которые необходимо поддерживать вручную.

Есть ли лучший способ форматирования многострочных docstrings?

4b9b3361

Ответ 1

Если вы используете Emacs, возьмите clojure-mode.el из technomancy Github, который отличается от такового в ELPA (я не знаю почему, оба претендуют на быть версией 1.11.5, может быть, кто-то может прокомментировать это?), но включает в себя clojure-fill-docstring, который будет форматировать docstrings с хорошим отступом и linewrapping, привязанным по умолчанию к C-c M-q.

Это займет следующее:

(defn flatten
  "Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns an empty sequence."
  {:added "1.2"
   :static true}
  [x]
  (filter (complement sequential?)
          (rest (tree-seq sequential? seq x))))

и превратите его в это:

(defn flatten
  "Takes any nested combination of sequential things (lists, vectors,
  etc.) and returns their contents as a single, flat sequence.
  (flatten nil) returns an empty sequence."
  {:added "1.2"
   :static true}
  [x]
  (filter (complement sequential?)
          (rest (tree-seq sequential? seq x))))

после выполнения C-c M-q с вашей точкой внутри docstring.

Ответ 2

Есть ли лучший способ форматирования многострочных docstrings?

Мое предложение - использовать Markdown форматирование в ваших документах. Вот несколько причин:

  • это то, что используется в github в README и вики проекта (и многие пользователи Clojure используют и знакомы с github).

  • судя по номер of . md files вы find присутствует в различных проектах Clojure, он представляется предпочтительным форматом разметки среди пользователей Clojure.

  • популярный Marginalia инструмент doc отображает docstrings и комментарии (и я понимаю, что Autodoc (инструмент, используемый для создания документов в clojure.org), в конечном итоге также сделает уценку в docstrings).

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

Кроме того, вы, вероятно, уже знакомы с ним, поскольку Stackoverflow использует его для вопросов/ответов/комментариев (а сайты, такие как reddit и различные системы комментариев в блогах, используют Markdown также).

Ответ 3

Я согласен с @uvtc, что уценка - хороший выбор. В качестве добавления я хотел бы отметить, что тривиальным является создание собственной функции просмотра док-станции для использования в REPL. В следующем коде предполагается, что у вас есть пакет markdown-clj на пути к классу (например, через зависимости dev) и использует REPL в OSX:

(ns docs
  (:require [clojure.java.shell :as s]
            [markdown.core :as md]))

(defmacro opendoc [name]
   `(do
        (md/md-to-html (java.io.StringReader. (:doc (meta (var ~name)))) "/tmp/doc.html")
        (s/sh "open" "/tmp/doc.html")
    )
  )

Возможно, вы захотите посмотреть источник для clojure.repl/doc для обработки особых случаев (например, предполагается, что вы передадите правильный символ для var). Также неплохо было бы, чтобы имя файла отражало имя пространства имен/функций для "кеширования", а не просто повторное использование одного и того же имени файла для каждого запроса... но я сохраняю его простым для иллюстрации.

Команда OSX open просто просит ОС открыть файл, указав его тип. Таким образом:

REPL=> (docs/opendoc my.ns/f)

приведет к тому, что браузер по умолчанию откроет вашу версию docstring для вашей HTML-версии.

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

(defn boo
  "
  # Title
  My thing

  * Item one
  * Item two
  "
  [args] ...)

а затем измените функцию opendoc, чтобы сначала применить левую обрезку:

(defn ltrim [str] (clojure.string/replace str #"(?m)^ {0,3}" ""))

(defmacro opendoc [name]
  `(do
    (md/md-to-html (java.io.StringReader. (ltrim (:doc (meta (var ~name))))) "/tmp/doc.html")
    (s/sh "open" "/tmp/doc.html")
   )
  )