I have done the same with React - but it gets messy. Something nice like in the post would be great for that.
Too often I see very poor Storybook sites in the wild (a web based design system visual explorer, somewhat like the screenshot in the post) where no thought was given to this exact problem.
Instead of something meaningful like in the post, I see:
() => <TextInputStorybook />
As the only avaliable code. The point of the code blocks is so people can copy paste. When I see that, I know I'm in for a rough ride because the code quality inevitably isn't any good either.For reference, this is easily the best design system I know of: https://seek-oss.github.io/braid-design-system/components/Te... I use this as a reference when I work on my own.
> Like, actually went to the file system, opened a file, and read its content? We already have the file name conveniently stored in file, and luckily Clojure keeps sources around.
> So this is what I ended up with:
> (defn slurp-source [file key]
Looks like a function to me (which is good).
Files are not directly relevant to macros.
The code that a macro invocation has access to by design is the datum which comprises that invocation itself. That may have come from an expression in a file, and may be annotated in some way with the location info. Other than that, macros do not necessarily have access to their textual source code. No such thing necessarily exists because macros can be invoked by code that was generated (possibly by other macros or in other ways) and so never existed as characters in a file.
I don't have a clear picture of the architecture of the system that the article refers to, but the author presents, as his end result, a defn form, which defines a function and not a macro.
If a macro is needed to get that function to be called at compile time, that would be a minor hooking detail, and not an instance of a macro being used to perpetrate a complex code transformation. The function just needs a file name and a string.
(It looks as if the author's system may be interactive; the code files are there all the time and can be changed, and he wants the view of the files to refresh?)
sometimes a vector is just a vector, but sometimes it’s a UI component and shows the structure of the UI.
Easily the worst aspect of Clojure. Everything is an untyped map or an untyped vector. Your editor can't tell the difference between a vector of keywords and some DSL for a macro. Things like this make Clojure a nightmare to refactor and scale poorly relative to languages like TypeScript.People now prefer using maps - even if it's a bit more verbose. Not sure why records fell out of fashion. You get the terseness of hiccup and the named keys of maps
$ cat slurp-source.tl
(defun slurp-source (path key)
(let* ((lines (file-get-lines path))
(match (member-if (op contains key) lines))
(tail (rest match))
(indent (find-min-key tail : (op match-regex @1 #/\s*/)))
(dedent (mapcar (op drop indent) tail)))
`@{dedent "\n"}\n`))
$ txr -i slurp-source.tl
1> (put-string (slurp-source "slurp-source.tl" "let*"))
(match (member-if (op contains key) lines))
(tail (rest match))
(indent (find-min-key tail : (op match-regex @1 #/\s*/)))
(dedent (mapcar (op drop indent) tail)))
`@{dedent "\n"}\n`))
t