diff --git a/l10n/bundle.l10n.de.json b/l10n/bundle.l10n.de.json index 6443a35..fac4a77 100644 --- a/l10n/bundle.l10n.de.json +++ b/l10n/bundle.l10n.de.json @@ -29,7 +29,7 @@ "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.progress.initialize-configure": "初始化项目配置", "info.pl.xilinx.launch.pick-project-placeholder": "Which project you want to open ?", - "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ncurrent parse list: \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", + "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly! current parse list: ", "info.pl.gui.open-successfully": "GUI open successfully", "info.pl.gui.report-title": "启动 GUI ...", "info.pl.exit.title": "正在退出 ...", @@ -37,5 +37,26 @@ "info.pl.del-files.title": "从项目中删除如下文件", "info.pl.launch.launch-info": "成功启动 Vivado TCL 脚本解释器", "info.pl.launch.progress.launch-tcl.title": "正在启动 Vivado TCL 脚本解释器", - "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:" + "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:", + "info.hdl-doc.markdown.basic-info": "基础信息", + "info.dide-doc.dependency": "依赖性", + "info.dide-doc.ports": "接口", + "info.dide-doc.parameters": "参数", + "info.dide-doc.source": "源", + "info.dide-doc.basic-info.parameter": "parameter", + "info.dide-doc.basic-info.port": "port", + "info.dide-doc.basic-info.top-module": "顶层模块", + "info.dide-doc.entity": "实体", + "info.dide-doc.module": "模块", + "info.dide-doc.port-name": "名称", + "info.dide-doc.direction": "方向", + "info.dide-doc.range": "位宽", + "info.dide-doc.description": "描述", + "info.dide-doc.param-name": "名称", + "info.dide-doc.parameter-init": "初始值", + "info.dide-doc.module-name": "名称", + "info.dide-doc.no-parameter-info": "没有参数信息", + "info.dide-doc.no-port-info": "没有端口信息", + "info.dide-doc.no-dep-info": "没有依赖信息", + "info.dide-doc.source.cannot-find": "无法找到" } \ No newline at end of file diff --git a/l10n/bundle.l10n.en.json b/l10n/bundle.l10n.en.json index d4a4fbd..66cf007 100644 --- a/l10n/bundle.l10n.en.json +++ b/l10n/bundle.l10n.en.json @@ -29,7 +29,7 @@ "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.progress.initialize-configure": "初始化项目配置", "info.pl.xilinx.launch.pick-project-placeholder": "Which project you want to open ?", - "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ncurrent parse list: \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", + "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!ncurrent parse list: ", "info.pl.gui.open-successfully": "GUI open successfully", "info.pl.gui.report-title": "启动 GUI ...", "info.pl.exit.title": "正在退出 ...", @@ -37,5 +37,26 @@ "info.pl.del-files.title": "从项目中删除如下文件", "info.pl.launch.launch-info": "成功启动 Vivado TCL 脚本解释器", "info.pl.launch.progress.launch-tcl.title": "正在启动 Vivado TCL 脚本解释器", - "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:" + "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:", + "info.hdl-doc.markdown.basic-info": "基础信息", + "info.dide-doc.dependency": "依赖性", + "info.dide-doc.ports": "接口", + "info.dide-doc.parameters": "参数", + "info.dide-doc.source": "源", + "info.dide-doc.basic-info.parameter": "parameter", + "info.dide-doc.basic-info.port": "port", + "info.dide-doc.basic-info.top-module": "顶层模块", + "info.dide-doc.entity": "实体", + "info.dide-doc.module": "模块", + "info.dide-doc.port-name": "名称", + "info.dide-doc.direction": "方向", + "info.dide-doc.range": "位宽", + "info.dide-doc.description": "描述", + "info.dide-doc.param-name": "名称", + "info.dide-doc.parameter-init": "初始值", + "info.dide-doc.module-name": "名称", + "info.dide-doc.no-parameter-info": "没有参数信息", + "info.dide-doc.no-port-info": "没有端口信息", + "info.dide-doc.no-dep-info": "没有依赖信息", + "info.dide-doc.source.cannot-find": "无法找到" } \ No newline at end of file diff --git a/l10n/bundle.l10n.ja.json b/l10n/bundle.l10n.ja.json index 2649df8..a8ea4f7 100644 --- a/l10n/bundle.l10n.ja.json +++ b/l10n/bundle.l10n.ja.json @@ -29,7 +29,7 @@ "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.progress.initialize-configure": "初始化项目配置", "info.pl.xilinx.launch.pick-project-placeholder": "Which project you want to open ?", - "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ncurrent parse list: \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", + "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!ncurrent parse list:", "info.pl.gui.open-successfully": "GUI open successfully", "info.pl.gui.report-title": "启动 GUI ...", "info.pl.exit.title": "正在退出 ...", @@ -37,5 +37,26 @@ "info.pl.del-files.title": "从项目中删除如下文件", "info.pl.launch.launch-info": "成功启动 Vivado TCL 脚本解释器", "info.pl.launch.progress.launch-tcl.title": "正在启动 Vivado TCL 脚本解释器", - "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:" + "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:", + "info.hdl-doc.markdown.basic-info": "基础信息", + "info.dide-doc.dependency": "依赖性", + "info.dide-doc.ports": "接口", + "info.dide-doc.parameters": "参数", + "info.dide-doc.source": "源", + "info.dide-doc.basic-info.parameter": "parameter", + "info.dide-doc.basic-info.port": "port", + "info.dide-doc.basic-info.top-module": "顶层模块", + "info.dide-doc.entity": "实体", + "info.dide-doc.module": "模块", + "info.dide-doc.port-name": "名称", + "info.dide-doc.direction": "方向", + "info.dide-doc.range": "位宽", + "info.dide-doc.description": "描述", + "info.dide-doc.param-name": "名称", + "info.dide-doc.parameter-init": "初始值", + "info.dide-doc.module-name": "名称", + "info.dide-doc.no-parameter-info": "没有参数信息", + "info.dide-doc.no-port-info": "没有端口信息", + "info.dide-doc.no-dep-info": "没有依赖信息", + "info.dide-doc.source.cannot-find": "无法找到" } \ No newline at end of file diff --git a/l10n/bundle.l10n.zh-cn.json b/l10n/bundle.l10n.zh-cn.json index 3f85f83..cf82fd2 100644 --- a/l10n/bundle.l10n.zh-cn.json +++ b/l10n/bundle.l10n.zh-cn.json @@ -37,5 +37,26 @@ "info.pl.del-files.title": "从项目中删除如下文件", "info.pl.launch.launch-info": "成功启动 Vivado TCL 脚本解释器", "info.pl.launch.progress.launch-tcl.title": "正在启动 Vivado TCL 脚本解释器", - "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:" + "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:", + "info.hdl-doc.markdown.basic-info": "基础信息", + "info.dide-doc.dependency": "依赖性", + "info.dide-doc.ports": "端口", + "info.dide-doc.parameters": "参数", + "info.dide-doc.source": "源", + "info.dide-doc.basic-info.parameter": "parameter", + "info.dide-doc.basic-info.port": "port", + "info.dide-doc.basic-info.top-module": "顶层模块", + "info.dide-doc.entity": "实体", + "info.dide-doc.module": "模块", + "info.dide-doc.port-name": "名称", + "info.dide-doc.direction": "方向", + "info.dide-doc.range": "位宽", + "info.dide-doc.description": "描述", + "info.dide-doc.param-name": "名称", + "info.dide-doc.parameter-init": "默认值", + "info.dide-doc.module-name": "名称", + "info.dide-doc.no-parameter-info": "没有参数信息", + "info.dide-doc.no-port-info": "没有端口信息", + "info.dide-doc.no-dep-info": "没有依赖信息", + "info.dide-doc.source.cannot-find": "无法找到" } \ No newline at end of file diff --git a/l10n/bundle.l10n.zh-tw.json b/l10n/bundle.l10n.zh-tw.json index 3082509..039f01e 100644 --- a/l10n/bundle.l10n.zh-tw.json +++ b/l10n/bundle.l10n.zh-tw.json @@ -29,7 +29,7 @@ "info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核", "info.progress.initialize-configure": "初始化项目配置", "info.pl.xilinx.launch.pick-project-placeholder": "Which project you want to open ?", - "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly!\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ncurrent parse list: \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", + "error.common.not-valid-hdl-file": "is not a valid hdl file in our parse list, check your property.json to see if arch.hardware.src is set correctly! current parse list:", "info.pl.gui.open-successfully": "GUI open successfully", "info.pl.gui.report-title": "启动 GUI ...", "info.pl.exit.title": "正在退出 ...", @@ -37,5 +37,26 @@ "info.pl.del-files.title": "从项目中删除如下文件", "info.pl.launch.launch-info": "成功启动 Vivado TCL 脚本解释器", "info.pl.launch.progress.launch-tcl.title": "正在启动 Vivado TCL 脚本解释器", - "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:" + "warn.command.transform-old-ppy.unknown-hardwarelib-state": "无法转换 HardwareLIB.state ,原因:未知的 state 枚举:", + "info.hdl-doc.markdown.basic-info": "基础信息", + "info.dide-doc.dependency": "依赖性", + "info.dide-doc.ports": "接口", + "info.dide-doc.parameters": "参数", + "info.dide-doc.source": "源", + "info.dide-doc.basic-info.parameter": "parameter", + "info.dide-doc.basic-info.port": "port", + "info.dide-doc.basic-info.top-module": "顶层模块", + "info.dide-doc.entity": "实体", + "info.dide-doc.module": "模块", + "info.dide-doc.port-name": "名称", + "info.dide-doc.direction": "方向", + "info.dide-doc.range": "位宽", + "info.dide-doc.description": "描述", + "info.dide-doc.param-name": "名称", + "info.dide-doc.parameter-init": "初始值", + "info.dide-doc.module-name": "名称", + "info.dide-doc.no-parameter-info": "没有参数信息", + "info.dide-doc.no-port-info": "没有端口信息", + "info.dide-doc.no-dep-info": "没有依赖信息", + "info.dide-doc.source.cannot-find": "无法找到" } \ No newline at end of file diff --git a/resources/dide-doc/documentation.css b/resources/dide-doc/documentation.css new file mode 100644 index 0000000..18cfd1c --- /dev/null +++ b/resources/dide-doc/documentation.css @@ -0,0 +1,638 @@ +:root { + --dark-main-color : #df733d; + --light-main-color : #cc6633; +} + + +body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + line-height: 1.5; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 16px; + line-height: 1.5; + word-wrap: break-word; + background-attachment: fixed; + background-repeat: no-repeat; + background-size: cover; + -webkit-background-size: cover; + -o-background-size: cover; + background-position: center 0; +} + +.octicon { + display: inline-block; + vertical-align: text-top; + fill: currentColor; +} + +a { + background-color: transparent; + -webkit-text-decoration-skip: objects; +} + +#wrapper { + justify-content: center; + display: flex; +} + +#write { + padding: 15px 30px; + width: 1000px; +} + +.ImgCaption { + padding-top: 0; + margin-top: 7px; + width: fit-content; +} + +.vscode-dark .ImgCaption { + /* border-bottom: 2px solid var(--dark-main-color); */ + color: white; +} + +.vscode-light .ImgCaption { + /* border-bottom: 2px solid var(--light-main-color); */ + color: black; +} + +a:active, +a:hover { + outline-width: 0; +} + +strong { + font-weight: inherit; +} + +strong { + font-weight: bolder; +} + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +.error-out { + display: flex; + justify-content: center; + align-items: center; +} + +.error { + color: rgb(227, 60, 60); + border-radius: 1em; + border: 1.5px solid rgb(227, 60, 60); + padding: 10px 20px; +} + +code, +kbd, +pre { + font-family: monospace, monospace; +} + +hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} + +input { + font: inherit; + margin: 0; +} + +input { + overflow: visible; +} + +[type="checkbox"] { + box-sizing: border-box; + padding: 0; +} + +* { + box-sizing: border-box; +} + +input { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +a { + text-decoration: none; +} + +a:hover, +a:active { + text-decoration: underline; +} + +strong { + font-weight: 600; +} + +hr { + height: 0; + margin: 15px 0; + overflow: hidden; + background: transparent; + border: 0; + border-bottom: 1px solid; +} + +hr::before { + display: table; + content: ""; +} + +hr::after { + display: table; + clear: both; + content: ""; +} + +table { + border-spacing: 0; + border-collapse: collapse; +} + +td, +th { + padding: 0; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin-top: 0; + margin-bottom: 0; +} + +h1 { + font-size: 32px; + font-weight: 600; +} + +h2 { + font-size: 24px; + font-weight: 600; +} + +h3 { + font-size: 20px; + font-weight: 600; +} + +h4 { + font-size: 16px; + font-weight: 600; +} + +h5 { + font-size: 14px; + font-weight: 600; +} + +h6 { + font-size: 12px; + font-weight: 600; +} + +p { + margin-top: 0; + margin-bottom: 10px; +} + +blockquote { + margin: 0; +} + +ul, +ol { + padding-left: 0; + margin-top: 0; + margin-bottom: 0; +} + +ol ol, +ul ol { + list-style-type: lower-roman; +} + +ul ul ol, +ul ol ol, +ol ul ol, +ol ol ol { + list-style-type: lower-alpha; +} + +dd { + margin-left: 0; +} + +code { + font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +pre { + margin-top: 0; + margin-bottom: 0; + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.octicon { + vertical-align: text-bottom; +} + +input { + -webkit-font-feature-settings: "liga" 0; + font-feature-settings: "liga" 0; +} + +.markdown-body::before { + display: table; + content: ""; +} + +.markdown-body::after { + display: table; + clear: both; + content: ""; +} + +.markdown-body>*:first-child { + margin-top: 0 !important; +} + +.markdown-body>*:last-child { + margin-bottom: 0 !important; +} + +a:not([href]) { + color: inherit; + text-decoration: none; +} + +.anchor { + float: left; + padding-right: 4px; + margin-left: -20px; + line-height: 1; +} + +.anchor:focus { + outline: none; +} + +p, +blockquote, +ul, +ol, +dl, +table, +pre { + margin-top: 0; + margin-bottom: 16px; +} + +hr { + height: 0.25em; + padding: 0; + margin: 24px 0; + border: 0; +} + +blockquote { + padding: 0 1em; +} + +blockquote>:first-child { + margin-top: 0; +} + +blockquote>:last-child { + margin-bottom: 0; +} + +kbd { + display: inline-block; + padding: 3px 5px; + font-size: 11px; + line-height: 10px; + vertical-align: middle; + border-radius: 3px; +} + +#write h1, +#write h2, +#write h3, +#write h4, +#write h5, +#write h6 { + margin-top: 24px; + margin-bottom: 16px; + font-weight: 600; + line-height: 1.25; +} + +.vscode-dark h1 { + color: #eee; + /* border-bottom: 3px solid #df733d; */ + width: fit-content; + margin: 0 0 1.0em 0; + line-height: 1.3; +} + +.vscode-dark h2 { + color: #eee; +} + +/* .vscode-dark h2::before { + content: 'H2'; + border-radius: .3em; + font-size: .8em; + padding: 3px 7px; + margin-right: 15px; + color: #eee; + background-color: #df733d; +} */ + +.vscode-light h1 { + color: #000; + /* border-bottom: 3px solid #cc6633; */ + width: fit-content; + margin: 0 0 1.0em 0; + line-height: 1.3; +} + +.vscode-light h2 { + color: #000; +} + +/* .vscode-light h2::before { + content: 'H2'; + border-radius: .3em; + font-size: .8em; + padding: 3px 7px; + margin-right: 15px; + color: #eee; + background-color: #cc6633; +} */ + +h1 { + padding-bottom: 0.3em; + font-size: 2em; +} + +h2 { + padding-bottom: 0.3em; + font-size: 1.5em; +} + +h3 { + font-size: 1.25em; +} + +h4 { + font-size: 1em; +} + +h5 { + font-size: 0.875em; +} + +h6 { + font-size: 0.85em; +} + +ul, +ol { + padding-left: 2em; +} + +ul ul, +ul ol, +ol ol, +ol ul { + margin-top: 0; + margin-bottom: 0; +} + +li>p { + margin-top: 16px; +} + +li+li { + margin-top: 0.25em; +} + +/* +table { + display: block; + width: 100%; + overflow: auto; +} + +table th { + font-weight: bold; +} + +table th, +table td { + padding: 6px 13px; + border: .7px solid; +} + +table tr { + border-top: .7px solid; +} */ + + +img { + max-width: 100%; + box-sizing: content-box; +} + +#write table { + width: 95%; + border-collapse: collapse; + text-align: center; + margin: 20px; + max-width: 750px; +} + +#write table td, table th { + border: 1px solid; + padding: 12px 10px; + /* border-radius: .5em; */ + word-wrap: break-word; +} + +#write table thead th { + /* background-color: var(--dark-main-color); */ + font-size: 20px; + font-weight: bolder; + width: 100px; + text-align: center; + vertical-align: middle; + padding: 10px; +} + +.vscode-dark table { + color: #F0F0F0; +} + +.vscode-light table { + color: #1F2329; +} + + +.vscode-dark #write table thead th { + background-color: rgb(76, 55, 114); +} + +.vscode-light #write table thead th { + background-color: rgb(236, 226, 254); +} + +.vscode-dark table tr:nth-child(even) { + background: #232323; +} + +.vscode-light table tr:nth-child(even) { + background: #F6F7F8; +} + + +/* TODO: Diagram CSS */ +.diagram-container { + width: 100%; + display: flex; + justify-content: center; +} + +.diagram-container .diagram-ports-wrapper { + display: flex; +} + +.diagram-container .diagram-params { + display: flex; + justify-content: space-between; + border-radius: 0.7em; + padding: 15px; + margin: 10px 60px; + width: 350px; + text-align: right; +} + +.diagram-container .diagram-ports { + border-radius: 0.7em; + padding: 20px 0px; + margin: 10px 0px 10px 0px; + width: 350px; +} + +.vscode-dark .diagram-params { + background-color: rgba(53,59,140); + border: solid 4.5px rgb(83,88,157); +} + +.vscode-light .diagram-params { + background-color: rgba(180,185,243); + border: solid 4.5px rgb(153,157,207); +} + +.vscode-dark .diagram-ports { + background-color: rgba(35,102,93); + border: solid 4.5px rgb(68,125,117); +} + +.vscode-light .diagram-ports { + background-color: rgb(169,239,230); + border: solid 4.5px rgb(144,203,196); +} + + +.diagram-container .digrame-port-item { + display: flex; + justify-content: space-between; + height: 40px; +} + +.diagram-container .i-port-name { + font-size: 18px; + padding: 3px 8px; +} + +.diagram-container .o-port-name { + font-size: 18px; + padding: 3px 8px; +} + +.diagram-container .io-port-name { + font-size: 18px; + padding: 3px 8px; + +} + +.diagram-container .left-direction { + padding-right: 0; + padding: 20px 0px; + margin: 10px 0 0 10px; + width: 105px; +} + +.diagram-container .right-direction { + padding-left: 0; + padding: 20px 0px; + margin: 10px 0 10px 0px; + width: 105px; +} + +.diagram-container .arrow-wrapper { + height: 40px; +} + +.diagram-container .port-width-left-caption { + position: absolute; + margin: -5px 10px; + font-size: 14px; +} + +.diagram-container .port-width-right-caption { + position: absolute; + margin: -5px 10px; + font-size: 14px; +} + +.vscode-dark .diagram-container { + color: white; +} + +.vscode-light .diagram-container { + color: black; +} + +#write .title-introduction { + margin-left: 10px; + font-size: 1.1rem; + font-weight: 300; + opacity: 0.8; +} + +.icon-port:before { + font-weight: 1000; +} + +.icon-parameter:before { + font-weight: 1000; +} \ No newline at end of file diff --git a/resources/dide-doc/iconfont.css b/resources/dide-doc/iconfont.css new file mode 100644 index 0000000..86f554a --- /dev/null +++ b/resources/dide-doc/iconfont.css @@ -0,0 +1,39 @@ +@font-face { + font-family: "iconfont"; /* Project id 4748764 */ + src: url('iconfont.woff2?t=1731847061847') format('woff2'), + url('iconfont.woff?t=1731847061847') format('woff'), + url('iconfont.ttf?t=1731847061847') format('truetype'); +} + +.iconfont { + font-family: "iconfont" !important; + + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-verilog:before { + content: "\e634"; +} + +.icon-top-module:before { + content: "\e682"; +} + +.icon-top:before { + content: "\e600"; +} + +.icon-parameter:before { + content: "\e655"; +} + +.icon-unknown:before { + content: "\e62a"; +} + +.icon-port:before { + content: "\e638"; +} + diff --git a/resources/dide-doc/iconfont.woff2 b/resources/dide-doc/iconfont.woff2 new file mode 100644 index 0000000..38df031 Binary files /dev/null and b/resources/dide-doc/iconfont.woff2 differ diff --git a/resources/dide-doc/index.html b/resources/dide-doc/index.html new file mode 100644 index 0000000..310e6ba --- /dev/null +++ b/resources/dide-doc/index.html @@ -0,0 +1,64 @@ + + + + + + + Digital IDE Document + + + + +
+
+
+ + + \ No newline at end of file diff --git a/resources/dide-doc/scripts/update_icon.py b/resources/dide-doc/scripts/update_icon.py new file mode 100644 index 0000000..372ecb3 --- /dev/null +++ b/resources/dide-doc/scripts/update_icon.py @@ -0,0 +1,42 @@ +import requests as r +import os +import shutil +import zipfile + +# 下载 压缩包 +headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36', + 'Cookie': 'cna=FeNcHjgPWA8CAXU/P9lD8IsF; EGG_SESS_ICONFONT=Hu68kBY7XO7C6Udp3T99M1asKmUZ0gxjps8xjTrjx4ZtNCIR_nFu9Li15nxoPAWLmGlcEMN2KEQyAvgBfASR3cSsmd2lhqg89lUmApzbWgBgCWjMwMzjawMqh2KNT8kCICxit3iWC7YLdUuCdUfXg_cGkRjPNvDohqyeHF27gTb5CloBSvLjqN45PcUvcUig; ctoken=Ku-GfnHTFQU6ObMjjX4rrwYn; u=10114852; u.sig=mv5vi-TPPlhvQJi2PMIC4VoPpD03Wc9UykMTMiG6ElA; xlly_s=1; tfstk=fSrIwBNqyBACtg2sZ2BZ5BUbpIn7PWsVNLM8n8KeeDnpwQex_JrEY887N5wxykyrvui717NU8DUUPYN4p7glKbl-N7y88OSV0J2nq0K5giSVfSIC9W9pv3B-6YMoT58eCJ2nqdvwwZzTKU6xnQBS27ntXvkj2HHKwO9tnfKKeHHJ6OMo6bn-9v39XxMD9e3Kpbdy1Y7IeJ69Kr6y7I-gLftJcKDKJZyez3-yav0nMVh62Arsd2GYpk3XwyMTblgq7L5ZX-4a9AifbenYCzFbk7b2SDw8J70_t1Ys_PE3eb3wenysPXaTvV9J2RmsN447O6Tn9yPsoA39FiDagfe3vP6k6JFqODHt7iBbB4UaxqqF6HiYoJoUy7b2SDw8JcszunlfpXTWCqxSCjW1CUYrE4jk1CVx8l3KIvIVCOO6r2HiCjW1CUYoJADLuO661Uf..; isg=BCwsfWsQZki1QXEWw0jCCc4h_Qpe5dCP-aVamIZsF1d6kc6br_ZyHmFnsVkpGQjn', + 'Pragma': 'no-cache', + 'sec-fetch-mode': 'navigate' +} + + + +url = 'https://www.iconfont.cn/api/project/download.zip?spm=a313x.manage_type_myprojects.i1.d7543c303.21213a81tE9WyY&pid=4748764&ctoken=QcRJGHx0m7kL39pW1Slgy_E8' +res = r.get(url, headers=headers) + +if res.status_code: + with open('./script/tmp.zip', 'wb') as fp: + fp.write(res.content) + +# 解压文件 +with zipfile.ZipFile('./script/tmp.zip', 'r') as zipf: + zipf.extractall('./script/tmp') + +# 将文件搬运至工作区,我的 css 全放在 public 下面了,你的视情况而定 +for parent, _, files in os.walk('./script/tmp'): + for file in files: + filepath = os.path.join(parent, file) + if file.startswith('demo'): + continue + if file.endswith('.css'): + content = open(filepath, 'r', encoding='utf-8').read().replace('font-size: 16px;', '') + open(filepath, 'w', encoding='utf-8').write(content) + shutil.move(filepath, os.path.join('./resources/dide-doc', file)) + elif file.endswith('.woff2'): + shutil.move(filepath, os.path.join('./resources/dide-doc', file)) + +# 删除压缩包和解压区域 +os.remove('./script/tmp.zip') +shutil.rmtree('./script/tmp') \ No newline at end of file diff --git a/src/function/hdlDoc/html.ts b/src/function/hdlDoc/html.ts index 662f4c6..77692d5 100644 --- a/src/function/hdlDoc/html.ts +++ b/src/function/hdlDoc/html.ts @@ -1,6 +1,7 @@ import * as assert from 'assert'; import * as vscode from 'vscode'; import * as fs from 'fs'; +import * as fspath from 'path'; import { opeParam, MainOutput, AbsPath } from '../../global'; @@ -100,7 +101,7 @@ function getDocCssString() { if (_cache.css) { return _cache.css; } else { - const cssPath = hdlPath.join(opeParam.extensionPath, 'css/documentation.css'); + const cssPath = hdlPath.join(opeParam.extensionPath, 'resources/dide-doc/documentation.css'); const cssString = fs.readFileSync(cssPath, 'utf-8'); _cache.css = cssString; return cssString; @@ -114,19 +115,18 @@ function makeWavedromRenderErrorHTML() {
`; } - /** - * @description make the html string of a finial display style - * @param usage in whick module is used + * @description 生成制作一个 webview 的 html 代码 + * @param usage */ -async function makeShowHTML(usage: 'webview' | 'pdf' | 'html' | 'markdown'): Promise { - +export async function makeDocBody(uri: vscode.Uri, usage: 'webview' | 'pdf' | 'html' | 'markdown'): Promise { // start to render the real html let body = ''; const userStyle = (usage === 'webview' || usage === 'markdown') ? undefined : ThemeType.Light; ThemeColorConfig.specify = userStyle; - const renderList = await getCurrentRenderList(); + const renderList = await getCurrentRenderList(uri); + if (!renderList || renderList.length === 0) { return ''; } @@ -144,13 +144,26 @@ async function makeShowHTML(usage: 'webview' | 'pdf' | 'html' | 'markdown'): Pro } } + return body; +} + + +/** + * @description 制作用于生成 pdf 等的文档 + * @param usage in whick module is used + */ +async function makeShowHTML(uri: vscode.Uri, usage: 'webview' | 'pdf' | 'html' | 'markdown'): Promise { + const body = await makeDocBody(uri, usage); + // add css let cssString = getDocCssString(); - if (usage === 'webview') { // if invoked by webview, change background image + if (usage === 'webview') { + // if invoked by webview, change background image const webviewConfig = vscode.workspace.getConfiguration("digital-ide.function.doc.webview"); const imageUrl = webviewConfig.get('backgroundImage', ''); cssString = cssString.replace("--backgroundImage", imageUrl); - } else if (usage === 'pdf') { // if invoked by pdf, transform .vscode-light to #write + } else if (usage === 'pdf') { + // if invoked by pdf, transform .vscode-light to #write cssString = cssString.replace(/\.vscode-light/g, '#write'); } const html = makeFinalHTML(body, cssString); @@ -159,8 +172,11 @@ async function makeShowHTML(usage: 'webview' | 'pdf' | 'html' | 'markdown'): Pro return html; } -async function showDocWebview() { - const htmlPromise = makeShowHTML("webview"); +/** + * @description 生成展示文档化的 webview + */ +async function showDocWebview(uri: vscode.Uri) { + const htmlPromise = makeShowHTML(uri, "webview"); const webview = vscode.window.createWebviewPanel( 'TOOL.doc.webview.show', 'document', @@ -172,6 +188,7 @@ async function showDocWebview() { ); webview.iconPath = hdlIcon.getIconConfig('documentation'); + webview.webview.html = await htmlPromise; webview.webview.onDidReceiveMessage(message => { switch (message.command) { @@ -179,9 +196,7 @@ async function showDocWebview() { let filePath: string = message.filePath; if (filePath.startsWith('file://')) { filePath = filePath.slice(7); - } - console.log('debug, ', filePath); - + } const uri = vscode.Uri.file(filePath); vscode.commands.executeCommand('vscode.open', uri); return; @@ -189,6 +204,57 @@ async function showDocWebview() { }); } +function getWebviewContent(context: vscode.ExtensionContext, panel?: vscode.WebviewPanel): string | undefined { + const didedocPath = hdlPath.join(context.extensionPath, 'resources', 'dide-doc'); + const htmlIndexPath = hdlPath.join(didedocPath, 'index.html'); + const html = hdlFile.readFile(htmlIndexPath)?.replace(/( { + const absLocalPath = fspath.resolve(didedocPath, $2); + const webviewUri = panel?.webview.asWebviewUri(vscode.Uri.file(absLocalPath)); + const replaceHref = $1 + webviewUri?.toString() + '"'; + return replaceHref; + }); + return html; +} + +export async function makeDocWebview(uri: vscode.Uri, context: vscode.ExtensionContext): Promise { + const panel = vscode.window.createWebviewPanel( + 'TOOL.doc.webview.show', + 'document', + vscode.ViewColumn.Two, + { + enableScripts: true, // enable JS + retainContextWhenHidden: true, // unchange webview when hidden, prevent extra refresh + } + ); + + panel.iconPath = hdlIcon.getIconConfig('documentation'); + + const html = getWebviewContent(context, panel); + if (html === undefined) { + return panel; + } + + panel.webview.html = html; + panel.webview.onDidReceiveMessage(async message => { + switch (message.command) { + case 'openFile': + let filePath: string = message.filePath; + if (filePath.startsWith('file://')) { + filePath = filePath.slice(7); + } + vscode.commands.executeCommand('vscode.open', vscode.Uri.file(filePath)); + return; + case 'do-render': + const renderBody = await makeDocBody(uri, 'webview'); + panel.webview.postMessage({ + command: 'do-render', + body: renderBody + }); + return; + } + }); + return panel; +} async function exportCurrentFileDocAsHTML() { if (vscode.window.activeColorTheme.kind !== vscode.ColorThemeKind.Light) { diff --git a/src/function/hdlDoc/index.ts b/src/function/hdlDoc/index.ts index 8b60258..459fd5f 100644 --- a/src/function/hdlDoc/index.ts +++ b/src/function/hdlDoc/index.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode'; import { hdlIcon } from "../../hdlFs"; import { exportCurrentFileDocAsMarkdown, exportProjectDocAsMarkdown } from './markdown'; -import { exportCurrentFileDocAsHTML, exportProjectDocAsHTML, showDocWebview } from './html'; +import { exportCurrentFileDocAsHTML, exportProjectDocAsHTML, showDocWebview, makeDocWebview } from './html'; import { exportCurrentFileDocAsPDF, exportProjectDocAsPDF } from './pdf'; const availableFormat = [ @@ -25,8 +25,15 @@ class ExportFunctionItem { } }; +export interface IDocManagerItem { + panel: vscode.WebviewPanel, + fileChangeDisposer: vscode.Disposable +} + +export const docManager = new Map(); + function registerFileDocExport(context: vscode.ExtensionContext) { - vscode.commands.registerCommand('digital-ide.hdlDoc.exportFile', async () => { + vscode.commands.registerCommand('digital-ide.hdlDoc.exportFile', async uri => { const option = { placeHolder: 'Select an Export Format' }; @@ -38,7 +45,7 @@ function registerFileDocExport(context: vscode.ExtensionContext) { const item = await vscode.window.showQuickPick(items, option); if (item) { - item.exportFunc(); + item.exportFunc(uri); } }); } @@ -64,5 +71,6 @@ function registerProjectDocExport(context: vscode.ExtensionContext) { export { registerFileDocExport, registerProjectDocExport, - showDocWebview + showDocWebview, + makeDocWebview }; \ No newline at end of file diff --git a/src/function/hdlDoc/markdown.ts b/src/function/hdlDoc/markdown.ts index a770f8d..f9e10ec 100644 --- a/src/function/hdlDoc/markdown.ts +++ b/src/function/hdlDoc/markdown.ts @@ -3,8 +3,8 @@ import * as fs from 'fs'; import * as fspath from 'path'; import { AbsPath, opeParam, MainOutput, ReportType } from '../../global'; -import { hdlParam, HdlModule, HdlFile } from '../../hdlParser/core'; -import { HdlModulePort, HdlModuleParam } from '../../hdlParser/common'; +import { hdlParam, HdlModule, HdlFile, HdlInstance } from '../../hdlParser/core'; +import { HdlModulePort, HdlModuleParam, InstModPathStatus } from '../../hdlParser/common'; import { MarkdownString, RenderString, RenderType, mergeSortByLine, getWavedromsFromFile, Count, WavedromString } from './common'; @@ -26,27 +26,31 @@ function makeSVGElementByLink(link: AbsPath, caption?: string) { return '
' + mainHtml + '

\n'; } -function selectFieldValue(obj: any, subName: string, ws: string, name: string): string { +function selectFieldValue(obj: any, subName: string, ws: string, name: string, isSingleFile: boolean): string { if (subName === 'empty') { return '——'; } let value = obj[subName]; // 对于 source ,支持跳转 - if (subName === 'instModPath' && value) { - const relativePath = value.replace(ws, ''); + if (subName === 'instModPath') { + // 如果是单文件,则直接返回 —— + if (isSingleFile) { + return '——'; + } + const relativePath = value.replace(ws, ''); if (fs.existsSync(value)) { // 判断 类型 const hdlFile = hdlParam.getHdlFile(value); if (hdlFile && hdlFile.type === 'remote_lib') { // 如果是 库 文件,做出更加自定义的字面量 const libRelPath = value.replace(`${opeParam.extensionPath}/library/`, ''); - value = `[library] [${libRelPath}](file://${value})`; + value = `(library) [${libRelPath}](file://${value})`; } else { - value = `[project] [${relativePath}](file://${value})`; + value = `(project) [${relativePath}](file://${value})`; } } else { - value = relativePath; + value = '(unknown) ' + vscode.l10n.t('info.dide-doc.source.cannot-find'); } } @@ -62,26 +66,29 @@ function selectFieldValue(obj: any, subName: string, ws: string, name: string): } -function makeTableFromObjArray(md: MarkdownString, array: any[], name: string, fieldNames: string[], displayNames: string[]) { +function makeTableFromObjArray( + md: MarkdownString, + array: any[], + name: string, + fieldNames: string[], + displayNames: string[], + isSingleFile: boolean +) { const ws = hdlPath.toSlash(opeParam.workspacePath) + '/'; - if (array.length === 0) { - md.addText(`no ${name} info`); + const rows = []; + for (const obj of array) { + const data = []; + for (const subName of fieldNames) { + const value = selectFieldValue(obj, subName, ws, name, isSingleFile); + data.push(value); + } + rows.push(data); + } + if (displayNames) { + md.addTable(displayNames, rows); } else { - const rows = []; - for (const obj of array) { - const data = []; - for (const subName of fieldNames) { - const value = selectFieldValue(obj, subName, ws, name); - data.push(value); - } - rows.push(data); - } - if (displayNames) { - md.addTable(displayNames, rows); - } else { - md.addTable(fieldNames, rows); - } + md.addTable(fieldNames, rows); } } @@ -116,6 +123,8 @@ async function patchComment(path: AbsPath, ports: (HdlModulePort | HdlModulePara * @param module */ async function getDocsFromModule(module: HdlModule): Promise { + const { t } = vscode.l10n; + const moduleName = module.name; const portNum = module.ports.length; const paramNum = module.params.length; @@ -124,32 +133,35 @@ async function getDocsFromModule(module: HdlModule): Promise { const paramPP = patchComment(module.path, module.params); const portPP = patchComment(module.path, module.ports); - let topModuleDesc = ''; - if (hdlParam.isTopModule(module.path, module.name)) { - topModuleDesc = '√'; - } else { - topModuleDesc = '×'; - } - const md = new MarkdownString(module.range.start.line); if (module.languageId === HdlLangID.Vhdl) { - md.addTitle('Entity: `' + moduleName + '`', 1); + md.addTitle(moduleName + `VHDL ${t('info.dide-doc.entity')}`, 1); } else if (module.languageId === HdlLangID.Verilog) { - md.addTitle('Module: `' + moduleName + '`', 1); + md.addTitle(moduleName + `Verilog ${t('info.dide-doc.module')}`, 1); } else if (module.languageId === HdlLangID.SystemVerilog) { - md.addTitle('Module: `' + moduleName + '`', 1); + md.addTitle(moduleName + `SystemVerilog ${t('info.dide-doc.module')}`, 1); } // add module name - md.addTitle('Basic Info', 2); + // md.addTitle(t('info.hdl-doc.markdown.basic-info'), 2); + const infos = [ - `**File:** ${fspath.basename(module.file.path)}`, - `${paramNum} params, ${portNum} ports`, - 'top module ' + topModuleDesc + '' + ' ' + fspath.basename(module.file.path), + '' + ' ' + `${paramNum}`, + '' + ' ' + `${portNum}` ]; - md.addUnorderedList(infos); + + if (hdlParam.isTopModule(module.path, module.name)) { + infos.push('' + ' ' + '√'); + } else { + infos.push('' + ' ' + '×'); + } + + // md.addUnorderedList(infos); + md.addText(infos.join(" ")); + md.addEnter(); const diagram = makeDiagram(module.params, module.ports); @@ -159,32 +171,94 @@ async function getDocsFromModule(module: HdlModule): Promise { await paramPP; await portPP; + // 判断是否为单文件 + let isSingleFile = false; + if (!opeParam.workspacePath || !fs.existsSync(opeParam.workspacePath)) { + isSingleFile = true; + } else { + const workspacePath = opeParam.workspacePath; + const modulePath = module.path; + isSingleFile = !modulePath.startsWith(workspacePath); + } + // param section - md.addTitle('Params', 2); - makeTableFromObjArray(md, module.params, 'params', - ['name', 'init', 'empty', 'desc'], - ['Param Name', 'Init', 'Range', 'Description']); + md.addTitle(t('info.dide-doc.parameters'), 2); + if (module.params.length > 0) { + makeTableFromObjArray(md, module.params, 'params', + ['name', 'init', 'empty', 'desc'], + // 'Param Name', 'Init', 'Range', 'Description' + [ + t('info.dide-doc.param-name'), + t('info.dide-doc.parameter-init'), + t('info.dide-doc.range'), + t('info.dide-doc.description') + ], + isSingleFile); + } else { + md.addText(t('info.dide-doc.no-parameter-info')); + } + + md.addEnter(); md.addEnter(); // port section - md.addTitle('Ports', 2); - makeTableFromObjArray(md, module.ports, 'ports', - ['name', 'type', 'width', 'desc'], - ['Port Name', 'Direction', 'Range', 'Description']); + md.addTitle(t('info.dide-doc.ports'), 2); + if (module.ports.length > 0) { + makeTableFromObjArray(md, module.ports, 'ports', + ['name', 'type', 'width', 'desc'], + // 'Port Name', 'Direction', 'Range', 'Description' + [ + t('info.dide-doc.port-name'), + t('info.dide-doc.direction'), + t('info.dide-doc.range'), + t('info.dide-doc.description') + ], + isSingleFile); + } else { + md.addText(t('info.dide-doc.no-port-info')); + } + + md.addEnter(); md.addEnter(); // dependency section - md.addTitle('Dependency', 2); - const insts = []; - for (const inst of module.getAllInstances()) { - insts.push(inst); - } + md.addTitle(t('info.dide-doc.dependency'), 2); - makeTableFromObjArray(md, insts, 'Dependencies', - ['name', 'type', 'instModPath'], - ['name', 'module', 'source']); + let insts = module.getAllInstances(); + // 对于单文件模式而言,未进行 instance 搜索,所以insts必然是空的 + if (isSingleFile && insts.length === 0 && module.rawInstances) { + insts = module.rawInstances.map(rawInstance => new HdlInstance( + rawInstance.name, + rawInstance.type, + undefined, + InstModPathStatus.Unknown, + rawInstance.instparams, + rawInstance.instports, + rawInstance.range, + module + )); + } + // 根据 start 进行排序 + insts.sort((a, b) => a.range.start.line - b.range.start.line); + + if (insts.length > 0) { + makeTableFromObjArray(md, insts, 'Dependencies', + ['name', 'type', 'instModPath'], + // 'name', 'module', 'source' + [ + t('info.dide-doc.module-name'), + t('info.dide-doc.module'), + t("info.dide-doc.source") + ], + isSingleFile); + } else { + md.addText(t('info.dide-doc.no-dep-info')); + } + + + md.addEnter(); md.addEnter(); return md; } @@ -252,13 +326,9 @@ async function getRenderList(path: AbsPath): Promise /** * @description return render list of current file */ -async function getCurrentRenderList(): Promise { - const editor = vscode.window.activeTextEditor; - if (editor) { - const currentFilePath = hdlPath.toSlash(editor.document.fileName); - return await getRenderList(currentFilePath); - } - return; +async function getCurrentRenderList(uri: vscode.Uri): Promise { + const currentFilePath = hdlPath.toSlash(uri.fsPath); + return await getRenderList(currentFilePath); } async function exportCurrentFileDocAsMarkdown() { diff --git a/src/function/hdlDoc/pdf.ts b/src/function/hdlDoc/pdf.ts index 72683fc..69b2a17 100644 --- a/src/function/hdlDoc/pdf.ts +++ b/src/function/hdlDoc/pdf.ts @@ -59,7 +59,7 @@ async function htmlFile2PdfFile(htmlPath: AbsPath, pdfPath: AbsPath) { await browser.close(); } -async function exportCurrentFileDocAsPDF() { +async function exportCurrentFileDocAsPDF(uri: vscode.Uri) { const editor = vscode.window.activeTextEditor; if (!editor) { return; @@ -73,7 +73,7 @@ async function exportCurrentFileDocAsPDF() { title: '[Digital-IDE]: Export ' + currentFilePath + '...' }, async progress => { try { - const html = await makeShowHTML("pdf"); + const html = await makeShowHTML(uri, "pdf"); if (!html) { return; diff --git a/src/function/index.ts b/src/function/index.ts index 061ea2c..7d75000 100644 --- a/src/function/index.ts +++ b/src/function/index.ts @@ -18,9 +18,44 @@ import * as Netlist from './netlist'; import * as WaveView from './dide-viewer'; import { ModuleDataItem } from './treeView/tree'; import { downloadLsp } from './lsp-client'; +import { hdlPath } from '../hdlFs'; +import { LspClient, opeParam } from '../global'; +import { DoFastToolChainType, SyncFastRequestType } from '../global/lsp'; +import { makeDocBody } from './hdlDoc/html'; function registerDocumentation(context: vscode.ExtensionContext) { - vscode.commands.registerCommand('digital-ide.hdlDoc.showWebview', hdlDoc.showDocWebview); + vscode.commands.registerCommand('digital-ide.hdlDoc.showWebview', async (uri: vscode.Uri) => { + const standardPath = hdlPath.toSlash(uri.fsPath); + const item = hdlDoc.docManager.get(standardPath); + if (item) { + // 展示 webview + item.panel.reveal(vscode.ViewColumn.Two); + } else { + const panel = await hdlDoc.makeDocWebview(uri, context); + // TODO: 注册文件变动监听 + const fileChangeDisposer = vscode.window.onDidChangeActiveTextEditor(async event => { + // const client = LspClient.DigitalIDE; + // if (client && event?.document) { + // const path = hdlPath.toSlash(event.document.fileName); + // const fileType = 'common'; + // const toolChain = opeParam.prjInfo.toolChain as DoFastToolChainType; + // const fast = await client.sendRequest(SyncFastRequestType, { path, fileType, toolChain }); + // if (fast) { + // const renderBody = await makeDocBody(uri, 'webview'); + // panel.webview.postMessage({ + // command: 'do-render', + // body: renderBody + // }); + // } + // } + }); + hdlDoc.docManager.set(standardPath, { panel, fileChangeDisposer }); + panel.onDidDispose(event => { + hdlDoc.docManager.delete(standardPath); + fileChangeDisposer.dispose(); + }); + } + }); hdlDoc.registerFileDocExport(context); hdlDoc.registerProjectDocExport(context); } diff --git a/src/global/lsp.ts b/src/global/lsp.ts index d130f46..a0cd5f8 100644 --- a/src/global/lsp.ts +++ b/src/global/lsp.ts @@ -26,8 +26,9 @@ export const LspClient: IDigitalIDELspClient = { export const CustomRequestType = new RequestType('custom/request'); export const CustomParamRequestType = new RequestType('custom/paramRequest'); export const DoFastRequestType = new RequestType('api/fast'); -export const UpdateConfigurationType = new RequestType('api/update-fast'); +export const UpdateConfigurationType = new RequestType('api/update-configuration'); export const DoPrimitivesJudgeType = new RequestType('api/do-primitives-judge'); +export const SyncFastRequestType = new RequestType('api/sync-fast'); export interface ITextDocumentItem { uri: vscode.Uri, @@ -36,6 +37,12 @@ export interface ITextDocumentItem { text: string } +export interface ISyncFastParam { + path: string, + fileType: DoFastFileType, + toolChain: DoFastToolChainType +} + export interface ICommonParam { param: string } diff --git a/src/hdlParser/core.ts b/src/hdlParser/core.ts index 5f13a12..59916a5 100644 --- a/src/hdlParser/core.ts +++ b/src/hdlParser/core.ts @@ -526,7 +526,7 @@ class HdlInstance { this.instparams = newInstance.instparams; this.instports = newInstance.instports; - this.instModPath = this.parentMod.path; + this.instModPath = this.module?.path || ''; this.instModPathStatus = this.parentMod.solveInstModPathStatus(); } @@ -615,7 +615,7 @@ class HdlModule { const instModName = rawHdlInstance.type; if (this.languageId === HdlLangID.Verilog || this.languageId === HdlLangID.SystemVerilog) { - const searchResult = this.searchInstModPath(instModName); + const searchResult = this.searchInstModPath(instModName); const hdlInstance = new HdlInstance(rawHdlInstance.name, rawHdlInstance.type, searchResult.path,