Skip to content

Commit 30d7787

Browse files
authored
Escape control characters in CSV and Remind output (#41)
1 parent 7c2c13a commit 30d7787

File tree

7 files changed

+21
-10
lines changed

7 files changed

+21
-10
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
icalPal-3.9.0
1+
icalPal-3.9.2
2+
==================
3+
4+
* Escape control characters in CSV and Remind output
5+
6+
icalPal-3.9.1
27
==================
38

49
* Implement tasksDueBefore command

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,12 @@ to mimic icalBuddy as much as possible.
280280

281281
CSV, Hash, JSON, XML, and YAML print all fields for all items in their
282282
respective formats. From that you can analyze the results any way you
283-
like.
284-
285-
[Remind](https://dianne.skoll.ca/projects/remind/) format uses a
283+
like. [Remind](https://dianne.skoll.ca/projects/remind/) format uses a
286284
minimal implementation built into icalPal.
287285

286+
Control characters are escaped in these formats to ensure they remain
287+
properly formatted.
288+
288289
Other formats such as ANSI, HTML, Markdown, RDoc, and TOC, use Ruby's
289290
[RDoc::Markup](https://ruby-doc.org/stdlib-2.6.10/libdoc/rdoc/rdoc/RDoc/Markup.html)
290291
framework to build and render the items.

bin/icalpal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ unless mu
290290
when 'remind' then items.map { |i|
291291
"REM #{i['sdate'].strftime('%F AT %R')} " +
292292
"DURATION #{((i['edate'] - i['sdate']).to_f * 1440).to_i} " +
293-
"MSG #{i['title']}"
293+
"MSG #{i['title'].gsub(/([[:cntrl:]])/) { |c| c.dump[1..-2] } }"
294294
}.join("\n")
295295
else abort "No formatter for #{$opts[:output]}"
296296
end

lib/icalPal.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,17 @@ def initialize(obj)
8888
obj['symbolic_color_name'] ||= type[:color]
8989
end
9090

91-
# Create a new CSV::Row with values from +self+. Newlines are
92-
# replaced with '\n' to ensure each Row is a single line of text.
91+
# Create a new CSV::Row with values from +self+. Control characters
92+
# are escaped to ensure they are not interpreted by the terminal.
9393
#
9494
# @param headers [Array] Key names used as the header row in a CSV::Table
9595
# @return [CSV::Row] The +Store+, +Calendar+, +CalendarItem+, or
9696
# +Reminder+ as a CSV::Row
9797
def to_csv(headers)
98-
values = headers.map { |h| (@self[h].respond_to?(:gsub))? @self[h].gsub("\n", '\n') : @self[h] }
98+
values = headers.map do |h|
99+
(@self[h].respond_to?(:gsub))?
100+
@self[h].gsub(/([[:cntrl:]])/) { |c| c.dump[1..-2] } : @self[h]
101+
end
99102

100103
CSV::Row.new(headers, values)
101104
end

lib/options.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,8 @@ def parse_options
337337
raise(OptionParser::InvalidArgument, '--li cannot be negative') if opts[:li].negative?
338338
raise(OptionParser::InvalidOption, 'Start date must be before end date') if opts[:from] && opts[:from] > opts[:to]
339339
raise(OptionParser::MissingArgument, 'No properties to display') if opts[:props].empty?
340+
raise(OptionParser::InvalidArgument, 'Cannot use remind output with tasks') if opts[:cmd] == 'tasks' &&
341+
opts[:output] == 'remind'
340342

341343
rescue StandardError => e
342344
@op.abort("#{e}\n\n#{@op.help}\n#{e}")

lib/reminder.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def [](k)
5353
when 'name', 'reminder', 'task' # Aliases
5454
@self['title']
5555

56-
else @self[k]
56+
else super
5757
end
5858
end
5959

lib/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
module ICalPal
22
NAME = 'icalPal'.freeze
3-
VERSION = '3.9.1'.freeze
3+
VERSION = '3.9.2'.freeze
44
end

0 commit comments

Comments
 (0)