0

Shadow-cljs has a resource loader that can include literal files into the Clojurescript code

(ns app.my
  (:require
   [shadow.resource :as rc]))

(rc/inline "file.txt")

I need a macro that includes the literal file, but preprocessed by some function. Let's for the sake of simplicity say that we uppercase the text of the file.

(ns app.my
  (:require
   [shadow.resource :as rc]))

(clojure.string/upper-case (rc/inline "file.txt"))

This code includes the regular text, and then uppercases it at run-time. I need it to be uppercased at macroexpansion, so that the uppercased text is included. Exactly like it would be if the original file was upper case.

I can't really fit this together, with macros expanding outside-in. Please help!

1 Answer 1

2

You can only do this by writing your own macro. inline itself is basically just using a helper function, which you can use in your own macro.

Basically as written in my macro guide you write 2 files.

First the simple CLJS file, which can contain additional code but must be at least this. So src/main/your/example.cljs (assuming src/main as the source path, adjust accordingly if not)

(ns your.example
  (:require-macros [your.example]))

Then the macro in src/main/your/example.clj

(ns your.example
  (:require
    [clojure.string :as str]
    [shadow.resource :as rc]
    ))

(defmacro my-inline [path]
  (-> (rc/slurp-resource &env path)
      (str/upper-case) ;; any post processing you want
      ))

And then whereever it is used (:require [your.example :as x]) and (x/my-inline "foo.txt").

Sign up to request clarification or add additional context in comments.

2 Comments

That works. I was trying to implement it by wrapping the inline macro, but with the evaluation being outside-in, this didn't work. On a purely theoretical level, as me trying to grok macros, is it possible to make it by wrapping the inline macro with my own macro? (let's assume the library doesn't give me access to slurp-resource) This seems like something that should be possible to fully evaluate at macroexpand time, by expanding the inner inline macro first, turning the argument into a literal string, and then expanding the outer macro.
I suppose it is technically possible, but not something I have ever done. Technically speaking macros are just functions, so anything is possible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.