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, 2011
7 The Free Software Foundation, Inc.
10 Miguel de Icaza, 1994, 1995, 1998
11 Janne Kukonlehto, 1994, 1995
13 Joseph M. Hinkle, 1996
16 Roland Illig <roland.illig@gmx.de>, 2004, 2005
17 Slava Zanko <slavazanko@google.com>, 2009
18 Andrew Borodin <aborodin@vmail.ru>, 2009
19 Ilia Maslakov <il.smind@gmail.com>, 2009
21 This file is part of the Midnight Commander.
23 The Midnight Commander is free software: you can redistribute it
24 and/or modify it under the terms of the GNU General Public License as
25 published by the Free Software Foundation, either version 3 of the License,
26 or (at your option) any later version.
28 The Midnight Commander is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU General Public License for more details.
33 You should have received a copy of the GNU General Public License
34 along with this program. If not, see <http://www.gnu.org/licenses/>.
39 #include "lib/global.h"
40 #include "lib/tty/tty.h"
43 #include "lib/charsets.h"
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 /* --------------------------------------------------------------------------------------------- */
62 mcview_nroff_get_char (mcview_nroff_t
* nroff
, int *ret_val
, off_t nroff_index
)
66 if (nroff
->view
->utf8
)
69 c
= mcview_get_utf (nroff
->view
, nroff_index
, &nroff
->char_width
, &utf_result
);
72 /* we need got symbol in any case */
73 nroff
->char_width
= 1;
74 if (!mcview_get_byte (nroff
->view
, nroff_index
, &c
) || !g_ascii_isprint (c
))
81 nroff
->char_width
= 1;
82 if (!mcview_get_byte (nroff
->view
, nroff_index
, &c
))
88 return g_unichar_isprint (c
);
91 /* --------------------------------------------------------------------------------------------- */
92 /*** public functions ****************************************************************************/
93 /* --------------------------------------------------------------------------------------------- */
96 mcview_display_nroff (mcview_t
* view
)
98 const screen_dimen left
= view
->data_area
.left
;
99 const screen_dimen top
= view
->data_area
.top
;
100 const screen_dimen width
= view
->data_area
.width
;
101 const screen_dimen height
= view
->data_area
.height
;
102 screen_dimen row
, col
;
108 struct hexedit_change_node
*curr
= view
->change_list
;
110 mcview_display_clean (view
);
111 mcview_display_ruler (view
);
113 /* Find the first displayable changed byte */
114 from
= view
->dpy_start
;
115 while (curr
&& (curr
->offset
< from
))
120 tty_setcolor (NORMAL_COLOR
);
121 for (row
= 0, col
= 0; row
< height
;)
126 gboolean read_res
= TRUE
;
127 c
= mcview_get_utf (view
, from
, &cw
, &read_res
);
134 if (!mcview_get_byte (view
, from
, &c
))
149 c_next
= mcview_get_utf (view
, from
, &cw
, &read_res
);
153 mcview_get_byte (view
, from
, &c_next
);
155 if (g_unichar_isprint (c_prev
) && g_unichar_isprint (c_next
)
156 && (c_prev
== c_next
|| c_prev
== '_' || (c_prev
== '+' && c_next
== 'o')))
162 /* We're inside an nroff character sequence at the
163 * beginning of the screen -- just skip the
164 * backspace and continue with the next character. */
172 && (c_next
!= '_' || mcview_count_backspaces (view
, from
+ 1) == 1))
173 tty_setcolor (VIEW_UNDERLINED_COLOR
);
175 tty_setcolor (VIEW_BOLD_COLOR
);
180 if ((c
== '\n') || (col
>= width
&& view
->text_wrap_mode
))
184 if (c
== '\n' || row
>= height
)
190 mcview_get_byte_indexed (view
, from
, 1, &c
);
191 if (c
== '\r' || c
== '\n')
201 mcview_offset_to_coord (view
, &line
, &column
, from
);
202 col
+= (option_tab_spacing
- col
% option_tab_spacing
);
203 if (view
->text_wrap_mode
&& col
>= width
&& width
!= 0)
211 if (view
->search_start
<= from
&& from
< view
->search_end
)
213 tty_setcolor (SELECTED_COLOR
);
218 if ((off_t
) col
>= view
->dpy_text_column
219 && (off_t
) col
- view
->dpy_text_column
< (off_t
) width
)
221 widget_move (view
, top
+ row
, left
+ ((off_t
) col
- view
->dpy_text_column
));
223 if (mc_global
.utf8_display
)
227 c
= convert_from_8bit_to_utf_c ((unsigned char) c
, view
->converter
);
229 if (!g_unichar_isprint (c
))
233 c
= convert_from_utf_to_current_c (c
, view
->converter
);
235 c
= convert_to_display_c (c
);
237 tty_print_anychar (c
);
243 if (g_unichar_iswide (c
))
245 else if (g_unichar_iszerowidth (c
))
249 tty_setcolor (NORMAL_COLOR
);
251 view
->dpy_end
= from
;
254 /* --------------------------------------------------------------------------------------------- */
257 mcview__get_nroff_real_len (mcview_t
* view
, off_t start
, off_t length
)
259 mcview_nroff_t
*nroff
;
263 if (!view
->text_nroff_mode
)
266 nroff
= mcview_nroff_seq_new_num (view
, start
);
273 case NROFF_TYPE_BOLD
:
274 ret
+= 1 + nroff
->char_width
; /* real char width and 0x8 */
276 case NROFF_TYPE_UNDERLINE
:
277 ret
+= 2; /* underline symbol and ox8 */
282 i
+= nroff
->char_width
;
283 mcview_nroff_seq_next (nroff
);
286 mcview_nroff_seq_free (&nroff
);
290 /* --------------------------------------------------------------------------------------------- */
293 mcview_nroff_seq_new_num (mcview_t
* view
, off_t lc_index
)
295 mcview_nroff_t
*nroff
;
297 nroff
= g_try_malloc0 (sizeof (mcview_nroff_t
));
300 nroff
->index
= lc_index
;
302 mcview_nroff_seq_info (nroff
);
307 /* --------------------------------------------------------------------------------------------- */
310 mcview_nroff_seq_new (mcview_t
* view
)
312 return mcview_nroff_seq_new_num (view
, (off_t
) 0);
316 /* --------------------------------------------------------------------------------------------- */
319 mcview_nroff_seq_free (mcview_nroff_t
** nroff
)
321 if (nroff
== NULL
|| *nroff
== NULL
)
327 /* --------------------------------------------------------------------------------------------- */
330 mcview_nroff_seq_info (mcview_nroff_t
* nroff
)
335 return NROFF_TYPE_NONE
;
336 nroff
->type
= NROFF_TYPE_NONE
;
338 if (!mcview_nroff_get_char (nroff
, &nroff
->current_char
, nroff
->index
))
341 if (!mcview_get_byte (nroff
->view
, nroff
->index
+ nroff
->char_width
, &next
) || next
!= '\b')
344 if (!mcview_nroff_get_char (nroff
, &next2
, nroff
->index
+ 1 + nroff
->char_width
))
347 if (nroff
->current_char
== '_' && next2
== '_')
349 nroff
->type
= (nroff
->prev_type
== NROFF_TYPE_BOLD
)
350 ? NROFF_TYPE_BOLD
: NROFF_TYPE_UNDERLINE
;
353 else if (nroff
->current_char
== next2
)
355 nroff
->type
= NROFF_TYPE_BOLD
;
357 else if (nroff
->current_char
== '_')
359 nroff
->current_char
= next2
;
360 nroff
->type
= NROFF_TYPE_UNDERLINE
;
362 else if (nroff
->current_char
== '+' && next2
== 'o')
369 /* --------------------------------------------------------------------------------------------- */
372 mcview_nroff_seq_next (mcview_nroff_t
* nroff
)
377 nroff
->prev_type
= nroff
->type
;
381 case NROFF_TYPE_BOLD
:
382 nroff
->index
+= 1 + nroff
->char_width
;
384 case NROFF_TYPE_UNDERLINE
:
391 nroff
->index
+= nroff
->char_width
;
393 mcview_nroff_seq_info (nroff
);
394 return nroff
->current_char
;
397 /* --------------------------------------------------------------------------------------------- */
400 mcview_nroff_seq_prev (mcview_nroff_t
* nroff
)
403 off_t prev_index
, prev_index2
;
408 nroff
->prev_type
= NROFF_TYPE_NONE
;
410 if (nroff
->index
== 0)
413 prev_index
= nroff
->index
- 1;
415 while (prev_index
!= 0)
417 if (mcview_nroff_get_char (nroff
, &nroff
->current_char
, prev_index
))
424 mcview_nroff_seq_info (nroff
);
425 return nroff
->current_char
;
430 if (!mcview_get_byte (nroff
->view
, prev_index
, &prev
) || prev
!= '\b')
432 nroff
->index
= prev_index
;
433 mcview_nroff_seq_info (nroff
);
434 return nroff
->current_char
;
436 prev_index2
= prev_index
- 1;
438 while (prev_index2
!= 0)
440 if (mcview_nroff_get_char (nroff
, &prev
, prev_index
))
445 nroff
->index
= (prev_index2
== 0) ? prev_index
: prev_index2
;
446 mcview_nroff_seq_info (nroff
);
447 return nroff
->current_char
;
450 /* --------------------------------------------------------------------------------------------- */