杂谈 #Java脚本
因本人英语不好在使用Obsidian时,一些插件的设置英文多令人头痛。故有写一个的翻译插件介绍和设置脚本的想法。看到有些前人写的一下翻译方法,简直惨目忍睹。竟然要手动。这个应该写好到只需要一键就可以汉化的地步吗?
好吧。我承认这有些难度。翻译引擎就用有道的吧。我觉得它对专业名词的翻译准确度还是很高的。
- 提取main.js中需要的词句
- 使用有道API来翻译并生成对应的文件
- 使用Quicker的插件一键替换
这里不想详细写过程了,直接贴代码吧。以后有空再整合。
main.js处理代码:(用了FastJson里面的工具,需要导入)- import com.alibaba.fastjson.JSON;
- import java.io.*;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- /**
- * @author ShuangLian
- * @date 2022/7/4 1:07
- */
- public class test {
- public static void main(String[] args) throws IOException {
- // 需要翻译的插件对应的main.js文件
- File file = new File("C:\\Users\\91324\\Documents\\Projects\\IdeaProjects\\Test-demo\\src\\test\\java\\cn\\lian\\main.js");
- System.out.println(file.getAbsolutePath());
- FileInputStream stream = new FileInputStream(file);
- InputStreamReader reader = new InputStreamReader(stream);
- BufferedReader bufferedReader = new BufferedReader(reader);
- LinkedList<String> list = new LinkedList<>();
- String line;
- while ((line = bufferedReader.readLine()) != null) {
- // 匹配要翻译的部分
- String s_setName = "setName\\([^\\)]+\\)";
- String s_addOption = "addOption\\([^\\)]+\\)";
- String s_setDesc = "setDesc\\([^\\)]+\\)*"\\)";
- String s_name = "name: ".*",";
- // 使用正则查找匹配
- List<String> linkedList;
- if ((linkedList = find(s_setName, line)).size() != 0) {
- for (String s : linkedList) {
- list.add(s.substring(9, s.length() - 2));
- }
- }
- if ((linkedList = find(s_setDesc, line)).size() != 0) {
- for (String s : linkedList) {
- list.add(s.substring(9, s.length() - 2));
- }
- }
- if ((linkedList = find(s_addOption, line)).size() != 0) {
- for (String ss : linkedList) {
- String substring = ss.substring(10, ss.length() - 1);
- String[] split = substring.split(",");
- for (String s : split) {
- s = s.strip();
- list.add(s.substring(1, s.length() - 1));
- }
- }
- }
- if ((linkedList = find(s_name, line)).size() != 0) {
- for (String s : linkedList) {
- list.add(s.substring(7, s.length() - 2));
- }
- }
- }
- System.out.println(list);
- bufferedReader.close();
- // 输出汉英对照.txt
- File file1 = new File(".\\test2.txt");
- FileOutputStream fileOutputStream = new FileOutputStream(file1);
- // 指定输出文件编码为gbk,不知道为啥做替换插件的那个2b不使用UTF-8
- OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "gbk");
- // OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
- BufferedWriter writer = new BufferedWriter(outputStreamWriter);
- for (String s : list) {
- writer.append(s).append("\n");
- String query = FanyiV3Demo.query(s);
- String translation = JSON.parseObject(query).getJSONArray("translation").get(0).toString();
- writer.append(translation).append("\n");
- }
- writer.flush();
- }
- public static List<String> find(String regex, String str) {
- List<String> strings = new LinkedList<>();
- Pattern p = Pattern.compile(regex);
- Matcher matcher = p.matcher(str);
- while (matcher.find()) {
- String fundStr = str.substring(matcher.start(), matcher.end());
- System.out.println(fundStr);
- strings.add(fundStr);
- }
- return strings;
- }
- }
复制代码 有道翻译Java SDK改装
[code]/** * @author ShuangLian * @date 2022/7/4 3:49 */import org.apache.http.Header;import org.apache.http.HttpEntity;import org.apache.http.NameValuePair;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpPost;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.message.BasicNameValuePair;import org.apache.http.util.EntityUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.*;import java.nio.charset.StandardCharsets;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.*;/** * 由有道提供,直接调用query方法即可 * 返回示例: * { * "tSpeakUrl": "https://openapi.youdao.com/ttsapi?", * "requestId": "afc14ed2-e6ca-49fe-8f8f-b36e6ff5bbaa", * "query": "Preview on Hover for File Links", * "translation": [ * "预览悬停文件链接" * ], * "errorCode": "0", * "dict": { * "url": "yddict://m.youdao.com/dict?le=eng&q=Preview+on+Hover+for+File+Links" * }, * "webdict": { * "url": "http://mobile.youdao.com/dict?le=eng&q=Preview+on+Hover+for+File+Links" * }, * "l": "en2zh-CHS", * "isWord": false, * "speakUrl": "https://openapi.youdao.com/ttsapi?" * } */public class FanyiV3Demo { private static Logger logger = LoggerFactory.getLogger(FanyiV3Demo.class); private static final String YOUDAO_URL = "https://openapi.youdao.com/api"; // 去有道查看,这里不能直接用 private static final String APP_KEY = "1fcc4"; // private static final String APP_SECRET = "LgA5Wxpm60KP7nyuGp"; public static void main(String[] args) throws IOException { Map params = new HashMap(); String q = "Decrease body font size"; String salt = String.valueOf(System.currentTimeMillis()); params.put("from", "en"); params.put("to", "zh-CHS"); params.put("signType", "v3"); String curtime = String.valueOf(System.currentTimeMillis() / 1000); params.put("curtime", curtime); String signStr = APP_KEY + truncate(q) + salt + curtime + APP_SECRET; String sign = getDigest(signStr); params.put("appKey", APP_KEY); params.put("q", q); params.put("salt", salt); params.put("sign", sign); params.put("vocabId", "您的用户词表ID"); /** 处理结果 */ requestForHttp(YOUDAO_URL, params); } public static String query(String Str) throws IOException { Map params = new HashMap(); String q = Str; String salt = String.valueOf(System.currentTimeMillis()); params.put("from", "en"); params.put("to", "zh-CHS"); params.put("signType", "v3"); String curtime = String.valueOf(System.currentTimeMillis() / 1000); params.put("curtime", curtime); String signStr = APP_KEY + truncate(q) + salt + curtime + APP_SECRET; String sign = getDigest(signStr); params.put("appKey", APP_KEY); params.put("q", q); params.put("salt", salt); params.put("sign", sign); params.put("vocabId", "您的用户词表ID"); /** 处理结果 */ return requestForHttp(YOUDAO_URL, params); } public static String requestForHttp(String url, Map params) throws IOException { String json = null; /** 创建HttpClient */ CloseableHttpClient httpClient = HttpClients.createDefault(); /** httpPost */ HttpPost httpPost = new HttpPost(url); List paramsList = new ArrayList(); Iterator it = params.entrySet().iterator(); while (it.hasNext()) { Map.Entry en = it.next(); String key = en.getKey(); String value = en.getValue(); paramsList.add(new BasicNameValuePair(key, value)); } httpPost.setEntity(new UrlEncodedFormEntity(paramsList, "UTF-8")); CloseableHttpResponse httpResponse = httpClient.execute(httpPost); try { Header[] contentType = httpResponse.getHeaders("Content-Type"); logger.info("Content-Type:" + contentType[0].getValue()); if ("audio/mp3".equals(contentType[0].getValue())) { //如果响应是wav HttpEntity httpEntity = httpResponse.getEntity(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); httpResponse.getEntity().writeTo(baos); byte[] result = baos.toByteArray(); EntityUtils.consume(httpEntity); if (result != null) {//合成成功 String file = "合成的音频存储路径" + System.currentTimeMillis() + ".mp3"; byte2File(result, file); } } else { /** 响应不是音频流,直接显示结果 */ HttpEntity httpEntity = httpResponse.getEntity(); json = EntityUtils.toString(httpEntity, "UTF-8"); EntityUtils.consume(httpEntity); logger.info(json); System.out.println(json); } } finally { try { if (httpResponse != null) { httpResponse.close(); } } catch (IOException e) { logger.info("## release resouce error ##" + e); } } return json; } /** * 生成加密字段 */ public static String getDigest(String string) { if (string == null) { return null; } char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; byte[] btInput = string.getBytes(StandardCharsets.UTF_8); try { MessageDigest mdInst = MessageDigest.getInstance("SHA-256"); mdInst.update(btInput); byte[] md = mdInst.digest(); int j = md.length; char str[] = new char[j * 2]; int k = 0; for (byte byte0 : md) { str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); } catch (NoSuchAlgorithmException e) { return null; } } /** * @param result 音频字节流 * @param file 存储路径 */ private static void byte2File(byte[] result, String file) { File audioFile = new File(file); FileOutputStream fos = null; try { fos = new FileOutputStream(audioFile); fos.write(result); } catch (Exception e) { logger.info(e.toString()); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static String truncate(String q) { if (q == null) { return null; } int len = q.length(); String result; return len |