Как запустить функции документации внутри roxygen2 @examples?

У меня есть множество подобных функций, в документации которых нужно изменить всего одно или два слова. Чтобы ограничить дублирование, я использую функции из документации.

Это работает в roxygen2 для @description и @param, но я не могу заставить его работать для @examples. Встроенный код не оценивается.

Пример

useless_description <- function(name) {
  paste0('This useless function prints the word "', name , '" n times.')
}

useless_example <- function(name) {
  paste("# Print ", name, " 1 time",
        name, "(1)",
        "",
        "# Print ", name, " 3 times",
        name, "(3)",
        sep = "\n"
        )
}

#' @title Hello
#' @description `r useless_description("hello")`
#' @examples `r useless_example("hello")`
hello <- function(n) {
  print(rep("hello", n))
}

#' @title Goodbye
#' @description `r useless_description("goodbye")`
#' @examples `r useless_example("hello")`
goodbye <- function(n) {
  print(rep("goodbye", n))
}

При запуске devtools::document() для функции hello() создается страница справки:

Возможное решение с помощью @eval

Я нашел способ обойти эту проблему, но он использует замененное ключевое слово @eval.

useless_example2 <- function(name) {
  c("@examples ",
    paste0("# Print ", name, " 1 time"),
    paste0(name, "(1)"),
    "",
    paste0("# Print ", name, " 3 time"),
    paste0(name, "(3)")
    )
}

#' @title Hello
#' @description `r useless_description("hello")`
#' @eval useless_example2("hello")
hello <- function(n) {
  print(rep("hello", n))
}

Итоговая страница справки:

Вопрос

Есть ли способ оценить встроенный код в roxygen2 @examples без использования замененных функций?

Я новичок в разработке пакетов. Я не могу воспроизвести пример документа roxygen2.r-lib.org/articles/reuse.html#inline-code; Я вижу буквально «Название 'r 1 + 1'». Я мало чем могу помочь; за исключением того, что я заметил, что вы используете paste0() с sep = "\n)" в useless_example, что является формальным аргументом только paste() (а не paste0(). Я буду следить за этим постом.

VinceGreg 10.06.2024 16:09

Если вы считаете, что пакет не работает так, как описано в документации, вам следует сообщить авторам о проблеме на github.

MrFlick 10.06.2024 19:05

@VinceGreg, ты прав paste(); Я обновил пример. Однако я не могу воспроизвести ваш пример. Код работает для меня. Пожалуйста, откройте новый вопрос, тогда я постараюсь вам помочь.

Johan Ejstrud 11.06.2024 07:11

@VinceGreg, ты добавил Roxygen: list(markdown = TRUE) в свой файл DESCRIPTION?

the-mad-statter 21.06.2024 03:18

@the-mad-statter, ты был прав! После быстрого поиска я использовал альтернативу; usethis::use_roxygen_md() , как объяснено [в документе roxygen2] (roxygen2.r-lib.org/articles/rd-formatting.html)

VinceGreg 21.06.2024 04:50
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
5
146
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Прежде всего обратите внимание, что использование встроенного кода с {Roxygen2} работает только в том случае, если включена поддержка уценки. Это достигается либо:

  1. глобально, вставив Roxygen: list(markdown = TRUE) в файл ОПИСАНИЯ пакета (например, usethis::use_roxygen_md()) или
  2. локально, используя @md в текущем кислородном блоке

Как вы заметили, использование @eval было заменено в пользу встроенного кода R.

На той же странице авторы говорят:

Встроенная уценка R может генерировать текст уценки только внутри тега, поэтому в принципе она менее гибкая, чем @eval/@evalRd/@template. Однако наш опыт показал, что создание нескольких тегов одновременно имеет тенденцию быть довольно негибким, и вам часто приходится проводить рефакторинг на более мелкие части, поэтому мы не считаем, что это отражает реальную потерю функциональности.

Я вижу два момента, которые стоит повторить:

  1. Встроенная уценка/код R может генерироваться только для каждого тега.
  2. Авторы не заинтересованы в изменении такого поведения.

Тогда на этой странице авторы отмечают, что:

Некоторые теги roxygen не анализируются как уценка. Большинство из них вряд ли будут содержать текст, требующий разметки, поэтому это не является важным ограничением. Теги без поддержки уценки: @aliases, @backref, @docType, @encoding, @evalRd, @example, @examples, @family, @inheritParams, @keywords, @method @name, @md, @noMd, @noRd, @ rdname, @rawRd, @usage.

Вот почему ваш встроенный код работает для @description, но не работает для @examples, поскольку авторы пакета явно решили не поддерживать встроенный код для @examples.

Если вы хотите следовать замыслу авторов пакета и не использовать устаревшие функции, я предлагаю вам расширить {roxygen2} своим собственным тегом. Вы даже можете сделать так, чтобы ваш тег просто добавлялся к уже существующему разделу примеров.

Несмотря на то, что придется разобраться с некоторыми тонкостями, добавление собственного пользовательского тега может быть таким же простым, как определение двух таких функций:

roxy_tag_parse.roxy_tag_examples2 <- function(x) {
  roxygen2::tag_markdown(x)
}

roxy_tag_rd.roxy_tag_examples2 <- function(x, base_path, env) {
  roxygen2::rd_section("examples", x$val)
}

Затем загрузите эти функции в память перед документированием вашего пакета.

Вот пример файла пакета R:

roxygen_generate_description <- function(x) {
  sprintf('This function prints the word "%s" n times.', x)
}

# a kink to workout:
# - use \u0023 for # to avoid an attempt at a level 1 header
roxygen_generate_examples <- function(x) {
  paste(
    sprintf("\u0023 Print %s 1 time", x),
    sprintf("%s(1)", x),
    "",
    sprintf("\u0023 Print %s 3 times", x),
    sprintf("%s(3)", x),
    sep = "\n"
  )
}

#' @title Hello
#' @description `r roxygen_generate_description("hello")`
#' @examples2 `r roxygen_generate_examples("hello")`
hello <- function(n) {
  print(rep("hello", n))
}

И затем делаем:

devtools::document()
?hello

Мы получаем это:

Отличное объяснение и запись. Думаю, я попробую использовать @eval, поскольку он делает то же самое, но с гораздо меньшей сложностью.

Johan Ejstrud 21.06.2024 10:31

Другие вопросы по теме