icalendar 1.4.1 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/Gemfile +3 -0
- data/History.txt +4 -0
- data/README.md +268 -0
- data/Rakefile +7 -17
- data/icalendar.gemspec +14 -6
- data/lib/icalendar/base.rb +1 -1
- data/lib/icalendar/component.rb +7 -7
- data/test/fixtures/nonstandard.ics +24 -0
- data/test/test_parameter.rb +17 -0
- metadata +34 -68
- data/.gemtest +0 -0
- data/Manifest.txt +0 -55
- data/README.rdoc +0 -286
- data/config/website.yml +0 -2
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/script/txt2html +0 -71
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 037c1a6dc0343e14f0ee3ab43f078385795d9b1c
|
4
|
+
data.tar.gz: e14616a6a69ca12590b9634100708b3f3b7276c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fcd6f74754bd83938a343d5f5b5fe9c3e70d22fc135f83960c5a615226c7d9418a0e972d2fa0daee663f60e40a21bf88f85e5327a3c7fff06defcfb08699d128
|
7
|
+
data.tar.gz: 9e400bf9c4c693f97e98759d020a3616d754fb7630ee75ddbb9cc8a824d9951c349157fd91e5911048691992171f0ff8d4df079fd81e9a408b50613982aecb66
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/History.txt
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
=== 1.4.2 2013-09-11
|
2
|
+
* Double Quote parameter values that contain forbidden characters
|
3
|
+
* Update Component#respond_to? to match Ruby 2.0 - Keith Marcum
|
4
|
+
|
1
5
|
=== 1.4.1 2013-06-25
|
2
6
|
* Don't escape semicolon in GEO property - temirov
|
3
7
|
* Allow access to various parts of RRule class
|
data/README.md
ADDED
@@ -0,0 +1,268 @@
|
|
1
|
+
iCalendar -- Internet calendaring, Ruby style
|
2
|
+
===
|
3
|
+
|
4
|
+
<http://github.com/icalendar/icalendar>
|
5
|
+
|
6
|
+
DESCRIPTION
|
7
|
+
---
|
8
|
+
|
9
|
+
iCalendar is a Ruby library for dealing with iCalendar files in the
|
10
|
+
iCalendar format defined by RFC-2445:
|
11
|
+
|
12
|
+
The use of calendaring and scheduling has grown considerably in the
|
13
|
+
last decade. Enterprise and inter-enterprise business has become
|
14
|
+
dependent on rapid scheduling of events and actions using this
|
15
|
+
information technology. However, the longer term growth of calendaring
|
16
|
+
and scheduling, is currently limited by the lack of Internet standards
|
17
|
+
for the message content types that are central to these knowledgeware
|
18
|
+
applications. This memo is intended to progress the level of
|
19
|
+
interoperability possible between dissimilar calendaring and
|
20
|
+
scheduling applications. This memo defines a MIME content type for
|
21
|
+
exchanging electronic calendaring and scheduling information. The
|
22
|
+
Internet Calendaring and Scheduling Core Object Specification, or
|
23
|
+
iCalendar, allows for the capture and exchange of information normally
|
24
|
+
stored within a calendaring and scheduling application; such as a
|
25
|
+
Personal Information Manager (PIM) or a Group Scheduling product.
|
26
|
+
|
27
|
+
The iCalendar format is suitable as an exchange format between
|
28
|
+
applications or systems. The format is defined in terms of a MIME
|
29
|
+
content type. This will enable the object to be exchanged using
|
30
|
+
several transports, including but not limited to SMTP, HTTP, a file
|
31
|
+
system, desktop interactive protocols such as the use of a memory-
|
32
|
+
based clipboard or drag/drop interactions, point-to-point asynchronous
|
33
|
+
communication, wired-network transport, or some form of unwired
|
34
|
+
transport such as infrared might also be used.
|
35
|
+
|
36
|
+
|
37
|
+
EXAMPLES
|
38
|
+
---
|
39
|
+
|
40
|
+
### Probably want to start with this ###
|
41
|
+
|
42
|
+
require 'icalendar'
|
43
|
+
require 'date'
|
44
|
+
|
45
|
+
include Icalendar # You should do this in your class to limit namespace overlap
|
46
|
+
|
47
|
+
### Creating calendars and events ###
|
48
|
+
|
49
|
+
# Create a calendar with an event (standard method)
|
50
|
+
cal = Calendar.new
|
51
|
+
cal.event do
|
52
|
+
dtstart Date.new(2005, 04, 29)
|
53
|
+
dtend Date.new(2005, 04, 28)
|
54
|
+
summary "Meeting with the man."
|
55
|
+
description "Have a long lunch meeting and decide nothing..."
|
56
|
+
klass "PRIVATE"
|
57
|
+
end
|
58
|
+
|
59
|
+
cal.publish
|
60
|
+
|
61
|
+
#### Or you can make events like this ####
|
62
|
+
|
63
|
+
event = Event.new
|
64
|
+
event.start = DateTime.civil(2006, 6, 23, 8, 30)
|
65
|
+
event.summary = "A great event!"
|
66
|
+
cal.add_event(event)
|
67
|
+
|
68
|
+
event2 = cal.event # This automatically adds the event to the calendar
|
69
|
+
event2.start = DateTime.civil(2006, 6, 24, 8, 30)
|
70
|
+
event2.summary = "Another great event!"
|
71
|
+
|
72
|
+
#### Now with support for property parameters ####
|
73
|
+
|
74
|
+
params = {"ALTREP" =>['"http://my.language.net"'], "LANGUAGE" => ["SPANISH"]}
|
75
|
+
|
76
|
+
cal.event do
|
77
|
+
dtstart Date.new(2005, 04, 29)
|
78
|
+
dtend Date.new(2005, 04, 28)
|
79
|
+
summary "This is a summary with params.", params
|
80
|
+
end
|
81
|
+
|
82
|
+
#### We can output the calendar as a string ####
|
83
|
+
|
84
|
+
cal_string = cal.to_ical
|
85
|
+
puts cal_string
|
86
|
+
|
87
|
+
ALARMS
|
88
|
+
---
|
89
|
+
|
90
|
+
### Within an event ###
|
91
|
+
|
92
|
+
cal.event.do
|
93
|
+
# ...other event properties
|
94
|
+
alarm do
|
95
|
+
action "EMAIL"
|
96
|
+
description "This is an event reminder" # email body (required)
|
97
|
+
summary "Alarm notification" # email subject (required)
|
98
|
+
attendees %w(mailto:me@my-domain.com mailto:me-too@my-domain.com) # one or more email recipients (required)
|
99
|
+
add_attendee "mailto:me-three@my-domain.com"
|
100
|
+
remove_attendee "mailto:me@my-domain.com"
|
101
|
+
trigger "-PT15M" # 15 minutes before
|
102
|
+
add_attach "ftp://host.com/novo-procs/felizano.exe", {"FMTTYPE" => "application/binary"} # email attachments (optional)
|
103
|
+
end
|
104
|
+
|
105
|
+
alarm do
|
106
|
+
action "DISPLAY" # This line isn't necessary, it's the default
|
107
|
+
summary "Alarm notification"
|
108
|
+
trigger "-P1DT0H0M0S" # 1 day before
|
109
|
+
end
|
110
|
+
|
111
|
+
alarm do
|
112
|
+
action "AUDIO"
|
113
|
+
trigger "-PT15M"
|
114
|
+
add_attach "Basso", {"VALUE" => ["URI"]} # only one attach allowed (optional)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
#### Output ####
|
119
|
+
|
120
|
+
# BEGIN:VALARM
|
121
|
+
# ACTION:EMAIL
|
122
|
+
# ATTACH;FMTTYPE=application/binary:ftp://host.com/novo-procs/felizano.exe
|
123
|
+
# TRIGGER:-PT15M
|
124
|
+
# SUMMARY:Alarm notification
|
125
|
+
# DESCRIPTION:This is an event reminder
|
126
|
+
# ATTENDEE:mailto:me-too@my-domain.com
|
127
|
+
# ATTENDEE:mailto:me-three@my-domain.com
|
128
|
+
# END:VALARM
|
129
|
+
#
|
130
|
+
# BEGIN:VALARM
|
131
|
+
# ACTION:DISPLAY
|
132
|
+
# TRIGGER:-P1DT0H0M0S
|
133
|
+
# SUMMARY:Alarm notification
|
134
|
+
# END:VALARM
|
135
|
+
#
|
136
|
+
# BEGIN:VALARM
|
137
|
+
# ACTION:AUDIO
|
138
|
+
# ATTACH;VALUE=URI:Basso
|
139
|
+
# TRIGGER:-PT15M
|
140
|
+
# END:VALARM
|
141
|
+
|
142
|
+
TIMEZONES
|
143
|
+
---
|
144
|
+
|
145
|
+
cal = Calendar.new
|
146
|
+
cal.timezone do
|
147
|
+
timezone_id "America/Chicago"
|
148
|
+
|
149
|
+
daylight do
|
150
|
+
timezone_offset_from "-0600"
|
151
|
+
timezone_offset_to "-0500"
|
152
|
+
timezone_name "CDT"
|
153
|
+
dtstart "19700308TO20000"
|
154
|
+
add_recurrence_rule "FREQ=YEARLY;BYMONTH=3;BYDAY=2SU"
|
155
|
+
end
|
156
|
+
|
157
|
+
standard do
|
158
|
+
timezone_offset_from "-0500"
|
159
|
+
timezone_offset_to "-0600"
|
160
|
+
timezone_name "CST"
|
161
|
+
dtstart "19701101T020000"
|
162
|
+
add_recurrence_rule "YEARLY;BYMONTH=11;BYDAY=1SU"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
#### Output ####
|
167
|
+
|
168
|
+
# BEGIN:VTIMEZONE
|
169
|
+
# TZID:America/Chicago
|
170
|
+
# BEGIN:DAYLIGHT
|
171
|
+
# TZOFFSETFROM:-0600
|
172
|
+
# TZOFFSETTO:-0500
|
173
|
+
# TZNAME:CDT
|
174
|
+
# DTSTART:19700308T020000
|
175
|
+
# RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
|
176
|
+
# END:DAYLIGHT
|
177
|
+
# BEGIN:STANDARD
|
178
|
+
# TZOFFSETFROM:-0500
|
179
|
+
# TZOFFSETTO:-0600
|
180
|
+
# TZNAME:CST
|
181
|
+
# DTSTART:19701101T020000
|
182
|
+
# RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
|
183
|
+
# END:STANDARD
|
184
|
+
# END:VTIMEZONE
|
185
|
+
|
186
|
+
Unicode
|
187
|
+
---
|
188
|
+
|
189
|
+
Add `$KCODE = 'u'` to make icalender work correctly with Utf8 texts
|
190
|
+
|
191
|
+
Parsing iCalendars
|
192
|
+
---
|
193
|
+
|
194
|
+
# Open a file or pass a string to the parser
|
195
|
+
cal_file = File.open("single_event.ics")
|
196
|
+
|
197
|
+
# Parser returns an array of calendars because a single file
|
198
|
+
# can have multiple calendars.
|
199
|
+
cals = Icalendar.parse(cal_file)
|
200
|
+
cal = cals.first
|
201
|
+
|
202
|
+
# Now you can access the cal object in just the same way I created it
|
203
|
+
event = cal.events.first
|
204
|
+
|
205
|
+
puts "start date-time: #{event.dtstart}"
|
206
|
+
puts "start date-time timezone: #{event.dtstart.icalendar_tzid}" if event.dtstart.is_a?(DateTime)
|
207
|
+
puts "summary: #{event.summary}"
|
208
|
+
|
209
|
+
# Some calendars contain non-standard parameters (e.g. Apple iCloud
|
210
|
+
# calendars). You can pass in a `strict` value when creating a new parser.
|
211
|
+
unstrict_parser = Icalendar::Parser.new(cal_file, false)
|
212
|
+
cal = unstrict_parser.parse()
|
213
|
+
|
214
|
+
Finders
|
215
|
+
---
|
216
|
+
|
217
|
+
Often times in web apps and other interactive applications you'll need to
|
218
|
+
lookup items in a calendar to make changes or get details. Now you can find
|
219
|
+
everything by the unique id automatically associated with all components.
|
220
|
+
|
221
|
+
cal = Calendar.new
|
222
|
+
10.times { cal.event } # Create 10 events with only default data.
|
223
|
+
some_event = cal.events[5] # Grab it from the array of events
|
224
|
+
|
225
|
+
# Use the uid as the key in your app
|
226
|
+
key = some_event.uid
|
227
|
+
|
228
|
+
# so later you can find it.
|
229
|
+
same_event = cal.find_event(key)
|
230
|
+
|
231
|
+
Examples
|
232
|
+
---
|
233
|
+
|
234
|
+
Check the unit tests for examples of most things you'll want to do, but please
|
235
|
+
send me example code or let me know what's missing.
|
236
|
+
|
237
|
+
Download
|
238
|
+
---
|
239
|
+
|
240
|
+
The latest release version of this library can be found at
|
241
|
+
|
242
|
+
* <http://rubygems.org/gems/icalendar>
|
243
|
+
|
244
|
+
Installation
|
245
|
+
---
|
246
|
+
|
247
|
+
It's all about rubygems:
|
248
|
+
|
249
|
+
$ gem install icalendar
|
250
|
+
|
251
|
+
Testing
|
252
|
+
---
|
253
|
+
|
254
|
+
To run the tests:
|
255
|
+
|
256
|
+
$ bundle install
|
257
|
+
$ rake test
|
258
|
+
|
259
|
+
License
|
260
|
+
---
|
261
|
+
|
262
|
+
This library is released under the same license as Ruby itself.
|
263
|
+
|
264
|
+
Support & Contributions
|
265
|
+
---
|
266
|
+
|
267
|
+
Please submit pull requests from a rebased topic branch and
|
268
|
+
include tests for all bugs and features.
|
data/Rakefile
CHANGED
@@ -1,20 +1,10 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
require './lib/icalendar'
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
# Generate all the Rake tasks
|
11
|
-
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
12
|
-
$hoe = Hoe.spec 'icalendar' do
|
13
|
-
developer 'Ryan Ahearn', 'ryan.c.ahearn@gmail.com'
|
14
|
-
self.extra_rdoc_files += %w[COPYING GPL]
|
4
|
+
require 'rake/testtask'
|
5
|
+
Rake::TestTask.new do |t|
|
6
|
+
t.pattern = 'test/**/test*.rb'
|
7
|
+
t.verbose = true
|
15
8
|
end
|
16
9
|
|
17
|
-
|
18
|
-
require 'ci/reporter/rake/test_unit'
|
19
|
-
task :test => ["ci:setup:testunit"]
|
20
|
-
end
|
10
|
+
task default: [:test, :build]
|
data/icalendar.gemspec
CHANGED
@@ -3,19 +3,27 @@ require 'icalendar/base'
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.authors = ['Ryan Ahearn']
|
6
|
+
s.email = ['ryan.c.ahearn@gmail.com']
|
6
7
|
|
7
8
|
s.name = "icalendar"
|
8
9
|
s.version = Icalendar::VERSION
|
9
10
|
|
10
|
-
s.homepage = "
|
11
|
+
s.homepage = "https://github.com/icalendar/icalendar"
|
11
12
|
s.platform = Gem::Platform::RUBY
|
12
13
|
s.summary = "A ruby implementation of the iCalendar specification (RFC-2445)."
|
13
|
-
s.description =
|
14
|
+
s.description = <<-EOD
|
15
|
+
Implements the iCalendar specification (RFC-2445) in Ruby. This allows
|
16
|
+
for the generation and parsing of .ics files, which are used by a
|
17
|
+
variety of calendaring applications.
|
18
|
+
EOD
|
14
19
|
|
15
|
-
s.
|
16
|
-
s.
|
17
|
-
s.
|
18
|
-
s.
|
20
|
+
s.files = `git ls-files`.split "\n"
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split "\n"
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename f }
|
23
|
+
s.require_paths = ['lib']
|
24
|
+
|
25
|
+
s.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
s.add_development_dependency 'bundler', '~> 1.3'
|
19
27
|
s.add_development_dependency 'tzinfo', '~> 0.3'
|
20
28
|
end
|
21
29
|
|
data/lib/icalendar/base.rb
CHANGED
data/lib/icalendar/component.rb
CHANGED
@@ -180,13 +180,13 @@ module Icalendar
|
|
180
180
|
# Possible parameter values
|
181
181
|
unless val.empty?
|
182
182
|
s << "="
|
183
|
-
|
184
|
-
val.each do |pval|
|
183
|
+
s << val.map do |pval|
|
185
184
|
if pval.respond_to? :to_ical
|
186
|
-
|
187
|
-
|
185
|
+
param = pval.to_ical
|
186
|
+
param = %|"#{param}"| unless param =~ %r{\A#{Parser::QSTR}\z|\A#{Parser::PTEXT}\z}
|
187
|
+
param
|
188
188
|
end
|
189
|
-
end
|
189
|
+
end.compact.join(',')
|
190
190
|
end
|
191
191
|
end
|
192
192
|
s
|
@@ -429,9 +429,9 @@ module Icalendar
|
|
429
429
|
|
430
430
|
public
|
431
431
|
|
432
|
-
def respond_to?(method_name)
|
432
|
+
def respond_to?(method_name, include_all=false)
|
433
433
|
if method_name.to_s.downcase =~ /x_.*/
|
434
|
-
|
434
|
+
true
|
435
435
|
else
|
436
436
|
super
|
437
437
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
BEGIN:VCALENDAR
|
2
|
+
VERSION:2.0
|
3
|
+
PRODID:bsprodidfortestabc123
|
4
|
+
BEGIN:VEVENT
|
5
|
+
UID:bsuidfortestabc123
|
6
|
+
ORGANIZER:mailto:joebob@random.net
|
7
|
+
ATTACH:http://bush.sucks.org/impeach/him.rhtml
|
8
|
+
ATTACH:http://corporations-dominate.existence.net/why.rhtml
|
9
|
+
SUMMARY:This is a really long summary
|
10
|
+
to test the method of unfolding lines\,
|
11
|
+
so I'm just going to ma
|
12
|
+
ke it
|
13
|
+
a whol
|
14
|
+
e
|
15
|
+
bunch of lines.
|
16
|
+
CLASS:PRIVATE
|
17
|
+
PRIORITY:2
|
18
|
+
CUSTOMFIELD:Not properly noted as custom with X- prefix.
|
19
|
+
GEO:37.386013;-122.0829322
|
20
|
+
DTSTART;TZID=US-Mountain:20050120T170000
|
21
|
+
DTEND:20050120T184500
|
22
|
+
DTSTAMP:20050118T211523Z
|
23
|
+
END:VEVENT
|
24
|
+
END:VCALENDAR
|
data/test/test_parameter.rb
CHANGED
@@ -38,6 +38,23 @@ class TestParameter < Test::Unit::TestCase
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
def test_unquoted_property_parameters
|
42
|
+
params = {'ALTREP' => ['"http://my.language.net"'],
|
43
|
+
'LANGUAGE' => ['SPANISH:CATILLAN']}
|
44
|
+
expected_params = {'ALTREP' => ['"http://my.language.net"'],
|
45
|
+
'LANGUAGE' => ['"SPANISH:CATILLAN"']}
|
46
|
+
@event.summary('This is a test summary.', params)
|
47
|
+
|
48
|
+
assert_equal params, @event.summary.ical_params
|
49
|
+
|
50
|
+
@cal.add_event @event
|
51
|
+
cal_str = @cal.to_ical
|
52
|
+
|
53
|
+
cals = Icalendar::Parser.new(cal_str).parse
|
54
|
+
event = cals.first.events.first
|
55
|
+
assert_equal expected_params, event.summary.ical_params
|
56
|
+
end
|
57
|
+
|
41
58
|
def test_nonstandard_property_parameters
|
42
59
|
params = {'CUSTOM' => ['yours']}
|
43
60
|
@event.priority(2, params)
|
metadata
CHANGED
@@ -1,110 +1,74 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: icalendar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Ahearn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - '>='
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 2.0.4
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - '>='
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 2.0.4
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rdoc
|
14
|
+
name: rake
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - ~>
|
32
18
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
19
|
+
version: '10.0'
|
34
20
|
type: :development
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
38
24
|
- - ~>
|
39
25
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
26
|
+
version: '10.0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
28
|
+
name: bundler
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
|
-
- -
|
31
|
+
- - ~>
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.
|
33
|
+
version: '1.3'
|
48
34
|
type: :development
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
|
-
- -
|
38
|
+
- - ~>
|
53
39
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.
|
40
|
+
version: '1.3'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
42
|
+
name: tzinfo
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
45
|
- - ~>
|
60
46
|
- !ruby/object:Gem::Version
|
61
|
-
version: '3
|
47
|
+
version: '0.3'
|
62
48
|
type: :development
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
52
|
- - ~>
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version: '3
|
69
|
-
description:
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
and actions using this\ninformation technology. However, the longer term growth
|
74
|
-
of calendaring\nand scheduling, is currently limited by the lack of Internet standards\nfor
|
75
|
-
the message content types that are central to these knowledgeware\napplications.
|
76
|
-
This memo is intended to progress the level of\ninteroperability possible between
|
77
|
-
dissimilar calendaring and\nscheduling applications. This memo defines a MIME content
|
78
|
-
type for\nexchanging electronic calendaring and scheduling information. The\nInternet
|
79
|
-
Calendaring and Scheduling Core Object Specification, or\niCalendar, allows for
|
80
|
-
the capture and exchange of information normally\nstored within a calendaring and
|
81
|
-
scheduling application; such as a\nPersonal Information Manager (PIM) or a Group
|
82
|
-
Scheduling product. \n\nThe iCalendar format is suitable as an exchange format between\napplications
|
83
|
-
or systems. The format is defined in terms of a MIME\ncontent type. This will enable
|
84
|
-
the object to be exchanged using\nseveral transports, including but not limited
|
85
|
-
to SMTP, HTTP, a file\nsystem, desktop interactive protocols such as the use of
|
86
|
-
a memory-\nbased clipboard or drag/drop interactions, point-to-point asynchronous\ncommunication,
|
87
|
-
wired-network transport, or some form of unwired\ntransport such as infrared might
|
88
|
-
also be used."
|
54
|
+
version: '0.3'
|
55
|
+
description: |2
|
56
|
+
Implements the iCalendar specification (RFC-2445) in Ruby. This allows
|
57
|
+
for the generation and parsing of .ics files, which are used by a
|
58
|
+
variety of calendaring applications.
|
89
59
|
email:
|
90
60
|
- ryan.c.ahearn@gmail.com
|
91
61
|
executables: []
|
92
62
|
extensions: []
|
93
|
-
extra_rdoc_files:
|
94
|
-
- History.txt
|
95
|
-
- Manifest.txt
|
96
|
-
- README.rdoc
|
97
|
-
- website/index.txt
|
98
|
-
- COPYING
|
99
|
-
- GPL
|
63
|
+
extra_rdoc_files: []
|
100
64
|
files:
|
65
|
+
- .gitignore
|
101
66
|
- COPYING
|
102
67
|
- GPL
|
68
|
+
- Gemfile
|
103
69
|
- History.txt
|
104
|
-
-
|
105
|
-
- README.rdoc
|
70
|
+
- README.md
|
106
71
|
- Rakefile
|
107
|
-
- config/website.yml
|
108
72
|
- examples/create_cal.rb
|
109
73
|
- examples/parse_cal.rb
|
110
74
|
- examples/single_event.ics
|
@@ -128,16 +92,14 @@ files:
|
|
128
92
|
- lib/icalendar/tzinfo.rb
|
129
93
|
- lib/meta.rb
|
130
94
|
- script/console
|
131
|
-
- script/destroy
|
132
|
-
- script/generate
|
133
95
|
- script/recur1.ics
|
134
96
|
- script/tryit.rb
|
135
|
-
- script/txt2html
|
136
97
|
- test/component/test_event.rb
|
137
98
|
- test/component/test_timezone.rb
|
138
99
|
- test/component/test_todo.rb
|
139
100
|
- test/fixtures/folding.ics
|
140
101
|
- test/fixtures/life.ics
|
102
|
+
- test/fixtures/nonstandard.ics
|
141
103
|
- test/fixtures/simplecal.ics
|
142
104
|
- test/fixtures/single_event.ics
|
143
105
|
- test/interactive.rb
|
@@ -148,20 +110,17 @@ files:
|
|
148
110
|
- test/test_helper.rb
|
149
111
|
- test/test_parameter.rb
|
150
112
|
- test/test_parser.rb
|
113
|
+
- test/test_tzinfo.rb
|
151
114
|
- website/index.html
|
152
115
|
- website/index.txt
|
153
116
|
- website/javascripts/rounded_corners_lite.inc.js
|
154
117
|
- website/stylesheets/screen.css
|
155
118
|
- website/template.html.erb
|
156
|
-
|
157
|
-
- .gemtest
|
158
|
-
homepage: http://github.com/icalendar/icalendar
|
119
|
+
homepage: https://github.com/icalendar/icalendar
|
159
120
|
licenses: []
|
160
121
|
metadata: {}
|
161
122
|
post_install_message:
|
162
|
-
rdoc_options:
|
163
|
-
- --main
|
164
|
-
- README.rdoc
|
123
|
+
rdoc_options: []
|
165
124
|
require_paths:
|
166
125
|
- lib
|
167
126
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -175,15 +134,22 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
134
|
- !ruby/object:Gem::Version
|
176
135
|
version: '0'
|
177
136
|
requirements: []
|
178
|
-
rubyforge_project:
|
137
|
+
rubyforge_project:
|
179
138
|
rubygems_version: 2.0.3
|
180
139
|
signing_key:
|
181
140
|
specification_version: 4
|
182
|
-
summary:
|
141
|
+
summary: A ruby implementation of the iCalendar specification (RFC-2445).
|
183
142
|
test_files:
|
184
143
|
- test/component/test_event.rb
|
185
144
|
- test/component/test_timezone.rb
|
186
145
|
- test/component/test_todo.rb
|
146
|
+
- test/fixtures/folding.ics
|
147
|
+
- test/fixtures/life.ics
|
148
|
+
- test/fixtures/nonstandard.ics
|
149
|
+
- test/fixtures/simplecal.ics
|
150
|
+
- test/fixtures/single_event.ics
|
151
|
+
- test/interactive.rb
|
152
|
+
- test/read_write.rb
|
187
153
|
- test/test_calendar.rb
|
188
154
|
- test/test_component.rb
|
189
155
|
- test/test_conversions.rb
|
data/.gemtest
DELETED
File without changes
|
data/Manifest.txt
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
COPYING
|
2
|
-
GPL
|
3
|
-
History.txt
|
4
|
-
Manifest.txt
|
5
|
-
README.rdoc
|
6
|
-
Rakefile
|
7
|
-
config/website.yml
|
8
|
-
examples/create_cal.rb
|
9
|
-
examples/parse_cal.rb
|
10
|
-
examples/single_event.ics
|
11
|
-
icalendar.gemspec
|
12
|
-
lib/hash_attrs.rb
|
13
|
-
lib/icalendar.rb
|
14
|
-
lib/icalendar/base.rb
|
15
|
-
lib/icalendar/calendar.rb
|
16
|
-
lib/icalendar/component.rb
|
17
|
-
lib/icalendar/component/alarm.rb
|
18
|
-
lib/icalendar/component/event.rb
|
19
|
-
lib/icalendar/component/freebusy.rb
|
20
|
-
lib/icalendar/component/journal.rb
|
21
|
-
lib/icalendar/component/timezone.rb
|
22
|
-
lib/icalendar/component/todo.rb
|
23
|
-
lib/icalendar/conversions.rb
|
24
|
-
lib/icalendar/helpers.rb
|
25
|
-
lib/icalendar/parameter.rb
|
26
|
-
lib/icalendar/parser.rb
|
27
|
-
lib/icalendar/rrule.rb
|
28
|
-
lib/icalendar/tzinfo.rb
|
29
|
-
lib/meta.rb
|
30
|
-
script/console
|
31
|
-
script/destroy
|
32
|
-
script/generate
|
33
|
-
script/recur1.ics
|
34
|
-
script/tryit.rb
|
35
|
-
script/txt2html
|
36
|
-
test/component/test_event.rb
|
37
|
-
test/component/test_timezone.rb
|
38
|
-
test/component/test_todo.rb
|
39
|
-
test/fixtures/folding.ics
|
40
|
-
test/fixtures/life.ics
|
41
|
-
test/fixtures/simplecal.ics
|
42
|
-
test/fixtures/single_event.ics
|
43
|
-
test/interactive.rb
|
44
|
-
test/read_write.rb
|
45
|
-
test/test_calendar.rb
|
46
|
-
test/test_component.rb
|
47
|
-
test/test_conversions.rb
|
48
|
-
test/test_helper.rb
|
49
|
-
test/test_parameter.rb
|
50
|
-
test/test_parser.rb
|
51
|
-
website/index.html
|
52
|
-
website/index.txt
|
53
|
-
website/javascripts/rounded_corners_lite.inc.js
|
54
|
-
website/stylesheets/screen.css
|
55
|
-
website/template.html.erb
|
data/README.rdoc
DELETED
@@ -1,286 +0,0 @@
|
|
1
|
-
= iCalendar -- Internet calendaring, Ruby style
|
2
|
-
|
3
|
-
* http://github.com/icalendar/icalendar
|
4
|
-
|
5
|
-
== DESCRIPTION
|
6
|
-
|
7
|
-
This is a Ruby library for dealing with iCalendar files. Rather than
|
8
|
-
explaining myself, here is the introduction from RFC-2445, which
|
9
|
-
defines the format:
|
10
|
-
|
11
|
-
The use of calendaring and scheduling has grown considerably in the
|
12
|
-
last decade. Enterprise and inter-enterprise business has become
|
13
|
-
dependent on rapid scheduling of events and actions using this
|
14
|
-
information technology. However, the longer term growth of calendaring
|
15
|
-
and scheduling, is currently limited by the lack of Internet standards
|
16
|
-
for the message content types that are central to these knowledgeware
|
17
|
-
applications. This memo is intended to progress the level of
|
18
|
-
interoperability possible between dissimilar calendaring and
|
19
|
-
scheduling applications. This memo defines a MIME content type for
|
20
|
-
exchanging electronic calendaring and scheduling information. The
|
21
|
-
Internet Calendaring and Scheduling Core Object Specification, or
|
22
|
-
iCalendar, allows for the capture and exchange of information normally
|
23
|
-
stored within a calendaring and scheduling application; such as a
|
24
|
-
Personal Information Manager (PIM) or a Group Scheduling product.
|
25
|
-
|
26
|
-
The iCalendar format is suitable as an exchange format between
|
27
|
-
applications or systems. The format is defined in terms of a MIME
|
28
|
-
content type. This will enable the object to be exchanged using
|
29
|
-
several transports, including but not limited to SMTP, HTTP, a file
|
30
|
-
system, desktop interactive protocols such as the use of a memory-
|
31
|
-
based clipboard or drag/drop interactions, point-to-point asynchronous
|
32
|
-
communication, wired-network transport, or some form of unwired
|
33
|
-
transport such as infrared might also be used.
|
34
|
-
|
35
|
-
|
36
|
-
== EXAMPLES
|
37
|
-
|
38
|
-
=== Probably want to start with this
|
39
|
-
|
40
|
-
require 'rubygems' # Unless you install from the tarball or zip.
|
41
|
-
require 'icalendar'
|
42
|
-
require 'date'
|
43
|
-
|
44
|
-
include Icalendar # Probably do this in your class to limit namespace overlap
|
45
|
-
|
46
|
-
=== Creating calendars and events is easy.
|
47
|
-
|
48
|
-
# Create a calendar with an event (standard method)
|
49
|
-
cal = Calendar.new
|
50
|
-
cal.event do
|
51
|
-
dtstart Date.new(2005, 04, 29)
|
52
|
-
dtend Date.new(2005, 04, 28)
|
53
|
-
summary "Meeting with the man."
|
54
|
-
description "Have a long lunch meeting and decide nothing..."
|
55
|
-
klass "PRIVATE"
|
56
|
-
end
|
57
|
-
|
58
|
-
cal.publish
|
59
|
-
|
60
|
-
=== Or you can make events like this
|
61
|
-
event = Event.new
|
62
|
-
event.start = DateTime.civil(2006, 6, 23, 8, 30)
|
63
|
-
event.summary = "A great event!"
|
64
|
-
cal.add_event(event)
|
65
|
-
|
66
|
-
event2 = cal.event # This automatically adds the event to the calendar
|
67
|
-
event2.start = DateTime.civil(2006, 6, 24, 8, 30)
|
68
|
-
event2.summary = "Another great event!"
|
69
|
-
|
70
|
-
# Now with support for property parameters
|
71
|
-
params = {"ALTREP" =>['"http://my.language.net"'], "LANGUAGE" => ["SPANISH"]}
|
72
|
-
|
73
|
-
cal.event do
|
74
|
-
dtstart Date.new(2005, 04, 29)
|
75
|
-
dtend Date.new(2005, 04, 28)
|
76
|
-
summary "This is a summary with params.", params
|
77
|
-
end
|
78
|
-
|
79
|
-
# We can output the calendar as a string to write to a file,
|
80
|
-
# network port, database etc.
|
81
|
-
cal_string = cal.to_ical
|
82
|
-
puts cal_string
|
83
|
-
|
84
|
-
== ALARMS
|
85
|
-
|
86
|
-
=== Within an event, you can create e-mail notification alarms like this...
|
87
|
-
|
88
|
-
cal.event.do
|
89
|
-
# ...other event properties
|
90
|
-
alarm do
|
91
|
-
action "EMAIL"
|
92
|
-
description "This is an event reminder" # email body (required)
|
93
|
-
summary "Alarm notification" # email subject (required)
|
94
|
-
attendees %w(mailto:me@my-domain.com mailto:me-too@my-domain.com) # one or more email recipients (required)
|
95
|
-
add_attendee "mailto:me-three@my-domain.com"
|
96
|
-
remove_attendee "mailto:me@my-domain.com"
|
97
|
-
trigger "-PT15M" # 15 minutes before
|
98
|
-
add_attach "ftp://host.com/novo-procs/felizano.exe", {"FMTTYPE" => "application/binary"} # email attachments (optional)
|
99
|
-
end
|
100
|
-
|
101
|
-
alarm do
|
102
|
-
action "DISPLAY" # This line isn't necessary, it's the default
|
103
|
-
summary "Alarm notification"
|
104
|
-
trigger "-P1DT0H0M0S" # 1 day before
|
105
|
-
end
|
106
|
-
|
107
|
-
alarm do
|
108
|
-
action "AUDIO"
|
109
|
-
trigger "-PT15M"
|
110
|
-
add_attach "Basso", {"VALUE" => ["URI"]} # only one attach allowed (optional)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# Output
|
115
|
-
|
116
|
-
# BEGIN:VALARM
|
117
|
-
# ACTION:EMAIL
|
118
|
-
# ATTACH;FMTTYPE=application/binary:ftp://host.com/novo-procs/felizano.exe
|
119
|
-
# TRIGGER:-PT15M
|
120
|
-
# SUMMARY:Alarm notification
|
121
|
-
# DESCRIPTION:This is an event reminder
|
122
|
-
# ATTENDEE:mailto:me-too@my-domain.com
|
123
|
-
# ATTENDEE:mailto:me-three@my-domain.com
|
124
|
-
# END:VALARM
|
125
|
-
#
|
126
|
-
# BEGIN:VALARM
|
127
|
-
# ACTION:DISPLAY
|
128
|
-
# TRIGGER:-P1DT0H0M0S
|
129
|
-
# SUMMARY:Alarm notification
|
130
|
-
# END:VALARM
|
131
|
-
#
|
132
|
-
# BEGIN:VALARM
|
133
|
-
# ACTION:AUDIO
|
134
|
-
# ATTACH;VALUE=URI:Basso
|
135
|
-
# TRIGGER:-PT15M
|
136
|
-
# END:VALARM
|
137
|
-
|
138
|
-
== Timezones
|
139
|
-
|
140
|
-
# Create a timezone definition (previous convention)
|
141
|
-
cal = Calendar.new
|
142
|
-
timezone = Icalendar::Timezone.new
|
143
|
-
daylight = Icalendar::Daylight.new
|
144
|
-
standard = Icalendar::Standard.new
|
145
|
-
|
146
|
-
timezone.timezone_id = "America/Chicago"
|
147
|
-
|
148
|
-
daylight.timezone_offset_from = "-0600"
|
149
|
-
daylight.timezone_offset_to = "-0500"
|
150
|
-
daylight.timezone_name = "CDT"
|
151
|
-
daylight.dtstart = "19700308TO20000"
|
152
|
-
daylight.recurrence_rules = ["FREQ=YEARLY;BYMONTH=3;BYDAY=2SU"]
|
153
|
-
|
154
|
-
standard.timezone_offset_from = "-0500"
|
155
|
-
standard.timezone_offset_to = "-0600"
|
156
|
-
standard.timezone_name = "CST"
|
157
|
-
standard.dtstart = "19701101T020000"
|
158
|
-
standard.recurrence_rules = ["YEARLY;BYMONTH=11;BYDAY=1SU"]
|
159
|
-
|
160
|
-
timezone.add(daylight)
|
161
|
-
timezone.add(standard)
|
162
|
-
cal.add(timezone)
|
163
|
-
|
164
|
-
# Now, you can make timezones like this
|
165
|
-
cal = Calendar.new
|
166
|
-
cal.timezone do
|
167
|
-
timezone_id "America/Chicago"
|
168
|
-
|
169
|
-
daylight do
|
170
|
-
timezone_offset_from "-0600"
|
171
|
-
timezone_offset_to "-0500"
|
172
|
-
timezone_name "CDT"
|
173
|
-
dtstart "19700308TO20000"
|
174
|
-
add_recurrence_rule "FREQ=YEARLY;BYMONTH=3;BYDAY=2SU"
|
175
|
-
end
|
176
|
-
|
177
|
-
standard do
|
178
|
-
timezone_offset_from "-0500"
|
179
|
-
timezone_offset_to "-0600"
|
180
|
-
timezone_name "CST"
|
181
|
-
dtstart "19701101T020000"
|
182
|
-
add_recurrence_rule "YEARLY;BYMONTH=11;BYDAY=1SU"
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
# Both conventions output
|
187
|
-
|
188
|
-
# BEGIN:VTIMEZONE
|
189
|
-
# TZID:America/Chicago
|
190
|
-
# BEGIN:DAYLIGHT
|
191
|
-
# TZOFFSETFROM:-0600
|
192
|
-
# TZOFFSETTO:-0500
|
193
|
-
# TZNAME:CDT
|
194
|
-
# DTSTART:19700308T020000
|
195
|
-
# RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
|
196
|
-
# END:DAYLIGHT
|
197
|
-
# BEGIN:STANDARD
|
198
|
-
# TZOFFSETFROM:-0500
|
199
|
-
# TZOFFSETTO:-0600
|
200
|
-
# TZNAME:CST
|
201
|
-
# DTSTART:19701101T020000
|
202
|
-
# RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
|
203
|
-
# END:STANDARD
|
204
|
-
# END:VTIMEZONE
|
205
|
-
|
206
|
-
== Unicode
|
207
|
-
Add `$KCODE = 'u'` to make icalender work correctly with Utf8 texts
|
208
|
-
|
209
|
-
== Parsing iCalendars:
|
210
|
-
|
211
|
-
# Open a file or pass a string to the parser
|
212
|
-
cal_file = File.open("single_event.ics")
|
213
|
-
|
214
|
-
# Parser returns an array of calendars because a single file
|
215
|
-
# can have multiple calendars.
|
216
|
-
cals = Icalendar.parse(cal_file)
|
217
|
-
cal = cals.first
|
218
|
-
|
219
|
-
# Now you can access the cal object in just the same way I created it
|
220
|
-
event = cal.events.first
|
221
|
-
|
222
|
-
puts "start date-time: " + event.dtstart
|
223
|
-
puts "summary: " + event.summary
|
224
|
-
|
225
|
-
# Some calendars contain non-standard parameters (e.g. Apple iCloud
|
226
|
-
# calendars). You can pass in a `strict` value when creating a new parser.
|
227
|
-
unstrict_parser = Icalendar::Parser.new(cal_file, false)
|
228
|
-
cal = unstrict_parser.parse()
|
229
|
-
|
230
|
-
== Finders:
|
231
|
-
|
232
|
-
Often times in web apps and other interactive applications you'll need to
|
233
|
-
lookup items in a calendar to make changes or get details. Now you can find
|
234
|
-
everything by the unique id automatically associated with all components.
|
235
|
-
|
236
|
-
cal = Calendar.new
|
237
|
-
10.times { cal.event } # Create 10 events with only default data.
|
238
|
-
some_event = cal.events[5] # Grab it from the array of events
|
239
|
-
|
240
|
-
# Use the uid as the key in your app
|
241
|
-
key = some_event.uid
|
242
|
-
|
243
|
-
# so later you can find it.
|
244
|
-
same_event = cal.find_event(key)
|
245
|
-
|
246
|
-
== Examples:
|
247
|
-
|
248
|
-
Check the unit tests for examples of most things you'll want to do, but please
|
249
|
-
send me example code or let me know what's missing.
|
250
|
-
|
251
|
-
== Download
|
252
|
-
|
253
|
-
The latest release version of this library can be found at
|
254
|
-
|
255
|
-
* http://rubyforge.org/projects/icalendar/
|
256
|
-
|
257
|
-
Documentation can be found at
|
258
|
-
|
259
|
-
* http://icalendar.rubyforge.org/
|
260
|
-
|
261
|
-
== Installation
|
262
|
-
|
263
|
-
It's all about rubygems:
|
264
|
-
|
265
|
-
$ sudo gem install icalendar
|
266
|
-
|
267
|
-
== Testing
|
268
|
-
|
269
|
-
The gem `hoe` is required as well:
|
270
|
-
|
271
|
-
gem install hoe
|
272
|
-
|
273
|
-
To run the tests:
|
274
|
-
|
275
|
-
rake test
|
276
|
-
|
277
|
-
== License
|
278
|
-
|
279
|
-
This library is released under the same license as Ruby itself.
|
280
|
-
|
281
|
-
== Support & Contributions
|
282
|
-
|
283
|
-
The iCalendar library homepage is http://icalendar.rubyforge.org/
|
284
|
-
|
285
|
-
There is an icalendar-devel@rubyforge.org mailing list that can be
|
286
|
-
used for asking questions, making comments or submitting patches.
|
data/config/website.yml
DELETED
data/script/destroy
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
-
|
4
|
-
begin
|
5
|
-
require 'rubigen'
|
6
|
-
rescue LoadError
|
7
|
-
require 'rubygems'
|
8
|
-
require 'rubigen'
|
9
|
-
end
|
10
|
-
require 'rubigen/scripts/destroy'
|
11
|
-
|
12
|
-
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
-
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
-
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
-
|
4
|
-
begin
|
5
|
-
require 'rubigen'
|
6
|
-
rescue LoadError
|
7
|
-
require 'rubygems'
|
8
|
-
require 'rubigen'
|
9
|
-
end
|
10
|
-
require 'rubigen/scripts/generate'
|
11
|
-
|
12
|
-
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
-
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
-
RubiGen::Scripts::Generate.new.run(ARGV)
|
data/script/txt2html
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
load File.dirname(__FILE__) + "/../Rakefile"
|
4
|
-
require 'rubyforge'
|
5
|
-
require 'redcloth'
|
6
|
-
require 'syntax/convertors/html'
|
7
|
-
require 'erb'
|
8
|
-
|
9
|
-
download = "http://rubyforge.org/projects/#{$hoe.rubyforge_name}"
|
10
|
-
version = $hoe.version
|
11
|
-
|
12
|
-
def rubyforge_project_id
|
13
|
-
RubyForge.new.configure.autoconfig["group_ids"][$hoe.rubyforge_name]
|
14
|
-
end
|
15
|
-
|
16
|
-
class Fixnum
|
17
|
-
def ordinal
|
18
|
-
# teens
|
19
|
-
return 'th' if (10..19).include?(self % 100)
|
20
|
-
# others
|
21
|
-
case self % 10
|
22
|
-
when 1 then return 'st'
|
23
|
-
when 2 then return 'nd'
|
24
|
-
when 3 then return 'rd'
|
25
|
-
else return 'th'
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
class Time
|
31
|
-
def pretty
|
32
|
-
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def convert_syntax(syntax, source)
|
37
|
-
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
38
|
-
end
|
39
|
-
|
40
|
-
if ARGV.length >= 1
|
41
|
-
src, template = ARGV
|
42
|
-
template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
|
43
|
-
else
|
44
|
-
puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
|
45
|
-
exit!
|
46
|
-
end
|
47
|
-
|
48
|
-
template = ERB.new(File.open(template).read)
|
49
|
-
|
50
|
-
title = nil
|
51
|
-
body = nil
|
52
|
-
File.open(src) do |fsrc|
|
53
|
-
title_text = fsrc.readline
|
54
|
-
body_text_template = fsrc.read
|
55
|
-
body_text = ERB.new(body_text_template).result(binding)
|
56
|
-
syntax_items = []
|
57
|
-
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
58
|
-
ident = syntax_items.length
|
59
|
-
element, syntax, source = $1, $2, $3
|
60
|
-
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
61
|
-
"syntax-temp-#{ident}"
|
62
|
-
}
|
63
|
-
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
64
|
-
body = RedCloth.new(body_text).to_html
|
65
|
-
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
66
|
-
end
|
67
|
-
stat = File.stat(src)
|
68
|
-
created = stat.ctime
|
69
|
-
modified = stat.mtime
|
70
|
-
|
71
|
-
$stdout << template.result(binding)
|