mirror of
https://github.com/kidwellj/hacking_religion_textbook.git
synced 2024-11-01 01:12:20 +00:00
working on chapter 1
This commit is contained in:
parent
286f263700
commit
d2371b7fb8
BIN
hacking_religion/.RData
Normal file
BIN
hacking_religion/.RData
Normal file
Binary file not shown.
512
hacking_religion/.Rhistory
Normal file
512
hacking_religion/.Rhistory
Normal file
|
@ -0,0 +1,512 @@
|
|||
q6_data_plot
|
||||
ggsave("figures/q6.png", width = 15, height = 10, units = "cm")
|
||||
# Faceted plot working with 3x3 grid
|
||||
df <- select(climate_experience_data, Q52_bin, Q53_bin, Q57_bin, Q6)
|
||||
names(df) <- c("Q52_bin", "Q53_bin", "Q57_bin", "response")
|
||||
facet_names <- c(`Q52_bin` = "Spirituality", `Q53_bin` = "Politics L/R", `Q57_bin` = "Religiosity", `low`="low", `medium`="medium", `high`="high")
|
||||
facet_labeller <- function(variable,value){return(facet_names[value])}
|
||||
q6_levels = c("Definitely changing", "Probably changing", "Probably not changing", "Definitely not changing")
|
||||
df$response <- factor(df$response, ordered = TRUE, levels = c("4", "3", "2", "1"))
|
||||
df$response <- fct_recode(df$response, "Definitely not changing" = "1", "Probably not changing" = "2", "Probably changing" = "3", "Definitely changing" = "4")
|
||||
# TODO: not working with function, need to sort out why
|
||||
df %>%
|
||||
# we need to get the data including facet info in long format, so we use pivot_longer()
|
||||
pivot_longer(!response, names_to = "bin_name", values_to = "b") %>%
|
||||
# add counts for plot below
|
||||
count(response, bin_name, b) %>%
|
||||
group_by(bin_name,b) %>%
|
||||
mutate(perc=paste0(round(n*100/sum(n),1),"%")) %>%
|
||||
# run ggplot
|
||||
ggplot(aes(x = n, y = "", fill = response)) +
|
||||
geom_col(position=position_fill(), aes(fill=response)) +
|
||||
geom_text(aes(label = perc), position = position_fill(vjust=.5), size=2) +
|
||||
scale_fill_brewer(palette="YlOrBr") +
|
||||
scale_x_continuous(labels = scales::percent_format()) +
|
||||
facet_grid(vars(b), vars(bin_name), labeller=as_labeller(facet_names)) +
|
||||
labs(caption = caption, x = "", y = "") +
|
||||
guides(fill = guide_legend(title = NULL))
|
||||
ggsave("figures/q6_faceted.png", width = 20, height = 10, units = "cm")
|
||||
library(readr)
|
||||
library(stringr)
|
||||
library(dplyr)
|
||||
library(ggplot2)
|
||||
hesa_students <- read_delim("~/Nextcloud/academic_service/TRS-UK/whiteness_research/hesa_data/hesa_all_ethnicity_utf8.csv",
|
||||
"\t", escape_double = FALSE, col_names = c("ay","ethnicity","sub_subject","subject","level","provider","fpe_pct", "fpe"),
|
||||
col_types = cols(ay = col_number(), fpe_pct = col_number(), fpe = col_number()), trim_ws = TRUE, skip = 1)
|
||||
# Convert NA to 0 for the sake of plot below
|
||||
# hesa_students$fpe[is.na(hesa_students$fpe)] <- 0
|
||||
# Omit rows with NA
|
||||
hesa_students_filtered <- hesa_students %>% filter(!is.na(fpe))
|
||||
# Calculate totals for sector
|
||||
arrange(hesa_students_v6, provider, level, ay, ethnicity)
|
||||
# Calculate totals for sector
|
||||
arrange(hesa_students_filtered, provider, level, ay, ethnicity)
|
||||
hesa_students_v6_grouped <- group_by(hesa_students_v6, level, ay, ethnicity)
|
||||
hesa_students_v6_grouped <- group_by(hesa_students_filtered, level, ay, ethnicity)
|
||||
# Calculate sum of all students by ethnicity across all provider departments
|
||||
hesa_students_v6_grouped_totals <- summarise(hesa_students_v6_grouped, fpe = sum(fpe))
|
||||
ggplot(data = hesa_students_v6_grouped_totals, aes(x=ay, y=fpe, colour=ethnicity)) + geom_point() + facet_grid( ~ level) + geom_smooth(method= "lm", se=FALSE)
|
||||
View(hesa_students_v6_grouped)
|
||||
View(hesa_students_filtered)
|
||||
# R Setup -----------------------------------------------------------------
|
||||
library(here) # much better way to manage working paths in R across multiple instances
|
||||
library(ragg) # better video device, more accurate and faster rendering, esp. on macos. Also should enable system fonts for display
|
||||
library(tidyverse)
|
||||
library(tidytext) # used for reorder_within() for factor and likert plots
|
||||
require(devtools)
|
||||
require(usethis)
|
||||
require(likert) # Used for likert data visualisation
|
||||
require(RColorBrewer)
|
||||
require(scales) # Used for adding percentages to bar charts
|
||||
library(ggthemes)
|
||||
library(hrbrthemes) # Used for ipsum theme etc.
|
||||
library(ggeasy) # Used for centring titles
|
||||
library(reshape2) # Added for use with centred stacked bar charts
|
||||
library(viridis) # Used for gradient colour schemes, as with violin plots
|
||||
library("readxl")
|
||||
library("htmlwidgets")
|
||||
library("ggstatsplot")
|
||||
library(showtext)
|
||||
library(glue) # used for clean_postcodes
|
||||
library(magrittr) # used for clean_postcodes
|
||||
require(RCurl) # used for fetching reproducible datasets
|
||||
require(sf) # new simplefeature data class, supercedes sp in many ways
|
||||
require(tmap)
|
||||
library(sp) # used to define CRS below only
|
||||
library(flextable) # pretty tables
|
||||
library(officer)
|
||||
library(ggrepel)
|
||||
library(patchwork) # used for side-by-side plotting (q19 etc.)
|
||||
library(gridExtra)
|
||||
library('foreign')
|
||||
library(regions)
|
||||
library(countrycode)
|
||||
library(haven) # used for importing SPSS .sav files
|
||||
caption <- "Jeremy H. Kidwell and Charles Ogunbode,\nGraphic is CC-by-SA 4.0"
|
||||
title <- "To what extent do you support or oppose the following policies?"
|
||||
q34_data <- select(climate_experience_data, Q34_ev:Q34_loss_and_damage)
|
||||
names(q34_data) <- c("Subsidies for electric (emission-free) vehicles", "Improving public transport", "Increasing taxes on any use of fossil fuels", "Increasing the price of electricity to reduce our consumption", "Increasing taxes on carbon-intensive foods like meat and dairy products", "Additional charges for people who fly more than twice a year", "Increasing taxes on companies and industries that emit large amounts of carbon", "Using public money to subsidise renewable energy (such as wind and solar power", "Including nuclear power in the energy mix", "Spending public money now to prepare the UK for the impacts of climate change", "Spending public money to help people in developing countries adapt to harmful climate change impacts", "Using public money to compensate developing countries for loss and damage")
|
||||
q34_levels <- c("strongly oppose", "tend to oppose", "tend to support", "strongly support")
|
||||
q34_likert_table <- q34_data %>%
|
||||
mutate(across(everything(),
|
||||
factor, ordered = TRUE, levels = 1:4, labels=q34_levels)) %>%
|
||||
as.data.frame %>%
|
||||
likert
|
||||
plot(q34_likert_table, wrap=45, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, caption = NULL, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-115, 115))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q34_likert.png", width = 20, height = 20, units = "cm")
|
||||
# Q48
|
||||
title <- "To what extent do you agree or disagree \nwith the following statements"
|
||||
caption <- "Jeremy H. Kidwell and Charles Ogunbode,\nGraphic is CC-by-SA 4.0"
|
||||
q48_data <- select(climate_experience_data, Q48_poor_suffer:Q48_colonialism)
|
||||
names(q48_data) <- c("People living in poverty suffer worse effects from climate change", "Around the world, people who are least responsible suffer the worst negative impacts from climate change", "Climate change affects women around the world worse than men", "Climate change will increase existing inequalities", "The effects of climate change are worse for people of colour", "Solving climate change requires redistribution of resources from the wealthy to those who have less", "People from communities most affected by climate change should have more of a say in decisions about solutions to climate change than they currently do", "Climate change is driven and exacerbated by exploitative systems like colonialism and capitalism")
|
||||
q48_levels <- c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree")
|
||||
q48_likert_table <- q48_data %>%
|
||||
mutate(across(everything(),
|
||||
factor, ordered = TRUE, levels = 1:5, labels=q48_levels)) %>%
|
||||
as.data.frame %>%
|
||||
likert
|
||||
plot(q48_likert_table, wrap=40, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, caption = NULL, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(axis.text.y = element_text(size = 9)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-110, 110))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q48_likert.png", width = 20, height = 18, units = "cm")
|
||||
plot(q48_likert_table, wrap=40, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, caption = NULL, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(axis.text.y = element_text(size = 9)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-105, 105))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q48_likert.png", width = 20, height = 18, units = "cm")
|
||||
plot(q48_likert_table, wrap=40, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, caption = NULL, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(axis.text.y = element_text(size = 9)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-115, 115))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q48_likert.png", width = 20, height = 18, units = "cm")
|
||||
# Q42
|
||||
title <- "To what degree would you say each of the following stops \nyou or acts as a barrier to you taking more \naction on climate change?"
|
||||
caption <- "Jeremy H. Kidwell and Charles Ogunbode,\nGraphic is CC-by-SA 4.0"
|
||||
q42_data <- select(climate_experience_data, Q42_lacking_knowledge:Q42_other)
|
||||
names(q42_data) <- c("Feeling that you have insufficient awareness or knowledge of climate change", "Feeling uncertain or skeptical about climate change", "Lacking trust in information sources", "Difficulty or inconvenience of climate actions or climate-friendly lifestyle changes", "Feeling that individual action to address climate change is ineffective", "Feeling is too late to slow or reverse the negative effects of climate change", "Other things taking up your time and energy", "Other barriers not included in this list")
|
||||
q42_levels <- c("Not at all", "A little", "A great deal")
|
||||
q42_likert_table <- q42_data %>%
|
||||
mutate(across(everything(),
|
||||
factor, ordered = TRUE, levels = 1:3, labels=q42_levels)) %>%
|
||||
as.data.frame %>%
|
||||
likert
|
||||
plot(q42_likert_table, wrap=45, centered=FALSE, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-5, 110))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q42_likert.png", width = 20, height = 15, units = "cm")
|
||||
plot(q42_likert_table, wrap=45, centered=TRUE, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-5, 110))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q42_likert.png", width = 20, height = 15, units = "cm")
|
||||
plot(q42_likert_table, wrap=45, centered=FALSE, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, y="") +
|
||||
guides((title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-5, 110))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q42_likert.png", width = 20, height = 15, units = "cm")
|
||||
plot(q42_likert_table, wrap=45, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-110, 110))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q42_likert.png", width = 20, height = 15, units = "cm")
|
||||
plot(q42_likert_table, center=1, wrap=45, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-110, 110))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q42_likert.png", width = 20, height = 15, units = "cm")
|
||||
plot(q42_likert_table, center=2, wrap=45, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-110, 110))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q42_likert.png", width = 20, height = 15, units = "cm")
|
||||
plot(q42_likert_table, center=3, wrap=45, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-110, 110))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q42_likert.png", width = 20, height = 15, units = "cm")
|
||||
plot(q42_likert_table, center=3, centered=true, wrap=45, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-110, 110))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q42_likert.png", width = 20, height = 15, units = "cm")
|
||||
plot(q42_likert_table, center=3, centered=TRUE, wrap=45, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-110, 110))
|
||||
plot(q42_likert_table, center=1.5, centered=TRUE, wrap=45, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-110, 110))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q42_likert.png", width = 20, height = 15, units = "cm")
|
||||
plot(q42_likert_table, center=1.5, centered=TRUE, wrap=45, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-110, 105))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q42_likert.png", width = 20, height = 15, units = "cm")
|
||||
plot(q42_likert_table, center=1.5, centered=TRUE, wrap=45, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-110, 115))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q42_likert.png", width = 20, height = 15, units = "cm")
|
||||
# Q25 - generate diverging stacked bar chart using likert()
|
||||
title <- "How serious a threat do you think \nclimate change poses to the following?"
|
||||
caption <- "Jeremy H. Kidwell and Charles Ogunbode,\nGraphic is CC-by-SA 4.0"
|
||||
q25_data <- select(climate_experience_data, Q25_self_and_family:Q25_outside_uk)
|
||||
names(q25_data) <- c("You and your family in the UK", "People in your local area or city", "The UK as a whole", "Your family and/or friends living outside the UK")
|
||||
# Set up levels text for question responses
|
||||
q25_levels <- paste(c("not at all", "somewhat", "moderately", "very", "extremely"),
|
||||
"serious")
|
||||
q25_likert_table <- q25_data %>%
|
||||
mutate(across(everything(),
|
||||
factor, ordered = TRUE, levels = 1:5, labels=q25_levels)) %>%
|
||||
as.data.frame %>%
|
||||
likert
|
||||
plot(q25_likert_table, centered=FALSE, wrap=20, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
ggtitle(title) +
|
||||
labs(title = title, caption = NULL, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum_rc() +
|
||||
theme(axis.text.y = element_text(size = 9))
|
||||
# save to png file for reports
|
||||
ggsave("figures/q25_likert.png", width = 20, height = 10, units = "cm")
|
||||
# using ggplot
|
||||
worry_elsewhere_data <- qualtrics_process_single_multiple_choice_unsorted(climate_experience_data_named$Q28)
|
||||
# add percentages for plot
|
||||
worry_elsewhere_data <- worry_elsewhere_data %>%
|
||||
dplyr::mutate(perc = scales::percent(n / sum(n), accuracy = 1, trim = FALSE))
|
||||
worry_elsewhere_ggpie <- ggplot(worry_elsewhere_data, aes(x = "", y = n, fill = response)) +
|
||||
geom_col() +
|
||||
geom_text(aes(label = perc),
|
||||
color = "white",
|
||||
position = position_stack(vjust = 0.5),
|
||||
show.legend = FALSE) +
|
||||
coord_polar(theta = "y") +
|
||||
# colours for slices
|
||||
scale_fill_manual(values = c("#3962B1", "#B1399E")) +
|
||||
# remove labels and add caption
|
||||
labs(title = title, x = "", y = "") +
|
||||
# remove extra lines
|
||||
theme(axis.text = element_blank(),
|
||||
axis.ticks = element_blank(),
|
||||
axis.title = element_blank(),
|
||||
panel.grid = element_blank(),
|
||||
plot.background = element_rect(fill = white),
|
||||
panel.background = element_rect(fill = white)) +
|
||||
# remove legend title
|
||||
guides(fill = guide_legend(title = NULL))
|
||||
worry_elsewhere_ggpie
|
||||
ggsave("figures/figure6.png", width = 20, height = 10, units = "cm")
|
||||
caption <- "Jeremy H. Kidwell and Charles Ogunbode,\nGraphic is CC-by-SA 4.0"
|
||||
title <- "To what extent do you support or oppose the following policies?"
|
||||
q34_data <- select(climate_experience_data, Q34_ev:Q34_loss_and_damage)
|
||||
names(q34_data) <- c("Subsidies for electric (emission-free) vehicles", "Improving public transport", "Increasing taxes on any use of fossil fuels", "Increasing the price of electricity to reduce our consumption", "Increasing taxes on carbon-intensive foods like meat and dairy products", "Additional charges for people who fly more than twice a year", "Increasing taxes on companies and industries that emit large amounts of carbon", "Using public money to subsidise renewable energy (such as wind and solar power", "Including nuclear power in the energy mix", "Spending public money now to prepare the UK for the impacts of climate change", "Spending public money to help people in developing countries adapt to harmful climate change impacts", "Using public money to compensate developing countries for loss and damage")
|
||||
q34_levels <- c("strongly oppose", "tend to oppose", "tend to support", "strongly support")
|
||||
q34_likert_table <- q34_data %>%
|
||||
mutate(across(everything(),
|
||||
factor, ordered = TRUE, levels = 1:4, labels=q34_levels)) %>%
|
||||
as.data.frame %>%
|
||||
likert
|
||||
plot(q34_likert_table, wrap=45, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, caption = NULL, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-115, 115))
|
||||
# save to png file for reports
|
||||
ggsave("figures/figure7.png", width = 20, height = 20, units = "cm")
|
||||
title <- "Have you ever heard of the phrase “Climate Justice”?"
|
||||
caption <- "Jeremy H. Kidwell and Charles Ogunbode,\nGraphic is CC-by-SA 4.0"
|
||||
q45_data <- qualtrics_process_single_multiple_choice(climate_experience_data_named$Q45)
|
||||
q45_plot <- plot_horizontal_bar(q45_data) + labs(title = title, caption = NULL, x = "", y = "")
|
||||
q45_plot
|
||||
ggsave("figures/figure8.png", width = 20, height = 5, units = "cm")
|
||||
# Q48
|
||||
title <- "To what extent do you agree or disagree \nwith the following statements"
|
||||
caption <- "Jeremy H. Kidwell and Charles Ogunbode,\nGraphic is CC-by-SA 4.0"
|
||||
q48_data <- select(climate_experience_data, Q48_poor_suffer:Q48_colonialism)
|
||||
names(q48_data) <- c("People living in poverty suffer worse effects from climate change", "Around the world, people who are least responsible suffer the worst negative impacts from climate change", "Climate change affects women around the world worse than men", "Climate change will increase existing inequalities", "The effects of climate change are worse for people of colour", "Solving climate change requires redistribution of resources from the wealthy to those who have less", "People from communities most affected by climate change should have more of a say in decisions about solutions to climate change than they currently do", "Climate change is driven and exacerbated by exploitative systems like colonialism and capitalism")
|
||||
q48_levels <- c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree")
|
||||
q48_likert_table <- q48_data %>%
|
||||
mutate(across(everything(),
|
||||
factor, ordered = TRUE, levels = 1:5, labels=q48_levels)) %>%
|
||||
as.data.frame %>%
|
||||
likert
|
||||
plot(q48_likert_table, wrap=40, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, caption = NULL, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(axis.text.y = element_text(size = 9)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-1105, 115))
|
||||
# save to png file for reports
|
||||
ggsave("figures/figure9.png", width = 20, height = 18, units = "cm")
|
||||
plot(q48_likert_table, wrap=40, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, caption = NULL, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(axis.text.y = element_text(size = 9)) +
|
||||
scale_y_continuous(labels = abs, limits = c(-105, 115))
|
||||
# save to png file for reports
|
||||
ggsave("figures/figure9.png", width = 20, height = 18, units = "cm")
|
||||
# Q40
|
||||
title <- "Have you engaged in the following \nactivities in the past year?"
|
||||
q40_data <- select(climate_experience_data, Q39_protest:Q39_active_member)
|
||||
names(q40_data) <- c("Attended a climate protest", "Donated money to an environmental organisation tackling climate change", "Changed your lifestyle to reduce impact on the environment or climate", "Volunteered in an organisation tackling climate issues", "Signed a petition or contacted a politician regarding climate change", "Attended a public lecture, webinar or workshop about climate change", "Participation as an active member of an environmental organisation")
|
||||
q40_levels <- c("No", "Yes")
|
||||
q40_likert_table <- q40_data %>%
|
||||
mutate(across(everything(),
|
||||
factor, ordered = TRUE, levels = 0:1, labels=q40_levels)) %>%
|
||||
as.data.frame %>%
|
||||
likert
|
||||
plot(q40_likert_table, wrap=25, text.size=3, ordered=TRUE, low.color='#B18839', high.color='#590048') +
|
||||
labs(title = title, caption = NULL, y="") +
|
||||
guides(fill = guide_legend(title = NULL)) +
|
||||
theme_ipsum() +
|
||||
theme(plot.title = element_text(lineheight = 0.9, size =12, hjust = 0))
|
||||
# save to png file for reports
|
||||
ggsave("figures/figure10.png", width = 20, height = 20, units = "cm")
|
||||
install.packages("pdftables")
|
||||
library(pdftables)
|
||||
here
|
||||
here()
|
||||
library(here)
|
||||
convert_pdf("gits/hesa_staff/Sheet1.pdf", "sheet.csv")
|
||||
install.packages("UKCensusAPI")
|
||||
install.packages("devtools")
|
||||
devtools::install_github("virgesmith/UKCensusAPI")
|
||||
RETICULATE_PYTHON=$(which python3)
|
||||
library(UKCensusAPI)
|
||||
install.packages("nomisr")
|
||||
library(nomisr)
|
||||
nomis_overview()
|
||||
nomis_data_info()
|
||||
nomis_search(name = census)
|
||||
x <- nomis_search(name = "*census*")
|
||||
View(x)
|
||||
nomis_get_data(id = TS031)
|
||||
x <- nomis_data_info()
|
||||
x <- nomis_data_info()
|
||||
View(x)
|
||||
View(x[[5]][[203]])
|
||||
head(x)
|
||||
as.data.frame(x)
|
||||
View(x[[5]][[314]])
|
||||
View(x[[6]][[315]])
|
||||
x <- nomis_data_info()library(dplyr)
|
||||
library(dplyr)
|
||||
x %>% filter(name.value %in% "ts030")
|
||||
x %>% filter(name.value == "*ts030*")
|
||||
x %>% filter(name.value == "%ts030%")
|
||||
filtered_df <- filter(x, grepl("ts030")
|
||||
)
|
||||
filtered_df <- filter(x, grepl("ts030", name.value)
|
||||
)
|
||||
View(filtered_df)
|
||||
filtered_df <- filter(x, grepl("030", name.value))
|
||||
filtered_df <- filter(x, grepl("TS030", name.value))
|
||||
View(filtered_df[[5]][[1]])
|
||||
filtered_df <- filter(x, grepl("TS030", name.value))
|
||||
View(filtered_df)
|
||||
nomis_get_data(id=NM_2049_1)
|
||||
nomis_get_data(id="NM_2049_1)
|
||||
nomis_get_data(id="NM_2049_1")
|
||||
```
|
||||
```
|
||||
View(x)
|
||||
View(x[[5]][[1316]])
|
||||
View(x[[6]][[1316]])
|
||||
```
|
||||
```
|
||||
```
|
||||
nomis_data_info("NM_2049_1")
|
||||
y <- nomis_data_info("NM_2049_1")
|
||||
tibble::glimpse(y)
|
||||
```
|
||||
library(here)
|
||||
# R Setup -----------------------------------------------------------------
|
||||
here::i_am("survey_analysis.R")
|
||||
```
|
||||
# R Setup -----------------------------------------------------------------
|
||||
here::i_am("chapter_1.qmd")
|
||||
# R Setup -----------------------------------------------------------------
|
||||
here::i_am("//Users/kidwellj/gits/hacking_religion_textbook/hacking_religion/chapter_1.qmd")
|
||||
# R Setup -----------------------------------------------------------------
|
||||
here::i_am("//Users/kidwellj/gits/hacking_religion_textbook/hacking_religion/chapter_1.qmd")
|
||||
# R Setup -----------------------------------------------------------------
|
||||
here::i_am("/Users/kidwellj/gits/hacking_religion_textbook/hacking_religion/chapter_1.qmd")
|
||||
# R Setup -----------------------------------------------------------------
|
||||
here::i_am("kidwellj/gits/hacking_religion_textbook/hacking_religion/chapter_1.qmd")
|
||||
library(here) # much better way to manage working paths in R across multiple instances
|
||||
# R Setup -----------------------------------------------------------------
|
||||
here::i_am("gits/hacking_religion_textbook/hacking_religion/chapter_1.qmd")
|
||||
library(here) # much better way to manage working paths in R across multiple instances
|
||||
# R Setup -----------------------------------------------------------------
|
||||
here::i_am("hacking_religion_textbook/hacking_religion/chapter_1.qmd")
|
||||
# R Setup -----------------------------------------------------------------
|
||||
here::i_am("Users/kidwellj/gits/hacking_religion_textbook/hacking_religion/chapter_1.qmd")
|
||||
library(here) # much better way to manage working paths in R across multiple instances
|
||||
# R Setup -----------------------------------------------------------------
|
||||
library(here) # much better way to manage working paths in R across multiple instances
|
||||
here::i_am("hacking_religion_textbook/hacking_religion/chapter_1.qmd")
|
||||
setwd("/Users/kidwellj/gits/hacking_religion_textbook/hacking_religion")
|
||||
# R Setup -----------------------------------------------------------------
|
||||
setwd("/Users/kidwellj/gits/hacking_religion_textbook/hacking_religion")
|
||||
library(here) # much better way to manage working paths in R across multiple instances
|
||||
here::i_am("hacking_religion_textbook/hacking_religion/chapter_1.qmd")
|
||||
# R Setup -----------------------------------------------------------------
|
||||
setwd("/Users/kidwellj/gits/hacking_religion_textbook/hacking_religion")
|
||||
library(here) # much better way to manage working paths in R across multiple instances
|
||||
here::i_am("hacking_religion/chapter_1.qmd")
|
||||
if (dir.exists(here("data")) == FALSE) {
|
||||
dir.create(here("data"))
|
||||
}
|
||||
religion_uk <- read_csv(here("example_data", "census2021-ts030-rgn.csv"))
|
||||
religion_uk <- read.csv(here("example_data", "census2021-ts030-rgn.csv"))
|
||||
religion_uk <- read.csv(here("example_data", "census2021-ts030-rgn.csv"))
|
||||
# R Setup -----------------------------------------------------------------
|
||||
setwd("/Users/kidwellj/gits/hacking_religion_textbook/hacking_religion")
|
||||
library(here) # much better way to manage working paths in R across multiple instances
|
||||
here::i_am("chapter_1.qmd")
|
||||
religion_uk <- read.csv(here("example_data", "census2021-ts030-rgn.csv"))
|
||||
View(religion_uk)
|
||||
View(religion_uk)
|
||||
# %>% select(Q0:Q68)
|
||||
head(religion_uk)
|
||||
```
|
||||
```r
|
||||
```
|
||||
```
|
||||
```
|
||||
```
|
||||
head(religion_uk)
|
||||
```
|
||||
```
|
||||
```
|
||||
```
|
||||
```
|
||||
# R Setup -----------------------------------------------------------------
|
||||
setwd("/Users/kidwellj/gits/hacking_religion_textbook/hacking_religion")
|
||||
library(here) # much better way to manage working paths in R across multiple instances
|
||||
here::i_am("chapter_1.qmd")
|
||||
dat(religion_uk)
|
||||
summary(religion_uk)
|
||||
tail(religion_uk)
|
||||
```
|
||||
```
|
||||
```
|
||||
```
|
||||
# R Setup -----------------------------------------------------------------
|
||||
library(here)
|
||||
religion_uk <- read.csv(here("example_data", "census2021-ts030-rgn.csv"))
|
||||
View(religion_uk)
|
||||
head(religion_uk)
|
||||
tail(religion_uk)
|
||||
religion_uk <- read.csv(here("example_data", "census2021-ts030-rgn.csv"))
|
||||
tail(religion_uk)
|
||||
knitr::kable(head(religion_uk))
|
||||
```
|
||||
wmids_data <- select(religion_uk, no_religion:other)
|
||||
library(tidyverse)
|
||||
install.packages("tidyverse")
|
||||
library(tidyverse)
|
||||
wmids_data <- select(religion_uk, no_religion:other)
|
||||
View(wmids_data)
|
||||
View(wmids_data)
|
||||
View(religion_uk)
|
||||
wmids_data <- select(religion_uk, geography="West Midlands")
|
||||
wmids_data <- select(religion_uk, geography='West Midlands')
|
||||
wmids_data <- select(religion_uk, geography=='West Midlands')
|
||||
View(religion_uk)
|
||||
wmids_data <- select(religion_uk, geography=="West Midlands")
|
||||
View(religion_uk)
|
1
hacking_religion/.gitignore
vendored
Normal file
1
hacking_religion/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/.quarto/
|
849
hacking_religion/_book/chapter_1.html
Normal file
849
hacking_religion/_book/chapter_1.html
Normal file
|
@ -0,0 +1,849 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="generator" content="quarto-1.3.450">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
|
||||
|
||||
<title>Hacking Religion: TRS & Data Science in Action - 2 The 2021 UK Census</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
|
||||
vertical-align: middle;
|
||||
}
|
||||
/* CSS for syntax highlighting */
|
||||
pre > code.sourceCode { white-space: pre; position: relative; }
|
||||
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
|
||||
pre > code.sourceCode > span:empty { height: 1.2em; }
|
||||
.sourceCode { overflow: visible; }
|
||||
code.sourceCode > span { color: inherit; text-decoration: inherit; }
|
||||
div.sourceCode { margin: 1em 0; }
|
||||
pre.sourceCode { margin: 0; }
|
||||
@media screen {
|
||||
div.sourceCode { overflow: auto; }
|
||||
}
|
||||
@media print {
|
||||
pre > code.sourceCode { white-space: pre-wrap; }
|
||||
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
|
||||
}
|
||||
pre.numberSource code
|
||||
{ counter-reset: source-line 0; }
|
||||
pre.numberSource code > span
|
||||
{ position: relative; left: -4em; counter-increment: source-line; }
|
||||
pre.numberSource code > span > a:first-child::before
|
||||
{ content: counter(source-line);
|
||||
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
||||
border: none; display: inline-block;
|
||||
-webkit-touch-callout: none; -webkit-user-select: none;
|
||||
-khtml-user-select: none; -moz-user-select: none;
|
||||
-ms-user-select: none; user-select: none;
|
||||
padding: 0 4px; width: 4em;
|
||||
}
|
||||
pre.numberSource { margin-left: 3em; padding-left: 4px; }
|
||||
div.sourceCode
|
||||
{ }
|
||||
@media screen {
|
||||
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
|
||||
}
|
||||
/* CSS for citations */
|
||||
div.csl-bib-body { }
|
||||
div.csl-entry {
|
||||
clear: both;
|
||||
}
|
||||
.hanging-indent div.csl-entry {
|
||||
margin-left:2em;
|
||||
text-indent:-2em;
|
||||
}
|
||||
div.csl-left-margin {
|
||||
min-width:2em;
|
||||
float:left;
|
||||
}
|
||||
div.csl-right-inline {
|
||||
margin-left:2em;
|
||||
padding-left:1em;
|
||||
}
|
||||
div.csl-indent {
|
||||
margin-left: 2em;
|
||||
}</style>
|
||||
|
||||
|
||||
<script src="site_libs/quarto-nav/quarto-nav.js"></script>
|
||||
<script src="site_libs/quarto-nav/headroom.min.js"></script>
|
||||
<script src="site_libs/clipboard/clipboard.min.js"></script>
|
||||
<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
|
||||
<script src="site_libs/quarto-search/fuse.min.js"></script>
|
||||
<script src="site_libs/quarto-search/quarto-search.js"></script>
|
||||
<meta name="quarto:offset" content="./">
|
||||
<link href="./chapter_2.html" rel="next">
|
||||
<link href="./intro.html" rel="prev">
|
||||
<script src="site_libs/quarto-html/quarto.js"></script>
|
||||
<script src="site_libs/quarto-html/popper.min.js"></script>
|
||||
<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
|
||||
<script src="site_libs/quarto-html/anchor.min.js"></script>
|
||||
<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
|
||||
<link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
|
||||
<script src="site_libs/bootstrap/bootstrap.min.js"></script>
|
||||
<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
|
||||
<script id="quarto-search-options" type="application/json">{
|
||||
"location": "sidebar",
|
||||
"copy-button": false,
|
||||
"collapse-after": 3,
|
||||
"panel-placement": "start",
|
||||
"type": "textbox",
|
||||
"limit": 20,
|
||||
"language": {
|
||||
"search-no-results-text": "No results",
|
||||
"search-matching-documents-text": "matching documents",
|
||||
"search-copy-link-title": "Copy link to search",
|
||||
"search-hide-matches-text": "Hide additional matches",
|
||||
"search-more-match-text": "more match in this document",
|
||||
"search-more-matches-text": "more matches in this document",
|
||||
"search-clear-button-title": "Clear",
|
||||
"search-detached-cancel-button-title": "Cancel",
|
||||
"search-submit-button-title": "Submit",
|
||||
"search-label": "Search"
|
||||
}
|
||||
}</script>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="nav-sidebar floating slimcontent">
|
||||
|
||||
<div id="quarto-search-results"></div>
|
||||
<header id="quarto-header" class="headroom fixed-top">
|
||||
<nav class="quarto-secondary-nav">
|
||||
<div class="container-fluid d-flex">
|
||||
<button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
<i class="bi bi-layout-text-sidebar-reverse"></i>
|
||||
</button>
|
||||
<nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="./chapter_1.html"><span class="chapter-number">2</span> <span class="chapter-title">The 2021 UK Census</span></a></li></ol></nav>
|
||||
<a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
</a>
|
||||
<button type="button" class="btn quarto-search-button" aria-label="" onclick="window.quartoOpenSearch();">
|
||||
<i class="bi bi-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<!-- content -->
|
||||
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article">
|
||||
<!-- sidebar -->
|
||||
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal sidebar-navigation floating overflow-auto">
|
||||
<div class="pt-lg-2 mt-2 text-left sidebar-header">
|
||||
<div class="sidebar-title mb-0 py-0">
|
||||
<a href="./">Hacking Religion: TRS & Data Science in Action</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 flex-shrink-0 align-items-center">
|
||||
<div class="sidebar-search">
|
||||
<div id="quarto-search" class="" title="Search"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-menu-container">
|
||||
<ul class="list-unstyled mt-1">
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./index.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">Preface</span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./intro.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">1</span> <span class="chapter-title">Introduction: Hacking Religion</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_1.html" class="sidebar-item-text sidebar-link active">
|
||||
<span class="menu-text"><span class="chapter-number">2</span> <span class="chapter-title">The 2021 UK Census</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_2.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">3</span> <span class="chapter-title">Survey Data: Spotlight Project</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_3.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">4</span> <span class="chapter-title">Mapping churches: geospatial data science</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_4.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">5</span> <span class="chapter-title">Data scraping, corpus analysis and wordclouds</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./summary.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">6</span> <span class="chapter-title">Summary</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./references.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">References</span></a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="quarto-sidebar-glass" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass"></div>
|
||||
<!-- margin-sidebar -->
|
||||
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
|
||||
<nav id="TOC" role="doc-toc" class="toc-active">
|
||||
<h2 id="toc-title">Table of contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#your-first-project-building-a-pie-chart" id="toc-your-first-project-building-a-pie-chart" class="nav-link active" data-scroll-target="#your-first-project-building-a-pie-chart"><span class="header-section-number">2.1</span> Your first project: building a pie chart</a>
|
||||
<ul class="collapse">
|
||||
<li><a href="#examining-data" id="toc-examining-data" class="nav-link" data-scroll-target="#examining-data"><span class="header-section-number">2.1.1</span> Examining data:</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#references" id="toc-references" class="nav-link" data-scroll-target="#references">References</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<!-- main -->
|
||||
<main class="content page-columns page-full" id="quarto-document-content">
|
||||
|
||||
<header id="title-block-header" class="quarto-title-block default">
|
||||
<div class="quarto-title">
|
||||
<h1 class="title"><span class="chapter-number">2</span> <span class="chapter-title">The 2021 UK Census</span></h1>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="quarto-title-meta">
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<section id="your-first-project-building-a-pie-chart" class="level2 page-columns page-full" data-number="2.1">
|
||||
<h2 data-number="2.1" class="anchored" data-anchor-id="your-first-project-building-a-pie-chart"><span class="header-section-number">2.1</span> Your first project: building a pie chart</h2>
|
||||
<p>Let’s start by importing some data into R. Because R is what is called an object-oriented programming language, we’ll always take our information and give it a home inside a named object. There are many different kinds of objects, which you can specify, but usually R will assign a type that seems to fit best.</p>
|
||||
<div class="page-columns page-full"><p></p><div class="no-row-height column-margin column-container"><span class="">If you’d like to explore this all in a bit more depth, you can find a very helpful summary in R for Data Science, chapter 8, <a href="https://r4ds.hadley.nz/data-import#reading-data-from-a-file">“data import”</a>.</span></div></div>
|
||||
<p>In the example below, we’re going to read in data from a comma separated value file (“csv”) which has rows of information on separate lines in a text file with each column separated by a comma. This is one of the standard plain text file formats. R has a function you can use to import this efficiently called “read.csv”. Each line of code in R usually starts with the object, and then follows with instructions on what we’re going to put inside it, where that comes from, and how to format it:</p>
|
||||
<div class="cell">
|
||||
<div class="sourceCode cell-code" id="cb1"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="co"># R Setup -----------------------------------------------------------------</span></span>
|
||||
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="fu">setwd</span>(<span class="st">"/Users/kidwellj/gits/hacking_religion_textbook/hacking_religion"</span>)</span>
|
||||
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="fu">library</span>(here) <span class="co"># much better way to manage working paths in R across multiple instances</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
|
||||
<div class="cell-output cell-output-stderr">
|
||||
<pre><code>here() starts at /Users/kidwellj/gits/hacking_religion_textbook</code></pre>
|
||||
</div>
|
||||
<div class="sourceCode cell-code" id="cb3"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">library</span>(tidyverse)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
|
||||
<div class="cell-output cell-output-stderr">
|
||||
<pre><code>-- Attaching core tidyverse packages ------------------------ tidyverse 2.0.0 --
|
||||
v dplyr 1.1.3 v readr 2.1.4
|
||||
v forcats 1.0.0 v stringr 1.5.0
|
||||
v ggplot2 3.4.3 v tibble 3.2.1
|
||||
v lubridate 1.9.3 v tidyr 1.3.0
|
||||
v purrr 1.0.2 </code></pre>
|
||||
</div>
|
||||
<div class="cell-output cell-output-stderr">
|
||||
<pre><code>-- Conflicts ------------------------------------------ tidyverse_conflicts() --
|
||||
x dplyr::filter() masks stats::filter()
|
||||
x dplyr::lag() masks stats::lag()
|
||||
i Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors</code></pre>
|
||||
</div>
|
||||
<div class="sourceCode cell-code" id="cb6"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>here<span class="sc">::</span><span class="fu">i_am</span>(<span class="st">"chapter_1.qmd"</span>)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
|
||||
<div class="cell-output cell-output-stderr">
|
||||
<pre><code>here() starts at /Users/kidwellj/gits/hacking_religion_textbook/hacking_religion</code></pre>
|
||||
</div>
|
||||
<div class="sourceCode cell-code" id="cb8"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>religion_uk <span class="ot"><-</span> <span class="fu">read.csv</span>(<span class="fu">here</span>(<span class="st">"example_data"</span>, <span class="st">"census2021-ts030-rgn.csv"</span>)) </span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
|
||||
</div>
|
||||
<section id="examining-data" class="level3 page-columns page-full" data-number="2.1.1">
|
||||
<h3 data-number="2.1.1" class="anchored" data-anchor-id="examining-data"><span class="header-section-number">2.1.1</span> Examining data:</h3>
|
||||
<p>What’s in the table? You can take a quick look at either the top of the data frame, or the bottom using one of the following commands:</p>
|
||||
<div class="cell">
|
||||
<div class="sourceCode cell-code" id="cb9"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">head</span>(religion_uk)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
|
||||
<div class="cell-output cell-output-stdout">
|
||||
<pre><code> geography total no_religion christian buddhist hindu jewish
|
||||
1 North East 2647012 1058122 1343948 7026 10924 4389
|
||||
2 North West 7417397 2419624 3895779 23028 49749 33285
|
||||
3 Yorkshire and The Humber 5480774 2161185 2461519 15803 29243 9355
|
||||
4 East Midlands 4880054 1950354 2214151 14521 120345 4313
|
||||
5 West Midlands 5950756 1955003 2770559 18804 88116 4394
|
||||
6 East 6335072 2544509 2955071 26814 86631 42012
|
||||
muslim sikh other no_response
|
||||
1 72102 7206 9950 133345
|
||||
2 563105 11862 28103 392862
|
||||
3 442533 24034 23618 313484
|
||||
4 210766 53950 24813 286841
|
||||
5 569963 172398 31805 339714
|
||||
6 234744 24284 36380 384627</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<p>This is actually a fairly ugly table, so I’ll use an R tool called kable to give you prettier tables in the future, like this:</p>
|
||||
<div class="cell">
|
||||
<div class="sourceCode cell-code" id="cb11"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>knitr<span class="sc">::</span><span class="fu">kable</span>(<span class="fu">head</span>(religion_uk))</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
|
||||
<div class="cell-output-display">
|
||||
<table class="table table-sm table-striped small">
|
||||
<colgroup>
|
||||
<col style="width: 22%">
|
||||
<col style="width: 7%">
|
||||
<col style="width: 10%">
|
||||
<col style="width: 9%">
|
||||
<col style="width: 8%">
|
||||
<col style="width: 6%">
|
||||
<col style="width: 6%">
|
||||
<col style="width: 6%">
|
||||
<col style="width: 6%">
|
||||
<col style="width: 5%">
|
||||
<col style="width: 10%">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th style="text-align: left;">geography</th>
|
||||
<th style="text-align: right;">total</th>
|
||||
<th style="text-align: right;">no_religion</th>
|
||||
<th style="text-align: right;">christian</th>
|
||||
<th style="text-align: right;">buddhist</th>
|
||||
<th style="text-align: right;">hindu</th>
|
||||
<th style="text-align: right;">jewish</th>
|
||||
<th style="text-align: right;">muslim</th>
|
||||
<th style="text-align: right;">sikh</th>
|
||||
<th style="text-align: right;">other</th>
|
||||
<th style="text-align: right;">no_response</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td style="text-align: left;">North East</td>
|
||||
<td style="text-align: right;">2647012</td>
|
||||
<td style="text-align: right;">1058122</td>
|
||||
<td style="text-align: right;">1343948</td>
|
||||
<td style="text-align: right;">7026</td>
|
||||
<td style="text-align: right;">10924</td>
|
||||
<td style="text-align: right;">4389</td>
|
||||
<td style="text-align: right;">72102</td>
|
||||
<td style="text-align: right;">7206</td>
|
||||
<td style="text-align: right;">9950</td>
|
||||
<td style="text-align: right;">133345</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: left;">North West</td>
|
||||
<td style="text-align: right;">7417397</td>
|
||||
<td style="text-align: right;">2419624</td>
|
||||
<td style="text-align: right;">3895779</td>
|
||||
<td style="text-align: right;">23028</td>
|
||||
<td style="text-align: right;">49749</td>
|
||||
<td style="text-align: right;">33285</td>
|
||||
<td style="text-align: right;">563105</td>
|
||||
<td style="text-align: right;">11862</td>
|
||||
<td style="text-align: right;">28103</td>
|
||||
<td style="text-align: right;">392862</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align: left;">Yorkshire and The Humber</td>
|
||||
<td style="text-align: right;">5480774</td>
|
||||
<td style="text-align: right;">2161185</td>
|
||||
<td style="text-align: right;">2461519</td>
|
||||
<td style="text-align: right;">15803</td>
|
||||
<td style="text-align: right;">29243</td>
|
||||
<td style="text-align: right;">9355</td>
|
||||
<td style="text-align: right;">442533</td>
|
||||
<td style="text-align: right;">24034</td>
|
||||
<td style="text-align: right;">23618</td>
|
||||
<td style="text-align: right;">313484</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: left;">East Midlands</td>
|
||||
<td style="text-align: right;">4880054</td>
|
||||
<td style="text-align: right;">1950354</td>
|
||||
<td style="text-align: right;">2214151</td>
|
||||
<td style="text-align: right;">14521</td>
|
||||
<td style="text-align: right;">120345</td>
|
||||
<td style="text-align: right;">4313</td>
|
||||
<td style="text-align: right;">210766</td>
|
||||
<td style="text-align: right;">53950</td>
|
||||
<td style="text-align: right;">24813</td>
|
||||
<td style="text-align: right;">286841</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align: left;">West Midlands</td>
|
||||
<td style="text-align: right;">5950756</td>
|
||||
<td style="text-align: right;">1955003</td>
|
||||
<td style="text-align: right;">2770559</td>
|
||||
<td style="text-align: right;">18804</td>
|
||||
<td style="text-align: right;">88116</td>
|
||||
<td style="text-align: right;">4394</td>
|
||||
<td style="text-align: right;">569963</td>
|
||||
<td style="text-align: right;">172398</td>
|
||||
<td style="text-align: right;">31805</td>
|
||||
<td style="text-align: right;">339714</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: left;">East</td>
|
||||
<td style="text-align: right;">6335072</td>
|
||||
<td style="text-align: right;">2544509</td>
|
||||
<td style="text-align: right;">2955071</td>
|
||||
<td style="text-align: right;">26814</td>
|
||||
<td style="text-align: right;">86631</td>
|
||||
<td style="text-align: right;">42012</td>
|
||||
<td style="text-align: right;">234744</td>
|
||||
<td style="text-align: right;">24284</td>
|
||||
<td style="text-align: right;">36380</td>
|
||||
<td style="text-align: right;">384627</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<p>You can see how I’ve nested the previous command inside the <code>kable</code> command. For reference, in some cases when you’re working with really complex scripts with many different libraries and functions, they may end up with functions that have the same name. You can specify the library where the function is meant to come from by preceding it with :: as we’ve done <code>knitr::</code> above. The same kind of output can be gotten using <code>tail</code>:</p>
|
||||
<div class="cell">
|
||||
<div class="sourceCode cell-code" id="cb12"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>knitr<span class="sc">::</span><span class="fu">kable</span>(<span class="fu">tail</span>(religion_uk))</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
|
||||
<div class="cell-output-display">
|
||||
<table class="table table-sm table-striped small">
|
||||
<colgroup>
|
||||
<col style="width: 2%">
|
||||
<col style="width: 13%">
|
||||
<col style="width: 7%">
|
||||
<col style="width: 11%">
|
||||
<col style="width: 9%">
|
||||
<col style="width: 8%">
|
||||
<col style="width: 6%">
|
||||
<col style="width: 6%">
|
||||
<col style="width: 7%">
|
||||
<col style="width: 6%">
|
||||
<col style="width: 5%">
|
||||
<col style="width: 11%">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th style="text-align: left;"></th>
|
||||
<th style="text-align: left;">geography</th>
|
||||
<th style="text-align: right;">total</th>
|
||||
<th style="text-align: right;">no_religion</th>
|
||||
<th style="text-align: right;">christian</th>
|
||||
<th style="text-align: right;">buddhist</th>
|
||||
<th style="text-align: right;">hindu</th>
|
||||
<th style="text-align: right;">jewish</th>
|
||||
<th style="text-align: right;">muslim</th>
|
||||
<th style="text-align: right;">sikh</th>
|
||||
<th style="text-align: right;">other</th>
|
||||
<th style="text-align: right;">no_response</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td style="text-align: left;">5</td>
|
||||
<td style="text-align: left;">West Midlands</td>
|
||||
<td style="text-align: right;">5950756</td>
|
||||
<td style="text-align: right;">1955003</td>
|
||||
<td style="text-align: right;">2770559</td>
|
||||
<td style="text-align: right;">18804</td>
|
||||
<td style="text-align: right;">88116</td>
|
||||
<td style="text-align: right;">4394</td>
|
||||
<td style="text-align: right;">569963</td>
|
||||
<td style="text-align: right;">172398</td>
|
||||
<td style="text-align: right;">31805</td>
|
||||
<td style="text-align: right;">339714</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: left;">6</td>
|
||||
<td style="text-align: left;">East</td>
|
||||
<td style="text-align: right;">6335072</td>
|
||||
<td style="text-align: right;">2544509</td>
|
||||
<td style="text-align: right;">2955071</td>
|
||||
<td style="text-align: right;">26814</td>
|
||||
<td style="text-align: right;">86631</td>
|
||||
<td style="text-align: right;">42012</td>
|
||||
<td style="text-align: right;">234744</td>
|
||||
<td style="text-align: right;">24284</td>
|
||||
<td style="text-align: right;">36380</td>
|
||||
<td style="text-align: right;">384627</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align: left;">7</td>
|
||||
<td style="text-align: left;">London</td>
|
||||
<td style="text-align: right;">8799728</td>
|
||||
<td style="text-align: right;">2380404</td>
|
||||
<td style="text-align: right;">3577681</td>
|
||||
<td style="text-align: right;">77425</td>
|
||||
<td style="text-align: right;">453034</td>
|
||||
<td style="text-align: right;">145466</td>
|
||||
<td style="text-align: right;">1318754</td>
|
||||
<td style="text-align: right;">144543</td>
|
||||
<td style="text-align: right;">86759</td>
|
||||
<td style="text-align: right;">615662</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: left;">8</td>
|
||||
<td style="text-align: left;">South East</td>
|
||||
<td style="text-align: right;">9278068</td>
|
||||
<td style="text-align: right;">3733094</td>
|
||||
<td style="text-align: right;">4313319</td>
|
||||
<td style="text-align: right;">54433</td>
|
||||
<td style="text-align: right;">154748</td>
|
||||
<td style="text-align: right;">18682</td>
|
||||
<td style="text-align: right;">309067</td>
|
||||
<td style="text-align: right;">74348</td>
|
||||
<td style="text-align: right;">54098</td>
|
||||
<td style="text-align: right;">566279</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align: left;">9</td>
|
||||
<td style="text-align: left;">South West</td>
|
||||
<td style="text-align: right;">5701186</td>
|
||||
<td style="text-align: right;">2513369</td>
|
||||
<td style="text-align: right;">2635872</td>
|
||||
<td style="text-align: right;">24579</td>
|
||||
<td style="text-align: right;">27746</td>
|
||||
<td style="text-align: right;">7387</td>
|
||||
<td style="text-align: right;">80152</td>
|
||||
<td style="text-align: right;">7465</td>
|
||||
<td style="text-align: right;">36884</td>
|
||||
<td style="text-align: right;">367732</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: left;">10</td>
|
||||
<td style="text-align: left;">Wales</td>
|
||||
<td style="text-align: right;">3107494</td>
|
||||
<td style="text-align: right;">1446398</td>
|
||||
<td style="text-align: right;">1354773</td>
|
||||
<td style="text-align: right;">10075</td>
|
||||
<td style="text-align: right;">12242</td>
|
||||
<td style="text-align: right;">2044</td>
|
||||
<td style="text-align: right;">66947</td>
|
||||
<td style="text-align: right;">4048</td>
|
||||
<td style="text-align: right;">15926</td>
|
||||
<td style="text-align: right;">195041</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<p>We use <code>filter</code> to pick a single row, in the following way:</p>
|
||||
<div class="cell">
|
||||
<div class="sourceCode cell-code" id="cb13"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="co"># wmids_data <- select(religion_uk, geography=="West Midlands")</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
|
||||
</div>
|
||||
<p>Now let’s say we want to just work with the data from the West Midlands, and we’d like to omit some of the columns. We can choose a specific range of columns using <code>select</code>, like this:</p>
|
||||
<div class="page-columns page-full"><p></p><div class="no-row-height column-margin column-container"><span class="">Some readers will want to pause here and check out Hadley Wickham’s “R For Data Science” book, in the section, <a href="https://r4ds.hadley.nz/data-visualize#introduction">“Data visualisation”</a> to get a fuller explanation of how to explore your data.</span></div></div>
|
||||
<div class="cell">
|
||||
<div class="sourceCode cell-code" id="cb14"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>wmids_data <span class="ot"><-</span> <span class="fu">select</span>(religion_uk, no_religion<span class="sc">:</span>other)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
|
||||
</div>
|
||||
<p>In keeping with my goal to demonstrate data science through examples, we’re going to move on to producing some snappy looking charts for this data.</p>
|
||||
<!--
|
||||
Reference on callout box syntax here: https://quarto.org/docs/authoring/callouts.html
|
||||
-->
|
||||
<div class="callout callout-style-default callout-tip callout-titled">
|
||||
<div class="callout-header d-flex align-content-center">
|
||||
<div class="callout-icon-container">
|
||||
<i class="callout-icon"></i>
|
||||
</div>
|
||||
<div class="callout-title-container flex-fill">
|
||||
What is Religion?
|
||||
</div>
|
||||
</div>
|
||||
<div class="callout-body-container callout-body">
|
||||
<p>Content tbd</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="callout callout-style-default callout-tip callout-titled">
|
||||
<div class="callout-header d-flex align-content-center">
|
||||
<div class="callout-icon-container">
|
||||
<i class="callout-icon"></i>
|
||||
</div>
|
||||
<div class="callout-title-container flex-fill">
|
||||
Hybrid Religious Identity
|
||||
</div>
|
||||
</div>
|
||||
<div class="callout-body-container callout-body">
|
||||
<p>Content tbd</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="callout callout-style-default callout-tip callout-titled">
|
||||
<div class="callout-header d-flex align-content-center">
|
||||
<div class="callout-icon-container">
|
||||
<i class="callout-icon"></i>
|
||||
</div>
|
||||
<div class="callout-title-container flex-fill">
|
||||
What is Secularisation?
|
||||
</div>
|
||||
</div>
|
||||
<div class="callout-body-container callout-body">
|
||||
<p>Content tbd</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section id="references" class="level1 unnumbered">
|
||||
<h1 class="unnumbered">References</h1>
|
||||
<div id="refs" role="list" style="display: none">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
</main> <!-- /main -->
|
||||
<script id="quarto-html-after-body" type="application/javascript">
|
||||
window.document.addEventListener("DOMContentLoaded", function (event) {
|
||||
const toggleBodyColorMode = (bsSheetEl) => {
|
||||
const mode = bsSheetEl.getAttribute("data-mode");
|
||||
const bodyEl = window.document.querySelector("body");
|
||||
if (mode === "dark") {
|
||||
bodyEl.classList.add("quarto-dark");
|
||||
bodyEl.classList.remove("quarto-light");
|
||||
} else {
|
||||
bodyEl.classList.add("quarto-light");
|
||||
bodyEl.classList.remove("quarto-dark");
|
||||
}
|
||||
}
|
||||
const toggleBodyColorPrimary = () => {
|
||||
const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
|
||||
if (bsSheetEl) {
|
||||
toggleBodyColorMode(bsSheetEl);
|
||||
}
|
||||
}
|
||||
toggleBodyColorPrimary();
|
||||
const icon = "";
|
||||
const anchorJS = new window.AnchorJS();
|
||||
anchorJS.options = {
|
||||
placement: 'right',
|
||||
icon: icon
|
||||
};
|
||||
anchorJS.add('.anchored');
|
||||
const isCodeAnnotation = (el) => {
|
||||
for (const clz of el.classList) {
|
||||
if (clz.startsWith('code-annotation-')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const clipboard = new window.ClipboardJS('.code-copy-button', {
|
||||
text: function(trigger) {
|
||||
const codeEl = trigger.previousElementSibling.cloneNode(true);
|
||||
for (const childEl of codeEl.children) {
|
||||
if (isCodeAnnotation(childEl)) {
|
||||
childEl.remove();
|
||||
}
|
||||
}
|
||||
return codeEl.innerText;
|
||||
}
|
||||
});
|
||||
clipboard.on('success', function(e) {
|
||||
// button target
|
||||
const button = e.trigger;
|
||||
// don't keep focus
|
||||
button.blur();
|
||||
// flash "checked"
|
||||
button.classList.add('code-copy-button-checked');
|
||||
var currentTitle = button.getAttribute("title");
|
||||
button.setAttribute("title", "Copied!");
|
||||
let tooltip;
|
||||
if (window.bootstrap) {
|
||||
button.setAttribute("data-bs-toggle", "tooltip");
|
||||
button.setAttribute("data-bs-placement", "left");
|
||||
button.setAttribute("data-bs-title", "Copied!");
|
||||
tooltip = new bootstrap.Tooltip(button,
|
||||
{ trigger: "manual",
|
||||
customClass: "code-copy-button-tooltip",
|
||||
offset: [0, -8]});
|
||||
tooltip.show();
|
||||
}
|
||||
setTimeout(function() {
|
||||
if (tooltip) {
|
||||
tooltip.hide();
|
||||
button.removeAttribute("data-bs-title");
|
||||
button.removeAttribute("data-bs-toggle");
|
||||
button.removeAttribute("data-bs-placement");
|
||||
}
|
||||
button.setAttribute("title", currentTitle);
|
||||
button.classList.remove('code-copy-button-checked');
|
||||
}, 1000);
|
||||
// clear code selection
|
||||
e.clearSelection();
|
||||
});
|
||||
function tippyHover(el, contentFn) {
|
||||
const config = {
|
||||
allowHTML: true,
|
||||
content: contentFn,
|
||||
maxWidth: 500,
|
||||
delay: 100,
|
||||
arrow: false,
|
||||
appendTo: function(el) {
|
||||
return el.parentElement;
|
||||
},
|
||||
interactive: true,
|
||||
interactiveBorder: 10,
|
||||
theme: 'quarto',
|
||||
placement: 'bottom-start'
|
||||
};
|
||||
window.tippy(el, config);
|
||||
}
|
||||
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
|
||||
for (var i=0; i<noterefs.length; i++) {
|
||||
const ref = noterefs[i];
|
||||
tippyHover(ref, function() {
|
||||
// use id or data attribute instead here
|
||||
let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
|
||||
try { href = new URL(href).hash; } catch {}
|
||||
const id = href.replace(/^#\/?/, "");
|
||||
const note = window.document.getElementById(id);
|
||||
return note.innerHTML;
|
||||
});
|
||||
}
|
||||
let selectedAnnoteEl;
|
||||
const selectorForAnnotation = ( cell, annotation) => {
|
||||
let cellAttr = 'data-code-cell="' + cell + '"';
|
||||
let lineAttr = 'data-code-annotation="' + annotation + '"';
|
||||
const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
|
||||
return selector;
|
||||
}
|
||||
const selectCodeLines = (annoteEl) => {
|
||||
const doc = window.document;
|
||||
const targetCell = annoteEl.getAttribute("data-target-cell");
|
||||
const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
|
||||
const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
|
||||
const lines = annoteSpan.getAttribute("data-code-lines").split(",");
|
||||
const lineIds = lines.map((line) => {
|
||||
return targetCell + "-" + line;
|
||||
})
|
||||
let top = null;
|
||||
let height = null;
|
||||
let parent = null;
|
||||
if (lineIds.length > 0) {
|
||||
//compute the position of the single el (top and bottom and make a div)
|
||||
const el = window.document.getElementById(lineIds[0]);
|
||||
top = el.offsetTop;
|
||||
height = el.offsetHeight;
|
||||
parent = el.parentElement.parentElement;
|
||||
if (lineIds.length > 1) {
|
||||
const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
|
||||
const bottom = lastEl.offsetTop + lastEl.offsetHeight;
|
||||
height = bottom - top;
|
||||
}
|
||||
if (top !== null && height !== null && parent !== null) {
|
||||
// cook up a div (if necessary) and position it
|
||||
let div = window.document.getElementById("code-annotation-line-highlight");
|
||||
if (div === null) {
|
||||
div = window.document.createElement("div");
|
||||
div.setAttribute("id", "code-annotation-line-highlight");
|
||||
div.style.position = 'absolute';
|
||||
parent.appendChild(div);
|
||||
}
|
||||
div.style.top = top - 2 + "px";
|
||||
div.style.height = height + 4 + "px";
|
||||
let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
|
||||
if (gutterDiv === null) {
|
||||
gutterDiv = window.document.createElement("div");
|
||||
gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
|
||||
gutterDiv.style.position = 'absolute';
|
||||
const codeCell = window.document.getElementById(targetCell);
|
||||
const gutter = codeCell.querySelector('.code-annotation-gutter');
|
||||
gutter.appendChild(gutterDiv);
|
||||
}
|
||||
gutterDiv.style.top = top - 2 + "px";
|
||||
gutterDiv.style.height = height + 4 + "px";
|
||||
}
|
||||
selectedAnnoteEl = annoteEl;
|
||||
}
|
||||
};
|
||||
const unselectCodeLines = () => {
|
||||
const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
|
||||
elementsIds.forEach((elId) => {
|
||||
const div = window.document.getElementById(elId);
|
||||
if (div) {
|
||||
div.remove();
|
||||
}
|
||||
});
|
||||
selectedAnnoteEl = undefined;
|
||||
};
|
||||
// Attach click handler to the DT
|
||||
const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
|
||||
for (const annoteDlNode of annoteDls) {
|
||||
annoteDlNode.addEventListener('click', (event) => {
|
||||
const clickedEl = event.target;
|
||||
if (clickedEl !== selectedAnnoteEl) {
|
||||
unselectCodeLines();
|
||||
const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
|
||||
if (activeEl) {
|
||||
activeEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
selectCodeLines(clickedEl);
|
||||
clickedEl.classList.add('code-annotation-active');
|
||||
} else {
|
||||
// Unselect the line
|
||||
unselectCodeLines();
|
||||
clickedEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
});
|
||||
}
|
||||
const findCites = (el) => {
|
||||
const parentEl = el.parentElement;
|
||||
if (parentEl) {
|
||||
const cites = parentEl.dataset.cites;
|
||||
if (cites) {
|
||||
return {
|
||||
el,
|
||||
cites: cites.split(' ')
|
||||
};
|
||||
} else {
|
||||
return findCites(el.parentElement)
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
|
||||
for (var i=0; i<bibliorefs.length; i++) {
|
||||
const ref = bibliorefs[i];
|
||||
const citeInfo = findCites(ref);
|
||||
if (citeInfo) {
|
||||
tippyHover(citeInfo.el, function() {
|
||||
var popup = window.document.createElement('div');
|
||||
citeInfo.cites.forEach(function(cite) {
|
||||
var citeDiv = window.document.createElement('div');
|
||||
citeDiv.classList.add('hanging-indent');
|
||||
citeDiv.classList.add('csl-entry');
|
||||
var biblioDiv = window.document.getElementById('ref-' + cite);
|
||||
if (biblioDiv) {
|
||||
citeDiv.innerHTML = biblioDiv.innerHTML;
|
||||
}
|
||||
popup.appendChild(citeDiv);
|
||||
});
|
||||
return popup.innerHTML;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<nav class="page-navigation">
|
||||
<div class="nav-page nav-page-previous">
|
||||
<a href="./intro.html" class="pagination-link">
|
||||
<i class="bi bi-arrow-left-short"></i> <span class="nav-page-text"><span class="chapter-number">1</span> <span class="chapter-title">Introduction: Hacking Religion</span></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-page nav-page-next">
|
||||
<a href="./chapter_2.html" class="pagination-link">
|
||||
<span class="nav-page-text"><span class="chapter-number">3</span> <span class="chapter-title">Survey Data: Spotlight Project</span></span> <i class="bi bi-arrow-right-short"></i>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div> <!-- /content -->
|
||||
|
||||
|
||||
|
||||
</body></html>
|
475
hacking_religion/_book/chapter_2.html
Normal file
475
hacking_religion/_book/chapter_2.html
Normal file
|
@ -0,0 +1,475 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="generator" content="quarto-1.3.450">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
|
||||
|
||||
<title>Hacking Religion: TRS & Data Science in Action - 3 Survey Data: Spotlight Project</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
|
||||
vertical-align: middle;
|
||||
}
|
||||
/* CSS for citations */
|
||||
div.csl-bib-body { }
|
||||
div.csl-entry {
|
||||
clear: both;
|
||||
}
|
||||
.hanging-indent div.csl-entry {
|
||||
margin-left:2em;
|
||||
text-indent:-2em;
|
||||
}
|
||||
div.csl-left-margin {
|
||||
min-width:2em;
|
||||
float:left;
|
||||
}
|
||||
div.csl-right-inline {
|
||||
margin-left:2em;
|
||||
padding-left:1em;
|
||||
}
|
||||
div.csl-indent {
|
||||
margin-left: 2em;
|
||||
}</style>
|
||||
|
||||
|
||||
<script src="site_libs/quarto-nav/quarto-nav.js"></script>
|
||||
<script src="site_libs/quarto-nav/headroom.min.js"></script>
|
||||
<script src="site_libs/clipboard/clipboard.min.js"></script>
|
||||
<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
|
||||
<script src="site_libs/quarto-search/fuse.min.js"></script>
|
||||
<script src="site_libs/quarto-search/quarto-search.js"></script>
|
||||
<meta name="quarto:offset" content="./">
|
||||
<link href="./chapter_3.html" rel="next">
|
||||
<link href="./chapter_1.html" rel="prev">
|
||||
<script src="site_libs/quarto-html/quarto.js"></script>
|
||||
<script src="site_libs/quarto-html/popper.min.js"></script>
|
||||
<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
|
||||
<script src="site_libs/quarto-html/anchor.min.js"></script>
|
||||
<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
|
||||
<link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
|
||||
<script src="site_libs/bootstrap/bootstrap.min.js"></script>
|
||||
<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
|
||||
<script id="quarto-search-options" type="application/json">{
|
||||
"location": "sidebar",
|
||||
"copy-button": false,
|
||||
"collapse-after": 3,
|
||||
"panel-placement": "start",
|
||||
"type": "textbox",
|
||||
"limit": 20,
|
||||
"language": {
|
||||
"search-no-results-text": "No results",
|
||||
"search-matching-documents-text": "matching documents",
|
||||
"search-copy-link-title": "Copy link to search",
|
||||
"search-hide-matches-text": "Hide additional matches",
|
||||
"search-more-match-text": "more match in this document",
|
||||
"search-more-matches-text": "more matches in this document",
|
||||
"search-clear-button-title": "Clear",
|
||||
"search-detached-cancel-button-title": "Cancel",
|
||||
"search-submit-button-title": "Submit",
|
||||
"search-label": "Search"
|
||||
}
|
||||
}</script>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="nav-sidebar floating">
|
||||
|
||||
<div id="quarto-search-results"></div>
|
||||
<header id="quarto-header" class="headroom fixed-top">
|
||||
<nav class="quarto-secondary-nav">
|
||||
<div class="container-fluid d-flex">
|
||||
<button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
<i class="bi bi-layout-text-sidebar-reverse"></i>
|
||||
</button>
|
||||
<nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="./chapter_2.html"><span class="chapter-number">3</span> <span class="chapter-title">Survey Data: Spotlight Project</span></a></li></ol></nav>
|
||||
<a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
</a>
|
||||
<button type="button" class="btn quarto-search-button" aria-label="" onclick="window.quartoOpenSearch();">
|
||||
<i class="bi bi-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<!-- content -->
|
||||
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article">
|
||||
<!-- sidebar -->
|
||||
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal sidebar-navigation floating overflow-auto">
|
||||
<div class="pt-lg-2 mt-2 text-left sidebar-header">
|
||||
<div class="sidebar-title mb-0 py-0">
|
||||
<a href="./">Hacking Religion: TRS & Data Science in Action</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 flex-shrink-0 align-items-center">
|
||||
<div class="sidebar-search">
|
||||
<div id="quarto-search" class="" title="Search"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-menu-container">
|
||||
<ul class="list-unstyled mt-1">
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./index.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">Preface</span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./intro.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">1</span> <span class="chapter-title">Introduction: Hacking Religion</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_1.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">2</span> <span class="chapter-title">The 2021 UK Census</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_2.html" class="sidebar-item-text sidebar-link active">
|
||||
<span class="menu-text"><span class="chapter-number">3</span> <span class="chapter-title">Survey Data: Spotlight Project</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_3.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">4</span> <span class="chapter-title">Mapping churches: geospatial data science</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_4.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">5</span> <span class="chapter-title">Data scraping, corpus analysis and wordclouds</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./summary.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">6</span> <span class="chapter-title">Summary</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./references.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">References</span></a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="quarto-sidebar-glass" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass"></div>
|
||||
<!-- margin-sidebar -->
|
||||
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
|
||||
<nav id="TOC" role="doc-toc" class="toc-active">
|
||||
<h2 id="toc-title">Table of contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#references" id="toc-references" class="nav-link active" data-scroll-target="#references">References</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<!-- main -->
|
||||
<main class="content" id="quarto-document-content">
|
||||
|
||||
<header id="title-block-header" class="quarto-title-block default">
|
||||
<div class="quarto-title">
|
||||
<h1 class="title"><span class="chapter-number">3</span> <span class="chapter-title">Survey Data: Spotlight Project</span></h1>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="quarto-title-meta">
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<div class="callout callout-style-default callout-tip callout-titled">
|
||||
<div class="callout-header d-flex align-content-center">
|
||||
<div class="callout-icon-container">
|
||||
<i class="callout-icon"></i>
|
||||
</div>
|
||||
<div class="callout-title-container flex-fill">
|
||||
How can we measure religion?
|
||||
</div>
|
||||
</div>
|
||||
<div class="callout-body-container callout-body">
|
||||
<p>Content tbd</p>
|
||||
</div>
|
||||
</div>
|
||||
<section id="references" class="level1 unnumbered">
|
||||
<h1 class="unnumbered">References</h1>
|
||||
<div id="refs" role="list" style="display: none">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
</main> <!-- /main -->
|
||||
<script id="quarto-html-after-body" type="application/javascript">
|
||||
window.document.addEventListener("DOMContentLoaded", function (event) {
|
||||
const toggleBodyColorMode = (bsSheetEl) => {
|
||||
const mode = bsSheetEl.getAttribute("data-mode");
|
||||
const bodyEl = window.document.querySelector("body");
|
||||
if (mode === "dark") {
|
||||
bodyEl.classList.add("quarto-dark");
|
||||
bodyEl.classList.remove("quarto-light");
|
||||
} else {
|
||||
bodyEl.classList.add("quarto-light");
|
||||
bodyEl.classList.remove("quarto-dark");
|
||||
}
|
||||
}
|
||||
const toggleBodyColorPrimary = () => {
|
||||
const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
|
||||
if (bsSheetEl) {
|
||||
toggleBodyColorMode(bsSheetEl);
|
||||
}
|
||||
}
|
||||
toggleBodyColorPrimary();
|
||||
const icon = "";
|
||||
const anchorJS = new window.AnchorJS();
|
||||
anchorJS.options = {
|
||||
placement: 'right',
|
||||
icon: icon
|
||||
};
|
||||
anchorJS.add('.anchored');
|
||||
const isCodeAnnotation = (el) => {
|
||||
for (const clz of el.classList) {
|
||||
if (clz.startsWith('code-annotation-')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const clipboard = new window.ClipboardJS('.code-copy-button', {
|
||||
text: function(trigger) {
|
||||
const codeEl = trigger.previousElementSibling.cloneNode(true);
|
||||
for (const childEl of codeEl.children) {
|
||||
if (isCodeAnnotation(childEl)) {
|
||||
childEl.remove();
|
||||
}
|
||||
}
|
||||
return codeEl.innerText;
|
||||
}
|
||||
});
|
||||
clipboard.on('success', function(e) {
|
||||
// button target
|
||||
const button = e.trigger;
|
||||
// don't keep focus
|
||||
button.blur();
|
||||
// flash "checked"
|
||||
button.classList.add('code-copy-button-checked');
|
||||
var currentTitle = button.getAttribute("title");
|
||||
button.setAttribute("title", "Copied!");
|
||||
let tooltip;
|
||||
if (window.bootstrap) {
|
||||
button.setAttribute("data-bs-toggle", "tooltip");
|
||||
button.setAttribute("data-bs-placement", "left");
|
||||
button.setAttribute("data-bs-title", "Copied!");
|
||||
tooltip = new bootstrap.Tooltip(button,
|
||||
{ trigger: "manual",
|
||||
customClass: "code-copy-button-tooltip",
|
||||
offset: [0, -8]});
|
||||
tooltip.show();
|
||||
}
|
||||
setTimeout(function() {
|
||||
if (tooltip) {
|
||||
tooltip.hide();
|
||||
button.removeAttribute("data-bs-title");
|
||||
button.removeAttribute("data-bs-toggle");
|
||||
button.removeAttribute("data-bs-placement");
|
||||
}
|
||||
button.setAttribute("title", currentTitle);
|
||||
button.classList.remove('code-copy-button-checked');
|
||||
}, 1000);
|
||||
// clear code selection
|
||||
e.clearSelection();
|
||||
});
|
||||
function tippyHover(el, contentFn) {
|
||||
const config = {
|
||||
allowHTML: true,
|
||||
content: contentFn,
|
||||
maxWidth: 500,
|
||||
delay: 100,
|
||||
arrow: false,
|
||||
appendTo: function(el) {
|
||||
return el.parentElement;
|
||||
},
|
||||
interactive: true,
|
||||
interactiveBorder: 10,
|
||||
theme: 'quarto',
|
||||
placement: 'bottom-start'
|
||||
};
|
||||
window.tippy(el, config);
|
||||
}
|
||||
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
|
||||
for (var i=0; i<noterefs.length; i++) {
|
||||
const ref = noterefs[i];
|
||||
tippyHover(ref, function() {
|
||||
// use id or data attribute instead here
|
||||
let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
|
||||
try { href = new URL(href).hash; } catch {}
|
||||
const id = href.replace(/^#\/?/, "");
|
||||
const note = window.document.getElementById(id);
|
||||
return note.innerHTML;
|
||||
});
|
||||
}
|
||||
let selectedAnnoteEl;
|
||||
const selectorForAnnotation = ( cell, annotation) => {
|
||||
let cellAttr = 'data-code-cell="' + cell + '"';
|
||||
let lineAttr = 'data-code-annotation="' + annotation + '"';
|
||||
const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
|
||||
return selector;
|
||||
}
|
||||
const selectCodeLines = (annoteEl) => {
|
||||
const doc = window.document;
|
||||
const targetCell = annoteEl.getAttribute("data-target-cell");
|
||||
const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
|
||||
const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
|
||||
const lines = annoteSpan.getAttribute("data-code-lines").split(",");
|
||||
const lineIds = lines.map((line) => {
|
||||
return targetCell + "-" + line;
|
||||
})
|
||||
let top = null;
|
||||
let height = null;
|
||||
let parent = null;
|
||||
if (lineIds.length > 0) {
|
||||
//compute the position of the single el (top and bottom and make a div)
|
||||
const el = window.document.getElementById(lineIds[0]);
|
||||
top = el.offsetTop;
|
||||
height = el.offsetHeight;
|
||||
parent = el.parentElement.parentElement;
|
||||
if (lineIds.length > 1) {
|
||||
const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
|
||||
const bottom = lastEl.offsetTop + lastEl.offsetHeight;
|
||||
height = bottom - top;
|
||||
}
|
||||
if (top !== null && height !== null && parent !== null) {
|
||||
// cook up a div (if necessary) and position it
|
||||
let div = window.document.getElementById("code-annotation-line-highlight");
|
||||
if (div === null) {
|
||||
div = window.document.createElement("div");
|
||||
div.setAttribute("id", "code-annotation-line-highlight");
|
||||
div.style.position = 'absolute';
|
||||
parent.appendChild(div);
|
||||
}
|
||||
div.style.top = top - 2 + "px";
|
||||
div.style.height = height + 4 + "px";
|
||||
let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
|
||||
if (gutterDiv === null) {
|
||||
gutterDiv = window.document.createElement("div");
|
||||
gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
|
||||
gutterDiv.style.position = 'absolute';
|
||||
const codeCell = window.document.getElementById(targetCell);
|
||||
const gutter = codeCell.querySelector('.code-annotation-gutter');
|
||||
gutter.appendChild(gutterDiv);
|
||||
}
|
||||
gutterDiv.style.top = top - 2 + "px";
|
||||
gutterDiv.style.height = height + 4 + "px";
|
||||
}
|
||||
selectedAnnoteEl = annoteEl;
|
||||
}
|
||||
};
|
||||
const unselectCodeLines = () => {
|
||||
const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
|
||||
elementsIds.forEach((elId) => {
|
||||
const div = window.document.getElementById(elId);
|
||||
if (div) {
|
||||
div.remove();
|
||||
}
|
||||
});
|
||||
selectedAnnoteEl = undefined;
|
||||
};
|
||||
// Attach click handler to the DT
|
||||
const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
|
||||
for (const annoteDlNode of annoteDls) {
|
||||
annoteDlNode.addEventListener('click', (event) => {
|
||||
const clickedEl = event.target;
|
||||
if (clickedEl !== selectedAnnoteEl) {
|
||||
unselectCodeLines();
|
||||
const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
|
||||
if (activeEl) {
|
||||
activeEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
selectCodeLines(clickedEl);
|
||||
clickedEl.classList.add('code-annotation-active');
|
||||
} else {
|
||||
// Unselect the line
|
||||
unselectCodeLines();
|
||||
clickedEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
});
|
||||
}
|
||||
const findCites = (el) => {
|
||||
const parentEl = el.parentElement;
|
||||
if (parentEl) {
|
||||
const cites = parentEl.dataset.cites;
|
||||
if (cites) {
|
||||
return {
|
||||
el,
|
||||
cites: cites.split(' ')
|
||||
};
|
||||
} else {
|
||||
return findCites(el.parentElement)
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
|
||||
for (var i=0; i<bibliorefs.length; i++) {
|
||||
const ref = bibliorefs[i];
|
||||
const citeInfo = findCites(ref);
|
||||
if (citeInfo) {
|
||||
tippyHover(citeInfo.el, function() {
|
||||
var popup = window.document.createElement('div');
|
||||
citeInfo.cites.forEach(function(cite) {
|
||||
var citeDiv = window.document.createElement('div');
|
||||
citeDiv.classList.add('hanging-indent');
|
||||
citeDiv.classList.add('csl-entry');
|
||||
var biblioDiv = window.document.getElementById('ref-' + cite);
|
||||
if (biblioDiv) {
|
||||
citeDiv.innerHTML = biblioDiv.innerHTML;
|
||||
}
|
||||
popup.appendChild(citeDiv);
|
||||
});
|
||||
return popup.innerHTML;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<nav class="page-navigation">
|
||||
<div class="nav-page nav-page-previous">
|
||||
<a href="./chapter_1.html" class="pagination-link">
|
||||
<i class="bi bi-arrow-left-short"></i> <span class="nav-page-text"><span class="chapter-number">2</span> <span class="chapter-title">The 2021 UK Census</span></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-page nav-page-next">
|
||||
<a href="./chapter_3.html" class="pagination-link">
|
||||
<span class="nav-page-text"><span class="chapter-number">4</span> <span class="chapter-title">Mapping churches: geospatial data science</span></span> <i class="bi bi-arrow-right-short"></i>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div> <!-- /content -->
|
||||
|
||||
|
||||
|
||||
</body></html>
|
462
hacking_religion/_book/chapter_3.html
Normal file
462
hacking_religion/_book/chapter_3.html
Normal file
|
@ -0,0 +1,462 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="generator" content="quarto-1.3.450">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
|
||||
|
||||
<title>Hacking Religion: TRS & Data Science in Action - 4 Mapping churches: geospatial data science</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
|
||||
vertical-align: middle;
|
||||
}
|
||||
/* CSS for citations */
|
||||
div.csl-bib-body { }
|
||||
div.csl-entry {
|
||||
clear: both;
|
||||
}
|
||||
.hanging-indent div.csl-entry {
|
||||
margin-left:2em;
|
||||
text-indent:-2em;
|
||||
}
|
||||
div.csl-left-margin {
|
||||
min-width:2em;
|
||||
float:left;
|
||||
}
|
||||
div.csl-right-inline {
|
||||
margin-left:2em;
|
||||
padding-left:1em;
|
||||
}
|
||||
div.csl-indent {
|
||||
margin-left: 2em;
|
||||
}</style>
|
||||
|
||||
|
||||
<script src="site_libs/quarto-nav/quarto-nav.js"></script>
|
||||
<script src="site_libs/quarto-nav/headroom.min.js"></script>
|
||||
<script src="site_libs/clipboard/clipboard.min.js"></script>
|
||||
<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
|
||||
<script src="site_libs/quarto-search/fuse.min.js"></script>
|
||||
<script src="site_libs/quarto-search/quarto-search.js"></script>
|
||||
<meta name="quarto:offset" content="./">
|
||||
<link href="./chapter_4.html" rel="next">
|
||||
<link href="./chapter_2.html" rel="prev">
|
||||
<script src="site_libs/quarto-html/quarto.js"></script>
|
||||
<script src="site_libs/quarto-html/popper.min.js"></script>
|
||||
<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
|
||||
<script src="site_libs/quarto-html/anchor.min.js"></script>
|
||||
<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
|
||||
<link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
|
||||
<script src="site_libs/bootstrap/bootstrap.min.js"></script>
|
||||
<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
|
||||
<script id="quarto-search-options" type="application/json">{
|
||||
"location": "sidebar",
|
||||
"copy-button": false,
|
||||
"collapse-after": 3,
|
||||
"panel-placement": "start",
|
||||
"type": "textbox",
|
||||
"limit": 20,
|
||||
"language": {
|
||||
"search-no-results-text": "No results",
|
||||
"search-matching-documents-text": "matching documents",
|
||||
"search-copy-link-title": "Copy link to search",
|
||||
"search-hide-matches-text": "Hide additional matches",
|
||||
"search-more-match-text": "more match in this document",
|
||||
"search-more-matches-text": "more matches in this document",
|
||||
"search-clear-button-title": "Clear",
|
||||
"search-detached-cancel-button-title": "Cancel",
|
||||
"search-submit-button-title": "Submit",
|
||||
"search-label": "Search"
|
||||
}
|
||||
}</script>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="nav-sidebar floating">
|
||||
|
||||
<div id="quarto-search-results"></div>
|
||||
<header id="quarto-header" class="headroom fixed-top">
|
||||
<nav class="quarto-secondary-nav">
|
||||
<div class="container-fluid d-flex">
|
||||
<button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
<i class="bi bi-layout-text-sidebar-reverse"></i>
|
||||
</button>
|
||||
<nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="./chapter_3.html"><span class="chapter-number">4</span> <span class="chapter-title">Mapping churches: geospatial data science</span></a></li></ol></nav>
|
||||
<a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
</a>
|
||||
<button type="button" class="btn quarto-search-button" aria-label="" onclick="window.quartoOpenSearch();">
|
||||
<i class="bi bi-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<!-- content -->
|
||||
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article">
|
||||
<!-- sidebar -->
|
||||
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal sidebar-navigation floating overflow-auto">
|
||||
<div class="pt-lg-2 mt-2 text-left sidebar-header">
|
||||
<div class="sidebar-title mb-0 py-0">
|
||||
<a href="./">Hacking Religion: TRS & Data Science in Action</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 flex-shrink-0 align-items-center">
|
||||
<div class="sidebar-search">
|
||||
<div id="quarto-search" class="" title="Search"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-menu-container">
|
||||
<ul class="list-unstyled mt-1">
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./index.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">Preface</span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./intro.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">1</span> <span class="chapter-title">Introduction: Hacking Religion</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_1.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">2</span> <span class="chapter-title">The 2021 UK Census</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_2.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">3</span> <span class="chapter-title">Survey Data: Spotlight Project</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_3.html" class="sidebar-item-text sidebar-link active">
|
||||
<span class="menu-text"><span class="chapter-number">4</span> <span class="chapter-title">Mapping churches: geospatial data science</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_4.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">5</span> <span class="chapter-title">Data scraping, corpus analysis and wordclouds</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./summary.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">6</span> <span class="chapter-title">Summary</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./references.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">References</span></a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="quarto-sidebar-glass" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass"></div>
|
||||
<!-- margin-sidebar -->
|
||||
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
|
||||
<nav id="TOC" role="doc-toc" class="toc-active">
|
||||
<h2 id="toc-title">Table of contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#references" id="toc-references" class="nav-link active" data-scroll-target="#references">References</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<!-- main -->
|
||||
<main class="content" id="quarto-document-content">
|
||||
|
||||
<header id="title-block-header" class="quarto-title-block default">
|
||||
<div class="quarto-title">
|
||||
<h1 class="title"><span class="chapter-number">4</span> <span class="chapter-title">Mapping churches: geospatial data science</span></h1>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="quarto-title-meta">
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<section id="references" class="level1 unnumbered">
|
||||
<h1 class="unnumbered">References</h1>
|
||||
<div id="refs" role="list" style="display: none">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
</main> <!-- /main -->
|
||||
<script id="quarto-html-after-body" type="application/javascript">
|
||||
window.document.addEventListener("DOMContentLoaded", function (event) {
|
||||
const toggleBodyColorMode = (bsSheetEl) => {
|
||||
const mode = bsSheetEl.getAttribute("data-mode");
|
||||
const bodyEl = window.document.querySelector("body");
|
||||
if (mode === "dark") {
|
||||
bodyEl.classList.add("quarto-dark");
|
||||
bodyEl.classList.remove("quarto-light");
|
||||
} else {
|
||||
bodyEl.classList.add("quarto-light");
|
||||
bodyEl.classList.remove("quarto-dark");
|
||||
}
|
||||
}
|
||||
const toggleBodyColorPrimary = () => {
|
||||
const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
|
||||
if (bsSheetEl) {
|
||||
toggleBodyColorMode(bsSheetEl);
|
||||
}
|
||||
}
|
||||
toggleBodyColorPrimary();
|
||||
const icon = "";
|
||||
const anchorJS = new window.AnchorJS();
|
||||
anchorJS.options = {
|
||||
placement: 'right',
|
||||
icon: icon
|
||||
};
|
||||
anchorJS.add('.anchored');
|
||||
const isCodeAnnotation = (el) => {
|
||||
for (const clz of el.classList) {
|
||||
if (clz.startsWith('code-annotation-')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const clipboard = new window.ClipboardJS('.code-copy-button', {
|
||||
text: function(trigger) {
|
||||
const codeEl = trigger.previousElementSibling.cloneNode(true);
|
||||
for (const childEl of codeEl.children) {
|
||||
if (isCodeAnnotation(childEl)) {
|
||||
childEl.remove();
|
||||
}
|
||||
}
|
||||
return codeEl.innerText;
|
||||
}
|
||||
});
|
||||
clipboard.on('success', function(e) {
|
||||
// button target
|
||||
const button = e.trigger;
|
||||
// don't keep focus
|
||||
button.blur();
|
||||
// flash "checked"
|
||||
button.classList.add('code-copy-button-checked');
|
||||
var currentTitle = button.getAttribute("title");
|
||||
button.setAttribute("title", "Copied!");
|
||||
let tooltip;
|
||||
if (window.bootstrap) {
|
||||
button.setAttribute("data-bs-toggle", "tooltip");
|
||||
button.setAttribute("data-bs-placement", "left");
|
||||
button.setAttribute("data-bs-title", "Copied!");
|
||||
tooltip = new bootstrap.Tooltip(button,
|
||||
{ trigger: "manual",
|
||||
customClass: "code-copy-button-tooltip",
|
||||
offset: [0, -8]});
|
||||
tooltip.show();
|
||||
}
|
||||
setTimeout(function() {
|
||||
if (tooltip) {
|
||||
tooltip.hide();
|
||||
button.removeAttribute("data-bs-title");
|
||||
button.removeAttribute("data-bs-toggle");
|
||||
button.removeAttribute("data-bs-placement");
|
||||
}
|
||||
button.setAttribute("title", currentTitle);
|
||||
button.classList.remove('code-copy-button-checked');
|
||||
}, 1000);
|
||||
// clear code selection
|
||||
e.clearSelection();
|
||||
});
|
||||
function tippyHover(el, contentFn) {
|
||||
const config = {
|
||||
allowHTML: true,
|
||||
content: contentFn,
|
||||
maxWidth: 500,
|
||||
delay: 100,
|
||||
arrow: false,
|
||||
appendTo: function(el) {
|
||||
return el.parentElement;
|
||||
},
|
||||
interactive: true,
|
||||
interactiveBorder: 10,
|
||||
theme: 'quarto',
|
||||
placement: 'bottom-start'
|
||||
};
|
||||
window.tippy(el, config);
|
||||
}
|
||||
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
|
||||
for (var i=0; i<noterefs.length; i++) {
|
||||
const ref = noterefs[i];
|
||||
tippyHover(ref, function() {
|
||||
// use id or data attribute instead here
|
||||
let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
|
||||
try { href = new URL(href).hash; } catch {}
|
||||
const id = href.replace(/^#\/?/, "");
|
||||
const note = window.document.getElementById(id);
|
||||
return note.innerHTML;
|
||||
});
|
||||
}
|
||||
let selectedAnnoteEl;
|
||||
const selectorForAnnotation = ( cell, annotation) => {
|
||||
let cellAttr = 'data-code-cell="' + cell + '"';
|
||||
let lineAttr = 'data-code-annotation="' + annotation + '"';
|
||||
const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
|
||||
return selector;
|
||||
}
|
||||
const selectCodeLines = (annoteEl) => {
|
||||
const doc = window.document;
|
||||
const targetCell = annoteEl.getAttribute("data-target-cell");
|
||||
const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
|
||||
const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
|
||||
const lines = annoteSpan.getAttribute("data-code-lines").split(",");
|
||||
const lineIds = lines.map((line) => {
|
||||
return targetCell + "-" + line;
|
||||
})
|
||||
let top = null;
|
||||
let height = null;
|
||||
let parent = null;
|
||||
if (lineIds.length > 0) {
|
||||
//compute the position of the single el (top and bottom and make a div)
|
||||
const el = window.document.getElementById(lineIds[0]);
|
||||
top = el.offsetTop;
|
||||
height = el.offsetHeight;
|
||||
parent = el.parentElement.parentElement;
|
||||
if (lineIds.length > 1) {
|
||||
const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
|
||||
const bottom = lastEl.offsetTop + lastEl.offsetHeight;
|
||||
height = bottom - top;
|
||||
}
|
||||
if (top !== null && height !== null && parent !== null) {
|
||||
// cook up a div (if necessary) and position it
|
||||
let div = window.document.getElementById("code-annotation-line-highlight");
|
||||
if (div === null) {
|
||||
div = window.document.createElement("div");
|
||||
div.setAttribute("id", "code-annotation-line-highlight");
|
||||
div.style.position = 'absolute';
|
||||
parent.appendChild(div);
|
||||
}
|
||||
div.style.top = top - 2 + "px";
|
||||
div.style.height = height + 4 + "px";
|
||||
let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
|
||||
if (gutterDiv === null) {
|
||||
gutterDiv = window.document.createElement("div");
|
||||
gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
|
||||
gutterDiv.style.position = 'absolute';
|
||||
const codeCell = window.document.getElementById(targetCell);
|
||||
const gutter = codeCell.querySelector('.code-annotation-gutter');
|
||||
gutter.appendChild(gutterDiv);
|
||||
}
|
||||
gutterDiv.style.top = top - 2 + "px";
|
||||
gutterDiv.style.height = height + 4 + "px";
|
||||
}
|
||||
selectedAnnoteEl = annoteEl;
|
||||
}
|
||||
};
|
||||
const unselectCodeLines = () => {
|
||||
const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
|
||||
elementsIds.forEach((elId) => {
|
||||
const div = window.document.getElementById(elId);
|
||||
if (div) {
|
||||
div.remove();
|
||||
}
|
||||
});
|
||||
selectedAnnoteEl = undefined;
|
||||
};
|
||||
// Attach click handler to the DT
|
||||
const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
|
||||
for (const annoteDlNode of annoteDls) {
|
||||
annoteDlNode.addEventListener('click', (event) => {
|
||||
const clickedEl = event.target;
|
||||
if (clickedEl !== selectedAnnoteEl) {
|
||||
unselectCodeLines();
|
||||
const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
|
||||
if (activeEl) {
|
||||
activeEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
selectCodeLines(clickedEl);
|
||||
clickedEl.classList.add('code-annotation-active');
|
||||
} else {
|
||||
// Unselect the line
|
||||
unselectCodeLines();
|
||||
clickedEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
});
|
||||
}
|
||||
const findCites = (el) => {
|
||||
const parentEl = el.parentElement;
|
||||
if (parentEl) {
|
||||
const cites = parentEl.dataset.cites;
|
||||
if (cites) {
|
||||
return {
|
||||
el,
|
||||
cites: cites.split(' ')
|
||||
};
|
||||
} else {
|
||||
return findCites(el.parentElement)
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
|
||||
for (var i=0; i<bibliorefs.length; i++) {
|
||||
const ref = bibliorefs[i];
|
||||
const citeInfo = findCites(ref);
|
||||
if (citeInfo) {
|
||||
tippyHover(citeInfo.el, function() {
|
||||
var popup = window.document.createElement('div');
|
||||
citeInfo.cites.forEach(function(cite) {
|
||||
var citeDiv = window.document.createElement('div');
|
||||
citeDiv.classList.add('hanging-indent');
|
||||
citeDiv.classList.add('csl-entry');
|
||||
var biblioDiv = window.document.getElementById('ref-' + cite);
|
||||
if (biblioDiv) {
|
||||
citeDiv.innerHTML = biblioDiv.innerHTML;
|
||||
}
|
||||
popup.appendChild(citeDiv);
|
||||
});
|
||||
return popup.innerHTML;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<nav class="page-navigation">
|
||||
<div class="nav-page nav-page-previous">
|
||||
<a href="./chapter_2.html" class="pagination-link">
|
||||
<i class="bi bi-arrow-left-short"></i> <span class="nav-page-text"><span class="chapter-number">3</span> <span class="chapter-title">Survey Data: Spotlight Project</span></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-page nav-page-next">
|
||||
<a href="./chapter_4.html" class="pagination-link">
|
||||
<span class="nav-page-text"><span class="chapter-number">5</span> <span class="chapter-title">Data scraping, corpus analysis and wordclouds</span></span> <i class="bi bi-arrow-right-short"></i>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div> <!-- /content -->
|
||||
|
||||
|
||||
|
||||
</body></html>
|
462
hacking_religion/_book/chapter_4.html
Normal file
462
hacking_religion/_book/chapter_4.html
Normal file
|
@ -0,0 +1,462 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="generator" content="quarto-1.3.450">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
|
||||
|
||||
<title>Hacking Religion: TRS & Data Science in Action - 5 Data scraping, corpus analysis and wordclouds</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
|
||||
vertical-align: middle;
|
||||
}
|
||||
/* CSS for citations */
|
||||
div.csl-bib-body { }
|
||||
div.csl-entry {
|
||||
clear: both;
|
||||
}
|
||||
.hanging-indent div.csl-entry {
|
||||
margin-left:2em;
|
||||
text-indent:-2em;
|
||||
}
|
||||
div.csl-left-margin {
|
||||
min-width:2em;
|
||||
float:left;
|
||||
}
|
||||
div.csl-right-inline {
|
||||
margin-left:2em;
|
||||
padding-left:1em;
|
||||
}
|
||||
div.csl-indent {
|
||||
margin-left: 2em;
|
||||
}</style>
|
||||
|
||||
|
||||
<script src="site_libs/quarto-nav/quarto-nav.js"></script>
|
||||
<script src="site_libs/quarto-nav/headroom.min.js"></script>
|
||||
<script src="site_libs/clipboard/clipboard.min.js"></script>
|
||||
<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
|
||||
<script src="site_libs/quarto-search/fuse.min.js"></script>
|
||||
<script src="site_libs/quarto-search/quarto-search.js"></script>
|
||||
<meta name="quarto:offset" content="./">
|
||||
<link href="./summary.html" rel="next">
|
||||
<link href="./chapter_3.html" rel="prev">
|
||||
<script src="site_libs/quarto-html/quarto.js"></script>
|
||||
<script src="site_libs/quarto-html/popper.min.js"></script>
|
||||
<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
|
||||
<script src="site_libs/quarto-html/anchor.min.js"></script>
|
||||
<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
|
||||
<link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
|
||||
<script src="site_libs/bootstrap/bootstrap.min.js"></script>
|
||||
<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
|
||||
<script id="quarto-search-options" type="application/json">{
|
||||
"location": "sidebar",
|
||||
"copy-button": false,
|
||||
"collapse-after": 3,
|
||||
"panel-placement": "start",
|
||||
"type": "textbox",
|
||||
"limit": 20,
|
||||
"language": {
|
||||
"search-no-results-text": "No results",
|
||||
"search-matching-documents-text": "matching documents",
|
||||
"search-copy-link-title": "Copy link to search",
|
||||
"search-hide-matches-text": "Hide additional matches",
|
||||
"search-more-match-text": "more match in this document",
|
||||
"search-more-matches-text": "more matches in this document",
|
||||
"search-clear-button-title": "Clear",
|
||||
"search-detached-cancel-button-title": "Cancel",
|
||||
"search-submit-button-title": "Submit",
|
||||
"search-label": "Search"
|
||||
}
|
||||
}</script>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="nav-sidebar floating">
|
||||
|
||||
<div id="quarto-search-results"></div>
|
||||
<header id="quarto-header" class="headroom fixed-top">
|
||||
<nav class="quarto-secondary-nav">
|
||||
<div class="container-fluid d-flex">
|
||||
<button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
<i class="bi bi-layout-text-sidebar-reverse"></i>
|
||||
</button>
|
||||
<nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="./chapter_4.html"><span class="chapter-number">5</span> <span class="chapter-title">Data scraping, corpus analysis and wordclouds</span></a></li></ol></nav>
|
||||
<a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
</a>
|
||||
<button type="button" class="btn quarto-search-button" aria-label="" onclick="window.quartoOpenSearch();">
|
||||
<i class="bi bi-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<!-- content -->
|
||||
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article">
|
||||
<!-- sidebar -->
|
||||
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal sidebar-navigation floating overflow-auto">
|
||||
<div class="pt-lg-2 mt-2 text-left sidebar-header">
|
||||
<div class="sidebar-title mb-0 py-0">
|
||||
<a href="./">Hacking Religion: TRS & Data Science in Action</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 flex-shrink-0 align-items-center">
|
||||
<div class="sidebar-search">
|
||||
<div id="quarto-search" class="" title="Search"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-menu-container">
|
||||
<ul class="list-unstyled mt-1">
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./index.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">Preface</span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./intro.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">1</span> <span class="chapter-title">Introduction: Hacking Religion</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_1.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">2</span> <span class="chapter-title">The 2021 UK Census</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_2.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">3</span> <span class="chapter-title">Survey Data: Spotlight Project</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_3.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">4</span> <span class="chapter-title">Mapping churches: geospatial data science</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_4.html" class="sidebar-item-text sidebar-link active">
|
||||
<span class="menu-text"><span class="chapter-number">5</span> <span class="chapter-title">Data scraping, corpus analysis and wordclouds</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./summary.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">6</span> <span class="chapter-title">Summary</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./references.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">References</span></a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="quarto-sidebar-glass" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass"></div>
|
||||
<!-- margin-sidebar -->
|
||||
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
|
||||
<nav id="TOC" role="doc-toc" class="toc-active">
|
||||
<h2 id="toc-title">Table of contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#references" id="toc-references" class="nav-link active" data-scroll-target="#references">References</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<!-- main -->
|
||||
<main class="content" id="quarto-document-content">
|
||||
|
||||
<header id="title-block-header" class="quarto-title-block default">
|
||||
<div class="quarto-title">
|
||||
<h1 class="title"><span class="chapter-number">5</span> <span class="chapter-title">Data scraping, corpus analysis and wordclouds</span></h1>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="quarto-title-meta">
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<section id="references" class="level1 unnumbered">
|
||||
<h1 class="unnumbered">References</h1>
|
||||
<div id="refs" role="list" style="display: none">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
</main> <!-- /main -->
|
||||
<script id="quarto-html-after-body" type="application/javascript">
|
||||
window.document.addEventListener("DOMContentLoaded", function (event) {
|
||||
const toggleBodyColorMode = (bsSheetEl) => {
|
||||
const mode = bsSheetEl.getAttribute("data-mode");
|
||||
const bodyEl = window.document.querySelector("body");
|
||||
if (mode === "dark") {
|
||||
bodyEl.classList.add("quarto-dark");
|
||||
bodyEl.classList.remove("quarto-light");
|
||||
} else {
|
||||
bodyEl.classList.add("quarto-light");
|
||||
bodyEl.classList.remove("quarto-dark");
|
||||
}
|
||||
}
|
||||
const toggleBodyColorPrimary = () => {
|
||||
const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
|
||||
if (bsSheetEl) {
|
||||
toggleBodyColorMode(bsSheetEl);
|
||||
}
|
||||
}
|
||||
toggleBodyColorPrimary();
|
||||
const icon = "";
|
||||
const anchorJS = new window.AnchorJS();
|
||||
anchorJS.options = {
|
||||
placement: 'right',
|
||||
icon: icon
|
||||
};
|
||||
anchorJS.add('.anchored');
|
||||
const isCodeAnnotation = (el) => {
|
||||
for (const clz of el.classList) {
|
||||
if (clz.startsWith('code-annotation-')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const clipboard = new window.ClipboardJS('.code-copy-button', {
|
||||
text: function(trigger) {
|
||||
const codeEl = trigger.previousElementSibling.cloneNode(true);
|
||||
for (const childEl of codeEl.children) {
|
||||
if (isCodeAnnotation(childEl)) {
|
||||
childEl.remove();
|
||||
}
|
||||
}
|
||||
return codeEl.innerText;
|
||||
}
|
||||
});
|
||||
clipboard.on('success', function(e) {
|
||||
// button target
|
||||
const button = e.trigger;
|
||||
// don't keep focus
|
||||
button.blur();
|
||||
// flash "checked"
|
||||
button.classList.add('code-copy-button-checked');
|
||||
var currentTitle = button.getAttribute("title");
|
||||
button.setAttribute("title", "Copied!");
|
||||
let tooltip;
|
||||
if (window.bootstrap) {
|
||||
button.setAttribute("data-bs-toggle", "tooltip");
|
||||
button.setAttribute("data-bs-placement", "left");
|
||||
button.setAttribute("data-bs-title", "Copied!");
|
||||
tooltip = new bootstrap.Tooltip(button,
|
||||
{ trigger: "manual",
|
||||
customClass: "code-copy-button-tooltip",
|
||||
offset: [0, -8]});
|
||||
tooltip.show();
|
||||
}
|
||||
setTimeout(function() {
|
||||
if (tooltip) {
|
||||
tooltip.hide();
|
||||
button.removeAttribute("data-bs-title");
|
||||
button.removeAttribute("data-bs-toggle");
|
||||
button.removeAttribute("data-bs-placement");
|
||||
}
|
||||
button.setAttribute("title", currentTitle);
|
||||
button.classList.remove('code-copy-button-checked');
|
||||
}, 1000);
|
||||
// clear code selection
|
||||
e.clearSelection();
|
||||
});
|
||||
function tippyHover(el, contentFn) {
|
||||
const config = {
|
||||
allowHTML: true,
|
||||
content: contentFn,
|
||||
maxWidth: 500,
|
||||
delay: 100,
|
||||
arrow: false,
|
||||
appendTo: function(el) {
|
||||
return el.parentElement;
|
||||
},
|
||||
interactive: true,
|
||||
interactiveBorder: 10,
|
||||
theme: 'quarto',
|
||||
placement: 'bottom-start'
|
||||
};
|
||||
window.tippy(el, config);
|
||||
}
|
||||
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
|
||||
for (var i=0; i<noterefs.length; i++) {
|
||||
const ref = noterefs[i];
|
||||
tippyHover(ref, function() {
|
||||
// use id or data attribute instead here
|
||||
let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
|
||||
try { href = new URL(href).hash; } catch {}
|
||||
const id = href.replace(/^#\/?/, "");
|
||||
const note = window.document.getElementById(id);
|
||||
return note.innerHTML;
|
||||
});
|
||||
}
|
||||
let selectedAnnoteEl;
|
||||
const selectorForAnnotation = ( cell, annotation) => {
|
||||
let cellAttr = 'data-code-cell="' + cell + '"';
|
||||
let lineAttr = 'data-code-annotation="' + annotation + '"';
|
||||
const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
|
||||
return selector;
|
||||
}
|
||||
const selectCodeLines = (annoteEl) => {
|
||||
const doc = window.document;
|
||||
const targetCell = annoteEl.getAttribute("data-target-cell");
|
||||
const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
|
||||
const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
|
||||
const lines = annoteSpan.getAttribute("data-code-lines").split(",");
|
||||
const lineIds = lines.map((line) => {
|
||||
return targetCell + "-" + line;
|
||||
})
|
||||
let top = null;
|
||||
let height = null;
|
||||
let parent = null;
|
||||
if (lineIds.length > 0) {
|
||||
//compute the position of the single el (top and bottom and make a div)
|
||||
const el = window.document.getElementById(lineIds[0]);
|
||||
top = el.offsetTop;
|
||||
height = el.offsetHeight;
|
||||
parent = el.parentElement.parentElement;
|
||||
if (lineIds.length > 1) {
|
||||
const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
|
||||
const bottom = lastEl.offsetTop + lastEl.offsetHeight;
|
||||
height = bottom - top;
|
||||
}
|
||||
if (top !== null && height !== null && parent !== null) {
|
||||
// cook up a div (if necessary) and position it
|
||||
let div = window.document.getElementById("code-annotation-line-highlight");
|
||||
if (div === null) {
|
||||
div = window.document.createElement("div");
|
||||
div.setAttribute("id", "code-annotation-line-highlight");
|
||||
div.style.position = 'absolute';
|
||||
parent.appendChild(div);
|
||||
}
|
||||
div.style.top = top - 2 + "px";
|
||||
div.style.height = height + 4 + "px";
|
||||
let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
|
||||
if (gutterDiv === null) {
|
||||
gutterDiv = window.document.createElement("div");
|
||||
gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
|
||||
gutterDiv.style.position = 'absolute';
|
||||
const codeCell = window.document.getElementById(targetCell);
|
||||
const gutter = codeCell.querySelector('.code-annotation-gutter');
|
||||
gutter.appendChild(gutterDiv);
|
||||
}
|
||||
gutterDiv.style.top = top - 2 + "px";
|
||||
gutterDiv.style.height = height + 4 + "px";
|
||||
}
|
||||
selectedAnnoteEl = annoteEl;
|
||||
}
|
||||
};
|
||||
const unselectCodeLines = () => {
|
||||
const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
|
||||
elementsIds.forEach((elId) => {
|
||||
const div = window.document.getElementById(elId);
|
||||
if (div) {
|
||||
div.remove();
|
||||
}
|
||||
});
|
||||
selectedAnnoteEl = undefined;
|
||||
};
|
||||
// Attach click handler to the DT
|
||||
const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
|
||||
for (const annoteDlNode of annoteDls) {
|
||||
annoteDlNode.addEventListener('click', (event) => {
|
||||
const clickedEl = event.target;
|
||||
if (clickedEl !== selectedAnnoteEl) {
|
||||
unselectCodeLines();
|
||||
const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
|
||||
if (activeEl) {
|
||||
activeEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
selectCodeLines(clickedEl);
|
||||
clickedEl.classList.add('code-annotation-active');
|
||||
} else {
|
||||
// Unselect the line
|
||||
unselectCodeLines();
|
||||
clickedEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
});
|
||||
}
|
||||
const findCites = (el) => {
|
||||
const parentEl = el.parentElement;
|
||||
if (parentEl) {
|
||||
const cites = parentEl.dataset.cites;
|
||||
if (cites) {
|
||||
return {
|
||||
el,
|
||||
cites: cites.split(' ')
|
||||
};
|
||||
} else {
|
||||
return findCites(el.parentElement)
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
|
||||
for (var i=0; i<bibliorefs.length; i++) {
|
||||
const ref = bibliorefs[i];
|
||||
const citeInfo = findCites(ref);
|
||||
if (citeInfo) {
|
||||
tippyHover(citeInfo.el, function() {
|
||||
var popup = window.document.createElement('div');
|
||||
citeInfo.cites.forEach(function(cite) {
|
||||
var citeDiv = window.document.createElement('div');
|
||||
citeDiv.classList.add('hanging-indent');
|
||||
citeDiv.classList.add('csl-entry');
|
||||
var biblioDiv = window.document.getElementById('ref-' + cite);
|
||||
if (biblioDiv) {
|
||||
citeDiv.innerHTML = biblioDiv.innerHTML;
|
||||
}
|
||||
popup.appendChild(citeDiv);
|
||||
});
|
||||
return popup.innerHTML;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<nav class="page-navigation">
|
||||
<div class="nav-page nav-page-previous">
|
||||
<a href="./chapter_3.html" class="pagination-link">
|
||||
<i class="bi bi-arrow-left-short"></i> <span class="nav-page-text"><span class="chapter-number">4</span> <span class="chapter-title">Mapping churches: geospatial data science</span></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-page nav-page-next">
|
||||
<a href="./summary.html" class="pagination-link">
|
||||
<span class="nav-page-text"><span class="chapter-number">6</span> <span class="chapter-title">Summary</span></span> <i class="bi bi-arrow-right-short"></i>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div> <!-- /content -->
|
||||
|
||||
|
||||
|
||||
</body></html>
|
452
hacking_religion/_book/index.html
Normal file
452
hacking_religion/_book/index.html
Normal file
|
@ -0,0 +1,452 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="generator" content="quarto-1.3.450">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
|
||||
<meta name="author" content="Jeremy H. Kidwell">
|
||||
<meta name="dcterms.date" content="2023-09-29">
|
||||
|
||||
<title>Hacking Religion: TRS & Data Science in Action</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<script src="site_libs/quarto-nav/quarto-nav.js"></script>
|
||||
<script src="site_libs/quarto-nav/headroom.min.js"></script>
|
||||
<script src="site_libs/clipboard/clipboard.min.js"></script>
|
||||
<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
|
||||
<script src="site_libs/quarto-search/fuse.min.js"></script>
|
||||
<script src="site_libs/quarto-search/quarto-search.js"></script>
|
||||
<meta name="quarto:offset" content="./">
|
||||
<link href="./intro.html" rel="next">
|
||||
<script src="site_libs/quarto-html/quarto.js"></script>
|
||||
<script src="site_libs/quarto-html/popper.min.js"></script>
|
||||
<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
|
||||
<script src="site_libs/quarto-html/anchor.min.js"></script>
|
||||
<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
|
||||
<link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
|
||||
<script src="site_libs/bootstrap/bootstrap.min.js"></script>
|
||||
<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
|
||||
<script id="quarto-search-options" type="application/json">{
|
||||
"location": "sidebar",
|
||||
"copy-button": false,
|
||||
"collapse-after": 3,
|
||||
"panel-placement": "start",
|
||||
"type": "textbox",
|
||||
"limit": 20,
|
||||
"language": {
|
||||
"search-no-results-text": "No results",
|
||||
"search-matching-documents-text": "matching documents",
|
||||
"search-copy-link-title": "Copy link to search",
|
||||
"search-hide-matches-text": "Hide additional matches",
|
||||
"search-more-match-text": "more match in this document",
|
||||
"search-more-matches-text": "more matches in this document",
|
||||
"search-clear-button-title": "Clear",
|
||||
"search-detached-cancel-button-title": "Cancel",
|
||||
"search-submit-button-title": "Submit",
|
||||
"search-label": "Search"
|
||||
}
|
||||
}</script>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="nav-sidebar floating">
|
||||
|
||||
<div id="quarto-search-results"></div>
|
||||
<header id="quarto-header" class="headroom fixed-top">
|
||||
<nav class="quarto-secondary-nav">
|
||||
<div class="container-fluid d-flex">
|
||||
<button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
<i class="bi bi-layout-text-sidebar-reverse"></i>
|
||||
</button>
|
||||
<nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="./index.html">Preface</a></li></ol></nav>
|
||||
<a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
</a>
|
||||
<button type="button" class="btn quarto-search-button" aria-label="" onclick="window.quartoOpenSearch();">
|
||||
<i class="bi bi-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<!-- content -->
|
||||
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article">
|
||||
<!-- sidebar -->
|
||||
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal sidebar-navigation floating overflow-auto">
|
||||
<div class="pt-lg-2 mt-2 text-left sidebar-header">
|
||||
<div class="sidebar-title mb-0 py-0">
|
||||
<a href="./">Hacking Religion: TRS & Data Science in Action</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 flex-shrink-0 align-items-center">
|
||||
<div class="sidebar-search">
|
||||
<div id="quarto-search" class="" title="Search"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-menu-container">
|
||||
<ul class="list-unstyled mt-1">
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./index.html" class="sidebar-item-text sidebar-link active">
|
||||
<span class="menu-text">Preface</span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./intro.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">1</span> <span class="chapter-title">Introduction: Hacking Religion</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_1.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">2</span> <span class="chapter-title">The 2021 UK Census</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_2.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">3</span> <span class="chapter-title">Survey Data: Spotlight Project</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_3.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">4</span> <span class="chapter-title">Mapping churches: geospatial data science</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_4.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">5</span> <span class="chapter-title">Data scraping, corpus analysis and wordclouds</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./summary.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">6</span> <span class="chapter-title">Summary</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./references.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">References</span></a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="quarto-sidebar-glass" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass"></div>
|
||||
<!-- margin-sidebar -->
|
||||
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
|
||||
<nav id="TOC" role="doc-toc" class="toc-active">
|
||||
<h2 id="toc-title">Table of contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#preface" id="toc-preface" class="nav-link active" data-scroll-target="#preface">Preface</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<!-- main -->
|
||||
<main class="content" id="quarto-document-content">
|
||||
|
||||
<header id="title-block-header" class="quarto-title-block default">
|
||||
<div class="quarto-title">
|
||||
<h1 class="title">Hacking Religion: TRS & Data Science in Action</h1>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="quarto-title-meta">
|
||||
|
||||
<div>
|
||||
<div class="quarto-title-meta-heading">Author</div>
|
||||
<div class="quarto-title-meta-contents">
|
||||
<p>Jeremy H. Kidwell </p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="quarto-title-meta-heading">Published</div>
|
||||
<div class="quarto-title-meta-contents">
|
||||
<p class="date">September 29, 2023</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<section id="preface" class="level1 unnumbered">
|
||||
<h1 class="unnumbered">Preface</h1>
|
||||
<p>This is a Quarto book.</p>
|
||||
<p>To learn more about Quarto books visit <a href="https://quarto.org/docs/books" class="uri">https://quarto.org/docs/books</a>.</p>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
</main> <!-- /main -->
|
||||
<script id="quarto-html-after-body" type="application/javascript">
|
||||
window.document.addEventListener("DOMContentLoaded", function (event) {
|
||||
const toggleBodyColorMode = (bsSheetEl) => {
|
||||
const mode = bsSheetEl.getAttribute("data-mode");
|
||||
const bodyEl = window.document.querySelector("body");
|
||||
if (mode === "dark") {
|
||||
bodyEl.classList.add("quarto-dark");
|
||||
bodyEl.classList.remove("quarto-light");
|
||||
} else {
|
||||
bodyEl.classList.add("quarto-light");
|
||||
bodyEl.classList.remove("quarto-dark");
|
||||
}
|
||||
}
|
||||
const toggleBodyColorPrimary = () => {
|
||||
const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
|
||||
if (bsSheetEl) {
|
||||
toggleBodyColorMode(bsSheetEl);
|
||||
}
|
||||
}
|
||||
toggleBodyColorPrimary();
|
||||
const icon = "";
|
||||
const anchorJS = new window.AnchorJS();
|
||||
anchorJS.options = {
|
||||
placement: 'right',
|
||||
icon: icon
|
||||
};
|
||||
anchorJS.add('.anchored');
|
||||
const isCodeAnnotation = (el) => {
|
||||
for (const clz of el.classList) {
|
||||
if (clz.startsWith('code-annotation-')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const clipboard = new window.ClipboardJS('.code-copy-button', {
|
||||
text: function(trigger) {
|
||||
const codeEl = trigger.previousElementSibling.cloneNode(true);
|
||||
for (const childEl of codeEl.children) {
|
||||
if (isCodeAnnotation(childEl)) {
|
||||
childEl.remove();
|
||||
}
|
||||
}
|
||||
return codeEl.innerText;
|
||||
}
|
||||
});
|
||||
clipboard.on('success', function(e) {
|
||||
// button target
|
||||
const button = e.trigger;
|
||||
// don't keep focus
|
||||
button.blur();
|
||||
// flash "checked"
|
||||
button.classList.add('code-copy-button-checked');
|
||||
var currentTitle = button.getAttribute("title");
|
||||
button.setAttribute("title", "Copied!");
|
||||
let tooltip;
|
||||
if (window.bootstrap) {
|
||||
button.setAttribute("data-bs-toggle", "tooltip");
|
||||
button.setAttribute("data-bs-placement", "left");
|
||||
button.setAttribute("data-bs-title", "Copied!");
|
||||
tooltip = new bootstrap.Tooltip(button,
|
||||
{ trigger: "manual",
|
||||
customClass: "code-copy-button-tooltip",
|
||||
offset: [0, -8]});
|
||||
tooltip.show();
|
||||
}
|
||||
setTimeout(function() {
|
||||
if (tooltip) {
|
||||
tooltip.hide();
|
||||
button.removeAttribute("data-bs-title");
|
||||
button.removeAttribute("data-bs-toggle");
|
||||
button.removeAttribute("data-bs-placement");
|
||||
}
|
||||
button.setAttribute("title", currentTitle);
|
||||
button.classList.remove('code-copy-button-checked');
|
||||
}, 1000);
|
||||
// clear code selection
|
||||
e.clearSelection();
|
||||
});
|
||||
function tippyHover(el, contentFn) {
|
||||
const config = {
|
||||
allowHTML: true,
|
||||
content: contentFn,
|
||||
maxWidth: 500,
|
||||
delay: 100,
|
||||
arrow: false,
|
||||
appendTo: function(el) {
|
||||
return el.parentElement;
|
||||
},
|
||||
interactive: true,
|
||||
interactiveBorder: 10,
|
||||
theme: 'quarto',
|
||||
placement: 'bottom-start'
|
||||
};
|
||||
window.tippy(el, config);
|
||||
}
|
||||
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
|
||||
for (var i=0; i<noterefs.length; i++) {
|
||||
const ref = noterefs[i];
|
||||
tippyHover(ref, function() {
|
||||
// use id or data attribute instead here
|
||||
let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
|
||||
try { href = new URL(href).hash; } catch {}
|
||||
const id = href.replace(/^#\/?/, "");
|
||||
const note = window.document.getElementById(id);
|
||||
return note.innerHTML;
|
||||
});
|
||||
}
|
||||
let selectedAnnoteEl;
|
||||
const selectorForAnnotation = ( cell, annotation) => {
|
||||
let cellAttr = 'data-code-cell="' + cell + '"';
|
||||
let lineAttr = 'data-code-annotation="' + annotation + '"';
|
||||
const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
|
||||
return selector;
|
||||
}
|
||||
const selectCodeLines = (annoteEl) => {
|
||||
const doc = window.document;
|
||||
const targetCell = annoteEl.getAttribute("data-target-cell");
|
||||
const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
|
||||
const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
|
||||
const lines = annoteSpan.getAttribute("data-code-lines").split(",");
|
||||
const lineIds = lines.map((line) => {
|
||||
return targetCell + "-" + line;
|
||||
})
|
||||
let top = null;
|
||||
let height = null;
|
||||
let parent = null;
|
||||
if (lineIds.length > 0) {
|
||||
//compute the position of the single el (top and bottom and make a div)
|
||||
const el = window.document.getElementById(lineIds[0]);
|
||||
top = el.offsetTop;
|
||||
height = el.offsetHeight;
|
||||
parent = el.parentElement.parentElement;
|
||||
if (lineIds.length > 1) {
|
||||
const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
|
||||
const bottom = lastEl.offsetTop + lastEl.offsetHeight;
|
||||
height = bottom - top;
|
||||
}
|
||||
if (top !== null && height !== null && parent !== null) {
|
||||
// cook up a div (if necessary) and position it
|
||||
let div = window.document.getElementById("code-annotation-line-highlight");
|
||||
if (div === null) {
|
||||
div = window.document.createElement("div");
|
||||
div.setAttribute("id", "code-annotation-line-highlight");
|
||||
div.style.position = 'absolute';
|
||||
parent.appendChild(div);
|
||||
}
|
||||
div.style.top = top - 2 + "px";
|
||||
div.style.height = height + 4 + "px";
|
||||
let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
|
||||
if (gutterDiv === null) {
|
||||
gutterDiv = window.document.createElement("div");
|
||||
gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
|
||||
gutterDiv.style.position = 'absolute';
|
||||
const codeCell = window.document.getElementById(targetCell);
|
||||
const gutter = codeCell.querySelector('.code-annotation-gutter');
|
||||
gutter.appendChild(gutterDiv);
|
||||
}
|
||||
gutterDiv.style.top = top - 2 + "px";
|
||||
gutterDiv.style.height = height + 4 + "px";
|
||||
}
|
||||
selectedAnnoteEl = annoteEl;
|
||||
}
|
||||
};
|
||||
const unselectCodeLines = () => {
|
||||
const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
|
||||
elementsIds.forEach((elId) => {
|
||||
const div = window.document.getElementById(elId);
|
||||
if (div) {
|
||||
div.remove();
|
||||
}
|
||||
});
|
||||
selectedAnnoteEl = undefined;
|
||||
};
|
||||
// Attach click handler to the DT
|
||||
const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
|
||||
for (const annoteDlNode of annoteDls) {
|
||||
annoteDlNode.addEventListener('click', (event) => {
|
||||
const clickedEl = event.target;
|
||||
if (clickedEl !== selectedAnnoteEl) {
|
||||
unselectCodeLines();
|
||||
const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
|
||||
if (activeEl) {
|
||||
activeEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
selectCodeLines(clickedEl);
|
||||
clickedEl.classList.add('code-annotation-active');
|
||||
} else {
|
||||
// Unselect the line
|
||||
unselectCodeLines();
|
||||
clickedEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
});
|
||||
}
|
||||
const findCites = (el) => {
|
||||
const parentEl = el.parentElement;
|
||||
if (parentEl) {
|
||||
const cites = parentEl.dataset.cites;
|
||||
if (cites) {
|
||||
return {
|
||||
el,
|
||||
cites: cites.split(' ')
|
||||
};
|
||||
} else {
|
||||
return findCites(el.parentElement)
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
|
||||
for (var i=0; i<bibliorefs.length; i++) {
|
||||
const ref = bibliorefs[i];
|
||||
const citeInfo = findCites(ref);
|
||||
if (citeInfo) {
|
||||
tippyHover(citeInfo.el, function() {
|
||||
var popup = window.document.createElement('div');
|
||||
citeInfo.cites.forEach(function(cite) {
|
||||
var citeDiv = window.document.createElement('div');
|
||||
citeDiv.classList.add('hanging-indent');
|
||||
citeDiv.classList.add('csl-entry');
|
||||
var biblioDiv = window.document.getElementById('ref-' + cite);
|
||||
if (biblioDiv) {
|
||||
citeDiv.innerHTML = biblioDiv.innerHTML;
|
||||
}
|
||||
popup.appendChild(citeDiv);
|
||||
});
|
||||
return popup.innerHTML;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<nav class="page-navigation">
|
||||
<div class="nav-page nav-page-previous">
|
||||
</div>
|
||||
<div class="nav-page nav-page-next">
|
||||
<a href="./intro.html" class="pagination-link">
|
||||
<span class="nav-page-text"><span class="chapter-number">1</span> <span class="chapter-title">Introduction: Hacking Religion</span></span> <i class="bi bi-arrow-right-short"></i>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div> <!-- /content -->
|
||||
|
||||
|
||||
|
||||
</body></html>
|
480
hacking_religion/_book/intro.html
Normal file
480
hacking_religion/_book/intro.html
Normal file
|
@ -0,0 +1,480 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="generator" content="quarto-1.3.450">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
|
||||
|
||||
<title>Hacking Religion: TRS & Data Science in Action - 1 Introduction: Hacking Religion</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<script src="site_libs/quarto-nav/quarto-nav.js"></script>
|
||||
<script src="site_libs/quarto-nav/headroom.min.js"></script>
|
||||
<script src="site_libs/clipboard/clipboard.min.js"></script>
|
||||
<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
|
||||
<script src="site_libs/quarto-search/fuse.min.js"></script>
|
||||
<script src="site_libs/quarto-search/quarto-search.js"></script>
|
||||
<meta name="quarto:offset" content="./">
|
||||
<link href="./chapter_1.html" rel="next">
|
||||
<link href="./index.html" rel="prev">
|
||||
<script src="site_libs/quarto-html/quarto.js"></script>
|
||||
<script src="site_libs/quarto-html/popper.min.js"></script>
|
||||
<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
|
||||
<script src="site_libs/quarto-html/anchor.min.js"></script>
|
||||
<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
|
||||
<link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
|
||||
<script src="site_libs/bootstrap/bootstrap.min.js"></script>
|
||||
<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
|
||||
<script id="quarto-search-options" type="application/json">{
|
||||
"location": "sidebar",
|
||||
"copy-button": false,
|
||||
"collapse-after": 3,
|
||||
"panel-placement": "start",
|
||||
"type": "textbox",
|
||||
"limit": 20,
|
||||
"language": {
|
||||
"search-no-results-text": "No results",
|
||||
"search-matching-documents-text": "matching documents",
|
||||
"search-copy-link-title": "Copy link to search",
|
||||
"search-hide-matches-text": "Hide additional matches",
|
||||
"search-more-match-text": "more match in this document",
|
||||
"search-more-matches-text": "more matches in this document",
|
||||
"search-clear-button-title": "Clear",
|
||||
"search-detached-cancel-button-title": "Cancel",
|
||||
"search-submit-button-title": "Submit",
|
||||
"search-label": "Search"
|
||||
}
|
||||
}</script>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="nav-sidebar floating">
|
||||
|
||||
<div id="quarto-search-results"></div>
|
||||
<header id="quarto-header" class="headroom fixed-top">
|
||||
<nav class="quarto-secondary-nav">
|
||||
<div class="container-fluid d-flex">
|
||||
<button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
<i class="bi bi-layout-text-sidebar-reverse"></i>
|
||||
</button>
|
||||
<nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="./intro.html"><span class="chapter-number">1</span> <span class="chapter-title">Introduction: Hacking Religion</span></a></li></ol></nav>
|
||||
<a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
</a>
|
||||
<button type="button" class="btn quarto-search-button" aria-label="" onclick="window.quartoOpenSearch();">
|
||||
<i class="bi bi-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<!-- content -->
|
||||
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article">
|
||||
<!-- sidebar -->
|
||||
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal sidebar-navigation floating overflow-auto">
|
||||
<div class="pt-lg-2 mt-2 text-left sidebar-header">
|
||||
<div class="sidebar-title mb-0 py-0">
|
||||
<a href="./">Hacking Religion: TRS & Data Science in Action</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 flex-shrink-0 align-items-center">
|
||||
<div class="sidebar-search">
|
||||
<div id="quarto-search" class="" title="Search"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-menu-container">
|
||||
<ul class="list-unstyled mt-1">
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./index.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">Preface</span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./intro.html" class="sidebar-item-text sidebar-link active">
|
||||
<span class="menu-text"><span class="chapter-number">1</span> <span class="chapter-title">Introduction: Hacking Religion</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_1.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">2</span> <span class="chapter-title">The 2021 UK Census</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_2.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">3</span> <span class="chapter-title">Survey Data: Spotlight Project</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_3.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">4</span> <span class="chapter-title">Mapping churches: geospatial data science</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_4.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">5</span> <span class="chapter-title">Data scraping, corpus analysis and wordclouds</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./summary.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">6</span> <span class="chapter-title">Summary</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./references.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">References</span></a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="quarto-sidebar-glass" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass"></div>
|
||||
<!-- margin-sidebar -->
|
||||
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
|
||||
<nav id="TOC" role="doc-toc" class="toc-active">
|
||||
<h2 id="toc-title">Table of contents</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#who-this-book-is-for" id="toc-who-this-book-is-for" class="nav-link active" data-scroll-target="#who-this-book-is-for"><span class="header-section-number">1.1</span> Who this book is for</a></li>
|
||||
<li><a href="#why-this-book" id="toc-why-this-book" class="nav-link" data-scroll-target="#why-this-book"><span class="header-section-number">1.2</span> Why this book?</a></li>
|
||||
<li><a href="#the-hacker-way" id="toc-the-hacker-way" class="nav-link" data-scroll-target="#the-hacker-way"><span class="header-section-number">1.3</span> The hacker way</a></li>
|
||||
<li><a href="#why-programmatic-data-science" id="toc-why-programmatic-data-science" class="nav-link" data-scroll-target="#why-programmatic-data-science"><span class="header-section-number">1.4</span> Why programmatic data science?</a></li>
|
||||
<li><a href="#learning-to-code-my-way" id="toc-learning-to-code-my-way" class="nav-link" data-scroll-target="#learning-to-code-my-way"><span class="header-section-number">1.5</span> Learning to code: my way</a></li>
|
||||
<li><a href="#getting-set-up" id="toc-getting-set-up" class="nav-link" data-scroll-target="#getting-set-up"><span class="header-section-number">1.6</span> Getting set up</a></li>
|
||||
<li><a href="#other-useful-guides" id="toc-other-useful-guides" class="nav-link" data-scroll-target="#other-useful-guides"><span class="header-section-number">1.7</span> Other useful guides:</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<!-- main -->
|
||||
<main class="content" id="quarto-document-content">
|
||||
|
||||
<header id="title-block-header" class="quarto-title-block default">
|
||||
<div class="quarto-title">
|
||||
<h1 class="title"><span class="chapter-number">1</span> <span class="chapter-title">Introduction: Hacking Religion</span></h1>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="quarto-title-meta">
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<section id="who-this-book-is-for" class="level2" data-number="1.1">
|
||||
<h2 data-number="1.1" class="anchored" data-anchor-id="who-this-book-is-for"><span class="header-section-number">1.1</span> Who this book is for</h2>
|
||||
</section>
|
||||
<section id="why-this-book" class="level2" data-number="1.2">
|
||||
<h2 data-number="1.2" class="anchored" data-anchor-id="why-this-book"><span class="header-section-number">1.2</span> Why this book?</h2>
|
||||
</section>
|
||||
<section id="the-hacker-way" class="level2" data-number="1.3">
|
||||
<h2 data-number="1.3" class="anchored" data-anchor-id="the-hacker-way"><span class="header-section-number">1.3</span> The hacker way</h2>
|
||||
<ol type="1">
|
||||
<li><p>Tell the truth</p></li>
|
||||
<li><p>Do not deceive using beauty</p></li>
|
||||
<li><p>Work transparently: research as open code using open data</p></li>
|
||||
<li><p>Draw others in: produce reproducible research</p></li>
|
||||
<li><p>Learn by doing</p></li>
|
||||
</ol>
|
||||
</section>
|
||||
<section id="why-programmatic-data-science" class="level2" data-number="1.4">
|
||||
<h2 data-number="1.4" class="anchored" data-anchor-id="why-programmatic-data-science"><span class="header-section-number">1.4</span> Why programmatic data science?</h2>
|
||||
<p>This isn’t just a book about data analysis, I’m proposing an approach which might be thought of as research-as-code, where you write out instructions to execute the various steps of work. The upside of this is that other researchers can learn from your work, correct and build on it as part of the commons. It takes a bit more time to learn and set things up, but the upside is that you’ll gain access to a set of tools and a research philosophy which is much more powerful.</p>
|
||||
</section>
|
||||
<section id="learning-to-code-my-way" class="level2" data-number="1.5">
|
||||
<h2 data-number="1.5" class="anchored" data-anchor-id="learning-to-code-my-way"><span class="header-section-number">1.5</span> Learning to code: my way</h2>
|
||||
<p>Explain accelerated approach in this book, working from examples and providing exposure to concepts in a streamlined way, pointing to other resources</p>
|
||||
<p>Point to other guides,</p>
|
||||
<p>There are a range of terrific textbooks out there which cover all these elements in greater depth and more slowly. In particular, I’d recommend that many readers will want to check out Hadley Wickham’s “R For Data Science” book. I’ll include marginal notes in this guide pointing to sections of that book, and a few others which unpack the basic mechanics of R in more detail.</p>
|
||||
</section>
|
||||
<section id="getting-set-up" class="level2" data-number="1.6">
|
||||
<h2 data-number="1.6" class="anchored" data-anchor-id="getting-set-up"><span class="header-section-number">1.6</span> Getting set up</h2>
|
||||
<p>Every single tool, programming language and data set we refer to in this book is free and open source. These tools have been produced by professionals and volunteers who are passionate about data science and research and want to share it with the world, and in order to do this (and following the “hacker way”) they’ve made these tools freely available. This also means that you aren’t restricted to a specific proprietary, expensive, or unavailable piece of software to do this work. I’ll make a few opinionated recommendations here based on my own preferences and experience, but it’s really up to your own style and approach. In fact, given that this is an open source textbook, you can even propose additions to this chapter explaining other tools you’ve found that you want to share with others.</p>
|
||||
<p>There are, right now, primarily two languages that statisticians and data scientists use for this kind of programmatic data science: python and R. Each language has its merits and I won’t rehash the debates between various factions. For this book, we’ll be using the R language. This is, in part, because the R user community and libraries tend to scale a bit better for the work that I’m commending in this book. However, it’s entirely possible that one could use python for all these exercises, and perhaps in the future we’ll have volume two of this book outlining python approaches to the same operations.</p>
|
||||
<p>Bearing this in mind, the first step you’ll need to take is to download and install R. You can find instructions and install packages for a wide range of hardware on the The Comprehensive R Archive Network (or “CRAN”): https://cran.rstudio.com. Once you’ve installed R, you’ve got some choices to make about the kind of programming environment you’d like to use. You can just use a plain text editor like <code>textedit</code> to write your code and then execute your programs using the R software you’ve just installed. However, most users, myself included, tend to use an integrated development environment (or “IDE”). This is usually another software package with a guided user interface and some visual elements that make it faster to write and test your code. Some IDE packages, will have built-in reference tools so you can look up options for libraries you use in your code, they will allow you to visualise the results of your code execution, and perhaps most important of all, will enable you to execute your programs line by line so you can spot errors more quickly (we call this “debugging”). The two most popular IDE platforms for R coding at the time of writing this textbook are RStudio and Visual Studio. You should download and try out both and stick with your favourite, as the differences are largely aesthetic. I use a combination of RStudio and an enhanced plain text editor Sublime Text for my coding.</p>
|
||||
<p>Once you have R and your pick of an IDE, you are ready to go! Proceed to the next chapter and we’ll dive right in and get started!</p>
|
||||
</section>
|
||||
<section id="other-useful-guides" class="level2" data-number="1.7">
|
||||
<h2 data-number="1.7" class="anchored" data-anchor-id="other-useful-guides"><span class="header-section-number">1.7</span> Other useful guides:</h2>
|
||||
<p><a href="https://r4ds.hadley.nz/">R For Data Science 2e</a> <a href="https://melaniewalsh.github.io/Intro-Cultural-Analytics/welcome.html">Intro to Cultural Analytics and Python</a> <a href="https://datasciencebox.org/01-overview">Data Science in a Box</a></p>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
</main> <!-- /main -->
|
||||
<script id="quarto-html-after-body" type="application/javascript">
|
||||
window.document.addEventListener("DOMContentLoaded", function (event) {
|
||||
const toggleBodyColorMode = (bsSheetEl) => {
|
||||
const mode = bsSheetEl.getAttribute("data-mode");
|
||||
const bodyEl = window.document.querySelector("body");
|
||||
if (mode === "dark") {
|
||||
bodyEl.classList.add("quarto-dark");
|
||||
bodyEl.classList.remove("quarto-light");
|
||||
} else {
|
||||
bodyEl.classList.add("quarto-light");
|
||||
bodyEl.classList.remove("quarto-dark");
|
||||
}
|
||||
}
|
||||
const toggleBodyColorPrimary = () => {
|
||||
const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
|
||||
if (bsSheetEl) {
|
||||
toggleBodyColorMode(bsSheetEl);
|
||||
}
|
||||
}
|
||||
toggleBodyColorPrimary();
|
||||
const icon = "";
|
||||
const anchorJS = new window.AnchorJS();
|
||||
anchorJS.options = {
|
||||
placement: 'right',
|
||||
icon: icon
|
||||
};
|
||||
anchorJS.add('.anchored');
|
||||
const isCodeAnnotation = (el) => {
|
||||
for (const clz of el.classList) {
|
||||
if (clz.startsWith('code-annotation-')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const clipboard = new window.ClipboardJS('.code-copy-button', {
|
||||
text: function(trigger) {
|
||||
const codeEl = trigger.previousElementSibling.cloneNode(true);
|
||||
for (const childEl of codeEl.children) {
|
||||
if (isCodeAnnotation(childEl)) {
|
||||
childEl.remove();
|
||||
}
|
||||
}
|
||||
return codeEl.innerText;
|
||||
}
|
||||
});
|
||||
clipboard.on('success', function(e) {
|
||||
// button target
|
||||
const button = e.trigger;
|
||||
// don't keep focus
|
||||
button.blur();
|
||||
// flash "checked"
|
||||
button.classList.add('code-copy-button-checked');
|
||||
var currentTitle = button.getAttribute("title");
|
||||
button.setAttribute("title", "Copied!");
|
||||
let tooltip;
|
||||
if (window.bootstrap) {
|
||||
button.setAttribute("data-bs-toggle", "tooltip");
|
||||
button.setAttribute("data-bs-placement", "left");
|
||||
button.setAttribute("data-bs-title", "Copied!");
|
||||
tooltip = new bootstrap.Tooltip(button,
|
||||
{ trigger: "manual",
|
||||
customClass: "code-copy-button-tooltip",
|
||||
offset: [0, -8]});
|
||||
tooltip.show();
|
||||
}
|
||||
setTimeout(function() {
|
||||
if (tooltip) {
|
||||
tooltip.hide();
|
||||
button.removeAttribute("data-bs-title");
|
||||
button.removeAttribute("data-bs-toggle");
|
||||
button.removeAttribute("data-bs-placement");
|
||||
}
|
||||
button.setAttribute("title", currentTitle);
|
||||
button.classList.remove('code-copy-button-checked');
|
||||
}, 1000);
|
||||
// clear code selection
|
||||
e.clearSelection();
|
||||
});
|
||||
function tippyHover(el, contentFn) {
|
||||
const config = {
|
||||
allowHTML: true,
|
||||
content: contentFn,
|
||||
maxWidth: 500,
|
||||
delay: 100,
|
||||
arrow: false,
|
||||
appendTo: function(el) {
|
||||
return el.parentElement;
|
||||
},
|
||||
interactive: true,
|
||||
interactiveBorder: 10,
|
||||
theme: 'quarto',
|
||||
placement: 'bottom-start'
|
||||
};
|
||||
window.tippy(el, config);
|
||||
}
|
||||
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
|
||||
for (var i=0; i<noterefs.length; i++) {
|
||||
const ref = noterefs[i];
|
||||
tippyHover(ref, function() {
|
||||
// use id or data attribute instead here
|
||||
let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
|
||||
try { href = new URL(href).hash; } catch {}
|
||||
const id = href.replace(/^#\/?/, "");
|
||||
const note = window.document.getElementById(id);
|
||||
return note.innerHTML;
|
||||
});
|
||||
}
|
||||
let selectedAnnoteEl;
|
||||
const selectorForAnnotation = ( cell, annotation) => {
|
||||
let cellAttr = 'data-code-cell="' + cell + '"';
|
||||
let lineAttr = 'data-code-annotation="' + annotation + '"';
|
||||
const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
|
||||
return selector;
|
||||
}
|
||||
const selectCodeLines = (annoteEl) => {
|
||||
const doc = window.document;
|
||||
const targetCell = annoteEl.getAttribute("data-target-cell");
|
||||
const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
|
||||
const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
|
||||
const lines = annoteSpan.getAttribute("data-code-lines").split(",");
|
||||
const lineIds = lines.map((line) => {
|
||||
return targetCell + "-" + line;
|
||||
})
|
||||
let top = null;
|
||||
let height = null;
|
||||
let parent = null;
|
||||
if (lineIds.length > 0) {
|
||||
//compute the position of the single el (top and bottom and make a div)
|
||||
const el = window.document.getElementById(lineIds[0]);
|
||||
top = el.offsetTop;
|
||||
height = el.offsetHeight;
|
||||
parent = el.parentElement.parentElement;
|
||||
if (lineIds.length > 1) {
|
||||
const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
|
||||
const bottom = lastEl.offsetTop + lastEl.offsetHeight;
|
||||
height = bottom - top;
|
||||
}
|
||||
if (top !== null && height !== null && parent !== null) {
|
||||
// cook up a div (if necessary) and position it
|
||||
let div = window.document.getElementById("code-annotation-line-highlight");
|
||||
if (div === null) {
|
||||
div = window.document.createElement("div");
|
||||
div.setAttribute("id", "code-annotation-line-highlight");
|
||||
div.style.position = 'absolute';
|
||||
parent.appendChild(div);
|
||||
}
|
||||
div.style.top = top - 2 + "px";
|
||||
div.style.height = height + 4 + "px";
|
||||
let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
|
||||
if (gutterDiv === null) {
|
||||
gutterDiv = window.document.createElement("div");
|
||||
gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
|
||||
gutterDiv.style.position = 'absolute';
|
||||
const codeCell = window.document.getElementById(targetCell);
|
||||
const gutter = codeCell.querySelector('.code-annotation-gutter');
|
||||
gutter.appendChild(gutterDiv);
|
||||
}
|
||||
gutterDiv.style.top = top - 2 + "px";
|
||||
gutterDiv.style.height = height + 4 + "px";
|
||||
}
|
||||
selectedAnnoteEl = annoteEl;
|
||||
}
|
||||
};
|
||||
const unselectCodeLines = () => {
|
||||
const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
|
||||
elementsIds.forEach((elId) => {
|
||||
const div = window.document.getElementById(elId);
|
||||
if (div) {
|
||||
div.remove();
|
||||
}
|
||||
});
|
||||
selectedAnnoteEl = undefined;
|
||||
};
|
||||
// Attach click handler to the DT
|
||||
const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
|
||||
for (const annoteDlNode of annoteDls) {
|
||||
annoteDlNode.addEventListener('click', (event) => {
|
||||
const clickedEl = event.target;
|
||||
if (clickedEl !== selectedAnnoteEl) {
|
||||
unselectCodeLines();
|
||||
const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
|
||||
if (activeEl) {
|
||||
activeEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
selectCodeLines(clickedEl);
|
||||
clickedEl.classList.add('code-annotation-active');
|
||||
} else {
|
||||
// Unselect the line
|
||||
unselectCodeLines();
|
||||
clickedEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
});
|
||||
}
|
||||
const findCites = (el) => {
|
||||
const parentEl = el.parentElement;
|
||||
if (parentEl) {
|
||||
const cites = parentEl.dataset.cites;
|
||||
if (cites) {
|
||||
return {
|
||||
el,
|
||||
cites: cites.split(' ')
|
||||
};
|
||||
} else {
|
||||
return findCites(el.parentElement)
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
|
||||
for (var i=0; i<bibliorefs.length; i++) {
|
||||
const ref = bibliorefs[i];
|
||||
const citeInfo = findCites(ref);
|
||||
if (citeInfo) {
|
||||
tippyHover(citeInfo.el, function() {
|
||||
var popup = window.document.createElement('div');
|
||||
citeInfo.cites.forEach(function(cite) {
|
||||
var citeDiv = window.document.createElement('div');
|
||||
citeDiv.classList.add('hanging-indent');
|
||||
citeDiv.classList.add('csl-entry');
|
||||
var biblioDiv = window.document.getElementById('ref-' + cite);
|
||||
if (biblioDiv) {
|
||||
citeDiv.innerHTML = biblioDiv.innerHTML;
|
||||
}
|
||||
popup.appendChild(citeDiv);
|
||||
});
|
||||
return popup.innerHTML;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<nav class="page-navigation">
|
||||
<div class="nav-page nav-page-previous">
|
||||
<a href="./index.html" class="pagination-link">
|
||||
<i class="bi bi-arrow-left-short"></i> <span class="nav-page-text">Preface</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-page nav-page-next">
|
||||
<a href="./chapter_1.html" class="pagination-link">
|
||||
<span class="nav-page-text"><span class="chapter-number">2</span> <span class="chapter-title">The 2021 UK Census</span></span> <i class="bi bi-arrow-right-short"></i>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div> <!-- /content -->
|
||||
|
||||
|
||||
|
||||
</body></html>
|
449
hacking_religion/_book/references.html
Normal file
449
hacking_religion/_book/references.html
Normal file
|
@ -0,0 +1,449 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="generator" content="quarto-1.3.450">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
|
||||
|
||||
<title>Hacking Religion: TRS & Data Science in Action - References</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
|
||||
vertical-align: middle;
|
||||
}
|
||||
/* CSS for citations */
|
||||
div.csl-bib-body { }
|
||||
div.csl-entry {
|
||||
clear: both;
|
||||
}
|
||||
.hanging-indent div.csl-entry {
|
||||
margin-left:2em;
|
||||
text-indent:-2em;
|
||||
}
|
||||
div.csl-left-margin {
|
||||
min-width:2em;
|
||||
float:left;
|
||||
}
|
||||
div.csl-right-inline {
|
||||
margin-left:2em;
|
||||
padding-left:1em;
|
||||
}
|
||||
div.csl-indent {
|
||||
margin-left: 2em;
|
||||
}</style>
|
||||
|
||||
|
||||
<script src="site_libs/quarto-nav/quarto-nav.js"></script>
|
||||
<script src="site_libs/quarto-nav/headroom.min.js"></script>
|
||||
<script src="site_libs/clipboard/clipboard.min.js"></script>
|
||||
<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
|
||||
<script src="site_libs/quarto-search/fuse.min.js"></script>
|
||||
<script src="site_libs/quarto-search/quarto-search.js"></script>
|
||||
<meta name="quarto:offset" content="./">
|
||||
<link href="./summary.html" rel="prev">
|
||||
<script src="site_libs/quarto-html/quarto.js"></script>
|
||||
<script src="site_libs/quarto-html/popper.min.js"></script>
|
||||
<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
|
||||
<script src="site_libs/quarto-html/anchor.min.js"></script>
|
||||
<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
|
||||
<link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
|
||||
<script src="site_libs/bootstrap/bootstrap.min.js"></script>
|
||||
<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
|
||||
<script id="quarto-search-options" type="application/json">{
|
||||
"location": "sidebar",
|
||||
"copy-button": false,
|
||||
"collapse-after": 3,
|
||||
"panel-placement": "start",
|
||||
"type": "textbox",
|
||||
"limit": 20,
|
||||
"language": {
|
||||
"search-no-results-text": "No results",
|
||||
"search-matching-documents-text": "matching documents",
|
||||
"search-copy-link-title": "Copy link to search",
|
||||
"search-hide-matches-text": "Hide additional matches",
|
||||
"search-more-match-text": "more match in this document",
|
||||
"search-more-matches-text": "more matches in this document",
|
||||
"search-clear-button-title": "Clear",
|
||||
"search-detached-cancel-button-title": "Cancel",
|
||||
"search-submit-button-title": "Submit",
|
||||
"search-label": "Search"
|
||||
}
|
||||
}</script>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="nav-sidebar floating">
|
||||
|
||||
<div id="quarto-search-results"></div>
|
||||
<header id="quarto-header" class="headroom fixed-top">
|
||||
<nav class="quarto-secondary-nav">
|
||||
<div class="container-fluid d-flex">
|
||||
<button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
<i class="bi bi-layout-text-sidebar-reverse"></i>
|
||||
</button>
|
||||
<nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="./references.html">References</a></li></ol></nav>
|
||||
<a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
</a>
|
||||
<button type="button" class="btn quarto-search-button" aria-label="" onclick="window.quartoOpenSearch();">
|
||||
<i class="bi bi-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<!-- content -->
|
||||
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article">
|
||||
<!-- sidebar -->
|
||||
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal sidebar-navigation floating overflow-auto">
|
||||
<div class="pt-lg-2 mt-2 text-left sidebar-header">
|
||||
<div class="sidebar-title mb-0 py-0">
|
||||
<a href="./">Hacking Religion: TRS & Data Science in Action</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 flex-shrink-0 align-items-center">
|
||||
<div class="sidebar-search">
|
||||
<div id="quarto-search" class="" title="Search"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-menu-container">
|
||||
<ul class="list-unstyled mt-1">
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./index.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">Preface</span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./intro.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">1</span> <span class="chapter-title">Introduction: Hacking Religion</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_1.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">2</span> <span class="chapter-title">The 2021 UK Census</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_2.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">3</span> <span class="chapter-title">Survey Data: Spotlight Project</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_3.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">4</span> <span class="chapter-title">Mapping churches: geospatial data science</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_4.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">5</span> <span class="chapter-title">Data scraping, corpus analysis and wordclouds</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./summary.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">6</span> <span class="chapter-title">Summary</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./references.html" class="sidebar-item-text sidebar-link active">
|
||||
<span class="menu-text">References</span></a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="quarto-sidebar-glass" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass"></div>
|
||||
<!-- margin-sidebar -->
|
||||
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
|
||||
|
||||
</div>
|
||||
<!-- main -->
|
||||
<main class="content" id="quarto-document-content">
|
||||
|
||||
<header id="title-block-header" class="quarto-title-block default">
|
||||
<div class="quarto-title">
|
||||
<h1 class="title">References</h1>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="quarto-title-meta">
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<div id="refs" role="list" style="display: none">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</main> <!-- /main -->
|
||||
<script id="quarto-html-after-body" type="application/javascript">
|
||||
window.document.addEventListener("DOMContentLoaded", function (event) {
|
||||
const toggleBodyColorMode = (bsSheetEl) => {
|
||||
const mode = bsSheetEl.getAttribute("data-mode");
|
||||
const bodyEl = window.document.querySelector("body");
|
||||
if (mode === "dark") {
|
||||
bodyEl.classList.add("quarto-dark");
|
||||
bodyEl.classList.remove("quarto-light");
|
||||
} else {
|
||||
bodyEl.classList.add("quarto-light");
|
||||
bodyEl.classList.remove("quarto-dark");
|
||||
}
|
||||
}
|
||||
const toggleBodyColorPrimary = () => {
|
||||
const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
|
||||
if (bsSheetEl) {
|
||||
toggleBodyColorMode(bsSheetEl);
|
||||
}
|
||||
}
|
||||
toggleBodyColorPrimary();
|
||||
const icon = "";
|
||||
const anchorJS = new window.AnchorJS();
|
||||
anchorJS.options = {
|
||||
placement: 'right',
|
||||
icon: icon
|
||||
};
|
||||
anchorJS.add('.anchored');
|
||||
const isCodeAnnotation = (el) => {
|
||||
for (const clz of el.classList) {
|
||||
if (clz.startsWith('code-annotation-')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const clipboard = new window.ClipboardJS('.code-copy-button', {
|
||||
text: function(trigger) {
|
||||
const codeEl = trigger.previousElementSibling.cloneNode(true);
|
||||
for (const childEl of codeEl.children) {
|
||||
if (isCodeAnnotation(childEl)) {
|
||||
childEl.remove();
|
||||
}
|
||||
}
|
||||
return codeEl.innerText;
|
||||
}
|
||||
});
|
||||
clipboard.on('success', function(e) {
|
||||
// button target
|
||||
const button = e.trigger;
|
||||
// don't keep focus
|
||||
button.blur();
|
||||
// flash "checked"
|
||||
button.classList.add('code-copy-button-checked');
|
||||
var currentTitle = button.getAttribute("title");
|
||||
button.setAttribute("title", "Copied!");
|
||||
let tooltip;
|
||||
if (window.bootstrap) {
|
||||
button.setAttribute("data-bs-toggle", "tooltip");
|
||||
button.setAttribute("data-bs-placement", "left");
|
||||
button.setAttribute("data-bs-title", "Copied!");
|
||||
tooltip = new bootstrap.Tooltip(button,
|
||||
{ trigger: "manual",
|
||||
customClass: "code-copy-button-tooltip",
|
||||
offset: [0, -8]});
|
||||
tooltip.show();
|
||||
}
|
||||
setTimeout(function() {
|
||||
if (tooltip) {
|
||||
tooltip.hide();
|
||||
button.removeAttribute("data-bs-title");
|
||||
button.removeAttribute("data-bs-toggle");
|
||||
button.removeAttribute("data-bs-placement");
|
||||
}
|
||||
button.setAttribute("title", currentTitle);
|
||||
button.classList.remove('code-copy-button-checked');
|
||||
}, 1000);
|
||||
// clear code selection
|
||||
e.clearSelection();
|
||||
});
|
||||
function tippyHover(el, contentFn) {
|
||||
const config = {
|
||||
allowHTML: true,
|
||||
content: contentFn,
|
||||
maxWidth: 500,
|
||||
delay: 100,
|
||||
arrow: false,
|
||||
appendTo: function(el) {
|
||||
return el.parentElement;
|
||||
},
|
||||
interactive: true,
|
||||
interactiveBorder: 10,
|
||||
theme: 'quarto',
|
||||
placement: 'bottom-start'
|
||||
};
|
||||
window.tippy(el, config);
|
||||
}
|
||||
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
|
||||
for (var i=0; i<noterefs.length; i++) {
|
||||
const ref = noterefs[i];
|
||||
tippyHover(ref, function() {
|
||||
// use id or data attribute instead here
|
||||
let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
|
||||
try { href = new URL(href).hash; } catch {}
|
||||
const id = href.replace(/^#\/?/, "");
|
||||
const note = window.document.getElementById(id);
|
||||
return note.innerHTML;
|
||||
});
|
||||
}
|
||||
let selectedAnnoteEl;
|
||||
const selectorForAnnotation = ( cell, annotation) => {
|
||||
let cellAttr = 'data-code-cell="' + cell + '"';
|
||||
let lineAttr = 'data-code-annotation="' + annotation + '"';
|
||||
const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
|
||||
return selector;
|
||||
}
|
||||
const selectCodeLines = (annoteEl) => {
|
||||
const doc = window.document;
|
||||
const targetCell = annoteEl.getAttribute("data-target-cell");
|
||||
const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
|
||||
const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
|
||||
const lines = annoteSpan.getAttribute("data-code-lines").split(",");
|
||||
const lineIds = lines.map((line) => {
|
||||
return targetCell + "-" + line;
|
||||
})
|
||||
let top = null;
|
||||
let height = null;
|
||||
let parent = null;
|
||||
if (lineIds.length > 0) {
|
||||
//compute the position of the single el (top and bottom and make a div)
|
||||
const el = window.document.getElementById(lineIds[0]);
|
||||
top = el.offsetTop;
|
||||
height = el.offsetHeight;
|
||||
parent = el.parentElement.parentElement;
|
||||
if (lineIds.length > 1) {
|
||||
const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
|
||||
const bottom = lastEl.offsetTop + lastEl.offsetHeight;
|
||||
height = bottom - top;
|
||||
}
|
||||
if (top !== null && height !== null && parent !== null) {
|
||||
// cook up a div (if necessary) and position it
|
||||
let div = window.document.getElementById("code-annotation-line-highlight");
|
||||
if (div === null) {
|
||||
div = window.document.createElement("div");
|
||||
div.setAttribute("id", "code-annotation-line-highlight");
|
||||
div.style.position = 'absolute';
|
||||
parent.appendChild(div);
|
||||
}
|
||||
div.style.top = top - 2 + "px";
|
||||
div.style.height = height + 4 + "px";
|
||||
let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
|
||||
if (gutterDiv === null) {
|
||||
gutterDiv = window.document.createElement("div");
|
||||
gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
|
||||
gutterDiv.style.position = 'absolute';
|
||||
const codeCell = window.document.getElementById(targetCell);
|
||||
const gutter = codeCell.querySelector('.code-annotation-gutter');
|
||||
gutter.appendChild(gutterDiv);
|
||||
}
|
||||
gutterDiv.style.top = top - 2 + "px";
|
||||
gutterDiv.style.height = height + 4 + "px";
|
||||
}
|
||||
selectedAnnoteEl = annoteEl;
|
||||
}
|
||||
};
|
||||
const unselectCodeLines = () => {
|
||||
const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
|
||||
elementsIds.forEach((elId) => {
|
||||
const div = window.document.getElementById(elId);
|
||||
if (div) {
|
||||
div.remove();
|
||||
}
|
||||
});
|
||||
selectedAnnoteEl = undefined;
|
||||
};
|
||||
// Attach click handler to the DT
|
||||
const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
|
||||
for (const annoteDlNode of annoteDls) {
|
||||
annoteDlNode.addEventListener('click', (event) => {
|
||||
const clickedEl = event.target;
|
||||
if (clickedEl !== selectedAnnoteEl) {
|
||||
unselectCodeLines();
|
||||
const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
|
||||
if (activeEl) {
|
||||
activeEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
selectCodeLines(clickedEl);
|
||||
clickedEl.classList.add('code-annotation-active');
|
||||
} else {
|
||||
// Unselect the line
|
||||
unselectCodeLines();
|
||||
clickedEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
});
|
||||
}
|
||||
const findCites = (el) => {
|
||||
const parentEl = el.parentElement;
|
||||
if (parentEl) {
|
||||
const cites = parentEl.dataset.cites;
|
||||
if (cites) {
|
||||
return {
|
||||
el,
|
||||
cites: cites.split(' ')
|
||||
};
|
||||
} else {
|
||||
return findCites(el.parentElement)
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
|
||||
for (var i=0; i<bibliorefs.length; i++) {
|
||||
const ref = bibliorefs[i];
|
||||
const citeInfo = findCites(ref);
|
||||
if (citeInfo) {
|
||||
tippyHover(citeInfo.el, function() {
|
||||
var popup = window.document.createElement('div');
|
||||
citeInfo.cites.forEach(function(cite) {
|
||||
var citeDiv = window.document.createElement('div');
|
||||
citeDiv.classList.add('hanging-indent');
|
||||
citeDiv.classList.add('csl-entry');
|
||||
var biblioDiv = window.document.getElementById('ref-' + cite);
|
||||
if (biblioDiv) {
|
||||
citeDiv.innerHTML = biblioDiv.innerHTML;
|
||||
}
|
||||
popup.appendChild(citeDiv);
|
||||
});
|
||||
return popup.innerHTML;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<nav class="page-navigation">
|
||||
<div class="nav-page nav-page-previous">
|
||||
<a href="./summary.html" class="pagination-link">
|
||||
<i class="bi bi-arrow-left-short"></i> <span class="nav-page-text"><span class="chapter-number">6</span> <span class="chapter-title">Summary</span></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-page nav-page-next">
|
||||
</div>
|
||||
</nav>
|
||||
</div> <!-- /content -->
|
||||
|
||||
|
||||
|
||||
</body></html>
|
100
hacking_religion/_book/search.json
Normal file
100
hacking_religion/_book/search.json
Normal file
File diff suppressed because one or more lines are too long
2018
hacking_religion/_book/site_libs/bootstrap/bootstrap-icons.css
vendored
Normal file
2018
hacking_religion/_book/site_libs/bootstrap/bootstrap-icons.css
vendored
Normal file
File diff suppressed because it is too large
Load diff
BIN
hacking_religion/_book/site_libs/bootstrap/bootstrap-icons.woff
Normal file
BIN
hacking_religion/_book/site_libs/bootstrap/bootstrap-icons.woff
Normal file
Binary file not shown.
10
hacking_religion/_book/site_libs/bootstrap/bootstrap.min.css
vendored
Normal file
10
hacking_religion/_book/site_libs/bootstrap/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
hacking_religion/_book/site_libs/bootstrap/bootstrap.min.js
vendored
Normal file
7
hacking_religion/_book/site_libs/bootstrap/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
hacking_religion/_book/site_libs/clipboard/clipboard.min.js
vendored
Normal file
7
hacking_religion/_book/site_libs/clipboard/clipboard.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
9
hacking_religion/_book/site_libs/quarto-html/anchor.min.js
vendored
Normal file
9
hacking_religion/_book/site_libs/quarto-html/anchor.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
hacking_religion/_book/site_libs/quarto-html/popper.min.js
vendored
Normal file
6
hacking_religion/_book/site_libs/quarto-html/popper.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,203 @@
|
|||
/* quarto syntax highlight colors */
|
||||
:root {
|
||||
--quarto-hl-ot-color: #003B4F;
|
||||
--quarto-hl-at-color: #657422;
|
||||
--quarto-hl-ss-color: #20794D;
|
||||
--quarto-hl-an-color: #5E5E5E;
|
||||
--quarto-hl-fu-color: #4758AB;
|
||||
--quarto-hl-st-color: #20794D;
|
||||
--quarto-hl-cf-color: #003B4F;
|
||||
--quarto-hl-op-color: #5E5E5E;
|
||||
--quarto-hl-er-color: #AD0000;
|
||||
--quarto-hl-bn-color: #AD0000;
|
||||
--quarto-hl-al-color: #AD0000;
|
||||
--quarto-hl-va-color: #111111;
|
||||
--quarto-hl-bu-color: inherit;
|
||||
--quarto-hl-ex-color: inherit;
|
||||
--quarto-hl-pp-color: #AD0000;
|
||||
--quarto-hl-in-color: #5E5E5E;
|
||||
--quarto-hl-vs-color: #20794D;
|
||||
--quarto-hl-wa-color: #5E5E5E;
|
||||
--quarto-hl-do-color: #5E5E5E;
|
||||
--quarto-hl-im-color: #00769E;
|
||||
--quarto-hl-ch-color: #20794D;
|
||||
--quarto-hl-dt-color: #AD0000;
|
||||
--quarto-hl-fl-color: #AD0000;
|
||||
--quarto-hl-co-color: #5E5E5E;
|
||||
--quarto-hl-cv-color: #5E5E5E;
|
||||
--quarto-hl-cn-color: #8f5902;
|
||||
--quarto-hl-sc-color: #5E5E5E;
|
||||
--quarto-hl-dv-color: #AD0000;
|
||||
--quarto-hl-kw-color: #003B4F;
|
||||
}
|
||||
|
||||
/* other quarto variables */
|
||||
:root {
|
||||
--quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
|
||||
pre > code.sourceCode > span {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
code span {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
code.sourceCode > span {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
div.sourceCode,
|
||||
div.sourceCode pre.sourceCode {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
code span.ot {
|
||||
color: #003B4F;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.at {
|
||||
color: #657422;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.ss {
|
||||
color: #20794D;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.an {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.fu {
|
||||
color: #4758AB;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.st {
|
||||
color: #20794D;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.cf {
|
||||
color: #003B4F;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.op {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.er {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.bn {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.al {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.va {
|
||||
color: #111111;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.bu {
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.ex {
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.pp {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.in {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.vs {
|
||||
color: #20794D;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.wa {
|
||||
color: #5E5E5E;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code span.do {
|
||||
color: #5E5E5E;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code span.im {
|
||||
color: #00769E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.ch {
|
||||
color: #20794D;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.dt {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.fl {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.co {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.cv {
|
||||
color: #5E5E5E;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code span.cn {
|
||||
color: #8f5902;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.sc {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.dv {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
code span.kw {
|
||||
color: #003B4F;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
.prevent-inlining {
|
||||
content: "</";
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=debc5d5d77c3f9108843748ff7464032.css.map */
|
902
hacking_religion/_book/site_libs/quarto-html/quarto.js
Normal file
902
hacking_religion/_book/site_libs/quarto-html/quarto.js
Normal file
|
@ -0,0 +1,902 @@
|
|||
const sectionChanged = new CustomEvent("quarto-sectionChanged", {
|
||||
detail: {},
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
composed: false,
|
||||
});
|
||||
|
||||
const layoutMarginEls = () => {
|
||||
// Find any conflicting margin elements and add margins to the
|
||||
// top to prevent overlap
|
||||
const marginChildren = window.document.querySelectorAll(
|
||||
".column-margin.column-container > * "
|
||||
);
|
||||
|
||||
let lastBottom = 0;
|
||||
for (const marginChild of marginChildren) {
|
||||
if (marginChild.offsetParent !== null) {
|
||||
// clear the top margin so we recompute it
|
||||
marginChild.style.marginTop = null;
|
||||
const top = marginChild.getBoundingClientRect().top + window.scrollY;
|
||||
console.log({
|
||||
childtop: marginChild.getBoundingClientRect().top,
|
||||
scroll: window.scrollY,
|
||||
top,
|
||||
lastBottom,
|
||||
});
|
||||
if (top < lastBottom) {
|
||||
const margin = lastBottom - top;
|
||||
marginChild.style.marginTop = `${margin}px`;
|
||||
}
|
||||
const styles = window.getComputedStyle(marginChild);
|
||||
const marginTop = parseFloat(styles["marginTop"]);
|
||||
|
||||
console.log({
|
||||
top,
|
||||
height: marginChild.getBoundingClientRect().height,
|
||||
marginTop,
|
||||
total: top + marginChild.getBoundingClientRect().height + marginTop,
|
||||
});
|
||||
lastBottom = top + marginChild.getBoundingClientRect().height + marginTop;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.document.addEventListener("DOMContentLoaded", function (_event) {
|
||||
// Recompute the position of margin elements anytime the body size changes
|
||||
if (window.ResizeObserver) {
|
||||
const resizeObserver = new window.ResizeObserver(
|
||||
throttle(layoutMarginEls, 50)
|
||||
);
|
||||
resizeObserver.observe(window.document.body);
|
||||
}
|
||||
|
||||
const tocEl = window.document.querySelector('nav.toc-active[role="doc-toc"]');
|
||||
const sidebarEl = window.document.getElementById("quarto-sidebar");
|
||||
const leftTocEl = window.document.getElementById("quarto-sidebar-toc-left");
|
||||
const marginSidebarEl = window.document.getElementById(
|
||||
"quarto-margin-sidebar"
|
||||
);
|
||||
// function to determine whether the element has a previous sibling that is active
|
||||
const prevSiblingIsActiveLink = (el) => {
|
||||
const sibling = el.previousElementSibling;
|
||||
if (sibling && sibling.tagName === "A") {
|
||||
return sibling.classList.contains("active");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// fire slideEnter for bootstrap tab activations (for htmlwidget resize behavior)
|
||||
function fireSlideEnter(e) {
|
||||
const event = window.document.createEvent("Event");
|
||||
event.initEvent("slideenter", true, true);
|
||||
window.document.dispatchEvent(event);
|
||||
}
|
||||
const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]');
|
||||
tabs.forEach((tab) => {
|
||||
tab.addEventListener("shown.bs.tab", fireSlideEnter);
|
||||
});
|
||||
|
||||
// fire slideEnter for tabby tab activations (for htmlwidget resize behavior)
|
||||
document.addEventListener("tabby", fireSlideEnter, false);
|
||||
|
||||
// Track scrolling and mark TOC links as active
|
||||
// get table of contents and sidebar (bail if we don't have at least one)
|
||||
const tocLinks = tocEl
|
||||
? [...tocEl.querySelectorAll("a[data-scroll-target]")]
|
||||
: [];
|
||||
const makeActive = (link) => tocLinks[link].classList.add("active");
|
||||
const removeActive = (link) => tocLinks[link].classList.remove("active");
|
||||
const removeAllActive = () =>
|
||||
[...Array(tocLinks.length).keys()].forEach((link) => removeActive(link));
|
||||
|
||||
// activate the anchor for a section associated with this TOC entry
|
||||
tocLinks.forEach((link) => {
|
||||
link.addEventListener("click", () => {
|
||||
if (link.href.indexOf("#") !== -1) {
|
||||
const anchor = link.href.split("#")[1];
|
||||
const heading = window.document.querySelector(
|
||||
`[data-anchor-id=${anchor}]`
|
||||
);
|
||||
if (heading) {
|
||||
// Add the class
|
||||
heading.classList.add("reveal-anchorjs-link");
|
||||
|
||||
// function to show the anchor
|
||||
const handleMouseout = () => {
|
||||
heading.classList.remove("reveal-anchorjs-link");
|
||||
heading.removeEventListener("mouseout", handleMouseout);
|
||||
};
|
||||
|
||||
// add a function to clear the anchor when the user mouses out of it
|
||||
heading.addEventListener("mouseout", handleMouseout);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const sections = tocLinks.map((link) => {
|
||||
const target = link.getAttribute("data-scroll-target");
|
||||
if (target.startsWith("#")) {
|
||||
return window.document.getElementById(decodeURI(`${target.slice(1)}`));
|
||||
} else {
|
||||
return window.document.querySelector(decodeURI(`${target}`));
|
||||
}
|
||||
});
|
||||
|
||||
const sectionMargin = 200;
|
||||
let currentActive = 0;
|
||||
// track whether we've initialized state the first time
|
||||
let init = false;
|
||||
|
||||
const updateActiveLink = () => {
|
||||
// The index from bottom to top (e.g. reversed list)
|
||||
let sectionIndex = -1;
|
||||
if (
|
||||
window.innerHeight + window.pageYOffset >=
|
||||
window.document.body.offsetHeight
|
||||
) {
|
||||
sectionIndex = 0;
|
||||
} else {
|
||||
sectionIndex = [...sections].reverse().findIndex((section) => {
|
||||
if (section) {
|
||||
return window.pageYOffset >= section.offsetTop - sectionMargin;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (sectionIndex > -1) {
|
||||
const current = sections.length - sectionIndex - 1;
|
||||
if (current !== currentActive) {
|
||||
removeAllActive();
|
||||
currentActive = current;
|
||||
makeActive(current);
|
||||
if (init) {
|
||||
window.dispatchEvent(sectionChanged);
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const inHiddenRegion = (top, bottom, hiddenRegions) => {
|
||||
for (const region of hiddenRegions) {
|
||||
if (top <= region.bottom && bottom >= region.top) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const categorySelector = "header.quarto-title-block .quarto-category";
|
||||
const activateCategories = (href) => {
|
||||
// Find any categories
|
||||
// Surround them with a link pointing back to:
|
||||
// #category=Authoring
|
||||
try {
|
||||
const categoryEls = window.document.querySelectorAll(categorySelector);
|
||||
for (const categoryEl of categoryEls) {
|
||||
const categoryText = categoryEl.textContent;
|
||||
if (categoryText) {
|
||||
const link = `${href}#category=${encodeURIComponent(categoryText)}`;
|
||||
const linkEl = window.document.createElement("a");
|
||||
linkEl.setAttribute("href", link);
|
||||
for (const child of categoryEl.childNodes) {
|
||||
linkEl.append(child);
|
||||
}
|
||||
categoryEl.appendChild(linkEl);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Ignore errors
|
||||
}
|
||||
};
|
||||
function hasTitleCategories() {
|
||||
return window.document.querySelector(categorySelector) !== null;
|
||||
}
|
||||
|
||||
function offsetRelativeUrl(url) {
|
||||
const offset = getMeta("quarto:offset");
|
||||
return offset ? offset + url : url;
|
||||
}
|
||||
|
||||
function offsetAbsoluteUrl(url) {
|
||||
const offset = getMeta("quarto:offset");
|
||||
const baseUrl = new URL(offset, window.location);
|
||||
|
||||
const projRelativeUrl = url.replace(baseUrl, "");
|
||||
if (projRelativeUrl.startsWith("/")) {
|
||||
return projRelativeUrl;
|
||||
} else {
|
||||
return "/" + projRelativeUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// read a meta tag value
|
||||
function getMeta(metaName) {
|
||||
const metas = window.document.getElementsByTagName("meta");
|
||||
for (let i = 0; i < metas.length; i++) {
|
||||
if (metas[i].getAttribute("name") === metaName) {
|
||||
return metas[i].getAttribute("content");
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
async function findAndActivateCategories() {
|
||||
const currentPagePath = offsetAbsoluteUrl(window.location.href);
|
||||
const response = await fetch(offsetRelativeUrl("listings.json"));
|
||||
if (response.status == 200) {
|
||||
return response.json().then(function (listingPaths) {
|
||||
const listingHrefs = [];
|
||||
for (const listingPath of listingPaths) {
|
||||
const pathWithoutLeadingSlash = listingPath.listing.substring(1);
|
||||
for (const item of listingPath.items) {
|
||||
if (
|
||||
item === currentPagePath ||
|
||||
item === currentPagePath + "index.html"
|
||||
) {
|
||||
// Resolve this path against the offset to be sure
|
||||
// we already are using the correct path to the listing
|
||||
// (this adjusts the listing urls to be rooted against
|
||||
// whatever root the page is actually running against)
|
||||
const relative = offsetRelativeUrl(pathWithoutLeadingSlash);
|
||||
const baseUrl = window.location;
|
||||
const resolvedPath = new URL(relative, baseUrl);
|
||||
listingHrefs.push(resolvedPath.pathname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look up the tree for a nearby linting and use that if we find one
|
||||
const nearestListing = findNearestParentListing(
|
||||
offsetAbsoluteUrl(window.location.pathname),
|
||||
listingHrefs
|
||||
);
|
||||
if (nearestListing) {
|
||||
activateCategories(nearestListing);
|
||||
} else {
|
||||
// See if the referrer is a listing page for this item
|
||||
const referredRelativePath = offsetAbsoluteUrl(document.referrer);
|
||||
const referrerListing = listingHrefs.find((listingHref) => {
|
||||
const isListingReferrer =
|
||||
listingHref === referredRelativePath ||
|
||||
listingHref === referredRelativePath + "index.html";
|
||||
return isListingReferrer;
|
||||
});
|
||||
|
||||
if (referrerListing) {
|
||||
// Try to use the referrer if possible
|
||||
activateCategories(referrerListing);
|
||||
} else if (listingHrefs.length > 0) {
|
||||
// Otherwise, just fall back to the first listing
|
||||
activateCategories(listingHrefs[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (hasTitleCategories()) {
|
||||
findAndActivateCategories();
|
||||
}
|
||||
|
||||
const findNearestParentListing = (href, listingHrefs) => {
|
||||
if (!href || !listingHrefs) {
|
||||
return undefined;
|
||||
}
|
||||
// Look up the tree for a nearby linting and use that if we find one
|
||||
const relativeParts = href.substring(1).split("/");
|
||||
while (relativeParts.length > 0) {
|
||||
const path = relativeParts.join("/");
|
||||
for (const listingHref of listingHrefs) {
|
||||
if (listingHref.startsWith(path)) {
|
||||
return listingHref;
|
||||
}
|
||||
}
|
||||
relativeParts.pop();
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const manageSidebarVisiblity = (el, placeholderDescriptor) => {
|
||||
let isVisible = true;
|
||||
let elRect;
|
||||
|
||||
return (hiddenRegions) => {
|
||||
if (el === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the last element of the TOC
|
||||
const lastChildEl = el.lastElementChild;
|
||||
|
||||
if (lastChildEl) {
|
||||
// Converts the sidebar to a menu
|
||||
const convertToMenu = () => {
|
||||
for (const child of el.children) {
|
||||
child.style.opacity = 0;
|
||||
child.style.overflow = "hidden";
|
||||
}
|
||||
|
||||
nexttick(() => {
|
||||
const toggleContainer = window.document.createElement("div");
|
||||
toggleContainer.style.width = "100%";
|
||||
toggleContainer.classList.add("zindex-over-content");
|
||||
toggleContainer.classList.add("quarto-sidebar-toggle");
|
||||
toggleContainer.classList.add("headroom-target"); // Marks this to be managed by headeroom
|
||||
toggleContainer.id = placeholderDescriptor.id;
|
||||
toggleContainer.style.position = "fixed";
|
||||
|
||||
const toggleIcon = window.document.createElement("i");
|
||||
toggleIcon.classList.add("quarto-sidebar-toggle-icon");
|
||||
toggleIcon.classList.add("bi");
|
||||
toggleIcon.classList.add("bi-caret-down-fill");
|
||||
|
||||
const toggleTitle = window.document.createElement("div");
|
||||
const titleEl = window.document.body.querySelector(
|
||||
placeholderDescriptor.titleSelector
|
||||
);
|
||||
if (titleEl) {
|
||||
toggleTitle.append(
|
||||
titleEl.textContent || titleEl.innerText,
|
||||
toggleIcon
|
||||
);
|
||||
}
|
||||
toggleTitle.classList.add("zindex-over-content");
|
||||
toggleTitle.classList.add("quarto-sidebar-toggle-title");
|
||||
toggleContainer.append(toggleTitle);
|
||||
|
||||
const toggleContents = window.document.createElement("div");
|
||||
toggleContents.classList = el.classList;
|
||||
toggleContents.classList.add("zindex-over-content");
|
||||
toggleContents.classList.add("quarto-sidebar-toggle-contents");
|
||||
for (const child of el.children) {
|
||||
if (child.id === "toc-title") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const clone = child.cloneNode(true);
|
||||
clone.style.opacity = 1;
|
||||
clone.style.display = null;
|
||||
toggleContents.append(clone);
|
||||
}
|
||||
toggleContents.style.height = "0px";
|
||||
const positionToggle = () => {
|
||||
// position the element (top left of parent, same width as parent)
|
||||
if (!elRect) {
|
||||
elRect = el.getBoundingClientRect();
|
||||
}
|
||||
toggleContainer.style.left = `${elRect.left}px`;
|
||||
toggleContainer.style.top = `${elRect.top}px`;
|
||||
toggleContainer.style.width = `${elRect.width}px`;
|
||||
};
|
||||
positionToggle();
|
||||
|
||||
toggleContainer.append(toggleContents);
|
||||
el.parentElement.prepend(toggleContainer);
|
||||
|
||||
// Process clicks
|
||||
let tocShowing = false;
|
||||
// Allow the caller to control whether this is dismissed
|
||||
// when it is clicked (e.g. sidebar navigation supports
|
||||
// opening and closing the nav tree, so don't dismiss on click)
|
||||
const clickEl = placeholderDescriptor.dismissOnClick
|
||||
? toggleContainer
|
||||
: toggleTitle;
|
||||
|
||||
const closeToggle = () => {
|
||||
if (tocShowing) {
|
||||
toggleContainer.classList.remove("expanded");
|
||||
toggleContents.style.height = "0px";
|
||||
tocShowing = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Get rid of any expanded toggle if the user scrolls
|
||||
window.document.addEventListener(
|
||||
"scroll",
|
||||
throttle(() => {
|
||||
closeToggle();
|
||||
}, 50)
|
||||
);
|
||||
|
||||
// Handle positioning of the toggle
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
throttle(() => {
|
||||
elRect = undefined;
|
||||
positionToggle();
|
||||
}, 50)
|
||||
);
|
||||
|
||||
window.addEventListener("quarto-hrChanged", () => {
|
||||
elRect = undefined;
|
||||
});
|
||||
|
||||
// Process the click
|
||||
clickEl.onclick = () => {
|
||||
if (!tocShowing) {
|
||||
toggleContainer.classList.add("expanded");
|
||||
toggleContents.style.height = null;
|
||||
tocShowing = true;
|
||||
} else {
|
||||
closeToggle();
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Converts a sidebar from a menu back to a sidebar
|
||||
const convertToSidebar = () => {
|
||||
for (const child of el.children) {
|
||||
child.style.opacity = 1;
|
||||
child.style.overflow = null;
|
||||
}
|
||||
|
||||
const placeholderEl = window.document.getElementById(
|
||||
placeholderDescriptor.id
|
||||
);
|
||||
if (placeholderEl) {
|
||||
placeholderEl.remove();
|
||||
}
|
||||
|
||||
el.classList.remove("rollup");
|
||||
};
|
||||
|
||||
if (isReaderMode()) {
|
||||
convertToMenu();
|
||||
isVisible = false;
|
||||
} else {
|
||||
// Find the top and bottom o the element that is being managed
|
||||
const elTop = el.offsetTop;
|
||||
const elBottom =
|
||||
elTop + lastChildEl.offsetTop + lastChildEl.offsetHeight;
|
||||
|
||||
if (!isVisible) {
|
||||
// If the element is current not visible reveal if there are
|
||||
// no conflicts with overlay regions
|
||||
if (!inHiddenRegion(elTop, elBottom, hiddenRegions)) {
|
||||
convertToSidebar();
|
||||
isVisible = true;
|
||||
}
|
||||
} else {
|
||||
// If the element is visible, hide it if it conflicts with overlay regions
|
||||
// and insert a placeholder toggle (or if we're in reader mode)
|
||||
if (inHiddenRegion(elTop, elBottom, hiddenRegions)) {
|
||||
convertToMenu();
|
||||
isVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const tabEls = document.querySelectorAll('a[data-bs-toggle="tab"]');
|
||||
for (const tabEl of tabEls) {
|
||||
const id = tabEl.getAttribute("data-bs-target");
|
||||
if (id) {
|
||||
const columnEl = document.querySelector(
|
||||
`${id} .column-margin, .tabset-margin-content`
|
||||
);
|
||||
if (columnEl)
|
||||
tabEl.addEventListener("shown.bs.tab", function (event) {
|
||||
const el = event.srcElement;
|
||||
if (el) {
|
||||
const visibleCls = `${el.id}-margin-content`;
|
||||
// walk up until we find a parent tabset
|
||||
let panelTabsetEl = el.parentElement;
|
||||
while (panelTabsetEl) {
|
||||
if (panelTabsetEl.classList.contains("panel-tabset")) {
|
||||
break;
|
||||
}
|
||||
panelTabsetEl = panelTabsetEl.parentElement;
|
||||
}
|
||||
|
||||
if (panelTabsetEl) {
|
||||
const prevSib = panelTabsetEl.previousElementSibling;
|
||||
if (
|
||||
prevSib &&
|
||||
prevSib.classList.contains("tabset-margin-container")
|
||||
) {
|
||||
const childNodes = prevSib.querySelectorAll(
|
||||
".tabset-margin-content"
|
||||
);
|
||||
for (const childEl of childNodes) {
|
||||
if (childEl.classList.contains(visibleCls)) {
|
||||
childEl.classList.remove("collapse");
|
||||
} else {
|
||||
childEl.classList.add("collapse");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layoutMarginEls();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Manage the visibility of the toc and the sidebar
|
||||
const marginScrollVisibility = manageSidebarVisiblity(marginSidebarEl, {
|
||||
id: "quarto-toc-toggle",
|
||||
titleSelector: "#toc-title",
|
||||
dismissOnClick: true,
|
||||
});
|
||||
const sidebarScrollVisiblity = manageSidebarVisiblity(sidebarEl, {
|
||||
id: "quarto-sidebarnav-toggle",
|
||||
titleSelector: ".title",
|
||||
dismissOnClick: false,
|
||||
});
|
||||
let tocLeftScrollVisibility;
|
||||
if (leftTocEl) {
|
||||
tocLeftScrollVisibility = manageSidebarVisiblity(leftTocEl, {
|
||||
id: "quarto-lefttoc-toggle",
|
||||
titleSelector: "#toc-title",
|
||||
dismissOnClick: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Find the first element that uses formatting in special columns
|
||||
const conflictingEls = window.document.body.querySelectorAll(
|
||||
'[class^="column-"], [class*=" column-"], aside, [class*="margin-caption"], [class*=" margin-caption"], [class*="margin-ref"], [class*=" margin-ref"]'
|
||||
);
|
||||
|
||||
// Filter all the possibly conflicting elements into ones
|
||||
// the do conflict on the left or ride side
|
||||
const arrConflictingEls = Array.from(conflictingEls);
|
||||
const leftSideConflictEls = arrConflictingEls.filter((el) => {
|
||||
if (el.tagName === "ASIDE") {
|
||||
return false;
|
||||
}
|
||||
return Array.from(el.classList).find((className) => {
|
||||
return (
|
||||
className !== "column-body" &&
|
||||
className.startsWith("column-") &&
|
||||
!className.endsWith("right") &&
|
||||
!className.endsWith("container") &&
|
||||
className !== "column-margin"
|
||||
);
|
||||
});
|
||||
});
|
||||
const rightSideConflictEls = arrConflictingEls.filter((el) => {
|
||||
if (el.tagName === "ASIDE") {
|
||||
return true;
|
||||
}
|
||||
|
||||
const hasMarginCaption = Array.from(el.classList).find((className) => {
|
||||
return className == "margin-caption";
|
||||
});
|
||||
if (hasMarginCaption) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Array.from(el.classList).find((className) => {
|
||||
return (
|
||||
className !== "column-body" &&
|
||||
!className.endsWith("container") &&
|
||||
className.startsWith("column-") &&
|
||||
!className.endsWith("left")
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const kOverlapPaddingSize = 10;
|
||||
function toRegions(els) {
|
||||
return els.map((el) => {
|
||||
const boundRect = el.getBoundingClientRect();
|
||||
const top =
|
||||
boundRect.top +
|
||||
document.documentElement.scrollTop -
|
||||
kOverlapPaddingSize;
|
||||
return {
|
||||
top,
|
||||
bottom: top + el.scrollHeight + 2 * kOverlapPaddingSize,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
let hasObserved = false;
|
||||
const visibleItemObserver = (els) => {
|
||||
let visibleElements = [...els];
|
||||
const intersectionObserver = new IntersectionObserver(
|
||||
(entries, _observer) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
if (visibleElements.indexOf(entry.target) === -1) {
|
||||
visibleElements.push(entry.target);
|
||||
}
|
||||
} else {
|
||||
visibleElements = visibleElements.filter((visibleEntry) => {
|
||||
return visibleEntry !== entry;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasObserved) {
|
||||
hideOverlappedSidebars();
|
||||
}
|
||||
hasObserved = true;
|
||||
},
|
||||
{}
|
||||
);
|
||||
els.forEach((el) => {
|
||||
intersectionObserver.observe(el);
|
||||
});
|
||||
|
||||
return {
|
||||
getVisibleEntries: () => {
|
||||
return visibleElements;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const rightElementObserver = visibleItemObserver(rightSideConflictEls);
|
||||
const leftElementObserver = visibleItemObserver(leftSideConflictEls);
|
||||
|
||||
const hideOverlappedSidebars = () => {
|
||||
marginScrollVisibility(toRegions(rightElementObserver.getVisibleEntries()));
|
||||
sidebarScrollVisiblity(toRegions(leftElementObserver.getVisibleEntries()));
|
||||
if (tocLeftScrollVisibility) {
|
||||
tocLeftScrollVisibility(
|
||||
toRegions(leftElementObserver.getVisibleEntries())
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
window.quartoToggleReader = () => {
|
||||
// Applies a slow class (or removes it)
|
||||
// to update the transition speed
|
||||
const slowTransition = (slow) => {
|
||||
const manageTransition = (id, slow) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) {
|
||||
if (slow) {
|
||||
el.classList.add("slow");
|
||||
} else {
|
||||
el.classList.remove("slow");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
manageTransition("TOC", slow);
|
||||
manageTransition("quarto-sidebar", slow);
|
||||
};
|
||||
const readerMode = !isReaderMode();
|
||||
setReaderModeValue(readerMode);
|
||||
|
||||
// If we're entering reader mode, slow the transition
|
||||
if (readerMode) {
|
||||
slowTransition(readerMode);
|
||||
}
|
||||
highlightReaderToggle(readerMode);
|
||||
hideOverlappedSidebars();
|
||||
|
||||
// If we're exiting reader mode, restore the non-slow transition
|
||||
if (!readerMode) {
|
||||
slowTransition(!readerMode);
|
||||
}
|
||||
};
|
||||
|
||||
const highlightReaderToggle = (readerMode) => {
|
||||
const els = document.querySelectorAll(".quarto-reader-toggle");
|
||||
if (els) {
|
||||
els.forEach((el) => {
|
||||
if (readerMode) {
|
||||
el.classList.add("reader");
|
||||
} else {
|
||||
el.classList.remove("reader");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const setReaderModeValue = (val) => {
|
||||
if (window.location.protocol !== "file:") {
|
||||
window.localStorage.setItem("quarto-reader-mode", val);
|
||||
} else {
|
||||
localReaderMode = val;
|
||||
}
|
||||
};
|
||||
|
||||
const isReaderMode = () => {
|
||||
if (window.location.protocol !== "file:") {
|
||||
return window.localStorage.getItem("quarto-reader-mode") === "true";
|
||||
} else {
|
||||
return localReaderMode;
|
||||
}
|
||||
};
|
||||
let localReaderMode = null;
|
||||
|
||||
const tocOpenDepthStr = tocEl?.getAttribute("data-toc-expanded");
|
||||
const tocOpenDepth = tocOpenDepthStr ? Number(tocOpenDepthStr) : 1;
|
||||
|
||||
// Walk the TOC and collapse/expand nodes
|
||||
// Nodes are expanded if:
|
||||
// - they are top level
|
||||
// - they have children that are 'active' links
|
||||
// - they are directly below an link that is 'active'
|
||||
const walk = (el, depth) => {
|
||||
// Tick depth when we enter a UL
|
||||
if (el.tagName === "UL") {
|
||||
depth = depth + 1;
|
||||
}
|
||||
|
||||
// It this is active link
|
||||
let isActiveNode = false;
|
||||
if (el.tagName === "A" && el.classList.contains("active")) {
|
||||
isActiveNode = true;
|
||||
}
|
||||
|
||||
// See if there is an active child to this element
|
||||
let hasActiveChild = false;
|
||||
for (child of el.children) {
|
||||
hasActiveChild = walk(child, depth) || hasActiveChild;
|
||||
}
|
||||
|
||||
// Process the collapse state if this is an UL
|
||||
if (el.tagName === "UL") {
|
||||
if (tocOpenDepth === -1 && depth > 1) {
|
||||
el.classList.add("collapse");
|
||||
} else if (
|
||||
depth <= tocOpenDepth ||
|
||||
hasActiveChild ||
|
||||
prevSiblingIsActiveLink(el)
|
||||
) {
|
||||
el.classList.remove("collapse");
|
||||
} else {
|
||||
el.classList.add("collapse");
|
||||
}
|
||||
|
||||
// untick depth when we leave a UL
|
||||
depth = depth - 1;
|
||||
}
|
||||
return hasActiveChild || isActiveNode;
|
||||
};
|
||||
|
||||
// walk the TOC and expand / collapse any items that should be shown
|
||||
|
||||
if (tocEl) {
|
||||
walk(tocEl, 0);
|
||||
updateActiveLink();
|
||||
}
|
||||
|
||||
// Throttle the scroll event and walk peridiocally
|
||||
window.document.addEventListener(
|
||||
"scroll",
|
||||
throttle(() => {
|
||||
if (tocEl) {
|
||||
updateActiveLink();
|
||||
walk(tocEl, 0);
|
||||
}
|
||||
if (!isReaderMode()) {
|
||||
hideOverlappedSidebars();
|
||||
}
|
||||
}, 5)
|
||||
);
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
throttle(() => {
|
||||
if (!isReaderMode()) {
|
||||
hideOverlappedSidebars();
|
||||
}
|
||||
}, 10)
|
||||
);
|
||||
hideOverlappedSidebars();
|
||||
highlightReaderToggle(isReaderMode());
|
||||
});
|
||||
|
||||
// grouped tabsets
|
||||
window.addEventListener("pageshow", (_event) => {
|
||||
function getTabSettings() {
|
||||
const data = localStorage.getItem("quarto-persistent-tabsets-data");
|
||||
if (!data) {
|
||||
localStorage.setItem("quarto-persistent-tabsets-data", "{}");
|
||||
return {};
|
||||
}
|
||||
if (data) {
|
||||
return JSON.parse(data);
|
||||
}
|
||||
}
|
||||
|
||||
function setTabSettings(data) {
|
||||
localStorage.setItem(
|
||||
"quarto-persistent-tabsets-data",
|
||||
JSON.stringify(data)
|
||||
);
|
||||
}
|
||||
|
||||
function setTabState(groupName, groupValue) {
|
||||
const data = getTabSettings();
|
||||
data[groupName] = groupValue;
|
||||
setTabSettings(data);
|
||||
}
|
||||
|
||||
function toggleTab(tab, active) {
|
||||
const tabPanelId = tab.getAttribute("aria-controls");
|
||||
const tabPanel = document.getElementById(tabPanelId);
|
||||
if (active) {
|
||||
tab.classList.add("active");
|
||||
tabPanel.classList.add("active");
|
||||
} else {
|
||||
tab.classList.remove("active");
|
||||
tabPanel.classList.remove("active");
|
||||
}
|
||||
}
|
||||
|
||||
function toggleAll(selectedGroup, selectorsToSync) {
|
||||
for (const [thisGroup, tabs] of Object.entries(selectorsToSync)) {
|
||||
const active = selectedGroup === thisGroup;
|
||||
for (const tab of tabs) {
|
||||
toggleTab(tab, active);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findSelectorsToSyncByLanguage() {
|
||||
const result = {};
|
||||
const tabs = Array.from(
|
||||
document.querySelectorAll(`div[data-group] a[id^='tabset-']`)
|
||||
);
|
||||
for (const item of tabs) {
|
||||
const div = item.parentElement.parentElement.parentElement;
|
||||
const group = div.getAttribute("data-group");
|
||||
if (!result[group]) {
|
||||
result[group] = {};
|
||||
}
|
||||
const selectorsToSync = result[group];
|
||||
const value = item.innerHTML;
|
||||
if (!selectorsToSync[value]) {
|
||||
selectorsToSync[value] = [];
|
||||
}
|
||||
selectorsToSync[value].push(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function setupSelectorSync() {
|
||||
const selectorsToSync = findSelectorsToSyncByLanguage();
|
||||
Object.entries(selectorsToSync).forEach(([group, tabSetsByValue]) => {
|
||||
Object.entries(tabSetsByValue).forEach(([value, items]) => {
|
||||
items.forEach((item) => {
|
||||
item.addEventListener("click", (_event) => {
|
||||
setTabState(group, value);
|
||||
toggleAll(value, selectorsToSync[group]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
return selectorsToSync;
|
||||
}
|
||||
|
||||
const selectorsToSync = setupSelectorSync();
|
||||
for (const [group, selectedName] of Object.entries(getTabSettings())) {
|
||||
const selectors = selectorsToSync[group];
|
||||
// it's possible that stale state gives us empty selections, so we explicitly check here.
|
||||
if (selectors) {
|
||||
toggleAll(selectedName, selectors);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function throttle(func, wait) {
|
||||
let waiting = false;
|
||||
return function () {
|
||||
if (!waiting) {
|
||||
func.apply(this, arguments);
|
||||
waiting = true;
|
||||
setTimeout(function () {
|
||||
waiting = false;
|
||||
}, wait);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function nexttick(func) {
|
||||
return setTimeout(func, 0);
|
||||
}
|
1
hacking_religion/_book/site_libs/quarto-html/tippy.css
Normal file
1
hacking_religion/_book/site_libs/quarto-html/tippy.css
Normal file
|
@ -0,0 +1 @@
|
|||
.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}
|
2
hacking_religion/_book/site_libs/quarto-html/tippy.umd.min.js
vendored
Normal file
2
hacking_religion/_book/site_libs/quarto-html/tippy.umd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
hacking_religion/_book/site_libs/quarto-nav/headroom.min.js
vendored
Normal file
7
hacking_religion/_book/site_libs/quarto-nav/headroom.min.js
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
/*!
|
||||
* headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it
|
||||
* Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=l<t?"down":"up",a.distance=Math.abs(t-l),a.isOutOfBounds=t<0||o<t+n,a.top=t<=s.offset[a.direction],a.bottom=o<=t+n,a.toleranceExceeded=a.distance>s.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s});
|
277
hacking_religion/_book/site_libs/quarto-nav/quarto-nav.js
Normal file
277
hacking_religion/_book/site_libs/quarto-nav/quarto-nav.js
Normal file
|
@ -0,0 +1,277 @@
|
|||
const headroomChanged = new CustomEvent("quarto-hrChanged", {
|
||||
detail: {},
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
composed: false,
|
||||
});
|
||||
|
||||
window.document.addEventListener("DOMContentLoaded", function () {
|
||||
let init = false;
|
||||
|
||||
// Manage the back to top button, if one is present.
|
||||
let lastScrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||
const scrollDownBuffer = 5;
|
||||
const scrollUpBuffer = 35;
|
||||
const btn = document.getElementById("quarto-back-to-top");
|
||||
const hideBackToTop = () => {
|
||||
btn.style.display = "none";
|
||||
};
|
||||
const showBackToTop = () => {
|
||||
btn.style.display = "inline-block";
|
||||
};
|
||||
if (btn) {
|
||||
window.document.addEventListener(
|
||||
"scroll",
|
||||
function () {
|
||||
const currentScrollTop =
|
||||
window.pageYOffset || document.documentElement.scrollTop;
|
||||
|
||||
// Shows and hides the button 'intelligently' as the user scrolls
|
||||
if (currentScrollTop - scrollDownBuffer > lastScrollTop) {
|
||||
hideBackToTop();
|
||||
lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop;
|
||||
} else if (currentScrollTop < lastScrollTop - scrollUpBuffer) {
|
||||
showBackToTop();
|
||||
lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop;
|
||||
}
|
||||
|
||||
// Show the button at the bottom, hides it at the top
|
||||
if (currentScrollTop <= 0) {
|
||||
hideBackToTop();
|
||||
} else if (
|
||||
window.innerHeight + currentScrollTop >=
|
||||
document.body.offsetHeight
|
||||
) {
|
||||
showBackToTop();
|
||||
}
|
||||
},
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
function throttle(func, wait) {
|
||||
var timeout;
|
||||
return function () {
|
||||
const context = this;
|
||||
const args = arguments;
|
||||
const later = function () {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
func.apply(context, args);
|
||||
};
|
||||
|
||||
if (!timeout) {
|
||||
timeout = setTimeout(later, wait);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function headerOffset() {
|
||||
// Set an offset if there is are fixed top navbar
|
||||
const headerEl = window.document.querySelector("header.fixed-top");
|
||||
if (headerEl) {
|
||||
return headerEl.clientHeight;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function footerOffset() {
|
||||
const footerEl = window.document.querySelector("footer.footer");
|
||||
if (footerEl) {
|
||||
return footerEl.clientHeight;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function updateDocumentOffsetWithoutAnimation() {
|
||||
updateDocumentOffset(false);
|
||||
}
|
||||
|
||||
function updateDocumentOffset(animated) {
|
||||
// set body offset
|
||||
const topOffset = headerOffset();
|
||||
const bodyOffset = topOffset + footerOffset();
|
||||
const bodyEl = window.document.body;
|
||||
bodyEl.setAttribute("data-bs-offset", topOffset);
|
||||
bodyEl.style.paddingTop = topOffset + "px";
|
||||
|
||||
// deal with sidebar offsets
|
||||
const sidebars = window.document.querySelectorAll(
|
||||
".sidebar, .headroom-target"
|
||||
);
|
||||
sidebars.forEach((sidebar) => {
|
||||
if (!animated) {
|
||||
sidebar.classList.add("notransition");
|
||||
// Remove the no transition class after the animation has time to complete
|
||||
setTimeout(function () {
|
||||
sidebar.classList.remove("notransition");
|
||||
}, 201);
|
||||
}
|
||||
|
||||
if (window.Headroom && sidebar.classList.contains("sidebar-unpinned")) {
|
||||
sidebar.style.top = "0";
|
||||
sidebar.style.maxHeight = "100vh";
|
||||
} else {
|
||||
sidebar.style.top = topOffset + "px";
|
||||
sidebar.style.maxHeight = "calc(100vh - " + topOffset + "px)";
|
||||
}
|
||||
});
|
||||
|
||||
// allow space for footer
|
||||
const mainContainer = window.document.querySelector(".quarto-container");
|
||||
if (mainContainer) {
|
||||
mainContainer.style.minHeight = "calc(100vh - " + bodyOffset + "px)";
|
||||
}
|
||||
|
||||
// link offset
|
||||
let linkStyle = window.document.querySelector("#quarto-target-style");
|
||||
if (!linkStyle) {
|
||||
linkStyle = window.document.createElement("style");
|
||||
linkStyle.setAttribute("id", "quarto-target-style");
|
||||
window.document.head.appendChild(linkStyle);
|
||||
}
|
||||
while (linkStyle.firstChild) {
|
||||
linkStyle.removeChild(linkStyle.firstChild);
|
||||
}
|
||||
if (topOffset > 0) {
|
||||
linkStyle.appendChild(
|
||||
window.document.createTextNode(`
|
||||
section:target::before {
|
||||
content: "";
|
||||
display: block;
|
||||
height: ${topOffset}px;
|
||||
margin: -${topOffset}px 0 0;
|
||||
}`)
|
||||
);
|
||||
}
|
||||
if (init) {
|
||||
window.dispatchEvent(headroomChanged);
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
|
||||
// initialize headroom
|
||||
var header = window.document.querySelector("#quarto-header");
|
||||
if (header && window.Headroom) {
|
||||
const headroom = new window.Headroom(header, {
|
||||
tolerance: 5,
|
||||
onPin: function () {
|
||||
const sidebars = window.document.querySelectorAll(
|
||||
".sidebar, .headroom-target"
|
||||
);
|
||||
sidebars.forEach((sidebar) => {
|
||||
sidebar.classList.remove("sidebar-unpinned");
|
||||
});
|
||||
updateDocumentOffset();
|
||||
},
|
||||
onUnpin: function () {
|
||||
const sidebars = window.document.querySelectorAll(
|
||||
".sidebar, .headroom-target"
|
||||
);
|
||||
sidebars.forEach((sidebar) => {
|
||||
sidebar.classList.add("sidebar-unpinned");
|
||||
});
|
||||
updateDocumentOffset();
|
||||
},
|
||||
});
|
||||
headroom.init();
|
||||
|
||||
let frozen = false;
|
||||
window.quartoToggleHeadroom = function () {
|
||||
if (frozen) {
|
||||
headroom.unfreeze();
|
||||
frozen = false;
|
||||
} else {
|
||||
headroom.freeze();
|
||||
frozen = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
window.addEventListener(
|
||||
"hashchange",
|
||||
function (e) {
|
||||
if (
|
||||
getComputedStyle(document.documentElement).scrollBehavior !== "smooth"
|
||||
) {
|
||||
window.scrollTo(0, window.pageYOffset - headerOffset());
|
||||
}
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
// Observe size changed for the header
|
||||
const headerEl = window.document.querySelector("header.fixed-top");
|
||||
if (headerEl && window.ResizeObserver) {
|
||||
const observer = new window.ResizeObserver(
|
||||
updateDocumentOffsetWithoutAnimation
|
||||
);
|
||||
observer.observe(headerEl, {
|
||||
attributes: true,
|
||||
childList: true,
|
||||
characterData: true,
|
||||
});
|
||||
} else {
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
throttle(updateDocumentOffsetWithoutAnimation, 50)
|
||||
);
|
||||
}
|
||||
setTimeout(updateDocumentOffsetWithoutAnimation, 250);
|
||||
|
||||
// fixup index.html links if we aren't on the filesystem
|
||||
if (window.location.protocol !== "file:") {
|
||||
const links = window.document.querySelectorAll("a");
|
||||
for (let i = 0; i < links.length; i++) {
|
||||
if (links[i].href) {
|
||||
links[i].href = links[i].href.replace(/\/index\.html/, "/");
|
||||
}
|
||||
}
|
||||
|
||||
// Fixup any sharing links that require urls
|
||||
// Append url to any sharing urls
|
||||
const sharingLinks = window.document.querySelectorAll(
|
||||
"a.sidebar-tools-main-item"
|
||||
);
|
||||
for (let i = 0; i < sharingLinks.length; i++) {
|
||||
const sharingLink = sharingLinks[i];
|
||||
const href = sharingLink.getAttribute("href");
|
||||
if (href) {
|
||||
sharingLink.setAttribute(
|
||||
"href",
|
||||
href.replace("|url|", window.location.href)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll the active navigation item into view, if necessary
|
||||
const navSidebar = window.document.querySelector("nav#quarto-sidebar");
|
||||
if (navSidebar) {
|
||||
// Find the active item
|
||||
const activeItem = navSidebar.querySelector("li.sidebar-item a.active");
|
||||
if (activeItem) {
|
||||
// Wait for the scroll height and height to resolve by observing size changes on the
|
||||
// nav element that is scrollable
|
||||
const resizeObserver = new ResizeObserver((_entries) => {
|
||||
// The bottom of the element
|
||||
const elBottom = activeItem.offsetTop;
|
||||
const viewBottom = navSidebar.scrollTop + navSidebar.clientHeight;
|
||||
|
||||
// The element height and scroll height are the same, then we are still loading
|
||||
if (viewBottom !== navSidebar.scrollHeight) {
|
||||
// Determine if the item isn't visible and scroll to it
|
||||
if (elBottom >= viewBottom) {
|
||||
navSidebar.scrollTop = elBottom;
|
||||
}
|
||||
|
||||
// stop observing now since we've completed the scroll
|
||||
resizeObserver.unobserve(navSidebar);
|
||||
}
|
||||
});
|
||||
resizeObserver.observe(navSidebar);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
File diff suppressed because one or more lines are too long
9
hacking_religion/_book/site_libs/quarto-search/fuse.min.js
vendored
Normal file
9
hacking_religion/_book/site_libs/quarto-search/fuse.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1140
hacking_religion/_book/site_libs/quarto-search/quarto-search.js
Normal file
1140
hacking_religion/_book/site_libs/quarto-search/quarto-search.js
Normal file
File diff suppressed because it is too large
Load diff
432
hacking_religion/_book/summary.html
Normal file
432
hacking_religion/_book/summary.html
Normal file
|
@ -0,0 +1,432 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="generator" content="quarto-1.3.450">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
|
||||
|
||||
<title>Hacking Religion: TRS & Data Science in Action - 6 Summary</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<script src="site_libs/quarto-nav/quarto-nav.js"></script>
|
||||
<script src="site_libs/quarto-nav/headroom.min.js"></script>
|
||||
<script src="site_libs/clipboard/clipboard.min.js"></script>
|
||||
<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
|
||||
<script src="site_libs/quarto-search/fuse.min.js"></script>
|
||||
<script src="site_libs/quarto-search/quarto-search.js"></script>
|
||||
<meta name="quarto:offset" content="./">
|
||||
<link href="./references.html" rel="next">
|
||||
<link href="./chapter_4.html" rel="prev">
|
||||
<script src="site_libs/quarto-html/quarto.js"></script>
|
||||
<script src="site_libs/quarto-html/popper.min.js"></script>
|
||||
<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
|
||||
<script src="site_libs/quarto-html/anchor.min.js"></script>
|
||||
<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
|
||||
<link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
|
||||
<script src="site_libs/bootstrap/bootstrap.min.js"></script>
|
||||
<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
|
||||
<script id="quarto-search-options" type="application/json">{
|
||||
"location": "sidebar",
|
||||
"copy-button": false,
|
||||
"collapse-after": 3,
|
||||
"panel-placement": "start",
|
||||
"type": "textbox",
|
||||
"limit": 20,
|
||||
"language": {
|
||||
"search-no-results-text": "No results",
|
||||
"search-matching-documents-text": "matching documents",
|
||||
"search-copy-link-title": "Copy link to search",
|
||||
"search-hide-matches-text": "Hide additional matches",
|
||||
"search-more-match-text": "more match in this document",
|
||||
"search-more-matches-text": "more matches in this document",
|
||||
"search-clear-button-title": "Clear",
|
||||
"search-detached-cancel-button-title": "Cancel",
|
||||
"search-submit-button-title": "Submit",
|
||||
"search-label": "Search"
|
||||
}
|
||||
}</script>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="nav-sidebar floating">
|
||||
|
||||
<div id="quarto-search-results"></div>
|
||||
<header id="quarto-header" class="headroom fixed-top">
|
||||
<nav class="quarto-secondary-nav">
|
||||
<div class="container-fluid d-flex">
|
||||
<button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
<i class="bi bi-layout-text-sidebar-reverse"></i>
|
||||
</button>
|
||||
<nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="./summary.html"><span class="chapter-number">6</span> <span class="chapter-title">Summary</span></a></li></ol></nav>
|
||||
<a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
|
||||
</a>
|
||||
<button type="button" class="btn quarto-search-button" aria-label="" onclick="window.quartoOpenSearch();">
|
||||
<i class="bi bi-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<!-- content -->
|
||||
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article">
|
||||
<!-- sidebar -->
|
||||
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal sidebar-navigation floating overflow-auto">
|
||||
<div class="pt-lg-2 mt-2 text-left sidebar-header">
|
||||
<div class="sidebar-title mb-0 py-0">
|
||||
<a href="./">Hacking Religion: TRS & Data Science in Action</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 flex-shrink-0 align-items-center">
|
||||
<div class="sidebar-search">
|
||||
<div id="quarto-search" class="" title="Search"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-menu-container">
|
||||
<ul class="list-unstyled mt-1">
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./index.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">Preface</span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./intro.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">1</span> <span class="chapter-title">Introduction: Hacking Religion</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_1.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">2</span> <span class="chapter-title">The 2021 UK Census</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_2.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">3</span> <span class="chapter-title">Survey Data: Spotlight Project</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_3.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">4</span> <span class="chapter-title">Mapping churches: geospatial data science</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./chapter_4.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text"><span class="chapter-number">5</span> <span class="chapter-title">Data scraping, corpus analysis and wordclouds</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./summary.html" class="sidebar-item-text sidebar-link active">
|
||||
<span class="menu-text"><span class="chapter-number">6</span> <span class="chapter-title">Summary</span></span></a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<div class="sidebar-item-container">
|
||||
<a href="./references.html" class="sidebar-item-text sidebar-link">
|
||||
<span class="menu-text">References</span></a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="quarto-sidebar-glass" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass"></div>
|
||||
<!-- margin-sidebar -->
|
||||
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
|
||||
|
||||
</div>
|
||||
<!-- main -->
|
||||
<main class="content" id="quarto-document-content">
|
||||
|
||||
<header id="title-block-header" class="quarto-title-block default">
|
||||
<div class="quarto-title">
|
||||
<h1 class="title"><span class="chapter-number">6</span> <span class="chapter-title">Summary</span></h1>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="quarto-title-meta">
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<p>An open textbook introducing data science to religious studies</p>
|
||||
|
||||
|
||||
|
||||
</main> <!-- /main -->
|
||||
<script id="quarto-html-after-body" type="application/javascript">
|
||||
window.document.addEventListener("DOMContentLoaded", function (event) {
|
||||
const toggleBodyColorMode = (bsSheetEl) => {
|
||||
const mode = bsSheetEl.getAttribute("data-mode");
|
||||
const bodyEl = window.document.querySelector("body");
|
||||
if (mode === "dark") {
|
||||
bodyEl.classList.add("quarto-dark");
|
||||
bodyEl.classList.remove("quarto-light");
|
||||
} else {
|
||||
bodyEl.classList.add("quarto-light");
|
||||
bodyEl.classList.remove("quarto-dark");
|
||||
}
|
||||
}
|
||||
const toggleBodyColorPrimary = () => {
|
||||
const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
|
||||
if (bsSheetEl) {
|
||||
toggleBodyColorMode(bsSheetEl);
|
||||
}
|
||||
}
|
||||
toggleBodyColorPrimary();
|
||||
const icon = "";
|
||||
const anchorJS = new window.AnchorJS();
|
||||
anchorJS.options = {
|
||||
placement: 'right',
|
||||
icon: icon
|
||||
};
|
||||
anchorJS.add('.anchored');
|
||||
const isCodeAnnotation = (el) => {
|
||||
for (const clz of el.classList) {
|
||||
if (clz.startsWith('code-annotation-')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const clipboard = new window.ClipboardJS('.code-copy-button', {
|
||||
text: function(trigger) {
|
||||
const codeEl = trigger.previousElementSibling.cloneNode(true);
|
||||
for (const childEl of codeEl.children) {
|
||||
if (isCodeAnnotation(childEl)) {
|
||||
childEl.remove();
|
||||
}
|
||||
}
|
||||
return codeEl.innerText;
|
||||
}
|
||||
});
|
||||
clipboard.on('success', function(e) {
|
||||
// button target
|
||||
const button = e.trigger;
|
||||
// don't keep focus
|
||||
button.blur();
|
||||
// flash "checked"
|
||||
button.classList.add('code-copy-button-checked');
|
||||
var currentTitle = button.getAttribute("title");
|
||||
button.setAttribute("title", "Copied!");
|
||||
let tooltip;
|
||||
if (window.bootstrap) {
|
||||
button.setAttribute("data-bs-toggle", "tooltip");
|
||||
button.setAttribute("data-bs-placement", "left");
|
||||
button.setAttribute("data-bs-title", "Copied!");
|
||||
tooltip = new bootstrap.Tooltip(button,
|
||||
{ trigger: "manual",
|
||||
customClass: "code-copy-button-tooltip",
|
||||
offset: [0, -8]});
|
||||
tooltip.show();
|
||||
}
|
||||
setTimeout(function() {
|
||||
if (tooltip) {
|
||||
tooltip.hide();
|
||||
button.removeAttribute("data-bs-title");
|
||||
button.removeAttribute("data-bs-toggle");
|
||||
button.removeAttribute("data-bs-placement");
|
||||
}
|
||||
button.setAttribute("title", currentTitle);
|
||||
button.classList.remove('code-copy-button-checked');
|
||||
}, 1000);
|
||||
// clear code selection
|
||||
e.clearSelection();
|
||||
});
|
||||
function tippyHover(el, contentFn) {
|
||||
const config = {
|
||||
allowHTML: true,
|
||||
content: contentFn,
|
||||
maxWidth: 500,
|
||||
delay: 100,
|
||||
arrow: false,
|
||||
appendTo: function(el) {
|
||||
return el.parentElement;
|
||||
},
|
||||
interactive: true,
|
||||
interactiveBorder: 10,
|
||||
theme: 'quarto',
|
||||
placement: 'bottom-start'
|
||||
};
|
||||
window.tippy(el, config);
|
||||
}
|
||||
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
|
||||
for (var i=0; i<noterefs.length; i++) {
|
||||
const ref = noterefs[i];
|
||||
tippyHover(ref, function() {
|
||||
// use id or data attribute instead here
|
||||
let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
|
||||
try { href = new URL(href).hash; } catch {}
|
||||
const id = href.replace(/^#\/?/, "");
|
||||
const note = window.document.getElementById(id);
|
||||
return note.innerHTML;
|
||||
});
|
||||
}
|
||||
let selectedAnnoteEl;
|
||||
const selectorForAnnotation = ( cell, annotation) => {
|
||||
let cellAttr = 'data-code-cell="' + cell + '"';
|
||||
let lineAttr = 'data-code-annotation="' + annotation + '"';
|
||||
const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
|
||||
return selector;
|
||||
}
|
||||
const selectCodeLines = (annoteEl) => {
|
||||
const doc = window.document;
|
||||
const targetCell = annoteEl.getAttribute("data-target-cell");
|
||||
const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
|
||||
const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
|
||||
const lines = annoteSpan.getAttribute("data-code-lines").split(",");
|
||||
const lineIds = lines.map((line) => {
|
||||
return targetCell + "-" + line;
|
||||
})
|
||||
let top = null;
|
||||
let height = null;
|
||||
let parent = null;
|
||||
if (lineIds.length > 0) {
|
||||
//compute the position of the single el (top and bottom and make a div)
|
||||
const el = window.document.getElementById(lineIds[0]);
|
||||
top = el.offsetTop;
|
||||
height = el.offsetHeight;
|
||||
parent = el.parentElement.parentElement;
|
||||
if (lineIds.length > 1) {
|
||||
const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
|
||||
const bottom = lastEl.offsetTop + lastEl.offsetHeight;
|
||||
height = bottom - top;
|
||||
}
|
||||
if (top !== null && height !== null && parent !== null) {
|
||||
// cook up a div (if necessary) and position it
|
||||
let div = window.document.getElementById("code-annotation-line-highlight");
|
||||
if (div === null) {
|
||||
div = window.document.createElement("div");
|
||||
div.setAttribute("id", "code-annotation-line-highlight");
|
||||
div.style.position = 'absolute';
|
||||
parent.appendChild(div);
|
||||
}
|
||||
div.style.top = top - 2 + "px";
|
||||
div.style.height = height + 4 + "px";
|
||||
let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
|
||||
if (gutterDiv === null) {
|
||||
gutterDiv = window.document.createElement("div");
|
||||
gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
|
||||
gutterDiv.style.position = 'absolute';
|
||||
const codeCell = window.document.getElementById(targetCell);
|
||||
const gutter = codeCell.querySelector('.code-annotation-gutter');
|
||||
gutter.appendChild(gutterDiv);
|
||||
}
|
||||
gutterDiv.style.top = top - 2 + "px";
|
||||
gutterDiv.style.height = height + 4 + "px";
|
||||
}
|
||||
selectedAnnoteEl = annoteEl;
|
||||
}
|
||||
};
|
||||
const unselectCodeLines = () => {
|
||||
const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
|
||||
elementsIds.forEach((elId) => {
|
||||
const div = window.document.getElementById(elId);
|
||||
if (div) {
|
||||
div.remove();
|
||||
}
|
||||
});
|
||||
selectedAnnoteEl = undefined;
|
||||
};
|
||||
// Attach click handler to the DT
|
||||
const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
|
||||
for (const annoteDlNode of annoteDls) {
|
||||
annoteDlNode.addEventListener('click', (event) => {
|
||||
const clickedEl = event.target;
|
||||
if (clickedEl !== selectedAnnoteEl) {
|
||||
unselectCodeLines();
|
||||
const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
|
||||
if (activeEl) {
|
||||
activeEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
selectCodeLines(clickedEl);
|
||||
clickedEl.classList.add('code-annotation-active');
|
||||
} else {
|
||||
// Unselect the line
|
||||
unselectCodeLines();
|
||||
clickedEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
});
|
||||
}
|
||||
const findCites = (el) => {
|
||||
const parentEl = el.parentElement;
|
||||
if (parentEl) {
|
||||
const cites = parentEl.dataset.cites;
|
||||
if (cites) {
|
||||
return {
|
||||
el,
|
||||
cites: cites.split(' ')
|
||||
};
|
||||
} else {
|
||||
return findCites(el.parentElement)
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
|
||||
for (var i=0; i<bibliorefs.length; i++) {
|
||||
const ref = bibliorefs[i];
|
||||
const citeInfo = findCites(ref);
|
||||
if (citeInfo) {
|
||||
tippyHover(citeInfo.el, function() {
|
||||
var popup = window.document.createElement('div');
|
||||
citeInfo.cites.forEach(function(cite) {
|
||||
var citeDiv = window.document.createElement('div');
|
||||
citeDiv.classList.add('hanging-indent');
|
||||
citeDiv.classList.add('csl-entry');
|
||||
var biblioDiv = window.document.getElementById('ref-' + cite);
|
||||
if (biblioDiv) {
|
||||
citeDiv.innerHTML = biblioDiv.innerHTML;
|
||||
}
|
||||
popup.appendChild(citeDiv);
|
||||
});
|
||||
return popup.innerHTML;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<nav class="page-navigation">
|
||||
<div class="nav-page nav-page-previous">
|
||||
<a href="./chapter_4.html" class="pagination-link">
|
||||
<i class="bi bi-arrow-left-short"></i> <span class="nav-page-text"><span class="chapter-number">5</span> <span class="chapter-title">Data scraping, corpus analysis and wordclouds</span></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-page nav-page-next">
|
||||
<a href="./references.html" class="pagination-link">
|
||||
<span class="nav-page-text">References</span> <i class="bi bi-arrow-right-short"></i>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div> <!-- /content -->
|
||||
|
||||
|
||||
|
||||
</body></html>
|
25
hacking_religion/appendix_a.qmd
Normal file
25
hacking_religion/appendix_a.qmd
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Appendix A: how to set up a reproducible R script:
|
||||
|
||||
```
|
||||
# R Setup -----------------------------------------------------------------
|
||||
setwd("/Users/kidwellj/gits/hacking_religion_textbook/hacking_religion")
|
||||
library(here) # much better way to manage working paths in R across multiple instances
|
||||
here::i_am("chapter_1.qmd")
|
||||
|
||||
# Set up local workspace, as needed: --------------------------------------
|
||||
|
||||
# Set up paths in case they haven't already been created
|
||||
|
||||
if (dir.exists(here("data")) == FALSE) {
|
||||
dir.create(here("data"))
|
||||
}
|
||||
|
||||
# Note, these two paths are excluded from github as it is best practice in reproducible research for end-user to generate their own
|
||||
|
||||
if (dir.exists(here("figures")) == FALSE) {
|
||||
dir.create(here("figures"))
|
||||
}
|
||||
|
||||
if (dir.exists(here("derivedData")) == FALSE) {
|
||||
dir.create(here("derivedData"))
|
||||
}
|
16
hacking_religion/chapter_5.qmd
Normal file
16
hacking_religion/chapter_5.qmd
Normal file
|
@ -0,0 +1,16 @@
|
|||
# What's next?
|
||||
|
||||
## How to get more data
|
||||
|
||||
Data can come from a wide variety of places
|
||||
|
||||
|
||||
## How to get help
|
||||
|
||||
Online forums
|
||||
Etiquette
|
||||
|
||||
# References {.unnumbered}
|
||||
|
||||
::: {#refs}
|
||||
:::
|
11
hacking_religion/example_data/census2021-ts030-rgn.csv
Normal file
11
hacking_religion/example_data/census2021-ts030-rgn.csv
Normal file
|
@ -0,0 +1,11 @@
|
|||
geography,total,no_religion,christian,buddhist,hindu,jewish,muslim,sikh,other,no_response
|
||||
North East,2647012,1058122,1343948,7026,10924,4389,72102,7206,9950,133345
|
||||
North West,7417397,2419624,3895779,23028,49749,33285,563105,11862,28103,392862
|
||||
Yorkshire and The Humber,5480774,2161185,2461519,15803,29243,9355,442533,24034,23618,313484
|
||||
East Midlands,4880054,1950354,2214151,14521,120345,4313,210766,53950,24813,286841
|
||||
West Midlands,5950756,1955003,2770559,18804,88116,4394,569963,172398,31805,339714
|
||||
East,6335072,2544509,2955071,26814,86631,42012,234744,24284,36380,384627
|
||||
London,8799728,2380404,3577681,77425,453034,145466,1318754,144543,86759,615662
|
||||
South East,9278068,3733094,4313319,54433,154748,18682,309067,74348,54098,566279
|
||||
South West,5701186,2513369,2635872,24579,27746,7387,80152,7465,36884,367732
|
||||
Wales,3107494,1446398,1354773,10075,12242,2044,66947,4048,15926,195041
|
|
Loading…
Reference in a new issue