/* Internal file viewer for the Midnight Commander Functions for searching in nroff-like view Copyright (C) 1994-2023 Free Software Foundation, Inc. Written by: Miguel de Icaza, 1994, 1995, 1998 Janne Kukonlehto, 1994, 1995 Jakub Jelinek, 1995 Joseph M. Hinkle, 1996 Norbert Warmuth, 1997 Pavel Machek, 1998 Roland Illig , 2004, 2005 Slava Zanko , 2009 Andrew Borodin , 2009 Ilia Maslakov , 2009 This file is part of the Midnight Commander. The Midnight Commander is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The Midnight Commander is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "lib/global.h" #include "lib/tty/tty.h" #include "lib/skin.h" #ifdef HAVE_CHARSET #include "lib/charsets.h" #endif #include "internal.h" /*** global variables ****************************************************************************/ /*** file scope macro definitions ****************************************************************/ /*** file scope type declarations ****************************************************************/ /*** forward declarations (file scope functions) *************************************************/ /*** file scope variables ************************************************************************/ /* --------------------------------------------------------------------------------------------- */ /*** file scope functions ************************************************************************/ /* --------------------------------------------------------------------------------------------- */ static gboolean mcview_nroff_get_char (mcview_nroff_t * nroff, int *ret_val, off_t nroff_index) { int c = 0; #ifdef HAVE_CHARSET if (nroff->view->utf8) { if (!mcview_get_utf (nroff->view, nroff_index, &c, &nroff->char_length)) { /* we need got symbol in any case */ nroff->char_length = 1; if (!mcview_get_byte (nroff->view, nroff_index, &c) || !g_ascii_isprint (c)) return FALSE; } } else #endif { nroff->char_length = 1; if (!mcview_get_byte (nroff->view, nroff_index, &c)) return FALSE; } *ret_val = c; return g_unichar_isprint (c); } /* --------------------------------------------------------------------------------------------- */ /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ int mcview__get_nroff_real_len (WView * view, off_t start, off_t length) { mcview_nroff_t *nroff; int ret = 0; off_t i = 0; if (!view->mode_flags.nroff) return 0; nroff = mcview_nroff_seq_new_num (view, start); if (nroff == NULL) return 0; while (i < length) { switch (nroff->type) { case NROFF_TYPE_BOLD: ret += 1 + nroff->char_length; /* real char length and 0x8 */ break; case NROFF_TYPE_UNDERLINE: ret += 2; /* underline symbol and ox8 */ break; default: break; } i += nroff->char_length; mcview_nroff_seq_next (nroff); } mcview_nroff_seq_free (&nroff); return ret; } /* --------------------------------------------------------------------------------------------- */ mcview_nroff_t * mcview_nroff_seq_new_num (WView * view, off_t lc_index) { mcview_nroff_t *nroff; nroff = g_try_malloc0 (sizeof (mcview_nroff_t)); if (nroff != NULL) { nroff->index = lc_index; nroff->view = view; mcview_nroff_seq_info (nroff); } return nroff; } /* --------------------------------------------------------------------------------------------- */ mcview_nroff_t * mcview_nroff_seq_new (WView * view) { return mcview_nroff_seq_new_num (view, (off_t) 0); } /* --------------------------------------------------------------------------------------------- */ void mcview_nroff_seq_free (mcview_nroff_t ** nroff) { if (nroff == NULL || *nroff == NULL) return; MC_PTR_FREE (*nroff); } /* --------------------------------------------------------------------------------------------- */ nroff_type_t mcview_nroff_seq_info (mcview_nroff_t * nroff) { int next, next2; if (nroff == NULL) return NROFF_TYPE_NONE; nroff->type = NROFF_TYPE_NONE; if (!mcview_nroff_get_char (nroff, &nroff->current_char, nroff->index)) return nroff->type; if (!mcview_get_byte (nroff->view, nroff->index + nroff->char_length, &next) || next != '\b') return nroff->type; if (!mcview_nroff_get_char (nroff, &next2, nroff->index + 1 + nroff->char_length)) return nroff->type; if (nroff->current_char == '_' && next2 == '_') { nroff->type = (nroff->prev_type == NROFF_TYPE_BOLD) ? NROFF_TYPE_BOLD : NROFF_TYPE_UNDERLINE; } else if (nroff->current_char == next2) { nroff->type = NROFF_TYPE_BOLD; } else if (nroff->current_char == '_') { nroff->current_char = next2; nroff->type = NROFF_TYPE_UNDERLINE; } else if (nroff->current_char == '+' && next2 == 'o') { /* ??? */ } return nroff->type; } /* --------------------------------------------------------------------------------------------- */ int mcview_nroff_seq_next (mcview_nroff_t * nroff) { if (nroff == NULL) return -1; nroff->prev_type = nroff->type; switch (nroff->type) { case NROFF_TYPE_BOLD: nroff->index += 1 + nroff->char_length; break; case NROFF_TYPE_UNDERLINE: nroff->index += 2; break; default: break; } nroff->index += nroff->char_length; mcview_nroff_seq_info (nroff); return nroff->current_char; } /* --------------------------------------------------------------------------------------------- */ int mcview_nroff_seq_prev (mcview_nroff_t * nroff) { int prev; off_t prev_index, prev_index2; if (nroff == NULL) return -1; nroff->prev_type = NROFF_TYPE_NONE; if (nroff->index == 0) return -1; prev_index = nroff->index - 1; while (prev_index != 0) { if (mcview_nroff_get_char (nroff, &nroff->current_char, prev_index)) break; prev_index--; } if (prev_index == 0) { nroff->index--; mcview_nroff_seq_info (nroff); return nroff->current_char; } prev_index--; if (!mcview_get_byte (nroff->view, prev_index, &prev) || prev != '\b') { nroff->index = prev_index; mcview_nroff_seq_info (nroff); return nroff->current_char; } prev_index2 = prev_index - 1; while (prev_index2 != 0) { if (mcview_nroff_get_char (nroff, &prev, prev_index)) break; prev_index2--; } nroff->index = (prev_index2 == 0) ? prev_index : prev_index2; mcview_nroff_seq_info (nroff); return nroff->current_char; } /* --------------------------------------------------------------------------------------------- */