Skip to content

Commit 4c5eb47

Browse files
committed
Initial commit
0 parents  commit 4c5eb47

File tree

7 files changed

+313
-0
lines changed

7 files changed

+313
-0
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.html
2+
*.pdf
3+
*_files/
4+
/.luarc.json

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Jonathan Graves
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Forms Extension For Quarto
2+
3+
This extension allows you to add an HTML form to your Quarto HTML pages, using the the `form` shortcode
4+
5+
6+
7+
## Installing
8+
9+
```bash
10+
quarto add jlgraves-ubc/forms
11+
```
12+
This will install the extension under the `_extensions` subdirectory.
13+
If you're using version control, you will want to check in this directory.
14+
15+
## Using
16+
17+
The forms extension has two parts:
18+
19+
1) A set of metadata, in the document header, which defines the form's part
20+
2) A shortcode `{{< form >}}` which embeds it in the appropriate place in the document.
21+
22+
## Form Definition
23+
24+
You define a form using the metadata in the document header, as follows:
25+
26+
```yaml
27+
---
28+
form:
29+
action: "/action.js"
30+
submit: "Submit Now!"
31+
fields:
32+
- name: "A Text Field"
33+
- type: "text"
34+
- id: "textfield1"
35+
---
36+
```
37+
38+
Fields which take multiple entry values take a `values` parameter, which looks like:
39+
40+
```yaml
41+
- name: Checkbox
42+
type: checkbox
43+
id: checkbox1
44+
label: "My Checkbox"
45+
values:
46+
- text: "High"
47+
value: "hi"
48+
- text: "Low"
49+
value: "lo"
50+
- text: "Mid"
51+
value: "mid"
52+
```
53+
54+
You can see more detailed (and better-formatted) documentation in the example, below.
55+
56+
## Example
57+
58+
Here is the source code for a minimal example: [example.qmd](example.qmd).
59+

_extensions/forms/_extension.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
title: Forms
2+
author: Jonathan Graves
3+
version: 0.0.1
4+
quarto-required: ">=1.2.0"
5+
contributes:
6+
shortcodes:
7+
- forms.lua
8+

