rinku 1.1.0 → 1.2.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/Rakefile CHANGED
@@ -56,8 +56,7 @@ task :gather => 'upskirt/src/markdown.h' do |t|
56
56
  files =
57
57
  FileList[
58
58
  'upskirt/src/{buffer,autolink}.h',
59
- 'upskirt/src/{buffer,autolink}.c',
60
- 'upskirt/html/html_autolink.c'
59
+ 'upskirt/src/{buffer,autolink}.c'
61
60
  ]
62
61
  cp files, 'ext/rinku/',
63
62
  :preserve => true,
data/ext/rinku/autolink.h CHANGED
@@ -19,15 +19,6 @@
19
19
 
20
20
  #include "buffer.h"
21
21
 
22
- typedef enum {
23
- AUTOLINK_URLS = (1 << 0),
24
- AUTOLINK_EMAILS = (1 << 1),
25
- AUTOLINK_ALL = AUTOLINK_URLS|AUTOLINK_EMAILS,
26
- AUTOLINK_SANITIZE_NAMES = (1 << 2),
27
- AUTOLINK_SANITIZE_URLS = (1 << 3),
28
- AUTOLINK_SANITIZE = AUTOLINK_SANITIZE_NAMES|AUTOLINK_SANITIZE_URLS,
29
- } autolink_mode;
30
-
31
22
  extern size_t
32
23
  ups_autolink__www(size_t *rewind_p, struct buf *link, char *data, size_t offset, size_t size);
33
24
 
data/ext/rinku/rinku.c CHANGED
@@ -27,17 +27,223 @@
27
27
  #include "autolink.h"
28
28
  #include "buffer.h"
29
29
 
