#| label: setup
#| include: false

# set RNG seeds
set.seed(42L)
htmlwidgets::setWidgetIdSeed(seed = 42L)

knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

Main semantic rules

The raw questionnaire is written in the TOML file format. Basically, all questionnaire items are defined in an ordered tree structure where child nodes inherit the attributes of their parent (and transitively grandparent etc.) nodes.

The following main semantic rules apply:

  1. Top table level (blockname) defines a questionnaire block[^1], whereby the (alphabetical) order of the table levels conforms to the order of the blocks in the questionnaire:

    toml [blockname]

  2. Lower table level names ideally start with a 3-digit number (###) since table levels (and hence questionnare items below them) are always ordered according to the (alphabetical) order of their names:

    toml [blockname.00X_2nd_lvl.00X_3rd_lvl]

  3. Deepest[^2] table level named item defines an "atomic" questionnaire item (= single row in Markdown questionnaires) or a template for multiple similar "atomic" questionnaire items. It can be defined multiple times (once for each item) and must be wrapped in double brackets:

    toml [[blockname.00X_2nd_lvl.00X_3rd_lvl.item]]

    Items appear in the final questionnaire in the same order they are defined here. Technically, the level item is an array of tables which is represented as a list of unnamed lists in R.

  4. Table levels in between top and deepest level item can be named anything except variable_name and are intended to arrange and/or group items and set keys that hold for multiple questionnaire items hierarchically in order to avoid redundancies.

    NOTE: It is still strongly discouraged to name table levels the same as any of the keys listed below.

[^1]: Exceptions: The following tables/table arrays are not questionnaire blocks by themselves, but also don't contain "atomic" questionnaire items.

-   `title`
-   `who`
-   `party`
-   `response_options`
-   `footnote`
-   `link`

[^2]: The term "deepest" is kind of misleading here since there can actually be TOML table levels below the level of an "atomic" questionnaire item, namely to define include rules (e.g. include.false = [ YYYY-MM-DD ]) or to account for varying topic, question etc. wordings at different ballot dates (e.g. topic.default = "bla" and topic.YYYYMMDD = "blup") or for different ballot types (e.g. topic.default.election = "bla" and topic.default.referendum = "blup").

Supported keys

Depending on the table level, the set of possible keys includes:

#| echo: false
#| results: "asis"

library(magrittr)
options(knitr.kable.NA = '')

fokus:::qstnr_item_keys %>%
  dplyr::select(key, type, default, is_optional, everything()) %>%
  dplyr::mutate(key = pal::wrap_chr(key,
                                    wrap = "`"),
                type = paste(type, dplyr::if_else(is_scalar,
                                                  "scalar",
                                                  "vector")),
                default = pal::wrap_chr(default,
                                        wrap = "`"),
                dplyr::across(where(is.logical),
                              fokus:::lgl_to_unicode)) %>%
  dplyr::select(-c(is_scalar,
                   default_val)) %>%
  dplyr::rename("Default value" = default) %>%
  dplyr::rename_with(.cols = starts_with("is_"),
                     .fn = stringr::str_remove,
                     pattern = "^is_") %>%
  dplyr::rename_with(stringr::str_to_title) %>%
  pal::pipe_table() %>%
  paste0("    ", .) %>%
  pal::cat_lines()

The keys regarded on item-level nodes are resolved in the following order

  1. lvl
  2. i
  3. j
  4. All the other item-level keys[^3].

[^3]: Except for question which can be referenced by question_full via string interpolation and hence is resolved before the latter.

Further notes

Supplemental assumptions to resolve glue/cli string interpolation

Debugging

The R function fokus:::gen_qstnr_tibble(), which is designed to turn the raw questionnaire into a tibble containing the questionnaire data for a specific ballot date and canton, prints helpful progress information when its verbose argument is set to TRUE (default is FALSE).

For the questionnaire \@ 2018-09-23 in Aargau, this looks as follows:

#| echo: false

fs::path_package("asciicasts/gen_qstnr_tibble-success.json",
                 package = "fokus") %>%
  asciicast::read_cast() %>%
  # playback speed is not stored in the asciicast itself, so has to be set here
  asciicast::asciinema_player(speed = 1)

If some mistake that breaks questionnaire generation is present in the raw questionnaire, like a syntax error in embedded R code for example, the progress output stops immediately, allowing to easily locate the exact source position of the mistake.



zdaarau/fokus documentation built on Dec. 24, 2024, 10:47 p.m.