Commit bec6546c authored by Gjalt-Jorn Peters's avatar Gjalt-Jorn Peters

Added setter/getter functions for the options (i.e. many shared arguments/parameters)

parent fa182490
Pipeline #94952495 failed with stages
in 12 minutes and 42 seconds
......@@ -18,8 +18,8 @@ Description: The Reproducible Open Coding Kit ('ROCK', and this package, 'rock')
general-purpose toolkit, three specific applications have been
implemented, specifically an interface to the 'rENA' package that
implements Epistemic Network Analysis ('ENA'), means to process notes
from Cognitive Interviews ('CIs'), and means to work with a decentralized
construct taxonomy ('DCT').
from Cognitive Interviews ('CIs'), and means to work with decentralized
construct taxonomies ('DCTs').
BugReports: https://gitlab.com/r-packages/rock/issues
URL: https://r-packages.gitlab.io/rock
License: GPL-3
......
......@@ -4,10 +4,11 @@
#'
#' @inheritParams parsing_sources
#' @param x A character vector with the source
#' @param codeClass The classes to use for, respectively, codes,
#' identifiers (such as case identifiers or coder identifiers), section
#' breaks, utterance identifiers, and full utterances. All `<span>` elements
#' except for the full utterances, which are placed in `<div>` elements.
#' @param codeClass,idClass,sectionClass,uidClass,utteranceClass The classes
#' to use for, respectively, codes, identifiers (such as case identifiers or
#' coder identifiers), section breaks, utterance identifiers, and full
#' utterances. All `<span>` elements except for the full utterances, which
#' are placed in `<div>` elements.
#'
#' @return The character vector with the replacements made.
#' @export
......@@ -18,17 +19,18 @@
#' ---paragraph-break---
#' And another utterance.");
add_html_tags <- function(x,
codeRegexes = rock::opts$get(codeRegexes),
idRegexes = rock::opts$get(idRegexes),
sectionRegexes = rock::opts$get(sectionRegexes),
uidRegex = rock::opts$get(uidRegex),
inductiveCodingHierarchyMarker = rock::opts$get(inductiveCodingHierarchyMarker),
codeClass = rock::opts$get(codeClass),
idClass = rock::opts$get(idClass),
sectionClass = rock::opts$get(sectionClass),
uidClass = rock::opts$get(uidClass),
utteranceClass = rock::opts$get(utteranceClass)) {
codeRegexes <- rock::opts$get(codeRegexes);
idRegexes <- rock::opts$get(idRegexes);
sectionRegexes <- rock::opts$get(sectionRegexes);
uidRegex <- rock::opts$get(uidRegex);
inductiveCodingHierarchyMarker <- rock::opts$get(inductiveCodingHierarchyMarker);
res <- x;
### First replace smaller than and bigger than symbols
......
......@@ -41,15 +41,14 @@
#' @param utteranceSplits This is a vector of regular expressions that specify where to
#' insert breaks between utterances in the source(s). Such breakes are specified using
#' `utteranceMarker`.
#' @param utteranceMarker How to specify breaks between utterances in the source(s). The
#' ROCK convention is to use a newline (`\\n`).
#' @param preventOverwriting Whether to prevent overwriting of output files.
#' @param removeNewlines Whether to remove all newline characters from the source before
#' starting to clean them.
#' @param encoding The encoding of the source(s).
#' @param silent Whether to suppress the warning about not editing the cleaned source.
#'
#' @return A character vector for `clean_source`, or a list of character vectors , for `clean_sources`.
#' @return A character vector for `clean_source`, or a list of character vectors,
#' for `clean_sources`.
#' @rdname cleaning_sources
#'
#' @examples exampleSource <-
......@@ -69,22 +68,17 @@
#' @export
clean_source <- function(input,
output = NULL,
replacementsPre = list(c("([^\\.])(\\.\\.)([^\\.])",
"\\1.\\3"),
c("([^\\.])(\\.\\.\\.\\.+)([^\\.])",
"\\1...\\3"),
c("(\\s*\\r?\\n){3,}",
"\n")),
replacementsPre = rock::opts$get(replacementsPre),
replacementsPost = rock::opts$get(replacementsPost),
extraReplacementsPre = NULL,
utteranceSplits = c("([\\?\\!]+\\s?|\u2026\\s?|[[:alnum:]\\s?]\\.(?!\\.\\.)\\s?)"),
utteranceMarker = rock::opts$get(utteranceMarker),
replacementsPost = list(c("([^\\,]),([^\\s])",
"\\1, \\2")),
extraReplacementsPost = NULL,
preventOverwriting = TRUE,
removeNewlines = FALSE,
encoding = "UTF-8",
silent=FALSE) {
utteranceSplits = rock::opts$get(utteranceSplits),
preventOverwriting = rock::opts$get(preventOverwriting),
encoding = rock::opts$get(encoding),
silent = rock::opts$get(silent)) {
utteranceMarker <- rock::opts$get(utteranceMarker);
if (file.exists(input)) {
res <- readLines(input,
......
......@@ -2,31 +2,26 @@
#' @param recursive Whether to search all subdirectories (`TRUE`) as well or not.
#' @param filenameRegex A regular expression to match against located files; only
#' files matching this regular expression are processed.
#' @param filenamePrefix,filenamePrefix The prefix and suffix to add to the
#' @param filenamePrefix,filenameSuffix The prefix and suffix to add to the
#' filenames when writing the processed files to disk.
#' @export
clean_sources <- function(input,
output,
replacementsPre = list(c("([^\\.])(\\.\\.)([^\\.])",
"\\1.\\3"),
c("([^\\.])(\\.\\.\\.\\.+)([^\\.])",
"\\1...\\3"),
c("(\\s*\\r?\\n){3,}",
"\n")),
extraReplacementsPre = NULL,
utteranceSplits = c("([\\?\\!]+\\s?|\u2026\\s?|[[:alnum:]\\s?]\\.(?!\\.\\.)\\s?)"),
utteranceMarker = "\n",
replacementsPost = list(c("([^\\,]),([^\\s])",
"\\1, \\2")),
extraReplacementsPost = NULL,
filenamePrefix = "",
filenameSuffix = "",
preventOverwriting=TRUE,
recursive=TRUE,
filenameRegex=".*",
replacementsPre = rock::opts$get(replacementsPre),
replacementsPost = rock::opts$get(replacementsPost),
extraReplacementsPre = NULL,
extraReplacementsPost = NULL,
removeNewlines = FALSE,
encoding = "UTF-8",
silent=FALSE) {
utteranceSplits = rock::opts$get(utteranceSplits),
preventOverwriting = rock::opts$get(preventOverwriting),
encoding = rock::opts$get(encoding),
silent=rock::opts$get(silent)) {
utteranceMarker <- rock::opts$get(utteranceMarker);
if (!is.character(input) || !length(input)==1) {
stop("Only specify a single string as 'input'!");
......@@ -95,13 +90,12 @@ clean_sources <- function(input,
replacementsPre=replacementsPre,
extraReplacementsPre=extraReplacementsPre,
utteranceSplits=utteranceSplits,
utteranceMarker=utteranceMarker,
replacementsPost=replacementsPost,
extraReplacementsPost=extraReplacementsPost,
preventOverwriting=preventOverwriting,
removeNewlines=removeNewlines,
encoding=encoding,
silent=TRUE);
silent=silent);
res <-
c(res,
newFilename);
......
......@@ -18,13 +18,19 @@
#' If no heading is used, the code prefix will be `headingLevel` hashes,
#' instead of `headingLevel+1` hashes.
#' @param headingLevel The number of hashes to insert before the headings.
#' @param add_html_tags Whether to add HTML tags to the result.
#' @param rawResult Whether to return the raw result, a list of the
#' fragments, or one character value in markdown format.
#' @param output Here, a path and filename can be provided where the
#' result will be written. If provided, the result will be returned
#' invisibly.
#' @param template The template to load; either the name of one
#' of the ROCK templates (currently, only 'default' is available), or
#' the path and filename of a CSS file.
#' @param cleanUtterances Whether to use the clean or the raw utterances
#' when constructing the fragments (the raw versions contain all codes).
#' when constructing the fragments (the raw versions contain all codes). Note that
#' this should be set to `FALSE` to have `add_html_tags` be of the most use.
#' @param preventOverwriting Whether to prevent overwriting of output files.
#' @param silent Whether to provide (`FALSE`) or suppress (`TRUE`) more detailed progress updates.
#'
#' @return Either a list of character vectors, or a single character value.
......@@ -53,15 +59,17 @@ collect_coded_fragments <- function(x,
context = 0,
heading = NULL,
headingLevel = 2,
fragmentDelimiter = rock::opts$get(fragmentDelimiter),
utteranceGlue = "\n\n",
sourceFormat = "\n\n**Source: `%s`**\n\n",
add_html_tags = TRUE,
rawResult = FALSE,
add_html_tags = FALSE,
cleanUtterances = TRUE,
template = "default",
output = NULL,
silent=TRUE) {
template = "default",
rawResult = FALSE,
preventOverwriting = rock::opts$get(preventOverwriting),
silent=rock::opts$get(silent)) {
fragmentDelimiter <- rock::opts$get(fragmentDelimiter);
utteranceGlue <- rock::opts$get(utteranceGlue);
sourceFormatting <- rock::opts$get(sourceFormatting);
if (!("rockParsedSource" %in% class(x)) &&
!("rockParsedSources" %in% class(x))) {
......@@ -108,8 +116,8 @@ collect_coded_fragments <- function(x,
collapse=utteranceGlue);
}
### Add the sources, if necessary
if (!identical(sourceFormat, FALSE)) {
res <- paste0(sprintf(sourceFormat, dat[center, 'originalSource']),
if (!identical(sourceFormatting, FALSE)) {
res <- paste0(sprintf(sourceFormatting, dat[center, 'originalSource']),
res);
}
### Return result
......@@ -180,11 +188,23 @@ collect_coded_fragments <- function(x,
return(res);
} else {
if (dir.exists(dirname(output))) {
writeLines(res,
con = con <- file(output,
"w",
encoding="UTF-8"));
close(con);
if (file.exists(output) | preventOverwriting) {
writeLines(res,
con = con <- file(output,
"w",
encoding="UTF-8"));
close(con);
if (!silent) {
cat0("Wrote output file '", output,
"' to disk.");
}
} else {
if (!silent) {
cat0("Specified output file '", output,
"' exists, and `preventOverwriting` is set to `TRUE`; ",
"did not write the file!");
}
}
return(invisible(res));
} else {
stop("You passed '", output,
......
#' Create HTML fragment with CSS styling
#'
#' @param template The template to load; either the name of one
#' of the ROCK templates (currently, only 'default' is available), or
#' the path and filename of a CSS file.
#'
#' @return A character vector with the HTML fragment.
#'
#' @export
css <- function(template = "default") {
......
......@@ -3,12 +3,15 @@
#' These function can be used to convert one or more parsed sources to HTML.
#'
#' @param input An object of class `rockParsedSource` (as resulting from a call
#' to [rock::parse_source()]) or of class `rockParsedSources` (as resulting from a call
#' to [rock::parse_sources()]).
#' to `parse_source`) or of class `rockParsedSources` (as resulting from a call
#' to `parse_sources`.
#' @param output Either NULL to not write any files, or, if `input` is a single
#' `rockParsedSource`, the filename to write to, and if `input` is a `rockParsedSources`
#' object, the path to write to. This path will be created with a warning
#' if it does not exist.
#' @param template The template to load; either the name of one
#' of the ROCK templates (currently, only 'default' is available), or
#' the path and filename of a CSS file.
#' @param preventOverwriting Whether to prevent overwriting of output files.
#' @param encoding The encoding to use when writing the exported source(s).
#' @param silent Whether to suppress messages.
......@@ -26,7 +29,8 @@
#' ### Export results to a temporary directory
#' tmpDir <- tempdir(check = TRUE);
#' prettySources <-
#' export_to_html(input = parsedExamples);
#' export_to_html(input = parsedExamples,
#' output = tmpDir);
#'
#' ### Show first one
#' print(prettySources[[1]]);
......@@ -35,45 +39,16 @@
export_to_html <- function(input,
output = NULL,
template = "default",
preventOverwriting = TRUE,
encoding = "UTF-8",
silent=TRUE) {
### Load stylesheets
bootstrapCSS <-
paste0(readLines(system.file("css", "bootstrap.min.css", package="rock")),
collapse="\n");
basicCSS <-
paste0(readLines(system.file("css", "basic.css", package="rock")),
collapse="\n");
if (file.exists(template)) {
templateCSS <-
paste0(readLines(template),
collapse="\n");
} else if (file.exists(system.file("css", paste0(template, ".css"), package="rock"))) {
templateCSS <-
paste0(readLines(system.file("css", "default.css", package="rock")),
collapse="\n");
} else {
templateCSS <-
paste0(readLines(system.file("css", "default.css", package="rock")),
collapse="\n");
}
### Merge stylesheets
fullCSS <-
paste0("\n<style\n>",
bootstrapCSS,
"\n\n",
basicCSS,
"\n\n",
templateCSS,
"\n</style>\n");
preventOverwriting = rock::opts$get(preventOverwriting),
encoding = rock::opts$get(encoding),
silent=rock::opts$get(silent)) {
htmlPre <-
"\n<html><head>\n";
fullCSS <-
rock::css(template = "default");
htmlMid <-
"\n</head><body>\n";
......@@ -89,12 +64,7 @@ export_to_html <- function(input,
if ("rockParsedSource" %in% class(input)) {
res <-
add_html_tags(x = input$rawSourceDf$utterances_raw,
codeRegexes = input$arguments$codeRegexes,
idRegexes = input$arguments$idRegexes,
sectionRegexes = input$arguments$sectionRegexes,
uidRegex = input$arguments$uidRegex,
inductiveCodingHierarchyMarker = input$arguments$inductiveCodingHierarchyMarker);
add_html_tags(x = input$rawSourceDf$utterances_raw);
res <- paste0(utterancePre, res, utterancePost);
res <- paste0(htmlPre,
fullCSS,
......
#' Extract the codings by each coder using the coderId
#'
#' @param input The directory with the sources.
#' @param recursive Whether to also process subdirectories.
#' @param filenameRegex Only files matching this regular expression will be processed.
#' @param postponeDeductiveTreeBuilding Whether to build deductive code trees, or only
#' store YAML fragments.
#' @param ignoreOddDelimiters Whether to throw an error when encountering an odd number of
#' YAML delimiters.
#' @param encoding The encoding of the files to read.
#' @param silent Whether to be chatty or silent.
#'
#' @return An object with the read sources.
#'
#' @export
extract_codings_by_coderId <- function(input,
coderId = "\\[\\[coderId=([a-zA-Z0-9._-]+)\\]\\]",
idForOmittedCoderIds = "noCoderId",
codeRegexes = c(codes = "\\[\\[([a-zA-Z0-9._>-]+)\\]\\]"),
idRegexes = c(caseId = "\\[\\[cid=([a-zA-Z0-9._-]+)\\]\\]",
stanzaId = "\\[\\[sid=([a-zA-Z0-9._-]+)\\]\\]",
coderId = "\\[\\[coderId=([a-zA-Z0-9._-]+)\\]\\]"),
sectionRegexes = c(paragraphs = "---paragraph-break---",
secondary = "---<[a-zA-Z0-9]?>---"),
uidRegex = "\\[\\[uid=([a-zA-Z0-9._-]+)\\]\\]",
autoGenerateIds = c('stanzaId'),
persistentIds = c('caseId', 'coderId'),
noCodes = "^uid:|^uid=|^dct:|^ci:",
recursive = TRUE,
filenameRegex = ".*",
delimiterRegEx = "^---$",
ignoreRegex = "^#",
ignoreOddDelimiters=FALSE,
postponeDeductiveTreeBuilding = TRUE,
encoding="UTF-8",
silent=TRUE) {
ignoreOddDelimiters=FALSE,
encoding=rock::opts$get(encoding),
silent=rock::opts$get(silent)) {
codeRegexes <- rock::opts$get(codeRegexes);
idRegexes <- rock::opts$get(idRegexes);
sectionRegexes <- rock::opts$get(sectionRegexes);
uidRegex <- rock::opts$get(uidRegex);
autoGenerateIds <- rock::opts$get(autoGenerateIds);
persistentIds <- rock::opts$get(persistentIds);
noCodes <- rock::opts$get(noCodes);
inductiveCodingHierarchyMarker <- rock::opts$get(inductiveCodingHierarchyMarker);
attributeContainers <- rock::opts$get(attributeContainers);
codesContainers <- rock::opts$get(codesContainers);
delimiterRegEx <- rock::opts$get(delimiterRegEx);
ignoreRegex <- rock::opts$get(ignoreRegex);
coderId <- rock::opts$get(coderId);
idForOmittedCoderIds <- rock::opts$get(idForOmittedCoderIds);
if (!silent) {
cat0("\n\nStarting to parse sources in directory '",
......
#' Generate utterance identifiers (UIDs)
#'
#' This function generated utterance identifiers.
#'
#' @param x The number of identifiers te generate.
#' @param origin The origin to use when generating the actual
#' identifiers. These identifiers are the present UNIX timestamp
......@@ -17,9 +19,10 @@
#'
#' @examples generate_uids(5);
generate_uids <- function(x,
origin=Sys.time(),
prefix="uid=",
delimiters = c("[[", "]]")) {
origin=Sys.time()) {
uidPrefix <- rock::opts$get(uidPrefix);
codeDelimiters <- rock::opts$get(codeDelimiters);
timeNrString <- as.character(round(as.numeric(origin) * 100, 0));
timeNrs <-
......@@ -27,5 +30,5 @@ generate_uids <- function(x,
res <-
unlist(lapply(timeNrs,
numericToBase30));
return(paste0(delimiters[1], prefix, res, delimiters[2]));
return(paste0(codeDelimiters[1], uidPrefix, res, codeDelimiters[2]));
}
......@@ -3,6 +3,9 @@
#' @param filenameRegex A regular expression to match against located files; only
#' files matching this regular expression are processed.
#' @param ignoreRegex Regular expression indicating which files to ignore.
#' @param full.names Whether to store source names as filenames only or whether
#' to include paths.
#'
#' @export
load_sources <- function(input,
encoding="UTF-8",
......
......@@ -18,22 +18,15 @@
#' @param primarySourcesIgnoreRegex A regular expression that specifies which
#' files to ignore as primary files.
#' @param primarySourcesPath The path containing the primary sources.
#' @param coderId A regular expression specifying the coder identifier, specified
#' similarly to the codeRegexes.
#' @param idForOmittedCoderIds The identifier to use for utterances that do not
#' have a coder id (i.e. utterance that occur in a source that does not specify
#' a coder id, or above the line where a coder id is specified).
#' @param recursive,primarySourcesRecursive Whether to read files from
#' sub-directories (`TRUE`) or not.
#' @param filenameRegex Only files matching this regular expression are read.
#' @param overwrite Whether to overwrite existing files or not.
#' @param preventOverwriting Whether to prevent overwriting existing files or not.
#' @param inheritSilence If not silent, whether to let functions called
#' by `merge_sources` inherit that setting.
#'
#' @return Invisibly, a list of the parsed, primary, and merged sources.
#' @export
#'
#' @examples
merge_sources <- function(input,
output,
outputPrefix = "",
......@@ -41,30 +34,32 @@ merge_sources <- function(input,
primarySourcesRegex=".*",
primarySourcesIgnoreRegex=outputSuffix,
primarySourcesPath = input,
coderId = "\\[\\[coderId=([a-zA-Z0-9._-]+)\\]\\]",
idForOmittedCoderIds = "noCoderId",
codeRegexes = c(codes = "\\[\\[([a-zA-Z0-9._>-]+)\\]\\]"),
idRegexes = c(caseId = "\\[\\[cid=([a-zA-Z0-9._-]+)\\]\\]",
stanzaId = "\\[\\[sid=([a-zA-Z0-9._-]+)\\]\\]",
coderId = "\\[\\[coderId=([a-zA-Z0-9._-]+)\\]\\]"),
sectionRegexes = c(paragraphs = "---paragraph-break---",
secondary = "---<[a-zA-Z0-9]?>---"),
uidRegex = "\\[\\[uid=([a-zA-Z0-9._-]+)\\]\\]",
autoGenerateIds = c('stanzaId'),
persistentIds = c('caseId', 'coderId'),
noCodes = "^uid:|^uid=|^dct:|^ci:",
recursive = TRUE,
primarySourcesRecursive = recursive,
filenameRegex = ".*",
delimiterRegEx = "^---$",
ignoreRegex = "^#",
overwrite = FALSE,
ignoreOddDelimiters=FALSE,
postponeDeductiveTreeBuilding = TRUE,
encoding="UTF-8",
silent=TRUE,
ignoreOddDelimiters=FALSE,
preventOverwriting = rock::opts$get(preventOverwriting),
encoding=rock::opts$get(encoding),
silent=rock::opts$get(silent),
inheritSilence = FALSE) {
codeRegexes <- rock::opts$get(codeRegexes);
idRegexes <- rock::opts$get(idRegexes);
sectionRegexes <- rock::opts$get(sectionRegexes);
uidRegex <- rock::opts$get(uidRegex);
autoGenerateIds <- rock::opts$get(autoGenerateIds);
persistentIds <- rock::opts$get(persistentIds);
utteranceMarker <- rock::opts$get(utteranceMarker);
noCodes <- rock::opts$get(noCodes);
inductiveCodingHierarchyMarker <- rock::opts$get(inductiveCodingHierarchyMarker);
attributeContainers <- rock::opts$get(attributeContainers);
codesContainers <- rock::opts$get(codesContainers);
delimiterRegEx <- rock::opts$get(delimiterRegEx);
ignoreRegex <- rock::opts$get(ignoreRegex);
coderId <- rock::opts$get(coderId);
idForOmittedCoderIds <- rock::opts$get(idForOmittedCoderIds);
if (!dir.exists(primarySourcesPath)) {
stop("Directory specified to read primary sources from (",
primarySourcesPath, ") does not exist!");
......@@ -81,7 +76,7 @@ merge_sources <- function(input,
'output',
'outputPrefix',
'outputSuffix',
'overwrite',
'preventOverwriting',
'inheritSilence'))];
### Set 'silent' as function of both imperative for this function and the called functions
......@@ -241,10 +236,10 @@ merge_sources <- function(input,
"' to directory '", newFileDir, "'.\n");
}
if (file.exists(newFullname) && (!overwrite)) {
if (file.exists(newFullname) && (preventOverwriting)) {
if (!silent) {
message("Output file '", newFilename, "' already exists and ",
"`overwrite` is set to FALSE - not writing output file!");
"`preventOverwriting` is set to TRUE - not writing output file!");
}
} else {
con <- file(description=newFullname,
......
......@@ -5,9 +5,75 @@
#' `rock::opts$get` to get options, or `rock::opts$reset` to reset specific or
#' all options to their default values.
#'
#' @usage rock::opts$set(...)
#' rock::opts$get(option, default=FALSE)
#' rock::opts$reset(...)
#' It is normally not necessary to get or set `rock` options. The defaults implement
#' the Reproducible Open Coding Kit (ROCK) standard, and deviating from these defaults
#' therefore means the processed sources and codes are not compatible and cannot be
#' processed by other software that implements the ROCK. Still, in some cases this
#' degree of customization might be desirable. The following options can be set:
#'
#' \describe{
#' \item{codeRegexes}{A named character vector with one or more regular
#' expressions that specify how to extract the codes (that were used to code the
#' sources). These regular expressions *must* each contain one capturing group
#' to capture the codes.}
#'
#' \item{idRegexes}{A named character vector with one or more regular
#' expressions that specify how to extract the different types of
#' identifiers. These regular expressions *must* each contain one capturing group
#' to capture the identifiers.}
#'
#' \item{sectionRegexes}{A named character vector with one or more regular
#' expressions that specify how to extract the different types of sections.}
#'
#' \item{autoGenerateIds}{The names of the `idRegexes` that, if missing, should receive
#' autogenerated identifiers (which consist of 'autogenerated_' followed by an
#' incrementing number).}
#'
#' \item{persistentIds}{The names of the `idRegexes` for the identifiers which, once
#' attached to an utterance, should be attached to all following utterances as well (until
#' a new identifier with the same name is encountered, after which that identifier will be
#' attached to all following utterances, etc).}
#'
#' \item{noCodes}{This regular expression is matched with all codes after they have been
#' extracted using the `codeRegexes` regular expression (i.e. they're matched against the
#' codes themselves without, for example, the square brackets in the default code regex). Any
#' codes matching this `noCodes` regular expression will be **ignored**, i.e., removed from the
#' list of codes.}
#'
#' \item{inductiveCodingHierarchyMarker}{For inductive coding, this marker is used to indicate
#' hierarchical relationships between codes. The code at the left hand side of this marker will
#' be considered the parent code of the code on the right hand side. More than two levels
#' can be specified in one code (for example, if the `inductiveCodingHierarchyMarker` is '>',
#' the code `grandparent>child>grandchild` would indicate codes at three levels.}
#'
#' \item{attributeContainers}{The name of YAML fragments containing case attributes (e.g.
#' metadata, demographic variables, quantitative data about cases, etc).}
#'
#' \item{codesContainers}{The name of YAML fragments containing (parts of) deductive coding
#' trees.}
#'
#' \item{delimiterRegEx}{The regular expression that is used to extract the YAML fragments.}
#'
#' \item{ignoreRegex}{The regular expression that is used to delete lines before any other
#' processing. This can be used to enable adding comments to sources, which are then ignored
#' during analysis.}
#'
#' \item{utteranceMarker}{How to specify breaks between utterances in the source(s). The
#' ROCK convention is to use a newline (`\\n`).}
#'
#' \item{coderId}{A regular expression specifying the coder identifier, specified
#' similarly to the codeRegexes.}
#'
#' \item{idForOmittedCoderIds}{The identifier to use for utterances that do not
#' have a coder id (i.e. utterance that occur in a source that does not specify
#' a coder id, or above the line where a coder id is specified).}
#'
#' \item{Two}{Second item}
#' }
#'
#' @aliases opts set get reset
#'
#' @usage rock::opts
#'
#' @param ... For `rock::opts$set`, the dots can be used to specify the options
#' to set, in the format `option = value`, for example, `utteranceMarker = "\n"`. For
......@@ -16,6 +82,21 @@
#' @param default The default value to return if the option has not been manually
#' specified.
#'
#' @examples ### Get the default utteranceMarker
#' rock::opts$get(utteranceMarker);
#'
#' ### Set it to a custom version, so that every line starts with a pipe
#' rock::opts$set(utteranceMarker = "\n|");
#'
#' ### Check that it worked
#' rock::opts$get(utteranceMarker);
#'
#' ### Reset this option to its default value
#' rock::opts$reset(utteranceMarker);
#'
#' ### Check that the reset worked, too
#' rock::opts$get(utteranceMarker);
#'
#' @export
opts <- list();
......@@ -43,41 +124,80 @@ opts$get <- function(option, default=FALSE) {
}
opts$reset <- function(...) {
dots <- list(...);
if (length(dots) == 0) {
optionNames <-
unlist(lapply(as.list(substitute(...())),
as.character));
if (length(optionNames) == 0) {
do.call(opts$set,
opts$defaults);
} else {
dotNames <- names(dots);
names(dots) <-
paste0("rock.", dotNames);
if (all(dotNames %in% names(opts$defaults))) {
prefixedOptionNames <-
paste0("rock.", optionNames);
if (all(optionNames %in% names(opts$defaults))) {
do.call(opts$set,
dots);
opts$defaults[optionNames]);
} else {
invalidOptions <-
!which(all(dotNames %in% names(opts$defaults)));
stop("Option(s) ", vecTxtQ(option[invalidOptions]),
!(optionNames %in% names(opts$defaults));
stop("Option(s) ", vecTxtQ(optionNames[invalidOptions]),
"' is/are not a valid (i.e. existing) option for the rock!");
}
}
}
opts$defaults <-
list(codeRegexes = c(codes = "\\[\\[([a-zA-Z0-9._>-]+)\\]\\]"),
list(### Used throughout
codeRegexes = c(codes = "\\[\\[([a-zA-Z0-9._>-]+)\\]\\]"),
idRegexes = c(caseId = "\\[\\[cid[=:]([a-zA-Z0-9._-]+)\\]\\]",
stanzaId = "\\[\\[sid[=:]([a-zA-Z0-9._-]+)\\]\\]",
coderId = "\\[\\[coderId[=:]([a-zA-Z0-9._-]+)\\]\\]"),
sectionRegexes = c(paragraphs = "---paragraph-break---",
secondary = "---<[a-zA-Z0-9]?>---"),
uidRegex = "\\[\\[uid[=:]([a-zA-Z0-9._-]+)\\]\\]",
inductiveCodingHierarchyMarker = ">",
### Used to parse sources
autoGenerateIds = c('stanzaId'),
persistentIds = c('caseId', 'coderId'),
noCodes = "^uid:|^uid=|^dct:|^ci:",
attributeContainers = c("rock_attributes"),
codesContainers = c("codes", "dct"),
delimiterRegEx = "^---$",
ignoreRegex = "^#",
### Used to merge sources
coderId = "\\[\\[coderId=([a-zA-Z0-9._-]+)\\]\\]",
idForOmittedCoderIds = "noCoderId",
### Used for cleaning sources and adding UIDs
codeDelimiters = c("[[", "]]"),
uidPrefix = "uid=",
utteranceMarker = "\n",
fragmentDelimiter = "\n\n-----\n\n",
inductiveCodingHierarchyMarker = ">",
replacementsPre = list(c("([^\\.])(\\.\\.)([^\\.])",
"\\1.\\3"),
c("([^\\.])(\\.\\.\\.\\.+)([^\\.])",
"\\1...\\3"),
c("(\\s*\\r?\\n){3,}",