| Title: | Render Multilingual Questionnaires from 'LimeSurvey' '.lss' Files |
| Version: | 0.1.0 |
| Description: | Render 'LimeSurvey' '.lss' survey exports as multilingual questionnaire documents in Word ('.docx') or PDF, displaying up to four languages side by side with localized chrome in English, French, German, Spanish and Italian. Includes a rule-based automated audit that flags missing translations, forward filter references, duplicate codes, array-scale inconsistencies and orphan structural references. Designed for anyone working with a 'LimeSurvey' survey: researchers, methodologists, ethics committees, translators and reviewers. Processing is fully local: the source file is the only input and no questionnaire content is uploaded to a third-party service. |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| Language: | en-US |
| Depends: | R (≥ 4.1) |
| Imports: | cli, rlang, xml2 |
| Suggests: | flextable, knitr, officer, rmarkdown, testthat (≥ 3.0.0), zip |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| URL: | https://amaltawfik.github.io/lssdoc/, https://github.com/amaltawfik/lssdoc |
| BugReports: | https://github.com/amaltawfik/lssdoc/issues |
| Config/roxygen2/version: | 8.0.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-06-07 08:21:58 UTC; at |
| Author: | Amal Tawfik |
| Maintainer: | Amal Tawfik <amal.tawfik@hesav.ch> |
| Repository: | CRAN |
| Date/Publication: | 2026-06-15 12:10:08 UTC |
lssdoc: Render Multilingual Questionnaires from LimeSurvey '.lss' Files
Description
Render LimeSurvey '.lss' survey exports as multilingual questionnaire documents in Word ('.docx') or PDF, displaying up to four languages side by side with localized chrome in English, French, German, Spanish and Italian. Includes a rule-based automated audit that flags missing translations, forward filter references, duplicate codes, array-scale inconsistencies and orphan structural references. Designed for anyone working with a LimeSurvey survey: researchers, methodologists, ethics committees, translators and reviewers. Processing is fully local: the source file is the only input and no questionnaire content is uploaded to a third-party service.
Example surveys
Two example .lss files ship with the package and are reachable with
base::system.file(), so every reader can reproduce the examples and
the Get started vignette without supplying their own LimeSurvey
export:
-
demo_survey.lss– a clean, synthetic four-language survey (English, French, German, Spanish) with quotas and a consent block:system.file("extdata", "demo_survey.lss", package = "lssdoc"). -
audit_demo.lss– a deliberately flawed survey seeded with every anomalyaudit_lss()detects:system.file("extdata", "audit_demo.lss", package = "lssdoc").
Author(s)
Maintainer: Amal Tawfik amal.tawfik@hesav.ch (ORCID) (ROR) [copyright holder]
Authors:
Amal Tawfik amal.tawfik@hesav.ch (ORCID) (ROR) [copyright holder]
See Also
Useful links:
Report bugs at https://github.com/amaltawfik/lssdoc/issues
Audit a LimeSurvey survey for reviewable anomalies
Description
Inspect a LimeSurvey survey and flag anomalies that can be detected without any AI. The audit guides a human reviewer; it does not silently correct anything. Every finding names a precise location and a severity.
Usage
audit_lss(input)
Arguments
input |
Either a path to a |
Details
Checks performed:
-
Missing translations – a question, help, answer, or subquestion text present in at least one language but empty in another.
-
Empty in all languages – a translatable text empty in every language.
-
Duplicate codes – a question variable code repeated in the survey, or an answer/subquestion code repeated within one question.
-
Whitespace in codes – a question, subquestion or answer code containing leading, trailing or interior whitespace (likely a typo; causes subtle bugs in the data export).
-
Missing options for the type – a question whose type requires answer options or subquestions but has none (per the type taxonomy).
-
Forward filter references – a relevance expression that names a variable appearing at or after the filtered question (the value is not yet collected when the filter is evaluated).
-
Array-scale inconsistencies – an array (single or dual) whose subquestions reference a
scale_idthat has no answer options, or vice versa. -
Orphan references – a subquestion or answer pointing to a question that does not exist.
Value
An object of class lss_audit: a list with file,
languages, summary counts, and a findings data frame
(severity, check, location, language, message). It has
a print() method and an as.data.frame() method.
See Also
render_audit() to write the same findings to a Word or
PDF document.
Examples
# A deliberately flawed demo survey ships with the package, seeded
# with every anomaly the audit detects.
demo <- system.file("extdata", "audit_demo.lss", package = "lssdoc")
audit_lss(demo)
Print an lss_audit object
Description
Pretty-printed audit summary on the console, capped at the first
n findings. Severity-based bullet symbols (errors, warnings,
notes) mirror what is shown in the audit table inside the
rendered .docx.
Usage
## S3 method for class 'lss_audit'
print(x, ..., n = 20L)
Arguments
x |
An |
... |
Currently ignored. |
n |
Maximum number of findings to print. Defaults to |
Value
The audit object, invisibly.
Read a LimeSurvey .lss file
Description
Read a LimeSurvey survey structure export (.lss, an XML file) and turn
it into a structured lss object that the rest of the package can
audit (audit_lss()) and render (render_questionnaire(),
render_audit()). Parsing is fully local: the file is never uploaded
anywhere.
Usage
read_lss(file)
Arguments
file |
Character. Path to a |
Details
The .lss format is a LimeSurvey XML export. Since DBVersion 4xx/7xx
the translatable text lives in dedicated localization sections
(*_l10ns), keyed by language, while the structural sections hold
identifiers and settings. read_lss() reads every section into a tidy
data frame without mutating any user-facing identifier or text. A
field that is present but empty (e.g. <help/>) is read as ""; a
field that is absent from a row is read as NA.
Value
An object of class lss: a list with the survey languages,
metadata, and one data frame per .lss section. Structural sections
(surveys, groups, questions, subquestions, answers,
question_attributes, conditions) stay separate from the
localized text sections (survey_language_settings, group_l10ns,
question_l10ns, answer_l10ns), which carry the per-language
titles, labels, and help texts. All values are read verbatim as
character.
Examples
# A synthetic four-language demo survey ships with the package.
demo <- system.file("extdata", "demo_survey.lss", package = "lssdoc")
lss <- read_lss(demo)
lss$languages
Render the audit as a focused Word or PDF document
Description
Build a short, action-oriented document containing only the audit findings: the same cover page as the full questionnaire document, summary counts, then one table per severity (errors, warnings, notes) listing every finding with its location and message. Use it for QA follow-up or to share issues with a colleague without distributing the full questionnaire.
Usage
render_audit(
input,
output,
languages = NULL,
logo = NULL,
logo_width = 1.5,
logo_height = 0.75,
font = NULL,
font_code = NULL,
colors = NULL,
authors = NULL,
description = NULL,
chrome_lang = NULL
)
Arguments
input |
Either a path to a |
output |
Character. Path to the file to create. The extension
determines the output format: |
languages |
Character vector of language codes used on the
cover page. |
logo |
Optional path (character) to a PNG or JPEG image
displayed at the top of the cover page. |
logo_width, logo_height |
Image dimensions in inches. Defaults
|
font |
Optional body font name (character). |
font_code |
Optional monospace font (character) used for
code-like content (variable codes, raw expressions). |
colors |
Optional named list of hex color overrides for the
editorial petrol-blue palette. |
authors, description |
Optional cover-page credit block
( |
chrome_lang |
Language used for the document chrome (column
headers, row labels, audit section). One of |
Value
The output path, invisibly.
See Also
audit_lss() to inspect the same findings in the console;
render_questionnaire() for the full questionnaire document.
Examples
## Not run:
# One-shot (path -> .docx)
render_audit(
system.file("extdata", "demo_survey.lss",
package = "lssdoc"),
tempfile(fileext = ".docx")
)
# PDF output -- same call, just pass a .pdf path
render_audit("survey.lss", "qa.pdf")
## End(Not run)
Render a LimeSurvey questionnaire to a Word or PDF document
Description
Build a professional questionnaire document from a LimeSurvey survey,
displaying up to four languages side by side. Each question becomes a
compact flextable with a meta header (variable code, type, mandatory,
filter) shown once, language column headers, the question text per
language, and the subquestion or answer-option rows underneath – codes
on the left, labels per language on the right. Headings, a metadata
cover page, an optional table of contents, and an optional audit summary
tie the document together. Rendering uses the suggested packages
officer and flextable; both must be installed.
Usage
render_questionnaire(
input,
output,
languages = NULL,
template = c("cards", "table"),
layout = c("auto", "side-by-side", "stacked"),
show_audit = TRUE,
show_help = TRUE,
show_attrs = c("prefix", "suffix", "other_replace_text", "validation"),
show_technical_attrs = FALSE,
page_format = c("auto", "A4-portrait", "A4-landscape", "A3"),
show_toc = TRUE,
show_index = TRUE,
show_quotas = TRUE,
show_header_title = TRUE,
show_source = TRUE,
show_item_heading = FALSE,
show_raw_filter = FALSE,
show_groups = TRUE,
show_welcome = TRUE,
show_endtext = TRUE,
show_description = TRUE,
show_consent = TRUE,
show_privacy_settings = FALSE,
show_admin_settings = FALSE,
title = NULL,
logo = NULL,
logo_width = 1.5,
logo_height = 0.75,
font = NULL,
font_code = NULL,
colors = NULL,
authors = NULL,
description = NULL,
chrome_lang = NULL,
variable_names = c("brackets", "underscore"),
base_size = 10L
)
Arguments
input |
Either a path to a |
output |
Character. Path to the file to create. The extension
determines the output format: |
languages |
Character vector of language codes to display,
in the order they will appear as columns. |
template |
Output style. One of
|
layout |
Reserved for future use. Currently |
show_audit |
Logical. If |
show_help |
Logical. If |
show_attrs |
Character vector of question attributes to surface
under the question text when present. Default keeps the attributes
that change how respondents see the item: |
show_technical_attrs |
Logical. If |
page_format |
Page format. One of |
show_toc |
Logical. If |
show_index |
Logical. If |
show_quotas |
Logical. If |
show_header_title |
Logical. If |
show_source |
Logical. If |
show_item_heading |
Logical. If |
show_raw_filter |
Logical. If |
show_groups |
Logical. If |
show_welcome |
Logical. If |
show_endtext |
Logical. If |
show_description |
Logical. If |
show_consent |
Logical. If |
show_privacy_settings |
Logical. If |
show_admin_settings |
Logical. If |
title |
Optional override of the survey title shown on the
cover and the top-right header. |
logo |
Optional path (character) to a PNG or JPEG image
displayed at the top of the cover page. |
logo_width, logo_height |
Image dimensions in inches.
Defaults |
font |
Optional body font name (character). |
font_code |
Optional monospace font name (character) used
for code-like content: the variable column in each meta table,
the raw relevance expression under each filter cell, and the
variable index entries. |
colors |
Optional named list of hex color overrides for the
editorial petrol-blue palette. |
authors |
Optional credit block for the questionnaire's
designers, displayed on the cover page below the subtitle.
Each author is shown centered on its own line as
|
description |
Optional free-form text (single string) shown
on the cover page below the authors block. |
chrome_lang |
Language used for the chrome of the document
(column headers, row labels, navigation titles, type labels,
Value descriptors, audit section). One of |
variable_names |
How response-variable names are written, so the document matches the data file the reader holds. One of:
|
base_size |
Body type size in points (default |
Value
The output path, invisibly.
"LimeSurvey last save" date on the cover
The cover metadata table carries a row labelled
"LimeSurvey last save" (or its localized equivalent). It is read
verbatim from the surveys.lastmodified column of the .lss,
which is the only timestamp LimeSurvey writes into the export –
no other table (questions, question_l10ns, answer_l10ns,
groups, etc.) carries a per-row modification date. The row is
named "last save" rather than "last modified" because LimeSurvey
only bumps that field reliably when the user clicks Save on a
survey-level form (Settings tab); editing a question text, an
answer label, or a translation through the Question Editor does
not consistently update it across LimeSurvey versions. If the
date looks stale relative to your most recent edits, the
workaround is to open Survey settings in LimeSurvey, click
Save (no other change needed), then re-export the .lss. The
next render will show the bumped timestamp.
Field-update prompt in Word
Opening the rendered .docx in Microsoft Word may surface a
security-style prompt: "This document contains fields that may
refer to other files. Do you want to update the fields in this
document?". This is expected: the package marks the page-number
and bookmark-reference fields as needing a refresh so the footer
shows the correct page count and the table of contents links
resolve to the right pages on first open (this is also what makes
headless PDF conversion via LibreOffice produce correctly
paginated output without a manual F9). Clicking Yes is safe –
the document has no INCLUDETEXT, INCLUDEPICTURE-linked, or DDE
fields; the only external links are the ORCID and DOI URLs in the
cover credits, which are static HYPERLINK targets and not fetched
on update.
PDF output
When output ends in .pdf, the function first renders a .docx
to a temporary location and then converts it locally via
LibreOffice headless (or Word on Windows). LibreOffice
(soffice executable) must be installed and on PATH; otherwise
a classed error explains how to install it. Conversion stays on
the user's machine: no upload, no network call. LibreOffice
headless does not refresh Word field values (TOC, page counts)
during conversion, so the table of contents may appear empty in
the converted PDF. To obtain a PDF with a populated TOC, render to
.docx instead, open it in Word (the TOC refreshes automatically)
and use File > Save As > PDF.
See Also
render_audit() for the audit-only document;
audit_lss() to inspect findings in the console without
rendering; read_lss() to pre-parse a .lss file once and
render multiple variants.
Examples
## Not run:
file <- system.file("extdata", "demo_survey.lss", package = "lssdoc")
# One-shot: parse + render Word document
render_questionnaire(file, tempfile(fileext = ".docx"))
# Same call, PDF output (format inferred from extension)
render_questionnaire(file, tempfile(fileext = ".pdf"))
# Parse once, render several variants without re-parsing
lss <- read_lss(file)
render_questionnaire(lss, tempfile(fileext = ".docx"),
languages = "en")
render_questionnaire(lss, tempfile(fileext = ".docx"),
template = "table",
languages = c("en", "fr"))
# Branded cover with authors block and palette override
render_questionnaire(
lss,
tempfile(fileext = ".docx"),
template = "table",
chrome_lang = "en",
colors = list(primary = "#5C9F1A", accent = "#7FA82E"),
authors = list(
list(name = "Jane Doe", affiliation = "HESAV",
orcid = "0009-0001-2345-6789"),
list(name = "John Doe", affiliation = "HESAV",
orcid = "0009-0002-3456-7890")
)
)
## End(Not run)