30
- static VALUE rb_cRinku;
30
+ #include <string.h>
31
+ #include <stdlib.h>
32
+ #include <stdio.h>
33
+ #include <ctype.h>
34
+
35
+ static VALUE rb_mRinku;
36
+
37
+ typedef enum {
38
+ AUTOLINK_URLS = (1 << 0),
39
+ AUTOLINK_EMAILS = (1 << 1),
40
+ AUTOLINK_ALL = AUTOLINK_URLS|AUTOLINK_EMAILS
41
+ } autolink_mode;
42
+
43
+ typedef size_t (*autolink_parse_cb)(size_t *rewind, struct buf *, char *, size_t, size_t);
44
+
45
+ typedef enum {
46
+ AUTOLINK_ACTION_NONE = 0,
47
+ AUTOLINK_ACTION_WWW,
48
+ AUTOLINK_ACTION_EMAIL,
49
+ AUTOLINK_ACTION_URL,
50
+ AUTOLINK_ACTION_SKIP_TAG
51
+ } autolink_action;
52
+
53
+ static autolink_parse_cb g_callbacks[] = {
54
+ NULL,
55
+ ups_autolink__www, /* 1 */
56
+ ups_autolink__email,/* 2 */
57
+ ups_autolink__url, /* 3 */
58
+ };
59
+
60
+ static const char *g_hrefs[] = {
61
+ NULL,
62
+ "<a href=\"http://",
63
+ "<a href=\"mailto:",
64
+ "<a href=\"",
65
+ };
66
+
67
+ static void
68
+ autolink_escape_cb(struct buf *ob, const struct buf *text, void *unused)
69
+ {
70
+ size_t i = 0, org;
71
+
72
+ while (i < text->size) {
73
+ org = i;
74
+
75
+ while (i < text->size &&
76
+ text->data[i] != '<' &&
77
+ text->data[i] != '>' &&
78
+ text->data[i] != '&' &&
79
+ text->data[i] != '"')
80
+ i++;
81
+
82
+ if (i > org)
83
+ bufput(ob, text->data + org, i - org);
84
+
85
+ if (i >= text->size)
86
+ break;
87
+
88
+ switch (text->data[i]) {
89
+ case '<': BUFPUTSL(ob, "&lt;"); break;
90
+ case '>': BUFPUTSL(ob, "&gt;"); break;
91
+ case '&': BUFPUTSL(ob, "&amp;"); break;
92
+ case '"': BUFPUTSL(ob, "&quot;"); break;
93
+ default: bufputc(ob, text->data[i]); break;
94
+ }
95
+
96
+ i++;
97
+ }
98
+ }
99
+
100
+ static inline int
101
+ is_closing_a(const char *tag, size_t size)
102
+ {
103
+ size_t i;
104
+
105
+ if (tag[0] != '<' || size < STRLEN("</a>") || tag[1] != '/')
106
+ return 0;
107
+
108
+ i = 2;
109
+
110
+ while (i < size && isspace(tag[i]))
111
+ i++;
112
+
113
+ if (i == size || tag[i] != 'a')
114
+ return 0;
115
+
116
+ i++;
117
+
118
+ while (i < size && isspace(tag[i]))
119
+ i++;
120
+
121
+ if (i == size || tag[i] != '>')
122
+ return 0;
123
+
124
+ return i;
125
+ }
126
+
127
+ static size_t
128
+ autolink__skip_tag(struct buf *ob, char *text, size_t size)
129
+ {
130
+ size_t i = 0;
131
+
132
+ while (i < size && text[i] != '>')
133
+ i++;
134
+
135
+ if (size > 3 && text[1] == 'a' && isspace(text[2])) {
136
+ while (i < size) {
137
+ size_t tag_len = is_closing_a(text + i, size - i);
138
+ if (tag_len) {
139
+ i += tag_len;
140
+ break;
141
+ }
142
+ i++;
143
+ }
144
+ }
31
145
 
32
- extern void
33
- upshtml_autolink(
146
+ return i + 1;
147
+ }
148
+
149
+ int
150
+ rinku_autolink(
34
151
  struct buf *ob,
35
152
  struct buf *text,
36
153
  unsigned int flags,
37
154
  const char *link_attr,
38
155
  void (*link_text_cb)(struct buf *ob, const struct buf *link, void *payload),
39
- void *payload);
156
+ void *payload)
157
+ {
158
+ size_t i, end;
159
+ struct buf *link = bufnew(16);
160
+ char active_chars[256];
161
+ void (*link_url_cb)(struct buf *, const struct buf *, void *);
162
+ int link_count = 0;
163
+
164
+ if (!text || text->size == 0)
165
+ return;
166
+
167
+ memset(active_chars, 0x0, sizeof(active_chars));
168
+
169
+ active_chars['<'] = AUTOLINK_ACTION_SKIP_TAG;
170
+
171
+ if (flags & AUTOLINK_EMAILS)
172
+ active_chars['@'] = AUTOLINK_ACTION_EMAIL;
173
+
174
+ if (flags & AUTOLINK_URLS) {
175
+ active_chars['w'] = AUTOLINK_ACTION_WWW;
176
+ active_chars['W'] = AUTOLINK_ACTION_WWW;
177
+ active_chars[':'] = AUTOLINK_ACTION_URL;
178
+ }
179
+
180
+ if (link_text_cb == NULL)
181
+ link_text_cb = &autolink_escape_cb;
182
+
183
+ if (link_attr != NULL) {
184
+ while (isspace(*link_attr))
185
+ link_attr++;
186
+ }
187
+
188
+ bufgrow(ob, text->size);
189
+
190
+ i = end = 0;
191
+
192
+ while (i < text->size) {
193
+ size_t rewind, link_end;
194
+ char action;
195
+
196
+ while (end < text->size && (action = active_chars[(int)text->data[end]]) == 0)
197
+ end++;
198
+
199
+ if (end == text->size) {
200
+ if (link_count > 0)
201
+ bufput(ob, text->data + i, end - i);
202
+ break;
203
+ }
40
204
 
205
+ if (action == AUTOLINK_ACTION_SKIP_TAG) {
206
+ end += autolink__skip_tag(ob, text->data + end, text->size - end);
207
+ continue;
208
+ }
209
+
210
+ link->size = 0;
211
+ link_end = g_callbacks[(int)action](&rewind, link, text->data + end, end, text->size - end);
212
+
213
+ /* print the link */
214
+ if (link_end > 0) {
215
+ bufput(ob, text->data + i, end - i - rewind);
216
+
217
+ bufputs(ob, g_hrefs[(int)action]);
218
+ autolink_escape_cb(ob, link, NULL);
219
+
220
+ if (link_attr) {
221
+ BUFPUTSL(ob, "\" ");
222
+ bufputs(ob, link_attr);
223
+ bufputc(ob, '>');
224
+ } else {
225
+ BUFPUTSL(ob, "\">");
226
+ }
227
+
228
+ link_text_cb(ob, link, payload);
229
+ BUFPUTSL(ob, "</a>");
230
+
231
+ link_count++;
232
+ i = end + link_end;
233
+ end = i;
234
+ } else {
235
+ end = end + 1;
236
+ }
237
+ }
238
+
239
+ bufrelease(link);
240
+ return link_count;
241
+ }
242
+
243
+
244
+ /**
245
+ * Ruby code
246
+ */
41
247
  static void
