Skip to content

Commit

Permalink
Merge pull request #70 from qmd-lab/trigger-shortcut-attr
Browse files Browse the repository at this point in the history
Trigger shortcut attr
  • Loading branch information
andrewpbray authored Aug 9, 2024
2 parents 31d705e + 10b778b commit bcd8533
Show file tree
Hide file tree
Showing 14 changed files with 339 additions and 143 deletions.
80 changes: 51 additions & 29 deletions _extensions/closeread/closeread.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
-- set defaults
local debug_mode = false
local trigger_selectors = {["focus-on"] = true}
local cr_attributes = {["pan-to"] = true, ["scale-by"] = true, ["highlight-spans"] = true}
local cr_attributes = {["pan-to"] = true,
["scale-by"] = true,
["highlight-spans"] = true}
local remove_header_space = false
local global_layout = "sidebar-left"

Expand Down Expand Up @@ -375,61 +377,81 @@ function process_trigger_shortcut(para)

local new_inlines = pandoc.Inlines({})
local sticky_id = nil
local focus_attributes = {}
local skip_next = false
local prefix = "cr-"

for i, elem in ipairs(para.content) do

-- if there is a Space that follows a Cite, remove it
if skip_next then
skip_next = false -- reset flag
-- skip any space that follows a cr-citation
if elem.t == "Space" then
goto endofloop
skip_next = false -- reset flag and skip this space
--elseif elem.t ~= "Span" then
-- skip_next = false -- reset flag but don't skip this element
-- new_inlines:insert(elem) -- it's not a space or span, so we insert it
end
end

