#include #include #include #include #include #include #define DEFAULT_PARAGRAPH_WIDTH 160 static void indent( struct b_paragraph_format *format, struct b_tty *tty, unsigned int margin) { unsigned int x = 0; while (x < margin) { b_tty_puts(tty, 0, " "); x++; } } static unsigned int extract_line( const char **sp, unsigned int line_length, b_string *out, struct b_paragraph_format *format) { const char *start = *sp; while (isspace(*start) || *start == '\n') { start++; } if (!*start) { return 0; } const char *end = NULL; unsigned int delta = 0; unsigned int i; for (i = 0; start[i]; i++) { if (start[i] == '\033') { while (start[i] && !isalpha(start[i])) { delta++; i++; } delta++; } if (start[i] == '[') { if (start[i + 1] == '[') { delta++; i++; continue; } while (start[i] && start[i] != ']') { i++; delta++; } delta++; } if (!isspace(start[i]) && start[i] != '\n') { continue; } if ((i - delta) >= line_length) { break; } end = &start[i]; if (start[i] == '\n') { break; } } if (start[i] == '\0' && (i - delta) < line_length) { end = NULL; } unsigned int len; if (end) { len = end - start; } else { len = strlen(start); } b_string_insert_cstrn(out, start, len, B_NPOS); *sp = end; return len; } static b_status print_paragraph_tty( const char *str, struct b_tty *tty, struct b_paragraph_format *format) { unsigned int w = 0, h = 0; b_tty_get_dimensions(tty, &w, &h); if (!w) { w = DEFAULT_PARAGRAPH_WIDTH; } unsigned int left_margin = format->p_left_margin; unsigned int line_length = format->p_line_length; if (format->p_left_margin + format->p_right_margin >= w) { return B_SUCCESS; } unsigned int page_width = w - format->p_left_margin - format->p_right_margin; if (page_width < line_length || line_length == 0) { line_length = page_width; } if (!(format->p_flags & B_PARAGRAPH_DONT_INDENT_FIRST_LINE)) { indent(format, tty, left_margin); } b_string *line = b_string_create(); bool need_indent = false; while (str) { if (*str == '\n') { if (format->p_flags & B_PARAGRAPH_DOUBLE_LINE_BREAK) { b_tty_putc(tty, 0, '\n'); } str++; need_indent = true; while (*str == '\n') { if (format->p_flags & B_PARAGRAPH_MULTI_LINE_BREAK) { b_tty_putc(tty, 0, '\n'); } str++; } } b_string_clear(line); unsigned int this_line = extract_line(&str, line_length, line, format); if (this_line == 0) { break; } if (need_indent) { indent(format, tty, left_margin); } b_tty_puts(tty, 0, b_string_ptr(line)); b_tty_putc(tty, 0, '\n'); need_indent = true; } b_string_unref(line); return B_SUCCESS; } static b_status print_paragraph_file( const char *str, FILE *fp, struct b_paragraph_format *format) { return B_SUCCESS; } b_status b_print_paragraph( const char *str, struct b_tty *fp, struct b_paragraph_format *format) { return print_paragraph_tty(str, fp, format); }