ext/greenmat/gm_render.c in greenmat-3.2.2.4 vs ext/greenmat/gm_render.c in greenmat-3.5.1.0
- old
+ new
@@ -1,19 +1,25 @@
/*
- * Copyright (c) 2011, Vicent Marti
+ * Copyright (c) 2015, Vicent Marti
*
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
*
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
*/
#include "greenmat.h"
#define SPAN_CALLBACK(method_name, ...) {\
@@ -32,14 +38,14 @@
Check_Type(ret, T_STRING);\
bufput(ob, RSTRING_PTR(ret), RSTRING_LEN(ret));\
}
extern VALUE rb_mGreenmat;
+extern VALUE rb_cRenderHTML_TOC;
VALUE rb_mRender;
VALUE rb_cRenderBase;
VALUE rb_cRenderHTML;
-VALUE rb_cRenderHTML_TOC;
VALUE rb_mSmartyPants;
#define buf2str(t) ((t) ? rb_enc_str_new((const char*)(t)->data, (t)->size, opt->active_enc) : Qnil)
static void
@@ -367,20 +373,26 @@
{
if (rndr->options.link_attributes)
rb_gc_mark(rndr->options.link_attributes);
}
+static void rndr_deallocate(void *rndr)
+{
+ xfree(rndr);
+}
+
static VALUE rb_greenmat_rbase_alloc(VALUE klass)
{
struct rb_greenmat_rndr *rndr = ALLOC(struct rb_greenmat_rndr);
memset(rndr, 0x0, sizeof(struct rb_greenmat_rndr));
- return Data_Wrap_Struct(klass, rb_greenmat_rbase_mark, NULL, rndr);
+ return Data_Wrap_Struct(klass, rb_greenmat_rbase_mark, rndr_deallocate, rndr);
}
static void rb_greenmat__overload(VALUE self, VALUE base_class)
{
struct rb_greenmat_rndr *rndr;
+ VALUE options_ivar;
Data_Get_Struct(self, struct rb_greenmat_rndr, rndr);
rndr->options.self = self;
rndr->options.base_class = base_class;
@@ -397,10 +409,14 @@
for (i = 0; i < rb_greenmat_method_count; ++i) {
if (rb_respond_to(self, rb_intern(rb_greenmat_method_names[i])))
dest[i] = source[i];
}
}
+
+ options_ivar = rb_attr_get(self, rb_intern("@options"));
+ if (options_ivar == Qundef || options_ivar == Qnil)
+ rb_iv_set(self, "@options", rb_hash_new());
}
static VALUE rb_greenmat_rbase_init(VALUE self)
{
rb_greenmat__overload(self, rb_cRenderBase);
@@ -416,10 +432,13 @@
Data_Get_Struct(self, struct rb_greenmat_rndr, rndr);
if (rb_scan_args(argc, argv, "01", &hash) == 1) {
Check_Type(hash, T_HASH);
+ /* Give access to the passed options through `@options` */
+ rb_iv_set(self, "@options", hash);
+
/* escape_html */
if (rb_hash_aref(hash, CSTR2SYM("escape_html")) == Qtrue)
render_flags |= HTML_ESCAPE;
/* filter_html */
@@ -470,27 +489,47 @@
}
static VALUE rb_greenmat_htmltoc_init(int argc, VALUE *argv, VALUE self)
{
struct rb_greenmat_rndr *rndr;
- int nesting_level = 6;
- VALUE hash, key = Qnil;
+ unsigned int render_flags = HTML_TOC;
+ VALUE hash, nesting_level = Qnil;
Data_Get_Struct(self, struct rb_greenmat_rndr, rndr);
if (rb_scan_args(argc, argv, "01", &hash) == 1) {
Check_Type(hash, T_HASH);
- key = CSTR2SYM("nesting_level");
+ /* Give access to the passed options through `@options` */
+ rb_iv_set(self, "@options", hash);
- if (RTEST(rb_hash_aref(hash, key))) {
- Check_Type(rb_hash_aref(hash, key), T_FIXNUM);
- nesting_level = NUM2INT(rb_hash_aref(hash, key));
- }
+ /* escape_html */
+ if (rb_hash_aref(hash, CSTR2SYM("escape_html")) == Qtrue)
+ render_flags |= HTML_ESCAPE;
+
+ /* Nesting level */
+ nesting_level = rb_hash_aref(hash, CSTR2SYM("nesting_level"));
}
- sdhtml_toc_renderer(&rndr->callbacks, (struct html_renderopt *)&rndr->options.html, nesting_level);
+ sdhtml_toc_renderer(&rndr->callbacks, (struct html_renderopt *)&rndr->options.html, render_flags);
rb_greenmat__overload(self, rb_cRenderHTML_TOC);
+
+ /* Check whether we are dealing with a Range object by
+ checking whether the object responds to min and max */
+ if (rb_respond_to(nesting_level, rb_intern("min")) &&
+ rb_respond_to(nesting_level, rb_intern("max"))) {
+ int min = NUM2INT(rb_funcall(nesting_level, rb_intern("min"), 0));
+ int max = NUM2INT(rb_funcall(nesting_level, rb_intern("max"), 0));
+
+ rndr->options.html.toc_data.nesting_bounds[0] = min;
+ rndr->options.html.toc_data.nesting_bounds[1] = max;
+ } else if (FIXNUM_P(nesting_level)) {
+ rndr->options.html.toc_data.nesting_bounds[0] = 1;
+ rndr->options.html.toc_data.nesting_bounds[1] = NUM2INT(nesting_level);
+ } else {
+ rndr->options.html.toc_data.nesting_bounds[0] = 1;
+ rndr->options.html.toc_data.nesting_bounds[1] = 6;
+ }
return Qnil;
}
static VALUE rb_greenmat_smartypants_render(VALUE self, VALUE text)