ifmapper 0.9.9 → 1.0.0
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.
- data/HISTORY.txt +36 -1
- data/IFMapper.gemspec +28 -0
- data/TODO.txt +1 -0
- data/docs/{index.html → en/index.html} +1 -1
- data/docs/{start.html → en/start.html} +6 -6
- data/docs/es/index.html +120 -0
- data/docs/es/start.html +1282 -0
- data/lib/IFMapper/FXConnection.rb +2 -2
- data/lib/IFMapper/FXConnectionDialogBox.rb +8 -26
- data/lib/IFMapper/FXMap.rb +36 -33
- data/lib/IFMapper/FXMapColorBox.rb +13 -16
- data/lib/IFMapper/FXMapDialogBox.rb +7 -7
- data/lib/IFMapper/FXMapFileDialog.rb +9 -4
- data/lib/IFMapper/FXMapperSettings.rb +162 -32
- data/lib/IFMapper/FXMapperWindow.rb +197 -202
- data/lib/IFMapper/FXRoomDialogBox.rb +12 -9
- data/lib/IFMapper/FXRoomList.rb +3 -3
- data/lib/IFMapper/FXSection.rb +1 -1
- data/lib/IFMapper/Inform7Writer.rb +103 -26
- data/lib/IFMapper/InformWriter.rb +15 -3
- data/lib/IFMapper/Room.rb +0 -11
- data/lib/IFMapper/TADSWriter.rb +15 -2
- data/lib/IFMapper/TranscriptDialogBox.rb +15 -103
- data/lib/IFMapper/locales/en/Messages.rb +435 -0
- data/lib/IFMapper/locales/es/Messages.rb +440 -0
- data/lib/IFMapper/locales/es/Messages_iso-8859-1.rb +440 -0
- data/lib/IFMapper/locales/es/runme.sh +3 -0
- data/maps/CityOfSecrets.map +0 -0
- data/maps/Janitor.map +0 -0
- metadata +28 -21
@@ -8,6 +8,7 @@ class FXRoomDialogBox < FXDialogBox
|
|
8
8
|
attr_writer :map
|
9
9
|
|
10
10
|
def copy_to()
|
11
|
+
|
11
12
|
@room.name = @name.text
|
12
13
|
@room.objects = @objects.text
|
13
14
|
@room.objects.gsub!(/[,\t]+/, "\n")
|
@@ -30,7 +31,7 @@ class FXRoomDialogBox < FXDialogBox
|
|
30
31
|
|
31
32
|
# Select text for quick editing if it uses default location name
|
32
33
|
@name.setCursorPos room.name.size
|
33
|
-
if room.name ==
|
34
|
+
if room.name == MSG_NEW_LOCATION
|
34
35
|
self.setFocus
|
35
36
|
@name.selectAll
|
36
37
|
@name.setFocus
|
@@ -85,14 +86,14 @@ class FXRoomDialogBox < FXDialogBox
|
|
85
86
|
decor = DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE
|
86
87
|
end
|
87
88
|
|
88
|
-
super( map.window,
|
89
|
+
super( map.window, BOX_ROOM_INFORMATION, decor, pos[0], pos[1], 0, 0 )
|
89
90
|
mainFrame = FXVerticalFrame.new(self,
|
90
91
|
FRAME_SUNKEN|FRAME_THICK|
|
91
92
|
LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
92
93
|
|
93
94
|
frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
94
95
|
|
95
|
-
FXLabel.new(frame,
|
96
|
+
FXLabel.new(frame, BOX_LOCATION, nil, 0, LAYOUT_FILL_X)
|
96
97
|
@name = FXTextField.new(frame, 40, nil, 0, LAYOUT_FILL_ROW)
|
97
98
|
|
98
99
|
|
@@ -104,8 +105,8 @@ class FXRoomDialogBox < FXDialogBox
|
|
104
105
|
LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
105
106
|
|
106
107
|
frame2 = FXHorizontalFrame.new(leftFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
107
|
-
FXLabel.new(frame2,
|
108
|
-
@darkness = FXCheckButton.new(frame2,
|
108
|
+
FXLabel.new(frame2, BOX_OBJECTS, nil, 0, LAYOUT_FILL_X)
|
109
|
+
@darkness = FXCheckButton.new(frame2, BOX_DARKNESS, nil, 0,
|
109
110
|
ICON_BEFORE_TEXT|LAYOUT_CENTER_X|
|
110
111
|
LAYOUT_SIDE_RIGHT)
|
111
112
|
|
@@ -115,7 +116,7 @@ class FXRoomDialogBox < FXDialogBox
|
|
115
116
|
|
116
117
|
@tasksFrame = FXVerticalFrame.new(leftFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|
|
117
118
|
LAYOUT_FILL_Y)
|
118
|
-
FXLabel.new(@tasksFrame,
|
119
|
+
FXLabel.new(@tasksFrame, BOX_TASKS, nil, 0, LAYOUT_FILL_X)
|
119
120
|
@tasks = FXText.new(@tasksFrame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
120
121
|
@tasks.visibleRows = 8
|
121
122
|
@tasks.visibleColumns = 40
|
@@ -123,7 +124,7 @@ class FXRoomDialogBox < FXDialogBox
|
|
123
124
|
######## Add description
|
124
125
|
@descFrame = FXVerticalFrame.new(all, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|
|
125
126
|
LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y)
|
126
|
-
FXLabel.new(@descFrame,
|
127
|
+
FXLabel.new(@descFrame, BOX_DESCRIPTION, nil, 0, LAYOUT_FILL_X)
|
127
128
|
@desc = FXText.new(@descFrame, nil, 0,
|
128
129
|
LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
|
129
130
|
@desc.visibleColumns = 70
|
@@ -134,11 +135,13 @@ class FXRoomDialogBox < FXDialogBox
|
|
134
135
|
LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|
|
135
136
|
PACK_UNIFORM_WIDTH)
|
136
137
|
# Accept
|
137
|
-
@ok = FXButton.new(buttons,
|
138
|
+
@ok = FXButton.new(buttons, BUTTON_ACCEPT, nil, self,
|
139
|
+
FXDialogBox::ID_ACCEPT,
|
138
140
|
FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT|LAYOUT_CENTER_Y)
|
139
141
|
|
140
142
|
# Cancel
|
141
|
-
cmd = FXButton.new(buttons,
|
143
|
+
cmd = FXButton.new(buttons, BUTTON_CANCEL, nil, self,
|
144
|
+
FXDialogBox::ID_CANCEL,
|
142
145
|
FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT|LAYOUT_CENTER_Y)
|
143
146
|
else
|
144
147
|
@name.connect(SEL_CHANGED) { copy_to() }
|
data/lib/IFMapper/FXRoomList.rb
CHANGED
@@ -66,13 +66,13 @@ class FXRoomList < FXDialogBox
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def initialize(map)
|
69
|
-
super(map.window.parent,
|
69
|
+
super(map.window.parent, BOX_LOCATIONS, DECOR_ALL, 40, 40, 300, 400)
|
70
70
|
|
71
71
|
@box = FXIconList.new(self, nil, 0,
|
72
72
|
ICONLIST_BROWSESELECT|
|
73
73
|
LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
74
|
-
@box.appendHeader(
|
75
|
-
@box.appendHeader(
|
74
|
+
@box.appendHeader(BOX_SECTION, nil, 60)
|
75
|
+
@box.appendHeader(BOX_NAME, nil, 200)
|
76
76
|
@box.header.connect(SEL_COMMAND) { |sender, sel, which|
|
77
77
|
if @box.header.arrowUp?(which)
|
78
78
|
dir = MAYBE
|
data/lib/IFMapper/FXSection.rb
CHANGED
@@ -23,7 +23,7 @@ class Inform7Writer
|
|
23
23
|
]
|
24
24
|
|
25
25
|
IGNORE_WORDS = [
|
26
|
-
'a', 'the', 'and', 'of', 'your', 'to'
|
26
|
+
'a', 'the', 'and', 'of', 'your', 'to', 'out', 'in'
|
27
27
|
]
|
28
28
|
|
29
29
|
IGNORED_ARTICLES = /^(?:#{IGNORE_WORDS.join('|')})$/
|
@@ -36,8 +36,14 @@ class Inform7Writer
|
|
36
36
|
'with',
|
37
37
|
'is',
|
38
38
|
'in',
|
39
|
-
'
|
40
|
-
|
39
|
+
'container',
|
40
|
+
'to',
|
41
|
+
'and',
|
42
|
+
'side',
|
43
|
+
'\s*,\s*',
|
44
|
+
'\s*\(\s*',
|
45
|
+
] + DIRECTIONS + OTHERDIRS[1..-1]
|
46
|
+
|
41
47
|
INVALID_KEYWORD = /\b(?:#{KEYWORDS.join('|')})\b/i
|
42
48
|
|
43
49
|
|
@@ -89,15 +95,27 @@ class Inform7Writer
|
|
89
95
|
|
90
96
|
IS_ANIMAL = /\b(?:#{ANIMALS.join('|')})\b/i
|
91
97
|
|
92
|
-
|
93
|
-
'
|
98
|
+
MALE_PEOPLE = [
|
99
|
+
'boy',
|
100
|
+
'man',
|
101
|
+
'sir',
|
102
|
+
]
|
103
|
+
IS_MALE_PERSON = /\b(?:#{MALE_PEOPLE.join('|')})\b/i
|
104
|
+
|
105
|
+
FEMALE_PEOPLE = [
|
94
106
|
'girl',
|
95
107
|
'woman',
|
96
108
|
'lady',
|
97
|
-
'
|
98
|
-
|
109
|
+
'actress',
|
110
|
+
]
|
111
|
+
IS_FEMALE_PERSON = /\b(?:#{FEMALE_PEOPLE.join('|')})\b/i
|
112
|
+
|
113
|
+
PEOPLE = MALE_PEOPLE + FEMALE_PEOPLE + [
|
114
|
+
'child',
|
99
115
|
'attendant',
|
100
116
|
'doctor',
|
117
|
+
'actor',
|
118
|
+
'character',
|
101
119
|
'engineer',
|
102
120
|
'bum',
|
103
121
|
'nerd',
|
@@ -117,14 +135,26 @@ class Inform7Writer
|
|
117
135
|
'can',
|
118
136
|
'chest',
|
119
137
|
'wardrobe',
|
138
|
+
'jacket',
|
139
|
+
'suit',
|
120
140
|
'trophy case',
|
121
141
|
'coffin',
|
122
142
|
'briefcase',
|
123
143
|
'suitcase',
|
124
144
|
'bag',
|
145
|
+
'flask',
|
125
146
|
]
|
126
147
|
IS_CONTAINER = /\b(?:#{CONTAINERS.join('|')})\b/i
|
127
148
|
|
149
|
+
#
|
150
|
+
# Some common lit types
|
151
|
+
#
|
152
|
+
UNLIT_TYPES = [
|
153
|
+
'lantern',
|
154
|
+
'torch',
|
155
|
+
]
|
156
|
+
IS_LIGHT = /\b(?:#{UNLIT_TYPES.join('|')})\b/i
|
157
|
+
|
128
158
|
#
|
129
159
|
# Some common wearable types
|
130
160
|
#
|
@@ -137,6 +167,8 @@ class Inform7Writer
|
|
137
167
|
'gown',
|
138
168
|
'backpack',
|
139
169
|
'shirt',
|
170
|
+
'jacket',
|
171
|
+
'suit',
|
140
172
|
'ring',
|
141
173
|
'bracelet',
|
142
174
|
'amulet',
|
@@ -178,6 +210,10 @@ class Inform7Writer
|
|
178
210
|
def new_tag(elem, str)
|
179
211
|
tag = str.dup
|
180
212
|
|
213
|
+
# Take text from Unicode utf-8 to iso-8859-1
|
214
|
+
utf = Iconv.new( 'iso-8859-1', 'utf-8' )
|
215
|
+
tag = utf.iconv( tag )
|
216
|
+
|
181
217
|
# Remove redundant spaces
|
182
218
|
tag.sub!(/^\s/, '')
|
183
219
|
tag.sub!(/\s$/, '')
|
@@ -188,8 +224,6 @@ class Inform7Writer
|
|
188
224
|
|
189
225
|
tag.gsub!(/__/, '_')
|
190
226
|
|
191
|
-
tag.upcase! # All tags are uppercase
|
192
|
-
|
193
227
|
# tag cannot be repeated and cannot be keyword (Doorway, Room, etc)
|
194
228
|
# In those cases, we add a number to the tag name.
|
195
229
|
idx = 0
|
@@ -217,9 +251,26 @@ class Inform7Writer
|
|
217
251
|
return tag
|
218
252
|
end
|
219
253
|
|
220
|
-
def get_tag(elem, name
|
254
|
+
def get_tag(elem, name)
|
221
255
|
return @tags[elem] if @tags[elem]
|
222
|
-
|
256
|
+
tag = name
|
257
|
+
if tag =~ INVALID_KEYWORD or @tags.values.include?(tag)
|
258
|
+
return new_tag(elem, name)
|
259
|
+
else
|
260
|
+
@tags[elem] = tag
|
261
|
+
end
|
262
|
+
return tag
|
263
|
+
end
|
264
|
+
|
265
|
+
def get_room_tag(elem)
|
266
|
+
return @tags[elem] if @tags[elem]
|
267
|
+
tag = elem.name
|
268
|
+
if tag =~ INVALID_KEYWORD or @tags.values.include?(tag)
|
269
|
+
tag = new_tag(elem, elem.name)
|
270
|
+
else
|
271
|
+
@tags[elem] = tag
|
272
|
+
end
|
273
|
+
return tag
|
223
274
|
end
|
224
275
|
|
225
276
|
def get_door_name(e)
|
@@ -230,18 +281,24 @@ class Inform7Writer
|
|
230
281
|
end
|
231
282
|
|
232
283
|
def get_door_tag(e)
|
233
|
-
|
284
|
+
name = get_door_name(e)
|
285
|
+
name.upcase
|
286
|
+
get_tag(e, name)
|
234
287
|
end
|
235
288
|
|
236
289
|
def wrap_text(text, width = 75, indent = 78 - width)
|
237
|
-
return 'UNDER CONSTRUCTION' if not text or text == ''
|
238
|
-
str = inform_quote( text
|
290
|
+
return 'UNDER CONSTRUCTION.' if not text or text == ''
|
291
|
+
str = inform_quote( text )
|
239
292
|
|
240
293
|
if str.size > width
|
241
294
|
r = ''
|
242
295
|
while str
|
243
|
-
|
244
|
-
|
296
|
+
if str.size >= width
|
297
|
+
idx = str.rindex(/[ -]/, width)
|
298
|
+
idx = str.size unless idx
|
299
|
+
else
|
300
|
+
idx = str.size
|
301
|
+
end
|
245
302
|
r << str[0..idx]
|
246
303
|
str = str[idx+1..-1]
|
247
304
|
r << "\n" << ' ' * indent if str
|
@@ -258,6 +315,11 @@ class Inform7Writer
|
|
258
315
|
#
|
259
316
|
def inform_quote(text)
|
260
317
|
str = text.dup
|
318
|
+
|
319
|
+
# Take text from Unicode utf-8 to iso-8859-1
|
320
|
+
utf = Iconv.new( 'iso-8859-1', 'utf-8' )
|
321
|
+
str = utf.iconv( str )
|
322
|
+
|
261
323
|
# Quote special characters
|
262
324
|
# str.gsub!(/@/, '@@64')
|
263
325
|
str.gsub!(/"/, '\'')
|
@@ -269,11 +331,11 @@ class Inform7Writer
|
|
269
331
|
|
270
332
|
|
271
333
|
def objects(r)
|
272
|
-
room =
|
334
|
+
room = get_room_tag(r)
|
273
335
|
objs = r.objects.split("\n")
|
274
336
|
objs.each { |o|
|
275
337
|
|
276
|
-
tag =
|
338
|
+
tag = get_tag(o, o)
|
277
339
|
|
278
340
|
names = o.dup
|
279
341
|
names.gsub!(/"/, '') # remove any quotes
|
@@ -285,7 +347,7 @@ class Inform7Writer
|
|
285
347
|
article = 'a '
|
286
348
|
if name =~ /ves$/ or name =~ /s$/
|
287
349
|
article = 'some '
|
288
|
-
elsif name[
|
350
|
+
elsif name =~ /^[aeiou]/
|
289
351
|
article = 'an '
|
290
352
|
end
|
291
353
|
|
@@ -295,7 +357,15 @@ class Inform7Writer
|
|
295
357
|
|
296
358
|
if name =~ IS_ANIMAL
|
297
359
|
type = 'an animal'
|
298
|
-
elsif name =~ IS_PERSON
|
360
|
+
elsif name =~ IS_PERSON
|
361
|
+
article = 'a '
|
362
|
+
type = 'a person'
|
363
|
+
if name =~ IS_MALE_PERSON
|
364
|
+
type = 'a male person'
|
365
|
+
elsif name =~ IS_FEMALE_PERSON
|
366
|
+
type = 'a female person'
|
367
|
+
end
|
368
|
+
elsif name =~ /[A-Z]/
|
299
369
|
if name !~ /'/ # possesive, like Michael's wallet
|
300
370
|
# if too many words, probably a book's title
|
301
371
|
if names.size <= 3
|
@@ -314,6 +384,12 @@ class Inform7Writer
|
|
314
384
|
|
315
385
|
if tag != name
|
316
386
|
props << "\n The printed name of #{tag} is \"#{article}#{name}\"."
|
387
|
+
else
|
388
|
+
tag = article + tag
|
389
|
+
end
|
390
|
+
|
391
|
+
if name =~ IS_LIGHT
|
392
|
+
props << "\n It is not lit."
|
317
393
|
end
|
318
394
|
|
319
395
|
if name =~ IS_CONTAINER
|
@@ -349,10 +425,10 @@ EOF
|
|
349
425
|
end
|
350
426
|
|
351
427
|
def door(e)
|
352
|
-
name
|
353
|
-
tag
|
354
|
-
roomA =
|
355
|
-
roomB =
|
428
|
+
name = get_door_name(e)
|
429
|
+
tag = get_tag(e, name)
|
430
|
+
roomA = get_room_tag(e.roomA)
|
431
|
+
roomB = get_room_tag(e.roomB)
|
356
432
|
dirA = e.roomA.exits.index(e)
|
357
433
|
dirB = e.roomB.exits.rindex(e)
|
358
434
|
dirA = DIRECTIONS[dirA].downcase
|
@@ -378,6 +454,7 @@ EOF
|
|
378
454
|
|
379
455
|
The #{tag} is a door. #{props}
|
380
456
|
The printed name of #{tag} is "a #{name}".
|
457
|
+
Understand "#{name}" as #{tag}.
|
381
458
|
Understand "door" as #{tag}.
|
382
459
|
#{found_in}.
|
383
460
|
EOF
|
@@ -386,7 +463,7 @@ EOF
|
|
386
463
|
|
387
464
|
|
388
465
|
def room(r)
|
389
|
-
tag =
|
466
|
+
tag = get_room_tag(r)
|
390
467
|
name = r.name
|
391
468
|
|
392
469
|
prop = ''
|
@@ -426,7 +503,7 @@ EOF
|
|
426
503
|
e.type == Connection::LOCKED_DOOR
|
427
504
|
@f.print get_door_tag(e)
|
428
505
|
else
|
429
|
-
@f.print
|
506
|
+
@f.print get_room_tag(b)
|
430
507
|
end
|
431
508
|
@f.puts '.'
|
432
509
|
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
|
2
2
|
|
3
|
+
|
3
4
|
class InformWriter
|
4
5
|
|
5
6
|
|
@@ -34,6 +35,8 @@ class InformWriter
|
|
34
35
|
|
35
36
|
def new_tag(elem, str)
|
36
37
|
tag = str.dup
|
38
|
+
utf = Iconv.new( 'iso-8859-1', 'utf-8' )
|
39
|
+
tag = utf.iconv( tag )
|
37
40
|
|
38
41
|
# Invalid tag characters, replaced with _
|
39
42
|
tag.gsub!(/[\s"'\/\\\-#\,.:;!\?\n\(\)]/,'_')
|
@@ -75,13 +78,17 @@ class InformWriter
|
|
75
78
|
|
76
79
|
def wrap_text(text, width = 65, indent = 79 - width)
|
77
80
|
return 'UNDER CONSTRUCTION' unless text
|
78
|
-
str = inform_quote( text
|
81
|
+
str = inform_quote( text )
|
79
82
|
|
80
83
|
if text.size > width
|
81
84
|
r = ''
|
82
85
|
while str
|
83
|
-
|
84
|
-
|
86
|
+
if str.size >= width
|
87
|
+
idx = str.rindex(/[ -]/, width)
|
88
|
+
idx = str.size unless idx
|
89
|
+
else
|
90
|
+
idx = str.size
|
91
|
+
end
|
85
92
|
r << str[0..idx]
|
86
93
|
str = str[idx+1..-1]
|
87
94
|
r << "\n" << ' ' * indent if str
|
@@ -98,6 +105,11 @@ class InformWriter
|
|
98
105
|
#
|
99
106
|
def inform_quote(text)
|
100
107
|
str = text.dup
|
108
|
+
|
109
|
+
# Take text from Unicode utf-8 to iso-8859-1
|
110
|
+
utf = Iconv.new( 'iso-8859-1', 'utf-8' )
|
111
|
+
str = utf.iconv( str )
|
112
|
+
|
101
113
|
# Quote special characters
|
102
114
|
str.gsub!(/@/, '@@64')
|
103
115
|
str.gsub!(/"/, '@@34')
|
data/lib/IFMapper/Room.rb
CHANGED
@@ -11,17 +11,6 @@ class Room
|
|
11
11
|
attr_accessor :x, :y # Room location in grid
|
12
12
|
attr_accessor :desc # Room description
|
13
13
|
|
14
|
-
DIRECTIONS = [
|
15
|
-
'n',
|
16
|
-
'ne',
|
17
|
-
'e',
|
18
|
-
'se',
|
19
|
-
's',
|
20
|
-
'sw',
|
21
|
-
'w',
|
22
|
-
'nw',
|
23
|
-
]
|
24
|
-
|
25
14
|
DIR_TO_VECTOR = {
|
26
15
|
0 => [ 0, -1 ],
|
27
16
|
1 => [ 1, -1 ],
|
data/lib/IFMapper/TADSWriter.rb
CHANGED
@@ -37,6 +37,10 @@ class TADSWriter
|
|
37
37
|
def new_tag(elem, str)
|
38
38
|
tag = str.dup
|
39
39
|
|
40
|
+
# Take text from Unicode utf-8 to iso-8859-1
|
41
|
+
utf = Iconv.new( 'iso-8859-1', 'utf-8' )
|
42
|
+
tag = utf.iconv( tag )
|
43
|
+
|
40
44
|
# Invalid tag characters, replaced with _
|
41
45
|
tag.gsub!(/[\s"'\/\\\-#\,.:;!\?\n\(\)]/,'_')
|
42
46
|
|
@@ -87,8 +91,12 @@ class TADSWriter
|
|
87
91
|
if text.size > width
|
88
92
|
r = ''
|
89
93
|
while str
|
90
|
-
|
91
|
-
|
94
|
+
if str.size >= width
|
95
|
+
idx = str.rindex(/[ -]/, width)
|
96
|
+
idx = str.size unless idx
|
97
|
+
else
|
98
|
+
idx = str.size
|
99
|
+
end
|
92
100
|
r << str[0..idx]
|
93
101
|
str = str[idx+1..-1]
|
94
102
|
r << "\n" << ' ' * indent if str
|
@@ -105,6 +113,11 @@ class TADSWriter
|
|
105
113
|
#
|
106
114
|
def self.quote(text)
|
107
115
|
str = text.dup
|
116
|
+
|
117
|
+
# Take text from Unicode utf-8 to iso-8859-1
|
118
|
+
utf = Iconv.new( 'iso-8859-1', 'utf-8' )
|
119
|
+
str = utf.iconv( str )
|
120
|
+
|
108
121
|
# Quote special characters
|
109
122
|
str.gsub!(/"/, '\"')
|
110
123
|
str.gsub!(/'/, "\\\\'")
|