Manual pages: mcmcdiffmceditmcview

root/src/viewer/nroff.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. mcview_nroff_get_char
  2. mcview__get_nroff_real_len
  3. mcview_nroff_seq_new_num
  4. mcview_nroff_seq_new
  5. mcview_nroff_seq_free
  6. mcview_nroff_seq_info
  7. mcview_nroff_seq_next
  8. mcview_nroff_seq_prev

   1 /*
   2    Internal file viewer for the Midnight Commander
   3    Functions for searching in nroff-like view
   4 
   5    Copyright (C) 1994-2025
   6    Free Software Foundation, Inc.
   7 
   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
  19 
  20    This file is part of the Midnight Commander.
  21 
  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.
  26 
  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.
  31 
  32    You should have received a copy of the GNU General Public License
  33    along with this program.  If not, see <https://www.gnu.org/licenses/>.
  34  */
  35 
  36 #include <config.h>
  37 
  38 #include "lib/global.h"
  39 #include "lib/tty/tty.h"
  40 #include "lib/skin.h"
  41 #include "lib/charsets.h"
  42 
  43 #include "internal.h"
  44 
  45 /*** global variables ****************************************************************************/
  46 
  47 /*** file scope macro definitions ****************************************************************/
  48 
  49 /*** file scope type declarations ****************************************************************/
  50 
  51 /*** forward declarations (file scope functions) *************************************************/
  52 
  53 /*** file scope variables ************************************************************************/
  54 
  55 /* --------------------------------------------------------------------------------------------- */
  56 /*** file scope functions ************************************************************************/
  57 /* --------------------------------------------------------------------------------------------- */
  58 
  59 static gboolean
  60 mcview_nroff_get_char (mcview_nroff_t *nroff, int *ret_val, off_t nroff_index)
     /* [previous][next][first][last][top][bottom][index][help]  */
  61 {
  62     int c = 0;
  63 
  64     if (nroff->view->utf8)
  65     {
  66         if (!mcview_get_utf (nroff->view, nroff_index, &c, &nroff->char_length))
  67         {
  68             // we need got symbol in any case
  69             nroff->char_length = 1;
  70             if (!mcview_get_byte (nroff->view, nroff_index, &c) || !g_ascii_isprint (c))
  71                 return FALSE;
  72         }
  73     }
  74     else
  75     {
  76         nroff->char_length = 1;
  77         if (!mcview_get_byte (nroff->view, nroff_index, &c))
  78             return FALSE;
  79     }
  80 
  81     *ret_val = c;
  82 
  83     return g_unichar_isprint (c);
  84 }
  85 
  86 /* --------------------------------------------------------------------------------------------- */
  87 /*** public functions ****************************************************************************/
  88 /* --------------------------------------------------------------------------------------------- */
  89 
  90 int
  91 mcview__get_nroff_real_len (WView *view, off_t start, off_t length)
     /* [previous][next][first][last][top][bottom][index][help]  */
  92 {
  93     mcview_nroff_t *nroff;
  94     int ret = 0;
  95     off_t i = 0;
  96 
  97     if (!view->mode_flags.nroff)
  98         return 0;
  99 
 100     nroff = mcview_nroff_seq_new_num (view, start);
 101     if (nroff == NULL)
 102         return 0;
 103     while (i < length)
 104     {
 105         switch (nroff->type)
 106         {
 107         case NROFF_TYPE_BOLD:
 108             ret += nroff->char_length + 1;  // letter + '\b'
 109             break;
 110         case NROFF_TYPE_UNDERLINE:
 111             ret += 2;  // '_' + '\b'
 112             break;
 113         case NROFF_TYPE_BOLD_UNDERLINE:
 114             ret += 2 + nroff->char_length + 1;  // '_' + '\b' + letter + '\b'
 115             break;
 116         default:
 117             break;
 118         }
 119         i += nroff->char_length;
 120         mcview_nroff_seq_next (nroff);
 121     }
 122 
 123     mcview_nroff_seq_free (&nroff);
 124     return ret;
 125 }
 126 
 127 /* --------------------------------------------------------------------------------------------- */
 128 
 129 mcview_nroff_t *
 130 mcview_nroff_seq_new_num (WView *view, off_t lc_index)
     /* [previous][next][first][last][top][bottom][index][help]  */
 131 {
 132     mcview_nroff_t *nroff;
 133 
 134     nroff = g_try_malloc0 (sizeof (mcview_nroff_t));
 135     if (nroff != NULL)
 136     {
 137         nroff->index = lc_index;
 138         nroff->view = view;
 139         mcview_nroff_seq_info (nroff);
 140     }
 141     return nroff;
 142 }
 143 
 144 /* --------------------------------------------------------------------------------------------- */
 145 
 146 mcview_nroff_t *
 147 mcview_nroff_seq_new (WView *view)
     /* [previous][next][first][last][top][bottom][index][help]  */
 148 {
 149     return mcview_nroff_seq_new_num (view, (off_t) 0);
 150 }
 151 
 152 /* --------------------------------------------------------------------------------------------- */
 153 
 154 void
 155 mcview_nroff_seq_free (mcview_nroff_t **nroff)
     /* [previous][next][first][last][top][bottom][index][help]  */
 156 {
 157     if (nroff == NULL || *nroff == NULL)
 158         return;
 159     MC_PTR_FREE (*nroff);
 160 }
 161 
 162 /* --------------------------------------------------------------------------------------------- */
 163 
 164 nroff_type_t
 165 mcview_nroff_seq_info (mcview_nroff_t *nroff)
     /* [previous][next][first][last][top][bottom][index][help]  */
 166 {
 167     int next, next2, next3, next4;
 168 
 169     if (nroff == NULL)
 170         return NROFF_TYPE_NONE;
 171     nroff->type = NROFF_TYPE_NONE;
 172 
 173     if (!mcview_nroff_get_char (nroff, &nroff->current_char, nroff->index))
 174         return nroff->type;
 175 
 176     if (!mcview_get_byte (nroff->view, nroff->index + nroff->char_length, &next) || next != '\b')
 177         return nroff->type;
 178 
 179     if (!mcview_nroff_get_char (nroff, &next2, nroff->index + 1 + nroff->char_length))
 180         return nroff->type;
 181 
 182     if (nroff->current_char == '_'
 183         && mcview_get_byte (nroff->view, nroff->index + 2 + nroff->char_length, &next3)
 184         && next3 == '\b'
 185         && mcview_nroff_get_char (nroff, &next4, nroff->index + 2 + nroff->char_length + 1)
 186         && next2 == next4)
 187     {
 188         nroff->current_char = next2;
 189         nroff->type = NROFF_TYPE_BOLD_UNDERLINE;
 190     }
 191     else if (nroff->current_char == '_' && next2 == '_')
 192     {
 193         nroff->type =
 194             (nroff->prev_type == NROFF_TYPE_BOLD) ? NROFF_TYPE_BOLD : NROFF_TYPE_UNDERLINE;
 195     }
 196     else if (nroff->current_char == next2)
 197     {
 198         nroff->type = NROFF_TYPE_BOLD;
 199     }
 200     else if (nroff->current_char == '_')
 201     {
 202         nroff->current_char = next2;
 203         nroff->type = NROFF_TYPE_UNDERLINE;
 204     }
 205     return nroff->type;
 206 }
 207 
 208 /* --------------------------------------------------------------------------------------------- */
 209 
 210 int
 211 mcview_nroff_seq_next (mcview_nroff_t *nroff)
     /* [previous][next][first][last][top][bottom][index][help]  */
 212 {
 213     if (nroff == NULL)
 214         return -1;
 215 
 216     nroff->prev_type = nroff->type;
 217 
 218     switch (nroff->type)
 219     {
 220     case NROFF_TYPE_BOLD:
 221         nroff->index += nroff->char_length + 1;  // letter + '\b'
 222         break;
 223     case NROFF_TYPE_UNDERLINE:
 224         nroff->index += 2;  // '_' + '\b'
 225         break;
 226     case NROFF_TYPE_BOLD_UNDERLINE:
 227         nroff->index += 2 + nroff->char_length + 1;  // '_' + '\b' + letter + '\b'
 228         break;
 229     default:
 230         break;
 231     }
 232 
 233     nroff->index += nroff->char_length;
 234 
 235     mcview_nroff_seq_info (nroff);
 236     return nroff->current_char;
 237 }
 238 
 239 /* --------------------------------------------------------------------------------------------- */
 240 
 241 int
 242 mcview_nroff_seq_prev (mcview_nroff_t *nroff)
     /* [previous][next][first][last][top][bottom][index][help]  */
 243 {
 244     int prev;
 245     off_t prev_index, prev_index2;
 246 
 247     if (nroff == NULL)
 248         return -1;
 249 
 250     nroff->prev_type = NROFF_TYPE_NONE;
 251 
 252     if (nroff->index == 0)
 253         return -1;
 254 
 255     prev_index = nroff->index - 1;
 256 
 257     while (prev_index != 0)
 258     {
 259         if (mcview_nroff_get_char (nroff, &nroff->current_char, prev_index))
 260             break;
 261         prev_index--;
 262     }
 263     if (prev_index == 0)
 264     {
 265         nroff->index--;
 266         mcview_nroff_seq_info (nroff);
 267         return nroff->current_char;
 268     }
 269 
 270     prev_index--;
 271 
 272     if (!mcview_get_byte (nroff->view, prev_index, &prev) || prev != '\b')
 273     {
 274         nroff->index = prev_index;
 275         mcview_nroff_seq_info (nroff);
 276         return nroff->current_char;
 277     }
 278     prev_index2 = prev_index - 1;
 279 
 280     while (prev_index2 != 0)
 281     {
 282         if (mcview_nroff_get_char (nroff, &prev, prev_index))
 283             break;
 284         prev_index2--;
 285     }
 286 
 287     nroff->index = (prev_index2 == 0) ? prev_index : prev_index2;
 288     mcview_nroff_seq_info (nroff);
 289     return nroff->current_char;
 290 }
 291 
 292 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */