ary_t *line; // stack for tracking scope as implied by current line
ary_t *line_buffer; // stack for tracking raw tokens (not scope) on current line
VALUE external_link_class; // CSS class applied to external links
+ VALUE external_link_rel; // rel attribute applied to external links
VALUE mailto_class; // CSS class applied to email (mailto) links
VALUE img_prefix; // path prepended when emitting img tags
int output_style; // HTML_OUTPUT (default) or XML_OUTPUT
const char space[] = " ";
const char a_start[] = "<a href=\"";
const char a_class[] = "\" class=\"";
+const char a_rel[] = "\" rel=\"";
const char a_start_close[] = "\">";
const char a_end[] = "</a>";
const char link_start[] = "[[";
parser->line = ary_new();
parser->line_buffer = ary_new();
parser->external_link_class = Qnil; // caller should set up
+ parser->external_link_rel = Qnil; // caller should set up
parser->mailto_class = Qnil; // caller should set up
parser->img_prefix = Qnil; // caller should set up
parser->output_style = HTML_OUTPUT;
// if check_autolink is true, checks parser->autolink to decide whether to emit a real hyperlink
// or merely the literal link target
// if link_text is Qnil, the link_target is re-used for the link text
-void wiki_append_hyperlink(parser_t *parser, VALUE link_prefix, str_t *link_target, str_t *link_text, VALUE link_class, bool check_autolink)
+void wiki_append_hyperlink(parser_t *parser, VALUE link_prefix, str_t *link_target, str_t *link_text, VALUE link_class, VALUE link_rel, bool check_autolink)
{
if (check_autolink && !parser->autolink)
str_append_str(parser->output, link_target);
str_append(parser->output, a_class, sizeof(a_class) - 1); // " class="
str_append_string(parser->output, link_class);
}
+ if (link_rel != Qnil)
+ {
+ str_append(parser->output, a_rel, sizeof(a_rel) - 1); // " rel="
+ str_append_string(parser->output, link_rel);
+ }
str_append(parser->output, a_start_close, sizeof(a_start_close) - 1); // ">
if (!link_text || link_text->len == 0) // re-use link_target
str_append_str(parser->output, link_target);
// store a couple of values before popping
int scope_includes_space = IN(SPACE);
VALUE link_class = IN(PATH) ? Qnil : parser->external_link_class;
+ VALUE link_rel = IN(PATH) ? Qnil : parser->external_link_rel;
wiki_pop_from_stack_up_to(parser, NULL, EXT_LINK_START, true);
str_append(parser->output, ext_link_start, sizeof(ext_link_start) - 1);
if (parser->link_target->len > 0)
{
- wiki_append_hyperlink(parser, Qnil, parser->link_target, NULL, link_class, true);
+ wiki_append_hyperlink(parser, Qnil, parser->link_target, NULL, link_class, link_rel, true);
if (scope_includes_space)
{
str_append(parser->output, space, sizeof(space) - 1);
VALUE autolink = Qtrue;
VALUE line_ending = rb_str_new2("\n");
VALUE external_link_class = rb_str_new2("external");
+ VALUE external_link_rel = Qnil;
VALUE mailto_class = rb_str_new2("mailto");
VALUE internal_link_prefix = rb_str_new2("/wiki/");
VALUE img_prefix = rb_str_new2("/images/");
autolink = OVERRIDE_IF_SET(autolink);
line_ending = OVERRIDE_IF_SET(line_ending);
external_link_class = OVERRIDE_IF_SET(external_link_class);
+ external_link_rel = OVERRIDE_IF_SET(external_link_rel);
mailto_class = OVERRIDE_IF_SET(mailto_class);
internal_link_prefix = OVERRIDE_IF_SET(internal_link_prefix);
img_prefix = OVERRIDE_IF_SET(img_prefix);
rb_iv_set(self, "@autolink", autolink);
rb_iv_set(self, "@line_ending", line_ending);
rb_iv_set(self, "@external_link_class", external_link_class);
+ rb_iv_set(self, "@external_link_rel", external_link_rel);
rb_iv_set(self, "@mailto_class", mailto_class);
rb_iv_set(self, "@internal_link_prefix", internal_link_prefix);
rb_iv_set(self, "@img_prefix", img_prefix);
line_ending = StringValue(line_ending);
VALUE link_class = rb_iv_get(self, "@external_link_class");
link_class = NIL_P(link_class) ? Qnil : StringValue(link_class);
+ VALUE link_rel = rb_iv_get(self, "@external_link_rel");
+ link_rel = NIL_P(link_rel) ? Qnil : StringValue(link_rel);
VALUE mailto_class = rb_iv_get(self, "@mailto_class");
mailto_class = NIL_P(mailto_class) ? Qnil : StringValue(mailto_class);
VALUE prefix = rb_iv_get(self, "@internal_link_prefix");
parser_t *parser = parser_new();
GC_WRAP_PARSER(parser, parser_gc);
parser->external_link_class = link_class;
+ parser->external_link_rel = link_rel;
parser->mailto_class = mailto_class;
parser->img_prefix = rb_iv_get(self, "@img_prefix");
parser->autolink = rb_iv_get(self, "@autolink") == Qtrue ? true : false;
wiki_start_para_if_necessary(parser);
token_str->ptr = token->start;
token_str->len = TOKEN_LEN(token);
- wiki_append_hyperlink(parser, rb_str_new2("mailto:"), token_str, NULL, mailto_class, true);
+ wiki_append_hyperlink(parser, rb_str_new2("mailto:"), token_str, NULL, mailto_class, Qnil, true);
}
break;
wiki_rollback_failed_internal_link(parser);
token_str->ptr = token->start;
token_str->len = TOKEN_LEN(token);
- wiki_append_hyperlink(parser, Qnil, token_str, NULL, parser->external_link_class, true);
+ wiki_append_hyperlink(parser, Qnil, token_str, NULL, parser->external_link_class, parser->external_link_rel, true);
}
else if (IN(EXT_LINK_START))
{
wiki_pop_excess_elements(parser);
wiki_start_para_if_necessary(parser);
str_append(parser->output, ext_link_start, sizeof(ext_link_start) - 1);
- wiki_append_hyperlink(parser, Qnil, token_str, NULL, parser->external_link_class, true);
+ wiki_append_hyperlink(parser, Qnil, token_str, NULL, parser->external_link_class, parser->external_link_rel, true);
}
}
else
wiki_start_para_if_necessary(parser);
token_str->ptr = token->start;
token_str->len = TOKEN_LEN(token);
- wiki_append_hyperlink(parser, Qnil, token_str, NULL, parser->external_link_class, true);
+ wiki_append_hyperlink(parser, Qnil, token_str, NULL, parser->external_link_class, parser->external_link_rel, true);
}
break;
wiki_encode_link_target(parser);
wiki_pop_from_stack_up_to(parser, output, LINK_START, true);
parser->capture = NULL;
- wiki_append_hyperlink(parser, prefix, parser->link_target, parser->link_text, j, false);
+ wiki_append_hyperlink(parser, prefix, parser->link_target, parser->link_text, j, Qnil, false);
str_clear(parser->link_target);
str_clear(parser->link_text);
}
{
// success!
j = IN(PATH) ? Qnil : parser->external_link_class;
+ k = IN(PATH) ? Qnil : parser->external_link_rel;
wiki_pop_from_stack_up_to(parser, output, EXT_LINK_START, true);
parser->capture = NULL;
- wiki_append_hyperlink(parser, Qnil, parser->link_target, parser->link_text, j, false);
+ wiki_append_hyperlink(parser, Qnil, parser->link_target, parser->link_text, j, k, false);
}
str_clear(parser->link_target);
str_clear(parser->link_text);