mcview: refactoring of mcview_get_utf().
[midnight-commander.git] / src / viewer / nroff.c
blob903906968223ee47d16874ebf53949a453d15fdd
1 /*
2 Internal file viewer for the Midnight Commander
3 Functions for searching in nroff-like view
5 Copyright (C) 1994-2016
6 Free Software Foundation, Inc.
8 Written by:
9 Miguel de Icaza, 1994, 1995, 1998
10 Janne Kukonlehto, 1994, 1995
11 Jakub Jelinek, 1995
12 Joseph M. Hinkle, 1996
13 Norbert Warmuth, 1997
14 Pavel Machek, 1998
15 Roland Illig <roland.illig@gmx.de>, 2004, 2005
16 Slava Zanko <slavazanko@google.com>, 2009
17 Andrew Borodin <aborodin@vmail.ru>, 2009
18 Ilia Maslakov <il.smind@gmail.com>, 2009
20 This file is part of the Midnight Commander.
22 The Midnight Commander is free software: you can redistribute it
23 and/or modify it under the terms of the GNU General Public License as
24 published by the Free Software Foundation, either version 3 of the License,
25 or (at your option) any later version.
27 The Midnight Commander is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
32 You should have received a copy of the GNU General Public License
33 along with this program. If not, see <http://www.gnu.org/licenses/>.
36 #include <config.h>
38 #include "lib/global.h"
39 #include "lib/tty/tty.h"
40 #include "lib/skin.h"
41 #ifdef HAVE_CHARSET
42 #include "lib/charsets.h"
43 #endif
45 #include "src/setup.h" /* option_tab_spacing */
47 #include "internal.h"
49 /*** global variables ****************************************************************************/
51 /*** file scope macro definitions ****************************************************************/
53 /*** file scope type declarations ****************************************************************/
55 /*** file scope variables ************************************************************************/
57 /*** file scope functions ************************************************************************/
58 /* --------------------------------------------------------------------------------------------- */
60 static gboolean
61 mcview_nroff_get_char (mcview_nroff_t * nroff, int *ret_val, off_t nroff_index)
63 int c = 0;
65 #ifdef HAVE_CHARSET
66 if (nroff->view->utf8)
68 if (!mcview_get_utf (nroff->view, nroff_index, &c, &nroff->char_length))
70 /* we need got symbol in any case */
71 nroff->char_length = 1;
72 if (!mcview_get_byte (nroff->view, nroff_index, &c) || !g_ascii_isprint (c))
73 return FALSE;
76 else
77 #endif
79 nroff->char_length = 1;
80 if (!mcview_get_byte (nroff->view, nroff_index, &c))
81 return FALSE;
84 *ret_val = c;
86 return g_unichar_isprint (c);
89 /* --------------------------------------------------------------------------------------------- */
90 /*** public functions ****************************************************************************/
91 /* --------------------------------------------------------------------------------------------- */
93 int
94 mcview__get_nroff_real_len (WView * view, off_t start, off_t length)
96 mcview_nroff_t *nroff;
97 int ret = 0;
98 off_t i = 0;
100 if (!view->text_nroff_mode)
101 return 0;
103 nroff = mcview_nroff_seq_new_num (view, start);
104 if (nroff == NULL)
105 return 0;
106 while (i < length)
108 switch (nroff->type)
110 case NROFF_TYPE_BOLD:
111 ret += 1 + nroff->char_length; /* real char length and 0x8 */
112 break;
113 case NROFF_TYPE_UNDERLINE:
114 ret += 2; /* underline symbol and ox8 */
115 break;
116 default:
117 break;
119 i += nroff->char_length;
120 mcview_nroff_seq_next (nroff);
123 mcview_nroff_seq_free (&nroff);
124 return ret;
127 /* --------------------------------------------------------------------------------------------- */
129 mcview_nroff_t *
130 mcview_nroff_seq_new_num (WView * view, off_t lc_index)
132 mcview_nroff_t *nroff;
134 nroff = g_try_malloc0 (sizeof (mcview_nroff_t));
135 if (nroff != NULL)
137 nroff->index = lc_index;
138 nroff->view = view;
139 mcview_nroff_seq_info (nroff);
141 return nroff;
144 /* --------------------------------------------------------------------------------------------- */
146 mcview_nroff_t *
147 mcview_nroff_seq_new (WView * view)
149 return mcview_nroff_seq_new_num (view, (off_t) 0);
153 /* --------------------------------------------------------------------------------------------- */
155 void
156 mcview_nroff_seq_free (mcview_nroff_t ** nroff)
158 if (nroff == NULL || *nroff == NULL)
159 return;
160 MC_PTR_FREE (*nroff);
163 /* --------------------------------------------------------------------------------------------- */
165 nroff_type_t
166 mcview_nroff_seq_info (mcview_nroff_t * nroff)
168 int next, next2;
170 if (nroff == NULL)
171 return NROFF_TYPE_NONE;
172 nroff->type = NROFF_TYPE_NONE;
174 if (!mcview_nroff_get_char (nroff, &nroff->current_char, nroff->index))
175 return nroff->type;
177 if (!mcview_get_byte (nroff->view, nroff->index + nroff->char_length, &next) || next != '\b')
178 return nroff->type;
180 if (!mcview_nroff_get_char (nroff, &next2, nroff->index + 1 + nroff->char_length))
181 return nroff->type;
183 if (nroff->current_char == '_' && next2 == '_')
185 nroff->type = (nroff->prev_type == NROFF_TYPE_BOLD)
186 ? NROFF_TYPE_BOLD : NROFF_TYPE_UNDERLINE;
189 else if (nroff->current_char == next2)
191 nroff->type = NROFF_TYPE_BOLD;
193 else if (nroff->current_char == '_')
195 nroff->current_char = next2;
196 nroff->type = NROFF_TYPE_UNDERLINE;
198 else if (nroff->current_char == '+' && next2 == 'o')
200 /* ??? */
202 return nroff->type;
205 /* --------------------------------------------------------------------------------------------- */
208 mcview_nroff_seq_next (mcview_nroff_t * nroff)
210 if (nroff == NULL)
211 return -1;
213 nroff->prev_type = nroff->type;
215 switch (nroff->type)
217 case NROFF_TYPE_BOLD:
218 nroff->index += 1 + nroff->char_length;
219 break;
220 case NROFF_TYPE_UNDERLINE:
221 nroff->index += 2;
222 break;
223 default:
224 break;
227 nroff->index += nroff->char_length;
229 mcview_nroff_seq_info (nroff);
230 return nroff->current_char;
233 /* --------------------------------------------------------------------------------------------- */
236 mcview_nroff_seq_prev (mcview_nroff_t * nroff)
238 int prev;
239 off_t prev_index, prev_index2;
241 if (nroff == NULL)
242 return -1;
244 nroff->prev_type = NROFF_TYPE_NONE;
246 if (nroff->index == 0)
247 return -1;
249 prev_index = nroff->index - 1;
251 while (prev_index != 0)
253 if (mcview_nroff_get_char (nroff, &nroff->current_char, prev_index))
254 break;
255 prev_index--;
257 if (prev_index == 0)
259 nroff->index--;
260 mcview_nroff_seq_info (nroff);
261 return nroff->current_char;
264 prev_index--;
266 if (!mcview_get_byte (nroff->view, prev_index, &prev) || prev != '\b')
268 nroff->index = prev_index;
269 mcview_nroff_seq_info (nroff);
270 return nroff->current_char;
272 prev_index2 = prev_index - 1;
274 while (prev_index2 != 0)
276 if (mcview_nroff_get_char (nroff, &prev, prev_index))
277 break;
278 prev_index2--;
281 nroff->index = (prev_index2 == 0) ? prev_index : prev_index2;
282 mcview_nroff_seq_info (nroff);
283 return nroff->current_char;
286 /* --------------------------------------------------------------------------------------------- */