如何在VSCode扩展中打开网页并跳转到选中文本?
实现Blender文档翻译VSCode扩展的网页锚点跳转
问题背景
在翻译Blender网页文档时,经常需要打开对应网页查看上下文来保证翻译准确。PO文件中嵌入了文档路径,例如:
#: ../../manual/editors/nla/tracks.rst:69
我用VSCode编写了一个小扩展,通过正则解析PO文本获取文档路径,拼接根地址后打开网页,但目前只能打开页面,无法跳转到选中文本对应的位置,需要解决这个锚点跳转的问题。
当前扩展代码
const vscode = require('vscode'); const path = require('node:path'); const os = require('node:os'); const dns = require('dns') const end_path = '.html' /** * @param {vscode.ExtensionContext} context */ function activate(context) { const hostname = os.hostname() const home = process.env.HOME const home_dev = path.join(home, 'Dev/tran') const docs = path.join(home_dev, 'blender_docs') const local_web_root = [ path.join(docs, 'build/en/html'), path.join(docs, 'build/vi/html'), ] const extern_web_root = [ path.join('https://docs.blender.org/manual/en/3.5'), path.join('https://docs.blender.org/manual/vi/3.5') ] let disposable = vscode.commands.registerCommand('OpenPage.openWebPage', async function () { const editor = vscode.window.activeTextEditor; const cursorPosition = editor.selection.active; const selection = editor.selection; if (selection && !selection.isEmpty) { const selectionRange = new vscode.Range(selection.start.line, selection.start.character, selection.end.line, selection.end.character); const highlighted = editor.document.getText(selectionRange); const fileTextToCursor = editor.document.getText(new vscode.Range(0, 0, cursorPosition.line, cursorPosition.character)); const blocks = fileTextToCursor.split(/[\r\n]{2}/); const block_len = blocks.length const last_index = Math.max(block_len-1, 0) const last_block = blocks[last_index] const last_block_list = last_block.split(/[\r\n]/) const last_block_length = last_block_list.length // 存储路径和对应行号的对象数组 const docRefs = []; for (let i = 0; i < last_block_length; i++) { const text_line = last_block_list[i] // 修改正则,同时捕获文档路径和行号(去掉前缀冒号) const matchurl = /#[^\/]+\/[^\/]+\/manual\/([^:\.]+)\.rst(?:\:(\d+))?/.exec(text_line) if (matchurl != null) { docRefs.push({ path: matchurl[1], lineNumber: matchurl[2] ? matchurl[2] : null }); } } const is_connected = (hostname.indexOf('local') == -1) console.log('last block:' + last_block) console.log('docRefs:' + JSON.stringify(docRefs)) console.log('highlighted: ' + highlighted) console.log('hostname:' + hostname) console.log('is_connected', is_connected) const address_list = (is_connected ? extern_web_root : local_web_root) const url_list = [] for (let i = 0; i < address_list.length; i++){ const web_root_path = address_list[i] for (let j = 0; j < docRefs.length; j++){ const docRef = docRefs[j]; let web_address = web_root_path + '/' + docRef.path + end_path; // 若存在行号,添加锚点跳转 if (docRef.lineNumber) { // Blender文档HTML的行号锚点格式为#line-{行号} web_address += `#line-${docRef.lineNumber}`; } url_list.push(web_address) } } for (let i = 0; i < url_list.length; i++) { const url_address = url_list[i] const uri = vscode.Uri.parse(url_address) console.log('uri', uri) vscode.env.openExternal(uri) } } context.subscriptions.push(disposable); } function deactivate() {} module.exports = { activate, deactivate }
关键修改说明
- 正则表达式优化:将原正则调整为
/#[^\/]+\/[^\/]+\/manual\/([^:\.]+)\.rst(?:\:(\d+))?/,新增捕获组提取行号(自动去除前缀的冒号)。 - 文档引用信息存储:改用对象数组
docRefs同时存储文档路径和对应行号,便于后续拼接锚点。 - 锚点拼接逻辑:生成网页地址时,若存在行号则追加
#line-{行号}锚点,Blender官方HTML文档支持该格式直接跳转到对应行位置。 - 锚点格式验证:如果发现跳转位置不准确,可打开目标HTML页面查看源码,确认行号对应的锚点ID格式后替换即可。
内容的提问来源于stack exchange,提问作者Hoang Duy Tran
相关产品推荐
相关产品推荐

