You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 06:02:09