Ticket #1791: a nice dark skin created by Lee Bigelow.
[kaloumi3.git] / src / viewer / nroff.c
blob95d743fb47e9582c1a4ac062ca03b249f4937d2a
1 /*
2 Internal file viewer for the Midnight Commander
3 Function for nroff-like view
5 Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
6 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
8 Written by: 1994, 1995, 1998 Miguel de Icaza
9 1994, 1995 Janne Kukonlehto
10 1995 Jakub Jelinek
11 1996 Joseph M. Hinkle
12 1997 Norbert Warmuth
13 1998 Pavel Machek
14 2004 Roland Illig <roland.illig@gmx.de>
15 2005 Roland Illig <roland.illig@gmx.de>
16 2009 Slava Zanko <slavazanko@google.com>
17 2009 Andrew Borodin <aborodin@vmail.ru>
18 2009 Ilia Maslakov <il.smind@gmail.com>
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 2 of the
25 License, or (at your option) any later version.
27 The Midnight Commander is distributed in the hope that it will be
28 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
29 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 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, write to the Free Software
34 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
35 MA 02110-1301, USA.
38 #include <config.h>
40 #include "lib/global.h"
41 #include "src/main.h"
42 #include "src/charsets.h"
43 #include "lib/tty/tty.h"
44 #include "lib/skin.h"
45 #include "internal.h"
48 /*** global variables ****************************************************************************/
50 /*** file scope macro definitions ****************************************************************/
52 /*** file scope type declarations ****************************************************************/
54 /*** file scope variables ************************************************************************/
56 /*** file scope functions ************************************************************************/
58 /*** public functions ****************************************************************************/
60 /* --------------------------------------------------------------------------------------------- */
62 void
63 mcview_display_nroff (mcview_t * view)
65 const screen_dimen left = view->data_area.left;
66 const screen_dimen top = view->data_area.top;
67 const screen_dimen width = view->data_area.width;
68 const screen_dimen height = view->data_area.height;
69 screen_dimen row, col;
70 off_t from;
71 int cw = 1;
72 int c;
73 int c_prev = 0;
74 int c_next = 0;
75 struct hexedit_change_node *curr = view->change_list;
77 mcview_display_clean (view);
78 mcview_display_ruler (view);
80 /* Find the first displayable changed byte */
81 from = view->dpy_start;
82 while (curr && (curr->offset < from))
84 curr = curr->next;
87 tty_setcolor (NORMAL_COLOR);
88 for (row = 0, col = 0; row < height;)
90 #ifdef HAVE_CHARSET
91 if (view->utf8)
93 gboolean read_res = TRUE;
94 c = mcview_get_utf (view, from, &cw, &read_res);
95 if (!read_res)
96 break;
98 else
99 #endif
101 if (!mcview_get_byte (view, from, &c))
102 break;
104 from++;
105 if (cw > 1)
106 from += cw - 1;
108 if (c == '\b')
110 if (from > 1)
112 mcview_get_byte (view, from - 2, &c_prev);
113 mcview_get_byte (view, from, &c_next);
115 if (g_ascii_isprint (c_prev) && g_ascii_isprint (c_prev)
116 && (c_prev == c_next || c_prev == '_' || (c_prev == '+' && c_next == 'o')))
118 if (col == 0)
120 if (row == 0)
122 /* We're inside an nroff character sequence at the
123 * beginning of the screen -- just skip the
124 * backspace and continue with the next character. */
125 continue;
127 row--;
128 col = width;
130 col--;
131 if (c_prev == '_'
132 && (c_next != '_' || mcview_count_backspaces (view, from + 1) == 1))
133 tty_setcolor (VIEW_UNDERLINED_COLOR);
134 else
135 tty_setcolor (MARKED_COLOR);
136 continue;
140 if ((c == '\n') || (col >= width && view->text_wrap_mode))
142 col = 0;
143 row++;
144 if (c == '\n' || row >= height)
145 continue;
148 if (c == '\r')
150 mcview_get_byte_indexed (view, from, 1, &c);
151 if (c == '\r' || c == '\n')
152 continue;
153 col = 0;
154 row++;
155 continue;
158 if (c == '\t')
160 off_t line, column;
161 mcview_offset_to_coord (view, &line, &column, from);
162 col += (option_tab_spacing - col % option_tab_spacing);
163 if (view->text_wrap_mode && col >= width && width != 0)
165 row += col / width;
166 col %= width;
168 continue;
171 if (view->search_start <= from && from < view->search_end)
173 tty_setcolor (SELECTED_COLOR);
176 if (col >= view->dpy_text_column && col - view->dpy_text_column < width)
178 widget_move (view, top + row, left + (col - view->dpy_text_column));
179 #ifdef HAVE_CHARSET
180 if (utf8_display)
182 if (!view->utf8)
184 c = convert_from_8bit_to_utf_c ((unsigned char) c, view->converter);
186 if (!g_unichar_isprint (c))
187 c = '.';
189 else
191 if (view->utf8)
193 c = convert_from_utf_to_current_c (c, view->converter);
195 else
197 #endif
198 c = convert_to_display_c (c);
199 #ifdef HAVE_CHARSET
202 #endif
203 tty_print_anychar (c);
205 col++;
206 #ifdef HAVE_CHARSET
207 if (view->utf8)
209 if (g_unichar_iswide (c))
210 col++;
211 else if (g_unichar_iszerowidth (c))
212 col--;
214 #endif
215 tty_setcolor (NORMAL_COLOR);
217 view->dpy_end = from;
220 /* --------------------------------------------------------------------------------------------- */
223 mcview__get_nroff_real_len (mcview_t * view, off_t start, off_t length)
225 mcview_nroff_t *nroff;
226 int ret = 0;
227 off_t i = 0;
229 nroff = mcview_nroff_seq_new_num (view, start);
230 if (nroff == NULL)
231 return 0;
233 while (i < length)
235 if (nroff->type != NROFF_TYPE_NONE)
237 ret += 2;
239 i++;
240 mcview_nroff_seq_next (nroff);
243 mcview_nroff_seq_free (&nroff);
244 return ret;
247 /* --------------------------------------------------------------------------------------------- */
249 mcview_nroff_t *
250 mcview_nroff_seq_new_num (mcview_t * view, off_t lc_index)
252 mcview_nroff_t *nroff;
254 nroff = g_try_malloc0 (sizeof (mcview_nroff_t));
255 if (nroff != NULL)
257 nroff->index = lc_index;
258 nroff->view = view;
259 mcview_nroff_seq_info (nroff);
261 return nroff;
264 /* --------------------------------------------------------------------------------------------- */
266 mcview_nroff_t *
267 mcview_nroff_seq_new (mcview_t * view)
269 return mcview_nroff_seq_new_num (view, (off_t) 0);
273 /* --------------------------------------------------------------------------------------------- */
275 void
276 mcview_nroff_seq_free (mcview_nroff_t ** nroff)
278 if (nroff == NULL || *nroff == NULL)
279 return;
280 g_free (*nroff);
281 nroff = NULL;
284 /* --------------------------------------------------------------------------------------------- */
286 nroff_type_t
287 mcview_nroff_seq_info (mcview_nroff_t * nroff)
289 int next, next2;
291 if (nroff == NULL)
292 return NROFF_TYPE_NONE;
293 nroff->type = NROFF_TYPE_NONE;
295 if (!mcview_get_byte (nroff->view, nroff->index, &nroff->current_char) || !g_ascii_isprint (nroff->current_char)) /* FIXME: utf-8 and g_ascii_isprint */
296 return nroff->type;
298 nroff->char_width = 1;
300 if (!mcview_get_byte (nroff->view, nroff->index + 1, &next) || next != '\b')
301 return nroff->type;
303 if (!mcview_get_byte (nroff->view, nroff->index + 2, &next2) || !g_ascii_isprint (next2)) /* FIXME: utf-8 and g_ascii_isprint */
304 return nroff->type;
306 if (nroff->current_char == '_' && next2 == '_')
308 nroff->type = (nroff->prev_type == NROFF_TYPE_BOLD)
309 ? NROFF_TYPE_BOLD : NROFF_TYPE_UNDERLINE;
312 else if (nroff->current_char == next2)
314 nroff->type = NROFF_TYPE_BOLD;
316 else if (nroff->current_char == '_')
318 nroff->current_char = next2;
319 nroff->type = NROFF_TYPE_UNDERLINE;
321 else if (nroff->current_char == '+' && next2 == 'o')
323 /* ??? */
326 return nroff->type;
329 /* --------------------------------------------------------------------------------------------- */
332 mcview_nroff_seq_next (mcview_nroff_t * nroff)
334 if (nroff == NULL)
335 return -1;
337 nroff->prev_type = nroff->type;
339 nroff->index += nroff->char_width;
341 if (nroff->prev_type != NROFF_TYPE_NONE)
342 nroff->index += 2;
343 mcview_nroff_seq_info (nroff);
344 return nroff->current_char;
347 /* --------------------------------------------------------------------------------------------- */