if elem.t == 'Cite' then
local cite_id = elem.citations[1].id
else
-- process Cite block
if elem.t == 'Cite' then
local cite_id = elem.citations[1].id
-- if it's a cr-cite, don't insert it
if string.find(cite_id, "^" .. prefix) == 1 then
-- but grab id for focus block
sticky_id = cite_id
-- and remove any Space that precedes it
if i > 1 and para.content[i-1].t == "Space" then
new_inlines:remove(#new_inlines)
end
skip_next = true -- and prepare to to skip following Space
else
-- if it's a cite that's not cr-, insert it
new_inlines:insert(elem)
end

-- if it's a cr- citation
if string.find(cite_id, "^" .. prefix) == 1 then
sticky_id = cite_id

-- don't insert this element but also

-- remove any preceding Space
if i > 1 and para.content[i-1].t == "Space" then
new_inlines:remove(#new_inlines)
-- process Cite within a Span
elseif elem.t == "Span" and elem.content[1] ~= nil and elem.content[1].t == "Cite" then
local cite_id = elem.content[1].citations[1].id
-- if it's a cr-cite, don't insert it
if string.find(cite_id, "^" .. prefix) == 1 then
-- but do grab id and attributes for focus block
sticky_id = cite_id
for k,v in pairs(elem.attr.attributes) do
focus_attributes[k] = v
end
-- and remove any space that precedes it
if i > 1 and para.content[i-1].t == "Space" then
new_inlines:remove(#new_inlines)
end
skip_next = true -- and prepare to skip the following Space
else
-- if it's a Cite that's not cr-, insert it
new_inlines:insert(elem)
end

-- and toggle flag to skip next element
skip_next = true
else

-- if it's a Cite (but not a cr-citation), add it
-- if it's a neither a Cite nor a Span > Cite, add it
new_inlines:insert(elem)
end
else

-- if it's not a Cite, add it
new_inlines:insert(elem)
end

::endofloop::
end

para.content = new_inlines

-- if a cr-cite was found, wrap in focus block
if sticky_id ~= nil then
wrapped_para = pandoc.Div(para, pandoc.Attr("", {}, {['focus-on'] = sticky_id}))
local attr = pandoc.Attr("", {}, {['focus-on'] = sticky_id})
for k, v in pairs(focus_attributes) do
attr.attributes[k] = v
end
wrapped_para = pandoc.Div(para, attr)
para = wrapped_para
end

return para
end



--================--
-- HTML Injection --
--================--
Expand Down
27 changes: 25 additions & 2 deletions docs/_quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,33 @@ website:
text: Gallery
- href: reference/index.qmd
text: Reference
- text: "Help"
menu:
- text: "Report a Bug"
icon: "bug"
href: "https://github.com/qmd-lab/closeread/issues"
- text: "Ask a Question"
icon: "chat-right-text"
href: "https://github.com/qmd-lab/closeread/discussions"
tools:
- icon: github
- text: "Closeread GitHub"
icon: github
href: https://github.com/qmd-lab/closeread
text: Closeread GitHub

sidebar:
- id: Guide
style: "docked"
background: light
contents:
- section: Guide
href: guide/index.qmd
contents:
- guide/components.qmd
- guide/focus-effects.qmd
- guide/layouts.qmd
- guide/authoring-tools.qmd



format:
html:
Expand Down
18 changes: 4 additions & 14 deletions docs/gallery/demos/highlighting/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,13 @@ To highlight particular lines of code for your reader, you can add an attribute
The following section demonstrates that functionality.

:::{.cr-section}

We'll show an example that demonstrates the use of the `dplyr` R package for data wrangling.

Here is a `dplyr` pipeline that processes a data frame containing information on Antarctic penguins. @cr-dplyr

:::{focus-on="cr-dplyr" highlight="1,2"}
In the first two lines we load the `dplyr` package and the `palmerpenguins` package, which contains the data frame.
:::
In the first two lines we load the `dplyr` package and the `palmerpenguins` package, which contains the data frame. [@cr-dplyr]{highlight="1,2"}

:::{focus-on="cr-dplyr" highlight="4-8"}
The main block of code is referred as a pipeline or chain. Each line starts with a function and ends with a pipe, `|>`.
:::
The main block of code is referred as a pipeline or chain. Each line starts with a function and ends with a pipe, `|>`. [@cr-dplyr]{highlight="4-8"}

:::{#cr-dplyr}
```{r}
Expand All @@ -52,18 +47,13 @@ The syntax for a lineblock (like a poem) is the same, with one addition.


:::{.cr-section}

The limerick is a form of poetry composed of five lines.

Here is the first limerick appearing in the written record, from the *Saint John Daily News* in 1880. @cr-limerick

:::{focus-on="cr-limerick" highlight="cr-mallory,cr-salary"}
The end of the first two lines of a Limerick must rhyme.
:::
The end of the first two lines of a Limerick must rhyme. [@cr-limerick]{highlight="cr-mallory,cr-salary"}

:::{focus-on="cr-limerick" highlight="3,4"}
The end third and fourth line also rhyme and are nudged in a bit.
:::
The end of the third and fourth line also rhyme and are nudged in a bit. [@cr-limerick]{highlight="3-4"}

| {#cr-limerick}
| There was a young rustic named [Mallory]{#cr-mallory},
Expand Down
17 changes: 5 additions & 12 deletions docs/gallery/demos/minard-zoom/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,15 @@ The first is the classic of Charles Joseph Minard (1781-1870), the French engine
![](minard-map.png)
:::

:::{focus-on="cr-map" pan-to="70%,-10%" scale-by="2.1"}
Beginning at left on the Polish-Russian border near the Niemen River, the thick tan flow-line shows the size of the Grand Army (422,000) as it invaded Russia in June 1812.
:::
Beginning at left on the Polish-Russian border near the Niemen River, the thick tan flow-line shows the size of the Grand Army (422,000) as it invaded Russia in June 1812. [@cr-map]{pan-to="70%,-10%" scale-by="2.1"}

The width of this band indicates the size of the army at each place on the map.

:::{focus-on="cr-map" pan-to="-55%,10%" scale-by="1.5"}
In September, the army reached Moscow, which was by then sacked and deserted, with 100,000 men.
:::
In September, the army reached Moscow, which was by then sacked and deserted, with 100,000 men. [@cr-map]{pan-to="-55%,10%" scale-by="1.5"}

:::{focus-on="cr-map" pan-to="-25%,10%" scale-by="1.5" style="padding-top: 0; padding-bottom: 60svh"}
The path of Napoleon's retreat from Moscow is depicted by the darker, lower band, which is linked to a temperature scale and dates at the bottom of the chart. It was a bitterly cold winter, and many froze on the march out of Russia.
:::
The path of Napoleon's retreat from Moscow is depicted by the darker, lower band, which is linked to a temperature scale and dates at the bottom of the chart. It was a bitterly cold winter, and many froze on the march out of Russia. [@cr-map]{pan-to="-25%,10%" scale-by="1.5"}

:::{focus-on="cr-map" pan-to="18%,-15%" scale-by="2.4"}
As the graphic shows, the crossing of the Berezina River was a disaster, and the army finally struggled back into Poland with only 10,000 men remaining.
:::
As the graphic shows, the crossing of the Berezina River was a disaster, and the army finally struggled back into Poland with only 10,000 men remaining. [@cr-map]{pan-to="18%,-15%" scale-by="2.4"}

Also shown are the movements of auxiliary troops, as they sought to protect the rear and the flank of the advancing army.

Expand Down
3 changes: 3 additions & 0 deletions docs/guide/_metadata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
format:
html:
toc: true
5 changes: 5 additions & 0 deletions docs/guide/authoring-tools.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: Authoring Tools
---

Coming soon!
81 changes: 81 additions & 0 deletions docs/guide/components.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
title: Closeread Components
---

Every closeread document consists of three components:

1. A section of the document flagged as a closeread section.
2. Within the section, an element flagged to appear in the main column of the closeread section (the "sticky"), and also
3. An element (often a paragraph of text) that will serve to trigger the appearance of the sticky element.

## Closeread Sections

To create a closeread section within a document, open up a [fenced div](https://quarto.org/docs/authoring/markdown-basics.html#sec-divs-and-spans) and add the `cr-section` class.

```markdown
:::{.cr-section}
< add paragraphs, images, code cells, etc. >
:::
```

Elements within a `.cr-section` div will appear as a closeread story while elements outside of a section will appear as a normal Quarto HTML document. This allows you to integrate one or more closeread sections into a conventional HTML document.

By wrapping your entire document with a `cr-section` div, you can make a 100% closeread document. By default, all elements with a closeread section appear in the narrative column unless you've indicated that they should be a sticky.

## Stickies

An element of your document that you wish to do a close read of is called a "sticky": as the user scrolls, it will remained pinned in the middle of the main column like a sticky note. To flag an element as a sticky, wrap it in a fenced div and provide an identifier that is prefixed with `cr-`.

```markdown
:::{#cr-myimage}
![](path-to-myimage.png)
:::
```

The syntax is the same regardless of whether the element you'd like to turn into a sticky is an image, a paragraph, a list, math, a code cell, etc. For example, the the syntax for a code cell is:

````markdown
:::{#cr-myplot}
```{{r}}
hist(rnorm(15))
```
:::
````
All sticky elements are placed in the main column of the closeread section and will be transparent. To make them appear, you need to create a trigger.

## Triggers

Any elements within a closeread section that are not stickies - usually paragraphs - will be placed in the narrative column. You can set a paragraph to trigger focus on a particular sticky by using Quarto's cross-referencing syntax: `@cr-mysticky`.

````markdown
When this paragraph scrolls into view it will reveal a histogram. @cr-myplot

:::{#cr-myplot}
```{{r}}
hist(rnorm(15))
```
:::
````

The reference can be placed anywhere in the paragraph, but it should be separated from other content by spaces. This syntax mirrors the syntax of Quarto Cross-refs but uses a distinct prefix for the identifier (`cr-`) and does not require a caption.

If you have multiple document blocks (say, two paragraphs) that you'd like to appear as a single trigger, wrap the blocks in a fenced div and supply a `focus-on` attribute and provide the sticky name as a string. For example:

````markdown
:::{focus-on="cr-myplot"}
This paragraph and the one that follows will appear as one narrative block

When these paragraphs scroll into view, they will reveal a histogram.
:::

:::{#cr-myplot}
```{{r}}
hist(rnorm(15))
```
:::
````

The primary role of triggers is to make a sticky element appear. They can also be used to trigger focus effects by attaching additional attributes to your triggers. Learn more in [Focus Effects](focus-effects.qmd).



74 changes: 74 additions & 0 deletions docs/guide/focus-effects.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
title: Focus Effects
---

Focus effects are used to closely guide your readers attention to particular aspects of your stickies. They are all supplied as [attributes](https://quarto.org/docs/authoring/markdown-basics.html#ordering-of-attributes), which follow a `attribute="value"` syntax where the value must be quoted and where `=` separates the value from the attribute with no spaces.

## Highlighting

You can highlight parts of the code and text of your sticky using the following syntax.

1. `highlight="1,3"`: highlight lines 1 and 3
2. `highlight="1-3"`: highlight lines 1, 2, and 3
3. `highlight="cr-span1"`: highlight the span with id `cr-span1`
4. `highlight="cr-span1,cr-span2"`: highlight the spans with ids `cr-span1` and `cr-span2`

Line highlighting (1 and 2) works on code cells and line blocks while span highlighting (3 and 4) only works on Line Blocks.

### Code Cell Examples

This will highlight lines 1 and 2:

````qmd
This is where we load the library. [@cr-dplyr]{highlight="1,2"}

:::{#cr-dplyr}
```{{r}}
library(dplyr)
library(palmerpenguins)

penguins |>
group_by(island) |>
summarize(avg_bill_length = mean(bill_length_mm))
```
:::
````

This will highlight lines 4 through 6.

````qmd
This calculates summary statistics. [@cr-dplyr]{highlight="4-6"}

:::{#cr-dplyr}
```{{r}}
library(dplyr)
library(palmerpenguins)

penguins |>
group_by(island) |>
summarize(avg_bill_length = mean(bill_length_mm))
```
:::
````

Highlighting spans of code within a line is currently not possible.


### Line Block Examples

To do.


## Panning

To do.


## Scaling

To do.


## Zooming

To do.
Loading

0 comments on commit bcd8533

Please sign in to comment.