-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add files for first complete example book
This includes: - parts/chapters in _quarto.yml - a DESCRIPTION file - a GitHub Action - a WebR example page
- Loading branch information
1 parent
4091921
commit 3498e6a
Showing
30 changed files
with
2,861 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# [A] SET PACKAGE NAME, BOOK TITLE AND VERSION | ||
Package: PACKAGE_NAME | ||
Title: BOOK_TITLE | ||
Version: 0.1 | ||
|
||
# [B] SET AUTHOR NAMES AND EMAILS | ||
Authors@R: c( | ||
person("FORENAME1", "SURNAME1", , "EMAIL.1@strath.ac.uk", role = c("aut", "cre")), | ||
person("FORENAME2", "SURNAME2", , "EMAIL.2@strath.ac.uk", role = c("aut", "cre")) | ||
) | ||
|
||
# [C] SET REPOSITORY URL | ||
URL: https://github.com/sipbs-compbiol/REPOSITORY | ||
|
||
# [D] SET REQUIRED PACKAGES IN R | ||
Depends: | ||
R (>= 3.1.0) | ||
Imports: | ||
tidyverse (>= 2.0.0), | ||
ggplot2, | ||
flextable, | ||
kableExtra | ||
Suggests: | ||
knitr, | ||
sessioninfo | ||
Remotes: tidyverse/dplyr | ||
Encoding: UTF-8 | ||
|
||
# [E] SET LICENCING INFORMATION | ||
License: CC NC ND 4.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# README.md sipbs-compbiol-book-template | ||
|
||
This repository is a template, intended as a convenience to take some manual work out of setting the style for Quarto books used by SIPBS Computational Biology. | ||
|
||
This version of the template includes: | ||
|
||
- a GitHub Action (`.github/workflows/publish.yml`) that should update the GitHub Pages version of the book on each push to the `main` branch. | ||
- an example WebR page | ||
|
||
## How to use this template | ||
|
||
### Setting Up | ||
|
||
1. Click on the `Use This Template` button to create a new repository/project based on this template | ||
2. Clone or download the project to your local development environment | ||
3. Open the project folder and modify `_variables.yml` to change: | ||
- `[A]` academic year | ||
- `[B]` administrator name and contact information | ||
- `[C]` GitHub URLs for the repository | ||
4. Modify `_quarto.yml` to change: | ||
- `[A]` book title | ||
- `[B]` footer text | ||
- `[C]` GitHub repository URL | ||
- `[D]` author name and publication/presentation date | ||
- `[E]` chapters and sections | ||
5. Modify `DESCRIPTION` to change: | ||
- `[A]` package name and book title | ||
- `[B]` author names and emails | ||
- `[C]` repository URL | ||
- `[D]` required R packages | ||
- `[E]` licensing information | ||
6. Change or update the licence, if required | ||
7. Add the `quarto-webr` extension (if necessary) using the command `quarto add coatless/quarto-webr` | ||
8. Generate the book by issuing `quarto render` in the terminal, or using the `Render` button in `RStudio` | ||
9. Commit your updates in the local development environment | ||
10. Publish your book to GitHub Pages by issuing `quarto publish gh-pages` in the terminal | ||
|
||
### General Usage | ||
|
||
1. Make changes to the `.qmd` files, updating chapter information in `_quarto.yml`, as needed for your material | ||
2. Commit your changes locally to the git repository | ||
3. Push your changes to the GitHub repository |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
name: webr | ||
title: Embedded webr code cells | ||
author: James Joseph Balamuta | ||
version: 0.4.2-dev.4 | ||
quarto-required: ">=1.2.198" | ||
contributes: | ||
filters: | ||
- webr.lua |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,274 @@ | ||
// Supported Evaluation Types for Context | ||
globalThis.EvalTypes = Object.freeze({ | ||
Interactive: 'interactive', | ||
Setup: 'setup', | ||
Output: 'output', | ||
}); | ||
|
||
// Function that obtains the font size for a given element | ||
globalThis.qwebrCurrentFontSizeOnElement = function(element, cssProperty = 'font-size') { | ||
|
||
const currentFontSize = parseFloat( | ||
window | ||
.getComputedStyle(element) | ||
.getPropertyValue(cssProperty) | ||
); | ||
|
||
return currentFontSize; | ||
} | ||
|
||
// Function to determine font scaling | ||
globalThis.qwebrScaledFontSize = function(div, qwebrOptions) { | ||
// Determine if we should compute font-size using RevealJS's `--r-main-font-size` | ||
// or if we can directly use the document's `font-size`. | ||
const cssProperty = document.body.classList.contains('reveal') ? | ||
"--r-main-font-size" : "font-size"; | ||
|
||
// Get the current font size on the div element | ||
const elementFontSize = qwebrCurrentFontSizeOnElement(div, cssProperty); | ||
|
||
// Determine the scaled font size value | ||
const scaledFontSize = ((qwebrOptions['editor-font-scale'] ?? 1) * elementFontSize) ?? 17.5; | ||
|
||
return scaledFontSize; | ||
} | ||
|
||
|
||
// Function that dispatches the creation request | ||
globalThis.qwebrCreateHTMLElement = function ( | ||
cellData | ||
) { | ||
|
||
// Extract key components | ||
const evalType = cellData.options.context; | ||
const qwebrCounter = cellData.id; | ||
|
||
// We make an assumption that insertion points are defined by the Lua filter as: | ||
// qwebr-insertion-location-{qwebrCounter} | ||
const elementLocator = document.getElementById(`qwebr-insertion-location-${qwebrCounter}`); | ||
|
||
// Figure out the routine to use to insert the element. | ||
let qwebrElement; | ||
switch ( evalType ) { | ||
case EvalTypes.Interactive: | ||
qwebrElement = qwebrCreateInteractiveElement(qwebrCounter, cellData.options); | ||
break; | ||
case EvalTypes.Output: | ||
qwebrElement = qwebrCreateNonInteractiveOutputElement(qwebrCounter, cellData.options); | ||
break; | ||
case EvalTypes.Setup: | ||
qwebrElement = qwebrCreateNonInteractiveSetupElement(qwebrCounter, cellData.options); | ||
break; | ||
default: | ||
qwebrElement = document.createElement('div'); | ||
qwebrElement.textContent = 'Error creating `quarto-webr` element'; | ||
} | ||
|
||
// Insert the dynamically generated object at the document location. | ||
elementLocator.appendChild(qwebrElement); | ||
}; | ||
|
||
// Function that setups the interactive element creation | ||
globalThis.qwebrCreateInteractiveElement = function (qwebrCounter, qwebrOptions) { | ||
|
||
// Create main div element | ||
var mainDiv = document.createElement('div'); | ||
mainDiv.id = 'qwebr-interactive-area-' + qwebrCounter; | ||
mainDiv.className = `qwebr-interactive-area`; | ||
if (qwebrOptions.classes) { | ||
mainDiv.className += " " + qwebrOptions.classes | ||
} | ||
|
||
// Add a unique cell identifier that users can customize | ||
if (qwebrOptions.label) { | ||
mainDiv.setAttribute('data-id', qwebrOptions.label); | ||
} | ||
|
||
// Create toolbar div | ||
var toolbarDiv = document.createElement('div'); | ||
toolbarDiv.className = 'qwebr-editor-toolbar'; | ||
toolbarDiv.id = 'qwebr-editor-toolbar-' + qwebrCounter; | ||
|
||
// Create a div to hold the left buttons | ||
var leftButtonsDiv = document.createElement('div'); | ||
leftButtonsDiv.className = 'qwebr-editor-toolbar-left-buttons'; | ||
|
||
// Create a div to hold the right buttons | ||
var rightButtonsDiv = document.createElement('div'); | ||
rightButtonsDiv.className = 'qwebr-editor-toolbar-right-buttons'; | ||
|
||
// Create Run Code button | ||
var runCodeButton = document.createElement('button'); | ||
runCodeButton.className = 'btn btn-default qwebr-button qwebr-button-run'; | ||
runCodeButton.disabled = true; | ||
runCodeButton.type = 'button'; | ||
runCodeButton.id = 'qwebr-button-run-' + qwebrCounter; | ||
runCodeButton.textContent = '🟡 Loading webR...'; | ||
runCodeButton.title = `Run code (Shift + Enter)`; | ||
|
||
// Append buttons to the leftButtonsDiv | ||
leftButtonsDiv.appendChild(runCodeButton); | ||
|
||
// Create Reset button | ||
var resetButton = document.createElement('button'); | ||
resetButton.className = 'btn btn-light btn-xs qwebr-button qwebr-button-reset'; | ||
resetButton.type = 'button'; | ||
resetButton.id = 'qwebr-button-reset-' + qwebrCounter; | ||
resetButton.title = 'Start over'; | ||
resetButton.innerHTML = '<i class="fa-solid fa-arrows-rotate"></i>'; | ||
|
||
// Create Copy button | ||
var copyButton = document.createElement('button'); | ||
copyButton.className = 'btn btn-light btn-xs qwebr-button qwebr-button-copy'; | ||
copyButton.type = 'button'; | ||
copyButton.id = 'qwebr-button-copy-' + qwebrCounter; | ||
copyButton.title = 'Copy code'; | ||
copyButton.innerHTML = '<i class="fa-regular fa-copy"></i>'; | ||
|
||
// Append buttons to the rightButtonsDiv | ||
rightButtonsDiv.appendChild(resetButton); | ||
rightButtonsDiv.appendChild(copyButton); | ||
|
||
// Create console area div | ||
var consoleAreaDiv = document.createElement('div'); | ||
consoleAreaDiv.id = 'qwebr-console-area-' + qwebrCounter; | ||
consoleAreaDiv.className = 'qwebr-console-area'; | ||
|
||
// Create editor div | ||
var editorDiv = document.createElement('div'); | ||
editorDiv.id = 'qwebr-editor-' + qwebrCounter; | ||
editorDiv.className = 'qwebr-editor'; | ||
|
||
// Create output code area div | ||
var outputCodeAreaDiv = document.createElement('div'); | ||
outputCodeAreaDiv.id = 'qwebr-output-code-area-' + qwebrCounter; | ||
outputCodeAreaDiv.className = 'qwebr-output-code-area'; | ||
outputCodeAreaDiv.setAttribute('aria-live', 'assertive'); | ||
|
||
// Create pre element inside output code area | ||
var preElement = document.createElement('pre'); | ||
preElement.style.visibility = 'hidden'; | ||
outputCodeAreaDiv.appendChild(preElement); | ||
|
||
// Create output graph area div | ||
var outputGraphAreaDiv = document.createElement('div'); | ||
outputGraphAreaDiv.id = 'qwebr-output-graph-area-' + qwebrCounter; | ||
outputGraphAreaDiv.className = 'qwebr-output-graph-area'; | ||
|
||
// Append buttons to the toolbar | ||
toolbarDiv.appendChild(leftButtonsDiv); | ||
toolbarDiv.appendChild(rightButtonsDiv); | ||
|
||
// Append all elements to the main div | ||
mainDiv.appendChild(toolbarDiv); | ||
consoleAreaDiv.appendChild(editorDiv); | ||
consoleAreaDiv.appendChild(outputCodeAreaDiv); | ||
mainDiv.appendChild(consoleAreaDiv); | ||
mainDiv.appendChild(outputGraphAreaDiv); | ||
|
||
return mainDiv; | ||
} | ||
|
||
// Function that adds output structure for non-interactive output | ||
globalThis.qwebrCreateNonInteractiveOutputElement = function(qwebrCounter, qwebrOptions) { | ||
// Create main div element | ||
var mainDiv = document.createElement('div'); | ||
mainDiv.id = 'qwebr-noninteractive-area-' + qwebrCounter; | ||
mainDiv.className = `qwebr-noninteractive-area`; | ||
if (qwebrOptions.classes) { | ||
mainDiv.className += " " + qwebrOptions.classes | ||
} | ||
|
||
// Add a unique cell identifier that users can customize | ||
if (qwebrOptions.label) { | ||
mainDiv.setAttribute('data-id', qwebrOptions.label); | ||
} | ||
|
||
// Create a status container div | ||
var statusContainer = createLoadingContainer(qwebrCounter); | ||
|
||
// Create output code area div | ||
var outputCodeAreaDiv = document.createElement('div'); | ||
outputCodeAreaDiv.id = 'qwebr-output-code-area-' + qwebrCounter; | ||
outputCodeAreaDiv.className = 'qwebr-output-code-area'; | ||
outputCodeAreaDiv.setAttribute('aria-live', 'assertive'); | ||
|
||
// Create pre element inside output code area | ||
var preElement = document.createElement('pre'); | ||
preElement.style.visibility = 'hidden'; | ||
outputCodeAreaDiv.appendChild(preElement); | ||
|
||
// Create output graph area div | ||
var outputGraphAreaDiv = document.createElement('div'); | ||
outputGraphAreaDiv.id = 'qwebr-output-graph-area-' + qwebrCounter; | ||
outputGraphAreaDiv.className = 'qwebr-output-graph-area'; | ||
|
||
// Append all elements to the main div | ||
mainDiv.appendChild(statusContainer); | ||
mainDiv.appendChild(outputCodeAreaDiv); | ||
mainDiv.appendChild(outputGraphAreaDiv); | ||
|
||
return mainDiv; | ||
}; | ||
|
||
// Function that adds a stub in the page to indicate a setup cell was used. | ||
globalThis.qwebrCreateNonInteractiveSetupElement = function(qwebrCounter, qwebrOptions) { | ||
// Create main div element | ||
var mainDiv = document.createElement('div'); | ||
mainDiv.id = `qwebr-noninteractive-setup-area-${qwebrCounter}`; | ||
mainDiv.className = `qwebr-noninteractive-setup-area`; | ||
if (qwebrOptions.classes) { | ||
mainDiv.className += " " + qwebrOptions.classes | ||
} | ||
|
||
|
||
// Add a unique cell identifier that users can customize | ||
if (qwebrOptions.label) { | ||
mainDiv.setAttribute('data-id', qwebrOptions.label); | ||
} | ||
|
||
// Create a status container div | ||
var statusContainer = createLoadingContainer(qwebrCounter); | ||
|
||
// Append status onto the main div | ||
mainDiv.appendChild(statusContainer); | ||
|
||
return mainDiv; | ||
} | ||
|
||
|
||
// Function to create loading container with specified ID | ||
globalThis.createLoadingContainer = function(qwebrCounter) { | ||
|
||
// Create a status container | ||
const container = document.createElement('div'); | ||
container.id = `qwebr-non-interactive-loading-container-${qwebrCounter}`; | ||
container.className = 'qwebr-non-interactive-loading-container qwebr-cell-needs-evaluation'; | ||
|
||
// Create an R project logo to indicate its a code space | ||
const rProjectIcon = document.createElement('i'); | ||
rProjectIcon.className = 'fa-brands fa-r-project fa-3x qwebr-r-project-logo'; | ||
|
||
// Setup a loading icon from font awesome | ||
const spinnerIcon = document.createElement('i'); | ||
spinnerIcon.className = 'fa-solid fa-spinner fa-spin fa-1x qwebr-icon-status-spinner'; | ||
|
||
// Add a section for status text | ||
const statusText = document.createElement('p'); | ||
statusText.id = `qwebr-status-text-${qwebrCounter}`; | ||
statusText.className = `qwebr-status-text qwebr-cell-needs-evaluation`; | ||
statusText.innerText = 'Loading webR...'; | ||
|
||
// Incorporate an inner container | ||
const innerContainer = document.createElement('div'); | ||
|
||
// Append elements to the inner container | ||
innerContainer.appendChild(spinnerIcon); | ||
innerContainer.appendChild(statusText); | ||
|
||
// Append elements to the main container | ||
container.appendChild(rProjectIcon); | ||
container.appendChild(innerContainer); | ||
|
||
return container; | ||
} |
Oops, something went wrong.