Skip to content

Commit 3eaf727

Browse files
Convert to roxygen2 (#263)
* Convert .Rd to roxygen2 * Convert roxygen2 to md * Convert lists * Add missing `@rdname` tags * Generate namespace with roxygen2 * improve wrapping * add a verbal example. * keep organization grouping of data.table imports Co-authored-by: Michael Chirico <michaelchirico4@gmail.com>
1 parent c9a35b0 commit 3eaf727

23 files changed

Lines changed: 1118 additions & 316 deletions

NAMESPACE

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,49 @@
1-
importFrom(data.table, data.table, foverlaps, fread, rbindlist, uniqueN, chmatch, "%chin%")
2-
importFrom(data.table, is.data.table, as.data.table)
3-
importFrom(data.table, copy, set, setattr, setcolorder, setDT, setindexv, setkeyv, setnafill, setnames, setorderv)
4-
importFrom(data.table, `:=`, .BY, .N, .SD)
5-
importFrom(data.table, fcase, fifelse, shift, tstrsplit)
1+
# Generated by roxygen2: do not edit by hand
62

7-
importFrom(stats, setNames)
8-
importFrom(utils, getParseData, globalVariables, head, tail, type.convert)
9-
10-
export(translate_package)
3+
S3method(all,equal.specials_metadata)
4+
S3method(format,po_metadata)
5+
S3method(format,specials_metadata)
6+
S3method(print,po_metadata)
7+
export(check_cracked_messages)
8+
export(check_potools_sys_reqs)
9+
export(check_untranslated_cat)
10+
export(check_untranslated_src)
1111
export(get_message_data)
12-
export(write_po_file, po_metadata)
13-
14-
export(po_extract)
1512
export(po_compile)
16-
17-
export(check_cracked_messages, check_untranslated_cat, check_untranslated_src)
18-
19-
export(check_potools_sys_reqs)
20-
21-
S3method(format, specials_metadata)
22-
S3method(all.equal, specials_metadata)
23-
24-
S3method(format, po_metadata)
25-
S3method(print, po_metadata)
13+
export(po_extract)
14+
export(po_metadata)
15+
export(translate_package)
16+
export(write_po_file)
17+
importFrom(data.table,"%chin%")
18+
importFrom(data.table,.BY)
19+
importFrom(data.table,.N)
20+
importFrom(data.table,.SD)
21+
importFrom(data.table,`:=`)
22+
importFrom(data.table,as.data.table)
23+
importFrom(data.table,chmatch)
24+
importFrom(data.table,copy)
25+
importFrom(data.table,data.table)
26+
importFrom(data.table,fcase)
27+
importFrom(data.table,fifelse)
28+
importFrom(data.table,foverlaps)
29+
importFrom(data.table,fread)
30+
importFrom(data.table,is.data.table)
31+
importFrom(data.table,rbindlist)
32+
importFrom(data.table,set)
33+
importFrom(data.table,setDT)
34+
importFrom(data.table,setattr)
35+
importFrom(data.table,setcolorder)
36+
importFrom(data.table,setindexv)
37+
importFrom(data.table,setkeyv)
38+
importFrom(data.table,setnafill)
39+
importFrom(data.table,setnames)
40+
importFrom(data.table,setorderv)
41+
importFrom(data.table,shift)
42+
importFrom(data.table,tstrsplit)
43+
importFrom(data.table,uniqueN)
44+
importFrom(stats,setNames)
45+
importFrom(utils,getParseData)
46+
importFrom(utils,globalVariables)
47+
importFrom(utils,head)
48+
importFrom(utils,tail)
49+
importFrom(utils,type.convert)

R/check_cracked_messages.R

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,46 @@
11
# check for calls like stop("a", i, "b", j) that are better suited for
22
# translation as calls like gettextf("a%db%d", i, j)
3+
4+
5+
#' Check for cracked messages more suitable for templating
6+
#'
7+
#' Diagnose the R messages in a package to discover the presence of "cracked"
8+
#' messages better served for translation by templating. See Details.
9+
#'
10+
#'
11+
#' Error messages built like
12+
#' `stop("You gave ", n, " arguments, but ", m, " are needed.")` are
13+
#' in general hard for translators -- the correct
14+
#' translation may be in a totally different order (e.g., this is often the
15+
#' case for Japanese). It is preferable instead to use
16+
#' [base::gettextf()] to build a templated message like
17+
#' `stop(gettextf("You gave %d arguments but %d are needed.", n, m))`.
18+
#' Translators are then free to rearrange the template to put the numeric
19+
#' pattern where it fits most naturally in the target language.
20+
#'
21+
#' @param message_data A `data.table`, or object convertible to one.
22+
#' @return A `data.table` with columns `call`, `file`,
23+
#' `line_number`, and `replacement` summarizing the results.
24+
#' @author Michael Chirico
25+
#' @seealso [translate_package()], [update_pkg_po()]
26+
#' @examples
27+
#'
28+
#' pkg <- file.path(system.file(package = 'potools'), 'pkg')
29+
#' # copy to a temporary location to be able to read/write/update below
30+
#' tmp_pkg <- file.path(tempdir(), "pkg")
31+
#' dir.create(tmp_pkg)
32+
#' file.copy(pkg, dirname(tmp_pkg), recursive = TRUE)
33+
#'
34+
#' # first, extract message data
35+
#' message_data = get_message_data(tmp_pkg)
36+
#'
37+
#' # now, diagnose the messages for any "cracked" ones
38+
#' check_cracked_messages(message_data)
39+
#'
40+
#' # cleanup
41+
#' unlink(tmp_pkg, recursive = TRUE)
42+
#' rm(pkg, tmp_pkg, message_data)
43+
#' @export
344
check_cracked_messages = function(message_data) {
445
if (!is.data.table(message_data)) message_data = as.data.table(message_data)
546

R/check_untranslated_cat.R

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,57 @@
11
# check a package for calls to cat() that have untranslated strings (i.e.,
22
# aren't passed through gettext or ngettext)
3+
4+
5+
#' Check for untranslated messages emitted by cat
6+
#'
7+
#' Diagnose the R messages in a package to discover the presence of messages
8+
#' emitted by [cat()] which haven't been translated (i.e., passed
9+
#' through [gettext()], [gettextf()], or
10+
#' [ngettext()]).
11+
#'
12+
#'
13+
#' The function `cat` is commonly used to emit messages to users (e.g.,
14+
#' for a `verbose` mode), but it is not equipped for translation. Instead,
15+
#' messages must first be translated and then emitted. Any character literals
16+
#' found in the package's R code used in `cat` but not translated will be
17+
#' flagged by this function.
18+
#'
19+
#' For flagged calls, a potential replacement is offered, built using
20+
#' `gettext` or `gettextf` (depending on whether one or more
21+
#' `...` arguments are supplied to `cat`). For the `gettextf`
22+
#' case, the suggested template is always `%s` (string) since this works
23+
#' for all inputs; the author should tighten this to the appropriate
24+
#' [sprintf()] template marker as appropriate, for example if the author
25+
#' knows the input is an integer, use `%d` or `%i` instead of `%s`.
26+
#'
27+
#' NB: not all `cat` calls are included -- in particular, no `cat`
28+
#' call specifying a non-default `file` are flagged, nor are any where the
29+
#' supplied `sep` is not a character literal (e.g., `sep=x` instead
30+
#' of `sep=""`)
31+
#'
32+
#' @param message_data A `data.table`, or object convertible to one.
33+
#' @return A `data.table` with columns `call`, `file`,
34+
#' `line_number`, and `replacement` summarizing the results.
35+
#' @author Michael Chirico
36+
#' @seealso [translate_package()], [update_pkg_po()]
37+
#' @examples
38+
#'
39+
#' pkg <- file.path(system.file(package = 'potools'), 'pkg')
40+
#' # copy to a temporary location to be able to read/write/update below
41+
#' tmp_pkg <- file.path(tempdir(), "pkg")
42+
#' dir.create(tmp_pkg)
43+
#' file.copy(pkg, dirname(tmp_pkg), recursive = TRUE)
44+
#'
45+
#' # first, extract message data
46+
#' message_data = get_message_data(tmp_pkg)
47+
#'
48+
#' # now, diagnose the messages for any untranslated strings shown through cat()
49+
#' check_untranslated_cat(message_data)
50+
#'
51+
#' # cleanup
52+
#' unlink(tmp_pkg, recursive = TRUE)
53+
#' rm(pkg, tmp_pkg, message_data)
54+
#' @export
355
check_untranslated_cat <- function (message_data) {
456
if (!is.data.table(message_data)) message_data = as.data.table(message_data)
557
# not iron-clad but it's a good first pass

R/check_untranslated_src.R

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,46 @@
11
# check a package for character arrays in messaging functions that
22
# haven't been passed through the translation macro
3+
4+
5+
#' Check for cracked messages in C/C++ sources
6+
#'
7+
#' Diagnose the C/C++ messages in a package to discover untranslated messages
8+
#'
9+
#'
10+
#' This diagnostic looks for literal `char` arrays passed to messaging
11+
#' functions (as identified by [translate_package()]) which are not
12+
#' marked for translation (by tagging them for translation with `_` or
13+
#' `N_` macros). These strings cannot be translated until they are so
14+
#' marked.
15+
#'
16+
#' @param message_data A `data.table`, or object convertible to one.
17+
#' @return A `data.table` with columns `call`, `file`,
18+
#' `line_number`, and `replacement` summarizing the results.
19+
#' `replacement` is `NA` at this time, i.e., no replacement is
20+
#' provided.
21+
#' @author Michael Chirico
22+
#' @seealso [translate_package()], [update_pkg_po()]
23+
#' @examples
24+
#'
25+
#' pkg <- file.path(system.file(package = 'potools'), 'pkg')
26+
#' # copy to a temporary location to be able to read/write/update below
27+
#' tmp_pkg <- file.path(tempdir(), "pkg")
28+
#' dir.create(tmp_pkg)
29+
#' file.copy(pkg, dirname(tmp_pkg), recursive = TRUE)
30+
#'
31+
#' # first, extract message data
32+
#' message_data = get_message_data(
33+
#' tmp_pkg,
34+
#' custom_translation_functions = list(src = "ReverseTemplateMessage:2")
35+
#' )
36+
#'
37+
#' # now, diagnose the messages for any untranslated messages in C/C++
38+
#' check_untranslated_src(message_data)
39+
#'
40+
#' # cleanup
41+
#' unlink(tmp_pkg, recursive = TRUE)
42+
#' rm(pkg, tmp_pkg, message_data)
43+
#' @export
344
check_untranslated_src <- function (message_data) {
445
if (!is.data.table(message_data)) message_data = as.data.table(message_data)
546

R/get_message_data.R

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,63 @@
11
#' Extract user-visible messages from a package
22
#'
33
#' This function looks in the R and src directories of a package for
4-
#' user-visible messages and compiles them as a [data.table::data.table()]
5-
#' to facilitate analyzing this corpus as such.
4+
#' user-visible messages and compiles them as a
5+
#' [data.table::data.table()] to facilitate
6+
#' analyzing this corpus as such.
67
#'
7-
#' @param dir Character, default the present directory; a directory in which
8-
#' an R package is stored.
8+
#'
9+
#' @param dir Character, default the present directory; a directory in which an
10+
#' R package is stored.
911
#' @param custom_translation_functions A `list` with either/both of two
10-
#' components, `R` and `src`, together governing how to extract any
11-
#' non-standard strings from the package.
12+
#' components, `R` and `src`, together governing how to extract any
13+
#' non-standard strings from the package.
1214
#'
13-
#' See Details in [translate_package()].
15+
#' See Details in [`translate_package()`][translate_package].
1416
#' @param style Translation style, either `"base"` or `"explict"`.
15-
#' The default, `NULL`, reads from the `DESCRIPTION` field
16-
#' `Config/potools/style` so you can specify the style once for your
17-
#' package.
17+
#' The default, `NULL`, reads from the `DESCRIPTION` field
18+
#' `Config/potools/style` so you can specify the style once for your
19+
#' package.
1820
#'
19-
#' Both styles extract strings explicitly flagged for translation with
20-
#' `gettext()` or `ngettext()`. The base style additionally extracts
21-
#' strings in calls to `stop()`, `warning()`, and `message()`,
22-
#' and to `stopf()`, `warningf()`, and `messagef()` if you have
23-
#' added those helpers to your package. The explicit style also accepts
24-
#' `tr_()` as a short hand for `gettext()`. See
25-
#' `vignette("developer")` for more details.
21+
#' Both styles extract strings explicitly flagged for translation with
22+
#' `gettext()` or `ngettext()`. The base style additionally extracts
23+
#' strings in calls to `stop()`, `warning()`, and `message()`,
24+
#' and to `stopf()`, `warningf()`, and `messagef()` if you have
25+
#' added those helpers to your package. The explicit style also accepts
26+
#' `tr_()` as a short hand for `gettext()`. See
27+
#' `vignette("developer")` for more details.
2628
#' @param verbose Logical, default `TRUE` (except during testing). Should
27-
#' extra information about progress, etc. be reported?
28-
#' @return A `data.table` with the following schema:
29+
#' extra information about progress, etc. be reported?
30+
#' @return
31+
#' A `data.table` with the following schema:
2932
#'
30-
#' * `message_source`, `character`, either `"R"`
31-
#' or `"src"`, saying whether the string was found in the R or the src
32-
#' folder of the package
33-
#' * `type`, `character`, either `"singular"` or `"plural"`;
34-
#' `"plural"` means the string came from [ngettext()] and can be pluralized
35-
#' * `file`, `character`, the file where the string was found
36-
#' * `msgid`, `character`, the string (character literal or `char` array as
33+
#' * `message_source`: `character`, either `"R"` or `"src"`,
34+
#' saying whether the string was found in the R or the src folder of the
35+
#' package
36+
#' * `type`: `character`, either `"singular"` or
37+
#' `"plural"`; `"plural"` means the string came from
38+
#' [`ngettext()`][ngettext] and can be pluralized
39+
#' * `file`: `character`, the file where the string was found
40+
#' * `msgid`: `character`, the string (character literal or `char` array as
3741
#' found in the source); missing for all `type == "plural"` strings
38-
#' * `msgid_plural`, `list(character, character)`, the strings
42+
#' * `msgid_plural`: `list(character, character)`, the strings
3943
#' (character literals or `char` arrays as found in the source); the first
4044
#' applies in English for `n=1` (see `ngettext`), while the second
4145
#' applies for `n!=1`; missing for all `type == "singular"` strings
42-
#' * `call`, `character`, the full call containing the string
46+
#' * `call`: `character`, the full call containing the string
4347
#' that was found
44-
#' * `line_number`, `integer`, the line in `file` where the string was found
45-
#' * `is_repeat`, `logical`, whether the `msgid` is a duplicate within this
48+
#' * `line_number`: `integer`, the line in `file` where the string was found
49+
#' * `is_repeat`: `logical`, whether the `msgid` is a duplicate within this
4650
#' `message_source`
47-
#' * `is_marked_for_translation`, `logical`, whether the string is marked for
48-
#' translation (e.g., in R, all character literals supplied to a `...`
49-
#' argument in [stop()] are so marked)
50-
#' * `is_templated`, `logical`,whether the string is templatable (e.g., uses
51-
#' `%s` or other formatting markers)
51+
#' * `is_marked_for_translation`:`logical`, whether the string is marked for
52+
#' translation (e.g., in R, all character literals supplied to a `...` argument in
53+
#' [`stop()`][stop] are so marked)
54+
#' * `is_templated`, `logical`, whether the string is templatable (e.g., uses
55+
#' `%s` or other formatting markers)
5256
#' @author Michael Chirico
53-
#' @seealso [translate_package()], [write_po_file()]
57+
#' @seealso [`translate_package()`][translate_package],
58+
#' [`write_po_file()`][write_po_file]
5459
#' @examples
60+
#'
5561
#' pkg <- system.file('pkg', package = 'potools')
5662
#' get_message_data(pkg)
5763
#'
@@ -67,6 +73,8 @@
6773
#'
6874
#' # cleanup
6975
#' rm(pkg)
76+
#'
77+
#' @export
7078
get_message_data = function(
7179
dir = ".",
7280
custom_translation_functions = list(R = NULL, src = NULL),

R/po_compile.R

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
#' Compile `.po` files to `.mo`
22
#'
3-
#' This function compiles the plain text `.po` files that translators work with
4-
#' into the binary `.mo` files that are installed with packages and used for
5-
#' live translations.
3+
#' This function compiles the plain text `.po` files that translators work
4+
#' with into the binary `.mo` files that are installed with packages and
5+
#' used for live translations.
6+
#'
67
#'
78
#' @param dir Path to package root directory.
8-
#' @param package Name of package. If not supplied, read from `DESCRIPTION`.
9-
#' @param lazy If `TRUE`, only `.mo` functions that are older than `.po`
10-
#' files be updated
9+
#' @param package Name of package. If not supplied, read from
10+
#' `DESCRIPTION`.
11+
#' @param lazy If `TRUE`, only `.mo` functions that are older than
12+
#' `.po` files be updated
1113
#' @param verbose If `TRUE`, print information as it goes.
14+
#' @export
1215
po_compile = function(dir = ".", package = NULL, lazy = TRUE, verbose = TRUE) {
1316
po_metadata <- get_po_metadata(dir = dir, package = package)
1417
dir_create(dirname(po_metadata$mo))

R/po_extract.R

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,35 @@
11
#' Extract messages for translation into a `.pot` file
22
#'
33
#' `po_extract()` scans your package for strings to be translated and
4-
#' saves them into a `.pot` template file (in the package's `po` directory).
5-
#' You should never modify this file by hand; instead modify the underlying
6-
#' source code and re-run `po_extract()`.
4+
#' saves them into a `.pot` template file (in the package's `po`
5+
#' directory). You should never modify this file by hand; instead modify the
6+
#' underlying source code and re-run `po_extract()`.
77
#'
8-
#' @returns The extracted messages as computed by [get_message_data()],
9-
#' invisibly.
10-
#' @inheritParams get_message_data
8+
#'
9+
#' @param dir Character, default the present directory; a directory in which an
10+
#' R package is stored.
11+
#' @param custom_translation_functions A `list` with either/both of two
12+
#' components, `R` and `src`, together governing how to extract any
13+
#' non-standard strings from the package.
14+
#'
15+
#' See Details in [`translate_package()`][translate_package].
16+
#' @param verbose Logical, default `TRUE` (except during testing). Should
17+
#' extra information about progress, etc. be reported?
18+
#' @param style Translation style, either `"base"` or `"explict"`.
19+
#' The default, `NULL`, reads from the `DESCRIPTION` field
20+
#' `Config/potools/style` so you can specify the style once for your
21+
#' package.
22+
#'
23+
#' Both styles extract strings explicitly flagged for translation with
24+
#' `gettext()` or `ngettext()`. The base style additionally extracts
25+
#' strings in calls to `stop()`, `warning()`, and `message()`,
26+
#' and to `stopf()`, `warningf()`, and `messagef()` if you have
27+
#' added those helpers to your package. The explicit style also accepts
28+
#' `tr_()` as a short hand for `gettext()`. See
29+
#' `vignette("developer")` for more details.
30+
#' @return The extracted messages as computed by
31+
#' [`get_message_data()`][get_message_data], invisibly.
32+
#' @export
1133
po_extract <- function(
1234
dir = ".",
1335
custom_translation_functions = list(),

0 commit comments

Comments
 (0)