From 927aed18dfce9a31f3f8ff9405d61b633bd7366f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Revilla?= Date: Tue, 17 Mar 2026 09:51:00 +0100 Subject: [PATCH 1/4] Force UTF-8 encoding when parsing code --- R/qenv-eval_code.R | 4 ++-- R/qenv-get_code.R | 2 +- R/utils-get_code_dependency.R | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/R/qenv-eval_code.R b/R/qenv-eval_code.R index cb37d14a9..ac9556d55 100644 --- a/R/qenv-eval_code.R +++ b/R/qenv-eval_code.R @@ -47,7 +47,7 @@ setMethod("eval_code", signature = c(object = "qenv.error"), function(object, co code <- paste(split_code(code), collapse = "\n") object@.xData <- rlang::env_clone(object@.xData, parent = parent.env(object@.xData)) - parsed_code <- parse(text = code, keep.source = TRUE) + parsed_code <- parse(text = code, keep.source = TRUE, encoding = "UTF-8") old <- evaluate::inject_funs( library = function(...) { @@ -72,7 +72,7 @@ setMethod("eval_code", signature = c(object = "qenv.error"), function(object, co for (this in out) { if (inherits(this, "source")) { this_code <- gsub("\n$", "", this$src) - attr(this_code, "dependency") <- extract_dependency(parse(text = this_code, keep.source = TRUE)) + attr(this_code, "dependency") <- extract_dependency(parse(text = this_code, keep.source = TRUE, encoding = "UTF-8")) new_code <- c(new_code, stats::setNames(list(this_code), sample.int(.Machine$integer.max, size = 1))) } else { last_code <- new_code[[length(new_code)]] diff --git a/R/qenv-get_code.R b/R/qenv-get_code.R index 136096100..1af5630a3 100644 --- a/R/qenv-get_code.R +++ b/R/qenv-get_code.R @@ -119,7 +119,7 @@ setMethod("get_code", signature = "qenv", function(object, deparse = TRUE, names if (deparse) { paste(unlist(code), collapse = "\n") } else { - parse(text = paste(c("{", unlist(code), "}"), collapse = "\n"), keep.source = TRUE) + parse(text = paste(c("{", unlist(code), "}"), collapse = "\n"), keep.source = TRUE, encoding = "UTF-8") } }) diff --git a/R/utils-get_code_dependency.R b/R/utils-get_code_dependency.R index 4adea57db..ec9615f27 100644 --- a/R/utils-get_code_dependency.R +++ b/R/utils-get_code_dependency.R @@ -407,7 +407,7 @@ extract_dependency <- function(parsed_code) { queue <- as.list(parsed_code[[1]][expr_ix]) new_list <- parsed_code[[1]] new_list[expr_ix] <- NULL - list(parse(text = as.expression(new_list), keep.source = TRUE)) + list(parse(text = as.expression(new_list), keep.source = TRUE, encoding = "UTF-8")) } while (length(queue) > 0) { @@ -416,7 +416,7 @@ extract_dependency <- function(parsed_code) { if (identical(current[[1L]], as.name("{"))) { queue <- append(queue, as.list(current)[-1L]) } else { - parsed_code_list[[length(parsed_code_list) + 1]] <- parse(text = as.expression(current), keep.source = TRUE) + parsed_code_list[[length(parsed_code_list) + 1]] <- parse(text = as.expression(current), keep.source = TRUE, encoding = "UTF-8") } } @@ -556,7 +556,7 @@ normalize_pd <- function(pd) { #' @keywords internal #' @noRd get_call_breaks <- function(code) { - parsed_code <- parse(text = code, keep.source = TRUE) + parsed_code <- parse(text = code, keep.source = TRUE, encoding = "UTF-8") pd <- utils::getParseData(parsed_code) pd <- normalize_pd(pd) pd <- pd[pd$token != "';'", ] From 0f62311dde34e5041e4a6f15015eeef34c0aa4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Revilla?= Date: Tue, 17 Mar 2026 09:52:38 +0100 Subject: [PATCH 2/4] Add a test to cover this issue --- tests/testthat/test-qenv_within.R | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/testthat/test-qenv_within.R b/tests/testthat/test-qenv_within.R index 14a311a38..1d44db7b2 100644 --- a/tests/testthat/test-qenv_within.R +++ b/tests/testthat/test-qenv_within.R @@ -154,3 +154,15 @@ testthat::test_that("Code executed with integer shorthand (1L) is the same as or q <- within(qenv(), a <- 1L) testthat::expect_identical(get_code(q), "a <- 1L") }) + + +testthat::test_that("Chinese characters are handled properly (issue 284)", { + q <- within(qenv(), { + "无进展生存期 (月)" + "总生存期 (月)" + "缓解持续时间 (月)" + "确认的缓解持续时间 (月)" + }) + + expect_equal(lengths(strsplit(get_code(q), split = "\n", fixed = TRUE)), 4L) +}) From fe998d9aa294d6bd5cac9fb8cfc7ce4fc4e577fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Revilla?= Date: Tue, 17 Mar 2026 10:01:18 +0100 Subject: [PATCH 3/4] Add sentence on NEWS --- NEWS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS.md b/NEWS.md index f7f04c503..2a2fde5db 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ # teal.code 0.7.1.9000 +### Bug fixes + +* Fixed a problem parsing Chinese characters due to the encoding (#284) + # teal.code 0.7.1 ### Bug fixes From 6ff32dad077b16bbd7d6cfd2b466a36bf5ee531f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Revilla?= Date: Tue, 17 Mar 2026 10:11:58 +0100 Subject: [PATCH 4/4] Avoid lines too long (lintr) --- R/qenv-eval_code.R | 5 ++++- R/utils-get_code_dependency.R | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/R/qenv-eval_code.R b/R/qenv-eval_code.R index ac9556d55..76a48258c 100644 --- a/R/qenv-eval_code.R +++ b/R/qenv-eval_code.R @@ -72,7 +72,10 @@ setMethod("eval_code", signature = c(object = "qenv.error"), function(object, co for (this in out) { if (inherits(this, "source")) { this_code <- gsub("\n$", "", this$src) - attr(this_code, "dependency") <- extract_dependency(parse(text = this_code, keep.source = TRUE, encoding = "UTF-8")) + attr(this_code, "dependency") <- extract_dependency(parse( + text = this_code, + keep.source = TRUE, encoding = "UTF-8" + )) new_code <- c(new_code, stats::setNames(list(this_code), sample.int(.Machine$integer.max, size = 1))) } else { last_code <- new_code[[length(new_code)]] diff --git a/R/utils-get_code_dependency.R b/R/utils-get_code_dependency.R index ec9615f27..0475927b8 100644 --- a/R/utils-get_code_dependency.R +++ b/R/utils-get_code_dependency.R @@ -416,7 +416,8 @@ extract_dependency <- function(parsed_code) { if (identical(current[[1L]], as.name("{"))) { queue <- append(queue, as.list(current)[-1L]) } else { - parsed_code_list[[length(parsed_code_list) + 1]] <- parse(text = as.expression(current), keep.source = TRUE, encoding = "UTF-8") + parsed_code <- parse(text = as.expression(current), keep.source = TRUE, encoding = "UTF-8") + parsed_code_list[[length(parsed_code_list) + 1]] <- parsed_code } }