#include // 固定文字幅での禁則処理 namespace { // 行末禁則 const char * const not_end = "‘“(〔[{〈《「『【"; // 行頭禁則 const char * const not_begin_send = "・:;?!ヽヾゝゞ〃々ー―〜…‥" "っゃゅょッャュョぁぃぅぇぉァィゥェォ"; // 行頭禁則(可能であればぶら下げ) const char * const not_begin_hang = "、。,.’”)〕]}〉》」』】"; inline bool is_lead(unsigned char c) {return (((c >= 0x81) & (c <= 0x9F)) | ((c >= 0xE0) & (c <= 0xFC))) != 0;} inline unsigned short code(const char *str) {return (unsigned char(*str) << 8) | unsigned char(*(str + 1));} bool is_not_end(unsigned short c) { for (const char *s = not_end;*s;s += 2) if (c == code(s)) return true; return false; } bool is_not_begin_send(unsigned short c) { for (const char *s = not_begin_send;*s;s += 2) if (c == code(s)) return true; return false; } bool is_not_begin_hang(unsigned short c) { for (const char *s = not_begin_hang;*s;s += 2) if (c == code(s)) return true; return false; } bool is_not_begin(unsigned short c) {return is_not_begin_hang(c) || is_not_begin_send(c);} size_t get_endpart_size(const char *str,int &hang) { const char *s = str; for (;is_lead(*s);s += 2) { unsigned short c = code(s); if (is_not_begin_hang(c)) hang = 2; else if (is_not_begin_send(c)) hang = 0; else break; } return s - str; } // 連結文字列の長さ size_t get_part_size(const char *str,int &hang) { if (is_lead(*str)) { if (is_not_end(code(str))) return get_part_size(str + 2,hang) + 2; return get_endpart_size(str + 2,hang) + 2; } if (*str == '\0') return 0; const char *s = str + 1; bool flag_space = false; for (;*s;s++) { if (is_lead(*s)) return get_endpart_size(s,hang) + (s - str); if (*s == '\n') break; if ((*s == ' ') | (*s == '\t')) { flag_space = true; hang++; } else if (flag_space) break; } return s - str; } }// anonymous namespace // 禁則処理済み文字列の取得 void kinsoku_string(std::string &dest,const char *text,size_t line_size) { dest.clear(); size_t line_pos = 0; const char *s = text; while (*s) { if (*s == '\n') { dest += '\n'; s++; line_pos = 0; continue; } int hang = 0; size_t size = get_part_size(s,hang); if (line_pos == 0 || line_pos + size <= line_size + hang) { dest.append(s,size); line_pos += size; } else { (dest += '\n').append(s,size); line_pos = size; } s += size; } }