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
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,
40 #include "lib/global.h"
41 #include "lib/tty/tty.h"
43 #include "lib/charsets.h"
45 #include "src/main.h" /* utf8_display */
46 #include "src/setup.h" /* option_tab_spacing */
50 /*** global variables ****************************************************************************/
52 /*** file scope macro definitions ****************************************************************/
54 /*** file scope type declarations ****************************************************************/
56 /*** file scope variables ************************************************************************/
58 /*** file scope functions ************************************************************************/
59 /* --------------------------------------------------------------------------------------------- */
61 /* --------------------------------------------------------------------------------------------- */
62 /*** public functions ****************************************************************************/
63 /* --------------------------------------------------------------------------------------------- */
66 mcview_display_nroff (mcview_t
* view
)
68 const screen_dimen left
= view
->data_area
.left
;
69 const screen_dimen top
= view
->data_area
.top
;
70 const screen_dimen width
= view
->data_area
.width
;
71 const screen_dimen height
= view
->data_area
.height
;
72 screen_dimen row
, col
;
78 struct hexedit_change_node
*curr
= view
->change_list
;
80 mcview_display_clean (view
);
81 mcview_display_ruler (view
);
83 /* Find the first displayable changed byte */
84 from
= view
->dpy_start
;
85 while (curr
&& (curr
->offset
< from
))
90 tty_setcolor (NORMAL_COLOR
);
91 for (row
= 0, col
= 0; row
< height
;)
96 gboolean read_res
= TRUE
;
97 c
= mcview_get_utf (view
, from
, &cw
, &read_res
);
104 if (!mcview_get_byte (view
, from
, &c
))
115 mcview_get_byte (view
, from
- 2, &c_prev
);
116 mcview_get_byte (view
, from
, &c_next
);
118 if (g_ascii_isprint (c_prev
) && g_ascii_isprint (c_prev
)
119 && (c_prev
== c_next
|| c_prev
== '_' || (c_prev
== '+' && c_next
== 'o')))
125 /* We're inside an nroff character sequence at the
126 * beginning of the screen -- just skip the
127 * backspace and continue with the next character. */
135 && (c_next
!= '_' || mcview_count_backspaces (view
, from
+ 1) == 1))
136 tty_setcolor (VIEW_UNDERLINED_COLOR
);
138 tty_setcolor (VIEW_BOLD_COLOR
);
143 if ((c
== '\n') || (col
>= width
&& view
->text_wrap_mode
))
147 if (c
== '\n' || row
>= height
)
153 mcview_get_byte_indexed (view
, from
, 1, &c
);
154 if (c
== '\r' || c
== '\n')
164 mcview_offset_to_coord (view
, &line
, &column
, from
);
165 col
+= (option_tab_spacing
- col
% option_tab_spacing
);
166 if (view
->text_wrap_mode
&& col
>= width
&& width
!= 0)
174 if (view
->search_start
<= from
&& from
< view
->search_end
)
176 tty_setcolor (SELECTED_COLOR
);
179 if ((off_t
) col
>= view
->dpy_text_column
180 && (off_t
) col
- view
->dpy_text_column
< (off_t
) width
)
182 widget_move (view
, top
+ row
, left
+ ((off_t
) col
- view
->dpy_text_column
));
188 c
= convert_from_8bit_to_utf_c ((unsigned char) c
, view
->converter
);
190 if (!g_unichar_isprint (c
))
197 c
= convert_from_utf_to_current_c (c
, view
->converter
);
202 c
= convert_to_display_c (c
);
207 tty_print_anychar (c
);
213 if (g_unichar_iswide (c
))
215 else if (g_unichar_iszerowidth (c
))
219 tty_setcolor (NORMAL_COLOR
);
221 view
->dpy_end
= from
;
224 /* --------------------------------------------------------------------------------------------- */
227 mcview__get_nroff_real_len (mcview_t
* view
, off_t start
, off_t length
)
229 mcview_nroff_t
*nroff
;
233 nroff
= mcview_nroff_seq_new_num (view
, start
);
239 if (nroff
->type
!= NROFF_TYPE_NONE
)
244 mcview_nroff_seq_next (nroff
);
247 mcview_nroff_seq_free (&nroff
);
251 /* --------------------------------------------------------------------------------------------- */
254 mcview_nroff_seq_new_num (mcview_t
* view
, off_t lc_index
)
256 mcview_nroff_t
*nroff
;
258 nroff
= g_try_malloc0 (sizeof (mcview_nroff_t
));
261 nroff
->index
= lc_index
;
263 mcview_nroff_seq_info (nroff
);
268 /* --------------------------------------------------------------------------------------------- */
271 mcview_nroff_seq_new (mcview_t
* view
)
273 return mcview_nroff_seq_new_num (view
, (off_t
) 0);
277 /* --------------------------------------------------------------------------------------------- */
280 mcview_nroff_seq_free (mcview_nroff_t
** nroff
)
282 if (nroff
== NULL
|| *nroff
== NULL
)
288 /* --------------------------------------------------------------------------------------------- */
291 mcview_nroff_seq_info (mcview_nroff_t
* nroff
)
296 return NROFF_TYPE_NONE
;
297 nroff
->type
= NROFF_TYPE_NONE
;
299 if (!mcview_get_byte (nroff
->view
, nroff
->index
, &nroff
->current_char
) || !g_ascii_isprint (nroff
->current_char
)) /* FIXME: utf-8 and g_ascii_isprint */
302 nroff
->char_width
= 1;
304 if (!mcview_get_byte (nroff
->view
, nroff
->index
+ 1, &next
) || next
!= '\b')
307 if (!mcview_get_byte (nroff
->view
, nroff
->index
+ 2, &next2
) || !g_ascii_isprint (next2
)) /* FIXME: utf-8 and g_ascii_isprint */
310 if (nroff
->current_char
== '_' && next2
== '_')
312 nroff
->type
= (nroff
->prev_type
== NROFF_TYPE_BOLD
)
313 ? NROFF_TYPE_BOLD
: NROFF_TYPE_UNDERLINE
;
316 else if (nroff
->current_char
== next2
)
318 nroff
->type
= NROFF_TYPE_BOLD
;
320 else if (nroff
->current_char
== '_')
322 nroff
->current_char
= next2
;
323 nroff
->type
= NROFF_TYPE_UNDERLINE
;
325 else if (nroff
->current_char
== '+' && next2
== 'o')
333 /* --------------------------------------------------------------------------------------------- */
336 mcview_nroff_seq_next (mcview_nroff_t
* nroff
)
341 nroff
->prev_type
= nroff
->type
;
343 nroff
->index
+= nroff
->char_width
;
345 if (nroff
->prev_type
!= NROFF_TYPE_NONE
)
347 mcview_nroff_seq_info (nroff
);
348 return nroff
->current_char
;
351 /* --------------------------------------------------------------------------------------------- */