在iCal文件中编码换行符

60

我正在研究如何以一种能够被Outlook、Google Calendar和Apple Calendar正确导入的方式编码iCal文件中“DESCRIPTION”部分中的换行符。

我继承的原始代码使用了带有quoted-printable编码的“=0D=0A”,在Outlook中效果很好,但在Google Calendar中却不起作用。

规范似乎表明应该使用“\n”表示换行符。这在Google Calendar中效果很好,但Outlook只会将文字字面上的“\n”字符放在那里。

您是否知道一种跨日历系统可靠的解决方案?


3
问题涉及到 iCal 规范的一部分:http://tools.ietf.org/html/rfc5545#section-3.3.11 - Matthew Buckett
9个回答

63

好的,看起来我要回答自己的问题。

正确的做法是使用“\n”作为换行符。由于描述中有“ENCODING=quoted-printable”,Outlook没有识别出来。一旦我去掉了它,Outlook就能正确地显示新的行了。

另外,为了让文件在 Apple iCal 中正确打开,你需要使用“VERSION:2.0”作为文件版本。如果使用“VERSION:1.0”,它会告诉你不能读取文件(即使符合 1.0 规范)。

注意:正如其他人所提到的,文件实际上必须包含文字串\n。由于大多数语言将其视为一个表示换行字符的转义序列,因此你可能需要在代码中使用字符串\\n


5
对于那些添加了 \n 以创建新行但仍然无效的人,我最终使用了 \n,就像 @periklis 所指出的那样。 - Sergiu Z

37

Matthew Bucket在原帖中提供的链接到RFC的评论对我有所帮助。引用他的话:

"TEXT"属性值中的反斜杠字符必须使用另一个反斜杠字符进行转义。

因此,我进行了一次

$description = str_replace("\r\n", "\\n", $description);

然后它正常工作了


引用和代码似乎不匹配。代码将Windows换行符替换为文字\n序列。 - Álvaro González
4
这看起来异常奇怪,有\\n出现,很难理解其真正含义。在.NET开发中,我创建了一个常量字符串textLineFeed = @"\" + "n"; - Chris Marisic
你的解决方案对我来说就像魔法弹药一样。我在这个页面上尝试了所有其他的方法都没有成功。谢谢你。 - Krafty

24

可能值得一提的是,你在ical文件中需要使用字面上的 \n 而不是换行符号。同时也别忘记进行75个字符的"折叠"。


还有一个需要使用CRLF,但是这里有更多关于内容折叠的信息。点击此处 - yellowsir

10

你的输出文件应该像下面这样---

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//2013//#Ur Site Name#//EN
BEGIN:VEVENT
UID:[event]2012
DTSTART:20130101T100000
DTEND:20130101T120000
LOCATION:
SUMMARY:#Meeting Title here#
DESCRIPTION:What is realistic for financial services companies to achieve via Social Media channels?    \n\nJoin us on 11th September 2013 at 4pm (BST) where we 
-----bla bla bla ----
END:VEVENT
END:VCALENDAR

在这里您需要注意版本号,它应该是2.0,以及转义字符... \n(换行),分号(;)和逗号(,)。如果你在 .net 中写入,那么应该像这样... "\\n","\\;"和"\\,"。

您也可以在此网站上检查输出文件... https://icalendar.org/validator.html

谢谢, Bhaskar


1
+1 给验证器,同时提到其他需要转义的字符。 - Matt Kemp
1
每行文字不得超过75个字符。 http://tools.ietf.org/html/rfc5545#section-3.1 - ofaurax
答案中提到的验证器已不再可用。这里有另外两个,它们会给出不同的结果(但在两种情况下都是合理的):https://icalendar.org/validator.html,http://ical-validator.herokuapp.com/。 - tcmb

6
根据此RFC

内容行由换行符分隔,这是一个CRLF序列(CR字符后跟LF字符)。

因此,您应该使用\r\n。 我在没有额外反斜杠转义的字符串中使用了这个。

2

这是我对DESCRIPTION的答案。

$filev = str_replace("\r\n", '\\n', $p);
$filev = str_replace("<br>",'\\n',$filev);
$filev = (str_replace(";","\;",str_replace(",",'\,',$filev)));

1
根据RFC 5545的规定,折叠超过75个字符的行的正确方式是在这些行的末尾添加CRLF和一个空格。以下Python代码可以实现该功能:
import re
def word_wrap(text):
   return re.sub("(.{75})", "\\1\r\n ", text, 0, re.DOTALL)

在 "\r\n" 后面的空格非常重要!如果没有它,像苹果日历这样的日历应用程序将无法正确导入 .ics 文件。


0

我必须在字符串中转义输出,以便在输出文件中设置一个字面的“\n”。就像这样。非常有效。

$events .= "DESCRIPTION:" . str_replace("\n","\\n",str_replace(";","\;",str_replace(",",'\,',get_event_contents()))) . "\n";

0

=0D=0A 可以在 Outlook 中使用,但您需要更改 DESCRIPTION 键,以便可以解释换行符。

DESCRIPTION;ENCODING=QUOTED-PRINTABLE:

在冒号后输入您的文本,使用=0D=0A进行换行。Outlook将正确读取换行符。仅当您使用ENCODING:QUOTED-PRINTABLE而不是DESCRIPTION时,使用\\n才有效。

我正在使用VERSION:2.0


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