你如何格式化多行的R包消息?

6
在开发一个R包时,我想使用R的message()或warning()函数为我的软件包用户生成输出。有时这些消息可能很长。我可以这样做(文本只是简单的示例):
message("If you got to this point in the code, it means the matrix was empty. Calculation continues but you should consider re-evaluating an earlier step in the process")

很不错...但是为了风格,我也希望我的代码行少于80个字符,这样它们可以在狭窄的屏幕、GitHub等上完美显示。然后如果更改了消息,我可以使用IDE代码重排工具轻松重新格式化我的消息。

所以我尝试了这个:

message("If you got to this point in the code, it means 
the matrix was empty. Calculation continues but you should consider
 re-evaluating an earlier step in the process")

这解决了我的代码要求——每行字符少于80个,且可以如预期般重新格式化。但是这会将空格粘在我的消息输出中,这也不是我想要的:
If you got to this point in the code, it means 
the matrix was empty. Calculation continues but you should consider
 re-evaluating an earlier step in the process

我发现了一个非常方便的函数叫做strwrap(),它似乎可以解决这个问题:

message(strwrap("If you got to this point in the code, it means 
the matrix was empty. Calculation continues but you should consider
 re-evaluating an earlier step in the process"))

输出:

If you got to this point in the code, it means the matrix was empty. 
Calculation continues but you should considerre-evaluating an earlier 
step in the process

看起来很不错 - 但它消除了“考虑”和“重新评估”之间的空格,因为这个空格位于换行符处。

另一种选择是在代码中将它分成几个部分:

message("If you got to this point in the code, it means ", 
"the matrix was empty. Calculation continues but you should consider ",
"re-evaluating an earlier step in the process")

这使输出看起来正确,但是文本不再能够轻松地与IDE等重新流动,因为它不是一个字符串,所以在开发方面对我来说这不起作用。
那么:如何制作一个漂亮格式的消息,让我可以轻松地在多行上编写消息?
我已经编写了这个函数:
.nicemsg = function(...) {
    message(paste(strwrap(...), collapse="\n"))
}

有没有更好的方法可以使用内置函数,这样我就不必在编写每个R包时都包含此函数?


2
message(strwrap(..., prefix = " ", initial = "")) 这个函数是否满足你的需求? - Benjamin
@Benjamin 是的,谢谢。不幸的是,它并没有比我的函数更简洁,所以我仍然可能需要将其包装起来... - nsheff
@Benjamin,既然没有其他答案,如果您将此作为答案发布,我会接受它。 - nsheff
2个回答

7
使用strwrap的更多参数可以实现这一点。
message(strwrap(..., prefix = " ", initial = ""))

通过调整参数的顺序,您可能会提高可读性。我不确定这是否更好。

message(strwrap(prefix = " ", initial = "", 
  "If you got to this point in the code, it means 
the matrix was empty. Calculation continues but you should consider
 re-evaluating an earlier step in the process"))

或者,如果你喜欢将其包装起来

tidymess <- function(..., prefix = " ", initial = ""){
  message(strwrap(..., prefix = prefix, initial = initial))
}

3
我特别喜欢函数名tidymess。这也是我会形容我的办公室的方式。 - nsheff
1
strwrap() 中使用 prefix = "\n" 可以防止单词在屏幕换行时被分割。 - Allen Baron

-3

您可以通过在字符串中添加\n来强制换行。

message("If you got to this point in the code,\nit means the matrix was empty.\nCalculation continues but you should consider re-evaluating\nan earlier step in the process")
# If you got to this point in the code,
# it means the matrix was empty.
# Calculation continues but you should consider re-evaluating
# an earlier step in the process

这既没有解决IDE重排问题,也没有解决80个字符的限制。请重新阅读问题。 - nsheff
在什么情况下您希望代码重新排列? - Andrew Brēza
在所有情况下都需要这样做吗?是的,这仍然像我第一个例子一样过度了。重点似乎不太清楚:代码需要在80个字符处换行。您的建议没有将代码包装在80个字符处(允许IDE重新排列代码)。 - nsheff
@nsheff 你希望在80个字符处出现换行,还是希望IDE根据自己的宽度限制重新排列代码? - Andrew Brēza
抱歉我之前表达不够清楚;我想让代码能够根据IDE所设置的任意值进行自动调整,80个字符只是一个例子。我并不关心输出结果。你的回复针对输出结果长度的格式化进行了讨论,这很好,但是我更关注的是代码需要保持可读性(在任意字符停止处)。这样是否有帮助呢?谢谢。 - nsheff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接