/* * redcloth_inline.c.rl * * Copyright (C) 2008 Jason Garber */ #include #include "redcloth.h" %%{ machine redcloth_inline; include redcloth_common "redcloth_common.c.rl"; include redcloth_inline "redcloth_inline.rl"; }%% %% write data nofinal; VALUE red_pass(VALUE self, VALUE regs, VALUE ref, ID meth, VALUE refs) { VALUE txt = rb_hash_aref(regs, ref); if (!NIL_P(txt)) { //printf("red_pass() '%s'\n", RSTRING(txt)->ptr); if (rb_funcall(self, rb_intern("bbcode_only"), 0) == Qtrue){ //rb_hash_aset(regs, ref, redcloth_bbcode_inline2(self, txt, refs)); rb_hash_aset(regs, ref, redcloth_bbcode_inline2(self, txt, refs)); } else { //printf("red_pass() '%s'\n", RSTRING(txt)->ptr); rb_hash_aset(regs, ref, redcloth_inline2(self, txt, refs)); } } VALUE test = rb_funcall(regs,rb_intern("inspect"),0); //printf("red_pass() '%s'\n", RSTRING(test)->ptr); //printf("red_pass()2 '%s'\n", RSTRING(rb_funcall(self, meth, 1, regs))->ptr); return rb_funcall(self, meth, 1, regs); } VALUE red_passthrough(VALUE self, char *ts, char *te, VALUE refs) { VALUE ret = rb_str_new(ts,1); VALUE txt = rb_str_new(ts+1,te-ts-2); if (!NIL_P(txt)) { //printf("red_passthrough() '%s'\n", RSTRING(txt)->ptr); if (rb_funcall(self, rb_intern("bbcode_only"), 0) == Qtrue){ rb_str_append(ret,redcloth_bbcode_inline2(self, txt, refs)); } else { rb_str_append(ret,redcloth_inline2(self, txt, refs)); } } rb_str_cat(ret,te-1,1); return ret; } VALUE red_parse_attr(VALUE self, VALUE regs, VALUE ref) { VALUE txt = rb_hash_aref(regs, ref); VALUE new_regs = redcloth_attributes(self, txt); return rb_funcall(regs, rb_intern("update"), 1, new_regs); } VALUE red_parse_link_attr(VALUE self, VALUE regs, VALUE ref) { VALUE txt = rb_hash_aref(regs, ref); VALUE new_regs = redcloth_link_attributes(self, txt); return rb_funcall(regs, rb_intern("update"), 1, new_regs); } VALUE red_pass_code(VALUE self, VALUE regs, VALUE ref, ID meth) { VALUE txt = rb_hash_aref(regs, ref); if (!NIL_P(txt)) { VALUE txt2 = rb_str_new2(""); rb_str_cat_escaped_for_preformatted(self, txt2, RSTRING_PTR(txt), RSTRING_PTR(txt) + RSTRING_LEN(txt)); rb_hash_aset(regs, ref, txt2); } return rb_funcall(self, meth, 1, regs); } VALUE red_block(VALUE self, VALUE regs, VALUE block, VALUE refs) { ID method; VALUE fallback; VALUE sym_text = ID2SYM(rb_intern("text")); VALUE btype = rb_hash_aref(regs, ID2SYM(rb_intern("type"))); block = rb_funcall(block, rb_intern("strip"), 0); if ((!NIL_P(block)) && !NIL_P(btype)) { method = rb_intern(RSTRING_PTR(btype)); if (method == rb_intern("notextile")) { rb_hash_aset(regs, sym_text, block); } else { rb_hash_aset(regs, sym_text, redcloth_inline2(self, block, refs)); } if (rb_respond_to(self, method)) { block = rb_funcall(self, method, 1, regs); } else { fallback = rb_hash_aref(regs, ID2SYM(rb_intern("fallback"))); if (!NIL_P(fallback)) { rb_str_append(fallback, rb_hash_aref(regs, sym_text)); CLEAR_REGS(); rb_hash_aset(regs, sym_text, fallback); } block = rb_funcall(self, rb_intern("p"), 1, regs); } } return block; } VALUE red_blockcode(VALUE self, VALUE regs, VALUE block) { VALUE btype = rb_hash_aref(regs, ID2SYM(rb_intern("type"))); if (RSTRING_LEN(block) > 0) { rb_hash_aset(regs, ID2SYM(rb_intern("text")), block); block = rb_funcall(self, rb_intern(RSTRING_PTR(btype)), 1, regs); } return block; } void red_inc(VALUE regs, VALUE ref) { int aint = 0; VALUE aval = rb_hash_aref(regs, ref); if (aval != Qnil) aint = NUM2INT(aval); rb_hash_aset(regs, ref, INT2NUM(aint + 1)); } VALUE redcloth_inline(self, p, pe, refs) VALUE self; char *p, *pe; VALUE refs; { int cs, act; char *ts, *te, *reg, *eof; char *orig_p = p, *orig_pe = pe; VALUE block = rb_str_new2(""); VALUE regs = Qnil; unsigned int opts = 0; VALUE buf = Qnil; VALUE hash = Qnil; VALUE html = rb_str_new2(""); VALUE failed_start = rb_str_new2(""); int stack[CALL_STACK_SIZE],top; %% write init; %% write exec; return block; } /** Append characters to a string, escaping (&, <, >, ", ') using the formatter's escape method. * @param str ruby string * @param ts start of character buffer to append * @param te end of character buffer */ void rb_str_cat_escaped(self, str, ts, te) VALUE self, str; char *ts, *te; { VALUE source_str = rb_str_new(ts, te-ts); VALUE escaped_str = rb_funcall(self, rb_intern("escape"), 1, source_str); rb_str_concat(str, escaped_str); } void rb_str_cat_escaped_for_preformatted(self, str, ts, te) VALUE self, str; char *ts, *te; { VALUE source_str = rb_str_new(ts, te-ts); VALUE escaped_str = rb_funcall(self, rb_intern("escape_pre"), 1, source_str); rb_str_concat(str, escaped_str); } void rb_str_cat_escaped_test(self, str, ts, te) VALUE self, str; char *ts, *te; { VALUE source_str = rb_str_new(ts, te-ts); rb_str_concat(str, source_str); } VALUE redcloth_inline2(self, str, refs) VALUE self, str, refs; { StringValue(str); return redcloth_inline(self, RSTRING_PTR(str), RSTRING_PTR(str) + RSTRING_LEN(str) + 1, refs); }