mirror of
https://github.com/js0ny/dotfiles.git
synced 2025-12-21 08:43:00 +00:00
feat(pdf2zh): pdf2zh podman definition and config
This commit is contained in:
parent
8cf2f0af5e
commit
5b546eff0d
10 changed files with 329 additions and 63 deletions
|
|
@ -3,13 +3,20 @@ return {
|
|||
event = "BufRead",
|
||||
-- lazy = false,
|
||||
version = false, -- Set this to "*" to always pull the latest release version, or set it to false to update to the latest code changes.
|
||||
---@module "avante"
|
||||
---@type avante.Config
|
||||
opts = {
|
||||
provider = "openrouter",
|
||||
|
||||
-- add any opts here
|
||||
-- for example
|
||||
providers = {
|
||||
openai = {
|
||||
endpoint = "https://openrouter.ai/v1",
|
||||
model = "x-ai/grok-code-fast-1",
|
||||
---@type AvanteProvider
|
||||
openrouter = {
|
||||
__inherited_from = "openai",
|
||||
endpoint = "https://openrouter.ai/api/v1",
|
||||
model = "anthropic/claude-sonnet-4.5",
|
||||
api_key_name = "OPENROUTER_API_KEY",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
235
home/dot_config/pdf2zh/config.v3.toml.tmpl
Normal file
235
home/dot_config/pdf2zh/config.v3.toml.tmpl
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
config_file = "null"
|
||||
report_interval = 0.2
|
||||
siliconflowfree = false
|
||||
openai = false
|
||||
aliyundashscope = false
|
||||
google = false
|
||||
bing = false
|
||||
deepl = false
|
||||
deepseek = false
|
||||
ollama = false
|
||||
xinference = false
|
||||
azureopenai = false
|
||||
modelscope = false
|
||||
zhipu = false
|
||||
siliconflow = false
|
||||
tencentmechinetranslation = false
|
||||
gemini = false
|
||||
azure = false
|
||||
anythingllm = false
|
||||
dify = false
|
||||
grok = false
|
||||
groq = false
|
||||
qwenmt = false
|
||||
openaicompatible = true
|
||||
claudecode = false
|
||||
|
||||
[basic]
|
||||
input_files = []
|
||||
debug = false
|
||||
gui = false
|
||||
warmup = false
|
||||
generate_offline_assets = "null"
|
||||
restore_offline_assets = "null"
|
||||
version = false
|
||||
|
||||
[translation]
|
||||
min_text_length = 5
|
||||
rpc_doclayout = "null"
|
||||
lang_in = "en"
|
||||
lang_out = "zh-CN"
|
||||
output = "null"
|
||||
qps = 4
|
||||
ignore_cache = false
|
||||
custom_system_prompt = "null"
|
||||
glossaries = "null"
|
||||
save_auto_extracted_glossary = false
|
||||
pool_max_workers = "null"
|
||||
no_auto_extract_glossary = false
|
||||
primary_font_family = "null"
|
||||
|
||||
[pdf]
|
||||
pages = "null"
|
||||
no_dual = false
|
||||
no_mono = false
|
||||
formular_font_pattern = "null"
|
||||
formular_char_pattern = "null"
|
||||
split_short_lines = false
|
||||
short_line_split_factor = 0.8
|
||||
skip_clean = false
|
||||
dual_translate_first = false
|
||||
disable_rich_text_translate = false
|
||||
enhance_compatibility = false
|
||||
use_alternating_pages_dual = false
|
||||
watermark_output_mode = "no_watermark"
|
||||
max_pages_per_part = "null"
|
||||
translate_table_text = true
|
||||
skip_scanned_detection = false
|
||||
ocr_workaround = false
|
||||
auto_enable_ocr_workaround = false
|
||||
only_include_translated_page = false
|
||||
no_merge_alternating_line_numbers = false
|
||||
no_remove_non_formula_lines = false
|
||||
non_formula_line_iou_threshold = 0.9
|
||||
figure_table_protection_threshold = 0.9
|
||||
skip_formula_offset_calculation = false
|
||||
|
||||
[gui_settings]
|
||||
share = false
|
||||
auth_file = "null"
|
||||
welcome_page = "null"
|
||||
enabled_services = "null"
|
||||
disable_gui_sensitive_input = false
|
||||
disable_config_auto_save = false
|
||||
server_port = 7860
|
||||
ui_lang = "en"
|
||||
|
||||
[siliconflowfree_detail]
|
||||
translate_engine_type = "SiliconFlowFree"
|
||||
support_llm = "yes"
|
||||
|
||||
[openai_detail]
|
||||
translate_engine_type = "OpenAI"
|
||||
support_llm = "yes"
|
||||
openai_model = "gpt-4o-mini"
|
||||
openai_base_url = "null"
|
||||
openai_api_key = "null"
|
||||
openai_timeout = "null"
|
||||
openai_temperature = "null"
|
||||
openai_reasoning_effort = "null"
|
||||
openai_enable_json_mode = "null"
|
||||
openai_send_temprature = "null"
|
||||
openai_send_reasoning_effort = "null"
|
||||
|
||||
[aliyundashscope_detail]
|
||||
translate_engine_type = "AliyunDashScope"
|
||||
support_llm = "yes"
|
||||
aliyun_dashscope_model = "qwen-plus-latest"
|
||||
aliyun_dashscope_base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
||||
aliyun_dashscope_api_key = "null"
|
||||
aliyun_dashscope_timeout = "500"
|
||||
aliyun_dashscope_temperature = "0.0"
|
||||
aliyun_dashscope_send_temperature = "null"
|
||||
aliyun_dashscope_enable_json_mode = "null"
|
||||
|
||||
[deepl_detail]
|
||||
translate_engine_type = "DeepL"
|
||||
deepl_auth_key = "null"
|
||||
|
||||
[deepseek_detail]
|
||||
translate_engine_type = "DeepSeek"
|
||||
support_llm = "yes"
|
||||
deepseek_model = "deepseek-chat"
|
||||
deepseek_api_key = "null"
|
||||
deepseek_enable_json_mode = "null"
|
||||
|
||||
[ollama_detail]
|
||||
translate_engine_type = "Ollama"
|
||||
support_llm = "yes"
|
||||
ollama_model = "gemma2"
|
||||
ollama_host = "http://localhost:11434"
|
||||
num_predict = 2000
|
||||
|
||||
[xinference_detail]
|
||||
translate_engine_type = "Xinference"
|
||||
support_llm = "yes"
|
||||
xinference_model = "gemma-2-it"
|
||||
xinference_host = "null"
|
||||
|
||||
[azureopenai_detail]
|
||||
translate_engine_type = "AzureOpenAI"
|
||||
support_llm = "yes"
|
||||
azure_openai_model = "gpt-4o-mini"
|
||||
azure_openai_base_url = "null"
|
||||
azure_openai_api_key = "null"
|
||||
azure_openai_api_version = "2024-06-01"
|
||||
|
||||
[modelscope_detail]
|
||||
translate_engine_type = "ModelScope"
|
||||
support_llm = "yes"
|
||||
modelscope_model = "Qwen/Qwen2.5-32B-Instruct"
|
||||
modelscope_api_key = "null"
|
||||
modelscope_enable_json_mode = "null"
|
||||
|
||||
[zhipu_detail]
|
||||
translate_engine_type = "Zhipu"
|
||||
support_llm = "yes"
|
||||
zhipu_model = "glm-4-flash"
|
||||
zhipu_api_key = "null"
|
||||
zhipu_enable_json_mode = "null"
|
||||
|
||||
[siliconflow_detail]
|
||||
translate_engine_type = "SiliconFlow"
|
||||
support_llm = "yes"
|
||||
siliconflow_base_url = "https://api.siliconflow.cn/v1"
|
||||
siliconflow_model = "Qwen/Qwen2.5-7B-Instruct"
|
||||
siliconflow_api_key = "null"
|
||||
siliconflow_enable_thinking = false
|
||||
siliconflow_send_enable_thinking_param = false
|
||||
|
||||
[tencentmechinetranslation_detail]
|
||||
translate_engine_type = "TencentMechineTranslation"
|
||||
tencentcloud_secret_id = "null"
|
||||
tencentcloud_secret_key = "null"
|
||||
|
||||
[gemini_detail]
|
||||
translate_engine_type = "Gemini"
|
||||
support_llm = "yes"
|
||||
gemini_model = "gemini-1.5-flash"
|
||||
gemini_api_key = "null"
|
||||
gemini_enable_json_mode = "null"
|
||||
|
||||
[azure_detail]
|
||||
translate_engine_type = "Azure"
|
||||
azure_endpoint = "https://api.translator.azure.cn"
|
||||
azure_api_key = "null"
|
||||
|
||||
[anythingllm_detail]
|
||||
translate_engine_type = "AnythingLLM"
|
||||
anythingllm_url = "null"
|
||||
anythingllm_apikey = "null"
|
||||
|
||||
[dify_detail]
|
||||
translate_engine_type = "Dify"
|
||||
dify_url = "null"
|
||||
dify_apikey = "null"
|
||||
|
||||
[grok_detail]
|
||||
translate_engine_type = "Grok"
|
||||
support_llm = "yes"
|
||||
grok_model = "grok-2-1212"
|
||||
grok_api_key = "null"
|
||||
grok_enable_json_mode = "null"
|
||||
|
||||
[groq_detail]
|
||||
translate_engine_type = "Groq"
|
||||
support_llm = "yes"
|
||||
groq_model = "llama-3-3-70b-versatile"
|
||||
groq_api_key = "null"
|
||||
groq_enable_json_mode = "null"
|
||||
|
||||
[qwenmt_detail]
|
||||
translate_engine_type = "QwenMt"
|
||||
support_llm = "no"
|
||||
qwenmt_model = "qwen-mt-plus"
|
||||
qwenmt_base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
||||
qwenmt_api_key = "null"
|
||||
ali_domains = "This sentence is extracted from a scientific paper. When translating, please pay close attention to the use of specialized troubleshooting terminologies and adhere to scientific sentence structures to maintain the technical rigor and precision of the original text."
|
||||
|
||||
[openaicompatible_detail]
|
||||
translate_engine_type = "OpenAICompatible"
|
||||
support_llm = "yes"
|
||||
openai_compatible_model = "google/gemini-2.5-flash"
|
||||
openai_compatible_base_url = "https://openrouter.ai/"
|
||||
openai_compatible_api_key = {{- "secrets/OPENROUTER_API_KEY.age" | include | decrypt | trim | quote -}}
|
||||
openai_compatible_timeout = "5"
|
||||
openai_compatible_temperature = "50"
|
||||
openai_compatible_reasoning_effort = "low"
|
||||
openai_compatible_send_temperature = false
|
||||
openai_compatible_send_reasoning_effort = false
|
||||
openai_compatible_enable_json_mode = false
|
||||
|
||||
[claudecode_detail]
|
||||
translate_engine_type = "ClaudeCode"
|
||||
claude_code_path = "claude"
|
||||
claude_code_model = "sonnet"
|
||||
|
|
@ -1,18 +1,3 @@
|
|||
-- ~/.config/yazi/init.lua
|
||||
-- function Linemode:size_and_mtime()
|
||||
-- local time = math.floor(self._file.cha.mtime or 0)
|
||||
-- if time == 0 then
|
||||
-- time = ""
|
||||
-- elseif os.date("%Y", time) == os.date("%Y") then
|
||||
-- time = os.date("%b %d %H:%M", time)
|
||||
-- else
|
||||
-- time = os.date("%b %d %Y", time)
|
||||
-- end
|
||||
--
|
||||
-- local size = self._file:size()
|
||||
-- return string.format("%s %s", size and ya.readable_size(size) or "-", time)
|
||||
-- end
|
||||
--
|
||||
-- -- require("dual-pane"):setup({ enabled = true })
|
||||
-- require("starship"):setup()
|
||||
require("yaziline"):setup()
|
||||
require("starship"):setup()
|
||||
require("git"):setup()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
// $DOTFILES/tools/zed/settings.json
|
||||
// Date: 2025-01-25
|
||||
// Author: js0ny
|
||||
// Description: Zed settings (jsonc)
|
||||
// vim:ft=jsonc
|
||||
|
||||
// Location:
|
||||
// GNU/Linux: ~/.config/zed/settings.json
|
||||
|
|
@ -44,7 +42,7 @@
|
|||
"dock": "right"
|
||||
},
|
||||
"edit_predictions": {
|
||||
"disabled_globs": ["*.bean", "*.env"],
|
||||
"disabled_globs": ["*.bean", "*.env", "secrets.yaml"],
|
||||
// "mode": "eager_preview",
|
||||
"copilot": {
|
||||
"proxy": null,
|
||||
|
|
@ -75,10 +73,10 @@
|
|||
},
|
||||
"dock": "bottom",
|
||||
"env": {
|
||||
"EDITOR": "zeditor"
|
||||
"EDITOR": "zeditor --wait"
|
||||
},
|
||||
"shell": {
|
||||
"program": "fish"
|
||||
"program": "zsh"
|
||||
},
|
||||
"option_as_meta": true
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
openrouter_api: ENC[AES256_GCM,data:ceu+FlTNrNoS56rHL9bdGjODfPBYnBd1GL97BgpmLvHz8q2KMXMvGofMTyZVGsLs1BEq4scjr+HN9r52tozLxeVWzkVfumcUMA==,iv:zT2vT94zAoKoutl58pbeOVqHm5nPmoMrA7wlZQcYVLs=,tag:+gS9EPcmfANCUipbeiAi0Q==,type:str]
|
||||
tavily_api: ENC[AES256_GCM,data:blrxGOW/kcTbR2taeWeadhrzdtZK5ete4+0KE6yrJi3ibaMkkCGa05M=,iv:v4oh8/lA2q6l60By3H6RDXqbmBUya2W5sYxX8vDkz1c=,tag:8vwSl1zQnG5/fWDOhp9eHQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age1mcvqpg39t32ll684r4m2l8j0l9zag6endg0h6zjw8svkgdwc4pjqkk5fvj
|
||||
|
|
@ -19,7 +20,7 @@ sops:
|
|||
c3ZZQlRrZDhtT2NFM0lnZTUxWmptQjgK5lZBkR5oSpb90oa+LWinEnvcmdPTF6wP
|
||||
Q1gJoVoT/krUu22VSTOj/ojKEzS6uamZnJkMBhH31f1w2j4TEtY5Lw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-11-03T09:13:13Z"
|
||||
mac: ENC[AES256_GCM,data:1bZT8E/M7CQgfshQV1LKJAqWcyoYomG29y7zSp7THZ9lwA4+FVpBNXV1HLQru4CMs3N1pq8g1ww6KxtGZ92pUo+JxtRdT9GxzqJenCp2qzSo5d2ws5fFvvjLnOtoPcqXlMTchECeA3K/emwbmIfjCH63D5STZmBz7+dNbx5PY20=,iv:Wcv6PNwroQawHkjJpspN5mM0b+PZG5BQTP9jOKH0OTQ=,tag:N/d/O/zbVkkH8kZdlkZErQ==,type:str]
|
||||
lastmodified: "2025-11-08T13:02:24Z"
|
||||
mac: ENC[AES256_GCM,data:QtK4Eg9DLb2TK1M1kzIsyJs4p7pUBeslGTjDxjdzatXcst2AyCKV3f0vc3bPPyE7WkSx51B9I9YGaRq/GNMIH5o16AcVwd1VNTTI5kEO5p+4RJywO1eR+DXidsCIFPAA5Rgh3lJIxdUCcDucZ5o/bPWzbDelrb+/RD4X1VozPD4=,iv:TOmgT3EyAENFIA7JxgkZMk7ZYUKnWrVEH7WL9Dg3fnw=,tag:po0WBC5dze20F5x/f47WqQ==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.11.0
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
{...}: let
|
||||
editFzfPosix = ''
|
||||
edit-fzf() {
|
||||
# 1. Declare a variable that is local to the function.
|
||||
local _file
|
||||
|
||||
if command -v fd >/dev/null 2>&1; then
|
||||
_file=$(fd --type f | fzf --height 40% --reverse -1 -q "$1")
|
||||
_file=$(fd --type f --exclude '*.lock' | fzf --height 40% --reverse -1 -q "$1")
|
||||
else
|
||||
# Fallback to 'find'
|
||||
_file=$(find . -type f | fzf --height 40% --reverse -1 -q "$1")
|
||||
_file=$(find . -type f ! -name '*.lock' | fzf --height 40% --reverse -1 -q "$1")
|
||||
fi
|
||||
|
||||
# In POSIX shell, if fzf is cancelled (Esc/Ctrl-C),
|
||||
|
|
@ -34,9 +33,9 @@ in {
|
|||
set -l file
|
||||
|
||||
if command -q fd
|
||||
set file (fd --type f | fzf --height 40% --reverse -1 -q "$argv[1]")
|
||||
set file (fd --type f --exclude '*.lock' | fzf --height 40% --reverse -1 -q "$argv[1]")
|
||||
else
|
||||
set file (find . -type f | fzf --height 40% --reverse -1 -q "$argv[1]")
|
||||
set file (find . -type f ! -name '*.lock' | fzf --height 40% --reverse -1 -q "$argv[1]")
|
||||
end
|
||||
|
||||
set -l fzf_status $status
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{pkgs, ...}: {
|
||||
home.packages = [pkgs.libreoffice];
|
||||
home.file.".local/share/kio/servicemenus/office2pdf.desktop" = {
|
||||
enable = true;
|
||||
executable = true;
|
||||
text = ''
|
||||
[Desktop Entry]
|
||||
Type=Service
|
||||
|
|
|
|||
52
nixcfgs/users/js0ny/programs/pdf2zh.nix
Normal file
52
nixcfgs/users/js0ny/programs/pdf2zh.nix
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{pkgs, ...}: let
|
||||
imageTag = "ghcr.io/pdfmathtranslate/pdfmathtranslate-next";
|
||||
# version = "2.6.4";
|
||||
pdf2zhRunner = pkgs.writeShellScriptBin "pdf2zh" ''
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
IMAGE_TAG="${imageTag}"
|
||||
|
||||
if ! podman image exists "$IMAGE_TAG"; then
|
||||
echo "[pdf2zh] Pulling image $IMAGE_TAG ..."
|
||||
podman pull "$IMAGE_TAG"
|
||||
fi
|
||||
|
||||
podman run --rm -it \
|
||||
-p 7860:7860 \
|
||||
-v "$(pwd):/data" \
|
||||
-w /data \
|
||||
"$IMAGE_TAG" "pdf2zh" "$@"
|
||||
'';
|
||||
descEn = "PDF scientific paper translation with preserved formats";
|
||||
descZh = "基于 AI 完整保留排版的 PDF 文档全文双语翻译";
|
||||
in {
|
||||
services.podman.enable = true;
|
||||
|
||||
# Declare an image, do not instantiate as a container
|
||||
services.podman.images.pdf2zh = {
|
||||
image = imageTag;
|
||||
description = " ${descEn} - ${descZh},支持 Google/DeepL/Ollama/OpenAI 等服务,提供 CLI/GUI/Docker";
|
||||
};
|
||||
|
||||
home.packages = [pdf2zhRunner];
|
||||
|
||||
home.file.".local/share/kio/servicemenus/pdf2zh.desktop" = {
|
||||
enable = true;
|
||||
executable = true;
|
||||
text = ''
|
||||
[Desktop Entry]
|
||||
Type=Service
|
||||
MimeType=application/pdf;
|
||||
Actions=translateToZh
|
||||
Icon=translate
|
||||
X-KDE-Priority=TopLevel
|
||||
X-KDE-StartupNotify=false
|
||||
|
||||
[Desktop Action translateToZh]
|
||||
Name=翻译为中文
|
||||
Icon=translate
|
||||
Exec=pdf2zh --openaicompatible "%f"
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -1,27 +1,28 @@
|
|||
{config, ...}: {
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
home.packages = with pkgs; [
|
||||
sops
|
||||
];
|
||||
sops = {
|
||||
# enable = true;
|
||||
defaultSopsFile = ../../secrets/secrets.yaml;
|
||||
defaultSopsFile = ../../../secrets/secrets.yaml;
|
||||
age.keyFile = "${config.xdg.configHome}/sops/age/keys.txt";
|
||||
age.generateKey = true;
|
||||
secrets = {
|
||||
"OPENROUTER_API_KEY" = {
|
||||
key = "openrouter_api";
|
||||
};
|
||||
"TAVILY_API_KEY" = {
|
||||
key = "tavily_api";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# home.sessionVariables = {
|
||||
# OPENROUTER_API_KEY = config.sops.secrets."OPENROUTER_API_KEY".path;
|
||||
# };
|
||||
|
||||
systemd.user.services.sops-envvar = {
|
||||
Unit.Description = "[sops-envvar] Auto-source environment variables defined via sops-nix";
|
||||
Service = {
|
||||
ExecStart = pkgs.writeShellScript "start" ''
|
||||
export OPENROUTER_API_KEY=$(cat ${config.sops.secrets."OPENROUTER_API_KEY".path})
|
||||
'';
|
||||
};
|
||||
Install.WantedBy = ["default.target"];
|
||||
home.sessionVariables = {
|
||||
OPENROUTER_API_KEY = "$(cat ${config.sops.secrets."OPENROUTER_API_KEY".path})";
|
||||
TAVILY_API_KEY = "$(cat ${config.sops.secrets."TAVILY_API_KEY".path})";
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
./programs/libreoffice.nix
|
||||
./programs/nvim.nix
|
||||
./programs/ollama.nix
|
||||
./programs/sops.nix
|
||||
./programs/pdf2zh.nix
|
||||
|
||||
# Desktop Linux
|
||||
./programs/desktop/plasma.nix
|
||||
|
|
@ -64,21 +66,5 @@
|
|||
rose-pine-cursor
|
||||
];
|
||||
|
||||
sops = {
|
||||
# enable = true;
|
||||
defaultSopsFile = ../../secrets/secrets.yaml;
|
||||
age.keyFile = "${config.xdg.configHome}/sops/age/keys.txt";
|
||||
age.generateKey = true;
|
||||
secrets = {
|
||||
"OPENROUTER_API_KEY" = {
|
||||
key = "openrouter_api";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
home.sessionVariables = {
|
||||
OPENROUTER_API_KEY = "$(cat ${config.sops.secrets."OPENROUTER_API_KEY".path})";
|
||||
};
|
||||
|
||||
home.stateVersion = "25.05";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue