Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zprints escapes already escaped newlines #326

Open
didibus opened this issue Jul 8, 2024 · 3 comments
Open

Zprints escapes already escaped newlines #326

didibus opened this issue Jul 8, 2024 · 3 comments

Comments

@didibus
Copy link

didibus commented Jul 8, 2024

I am calling the following zprint function:

(zprint
 '(defn testivius "This is a\n        multiline docstring." {:inline (fn ([a] ` (com.xadecimal.expose-api.impl-test/testivius ~a)) ([b c] ` (com.xadecimal.expose-api.impl-test/testivius ~b ~c)))} ([a] (com.xadecimal.expose-api.impl-test/testivius a)) ([b c] (com.xadecimal.expose-api.impl-test/testivius b c))))

;;; It prints

(defn testivius
  "This is a\n        multiline docstring."
  {:inline (fn
             ([a]
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list
                    (quote com.xadecimal.expose-api.impl-test/testivius))
                  (clojure.core/list a))))
             ([b c]
              (clojure.core/seq
                (clojure.core/concat
                  (clojure.core/list
                    (quote com.xadecimal.expose-api.impl-test/testivius))
                  (clojure.core/list b)
                  (clojure.core/list c)))))}
  ([a] (com.xadecimal.expose-api.impl-test/testivius a))
  ([b c] (com.xadecimal.expose-api.impl-test/testivius b c)))

The issue is the docstring is escaped again by zprint, so it ends up printing in one line, instead of multiline as you see we got:

  "This is a\n        multiline docstring."

If I wrap the call in with-out-str I can see it double escaping:

"(defn testivius\n  \"This is a\\n        multiline docstring.\"\n  {:inline (fn\n             ([a]\n              (clojure.core/seq\n                (clojure.core/concat\n                  (clojure.core/list\n                    (quote com.xadecimal.expose-api.impl-test/testivius))\n                  (clojure.core/list a))))\n             ([b c]\n              (clojure.core/seq\n                (clojure.core/concat\n                  (clojure.core/list\n                    (quote com.xadecimal.expose-api.impl-test/testivius))\n                  (clojure.core/list b)\n                  (clojure.core/list c)))))}\n  ([a] (com.xadecimal.expose-api.impl-test/testivius a))\n  ([b c] (com.xadecimal.expose-api.impl-test/testivius b c)))\n"

Is there a way to fix this?

@kkinnear
Copy link
Owner

This is a very interesting question indeed. You might think it had a simple answer, and it might, but I sure haven't found it yet despite a considerable time spent working on it. Until I know for sure exactly what is going on, I can't say for sure, but it seems like the output you want should be at least optionally available. More to come...

@kkinnear
Copy link
Owner

kkinnear commented Aug 3, 2024

This will be possible, but unfortunately it will have to wait until the next release. This was really quite the challenge, but in retrospect it seems straightforward.

When parsing Clojure source, rewrite-clj parses a string containing an actual newline differently from a string containing the characters \n. In an actual Clojure string there is only one way to represent a newline, and it looks like \n. So there is no way for you to "tell" zprint that you really want this string to format with actual newlines when you have a Clojure structure for a defn form.

In order to do what you want, I have created a new style called :docstring-nl, which will, if the third thing in an actual Clojure list with defn as its first element is a string, format only that string in such a way that any \n characters turn into actual newlines.

It required a small change to the spec for option maps, or I could give you an option-fn that does it in the current release. I'm sorry you will have to wait a bit, but at least it will work soon.

@didibus
Copy link
Author

didibus commented Aug 3, 2024

Awesome! I can wait no worries. I've got a rudimentary workaround now with a string/replace I run as a post-process step. But I'll be happy to switch to the first class support.

Thanks for looking into it! And love zprint by the way, amazing library and great addition to Clojure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants