Skip to content

Commit c3531e3

Browse files
Set up Quarto website course shell and {renv}
1 parent 1cbdbe1 commit c3531e3

File tree

147 files changed

+6467
-1022
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

147 files changed

+6467
-1022
lines changed

.Rprofile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Use Posit Package Manager
2+
options(
3+
renv.config.pak.enabled = TRUE,
4+
renv.config.ppm.enabled = TRUE,
5+
renv.config.ppm.default = TRUE
6+
)
7+
8+
# Use renv
9+
source("renv/activate.R")
10+
11+
# Set error handler to rlang
12+
if (require(rlang, quietly = TRUE)) {
13+
globalCallingHandlers(error = rlang::entrace)
14+
}

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,10 @@ dmypy.json
127127

128128
# R user settings
129129
.Rproj.user
130+
131+
# Quarto project files
132+
/.quarto/
133+
134+
# Jupyter Book and Quarto outputs
135+
/_build/
136+
/_site/

R/combine-pdfs.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
library(fs)
2+
library(qpdf)
3+
4+
worksheets <- path("_site", "activities", "01_analysis-review.pdf")
5+
output <- path("_site", "activities", "analysis.pdf")
6+
combined_pdf <- file_temp(ext = "pdf")
7+
pdf_combine(c(worksheets, output), combined_pdf)
8+
file_copy(combined_pdf, worksheets, overwrite = TRUE)

R/format-md-link.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
format_md_link <- function(link) {
2+
glue::glue('[{link |> stringr::str_remove("https://")}]({link})') |>
3+
I()
4+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
title: Qrcode
2+
author: Jannik Buhr
3+
version: 0.0.1
4+
contributes:
5+
shortcodes:
6+
- qrcode.lua

_extensions/jmbuhr/qrcode/assets/qrcode.js

Lines changed: 614 additions & 0 deletions
Large diffs are not rendered by default.

_extensions/jmbuhr/qrcode/qrcode.lua

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
-- for development:
2+
local p = quarto.log.warning
3+
4+
---Format string like in bash or python,
5+
---e.g. f('Hello ${one}', {one = 'world'})
6+
---@param s string The string to format
7+
---@param kwargs {[string]: string} A table with key-value replacemen pairs
8+
---@return string
9+
local function f(s, kwargs)
10+
return (s:gsub('($%b{})', function(w) return kwargs[w:sub(3, -2)] or w end))
11+
end
12+
13+
14+
---Merge user provided options with defaults
15+
---@param userOptions table
16+
---@return string JSON string to pass to molstar
17+
local function mergeOptions(url, userOptions)
18+
local defaultOptions = {
19+
text = url,
20+
width = 128,
21+
height = 128,
22+
colorDark = "#000000",
23+
colorLight = "#ffffff",
24+
}
25+
if userOptions == nil then
26+
return quarto.json.encode(defaultOptions)
27+
end
28+
29+
for k, v in pairs(userOptions) do
30+
local value = pandoc.utils.stringify(v)
31+
if value == 'true' then value = true end
32+
if value == 'false' then value = false end
33+
defaultOptions[k] = value
34+
end
35+
36+
return quarto.json.encode(defaultOptions)
37+
end
38+
39+
40+
---@return string
41+
local function wrapInlineDiv(options)
42+
return [[
43+
<div id="${id}" class="qrcode"></div>
44+
<script type="text/javascript">
45+
(function() {
46+
var script = document.currentScript;
47+
var qrcode = script.previousElementSibling;
48+
qrcode.qrcode = new QRCode(qrcode, ]] .. options .. [[);
49+
script.remove();
50+
})();
51+
</script>
52+
]]
53+
end
54+
55+
---@return string
56+
local function wrapInlineTex(url, opts)
57+
return [[
58+
\qrcode[]] .. opts .. [[]{]] .. url .. [[}
59+
]]
60+
end
61+
62+
return {
63+
['qrcode'] = function(args, kwargs, _)
64+
if quarto.doc.is_format("html:js") then
65+
quarto.doc.add_html_dependency {
66+
name = 'qrcodejs',
67+
version = 'v1.0.0',
68+
scripts = { './assets/qrcode.js' },
69+
}
70+
local url = pandoc.utils.stringify(args[1])
71+
local id = ""
72+
if args[2] ~= nil then
73+
id = f('id="${id}" ', { id = pandoc.utils.stringify(id) })
74+
end
75+
local options = mergeOptions(url, kwargs)
76+
local text = wrapInlineDiv(options)
77+
return pandoc.RawBlock(
78+
'html',
79+
f(text, { id = id })
80+
)
81+
elseif quarto.doc.is_format("pdf") then
82+
quarto.doc.use_latex_package("qrcode")
83+
local url = pandoc.utils.stringify(args[1])
84+
local opts = ""
85+
for k, v in pairs(kwargs) do
86+
if string.match(k, "^pdf") then
87+
k = string.sub(k, 4)
88+
opts = opts .. k .. "=" .. v .. ", "
89+
end
90+
end
91+
for _, v in ipairs(args) do
92+
if string.match(v, "^pdf") then
93+
v = string.sub(v, 4)
94+
opts = opts .. v .. ", "
95+
end
96+
end
97+
if string.len(opts) then
98+
opts = string.sub(opts, 1, string.len(opts) - 2)
99+
end
100+
local text = wrapInlineTex(url, opts)
101+
return pandoc.RawBlock(
102+
'tex',
103+
text
104+
)
105+
end
106+
end,
107+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
title: Include Code Files
2+
author: Bruno Beaufils
3+
version: 1.0.0
4+
quarto-required: ">=1.2"
5+
contributes:
6+
filters:
7+
- include-code-files.lua
8+
9+
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
--- include-code-files.lua – filter to include code from source files
2+
---
3+
--- Copyright: © 2020 Bruno BEAUFILS
4+
--- License: MIT – see LICENSE file for details
5+
6+
--- Dedent a line
7+
local function dedent(line, n)
8+
return line:sub(1, n):gsub(" ", "") .. line:sub(n + 1)
9+
end
10+
11+
--- Find snippet start and end.
12+
--
13+
-- Use this to populate startline and endline.
14+
-- This should work like pandocs snippet functionality: https://github.com/owickstrom/pandoc-include-code/tree/master
15+
local function snippet(cb, fh)
16+
if not cb.attributes.snippet then
17+
return
18+
end
19+
20+
-- Cannot capture enum: http://lua-users.org/wiki/PatternsTutorial
21+
local comment
22+
local comment_stop = ""
23+
if
24+
string.match(cb.attributes.include, ".py$")
25+
or string.match(cb.attributes.include, ".jl$")
26+
or string.match(cb.attributes.include, ".r$")
27+
then
28+
comment = "#"
29+
elseif string.match(cb.attributes.include, ".o?js$") or string.match(cb.attributes.include, ".css$") then
30+
comment = "//"
31+
elseif string.match(cb.attributes.include, ".lua$") then
32+
comment = "--"
33+
elseif string.match(cb.attributes.include, ".html$") then
34+
comment = "<!%-%-"
35+
comment_stop = " *%-%->"
36+
else
37+
-- If not known assume that it is something one or two long and not alphanumeric.
38+
comment = "%W%W?"
39+
end
40+
41+
local p_start = string.format("^ *%s start snippet %s%s", comment, cb.attributes.snippet, comment_stop)
42+
local p_stop = string.format("^ *%s end snippet %s%s", comment, cb.attributes.snippet, comment_stop)
43+
local start, stop = nil, nil
44+
45+
-- Cannot use pairs.
46+
local line_no = 1
47+
for line in fh:lines() do
48+
if start == nil then
49+
if string.match(line, p_start) then
50+
start = line_no + 1
51+
end
52+
elseif stop == nil then
53+
if string.match(line, p_stop) then
54+
stop = line_no - 1
55+
end
56+
else
57+
break
58+
end
59+
line_no = line_no + 1
60+
end
61+
62+
-- Reset so nothing is broken later on.
63+
fh:seek("set")
64+
65+
-- If start and stop not found, just continue
66+
if start == nil or stop == nil then
67+
return nil
68+
end
69+
70+
cb.attributes.startLine = tostring(start)
71+
cb.attributes.endLine = tostring(stop)
72+
end
73+
74+
--- Filter function for code blocks
75+
local function transclude(cb)
76+
if cb.attributes.include then
77+
local content = ""
78+
local fh = io.open(cb.attributes.include)
79+
if not fh then
80+
io.stderr:write("Cannot open file " .. cb.attributes.include .. " | Skipping includes\n")
81+
else
82+
local number = 1
83+
local start = 1
84+
85+
-- change hyphenated attributes to PascalCase
86+
for i, pascal in pairs({ "startLine", "endLine" }) do
87+
local hyphen = pascal:gsub("%u", "-%0"):lower()
88+
if cb.attributes[hyphen] then
89+
cb.attributes[pascal] = cb.attributes[hyphen]
90+
cb.attributes[hyphen] = nil
91+
end
92+
end
93+
94+
-- Overwrite startLine and stopLine with the snippet if any.
95+
snippet(cb, fh)
96+
97+
if cb.attributes.startLine then
98+
cb.attributes.startFrom = cb.attributes.startLine
99+
start = tonumber(cb.attributes.startLine)
100+
end
101+
102+
for line in fh:lines("L") do
103+
if cb.attributes.dedent then
104+
line = dedent(line, cb.attributes.dedent)
105+
end
106+
if number >= start then
107+
if not cb.attributes.endLine or number <= tonumber(cb.attributes.endLine) then
108+
content = content .. line
109+
end
110+
end
111+
number = number + 1
112+
end
113+
114+
fh:close()
115+
end
116+
117+
-- remove key-value pair for used keys
118+
cb.attributes.include = nil
119+
cb.attributes.startLine = nil
120+
cb.attributes.endLine = nil
121+
cb.attributes.dedent = nil
122+
123+
-- return final code block
124+
return pandoc.CodeBlock(content, cb.attr)
125+
end
126+
end
127+
128+
return {
129+
{ CodeBlock = transclude },
130+
}

_quarto.yml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
project:
2+
type: website
3+
output-dir: _site
4+
preview:
5+
port: 4200
6+
browser: false
7+
render:
8+
- "*.qmd"
9+
- "slides"
10+
- "!quarto"
11+
- "!tools"
12+
- "!about"
13+
- "!getting-started"
14+
- "!notes"
15+
16+
post-render:
17+
- R/combine-pdfs.R
18+
19+
website:
20+
title: "{{< var course.full-title >}}"
21+
description: >
22+
Course website for {{< var course.code >}} of the Department of Computer Science at the
23+
University of British Columbia
24+
open-graph: true
25+
twitter-card: true
26+
site-url: "https://ubc-cs.github.io/cpsc203"
27+
repo-url: "https://github.com/UBC-CS/cpsc203"
28+
repo-actions: [source, edit, issue]
29+
bread-crumbs: false
30+
31+
page-footer:
32+
left: >
33+
CPSC 203 was created by
34+
[Dr. Cinda Heeren](https://www.cs.ubc.ca/people/cinda-heeren),
35+
then adapted by [Dr. Firas Moosvi](https://firas.moosvi.com), and further
36+
refined by [Dr. Ian Mitchell](https://www.cs.ubc.ca/~mitchell/).
37+
The website and slides were converted to [Quarto](https://quarto.org/) by
38+
[Dr. Stephan Koenig](https://stephankoenig.io).
39+
center: >
40+
UBC's Point Grey Campus is located on the traditional, ancestral, and
41+
unceded territory of the [xʷməθkʷəy̓ə
42+
(Musqueam)](https://www.musqueam.bc.ca/) people.
43+
right: >
44+
Unless specified otherwise, all content on this site is licensed under
45+
[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0)
46+
{{< iconify fa6-brands creative-commons >}}
47+
{{< iconify fa6-brands creative-commons-by >}}
48+
{{< iconify fa6-brands creative-commons-sa >}}
49+
50+
search:
51+
location: sidebar
52+
type: overlay
53+
54+
sidebar:
55+
style: floating
56+
search: true
57+
contents:
58+
- section: "Course information"
59+
contents:
60+
- href: announcements.qmd
61+
text: "Announcements"
62+
- href: syllabus.qmd
63+
text: "Syllabus"
64+
- href: index.qmd
65+
text: "Schedule"
66+
- section: "Resources"
67+
contents:
68+
- href: formatting.qmd
69+
text: "Formatting"
70+
- href: "https://canvas.ubc.ca/courses/130127"
71+
text: "Canvas"
72+
- href: "https://ca.prairielearn.com/pl/course_instance/6665"
73+
text: "PrairieLearn"
74+
75+
# comments:
76+
# giscus:
77+
# repo: UBC-CS/cpsc203
78+
# repo-id:
79+
# category: announcements
80+
# category-id:
81+
# mapping: title
82+
# reactions-enabled: true
83+
# loading: lazy
84+
85+
format:
86+
html:
87+
theme: [cosmo, styles/theme.scss]
88+
css: styles/styles.css
89+
toc: true
90+
91+
freeze: auto

0 commit comments

Comments
 (0)