1 #ifdef HAVE_CONFIG_H
2   #include <config.h>
3 #endif
4 
5 #define PERL_NO_GET_CONTEXT
6 #include "EXTERN.h"
7 #include "perl.h"
8 #include "XSUB.h"
9 
10 #include "ppport.h"
11 
12 #include "xspara.h"
13 
14 MODULE = Texinfo::Convert::Paragraph PACKAGE = Texinfo::Convert::Paragraph PREFIX = xspara_
15 
16 #  Copyright 2010-2020 Free Software Foundation, Inc.
17 #
18 #  This program is free software: you can redistribute it and/or modify
19 #  it under the terms of the GNU General Public License as published by
20 #  the Free Software Foundation, either version 3 of the License, or
21 #  (at your option) any later version.
22 #
23 #  This program is distributed in the hope that it will be useful,
24 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
25 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26 #  GNU General Public License for more details.
27 #
28 #  You should have received a copy of the GNU General Public License
29 #  along with this program.  If not, see <http://www.gnu.org/licenses/>.
30 
31 PROTOTYPES: ENABLE
32 
33 int
34 xspara_init (unused, unused2)
35      int unused
36      char *unused2
37 
38 void
39 xspara_set_state (state)
40      SV * state
41 
42 # Return a reference blessed into the XSParagraph class
43 # CLASS is ignored because we know it is "XSParagraph".  Optional
44 # CONF parameter.
45 SV *
46 xspara_new (class, ...)
47         SV * class
48     PREINIT:
49         HV *conf = 0;
50         int id;
51     CODE:
52         items--;
53         if (items > 0)
54           {
55             if (SvROK(ST(1)) && SvTYPE(SvRV(ST(1))) == SVt_PVHV)
56               conf = (HV *) SvRV(ST(1));
57           }
58         id = xspara_new (conf);
59 
60         /* Create an integer, which the other functions
61            need as their first argument. */
62         RETVAL = newSViv (id);
63     OUTPUT:
64         RETVAL
65 
66 
67 int
68 xspara_end_line_count (paragraph)
69         SV *paragraph
70     CODE:
71         xspara_set_state (paragraph);
72         RETVAL = xspara_end_line_count ();
73     OUTPUT:
74         RETVAL
75 
76 void
77 xspara__end_line (paragraph)
78         SV *paragraph
79     CODE:
80         xspara_set_state (paragraph);
81         xspara__end_line ();
82 
83 char *
84 xspara_end_line (paragraph)
85         SV *paragraph
86     CODE:
87         xspara_set_state (paragraph);
88         RETVAL = xspara_end_line ();
89     OUTPUT:
90         RETVAL
91 
92 char *
93 xspara_get_pending (paragraph)
94         SV *paragraph
95     CODE:
96         xspara_set_state (paragraph);
97         RETVAL = xspara_get_pending ();
98     OUTPUT:
99         RETVAL
100 
101 # ... is for add_spaces
102 SV *
103 xspara_add_pending_word (paragraph, ...)
104         SV *paragraph
105     PREINIT:
106         int add_spaces = 0;
107         char *retval;
108     CODE:
109         items -= 1;
110         if (items > 0)
111           {
112             if (SvOK(ST(1)))
113               {
114                 add_spaces = (int)SvIV(ST(1));;
115               }
116           }
117         xspara_set_state (paragraph);
118         retval = xspara_add_pending_word (add_spaces);
119 
120         RETVAL = newSVpv (retval, 0);
121         SvUTF8_on (RETVAL);
122     OUTPUT:
123         RETVAL
124 
125 SV *
126 xspara_end (paragraph)
127         SV *paragraph
128     PREINIT:
129         char *retval;
130     CODE:
131         xspara_set_state (paragraph);
132         retval = xspara_end ();
133 
134         RETVAL = newSVpv (retval, 0);
135         SvUTF8_on (RETVAL);
136     OUTPUT:
137         RETVAL
138 
139 
140 SV *
141 xspara_add_text (paragraph, text_in)
142         SV *paragraph
143         SV * text_in
144     PREINIT:
145         char *text;
146         char *retval;
147     CODE:
148         /* Always convert the input to UTF8 with sv_utf8_upgrade, so we can
149            process it properly in xspara_add_next. */
150         if (!SvUTF8 (text_in))
151           sv_utf8_upgrade (text_in);
152 
153         text = SvPV_nolen (text_in);
154 
155         xspara_set_state (paragraph);
156         retval = xspara_add_text (text);
157 
158         RETVAL = newSVpv (retval, 0);
159         SvUTF8_on (RETVAL);
160 
161     OUTPUT:
162         RETVAL
163 
164 SV *
165 xspara_add_next (paragraph, text_in, ...)
166         SV *paragraph
167         SV * text_in
168     PREINIT:
169         char *text;
170         STRLEN text_len;
171         char *retval;
172         SV *arg_in;
173         int transparent = 0;
174     CODE:
175         items -= 2;
176         if (items > 0)
177           {
178             items--;
179             arg_in = ST(2);
180             if (SvOK(arg_in))
181               transparent = (int)SvIV(arg_in);
182           }
183 
184         /* Always convert the input to UTF8 with sv_utf8_upgrade, so we can
185            process it properly in xspara_add_next. */
186         if (!SvUTF8 (text_in))
187           sv_utf8_upgrade (text_in);
188         text = SvPV (text_in, text_len);
189 
190         xspara_set_state (paragraph);
191         retval = xspara_add_next (text, text_len, transparent);
192 
193         RETVAL = newSVpv (retval, 0);
194         SvUTF8_on (RETVAL);
195 
196     OUTPUT:
197         RETVAL
198 
199 
200 void
201 xspara_remove_end_sentence (paragraph)
202         SV *paragraph
203     CODE:
204         xspara_set_state (paragraph);
205         xspara_remove_end_sentence ();
206 
207 void
208 xspara_add_end_sentence (paragraph, value)
209         SV *paragraph
210         SV * value
211     PREINIT:
212         int intvalue = 0;
213     CODE:
214         if (SvOK(value))
215           intvalue = (int)SvIV(value);
216         xspara_set_state (paragraph);
217         xspara_add_end_sentence (intvalue);
218 
219 void
220 xspara_allow_end_sentence (paragraph)
221         SV *paragraph
222     CODE:
223         xspara_set_state (paragraph);
224         xspara_allow_end_sentence ();
225 
226 # Optional parameters are IGNORE_COLUMNS, KEEP_END_LINES, FRENCHSPACING,
227 # DOUBLE_WIDTH_NO_BREAK.
228 # Pass them to the C function as -1 if not given or undef.
229 void
230 xspara_set_space_protection (paragraph, space_protection_in, ...)
231         SV *paragraph
232         SV * space_protection_in
233     PREINIT:
234         int space_protection = -1;
235         int ignore_columns = -1;
236         int keep_end_lines = -1;
237         int french_spacing = -1;
238         int double_width_no_break = -1;
239         SV *arg_in;
240     CODE:
241         if (SvOK(space_protection_in))
242           space_protection = (int)SvIV(space_protection_in);
243         /* Get optional arguments from stack. */
244         items -= 2;
245         if (items > 0)
246           {
247             items--;
248             arg_in = ST(2);
249             if (SvOK(arg_in))
250               ignore_columns = (int)SvIV(arg_in);
251           }
252         if (items > 0)
253           {
254             items--;
255             arg_in = ST(3);
256             if (SvOK(arg_in))
257               keep_end_lines = (int)SvIV(arg_in);
258           }
259         if (items > 0)
260           {
261             items--;
262             arg_in = ST(4);
263             if (SvOK(arg_in))
264               french_spacing = (int)SvIV(arg_in);
265           }
266         if (items > 0)
267           {
268             items--;
269             arg_in = ST(5);
270             if (SvOK(arg_in))
271               double_width_no_break = (int)SvIV(arg_in);
272           }
273 
274         xspara_set_state (paragraph);
275         xspara_set_space_protection
276           (space_protection, ignore_columns, keep_end_lines,
277            french_spacing, double_width_no_break);
278 
279