#include "print.h" #include #include #include #include #include #include #define DEFAULT_PARAGRAPH_WIDTH 160 static void indent( struct b_paragraph_format *format, FILE *fp, unsigned int margin, bool tty) { unsigned int x = 0; while (x < margin) { fputs(" ", fp); 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, FILE *fp, struct b_paragraph_format *format) { unsigned int w = 0, h = 0; z__b_stream_dimensions(fp, &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, fp, left_margin, true); } b_string *line = b_string_create(); bool need_indent = false; while (str) { if (*str == '\n') { if (format->p_flags & B_PARAGRAPH_DOUBLE_LINE_BREAK) { fputc('\n', fp); } str++; need_indent = true; while (*str == '\n') { if (format->p_flags & B_PARAGRAPH_MULTI_LINE_BREAK) { fputc('\n', fp); } 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, fp, left_margin, false); } b_fputs(b_string_ptr(line), fp); fputc('\n', fp); need_indent = true; } b_string_release(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, FILE *fp, struct b_paragraph_format *format) { if (z__b_stream_is_tty(fp)) { return print_paragraph_tty(str, fp, format); } return print_paragraph_tty(str, fp, format); }