_extensions/forms/forms.lua

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
-- Forms.lua
2+
-- Author: Jonathan Graves
3+
4+
-- Helper Functions
5+
6+
local function checkHTMLDeps()
7+
-- check the HTML requirements for the library used
8+
end
9+
10+
local function isEmpty(s)
11+
return s == '' or s == nil
12+
end
13+
14+
-- Main Form Function Shortcode
15+
16+
return {
17+
18+
["form"] = function(args, kwargs, meta)
19+
20+
21+
if quarto.doc.is_format("html:js") then
22+
-- this will only run for HTML documents
23+
checkHTMLDeps()
24+
25+
local submit_text = pandoc.utils.stringify(meta["form.submit"])
26+
27+
-- These are the form items
28+
-- action (form.action) describes the handler function for the form submit
29+
local form_start = "<div id = \"form\" class = \"form-wrapper\">\n <form action = \"" .. pandoc.utils.stringify(meta["form.action"]) .. "\">\n"
30+
local form_end = "</form></div>\n"
31+
32+
-- Fields for the Form --
33+
local fields = meta["form.fields"]
34+
35+
for f = 1, #fields do
36+
37+
local field = fields[f]
38+
39+
40+
if isEmpty(field.type) and not isEmpty(field.text) then
41+
-- Handle non-fields (i.e. text)
42+
43+
text = pandoc.utils.stringify(field.text)
44+
45+
if text == "" then
46+
form_start = form_start .. "<hr>" .. "\n"
47+
else
48+
form_start = form_start .. "<br><p>" .. text .. "</p>\n"
49+
end
50+
else
51+
-- Handle regular form fields
52+
53+
local name = pandoc.utils.stringify(field.name)
54+
local type = pandoc.utils.stringify(field.type)
55+
local id = pandoc.utils.stringify(field.id)
56+
local label = pandoc.utils.stringify(field.label)
57+
58+
if type == "text" then
59+
-- Handle text fields
60+
61+
form_start = form_start .. "<label for=\"" .. id .. "\">" .. label .. "</label><br>\n"
62+
form_start = form_start .. " <input type = \"text\" id = \"" .. id .. "\" name = \"" .. name .. "\"><br>\n"
63+
64+
elseif type == "textarea" then
65+
-- Handle textarea fields
66+
local cols = "30"
67+
local rows = "10"
68+
69+
if not isEmpty(field.width) then
70+
cols = pandoc.utils.stringify(field.width)
71+
end
72+
73+
if not isEmpty(field.height) then
74+
rows = pandoc.utils.stringify(field.height)
75+
end
76+
77+
78+
79+
form_start = form_start .. "<label for =\"" .. id .. "\">" .. label .. "</label><br>\n"
80+
form_start = form_start .. "<textarea name =\"" .. name .. "\" id = \"" .. id .. "\" rows = ..\"" .. rows .. "\" cols =\"" .. cols .."\"></textarea><br>\n"
81+
82+
elseif type == "select" then
83+
-- Handle selector (drop-dpwns)
84+
85+
local size = "3"
86+
if not isEmpty(field.size) then
87+
size = pandoc.utils.stringify(field.size)
88+
end
89+
90+
91+
local multiple = ""
92+
if not isEmpty(field.multiple) then
93+
if pandoc.utils.stringify(field.multiple) == "true" then
94+
multiple = "multiple"
95+
end
96+
end
97+
98+
form_start = form_start .. "<label for = \"" .. id .. "\">" .. label .. "</label><br>\n"
99+
form_start = form_start .. "<select id= \"" .. id .. "\" size = \"" .. size .. "\" " .. multiple .. ">\n"
100+
101+
for v = 1,#field.values do
102+
local value = field.values[v]
103+
local label_t = pandoc.utils.stringify(value.text)
104+
local val = pandoc.utils.stringify(value.value)
105+
106+
form_start = form_start .. " <option value = \"" .. val .. "\">" .. label_t .. "</option><br>\n"
107+
108+
end
109+
110+
form_start = form_start .. "</select><br>\n"
111+
112+
else
113+
-- Handle radio and checkboxes
114+
115+
form_start = form_start .. "<span>" .. label .. "</span><br>\n"
116+
117+
for v = 1, #field.values do
118+
119+
local value = field.values[v]
120+
-- multi-option fields need to have a label for each value
121+
local label_t = pandoc.utils.stringify(value.text)
122+
local val = pandoc.utils.stringify(value.value)
123+
124+
125+
form_start = form_start .. " <input type = \"" .. type .. "\" id = \"" .. id .. "\" name = \"" .. name .. "\" value =\"" .. val .. "\">\n"
126+
form_start = form_start .. " <label for=\"" .. id .. "\">" .. label_t .. "</label><br> \n"
127+
-- <input type = "type" id = "id" name = "name" value = "label_v">
128+
-- <label for = "id">label_t</label><br>
129+
end
130+
131+
132+
end
133+
134+
end
135+
end
136+
-- Close the form and submit
137+
form_start = form_start .. "<input type=\"submit\" value = \"" .. submit_text .. "\"> \n"
138+
form_start = form_start .. form_end
139+
--quarto.log.output(form_start)
140+
return pandoc.RawInline("html", form_start)
141+
142+
143+
else
144+
return pandoc.Null()
145+
end
146+
147+
end
148+
149+
}
150+

example.qmd

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
title: "Forms Example"
3+
format: html
4+
5+
form:
6+
submit: "Submit"
7+
action: ""
8+
fields:
9+
- text: "This is a form spacer"
10+
- name: Text1
11+
type: text
12+
id: textid
13+
label: "A text field (1)"
14+
- name: Text2
15+
type: text
16+
id: textid2
17+
label: "Another text field (2)"
18+
- text: "This is a form spacer"
19+
- text: ---
20+
- name: Radio
21+
type: radio
22+
label: "My Radio Button"
23+
id: radio1
24+
values:
25+
- text: Good
26+
value: 1
27+
- text: Bad
28+
value: 0
29+
- name: Checkbox
30+
type: checkbox
31+
id: checkbox1
32+
label: "My Checkbox"
33+
values:
34+
- text: "High"
35+
value: "hi"
36+
- text: "Low"
37+
value: "lo"
38+
- text: "Mid"
39+
value: "mid"
40+
- name: Selector
41+
type: select
42+
id: selector1
43+
label: My Selector
44+
multiple: true #multiple selections?
45+
size: 3 #number to size
46+
values:
47+
- text: Option 1
48+
value: 1
49+
- text: Option 2
50+
value: 2
51+
- text: Option 3
52+
value: 3
53+
- text: Option 4
54+
value: 4
55+
- name: BigText
56+
id: textarea1
57+
type: textarea
58+
label: Enter lots of text
59+
width: 30 #in rows
60+
height: 30 #in cols
61+
---
62+
63+
64+
---
65+
## Heading
66+
67+
{{< form >}}
68+
69+

0 commit comments

Comments
 (0)