42
248
  autolink_callback(struct buf *link_text, const struct buf *link, void *block)
43
249
  {
@@ -97,7 +303,7 @@ rb_rinku_autolink(int argc, VALUE *argv, VALUE self)
97
303
  {
98
304
  VALUE result, rb_text, rb_mode, rb_html, rb_block;
99
305
  struct buf input_buf = {0, 0, 0, 0, 0}, *output_buf;
100
- int link_mode;
306
+ int link_mode, count;
101
307
  const char *link_attr = NULL;
102
308
  ID mode_sym;
103
309
 
@@ -119,7 +325,7 @@ rb_rinku_autolink(int argc, VALUE *argv, VALUE self)
119
325
 
120
326
  input_buf.data = RSTRING_PTR(rb_text);
121
327
  input_buf.size = RSTRING_LEN(rb_text);
122
- output_buf = bufnew(128);
328
+ output_buf = bufnew(32);
123
329
 
124
330
  if (mode_sym == rb_intern("all"))
125
331
  link_mode = AUTOLINK_ALL;
@@ -131,26 +337,29 @@ rb_rinku_autolink(int argc, VALUE *argv, VALUE self)
131
337
  rb_raise(rb_eTypeError,
132
338
  "Invalid linking mode (possible values are :all, :urls, :email_addresses)");
133
339
 
134
- link_mode |= AUTOLINK_SANITIZE;
340
+ count = rinku_autolink(
341
+ output_buf,
342
+ &input_buf,
343
+ link_mode,
344
+ link_attr,
345
+ RTEST(rb_block) ? &autolink_callback : NULL,
346
+ (void*)rb_block);
135
347
 
136
- if (RTEST(rb_block))
137
- upshtml_autolink(output_buf, &input_buf, link_mode, link_attr, &autolink_callback, (void*)rb_block);
138
- else
139
- upshtml_autolink(output_buf, &input_buf, link_mode, link_attr, NULL, NULL);
348
+ if (count == 0)
349
+ result = rb_text;
350
+ else {
351
+ result = rb_str_new(output_buf->data, output_buf->size);
352
+ rb_enc_copy(result, rb_text);
353
+ }
140
354
 
141
- result = rb_str_new(output_buf->data, output_buf->size);
142
355
  bufrelease(output_buf);
143
-
144
- /* force the input encoding */
145
- rb_enc_copy(result, rb_text);
146
-
147
356
  return result;
148
357
  }
149
358
 
150
359
  void Init_rinku()
151
360
  {
152
- rb_cRinku = rb_define_class("Rinku", rb_cObject);
153
- rb_define_singleton_method(rb_cRinku, "auto_link", rb_rinku_autolink, -1);
361
+ rb_mRinku = rb_define_module("Rinku");
362
+ rb_define_method(rb_mRinku, "auto_link", rb_rinku_autolink, -1);
154
363
  }
155
364
 
156
365
 
data/lib/rails_rinku.rb CHANGED
@@ -1,35 +1,21 @@
1
1
  require 'rinku'
2
2
 
3
3
  module RailsRinku
4
- class Railtie < ::Rails::Railtie
5
- initializer 'rails_rinku' do |app|
6
- ActiveSupport.on_load(:action_view) do
7
- require 'active_support/core_ext/object/blank'
8
- require 'active_support/core_ext/array/extract_options'
9
- require 'active_support/core_ext/hash/reverse_merge'
10
- require 'active_support/core_ext/hash/keys'
4
+ def auto_link(text, *args, &block)
5
+ return ''.html_safe if text.blank?
11
6
 
12
- module ::ActionView
13
- module Helpers # :nodoc:
14
- module TextHelper
15
- def auto_link(text, *args, &block)
16
- return ''.html_safe if text.blank?
17
-
18
- options = args.size == 2 ? {} : args.extract_options!
19
- unless args.empty?
20
- options[:link] = args[0] || :all
21
- options[:html] = args[1] || {}
22
- end
23
- options.reverse_merge!(:link => :all, :html => {})
24
- text = sanitize(text) unless options[:sanitize] == false
25
-
26
- Rinku.auto_link(text, options[:link], tag_options(options[:html]), &block)
27
- end
28
- end
29
- end
30
- end
31
- end
7
+ options = args.size == 2 ? {} : args.extract_options!
8
+ unless args.empty?
9
+ options[:link] = args[0] || :all
10
+ options[:html] = args[1] || {}
32
11
  end
12
+ options.reverse_merge!(:link => :all, :html => {})
13
+ text = sanitize(text) unless options[:sanitize] == false
14
+
15
+ Rinku.auto_link(text, options[:link], tag_options(options[:html]), &block)
33
16
  end
34
17
  end
35
18
 
19
+ module ActionView::Helpers::TextHelper
20
+ include RailsRinku
21
+ end
data/lib/rinku.rb CHANGED
@@ -1,5 +1,6 @@
1
- class Rinku
2
- VERSION = "1.1.0"
1
+ module Rinku
2
+ VERSION = "1.2.0"
3
+ extend self
3
4
  end
4
5
 
5
6
  require 'rinku.so'
data/rinku.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rinku'
3
- s.version = '1.1.0'
3
+ s.version = '1.2.0'
4
4
  s.summary = "Mostly autolinking"
5
5
  s.description = <<-EOF
6
6
  A fast and very smart autolinking library that
@@ -19,7 +19,6 @@ Gem::Specification.new do |s|
19
19
  ext/rinku/autolink.h
20
20
  ext/rinku/buffer.c
21
21
  ext/rinku/buffer.h
22
- ext/rinku/html_autolink.c
23
22
  ext/rinku/extconf.rb
24
23
  lib/rinku.rb
25
24
  lib/rails_rinku.rb
@@ -28,7 +28,7 @@ class RedcarpetAutolinkTest < Test::Unit::TestCase
28
28
  assert_equal "{link: #{link3_result}}", Rinku.auto_link("{link: #{link3_raw}}")
29
29
  end
30
30
 
31
- def test_auto_link_with_multiple_trailing_punctuations
31
+ def test_auto_link_with_multiple_trailing_punctuations
32
32
  url = "http://youtube.com"
33
33
  url_result = generate_result(url)
34
34
  assert_equal url_result, Rinku.auto_link(url)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rinku
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 1.1.0
10
+ version: 1.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Vicent Mart\xC3\xAD"
@@ -15,7 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-06-11 00:00:00 Z
18
+ date: 2011-06-11 00:00:00 +02:00
19
+ default_executable:
19
20
  dependencies: []
20
21
 
21
22
  description: " A fast and very smart autolinking library that\n acts as a drop-in replacement for Rails `auto_link`\n"
@@ -35,12 +36,12 @@ files:
35
36
  - ext/rinku/autolink.h
36
37
  - ext/rinku/buffer.c
37
38
  - ext/rinku/buffer.h
38
- - ext/rinku/html_autolink.c
39
39
  - ext/rinku/extconf.rb
40
40
  - lib/rinku.rb
41
41
  - lib/rails_rinku.rb
42
42
  - rinku.gemspec
43
43
  - test/autolink_test.rb
44
+ has_rdoc: true
44
45
  homepage: http://github.com/tanoku/rinku
45
46
  licenses: []
46
47
 
@@ -70,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
71
  requirements: []
71
72
 
72
73
  rubyforge_project:
73
- rubygems_version: 1.8.5
74
+ rubygems_version: 1.6.2
74
75
  signing_key:
75
76
  specification_version: 3
76
77
  summary: Mostly autolinking
@@ -1,226 +0,0 @@
1
- /*
2
- * Copyright (c) 2011, Vicent Marti
3
- *
4
- * Permission to use, copy, modify, and distribute this software for any
5
- * purpose with or without fee is hereby granted, provided that the above
6
- * copyright notice and this permission notice appear in all copies.
7
- *
8
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
- */
16
-
17
- #include "autolink.h"
18
- #include "buffer.h"
19
-
20
- #include <string.h>
21
- #include <stdlib.h>
22
- #include <stdio.h>
23
- #include <ctype.h>
24
-
25
- static void
26
- autolink_escape_cb(struct buf *ob, const struct buf *text, void *unused)
27
- {
28
- size_t i = 0, org;
29
-
30
- while (i < text->size) {
31
- org = i;
32
-
33
- while (i < text->size &&
34
- text->data[i] != '<' &&
35
- text->data[i] != '>' &&
36
- text->data[i] != '&' &&
37
- text->data[i] != '"')
38
- i++;
39
-
40
- if (i > org)
41
- bufput(ob, text->data + org, i - org);
42
-
43
- if (i >= text->size)
44
- break;
45
-
46
- switch (text->data[i]) {
47
- case '<': BUFPUTSL(ob, "&lt;"); break;
48
- case '>': BUFPUTSL(ob, "&gt;"); break;
49
- case '&': BUFPUTSL(ob, "&amp;"); break;
50
- case '"': BUFPUTSL(ob, "&quot;"); break;
51
- default: bufputc(ob, text->data[i]); break;
52
- }
53
-
54
- i++;
55
- }
56
- }
57
-
58
- static inline int
59
- is_closing_a(const char *tag, size_t size)
60
- {
61
- size_t i;
62
-
63
- if (tag[0] != '<' || size < STRLEN("</a>") || tag[1] != '/')
64
- return 0;
65
-
66
- i = 2;
67
-
68
- while (i < size && isspace(tag[i]))
69
- i++;
70
-
71
- if (i == size || tag[i] != 'a')
72
- return 0;
73
-
74
- i++;
75
-
76
- while (i < size && isspace(tag[i]))
77
- i++;
78
-
79
- if (i == size || tag[i] != '>')
80
- return 0;
81
-
82
- return i;
83
- }
84
-
85
- static size_t
86
- autolink__skip_tag(struct buf *ob, char *text, size_t size)
87
- {
88
- size_t i = 0;
89
-
90
- while (i < size && text[i] != '>')
91
- i++;
92
-
93
- if (size > 3 && text[1] == 'a' && isspace(text[2])) {
94
- while (i < size) {
95
- size_t tag_len = is_closing_a(text + i, size - i);
96
- if (tag_len) {
97
- i += tag_len;
98
- break;
99
- }
100
- i++;
101
- }
102
- }
103
-
104
- bufput(ob, text, i + 1);
105
- return i + 1;
106
- }
107
-
108
- typedef size_t (*autolink_parse_cb)(size_t *rewind, struct buf *, char *, size_t, size_t);
109
-
110
- typedef enum {
111
- AUTOLINK_ACTION_NONE = 0,
112
- AUTOLINK_ACTION_WWW,
113
- AUTOLINK_ACTION_EMAIL,
114
- AUTOLINK_ACTION_URL,
115
- AUTOLINK_ACTION_SKIP_TAG
116
- } autolink_action;
117
-
118
- static autolink_parse_cb g_callbacks[] = {
119
- NULL,
120
- ups_autolink__www, /* 1 */
121
- ups_autolink__email,/* 2 */
122
- ups_autolink__url, /* 3 */
123
- };
124
-
125
- static const char *g_hrefs[] = {
126
- NULL,
127
- "<a href=\"http://",
128
- "<a href=\"mailto:",
129
- "<a href=\"",
130
- };
131
-
132
- void
133
- upshtml_autolink(
134
- struct buf *ob,
135
- struct buf *text,
136
- unsigned int flags,
137
- const char *link_attr,
138
- void (*link_text_cb)(struct buf *ob, const struct buf *link, void *payload),
139
- void *payload)
140
- {
141
- size_t i, end;
142
- struct buf *link = bufnew(16);
143
- char active_chars[256];
144
- void (*link_url_cb)(struct buf *, const struct buf *, void *);
145
-
146
- if (!text || text->size == 0)
147
- return;
148
-
149
- memset(active_chars, 0x0, sizeof(active_chars));
150
-
151
- active_chars['<'] = AUTOLINK_ACTION_SKIP_TAG;
152
-
153
- if (flags & AUTOLINK_EMAILS)
154
- active_chars['@'] = AUTOLINK_ACTION_EMAIL;
155
-
156
- if (flags & AUTOLINK_URLS) {
157
- active_chars['w'] = AUTOLINK_ACTION_WWW;
158
- active_chars['W'] = AUTOLINK_ACTION_WWW;
159
- active_chars[':'] = AUTOLINK_ACTION_URL;
160
- }
161
-
162
- if (link_text_cb == NULL)
163
- link_text_cb = &autolink_escape_cb;
164
-
165
- if (link_attr != NULL) {
166
- while (isspace(*link_attr))
167
- link_attr++;
168
- }
169
-
170
- bufgrow(ob, text->size);
171
-
172
- i = end = 0;
173
-
174
- while (i < text->size) {
175
- size_t rewind;
176
- char action;
177
-
178
- while (end < text->size && (action = active_chars[(int)text->data[end]]) == 0)
179
- end++;
180
-
181
- bufput(ob, text->data + i, end - i);
182
-
183
- if (end >= text->size)
184
- break;
185
-
186
- i = end;
187
- end = 0;
188
- link->size = 0;
189
-
190
- if (action == AUTOLINK_ACTION_SKIP_TAG) {
191
- end = autolink__skip_tag(ob, text->data + i, text->size - i);
192
- } else {
193
- end = g_callbacks[(int)action](&rewind, link, text->data + i, i, text->size - i);
194
-
195
- /* print the link */
196
- if (end > 0) {
197
- ob->size -= rewind;
198
-
199
- bufputs(ob, g_hrefs[(int)action]);
200
- autolink_escape_cb(ob, link, NULL);
201
-
202
- if (link_attr) {
203
- BUFPUTSL(ob, "\" ");
204
- bufputs(ob, link_attr);
205
- bufputc(ob, '>');
206
- } else {
207
- BUFPUTSL(ob, "\">");
208
- }
209
-
210
- link_text_cb(ob, link, payload);
211
- BUFPUTSL(ob, "</a>");
212
- }
213
- }
214
-
215
- if (!end)
216
- end = i + 1;
217
- else {
218
- i += end;
219
- end = i;
220
- }
221
- }
222
-
223
- bufrelease(link);
224
- }
225
-
226
-