Evaluating variables in Racket response/xexpr - racket

I'm trying to make a simple bookmarking web-app in Racket.
It's meant to receive a url as a CGI argument, and right now, I'm just trying to confirm I received it by reflecting it back.
(define (start request)
(response/xexpr
(let* ([bindings (request-bindings request)]
[url (if (exists-binding? 'url bindings)
(extract-binding/single 'url bindings)
"NO URL")])
`(html
(head (title "TITLE"))
(body (h2 "TITLE")
(p "URL = " url))
))))
However, instead of seeing what I expect to see .. which is a page that contains
URL = http://google.com
I'm seeing
URL = &url;
Which suggests that url is being quoted literally in the xexpr (treated as an entity), rather than being evaluated as a variable.
So what am I doing wrong? How do I get url evaluated?

You need to use quasiquote and unquote to inject values into a quoted experession, more often seen as their reader abbreviation equivalents, ` and ,, respectively. When you use unquote/, inside of quasiquote/`, it will evaluate the expression and insert it into the surrounding quotation:
> (define url "http://google.com")
> `(p "URL = " ,url)
(p "URL = " "http://google.com")
You should put , in front of url in your template to unquote it.
For a more detailed explanation of quotation and quasiquotation, see Appendix A of this answer.

Use ,url :
`(html
(head (title "TITLE"))
(body (h2 "TITLE")
(p "URL = " ,url))
))))
Look for unquote in the documentation: http://docs.racket-lang.org/reference/quasiquote.html?q=unquote#%28form.%28%28quote.~23~25kernel%29._unquote%29%29

Related

ido-completing-read interaction with _ and -, hides possible results

When using ido-completing-read
(ido-completing-read "Which tag: " '("DALL-E" "monoidallens") nil t)
it finds both tags when I type "dall" but once I enter "dalle" it no longer finds "DALL-E"
Which tag: dall{DALL-E | monoidallens}
Which tag: dalle[monoidallens]
Whereas if I add an underscore to the "monoidal_lens" tag
(ido-completing-read "Which tag: " '("DALL-E" "monoidal_lens") nil t)
the input "dall" only matches "DALL-E" and while the input "dalle" matches both.
Which tag: dall[DALL-E]
Which tag: dalle{DALL-E | monoidal_lens}
Why does this happen? Is there a way to show all possible suggestions, adding more characters should not make suggestions go away.

Org mode agenda: Reuse code in block agenda

I have an org-agenda-custom-commands like so:
("u" "Unscheduled TODO"
todo ""
((org-agenda-overriding-header "\nUnscheduled TODO")
(org-agenda-skip-function '(org-agenda-skip-entry-if
'scheduled 'deadline 'timestamp
'todo '("BACKBURNER")))))
I would like to reuse the todo part of this agenda view in other block agenda views. So for instance defining an unscheduled-todo list for reuse (pseudocode, not working):
(setq unscheduled-todo '((org-agenda-overriding-header "\nUnscheduled TODO")
(org-agenda-skip-function '(org-agenda-skip-entry-if
'scheduled 'deadline 'timestamp
'todo '("BACKBURNER")))))
(setq org-agenda-custom-commands
'(("u" "Unscheduled TODO"
(todo "" unscheduled-todo))
("c" "Complete View"
((agenda "")
(todo "" unscheduled-todo))))
How do I get the above code to work? I think I have a fundamental misunderstanding of how and when the code and lists are getting evaluated. I've tried a number of configurations of ' and () in both setq and org-agenda-custom-commands, along with append to create lists, but I'd also like to understand what's going on here.
Here's an implementation along the lines of my comment (although I think you really don't need a macro here: a function does just as well or better):
(defun unscheduled-todo ()
'((org-agenda-overriding-header "\nUnscheduled TODO")
(org-agenda-skip-function '(org-agenda-skip-entry-if
'scheduled 'deadline 'timestamp
'todo '("BACKBURNER")))))
(setq org-agenda-custom-commands
; N.B. the character following this comment is a *backquote*
; (the key to the left of the 1 key on a standard US keyboard);
; it is *NOT* a quote (the key to the left of the ENTER key
; on a standard US keyboard).
`(("u" "Unscheduled TODO"
todo "" ,(unscheduled-todo))
("c" "Complete View"
((agenda "")
(todo "" ,(unscheduled-todo))))))
I hope it's correct now (I had to fix it a couple of bugs) but it's only lightly tested.
Note that this uses the backquote mechanism to quote most of the value in the
setq of org-agenda-custom-commands while allowing the evaluation of the call to the macro using the comma mechanism.
EDIT: As #Rorschach points out in a (now deleted) comment, I'm overcomplicating things. You still need backquote and comma, but you can use the variable you defined:
(setq unscheduled-todo
'((org-agenda-overriding-header "\nUnscheduled TODO")
(org-agenda-skip-function '(org-agenda-skip-entry-if
'scheduled 'deadline 'timestamp
'todo '("BACKBURNER")))))
(setq org-agenda-custom-commands
; N.B. the character following this comment is a *backquote*
; (the key to the left of the 1 key on a standard US keyboard);
; it is *NOT* a quote (the key to the left of the ENTER key
; on a standard US keyboard).
`(("u" "Unscheduled TODO"
todo "" ,unscheduled-todo)
("c" "Complete View"
((agenda "")
(todo "" ,unscheduled-todo)))))
The backquote/comma mechanism allows the evaluation of a spliced-in variable just as well as it allows the evaluation of a spliced-in function call.

Query parameter encoding using Jersey client

I am using Jersey client 2.25.1 and the queryParam(...) method does not correctly encode the values, e.g this approach fails:
Response response = client.target(uri)
.queryParam("a", "%20") // Translated into space ' '(!)
.queryParam("b", "{") // Will ruin template parsing(!)
.queryParam("c", "}") // Will ruin template parsing(!)
.queryParam("d", URLEncoder.encode(" ", "UTF-8")) // Using explicit encoding will translate ' ' into '+'(!)
.request().get();
So the workaround suggested is like this:
Response response = client.target(uri)
.queryParam("a", "{a}").resolveTemplate("a", "%20")
.queryParam("b", "{b}").resolveTemplate("b", "{")
.queryParam("c", "{c}").resolveTemplate("c", "}")
.queryParam("d", "{d}").resolveTemplate("d", " ")
.request().get();
This works, but it puzzles me that this very common use case doesn't have better library support from the Jersey client(?) I want to be able to have an arbitrary value properly URL encoded as a query parameter, so that exact same value will reach the server side.
Are there alternatives to this solution? Which is the preferred/best way to solve this?

Select from H2 adds "clob:" to texts in clojure

I am using a h2 database with clojure. I made a table and put some data in like this
(j/create-table :locations
[:id "bigint primary key auto_increment"]
[:title "varchar (255)"]
[:part "clob"])
(j/insert-records :locations
{:title "Steven Gerrard: I'm not the new Beckham" :part "He might not have the Becks appeal -- but Steven Gerrard says he's ready to light up Hollywood in his own way..."}))
)
)
And then I selected the data
(defn newest []
(database/mysql-db)
(let [results (j/with-connection db-spec
(j/with-query-results res
["select id, title, part from locations"]
(doall res)))]
results))
And I used the data on a clostache page
<div class="container">
<sections>
{{#newest}}
<p style="padding-bottom: 15px;">{{title}}<p>
<p style="padding-bottom: 15px;">{{part}}<p>
{{/newest}}
</sections>
</div>
On the page i get
Steven Gerrard: I'm not the new Beckham
clob0: 'He might not have the Becks appeal -- but Steven Gerrard says he''s ready to light up Hollywood in his own way...'
How can I remove the clob0: string that is attached to the text I have in the database? This happens even if I use text instead of clob for the part column in my database.
The 'clob0:' prefix is not actually attached to your data in database.
The reason you get this is because ResultSet returns instances of class java.sql.Clob for column "part" (for both CLOB and TEXT data types, they are actually synonyms).
It's not proper way to convert Clob to String by using toString() method, implementation is free to return any human-readable form. Correct way may be found in other answers.
You might have noticed that new lines get lost by the above... something like this adds them back in...
(defn clob-to-string [clob]
"Turn an Clob into a String, with new new lines"
(with-open [rdr (java.io.BufferedReader. (.getCharacterStream clob))]
(let [lseq (line-seq rdr)
butlast-line (butlast lseq)
butlast-line-mapped (map (fn [l] (str l "\n")) butlast-line)
last-line (last lseq)
all-lines-with-newline (concat butlast-line-mapped last-line)
]
(apply str all-lines-with-newline)
)))
I removed the clob: with:
(defn clob-to-string [row]
(assoc row :text (with-open [rdr (java.io.BufferedReader. (.getCharacterStream (:text row)))]
(apply str (line-seq rdr)))))
(defn newest []
(database/mysql-db)
(j/query db-spec
["select id, title, text from news"]
:row-fn clob-to-string
))

When creating a customizable value with defcustom, how can I validate users' entries?

I'm writing an elisp file that's evolving into a package, so I'm translating some of its variables into defcustom statements and documenting them. A few of these defcustom variables are related, and I'd like to validate values entered through the Customize system to ensure that the relationships hold true.
Here's an example of what I have:
(defcustom widget-canonical-names '("my_widget" . "widget_assembly 8911_j4")
"Documentation"
:type '(alist :key-type (string :tag "Widget's short name")
:value-type (string :tag "Full widget name"))
:risky nil
:group 'widgets)
(defcustom widget-colors '("my_widget" . "brown")
"Documentation"
:type '(alist :key-type (string :tag "Widget's short name")
:value-type (color :tag "color of the widget"))
:risky nil
:group 'widgets)
(defcustom widget-paths '("my_widget" . "~/widgets")
"Documentation"
:type '(alist :key-type (string :tag "Widget's short name")
:value-type (directory :tag "support files for widget"))
:risky nil
:group 'widgets)
So there are widgets and they have various settings, and I need to be able to access an arbitrary setting for a widget by knowing just the widget's short name. I'd like to make a validation function of some kind (googling around for "emacs defcustom validate" hasn't helped, unfortunately) such that if the user enters a widget name in widget-paths or widget-colors that is not in the widget-canonical-names list, they get an "are you sure?" warning and are cautioned about entering mismatched names. Can I attach such a validation function to my defcustoms? If so, what's the syntax for that?
Of course, what would be ideal would be to just make the user enter the short name once, but I can't figure out how to do that from the 'Composite Types' elisp documentation. So an even better answer to my question would tell me how to arrange a defcustom that sets up a data structure similar to this Python dict:
customized_widgets = {
"my_widget": { "canonical_name": "widget_assembly 8911_j4",
"widget_color": "brown",
"widget_path": "~/widgets",
},
"another_widget": { "canonical_name" : "widget_obsolete 11.0",
"widget_color": "blue",
"widget_path": "~/blue_widgets",
},
}
So: how can I get the behavior I want, where settings are grouped according to the data that'll be used to access them, or where a validation function warns users when they might be entering inconsistent data?
This will define the closest Emacs equivalent of that Python structure, with dicts represented as alists, and fixed keys of the inner dict represented as symbols.
(defcustom my-customized-widgets ()
"My widget customization alist"
:type '(alist
:tag "Widgets"
:key-type (string :tag "Short name")
:value-type
(set
:format "%v"
:entry-format "%b %v"
(cons :format "%v"
(const :format "" widget-canonical-name)
(string :tag "CName"))
(cons :format "%v"
(const :format "" widget-color)
(color :tag "Color"))
(cons :format "%v"
(const :format "" widget-path)
(directory :tag " Path"))))
:group 'widgets)