Module: Rinku

Defined in:
lib/rinku.rb,
ext/rinku/rinku_rb.c

Constant Summary collapse

VERSION =
"2.0.6"
INT2FIX(AUTOLINK_SHORT_DOMAINS)

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.skip_tagsObject

Returns the value of attribute skip_tags.



5
6
7
# File 'lib/rinku.rb', line 5

def skip_tags
  @skip_tags
end

Class Method Details

call-seq:

auto_link(text, mode=:all, link_attr=nil, skip_tags=nil, flags=0)
auto_link(text, mode=:all, link_attr=nil, skip_tags=nil, flags=0) { |link_text| ... }

Parses a block of text looking for “safe” urls or email addresses, and turns them into HTML links with the given attributes.

NOTE: The block of text may or may not be HTML; if the text is HTML, Rinku will skip the relevant tags to prevent double-linking and linking inside ‘pre` blocks by default.

NOTE: If the input text is HTML, it’s expected to be already escaped. Rinku will perform no escaping.

NOTE: Currently the follow protocols are considered safe and are the only ones that will be autolinked.

http:// https:// ftp:// mailto://

Email addresses are also autolinked by default. URLs without a protocol specifier but starting with ‘www.’ will also be autolinked, defaulting to the ‘http://’ protocol.

  • ‘text` is a string in plain text or HTML markup. If the string is formatted in

HTML, Rinku is smart enough to skip the links that are already enclosed in ‘<a>` tags.`

  • ‘mode` is a symbol, either `:all`, `:urls` or `:email_addresses`,

which specifies which kind of links will be auto-linked.

  • ‘link_attr` is a string containing the link attributes for each link that

will be generated. These attributes are not sanitized and will be include as-is in each generated link, e.g.

 ~~~~~ruby
 auto_link('http://www.pokemon.com', :all, 'target="_blank"')
 # => '<a href="http://www.pokemon.com" target="_blank">http://www.pokemon.com</a>'
 ~~~~~

This string can be autogenerated from a hash using the Rails `tag_options` helper.
  • ‘skip_tags` is a list of strings with the names of HTML tags that will be skipped

when autolinking. If ‘nil`, this defaults to the value of the global `Rinku.skip_tags`, which is initially `[“a”, “pre”, “code”, “kbd”, “script”]`.

  • ‘flag` is an optional boolean value specifying whether to recognize

foo’ as a valid domain, or require at least one ‘.’. It defaults to false.

  • ‘&block` is an optional block argument. If a block is passed, it will

be yielded for each found link in the text, and its return value will be used instead of the name of the link. E.g.

~~~~~ruby
auto_link('Check it out at http://www.pokemon.com') do |url|
  "THE POKEMAN WEBSITEZ"
end
# => 'Check it out at <a href="http://www.pokemon.com">THE POKEMAN WEBSITEZ</a>'
~~~~~~


150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'ext/rinku/rinku_rb.c', line 150

static VALUE
rb_rinku_autolink(int argc, VALUE *argv, VALUE self)
{
	static const char *SKIP_TAGS[] = {"a", "pre", "code", "kbd", "script", NULL};

	VALUE result, rb_text, rb_mode, rb_html, rb_skip, rb_flags, rb_block;
	rb_encoding *text_encoding;
	struct buf *output_buf;
	int link_mode = AUTOLINK_ALL, count;
	unsigned int link_flags = 0;
	const char *link_attr = NULL;
	const char **skip_tags = NULL;
	struct callback_data cbdata;

	rb_scan_args(argc, argv, "14&", &rb_text, &rb_mode,
		&rb_html, &rb_skip, &rb_flags, &rb_block); 

	text_encoding = validate_encoding(rb_text);

	if (!NIL_P(rb_mode)) {
		ID mode_sym;
		Check_Type(rb_mode, T_SYMBOL);

		mode_sym = SYM2ID(rb_mode);
		if (mode_sym == rb_intern("all"))
			link_mode = AUTOLINK_ALL;
		else if (mode_sym == rb_intern("email_addresses"))
			link_mode = AUTOLINK_EMAILS;
		else if (mode_sym == rb_intern("urls"))
			link_mode = AUTOLINK_URLS;
		else
			rb_raise(rb_eTypeError,
				"Invalid linking mode "
				"(possible values are :all, :urls, :email_addresses)");
	}

	if (!NIL_P(rb_html)) {
		Check_Type(rb_html, T_STRING);
		link_attr = RSTRING_PTR(rb_html);
	}

	if (!NIL_P(rb_flags)) {
		Check_Type(rb_flags, T_FIXNUM);
		link_flags = FIX2INT(rb_flags);
	}

	if (NIL_P(rb_skip))
		rb_skip = rb_iv_get(self, "@skip_tags");

	if (NIL_P(rb_skip)) {
		skip_tags = SKIP_TAGS;
	} else {
		skip_tags = rinku_load_tags(rb_skip);
	}

	output_buf = bufnew(32);
	cbdata.rb_block = rb_block;
	cbdata.encoding = text_encoding;
	count = rinku_autolink(
		output_buf,
		(const uint8_t *)RSTRING_PTR(rb_text),
		(size_t)RSTRING_LEN(rb_text),
		link_mode,
		link_flags,
		link_attr,
		skip_tags,
		RTEST(rb_block) ? &autolink_callback : NULL,
		(void*)&cbdata);

	if (count == 0)
		result = rb_text;
	else {
		result = rb_enc_str_new((char *)output_buf->data, output_buf->size,
			text_encoding);
	}

	if (skip_tags != SKIP_TAGS)
		xfree(skip_tags);

	bufrelease(output_buf);
	return result;
}