ldown 0.0.1
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.
- checksums.yaml +7 -0
- data/.clang-format +1 -0
- data/.dir-locals.el +8 -0
- data/.document +6 -0
- data/.envrc +9 -0
- data/.rdoc_options +29 -0
- data/CHANGELOG.md +7 -0
- data/COPYING +674 -0
- data/README.md +78 -0
- data/Rakefile +22 -0
- data/ext/ldown/extconf.rb +32 -0
- data/ext/ldown/ldown.c +820 -0
- data/ext/ldown/ldown.h +6 -0
- data/lib/ldown/version.rb +5 -0
- data/lib/ldown.rb +139 -0
- data/sig/ldown.rbs +128 -0
- metadata +63 -0
data/ext/ldown/ldown.c
ADDED
|
@@ -0,0 +1,820 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2026 gemmaro
|
|
3
|
+
*
|
|
4
|
+
* This program is free software: you can redistribute it and/or modify
|
|
5
|
+
* it under the terms of the GNU General Public License as published by
|
|
6
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
* (at your option) any later version.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU General Public License
|
|
15
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/* Admonitions: TODO, Question */
|
|
19
|
+
|
|
20
|
+
/* TODO: Support abstract syntax tree manipulation. */
|
|
21
|
+
|
|
22
|
+
/* Question: lowdown_file(3) and lowdown_file_diff(3); are they any
|
|
23
|
+
safe ways to do these with Ruby's C API? */
|
|
24
|
+
|
|
25
|
+
/* Question: Should we provide buffer class? I don't think so, since
|
|
26
|
+
the only its parameter is a grow (increment) size, which is
|
|
27
|
+
typically 256 or something, greater than zero at least. */
|
|
28
|
+
|
|
29
|
+
#include "ldown.h"
|
|
30
|
+
|
|
31
|
+
#include <stdlib.h>
|
|
32
|
+
#include <sys/queue.h> /* required by lowdown */
|
|
33
|
+
|
|
34
|
+
#include <lowdown.h>
|
|
35
|
+
|
|
36
|
+
#include <ruby.h>
|
|
37
|
+
#include <ruby/encoding.h>
|
|
38
|
+
|
|
39
|
+
#include <stddef.h>
|
|
40
|
+
|
|
41
|
+
/* rbl_ prefix means RuBy Lowdown. */
|
|
42
|
+
|
|
43
|
+
#define RBL_BUF_GROW 256
|
|
44
|
+
|
|
45
|
+
VALUE rb_mLdown, rbl_cDocument, rbl_cNode,
|
|
46
|
+
/* per format: */
|
|
47
|
+
rbl_cHTML, rbl_cGemini, rbl_cLaTeX, rbl_cOpenDocument, rbl_cRoff,
|
|
48
|
+
rbl_cTerm,
|
|
49
|
+
/* misc --> */ rbl_eError;
|
|
50
|
+
|
|
51
|
+
static inline void
|
|
52
|
+
set_feat (unsigned int *feat, unsigned int fval, size_t index,
|
|
53
|
+
const VALUE *kwargs_vals)
|
|
54
|
+
{
|
|
55
|
+
if (!RB_UNDEF_P (kwargs_vals[index]) && RB_TEST (kwargs_vals[index]))
|
|
56
|
+
*feat |= fval;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static inline struct lowdown_opts
|
|
60
|
+
get_opts (VALUE kwargs)
|
|
61
|
+
{
|
|
62
|
+
/* Naming: Separate "no-". If it's hard to read, dissect.
|
|
63
|
+
Basically respect originals. */
|
|
64
|
+
const ID kwargs_ids[] = {
|
|
65
|
+
/* feat: */
|
|
66
|
+
rb_intern ("attrs"),
|
|
67
|
+
rb_intern ("autolink"),
|
|
68
|
+
rb_intern ("callouts"),
|
|
69
|
+
rb_intern ("commonmark"),
|
|
70
|
+
rb_intern ("deflist"),
|
|
71
|
+
rb_intern ("fenced"),
|
|
72
|
+
rb_intern ("footnotes"),
|
|
73
|
+
rb_intern ("hilite"),
|
|
74
|
+
rb_intern ("mantitle"),
|
|
75
|
+
rb_intern ("math"),
|
|
76
|
+
rb_intern ("metadata"),
|
|
77
|
+
rb_intern ("no_code_indented" /* nocodeind */),
|
|
78
|
+
rb_intern ("no_intra_emph" /* nointem */),
|
|
79
|
+
rb_intern ("strike"),
|
|
80
|
+
rb_intern ("super"),
|
|
81
|
+
rb_intern ("super_short"),
|
|
82
|
+
rb_intern ("tables"),
|
|
83
|
+
rb_intern ("tasklist"),
|
|
84
|
+
/* oflags/general: */
|
|
85
|
+
rb_intern ("no_link"),
|
|
86
|
+
rb_intern ("no_rellink"),
|
|
87
|
+
rb_intern ("shortlink"),
|
|
88
|
+
rb_intern ("skip_html"),
|
|
89
|
+
rb_intern ("smarty"),
|
|
90
|
+
rb_intern ("standalone"),
|
|
91
|
+
/* oflags/HTML: */
|
|
92
|
+
rb_intern ("html_callout_mdn"),
|
|
93
|
+
rb_intern ("html_callout_gfm"),
|
|
94
|
+
rb_intern ("html_custom_attrs"),
|
|
95
|
+
rb_intern ("html_escape"),
|
|
96
|
+
rb_intern ("html_hard_wrap"),
|
|
97
|
+
rb_intern ("html_head_ids"),
|
|
98
|
+
rb_intern ("html_num_entity" /* ent */),
|
|
99
|
+
rb_intern ("html_owasp"),
|
|
100
|
+
rb_intern ("html_titleblock"),
|
|
101
|
+
/* oflags/gemini: */
|
|
102
|
+
rb_intern ("gemini_link_end"),
|
|
103
|
+
rb_intern ("gemini_link_in"),
|
|
104
|
+
rb_intern ("gemini_link_no_ref"),
|
|
105
|
+
rb_intern ("gemini_link_roman"),
|
|
106
|
+
rb_intern ("gemini_metadata"),
|
|
107
|
+
/* oflags/latex: */
|
|
108
|
+
rb_intern ("latex_numbered"),
|
|
109
|
+
/* oflags/roff: */
|
|
110
|
+
rb_intern ("roff_groff"),
|
|
111
|
+
rb_intern ("roff_numbered"),
|
|
112
|
+
rb_intern ("roff_manpage"),
|
|
113
|
+
rb_intern ("roff_endnotes"),
|
|
114
|
+
/* oflags/term: */
|
|
115
|
+
rb_intern ("term_all_meta"),
|
|
116
|
+
rb_intern ("term_no_ansi"),
|
|
117
|
+
rb_intern ("term_no_colour"),
|
|
118
|
+
|
|
119
|
+
rb_intern ("maxdepth"),
|
|
120
|
+
};
|
|
121
|
+
VALUE kwargs_vals[sizeof (kwargs_ids) / sizeof (kwargs_ids[0])] = { 0 };
|
|
122
|
+
rb_get_kwargs (kwargs, kwargs_ids, 0,
|
|
123
|
+
sizeof (kwargs_ids) / sizeof (kwargs_ids[0]), kwargs_vals);
|
|
124
|
+
|
|
125
|
+
unsigned int feat = 0;
|
|
126
|
+
set_feat (&feat, LOWDOWN_ATTRS, 0, kwargs_vals);
|
|
127
|
+
set_feat (&feat, LOWDOWN_AUTOLINK, 1, kwargs_vals);
|
|
128
|
+
set_feat (&feat, LOWDOWN_CALLOUTS, 2, kwargs_vals);
|
|
129
|
+
set_feat (&feat, LOWDOWN_COMMONMARK, 3, kwargs_vals);
|
|
130
|
+
set_feat (&feat, LOWDOWN_DEFLIST, 4, kwargs_vals);
|
|
131
|
+
set_feat (&feat, LOWDOWN_FENCED, 5, kwargs_vals);
|
|
132
|
+
set_feat (&feat, LOWDOWN_FOOTNOTES, 6, kwargs_vals);
|
|
133
|
+
set_feat (&feat, LOWDOWN_HILITE /* or highlit; what is this? */, 7,
|
|
134
|
+
kwargs_vals);
|
|
135
|
+
set_feat (&feat, LOWDOWN_MANTITLE, 8, kwargs_vals);
|
|
136
|
+
set_feat (&feat, LOWDOWN_MATH, 9, kwargs_vals);
|
|
137
|
+
set_feat (&feat, LOWDOWN_METADATA, 10, kwargs_vals);
|
|
138
|
+
set_feat (&feat, LOWDOWN_NOCODEIND, 11, kwargs_vals);
|
|
139
|
+
set_feat (&feat, LOWDOWN_NOINTEM, 12, kwargs_vals);
|
|
140
|
+
set_feat (&feat, LOWDOWN_STRIKE, 13, kwargs_vals);
|
|
141
|
+
set_feat (&feat, LOWDOWN_SUPER, 14, kwargs_vals);
|
|
142
|
+
set_feat (&feat, LOWDOWN_SUPER_SHORT, 15, kwargs_vals);
|
|
143
|
+
set_feat (&feat, LOWDOWN_TABLES, 16, kwargs_vals);
|
|
144
|
+
set_feat (&feat, LOWDOWN_TASKLIST, 17, kwargs_vals);
|
|
145
|
+
|
|
146
|
+
unsigned int oflags = 0;
|
|
147
|
+
if (!RB_UNDEF_P (kwargs_vals[18]) && RB_TEST (kwargs_vals[18]))
|
|
148
|
+
oflags |= LOWDOWN_NOLINK;
|
|
149
|
+
if (!RB_UNDEF_P (kwargs_vals[19]) && RB_TEST (kwargs_vals[19]))
|
|
150
|
+
oflags |= LOWDOWN_NORELLINK;
|
|
151
|
+
if (!RB_UNDEF_P (kwargs_vals[20]) && RB_TEST (kwargs_vals[20]))
|
|
152
|
+
oflags |= LOWDOWN_SHORTLINK;
|
|
153
|
+
if (!RB_UNDEF_P (kwargs_vals[21]) && RB_TEST (kwargs_vals[21]))
|
|
154
|
+
oflags |= LOWDOWN_SKIP_HTML;
|
|
155
|
+
if (!RB_UNDEF_P (kwargs_vals[22]) && RB_TEST (kwargs_vals[22]))
|
|
156
|
+
oflags |= LOWDOWN_SMARTY;
|
|
157
|
+
if (!RB_UNDEF_P (kwargs_vals[23]) && RB_TEST (kwargs_vals[23]))
|
|
158
|
+
oflags |= LOWDOWN_STANDALONE;
|
|
159
|
+
/* oflags/HTML: */
|
|
160
|
+
if (!RB_UNDEF_P (kwargs_vals[24]) && RB_TEST (kwargs_vals[24]))
|
|
161
|
+
oflags |= LOWDOWN_HTML_CALLOUT_MDN;
|
|
162
|
+
if (!RB_UNDEF_P (kwargs_vals[25]) && RB_TEST (kwargs_vals[25]))
|
|
163
|
+
oflags |= LOWDOWN_HTML_CALLOUT_GFM;
|
|
164
|
+
if (!RB_UNDEF_P (kwargs_vals[26]) && RB_TEST (kwargs_vals[26]))
|
|
165
|
+
oflags |= LOWDOWN_HTML_CUSTOM_ATTRS;
|
|
166
|
+
if (!RB_UNDEF_P (kwargs_vals[27]) && RB_TEST (kwargs_vals[27]))
|
|
167
|
+
oflags |= LOWDOWN_HTML_ESCAPE;
|
|
168
|
+
if (!RB_UNDEF_P (kwargs_vals[28]) && RB_TEST (kwargs_vals[28]))
|
|
169
|
+
oflags |= LOWDOWN_HTML_HARD_WRAP;
|
|
170
|
+
if (!RB_UNDEF_P (kwargs_vals[29]) && RB_TEST (kwargs_vals[29]))
|
|
171
|
+
oflags |= LOWDOWN_HTML_HEAD_IDS;
|
|
172
|
+
if (!RB_UNDEF_P (kwargs_vals[30]) && RB_TEST (kwargs_vals[30]))
|
|
173
|
+
oflags |= LOWDOWN_HTML_NUM_ENT;
|
|
174
|
+
if (!RB_UNDEF_P (kwargs_vals[31]) && RB_TEST (kwargs_vals[31]))
|
|
175
|
+
oflags |= LOWDOWN_HTML_OWASP;
|
|
176
|
+
if (!RB_UNDEF_P (kwargs_vals[32]) && RB_TEST (kwargs_vals[32]))
|
|
177
|
+
oflags |= LOWDOWN_HTML_TITLEBLOCK;
|
|
178
|
+
if (!RB_UNDEF_P (kwargs_vals[33]) && RB_TEST (kwargs_vals[33]))
|
|
179
|
+
oflags |= LOWDOWN_GEMINI_LINK_END;
|
|
180
|
+
if (!RB_UNDEF_P (kwargs_vals[34]) && RB_TEST (kwargs_vals[34]))
|
|
181
|
+
oflags |= LOWDOWN_GEMINI_LINK_IN;
|
|
182
|
+
if (!RB_UNDEF_P (kwargs_vals[35]) && RB_TEST (kwargs_vals[35]))
|
|
183
|
+
oflags |= LOWDOWN_GEMINI_LINK_NOREF;
|
|
184
|
+
if (!RB_UNDEF_P (kwargs_vals[36]) && RB_TEST (kwargs_vals[36]))
|
|
185
|
+
oflags |= LOWDOWN_GEMINI_LINK_ROMAN;
|
|
186
|
+
if (!RB_UNDEF_P (kwargs_vals[37]) && RB_TEST (kwargs_vals[37]))
|
|
187
|
+
oflags |= LOWDOWN_GEMINI_METADATA;
|
|
188
|
+
|
|
189
|
+
if (!RB_UNDEF_P (kwargs_vals[38]) && RB_TEST (kwargs_vals[38]))
|
|
190
|
+
oflags |= LOWDOWN_LATEX_NUMBERED;
|
|
191
|
+
if (!RB_UNDEF_P (kwargs_vals[39]) && RB_TEST (kwargs_vals[39]))
|
|
192
|
+
oflags |= LOWDOWN_ROFF_GROFF;
|
|
193
|
+
if (!RB_UNDEF_P (kwargs_vals[40]) && RB_TEST (kwargs_vals[40]))
|
|
194
|
+
oflags |= LOWDOWN_ROFF_NUMBERED;
|
|
195
|
+
if (!RB_UNDEF_P (kwargs_vals[41]) && RB_TEST (kwargs_vals[41]))
|
|
196
|
+
oflags |= LOWDOWN_ROFF_MANPAGE;
|
|
197
|
+
if (!RB_UNDEF_P (kwargs_vals[42]) && RB_TEST (kwargs_vals[42]))
|
|
198
|
+
oflags |= LOWDOWN_ROFF_ENDNOTES;
|
|
199
|
+
if (!RB_UNDEF_P (kwargs_vals[43]) && RB_TEST (kwargs_vals[43]))
|
|
200
|
+
oflags |= LOWDOWN_TERM_ALL_META;
|
|
201
|
+
if (!RB_UNDEF_P (kwargs_vals[44]) && RB_TEST (kwargs_vals[44]))
|
|
202
|
+
oflags |= LOWDOWN_TERM_NOANSI;
|
|
203
|
+
if (!RB_UNDEF_P (kwargs_vals[45]) && RB_TEST (kwargs_vals[45]))
|
|
204
|
+
oflags |= LOWDOWN_TERM_NOCOLOUR;
|
|
205
|
+
|
|
206
|
+
size_t maxdepth = 0;
|
|
207
|
+
if (!RB_UNDEF_P (kwargs_vals[46]) && RB_TEST (kwargs_vals[46]))
|
|
208
|
+
maxdepth = RB_NUM2SIZE (kwargs_vals[46]);
|
|
209
|
+
|
|
210
|
+
/* TODO: support more options, including nroff, odt, term, etc. */
|
|
211
|
+
return (struct lowdown_opts){
|
|
212
|
+
.feat = feat,
|
|
213
|
+
.oflags = oflags,
|
|
214
|
+
.maxdepth = maxdepth,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
static inline VALUE
|
|
219
|
+
rbl_parse_into (int argc, VALUE *argv, enum lowdown_type type)
|
|
220
|
+
{
|
|
221
|
+
VALUE input, kwargs;
|
|
222
|
+
rb_scan_args (argc, argv, "1:", &input, &kwargs);
|
|
223
|
+
|
|
224
|
+
const char *buf = rb_string_value_ptr (&input);
|
|
225
|
+
size_t bufsz = RSTRING_LEN (input);
|
|
226
|
+
|
|
227
|
+
struct lowdown_opts opts = get_opts (kwargs);
|
|
228
|
+
opts.type = type;
|
|
229
|
+
|
|
230
|
+
char *ret;
|
|
231
|
+
size_t retsz;
|
|
232
|
+
struct lowdown_metaq metaq = { 0 };
|
|
233
|
+
|
|
234
|
+
int result = lowdown_buf (&opts, buf, bufsz, &ret, &retsz, &metaq);
|
|
235
|
+
if (result == 0)
|
|
236
|
+
rb_raise (rbl_eError, "failed to parse");
|
|
237
|
+
|
|
238
|
+
VALUE ary = rb_ary_new ();
|
|
239
|
+
VALUE output = rb_str_new (ret, retsz);
|
|
240
|
+
free (ret);
|
|
241
|
+
rb_ary_push (ary, output);
|
|
242
|
+
|
|
243
|
+
VALUE hash = rb_hash_new ();
|
|
244
|
+
struct lowdown_meta *meta;
|
|
245
|
+
TAILQ_FOREACH (meta, &metaq, entries)
|
|
246
|
+
{
|
|
247
|
+
VALUE key = rb_str_new_cstr (meta->key),
|
|
248
|
+
val = rb_str_new_cstr (meta->value);
|
|
249
|
+
rb_hash_aset (hash, key, val);
|
|
250
|
+
}
|
|
251
|
+
lowdown_metaq_free (&metaq);
|
|
252
|
+
rb_ary_push (ary, hash);
|
|
253
|
+
|
|
254
|
+
return ary;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
static VALUE
|
|
258
|
+
rbl_mLdown_m_into_html (int argc, VALUE *argv, VALUE klass)
|
|
259
|
+
{
|
|
260
|
+
(void)klass;
|
|
261
|
+
return rbl_parse_into (argc, argv, LOWDOWN_HTML);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
static VALUE
|
|
265
|
+
rbl_mLdown_m_into_latex (int argc, VALUE *argv, VALUE klass)
|
|
266
|
+
{
|
|
267
|
+
(void)klass;
|
|
268
|
+
return rbl_parse_into (argc, argv, LOWDOWN_LATEX);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
static VALUE
|
|
272
|
+
rbl_mLdown_m_into_man (int argc, VALUE *argv, VALUE klass)
|
|
273
|
+
{
|
|
274
|
+
(void)klass;
|
|
275
|
+
return rbl_parse_into (argc, argv, LOWDOWN_MAN);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
static VALUE
|
|
279
|
+
rbl_mLdown_m_into_mdoc (int argc, VALUE *argv, VALUE klass)
|
|
280
|
+
{
|
|
281
|
+
(void)klass;
|
|
282
|
+
return rbl_parse_into (argc, argv, LOWDOWN_MDOC);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
static VALUE
|
|
286
|
+
rbl_mLdown_m_into_fodt (int argc, VALUE *argv, VALUE klass)
|
|
287
|
+
{
|
|
288
|
+
(void)klass;
|
|
289
|
+
return rbl_parse_into (argc, argv, LOWDOWN_FODT);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
static VALUE
|
|
293
|
+
rbl_mLdown_m_into_term (int argc, VALUE *argv, VALUE klass)
|
|
294
|
+
{
|
|
295
|
+
(void)klass;
|
|
296
|
+
return rbl_parse_into (argc, argv, LOWDOWN_TERM);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
static VALUE
|
|
300
|
+
rbl_mLdown_m_into_gemini (int argc, VALUE *argv, VALUE klass)
|
|
301
|
+
{
|
|
302
|
+
(void)klass;
|
|
303
|
+
return rbl_parse_into (argc, argv, LOWDOWN_GEMINI);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
static VALUE
|
|
307
|
+
rbl_mLdown_m_into_ms (int argc, VALUE *argv, VALUE klass)
|
|
308
|
+
{
|
|
309
|
+
(void)klass;
|
|
310
|
+
return rbl_parse_into (argc, argv, LOWDOWN_MS);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
static VALUE
|
|
314
|
+
rbl_mLdown_m_into_tree (int argc, VALUE *argv, VALUE klass)
|
|
315
|
+
{
|
|
316
|
+
(void)klass;
|
|
317
|
+
return rbl_parse_into (argc, argv, LOWDOWN_TREE);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/* document */
|
|
321
|
+
|
|
322
|
+
static void
|
|
323
|
+
rbl_cDocument_free (void *ptr)
|
|
324
|
+
{
|
|
325
|
+
struct lowdown_doc *doc = ptr;
|
|
326
|
+
lowdown_doc_free (doc);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
static const rb_data_type_t rbl_cDocument_type
|
|
330
|
+
= { .wrap_struct_name = "lowdown document",
|
|
331
|
+
.function = { .dfree = rbl_cDocument_free },
|
|
332
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY };
|
|
333
|
+
|
|
334
|
+
static VALUE
|
|
335
|
+
rbl_cDocument_alloc (VALUE klass)
|
|
336
|
+
{
|
|
337
|
+
return rb_data_typed_object_wrap (rbl_cDocument, NULL, &rbl_cDocument_type);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
static VALUE
|
|
341
|
+
rbl_cDocument_m_initialize (int argc, VALUE *argv, VALUE self)
|
|
342
|
+
{
|
|
343
|
+
VALUE kwargs;
|
|
344
|
+
rb_scan_args (argc, argv, ":", &kwargs);
|
|
345
|
+
|
|
346
|
+
struct lowdown_opts opts = get_opts (kwargs);
|
|
347
|
+
|
|
348
|
+
struct lowdown_doc *doc = lowdown_doc_new (&opts);
|
|
349
|
+
if (doc == NULL)
|
|
350
|
+
rb_raise (rbl_eError, "failed to initialize document");
|
|
351
|
+
|
|
352
|
+
RTYPEDDATA_DATA (self) = doc;
|
|
353
|
+
return self;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
static VALUE
|
|
357
|
+
rbl_cDocument_m_parse (VALUE self, VALUE input)
|
|
358
|
+
{
|
|
359
|
+
struct lowdown_doc *doc = RTYPEDDATA_DATA (self);
|
|
360
|
+
if (!doc)
|
|
361
|
+
rb_raise (rbl_eError, "improperly initialized document");
|
|
362
|
+
|
|
363
|
+
const char *input_bytes = rb_string_value_cstr (&input);
|
|
364
|
+
size_t size = RSTRING_LEN (input);
|
|
365
|
+
/* Question: Supporting node identifier and metadata specification
|
|
366
|
+
useful? They are currently NULL. */
|
|
367
|
+
struct lowdown_node *node
|
|
368
|
+
= lowdown_doc_parse (doc, NULL, input_bytes, size, NULL);
|
|
369
|
+
if (node == NULL)
|
|
370
|
+
rb_raise (rbl_eError, "failed to parse");
|
|
371
|
+
|
|
372
|
+
VALUE node_obj = rb_obj_alloc (rbl_cNode);
|
|
373
|
+
RTYPEDDATA_DATA (node_obj) = node;
|
|
374
|
+
return node_obj;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/* HTML */
|
|
378
|
+
|
|
379
|
+
static void
|
|
380
|
+
rbl_cHTML_free (void *ptr)
|
|
381
|
+
{
|
|
382
|
+
void *doc = ptr;
|
|
383
|
+
lowdown_html_free (doc);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
static const rb_data_type_t rbl_cHTML_type
|
|
387
|
+
= { .wrap_struct_name = "lowdown HTML",
|
|
388
|
+
.function = { .dfree = rbl_cHTML_free },
|
|
389
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY };
|
|
390
|
+
|
|
391
|
+
static VALUE
|
|
392
|
+
rbl_cHTML_alloc (VALUE klass)
|
|
393
|
+
{
|
|
394
|
+
return rb_data_typed_object_wrap (rbl_cHTML, NULL, &rbl_cHTML_type);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
static VALUE
|
|
398
|
+
rbl_cHTML_m_initialize (int argc, VALUE *argv, VALUE self)
|
|
399
|
+
{
|
|
400
|
+
VALUE kwargs;
|
|
401
|
+
rb_scan_args (argc, argv, ":", &kwargs);
|
|
402
|
+
|
|
403
|
+
struct lowdown_opts opts = get_opts (kwargs);
|
|
404
|
+
|
|
405
|
+
void *rndr = lowdown_html_new (&opts);
|
|
406
|
+
if (rndr == NULL)
|
|
407
|
+
rb_raise (rbl_eError, "failed to initialize HTML");
|
|
408
|
+
|
|
409
|
+
RTYPEDDATA_DATA (self) = rndr;
|
|
410
|
+
return self;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
static VALUE
|
|
414
|
+
rbl_cHTML_m_render (VALUE self, VALUE node)
|
|
415
|
+
{
|
|
416
|
+
struct lowdown_buf *out = lowdown_buf_new (RBL_BUF_GROW);
|
|
417
|
+
if (out == NULL)
|
|
418
|
+
rb_raise (rbl_eError, "failed to create buffer");
|
|
419
|
+
|
|
420
|
+
void *rndr = RTYPEDDATA_DATA (self);
|
|
421
|
+
struct lowdown_node *node_ptr = RTYPEDDATA_DATA (node);
|
|
422
|
+
if (!lowdown_html_rndr (out, rndr, node_ptr))
|
|
423
|
+
rb_raise (rbl_eError, "failed to render into HTML");
|
|
424
|
+
|
|
425
|
+
VALUE rendered = rb_utf8_str_new (out->data, out->size);
|
|
426
|
+
lowdown_buf_free (out);
|
|
427
|
+
return rendered;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/* Gemini */
|
|
431
|
+
|
|
432
|
+
static void
|
|
433
|
+
rbl_cGemini_free (void *ptr)
|
|
434
|
+
{
|
|
435
|
+
void *doc = ptr;
|
|
436
|
+
lowdown_gemini_free (doc);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
static const rb_data_type_t rbl_cGemini_type
|
|
440
|
+
= { .wrap_struct_name = "lowdown Gemini",
|
|
441
|
+
.function = { .dfree = rbl_cGemini_free },
|
|
442
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY };
|
|
443
|
+
|
|
444
|
+
static VALUE
|
|
445
|
+
rbl_cGemini_alloc (VALUE klass)
|
|
446
|
+
{
|
|
447
|
+
return rb_data_typed_object_wrap (rbl_cGemini, NULL, &rbl_cGemini_type);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
static VALUE
|
|
451
|
+
rbl_cGemini_m_initialize (int argc, VALUE *argv, VALUE self)
|
|
452
|
+
{
|
|
453
|
+
VALUE kwargs;
|
|
454
|
+
rb_scan_args (argc, argv, ":", &kwargs);
|
|
455
|
+
|
|
456
|
+
struct lowdown_opts opts = get_opts (kwargs);
|
|
457
|
+
|
|
458
|
+
void *rndr = lowdown_gemini_new (&opts);
|
|
459
|
+
if (rndr == NULL)
|
|
460
|
+
rb_raise (rbl_eError, "failed to initialize Gemini");
|
|
461
|
+
|
|
462
|
+
RTYPEDDATA_DATA (self) = rndr;
|
|
463
|
+
return self;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
static VALUE
|
|
467
|
+
rbl_cGemini_m_render (VALUE self, VALUE node)
|
|
468
|
+
{
|
|
469
|
+
struct lowdown_buf *out = lowdown_buf_new (RBL_BUF_GROW);
|
|
470
|
+
if (out == NULL)
|
|
471
|
+
rb_raise (rbl_eError, "failed to create buffer");
|
|
472
|
+
|
|
473
|
+
void *rndr = RTYPEDDATA_DATA (self);
|
|
474
|
+
struct lowdown_node *node_ptr = RTYPEDDATA_DATA (node);
|
|
475
|
+
if (!lowdown_gemini_rndr (out, rndr, node_ptr))
|
|
476
|
+
rb_raise (rbl_eError, "failed to render into Gemini");
|
|
477
|
+
|
|
478
|
+
VALUE rendered = rb_utf8_str_new (out->data, out->size);
|
|
479
|
+
lowdown_buf_free (out);
|
|
480
|
+
return rendered;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/* LaTeX */
|
|
484
|
+
|
|
485
|
+
static void
|
|
486
|
+
rbl_cLaTeX_free (void *ptr)
|
|
487
|
+
{
|
|
488
|
+
void *doc = ptr;
|
|
489
|
+
lowdown_latex_free (doc);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
static const rb_data_type_t rbl_cLaTeX_type
|
|
493
|
+
= { .wrap_struct_name = "lowdown LaTeX",
|
|
494
|
+
.function = { .dfree = rbl_cLaTeX_free },
|
|
495
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY };
|
|
496
|
+
|
|
497
|
+
static VALUE
|
|
498
|
+
rbl_cLaTeX_alloc (VALUE klass)
|
|
499
|
+
{
|
|
500
|
+
return rb_data_typed_object_wrap (rbl_cLaTeX, NULL, &rbl_cLaTeX_type);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
static VALUE
|
|
504
|
+
rbl_cLaTeX_m_initialize (int argc, VALUE *argv, VALUE self)
|
|
505
|
+
{
|
|
506
|
+
VALUE kwargs;
|
|
507
|
+
rb_scan_args (argc, argv, ":", &kwargs);
|
|
508
|
+
|
|
509
|
+
struct lowdown_opts opts = get_opts (kwargs);
|
|
510
|
+
|
|
511
|
+
void *rndr = lowdown_latex_new (&opts);
|
|
512
|
+
if (rndr == NULL)
|
|
513
|
+
rb_raise (rbl_eError, "failed to initialize LaTeX");
|
|
514
|
+
|
|
515
|
+
RTYPEDDATA_DATA (self) = rndr;
|
|
516
|
+
return self;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
static VALUE
|
|
520
|
+
rbl_cLaTeX_m_render (VALUE self, VALUE node)
|
|
521
|
+
{
|
|
522
|
+
struct lowdown_buf *out = lowdown_buf_new (RBL_BUF_GROW);
|
|
523
|
+
if (out == NULL)
|
|
524
|
+
rb_raise (rbl_eError, "failed to create buffer");
|
|
525
|
+
|
|
526
|
+
void *rndr = RTYPEDDATA_DATA (self);
|
|
527
|
+
struct lowdown_node *node_ptr = RTYPEDDATA_DATA (node);
|
|
528
|
+
if (!lowdown_latex_rndr (out, rndr, node_ptr))
|
|
529
|
+
rb_raise (rbl_eError, "failed to render into LaTeX");
|
|
530
|
+
|
|
531
|
+
VALUE rendered = rb_utf8_str_new (out->data, out->size);
|
|
532
|
+
lowdown_buf_free (out);
|
|
533
|
+
return rendered;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/* OpenDocument */
|
|
537
|
+
|
|
538
|
+
static void
|
|
539
|
+
rbl_cOpenDocument_free (void *ptr)
|
|
540
|
+
{
|
|
541
|
+
void *doc = ptr;
|
|
542
|
+
lowdown_odt_free (doc);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
static const rb_data_type_t rbl_cOpenDocument_type
|
|
546
|
+
= { .wrap_struct_name = "lowdown OpenDocument",
|
|
547
|
+
.function = { .dfree = rbl_cOpenDocument_free },
|
|
548
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY };
|
|
549
|
+
|
|
550
|
+
static VALUE
|
|
551
|
+
rbl_cOpenDocument_alloc (VALUE klass)
|
|
552
|
+
{
|
|
553
|
+
return rb_data_typed_object_wrap (rbl_cOpenDocument, NULL,
|
|
554
|
+
&rbl_cOpenDocument_type);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
static VALUE
|
|
558
|
+
rbl_cOpenDocument_m_initialize (int argc, VALUE *argv, VALUE self)
|
|
559
|
+
{
|
|
560
|
+
VALUE kwargs;
|
|
561
|
+
rb_scan_args (argc, argv, ":", &kwargs);
|
|
562
|
+
|
|
563
|
+
struct lowdown_opts opts = get_opts (kwargs);
|
|
564
|
+
|
|
565
|
+
void *rndr = lowdown_odt_new (&opts);
|
|
566
|
+
if (rndr == NULL)
|
|
567
|
+
rb_raise (rbl_eError, "failed to initialize OpenDocument");
|
|
568
|
+
|
|
569
|
+
RTYPEDDATA_DATA (self) = rndr;
|
|
570
|
+
return self;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
static VALUE
|
|
574
|
+
rbl_cOpenDocument_m_render (VALUE self, VALUE node)
|
|
575
|
+
{
|
|
576
|
+
struct lowdown_buf *out = lowdown_buf_new (RBL_BUF_GROW);
|
|
577
|
+
if (out == NULL)
|
|
578
|
+
rb_raise (rbl_eError, "failed to create buffer");
|
|
579
|
+
|
|
580
|
+
void *rndr = RTYPEDDATA_DATA (self);
|
|
581
|
+
struct lowdown_node *node_ptr = RTYPEDDATA_DATA (node);
|
|
582
|
+
if (!lowdown_odt_rndr (out, rndr, node_ptr))
|
|
583
|
+
rb_raise (rbl_eError, "failed to render into OpenDocument");
|
|
584
|
+
|
|
585
|
+
VALUE rendered = rb_utf8_str_new (out->data, out->size);
|
|
586
|
+
lowdown_buf_free (out);
|
|
587
|
+
return rendered;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/* Roff */
|
|
591
|
+
|
|
592
|
+
static void
|
|
593
|
+
rbl_cRoff_free (void *ptr)
|
|
594
|
+
{
|
|
595
|
+
void *doc = ptr;
|
|
596
|
+
lowdown_roff_free (doc);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
static const rb_data_type_t rbl_cRoff_type
|
|
600
|
+
= { .wrap_struct_name = "lowdown Roff",
|
|
601
|
+
.function = { .dfree = rbl_cRoff_free },
|
|
602
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY };
|
|
603
|
+
|
|
604
|
+
static VALUE
|
|
605
|
+
rbl_cRoff_alloc (VALUE klass)
|
|
606
|
+
{
|
|
607
|
+
return rb_data_typed_object_wrap (rbl_cRoff, NULL, &rbl_cRoff_type);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
static VALUE
|
|
611
|
+
rbl_cRoff_m_initialize (int argc, VALUE *argv, VALUE self)
|
|
612
|
+
{
|
|
613
|
+
VALUE kwargs;
|
|
614
|
+
rb_scan_args (argc, argv, ":", &kwargs);
|
|
615
|
+
|
|
616
|
+
struct lowdown_opts opts = get_opts (kwargs);
|
|
617
|
+
|
|
618
|
+
void *rndr = lowdown_roff_new (&opts);
|
|
619
|
+
if (rndr == NULL)
|
|
620
|
+
rb_raise (rbl_eError, "failed to initialize Roff");
|
|
621
|
+
|
|
622
|
+
RTYPEDDATA_DATA (self) = rndr;
|
|
623
|
+
return self;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
static VALUE
|
|
627
|
+
rbl_cRoff_m_render (VALUE self, VALUE node)
|
|
628
|
+
{
|
|
629
|
+
struct lowdown_buf *out = lowdown_buf_new (RBL_BUF_GROW);
|
|
630
|
+
if (out == NULL)
|
|
631
|
+
rb_raise (rbl_eError, "failed to create buffer");
|
|
632
|
+
|
|
633
|
+
void *rndr = RTYPEDDATA_DATA (self);
|
|
634
|
+
struct lowdown_node *node_ptr = RTYPEDDATA_DATA (node);
|
|
635
|
+
if (!lowdown_roff_rndr (out, rndr, node_ptr))
|
|
636
|
+
rb_raise (rbl_eError, "failed to render into Roff");
|
|
637
|
+
|
|
638
|
+
VALUE rendered = rb_utf8_str_new (out->data, out->size);
|
|
639
|
+
lowdown_buf_free (out);
|
|
640
|
+
return rendered;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/* Term */
|
|
644
|
+
|
|
645
|
+
static void
|
|
646
|
+
rbl_cTerm_free (void *ptr)
|
|
647
|
+
{
|
|
648
|
+
void *doc = ptr;
|
|
649
|
+
lowdown_term_free (doc);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
static const rb_data_type_t rbl_cTerm_type
|
|
653
|
+
= { .wrap_struct_name = "lowdown Term",
|
|
654
|
+
.function = { .dfree = rbl_cTerm_free },
|
|
655
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY };
|
|
656
|
+
|
|
657
|
+
static VALUE
|
|
658
|
+
rbl_cTerm_alloc (VALUE klass)
|
|
659
|
+
{
|
|
660
|
+
return rb_data_typed_object_wrap (rbl_cTerm, NULL, &rbl_cTerm_type);
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
static VALUE
|
|
664
|
+
rbl_cTerm_m_initialize (int argc, VALUE *argv, VALUE self)
|
|
665
|
+
{
|
|
666
|
+
VALUE kwargs;
|
|
667
|
+
rb_scan_args (argc, argv, ":", &kwargs);
|
|
668
|
+
|
|
669
|
+
struct lowdown_opts opts = get_opts (kwargs);
|
|
670
|
+
|
|
671
|
+
void *rndr = lowdown_term_new (&opts);
|
|
672
|
+
if (rndr == NULL)
|
|
673
|
+
rb_raise (rbl_eError, "failed to initialize Term");
|
|
674
|
+
|
|
675
|
+
RTYPEDDATA_DATA (self) = rndr;
|
|
676
|
+
return self;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
static VALUE
|
|
680
|
+
rbl_cTerm_m_render (VALUE self, VALUE node)
|
|
681
|
+
{
|
|
682
|
+
struct lowdown_buf *out = lowdown_buf_new (RBL_BUF_GROW);
|
|
683
|
+
if (out == NULL)
|
|
684
|
+
rb_raise (rbl_eError, "failed to create buffer");
|
|
685
|
+
|
|
686
|
+
void *rndr = RTYPEDDATA_DATA (self);
|
|
687
|
+
struct lowdown_node *node_ptr = RTYPEDDATA_DATA (node);
|
|
688
|
+
if (!lowdown_term_rndr (out, rndr, node_ptr))
|
|
689
|
+
rb_raise (rbl_eError, "failed to render into Term");
|
|
690
|
+
|
|
691
|
+
VALUE rendered = rb_utf8_str_new (out->data, out->size);
|
|
692
|
+
lowdown_buf_free (out);
|
|
693
|
+
return rendered;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/* node */
|
|
697
|
+
|
|
698
|
+
static void
|
|
699
|
+
rbl_cNode_free (void *ptr)
|
|
700
|
+
{
|
|
701
|
+
void *node = ptr;
|
|
702
|
+
lowdown_node_free (node);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
static const rb_data_type_t rbl_cNode_type
|
|
706
|
+
= { .wrap_struct_name = "lowdown node",
|
|
707
|
+
.function = { .dfree = rbl_cNode_free },
|
|
708
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY };
|
|
709
|
+
|
|
710
|
+
static VALUE
|
|
711
|
+
rbl_cNode_alloc (VALUE klass)
|
|
712
|
+
{
|
|
713
|
+
return rb_data_typed_object_wrap (rbl_cNode, NULL, &rbl_cNode_type);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
static VALUE
|
|
717
|
+
rbl_cNode_m_tree (int argc, VALUE *argv, VALUE self)
|
|
718
|
+
{
|
|
719
|
+
VALUE kwargs;
|
|
720
|
+
rb_scan_args (argc, argv, ":", &kwargs);
|
|
721
|
+
|
|
722
|
+
struct lowdown_opts opts = get_opts (kwargs);
|
|
723
|
+
|
|
724
|
+
struct lowdown_buf *out = lowdown_buf_new (RBL_BUF_GROW);
|
|
725
|
+
if (out == NULL)
|
|
726
|
+
rb_raise (rbl_eError, "failed to create buffer");
|
|
727
|
+
|
|
728
|
+
struct lowdown_node *node_ptr = RTYPEDDATA_DATA (self);
|
|
729
|
+
if (lowdown_tree_rndr (out, node_ptr, &opts) == 0)
|
|
730
|
+
rb_raise (rbl_eError, "failed to render into Term");
|
|
731
|
+
|
|
732
|
+
VALUE rendered = rb_utf8_str_new (out->data, out->size);
|
|
733
|
+
lowdown_buf_free (out);
|
|
734
|
+
return rendered;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
static VALUE
|
|
738
|
+
rbl_cNode_m_diff_from (VALUE self, VALUE old)
|
|
739
|
+
{
|
|
740
|
+
struct lowdown_node *new = rb_check_typeddata (self, &rbl_cNode_type);
|
|
741
|
+
struct lowdown_node *o = rb_check_typeddata (old, &rbl_cNode_type);
|
|
742
|
+
size_t max_id;
|
|
743
|
+
struct lowdown_node *node = lowdown_diff (
|
|
744
|
+
o, new, &max_id /* Question: utilize max node identifier? */);
|
|
745
|
+
if (!node)
|
|
746
|
+
rb_raise (rbl_eError, "memory exhaustion");
|
|
747
|
+
|
|
748
|
+
return rb_data_typed_object_wrap (rbl_cNode, node, &rbl_cNode_type);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/* initialize */
|
|
752
|
+
|
|
753
|
+
RUBY_FUNC_EXPORTED void
|
|
754
|
+
Init_ldown (void)
|
|
755
|
+
{
|
|
756
|
+
rb_mLdown = rb_define_module ("Ldown");
|
|
757
|
+
|
|
758
|
+
rb_define_module_function (rb_mLdown, "into_html", rbl_mLdown_m_into_html,
|
|
759
|
+
-1);
|
|
760
|
+
rb_define_module_function (rb_mLdown, "into_latex", rbl_mLdown_m_into_latex,
|
|
761
|
+
-1);
|
|
762
|
+
rb_define_module_function (rb_mLdown, "into_man", rbl_mLdown_m_into_man, -1);
|
|
763
|
+
rb_define_module_function (rb_mLdown, "into_mdoc", rbl_mLdown_m_into_mdoc,
|
|
764
|
+
-1);
|
|
765
|
+
rb_define_module_function (rb_mLdown, "into_fodt", rbl_mLdown_m_into_fodt,
|
|
766
|
+
-1);
|
|
767
|
+
rb_define_module_function (rb_mLdown, "into_term", rbl_mLdown_m_into_term,
|
|
768
|
+
-1);
|
|
769
|
+
rb_define_module_function (rb_mLdown, "into_gemini",
|
|
770
|
+
rbl_mLdown_m_into_gemini, -1);
|
|
771
|
+
rb_define_module_function (rb_mLdown, "into_ms", rbl_mLdown_m_into_ms, -1);
|
|
772
|
+
rb_define_module_function (rb_mLdown, "into_tree", rbl_mLdown_m_into_tree,
|
|
773
|
+
-1);
|
|
774
|
+
|
|
775
|
+
rbl_cDocument = rb_define_class_under (rb_mLdown, "Document", rb_cObject);
|
|
776
|
+
rb_define_alloc_func (rbl_cDocument, rbl_cDocument_alloc);
|
|
777
|
+
rb_define_method (rbl_cDocument, "initialize", rbl_cDocument_m_initialize,
|
|
778
|
+
-1);
|
|
779
|
+
rb_define_method (rbl_cDocument, "parse", rbl_cDocument_m_parse, 1);
|
|
780
|
+
|
|
781
|
+
rbl_cHTML = rb_define_class_under (rb_mLdown, "HTML", rb_cObject);
|
|
782
|
+
rb_define_alloc_func (rbl_cHTML, rbl_cHTML_alloc);
|
|
783
|
+
rb_define_method (rbl_cHTML, "initialize", rbl_cHTML_m_initialize, -1);
|
|
784
|
+
rb_define_method (rbl_cHTML, "render", rbl_cHTML_m_render, 1);
|
|
785
|
+
|
|
786
|
+
rbl_cGemini = rb_define_class_under (rb_mLdown, "Gemini", rb_cObject);
|
|
787
|
+
rb_define_alloc_func (rbl_cGemini, rbl_cGemini_alloc);
|
|
788
|
+
rb_define_method (rbl_cGemini, "initialize", rbl_cGemini_m_initialize, -1);
|
|
789
|
+
rb_define_method (rbl_cGemini, "render", rbl_cGemini_m_render, 1);
|
|
790
|
+
|
|
791
|
+
rbl_cLaTeX = rb_define_class_under (rb_mLdown, "LaTeX", rb_cObject);
|
|
792
|
+
rb_define_alloc_func (rbl_cLaTeX, rbl_cLaTeX_alloc);
|
|
793
|
+
rb_define_method (rbl_cLaTeX, "initialize", rbl_cLaTeX_m_initialize, -1);
|
|
794
|
+
rb_define_method (rbl_cLaTeX, "render", rbl_cLaTeX_m_render, 1);
|
|
795
|
+
|
|
796
|
+
rbl_cOpenDocument
|
|
797
|
+
= rb_define_class_under (rb_mLdown, "OpenDocument", rb_cObject);
|
|
798
|
+
rb_define_alloc_func (rbl_cOpenDocument, rbl_cOpenDocument_alloc);
|
|
799
|
+
rb_define_method (rbl_cOpenDocument, "initialize",
|
|
800
|
+
rbl_cOpenDocument_m_initialize, -1);
|
|
801
|
+
rb_define_method (rbl_cOpenDocument, "render", rbl_cOpenDocument_m_render,
|
|
802
|
+
1);
|
|
803
|
+
|
|
804
|
+
rbl_cRoff = rb_define_class_under (rb_mLdown, "Roff", rb_cObject);
|
|
805
|
+
rb_define_alloc_func (rbl_cRoff, rbl_cRoff_alloc);
|
|
806
|
+
rb_define_method (rbl_cRoff, "initialize", rbl_cRoff_m_initialize, -1);
|
|
807
|
+
rb_define_method (rbl_cRoff, "render", rbl_cRoff_m_render, 1);
|
|
808
|
+
|
|
809
|
+
rbl_cTerm = rb_define_class_under (rb_mLdown, "Term", rb_cObject);
|
|
810
|
+
rb_define_alloc_func (rbl_cTerm, rbl_cTerm_alloc);
|
|
811
|
+
rb_define_method (rbl_cTerm, "initialize", rbl_cTerm_m_initialize, -1);
|
|
812
|
+
rb_define_method (rbl_cTerm, "render", rbl_cTerm_m_render, 1);
|
|
813
|
+
|
|
814
|
+
rbl_cNode = rb_define_class_under (rb_mLdown, "Node", rb_cObject);
|
|
815
|
+
rb_define_alloc_func (rbl_cNode, rbl_cNode_alloc);
|
|
816
|
+
rb_define_method (rbl_cNode, "tree", rbl_cNode_m_tree, -1);
|
|
817
|
+
rb_define_method (rbl_cNode, "diff_from", rbl_cNode_m_diff_from, 1);
|
|
818
|
+
|
|
819
|
+
rbl_eError = rb_define_class_under (rb_mLdown, "Error", rb_eStandardError);
|
|
820
|
+
}
|