【问题标题】:Multiline Clojure docstrings多行 Clojure 文档字符串
【发布时间】:2012-05-23 03:11:35
【问题描述】:

我注意到在大多数情况下,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))))

这看起来很奇怪,因为这意味着不同的文档字符串会有不同的换行长度等,需要手动维护。

有没有更好的方法来格式化多行文档字符串?

【问题讨论】:

  • 我认为解决这个问题很大程度上取决于能够配置(或增强)您的编辑器,以便在您键入时或按需为您格式化文档字符串。
  • 还有其他文档字符串约定可以/应该被形式化,恕我直言,例如来自 let -> (let bindings & body) bindings => binding-form init-expr

标签: clojure documentation docstring


【解决方案1】:

如果您使用的是 Emacs,请从 technomancy's Github 中获取 clojure-mode.el,这与 ELPA 中的不同(我不知道为什么,两者都声称是 1.11.5 版本,也许有人可以对此发表评论? ) 但包括clojure-fill-docstring,它将格式化具有良好缩进和换行的文档字符串,默认绑定到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 之后。

【讨论】:

  • 我刚刚从 ELPA 更新了 clojure-mode。就像你提到的,它似乎已经过时了(我找不到 clojure-fill-docstring 函数)。为了解决这个问题,我跑了package-list-packages,找到了一个旧的(过时的)clojure-mode并删除了它(用d标记,用x执行。)问题解决了。
【解决方案2】:

有没有更好的方法来格式化多行文档字符串?

我的建议是在您的文档字符串中使用Markdown 格式。以下是一些原因:

  • 这是 github 在 README 和项目 wiki 中使用的内容(许多 Clo​​jure 用户使用并熟悉 github)。

  • 从各个 Clojure 项目中出现的 number of .md files you find 来看,它似乎是 Clojure 用户首选的标记格式。

  • 流行的Marginalia doc 工具呈现markdown 格式的文档字符串和cmets(我的理解是Autodoc(用于在clojure.org 生成文档的工具)最终也会在文档字符串中呈现markdown )。

  • 它看起来像纯文本一样好,易于键入,不需要任何特殊的编辑器支持,并且标记最少且易于记忆。

此外,您可能已经熟悉它,因为 Stackoverflow uses it 用于问题/答案/cmets(以及 reddit 和各种博客评论系统等网站也使用 Markdown)。

【讨论】:

  • 有趣的想法,我当然会使用 markdown 并且喜欢它用于其他事情(例如 Github 上的 README.mds)。虽然我不确定读取文档字符串的工具通常是否支持降价 - 特别是在 Clojure REPL 中键入 (doc xxx) 只会将文档字符串作为纯文本返回......
  • 它不需要以任何方式支持 --- 它看起来像纯文本一样好。现在,(doc xxx) 将继续像它已经做的那样未经修改地吐出它。如果文档字符串是降价格式的,它看起来会更好,并且格式更一致。
  • 至于换行,正如您所指出的,doc 目前似乎没有这样做。但是,请注意,大多数降价处理器会为您进行直接的降价->降价“转换”,其中包括换行。我可以想象doc 最终会做类似的事情。
  • 在 OSX 上,您还可以在命令行安装 lynx 和 markdown,然后使用 clojure.java.shell 通过 (markdown | lynx -stdin -dump) 发送文档字符串。然后你就有了一个库函数,可以很好地从 repl 中工作。
  • 我认为如果 Clojure 对此进行全面标准化会很好。如果它向 Markdown 添加了一种从函数中引用其他函数的方法。
【解决方案3】:

我同意@uvtc 的观点,即降价是一个不错的选择。作为附录,我想指出,生成您自己的 markdown 文档查看功能以在 REPL 中使用是微不足道的。以下代码假设您的类路径中有 markdown-clj 包(例如,通过 dev 依赖项),并且在 OSX 中使用 REPL:

(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)

将使您的默认浏览器打开函数文档字符串的 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")
   )
  )

【讨论】:

    猜你喜欢
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多