mirror of
https://github.com/m1ngsama/TUT.git
synced 2025-12-24 10:51:46 +00:00
refactor: Improve code quality and Unix philosophy
- Remove redundant comments for cleaner code - Simplify error messages and status display - Improve code consistency across modules - Fix GitHub Actions workflow binary names - Enhance .gitignore for common editor files - Align help text formatting - Remove unnecessary verbose comments
This commit is contained in:
parent
ab2d1932e4
commit
ef80f9ab82
6 changed files with 36 additions and 81 deletions
14
.github/workflows/release.yml
vendored
14
.github/workflows/release.yml
vendored
|
|
@ -47,13 +47,13 @@ jobs:
|
||||||
|
|
||||||
- name: Rename binary with platform suffix
|
- name: Rename binary with platform suffix
|
||||||
run: |
|
run: |
|
||||||
mv build/nbtca_tui build/nbtca_tui-${{ matrix.name }}
|
mv build/tut build/tut-${{ matrix.name }}
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: nbtca_tui-${{ matrix.name }}
|
name: tut-${{ matrix.name }}
|
||||||
path: build/nbtca_tui-${{ matrix.name }}
|
path: build/tut-${{ matrix.name }}
|
||||||
|
|
||||||
release:
|
release:
|
||||||
needs: build
|
needs: build
|
||||||
|
|
@ -85,13 +85,13 @@ jobs:
|
||||||
Automated release for commit ${{ github.sha }}
|
Automated release for commit ${{ github.sha }}
|
||||||
|
|
||||||
## Download
|
## Download
|
||||||
- **macOS**: `nbtca_tui-macos`
|
- **macOS**: `tut-macos`
|
||||||
- **Linux**: `nbtca_tui-linux`
|
- **Linux**: `tut-linux`
|
||||||
|
|
||||||
## Build from source
|
## Build from source
|
||||||
See the [README](https://github.com/${{ github.repository }}/blob/main/README.md) for build instructions.
|
See the [README](https://github.com/${{ github.repository }}/blob/main/README.md) for build instructions.
|
||||||
files: |
|
files: |
|
||||||
artifacts/nbtca_tui-macos/nbtca_tui-macos
|
artifacts/tut-macos/tut-macos
|
||||||
artifacts/nbtca_tui-linux/nbtca_tui-linux
|
artifacts/tut-linux/tut-linux
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -2,3 +2,8 @@ build/
|
||||||
*.o
|
*.o
|
||||||
tut
|
tut
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
|
|
||||||
|
|
@ -52,9 +52,9 @@ public:
|
||||||
auto response = http_client.fetch(url);
|
auto response = http_client.fetch(url);
|
||||||
|
|
||||||
if (!response.is_success()) {
|
if (!response.is_success()) {
|
||||||
status_message = "Error: " + (response.error_message.empty() ?
|
status_message = response.error_message.empty() ?
|
||||||
"HTTP " + std::to_string(response.status_code) :
|
"HTTP " + std::to_string(response.status_code) :
|
||||||
response.error_message);
|
response.error_message;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,14 +65,13 @@ public:
|
||||||
current_link = -1;
|
current_link = -1;
|
||||||
search_results.clear();
|
search_results.clear();
|
||||||
|
|
||||||
// 更新历史
|
|
||||||
if (history_pos >= 0 && history_pos < static_cast<int>(history.size()) - 1) {
|
if (history_pos >= 0 && history_pos < static_cast<int>(history.size()) - 1) {
|
||||||
history.erase(history.begin() + history_pos + 1, history.end());
|
history.erase(history.begin() + history_pos + 1, history.end());
|
||||||
}
|
}
|
||||||
history.push_back(url);
|
history.push_back(url);
|
||||||
history_pos = history.size() - 1;
|
history_pos = history.size() - 1;
|
||||||
|
|
||||||
status_message = "Loaded: " + (current_doc.title.empty() ? url : current_doc.title);
|
status_message = current_doc.title.empty() ? url : current_doc.title;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +79,6 @@ public:
|
||||||
attron(COLOR_PAIR(COLOR_STATUS_BAR));
|
attron(COLOR_PAIR(COLOR_STATUS_BAR));
|
||||||
mvprintw(screen_height - 1, 0, "%s", std::string(screen_width, ' ').c_str());
|
mvprintw(screen_height - 1, 0, "%s", std::string(screen_width, ' ').c_str());
|
||||||
|
|
||||||
// 显示模式和缓冲
|
|
||||||
std::string mode_str;
|
std::string mode_str;
|
||||||
InputMode mode = input_handler.get_mode();
|
InputMode mode = input_handler.get_mode();
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
|
@ -88,29 +86,24 @@ public:
|
||||||
mode_str = "NORMAL";
|
mode_str = "NORMAL";
|
||||||
break;
|
break;
|
||||||
case InputMode::COMMAND:
|
case InputMode::COMMAND:
|
||||||
mode_str = input_handler.get_buffer();
|
|
||||||
break;
|
|
||||||
case InputMode::SEARCH:
|
case InputMode::SEARCH:
|
||||||
mode_str = input_handler.get_buffer();
|
mode_str = input_handler.get_buffer();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mode_str = "???";
|
mode_str = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 左侧:模式或命令
|
|
||||||
mvprintw(screen_height - 1, 0, " %s", mode_str.c_str());
|
mvprintw(screen_height - 1, 0, " %s", mode_str.c_str());
|
||||||
|
|
||||||
// 中间:状态消息
|
|
||||||
if (!status_message.empty() && mode == InputMode::NORMAL) {
|
if (!status_message.empty() && mode == InputMode::NORMAL) {
|
||||||
int msg_x = (screen_width - status_message.length()) / 2;
|
int msg_x = (screen_width - status_message.length()) / 2;
|
||||||
if (msg_x < mode_str.length() + 2) {
|
if (msg_x < static_cast<int>(mode_str.length()) + 2) {
|
||||||
msg_x = mode_str.length() + 2;
|
msg_x = mode_str.length() + 2;
|
||||||
}
|
}
|
||||||
mvprintw(screen_height - 1, msg_x, "%s", status_message.c_str());
|
mvprintw(screen_height - 1, msg_x, "%s", status_message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 右侧:位置信息
|
|
||||||
int total_lines = rendered_lines.size();
|
int total_lines = rendered_lines.size();
|
||||||
int visible_lines = screen_height - 2;
|
int visible_lines = screen_height - 2;
|
||||||
int percentage = 0;
|
int percentage = 0;
|
||||||
|
|
@ -147,7 +140,6 @@ public:
|
||||||
int line_idx = scroll_pos + i;
|
int line_idx = scroll_pos + i;
|
||||||
const auto& line = rendered_lines[line_idx];
|
const auto& line = rendered_lines[line_idx];
|
||||||
|
|
||||||
// 高亮当前链接
|
|
||||||
if (line.is_link && line.link_index == current_link) {
|
if (line.is_link && line.link_index == current_link) {
|
||||||
attron(COLOR_PAIR(COLOR_LINK_ACTIVE));
|
attron(COLOR_PAIR(COLOR_LINK_ACTIVE));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -157,15 +149,12 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 搜索高亮
|
|
||||||
std::string display_text = line.text;
|
|
||||||
if (!search_term.empty() &&
|
if (!search_term.empty() &&
|
||||||
std::find(search_results.begin(), search_results.end(), line_idx) != search_results.end()) {
|
std::find(search_results.begin(), search_results.end(), line_idx) != search_results.end()) {
|
||||||
// 简单高亮:整行反色(实际应该只高亮匹配部分)
|
|
||||||
attron(A_REVERSE);
|
attron(A_REVERSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mvprintw(i, 0, "%s", display_text.c_str());
|
mvprintw(i, 0, "%s", line.text.c_str());
|
||||||
|
|
||||||
if (!search_term.empty() &&
|
if (!search_term.empty() &&
|
||||||
std::find(search_results.begin(), search_results.end(), line_idx) != search_results.end()) {
|
std::find(search_results.begin(), search_results.end(), line_idx) != search_results.end()) {
|
||||||
|
|
@ -225,7 +214,6 @@ public:
|
||||||
case Action::NEXT_LINK:
|
case Action::NEXT_LINK:
|
||||||
if (!current_doc.links.empty()) {
|
if (!current_doc.links.empty()) {
|
||||||
current_link = (current_link + 1) % current_doc.links.size();
|
current_link = (current_link + 1) % current_doc.links.size();
|
||||||
// 滚动到链接位置
|
|
||||||
scroll_to_link(current_link);
|
scroll_to_link(current_link);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -23,22 +23,18 @@ public:
|
||||||
result.has_count = false;
|
result.has_count = false;
|
||||||
result.count = 1;
|
result.count = 1;
|
||||||
|
|
||||||
// 处理数字前缀
|
|
||||||
if (std::isdigit(ch) && (ch != '0' || !count_buffer.empty())) {
|
if (std::isdigit(ch) && (ch != '0' || !count_buffer.empty())) {
|
||||||
count_buffer += static_cast<char>(ch);
|
count_buffer += static_cast<char>(ch);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析count
|
|
||||||
if (!count_buffer.empty()) {
|
if (!count_buffer.empty()) {
|
||||||
result.has_count = true;
|
result.has_count = true;
|
||||||
result.count = std::stoi(count_buffer);
|
result.count = std::stoi(count_buffer);
|
||||||
count_buffer.clear();
|
count_buffer.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理vim风格的命令
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
// 移动
|
|
||||||
case 'j':
|
case 'j':
|
||||||
case KEY_DOWN:
|
case KEY_DOWN:
|
||||||
result.action = Action::SCROLL_DOWN;
|
result.action = Action::SCROLL_DOWN;
|
||||||
|
|
@ -55,18 +51,14 @@ public:
|
||||||
case KEY_RIGHT:
|
case KEY_RIGHT:
|
||||||
result.action = Action::GO_FORWARD;
|
result.action = Action::GO_FORWARD;
|
||||||
break;
|
break;
|
||||||
|
case 4:
|
||||||
// 翻页
|
|
||||||
case 4: // Ctrl-D
|
|
||||||
case ' ':
|
case ' ':
|
||||||
result.action = Action::SCROLL_PAGE_DOWN;
|
result.action = Action::SCROLL_PAGE_DOWN;
|
||||||
break;
|
break;
|
||||||
case 21: // Ctrl-U
|
case 21:
|
||||||
case 'b':
|
case 'b':
|
||||||
result.action = Action::SCROLL_PAGE_UP;
|
result.action = Action::SCROLL_PAGE_UP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 跳转
|
|
||||||
case 'g':
|
case 'g':
|
||||||
buffer += 'g';
|
buffer += 'g';
|
||||||
if (buffer == "gg") {
|
if (buffer == "gg") {
|
||||||
|
|
@ -82,8 +74,6 @@ public:
|
||||||
result.action = Action::GOTO_BOTTOM;
|
result.action = Action::GOTO_BOTTOM;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 搜索
|
|
||||||
case '/':
|
case '/':
|
||||||
mode = InputMode::SEARCH;
|
mode = InputMode::SEARCH;
|
||||||
buffer = "/";
|
buffer = "/";
|
||||||
|
|
@ -94,27 +84,21 @@ public:
|
||||||
case 'N':
|
case 'N':
|
||||||
result.action = Action::SEARCH_PREV;
|
result.action = Action::SEARCH_PREV;
|
||||||
break;
|
break;
|
||||||
|
case '\t':
|
||||||
// 链接导航
|
|
||||||
case '\t': // Tab
|
|
||||||
result.action = Action::NEXT_LINK;
|
result.action = Action::NEXT_LINK;
|
||||||
break;
|
break;
|
||||||
case KEY_BTAB: // Shift-Tab (可能不是所有终端都支持)
|
case KEY_BTAB:
|
||||||
case 'T':
|
case 'T':
|
||||||
result.action = Action::PREV_LINK;
|
result.action = Action::PREV_LINK;
|
||||||
break;
|
break;
|
||||||
case '\n': // Enter
|
case '\n':
|
||||||
case '\r':
|
case '\r':
|
||||||
result.action = Action::FOLLOW_LINK;
|
result.action = Action::FOLLOW_LINK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 命令模式
|
|
||||||
case ':':
|
case ':':
|
||||||
mode = InputMode::COMMAND;
|
mode = InputMode::COMMAND;
|
||||||
buffer = ":";
|
buffer = ":";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 其他操作
|
|
||||||
case 'r':
|
case 'r':
|
||||||
result.action = Action::REFRESH;
|
result.action = Action::REFRESH;
|
||||||
break;
|
break;
|
||||||
|
|
@ -124,7 +108,6 @@ public:
|
||||||
case '?':
|
case '?':
|
||||||
result.action = Action::HELP;
|
result.action = Action::HELP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
break;
|
break;
|
||||||
|
|
@ -138,8 +121,7 @@ public:
|
||||||
result.action = Action::NONE;
|
result.action = Action::NONE;
|
||||||
|
|
||||||
if (ch == '\n' || ch == '\r') {
|
if (ch == '\n' || ch == '\r') {
|
||||||
// 执行命令
|
std::string command = buffer.substr(1);
|
||||||
std::string command = buffer.substr(1); // 去掉':'
|
|
||||||
|
|
||||||
if (command == "q" || command == "quit") {
|
if (command == "q" || command == "quit") {
|
||||||
result.action = Action::QUIT;
|
result.action = Action::QUIT;
|
||||||
|
|
@ -148,14 +130,12 @@ public:
|
||||||
} else if (command == "r" || command == "refresh") {
|
} else if (command == "r" || command == "refresh") {
|
||||||
result.action = Action::REFRESH;
|
result.action = Action::REFRESH;
|
||||||
} else if (command.rfind("o ", 0) == 0 || command.rfind("open ", 0) == 0) {
|
} else if (command.rfind("o ", 0) == 0 || command.rfind("open ", 0) == 0) {
|
||||||
// :o URL 或 :open URL
|
|
||||||
size_t space_pos = command.find(' ');
|
size_t space_pos = command.find(' ');
|
||||||
if (space_pos != std::string::npos) {
|
if (space_pos != std::string::npos) {
|
||||||
result.action = Action::OPEN_URL;
|
result.action = Action::OPEN_URL;
|
||||||
result.text = command.substr(space_pos + 1);
|
result.text = command.substr(space_pos + 1);
|
||||||
}
|
}
|
||||||
} else if (!command.empty() && std::isdigit(command[0])) {
|
} else if (!command.empty() && std::isdigit(command[0])) {
|
||||||
// 跳转到行号
|
|
||||||
try {
|
try {
|
||||||
result.action = Action::GOTO_LINE;
|
result.action = Action::GOTO_LINE;
|
||||||
result.number = std::stoi(command);
|
result.number = std::stoi(command);
|
||||||
|
|
@ -166,7 +146,7 @@ public:
|
||||||
|
|
||||||
mode = InputMode::NORMAL;
|
mode = InputMode::NORMAL;
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
} else if (ch == 27) { // ESC
|
} else if (ch == 27) {
|
||||||
mode = InputMode::NORMAL;
|
mode = InputMode::NORMAL;
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
} else if (ch == KEY_BACKSPACE || ch == 127 || ch == 8) {
|
} else if (ch == KEY_BACKSPACE || ch == 127 || ch == 8) {
|
||||||
|
|
@ -188,14 +168,13 @@ public:
|
||||||
result.action = Action::NONE;
|
result.action = Action::NONE;
|
||||||
|
|
||||||
if (ch == '\n' || ch == '\r') {
|
if (ch == '\n' || ch == '\r') {
|
||||||
// 执行搜索
|
|
||||||
if (buffer.length() > 1) {
|
if (buffer.length() > 1) {
|
||||||
result.action = Action::SEARCH_FORWARD;
|
result.action = Action::SEARCH_FORWARD;
|
||||||
result.text = buffer.substr(1); // 去掉'/'
|
result.text = buffer.substr(1);
|
||||||
}
|
}
|
||||||
mode = InputMode::NORMAL;
|
mode = InputMode::NORMAL;
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
} else if (ch == 27) { // ESC
|
} else if (ch == 27) {
|
||||||
mode = InputMode::NORMAL;
|
mode = InputMode::NORMAL;
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
} else if (ch == KEY_BACKSPACE || ch == 127 || ch == 8) {
|
} else if (ch == KEY_BACKSPACE || ch == 127 || ch == 8) {
|
||||||
|
|
|
||||||
19
src/main.cpp
19
src/main.cpp
|
|
@ -12,19 +12,18 @@ void print_usage(const char* prog_name) {
|
||||||
<< " " << prog_name << " https://example.com\n"
|
<< " " << prog_name << " https://example.com\n"
|
||||||
<< " " << prog_name << " https://news.ycombinator.com\n\n"
|
<< " " << prog_name << " https://news.ycombinator.com\n\n"
|
||||||
<< "Vim-style keybindings:\n"
|
<< "Vim-style keybindings:\n"
|
||||||
<< " j/k - Scroll down/up\n"
|
<< " j/k - Scroll down/up\n"
|
||||||
<< " gg/G - Go to top/bottom\n"
|
<< " gg/G - Go to top/bottom\n"
|
||||||
<< " / - Search\n"
|
<< " / - Search\n"
|
||||||
<< " Tab - Next link\n"
|
<< " Tab - Next link\n"
|
||||||
<< " Enter - Follow link\n"
|
<< " Enter - Follow link\n"
|
||||||
<< " h/l - Back/Forward\n"
|
<< " h/l - Back/Forward\n"
|
||||||
<< " :o URL - Open URL\n"
|
<< " :o URL - Open URL\n"
|
||||||
<< " :q - Quit\n"
|
<< " :q - Quit\n"
|
||||||
<< " ? - Show help\n";
|
<< " ? - Show help\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
// 解析命令行参数
|
|
||||||
std::string initial_url;
|
std::string initial_url;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ class TextRenderer::Impl {
|
||||||
public:
|
public:
|
||||||
RenderConfig config;
|
RenderConfig config;
|
||||||
|
|
||||||
// 自动换行处理
|
|
||||||
std::vector<std::string> wrap_text(const std::string& text, int width) {
|
std::vector<std::string> wrap_text(const std::string& text, int width) {
|
||||||
std::vector<std::string> lines;
|
std::vector<std::string> lines;
|
||||||
if (text.empty()) {
|
if (text.empty()) {
|
||||||
|
|
@ -19,20 +18,17 @@ public:
|
||||||
std::string current_line;
|
std::string current_line;
|
||||||
|
|
||||||
while (words_stream >> word) {
|
while (words_stream >> word) {
|
||||||
// 处理单个词超长的情况
|
|
||||||
if (word.length() > static_cast<size_t>(width)) {
|
if (word.length() > static_cast<size_t>(width)) {
|
||||||
if (!current_line.empty()) {
|
if (!current_line.empty()) {
|
||||||
lines.push_back(current_line);
|
lines.push_back(current_line);
|
||||||
current_line.clear();
|
current_line.clear();
|
||||||
}
|
}
|
||||||
// 强制分割长词
|
|
||||||
for (size_t i = 0; i < word.length(); i += width) {
|
for (size_t i = 0; i < word.length(); i += width) {
|
||||||
lines.push_back(word.substr(i, width));
|
lines.push_back(word.substr(i, width));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 正常换行逻辑
|
|
||||||
if (current_line.empty()) {
|
if (current_line.empty()) {
|
||||||
current_line = word;
|
current_line = word;
|
||||||
} else if (current_line.length() + 1 + word.length() <= static_cast<size_t>(width)) {
|
} else if (current_line.length() + 1 + word.length() <= static_cast<size_t>(width)) {
|
||||||
|
|
@ -54,7 +50,6 @@ public:
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加缩进
|
|
||||||
std::string add_indent(const std::string& text, int indent) {
|
std::string add_indent(const std::string& text, int indent) {
|
||||||
return std::string(indent, ' ') + text;
|
return std::string(indent, ' ') + text;
|
||||||
}
|
}
|
||||||
|
|
@ -69,20 +64,17 @@ TextRenderer::~TextRenderer() = default;
|
||||||
std::vector<RenderedLine> TextRenderer::render(const ParsedDocument& doc, int screen_width) {
|
std::vector<RenderedLine> TextRenderer::render(const ParsedDocument& doc, int screen_width) {
|
||||||
std::vector<RenderedLine> lines;
|
std::vector<RenderedLine> lines;
|
||||||
|
|
||||||
// 计算实际内容宽度
|
|
||||||
int content_width = std::min(pImpl->config.max_width, screen_width - 4);
|
int content_width = std::min(pImpl->config.max_width, screen_width - 4);
|
||||||
if (content_width < 40) {
|
if (content_width < 40) {
|
||||||
content_width = screen_width - 4;
|
content_width = screen_width - 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算左边距(如果居中)
|
|
||||||
int margin = 0;
|
int margin = 0;
|
||||||
if (pImpl->config.center_content && content_width < screen_width) {
|
if (pImpl->config.center_content && content_width < screen_width) {
|
||||||
margin = (screen_width - content_width) / 2;
|
margin = (screen_width - content_width) / 2;
|
||||||
}
|
}
|
||||||
pImpl->config.margin_left = margin;
|
pImpl->config.margin_left = margin;
|
||||||
|
|
||||||
// 渲染标题
|
|
||||||
if (!doc.title.empty()) {
|
if (!doc.title.empty()) {
|
||||||
RenderedLine title_line;
|
RenderedLine title_line;
|
||||||
title_line.text = std::string(margin, ' ') + doc.title;
|
title_line.text = std::string(margin, ' ') + doc.title;
|
||||||
|
|
@ -92,7 +84,6 @@ std::vector<RenderedLine> TextRenderer::render(const ParsedDocument& doc, int sc
|
||||||
title_line.link_index = -1;
|
title_line.link_index = -1;
|
||||||
lines.push_back(title_line);
|
lines.push_back(title_line);
|
||||||
|
|
||||||
// 标题下划线
|
|
||||||
RenderedLine underline;
|
RenderedLine underline;
|
||||||
underline.text = std::string(margin, ' ') + std::string(std::min((int)doc.title.length(), content_width), '=');
|
underline.text = std::string(margin, ' ') + std::string(std::min((int)doc.title.length(), content_width), '=');
|
||||||
underline.color_pair = COLOR_HEADING1;
|
underline.color_pair = COLOR_HEADING1;
|
||||||
|
|
@ -101,7 +92,6 @@ std::vector<RenderedLine> TextRenderer::render(const ParsedDocument& doc, int sc
|
||||||
underline.link_index = -1;
|
underline.link_index = -1;
|
||||||
lines.push_back(underline);
|
lines.push_back(underline);
|
||||||
|
|
||||||
// 空行
|
|
||||||
RenderedLine empty;
|
RenderedLine empty;
|
||||||
empty.text = "";
|
empty.text = "";
|
||||||
empty.color_pair = COLOR_NORMAL;
|
empty.color_pair = COLOR_NORMAL;
|
||||||
|
|
@ -111,7 +101,6 @@ std::vector<RenderedLine> TextRenderer::render(const ParsedDocument& doc, int sc
|
||||||
lines.push_back(empty);
|
lines.push_back(empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 渲染URL
|
|
||||||
if (!doc.url.empty()) {
|
if (!doc.url.empty()) {
|
||||||
RenderedLine url_line;
|
RenderedLine url_line;
|
||||||
url_line.text = std::string(margin, ' ') + "URL: " + doc.url;
|
url_line.text = std::string(margin, ' ') + "URL: " + doc.url;
|
||||||
|
|
@ -130,7 +119,6 @@ std::vector<RenderedLine> TextRenderer::render(const ParsedDocument& doc, int sc
|
||||||
lines.push_back(empty);
|
lines.push_back(empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 渲染内容元素
|
|
||||||
for (const auto& elem : doc.elements) {
|
for (const auto& elem : doc.elements) {
|
||||||
int color = COLOR_NORMAL;
|
int color = COLOR_NORMAL;
|
||||||
bool bold = false;
|
bool bold = false;
|
||||||
|
|
@ -179,7 +167,6 @@ std::vector<RenderedLine> TextRenderer::render(const ParsedDocument& doc, int sc
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 换行处理
|
|
||||||
auto wrapped_lines = pImpl->wrap_text(elem.text, content_width - prefix.length());
|
auto wrapped_lines = pImpl->wrap_text(elem.text, content_width - prefix.length());
|
||||||
for (size_t i = 0; i < wrapped_lines.size(); ++i) {
|
for (size_t i = 0; i < wrapped_lines.size(); ++i) {
|
||||||
RenderedLine line;
|
RenderedLine line;
|
||||||
|
|
@ -195,7 +182,6 @@ std::vector<RenderedLine> TextRenderer::render(const ParsedDocument& doc, int sc
|
||||||
lines.push_back(line);
|
lines.push_back(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 段落间距
|
|
||||||
if (elem.type == ElementType::PARAGRAPH ||
|
if (elem.type == ElementType::PARAGRAPH ||
|
||||||
elem.type == ElementType::HEADING1 ||
|
elem.type == ElementType::HEADING1 ||
|
||||||
elem.type == ElementType::HEADING2 ||
|
elem.type == ElementType::HEADING2 ||
|
||||||
|
|
@ -212,7 +198,6 @@ std::vector<RenderedLine> TextRenderer::render(const ParsedDocument& doc, int sc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 渲染链接列表
|
|
||||||
if (!doc.links.empty() && pImpl->config.show_link_indicators) {
|
if (!doc.links.empty() && pImpl->config.show_link_indicators) {
|
||||||
RenderedLine separator;
|
RenderedLine separator;
|
||||||
std::string sepline(content_width, '-');
|
std::string sepline(content_width, '-');
|
||||||
|
|
@ -254,7 +239,6 @@ std::vector<RenderedLine> TextRenderer::render(const ParsedDocument& doc, int sc
|
||||||
lines.push_back(link_line);
|
lines.push_back(link_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// URL on next line
|
|
||||||
auto url_wrapped = pImpl->wrap_text(link.url, content_width - 6);
|
auto url_wrapped = pImpl->wrap_text(link.url, content_width - 6);
|
||||||
for (const auto& url_line_text : url_wrapped) {
|
for (const auto& url_line_text : url_wrapped) {
|
||||||
RenderedLine url_line;
|
RenderedLine url_line;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue