2012-05-23 19 views
21

Me he dado cuenta de que las cadenas multilínea Clojure parecen formatearse manualmente en la mayoría de los casos, incluidas las de clojure.core. Ejemplo de https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj:Multiline Clojure docstrings

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

Esto parece extraño, ya que significa que diferentes docstrings tendrán diferentes longitudes de ajuste de línea, etc., que necesitan ser mantenido manualmente.

¿Existe alguna forma mejor de formatear las cadenas de documentos multilínea?

+1

creo que la solución a este depende en gran medida de su capacidad para configurar (o aumentar) el editor de formato las cadenas de documentos para ti, ya sea que escribas o cuando lo solicites. – Jeremy

+0

Hay otras convenciones de docstring que podrían/​​deberían formalizarse también en mi humilde opinión. from let -> '' (let bindings & body) bindings => binding-form init-expr'' – sw1nn

Respuesta

12

Si está usando Emacs, agarra clojure-mode.el de technomancy's Github, que difiere de la de ELPA (no sé por qué, ambos afirman ser la versión 1.11.5, tal vez alguien puede comentar al respecto?) Sino que incluye clojure-fill-docstring que formateará las cadenas de documentos con una buena sangría y alineación de línea, enlazado por defecto a C-c M-q.

Se llevará a esto:

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

y convertirlo en esto:

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

después de hacer C-c M-q con su punto dentro de la cadena de documentación.

+1

Acabo de actualizar el modo clojure de ELPA. Como mencionaste, parecía estar desactualizado (no pude encontrar la función 'clojure-fill-docstring'). Para resolver este problema, ejecuté 'package-list-packages' y encontré una antigua (desactualizada)' clojure-mode' y la borré (marque con 'd', ejecute con' x'.) Problema resuelto. –

12

¿Existe una forma mejor de formatear las cadenas de documentos multilínea?

Mi sugerencia es utilizar el formato Markdown en sus documentos. Aquí hay algunas razones por qué:

  • que es lo que se utilizan en GitHub en README y wikis proyecto (y muchos usuarios utilizan Clojure y están familiarizados con github).

  • a juzgar por el numberof.md filesyoufind presente en diversos proyectos de Clojure, que parece ser un formato de marcado preferido entre los usuarios de Clojure.

  • la popular herramienta de Marginalia doc renders cadenas de documentación y comentarios de rebajas con formato (y mi opinión es que Autodoc (la herramienta utilizada para generar la documentación en clojure.org) con el tiempo hará que rebaja en docstrings también).

  • Se ve bien como texto sin formato, es fácil de escribir, no requiere ningún soporte de editor especial, y el marcado es mínimo y fácil de recordar.

Además, es probable que ya están familiarizados con ella, ya Stackoverflow uses it de preguntas/respuestas/comentarios (y sitios como diversos sistemas de blog de comentarios reddit y el uso de rebajas también).

+0

Idea interesante, ciertamente utilizo markdown y me gusta para otras cosas (por ejemplo, README.mds en Github). Aunque no estoy seguro de que el descuento sea generalmente soportado por herramientas que leen docstrings, en particular escribiendo '(doc xxx)' en Clojure REPL simplemente devuelve el docstring como texto sin formato .... – mikera

+0

No * necesita * ser compatible de cualquier manera --- se ve bien como texto sin formato. En este momento, '(doc xxx)' continuará escupiéndolo sin modificaciones como ya lo hace. Si la docstring tiene formato de marcado, simplemente se verá mejor y tendrá un formato más consistente. – uvtc

+0

En cuanto al ajuste de línea, como usted señala, 'doc' en este momento no parece hacer eso. Sin embargo, tenga en cuenta que la mayoría de los procesadores de rebajas le harán una "conversión" de rebaja directa-> rebaja, que incluye el ajuste de línea. Podría imaginar al 'doc' eventualmente haciendo algo así. – uvtc

2

Estoy de acuerdo con @uvtc en que el descuento es una buena opción. Como apéndice, me gustaría señalar que es trivial generar su propia función de visualización de doc para uso en REPL. El siguiente código supone que tiene el paquete markdown-clj en su classpath (p.a través de las dependencias dev), y están utilizando un REPL en 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") 
    ) 
) 

Es posible que desee mirar a la fuente de clojure.repl/doc para manejar casos especiales (por ejemplo, esto se supone que va a estar pasando en una símbolo apropiado para una var). También podría ser bueno tener el nombre de archivo reflejando el nombre/nombre de la función para el "almacenamiento en caché", en lugar de simplemente reutilizar el mismo nombre de archivo para cada solicitud ... pero lo mantengo simple para fines ilustrativos.

El comando OSX open simplemente le pide al sistema operativo que abra un archivo al detectar su tipo. Por lo tanto:

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

hará que su navegador predeterminado abra la versión HTMLified de la cadena de documentos de su función.

Otra advertencia: si sangra su cadena multilínea (lo que suelen hacer los editores), entonces su MD puede terminar con rarezas (por ejemplo, las listas de viñetas pueden anidar de una manera que no pretenden). Una forma de resolver esto es recortarlo. Por ejemplo:

(defn boo 
    " 
    # Title 
    My thing 

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

y luego modificar la función opendoc aplicar primero un ajuste izquierda:

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