improve documentation
12
CHANGELOG.md
@ -4,6 +4,18 @@ All notable changes to the "digital-ide" extension will be documented in this fi
|
|||||||
|
|
||||||
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
|
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
|
||||||
|
|
||||||
|
## [0.3.3] - 2024-02-05
|
||||||
|
|
||||||
|
Feature
|
||||||
|
- 重做了文档化功能,并且添加了参数和接口的 diagram 可视化的渲染模块
|
||||||
|
|
||||||
|
|
||||||
|
Bug 修复
|
||||||
|
- Verilog 参数例化位置错误
|
||||||
|
- 文档化的部分问题
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
## [0.3.2] - 2023-11-01
|
## [0.3.2] - 2023-11-01
|
||||||
|
|
||||||
Feature
|
Feature
|
||||||
|
520
css/documentation.backup.css
Normal file
@ -0,0 +1,520 @@
|
|||||||
|
: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;
|
||||||
|
background-image: url(--backgroundImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
color: #4078c0;
|
||||||
|
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;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 transparent;
|
||||||
|
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 thead th {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vscode-dark table td, table th {
|
||||||
|
color: rgb(234, 231, 231);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vscode-light table thead th {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vscode-light table td, table th {
|
||||||
|
color: rgb(16, 16, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vscode-dark table tr:nth-child(even)
|
||||||
|
{
|
||||||
|
background: #20242b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vscode-light table tr:nth-child(even)
|
||||||
|
{
|
||||||
|
background: #e7e1e1;
|
||||||
|
}
|
@ -18,7 +18,6 @@ body {
|
|||||||
-webkit-background-size: cover;
|
-webkit-background-size: cover;
|
||||||
-o-background-size: cover;
|
-o-background-size: cover;
|
||||||
background-position: center 0;
|
background-position: center 0;
|
||||||
background-image: url(--backgroundImage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.octicon {
|
.octicon {
|
||||||
@ -49,12 +48,12 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.vscode-dark .ImgCaption {
|
.vscode-dark .ImgCaption {
|
||||||
border-bottom: 2px solid var(--dark-main-color);
|
/* border-bottom: 2px solid var(--dark-main-color); */
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vscode-light .ImgCaption {
|
.vscode-light .ImgCaption {
|
||||||
border-bottom: 2px solid var(--light-main-color);
|
/* border-bottom: 2px solid var(--light-main-color); */
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +92,6 @@ code,
|
|||||||
kbd,
|
kbd,
|
||||||
pre {
|
pre {
|
||||||
font-family: monospace, monospace;
|
font-family: monospace, monospace;
|
||||||
font-size: 1em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
@ -244,7 +242,6 @@ dd {
|
|||||||
|
|
||||||
code {
|
code {
|
||||||
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||||
font-size: 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
@ -350,7 +347,7 @@ kbd {
|
|||||||
|
|
||||||
.vscode-dark h1 {
|
.vscode-dark h1 {
|
||||||
color: #eee;
|
color: #eee;
|
||||||
border-bottom: 3px solid #df733d;
|
/* border-bottom: 3px solid #df733d; */
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
margin: 0 0 1.0em 0;
|
margin: 0 0 1.0em 0;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
@ -360,7 +357,7 @@ kbd {
|
|||||||
color: #eee;
|
color: #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vscode-dark h2::before {
|
/* .vscode-dark h2::before {
|
||||||
content: 'H2';
|
content: 'H2';
|
||||||
border-radius: .3em;
|
border-radius: .3em;
|
||||||
font-size: .8em;
|
font-size: .8em;
|
||||||
@ -368,11 +365,11 @@ kbd {
|
|||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
color: #eee;
|
color: #eee;
|
||||||
background-color: #df733d;
|
background-color: #df733d;
|
||||||
}
|
} */
|
||||||
|
|
||||||
.vscode-light h1 {
|
.vscode-light h1 {
|
||||||
color: #000;
|
color: #000;
|
||||||
border-bottom: 3px solid #cc6633;
|
/* border-bottom: 3px solid #cc6633; */
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
margin: 0 0 1.0em 0;
|
margin: 0 0 1.0em 0;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
@ -382,7 +379,7 @@ kbd {
|
|||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vscode-light h2::before {
|
/* .vscode-light h2::before {
|
||||||
content: 'H2';
|
content: 'H2';
|
||||||
border-radius: .3em;
|
border-radius: .3em;
|
||||||
font-size: .8em;
|
font-size: .8em;
|
||||||
@ -390,7 +387,7 @@ kbd {
|
|||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
color: #eee;
|
color: #eee;
|
||||||
background-color: #cc6633;
|
background-color: #cc6633;
|
||||||
}
|
} */
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
padding-bottom: 0.3em;
|
padding-bottom: 0.3em;
|
||||||
@ -466,25 +463,23 @@ img {
|
|||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
#write table
|
#write table {
|
||||||
{
|
|
||||||
width: 95%;
|
width: 95%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
max-width: 750px;
|
max-width: 750px;
|
||||||
}
|
}
|
||||||
#write table td, table th
|
|
||||||
{
|
#write table td, table th {
|
||||||
border: 1px solid transparent;
|
border: 1px solid;
|
||||||
padding: 12px 10px;
|
padding: 12px 10px;
|
||||||
border-radius: .5em;
|
/* border-radius: .5em; */
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
#write table thead th
|
#write table thead th {
|
||||||
{
|
/* background-color: var(--dark-main-color); */
|
||||||
background-color: var(--dark-main-color);
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
@ -493,28 +488,135 @@ img {
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vscode-dark table thead th {
|
.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: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diagram-container .i-port-name {
|
||||||
|
font-size: 20px;
|
||||||
|
padding: 3px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diagram-container .o-port-name {
|
||||||
|
font-size: 20px;
|
||||||
|
padding: 3px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diagram-container .io-port-name {
|
||||||
|
font-size: 20px;
|
||||||
|
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: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diagram-container .port-width-left-caption {
|
||||||
|
position: absolute;
|
||||||
|
margin: -10px 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diagram-container .port-width-right-caption {
|
||||||
|
position: absolute;
|
||||||
|
margin: -10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vscode-dark .diagram-container {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vscode-dark table td, table th {
|
.vscode-light .diagram-container {
|
||||||
color: rgb(234, 231, 231);
|
color: black;
|
||||||
}
|
|
||||||
|
|
||||||
.vscode-light table thead th {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vscode-light table td, table th {
|
|
||||||
color: rgb(16, 16, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
.vscode-dark table tr:nth-child(even)
|
|
||||||
{
|
|
||||||
background: #20242b;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vscode-light table tr:nth-child(even)
|
|
||||||
{
|
|
||||||
background: #e7e1e1;
|
|
||||||
}
|
}
|
10
images/svg/dark/left-arrow.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
|
||||||
|
width="125px" height="45px" viewBox="-0.5 -0.5 125 45">
|
||||||
|
<defs />
|
||||||
|
<g>
|
||||||
|
<path d="M 101 21 L 25.47 21" fill="none" stroke="rgb(255, 255, 255)" stroke-width="3"
|
||||||
|
stroke-miterlimit="10" pointer-events="stroke" />
|
||||||
|
<path d="M 45.24 10 L 23.24 21 L 45.24 32" fill="none" stroke="rgb(255, 255, 255)"
|
||||||
|
stroke-width="3" stroke-miterlimit="10" pointer-events="all" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 517 B |
12
images/svg/dark/left-right-arrow.svg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
|
||||||
|
width="127px" height="47px" viewBox="-0.5 -0.5 125 45">
|
||||||
|
<defs />
|
||||||
|
<g>
|
||||||
|
<path d="M 97.53 22 L 26.47 22" fill="none" stroke="rgb(255, 255, 255)" stroke-width="3"
|
||||||
|
stroke-miterlimit="10" pointer-events="stroke" />
|
||||||
|
<path d="M 77.76 33 L 99.76 22 L 77.76 11" fill="none" stroke="rgb(255, 255, 255)"
|
||||||
|
stroke-width="3" stroke-miterlimit="10" pointer-events="all" />
|
||||||
|
<path d="M 46.24 11 L 24.24 22 L 46.24 33" fill="none" stroke="rgb(255, 255, 255)"
|
||||||
|
stroke-width="3" stroke-miterlimit="10" pointer-events="all" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 686 B |
10
images/svg/dark/right-arrow.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
|
||||||
|
width="125px" height="45px" viewBox="-0.5 -0.5 125 45">
|
||||||
|
<defs />
|
||||||
|
<g>
|
||||||
|
<path d="M 21 21 L 96.53 21" fill="none" stroke="rgb(255, 255, 255)" stroke-width="3"
|
||||||
|
stroke-miterlimit="10" pointer-events="stroke" />
|
||||||
|
<path d="M 76.76 32 L 98.76 21 L 76.76 10" fill="none" stroke="rgb(255, 255, 255)"
|
||||||
|
stroke-width="3" stroke-miterlimit="10" pointer-events="all" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 516 B |
12
images/svg/dark/right-dot-arrow.svg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
|
||||||
|
width="125px" height="45px" viewBox="-0.5 -0.5 125 45">
|
||||||
|
<defs />
|
||||||
|
<g>
|
||||||
|
<path d="M 22 22 L 97.53 22" fill="none" stroke="rgb(255, 255, 255)" stroke-width="3"
|
||||||
|
stroke-miterlimit="10" pointer-events="stroke" />
|
||||||
|
<path d="M 77.76 33 L 99.76 22 L 77.76 11" fill="none" stroke="rgb(255, 255, 255)"
|
||||||
|
stroke-width="3" stroke-miterlimit="10" pointer-events="all" />
|
||||||
|
<path d="M 72 32 L 52 12" fill="none" stroke="rgb(255, 255, 255)" stroke-width="3"
|
||||||
|
stroke-miterlimit="10" pointer-events="stroke" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 669 B |
10
images/svg/light/left-arrow.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
|
||||||
|
width="125px" height="45px" viewBox="-0.5 -0.5 125 45">
|
||||||
|
<defs />
|
||||||
|
<g>
|
||||||
|
<path d="M 101 21 L 25.47 21" fill="none" stroke="rgb(0, 0, 0)" stroke-width="3"
|
||||||
|
stroke-miterlimit="10" pointer-events="stroke" />
|
||||||
|
<path d="M 45.24 10 L 23.24 21 L 45.24 32" fill="none" stroke="rgb(0, 0, 0)"
|
||||||
|
stroke-width="3" stroke-miterlimit="10" pointer-events="all" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 505 B |
12
images/svg/light/left-right-arrow.svg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
|
||||||
|
width="127px" height="47px" viewBox="-0.5 -0.5 125 45">
|
||||||
|
<defs />
|
||||||
|
<g>
|
||||||
|
<path d="M 97.53 22 L 26.47 22" fill="none" stroke="rgb(0, 0, 0)" stroke-width="3"
|
||||||
|
stroke-miterlimit="10" pointer-events="stroke" />
|
||||||
|
<path d="M 77.76 33 L 99.76 22 L 77.76 11" fill="none" stroke="rgb(0, 0, 0)"
|
||||||
|
stroke-width="3" stroke-miterlimit="10" pointer-events="all" />
|
||||||
|
<path d="M 46.24 11 L 24.24 22 L 46.24 33" fill="none" stroke="rgb(0, 0, 0)"
|
||||||
|
stroke-width="3" stroke-miterlimit="10" pointer-events="all" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 668 B |
10
images/svg/light/right-arrow.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
|
||||||
|
width="125px" height="45px" viewBox="-0.5 -0.5 125 45">
|
||||||
|
<defs />
|
||||||
|
<g>
|
||||||
|
<path d="M 21 21 L 96.53 21" fill="none" stroke="rgb(0, 0, 0)" stroke-width="3"
|
||||||
|
stroke-miterlimit="10" pointer-events="stroke" />
|
||||||
|
<path d="M 76.76 32 L 98.76 21 L 76.76 10" fill="none" stroke="rgb(0, 0, 0)"
|
||||||
|
stroke-width="3" stroke-miterlimit="10" pointer-events="all" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 504 B |
12
images/svg/light/right-dot-arrow.svg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
|
||||||
|
width="125px" height="45px" viewBox="-0.5 -0.5 125 45">
|
||||||
|
<defs />
|
||||||
|
<g>
|
||||||
|
<path d="M 22 22 L 97.53 22" fill="none" stroke="rgb(0, 0, 0)" stroke-width="3"
|
||||||
|
stroke-miterlimit="10" pointer-events="stroke" />
|
||||||
|
<path d="M 77.76 33 L 99.76 22 L 77.76 11" fill="none" stroke="rgb(0, 0, 0)"
|
||||||
|
stroke-width="3" stroke-miterlimit="10" pointer-events="all" />
|
||||||
|
<path d="M 72 32 L 52 12" fill="none" stroke="rgb(0, 0, 0)" stroke-width="3"
|
||||||
|
stroke-miterlimit="10" pointer-events="stroke" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 651 B |
@ -28,10 +28,10 @@
|
|||||||
"digital-ide.hard.gui.title": "打开界面",
|
"digital-ide.hard.gui.title": "打开界面",
|
||||||
"digital-ide.hard.exit.title": "退出当前项目",
|
"digital-ide.hard.exit.title": "退出当前项目",
|
||||||
"digital-ide.pickLibrary.title": "从自定义选择自由和普遍",
|
"digital-ide.pickLibrary.title": "从自定义选择自由和普遍",
|
||||||
"digital-ide.pl.setSrcTop.title": "设置为src的top",
|
"digital-ide.pl.setSrcTop.title": "设置为 源文件(src)的顶层文件",
|
||||||
"digital-ide.pl.setSimTop.title": "设置为sim的top",
|
"digital-ide.pl.setSimTop.title": "设置为 测试文件(sim) 的顶层文件",
|
||||||
"digital-ide.pl.addDevice.title": "添加device",
|
"digital-ide.pl.addDevice.title": "添加 device",
|
||||||
"digital-ide.pl.delDevice.title": "删除device",
|
"digital-ide.pl.delDevice.title": "删除 device",
|
||||||
"digital-ide.pl.addFile.title": "添加文件",
|
"digital-ide.pl.addFile.title": "添加文件",
|
||||||
"digital-ide.pl.delFile.title": "d删除文件",
|
"digital-ide.pl.delFile.title": "d删除文件",
|
||||||
"digital-ide.netlist.title": "netlist",
|
"digital-ide.netlist.title": "netlist",
|
||||||
@ -39,8 +39,8 @@
|
|||||||
"digital-ide.lsp.tool.insertTextToUri.title": "插入文本uri",
|
"digital-ide.lsp.tool.insertTextToUri.title": "插入文本uri",
|
||||||
"digital-ide.lsp.tool.transformOldPropertyFile.title": "转换配置文件从先前版本新版本",
|
"digital-ide.lsp.tool.transformOldPropertyFile.title": "转换配置文件从先前版本新版本",
|
||||||
"digital-ide.vhdl2vlog.title": "vhdl代码翻译为verilog代码",
|
"digital-ide.vhdl2vlog.title": "vhdl代码翻译为verilog代码",
|
||||||
"digital-ide.fsm.show.title": "显示当前文件的FSM图",
|
"digital-ide.fsm.show.title": "显示当前文件的 FSM",
|
||||||
"digital-ide.netlist.show.title": "显示当前文件的netlist",
|
"digital-ide.netlist.show.title": "显示当前文件的 Netlist",
|
||||||
"digital-ide.lsp.vlog.linter.pick.title": "选择 Verilog 的诊断",
|
"digital-ide.lsp.vlog.linter.pick.title": "选择 Verilog 的诊断",
|
||||||
"digital-ide.lsp.svlog.linter.pick.title": "选择 System Verilog 的诊断",
|
"digital-ide.lsp.svlog.linter.pick.title": "选择 System Verilog 的诊断",
|
||||||
"digital-ide.lsp.vhdl.linter.pick.title": "选择 VHDL 的诊断",
|
"digital-ide.lsp.vhdl.linter.pick.title": "选择 VHDL 的诊断",
|
||||||
|
@ -39,8 +39,8 @@
|
|||||||
"digital-ide.lsp.tool.insertTextToUri.title": "插入文本uri",
|
"digital-ide.lsp.tool.insertTextToUri.title": "插入文本uri",
|
||||||
"digital-ide.lsp.tool.transformOldPropertyFile.title": "轉換配置文件從先前版本新版本",
|
"digital-ide.lsp.tool.transformOldPropertyFile.title": "轉換配置文件從先前版本新版本",
|
||||||
"digital-ide.vhdl2vlog.title": "vhdl代碼翻譯為verilog代碼",
|
"digital-ide.vhdl2vlog.title": "vhdl代碼翻譯為verilog代碼",
|
||||||
"digital-ide.fsm.show.title": "顯示當前文件的FSM圖",
|
"digital-ide.fsm.show.title": "顯示當前文件的 FSM",
|
||||||
"digital-ide.netlist.show.title": "顯示當前文件的netlist",
|
"digital-ide.netlist.show.title": "顯示當前文件的 Netlist",
|
||||||
"digital-ide.lsp.vlog.linter.pick.title": "選擇 Verilog 的診斷",
|
"digital-ide.lsp.vlog.linter.pick.title": "選擇 Verilog 的診斷",
|
||||||
"digital-ide.lsp.svlog.linter.pick.title": "選擇 System Verilog 的診斷",
|
"digital-ide.lsp.svlog.linter.pick.title": "選擇 System Verilog 的診斷",
|
||||||
"digital-ide.lsp.vhdl.linter.pick.title": "選擇 VHDL 的診斷",
|
"digital-ide.lsp.vhdl.linter.pick.title": "選擇 VHDL 的診斷",
|
||||||
|
@ -10,6 +10,7 @@ import * as showdown from 'showdown';
|
|||||||
|
|
||||||
import { ThemeType } from '../../global/enum';
|
import { ThemeType } from '../../global/enum';
|
||||||
import { MainOutput, ReportType } from '../../global';
|
import { MainOutput, ReportType } from '../../global';
|
||||||
|
import { HdlModuleParam, HdlModulePort } from '../../hdlParser/common';
|
||||||
|
|
||||||
const Count = {
|
const Count = {
|
||||||
svgMakeTimes: 0
|
svgMakeTimes: 0
|
||||||
@ -32,7 +33,7 @@ enum MarkdownTag {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum MarkdownAlign { Left, Center, Right };
|
enum MarkdownAlign { Left, Center, Right };
|
||||||
enum RenderType { Wavedrom, Markdown };
|
enum RenderType { Wavedrom, Markdown, Diagram };
|
||||||
|
|
||||||
function getAlignSpliter(align: MarkdownAlign): string {
|
function getAlignSpliter(align: MarkdownAlign): string {
|
||||||
switch (align) {
|
switch (align) {
|
||||||
@ -267,6 +268,26 @@ class WavedromString extends RenderString {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DiagramString extends RenderString {
|
||||||
|
params: HdlModuleParam[];
|
||||||
|
ports: HdlModulePort[];
|
||||||
|
|
||||||
|
constructor(line: number) {
|
||||||
|
super(line, RenderType.Diagram);
|
||||||
|
this.params = [];
|
||||||
|
this.ports = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
add() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render(): string {
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function parseJson5(text: string): any {
|
function parseJson5(text: string): any {
|
||||||
let json = null;
|
let json = null;
|
||||||
try {
|
try {
|
||||||
@ -368,5 +389,6 @@ export {
|
|||||||
RenderString,
|
RenderString,
|
||||||
makeWaveDromSVG,
|
makeWaveDromSVG,
|
||||||
getWavedromsFromFile,
|
getWavedromsFromFile,
|
||||||
|
getThemeColorKind,
|
||||||
Count
|
Count
|
||||||
};
|
};
|
191
src/function/hdlDoc/diagram.ts
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/naming-convention */
|
||||||
|
|
||||||
|
import { opeParam } from "../../global";
|
||||||
|
import { ThemeType } from "../../global/enum";
|
||||||
|
import { hdlFile, hdlPath } from "../../hdlFs";
|
||||||
|
import { HdlModuleParam, HdlModulePort, HdlModulePortType } from "../../hdlParser/common";
|
||||||
|
import { getThemeColorKind } from "./common";
|
||||||
|
|
||||||
|
const arrowSvgCache: Record<string, string> = {
|
||||||
|
'left': '',
|
||||||
|
'right': '',
|
||||||
|
'left-right': '',
|
||||||
|
'left-dot': '',
|
||||||
|
'right-dot': ''
|
||||||
|
};
|
||||||
|
|
||||||
|
function getArrowSvgString(name: 'left' | 'right' | 'left-right' | 'left-dot' | 'right-dot'): string {
|
||||||
|
let svgString = arrowSvgCache[name];
|
||||||
|
if (svgString.length === 0) {
|
||||||
|
const themeType = getThemeColorKind();
|
||||||
|
const iconFile = name + '-arrow.svg';
|
||||||
|
const svgDir = hdlPath.join(opeParam.extensionPath, 'images', 'svg');
|
||||||
|
const svgPath = hdlPath.join(svgDir, themeType, iconFile);
|
||||||
|
const readSvgString = hdlFile.readFile(svgPath);
|
||||||
|
if (readSvgString) {
|
||||||
|
svgString = readSvgString;
|
||||||
|
arrowSvgCache[name] = readSvgString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return svgString;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeDiagram(params: HdlModuleParam[], ports: HdlModulePort[]): string {
|
||||||
|
// make params block
|
||||||
|
const diagramParamWrapper = makeDiagramParamWrapper(params);
|
||||||
|
|
||||||
|
// make ports block
|
||||||
|
const diagramPortWrapper = makeDiagramPortWrapper(ports);
|
||||||
|
|
||||||
|
const diagram = `<div class="diagram-container"><div class="diagram">${diagramParamWrapper}${diagramPortWrapper}</div></div>`;
|
||||||
|
return diagram;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function makeDiagramParamWrapper(params: HdlModuleParam[]): string {
|
||||||
|
if (params.length === 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
let diagramParams = '';
|
||||||
|
for (const param of params) {
|
||||||
|
let diagramParam = '<div>' + param.name;
|
||||||
|
if (param.init && param.init.length > 0) {
|
||||||
|
diagramParam += `(${param.init})`;
|
||||||
|
}
|
||||||
|
diagramParam += '</div>';
|
||||||
|
diagramParams += diagramParam;
|
||||||
|
}
|
||||||
|
const diagramParamWrapper = `<div class="diagram-ports-wrapper"><div style="width: 55px;"></div><div class="diagram-params"><div></div><div align="left">${diagramParams}</div></div></div>`;
|
||||||
|
return diagramParamWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function makeDiagramPortWrapper(ports: HdlModulePort[]): string {
|
||||||
|
if (ports.length === 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const leftPorts = ports.filter(port => port.type === HdlModulePortType.Input || port.type === HdlModulePortType.Inout);
|
||||||
|
const rightPorts = ports.filter(port => port.type === HdlModulePortType.Output);
|
||||||
|
|
||||||
|
const leftDirection = makeLeftDirection(leftPorts);
|
||||||
|
const diagramPorts = makeDiagramPorts(leftPorts, rightPorts);
|
||||||
|
const rightDirection = makeRightDirection(rightPorts);
|
||||||
|
|
||||||
|
const diagramPortWrapper = `<div class="diagram-ports-wrapper">${leftDirection}${diagramPorts}${rightDirection}</div>`;
|
||||||
|
return diagramPortWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isValidWidth(portWidth: string | undefined): boolean {
|
||||||
|
if (portWidth === undefined || portWidth === '' || portWidth === '1') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makePortCaption(port: HdlModulePort, direction: 'left' | 'right'): string {
|
||||||
|
if (!isValidWidth(port.width)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return `<div class="port-width-${direction}-caption">${port.width}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makePortArrow(port: HdlModulePort, direction: 'left' | 'right'): string {
|
||||||
|
if (port.type === HdlModulePortType.Inout) {
|
||||||
|
return getArrowSvgString('left-right');
|
||||||
|
}
|
||||||
|
if (direction === 'left') {
|
||||||
|
if (port.type === HdlModulePortType.Input) {
|
||||||
|
if (isValidWidth(port.width)) {
|
||||||
|
return getArrowSvgString('right-dot');
|
||||||
|
} else {
|
||||||
|
return getArrowSvgString('right');
|
||||||
|
}
|
||||||
|
} else if (port.type === HdlModulePortType.Output) {
|
||||||
|
if (isValidWidth(port.width)) {
|
||||||
|
return getArrowSvgString('left-dot');
|
||||||
|
} else {
|
||||||
|
return getArrowSvgString('left');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (direction === 'right') {
|
||||||
|
if (port.type === HdlModulePortType.Input) {
|
||||||
|
if (isValidWidth(port.width)) {
|
||||||
|
return getArrowSvgString('left-dot');
|
||||||
|
} else {
|
||||||
|
return getArrowSvgString('left');
|
||||||
|
}
|
||||||
|
} else if (port.type === HdlModulePortType.Output) {
|
||||||
|
if (isValidWidth(port.width)) {
|
||||||
|
return getArrowSvgString('right-dot');
|
||||||
|
} else {
|
||||||
|
return getArrowSvgString('right');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeLeftDirection(leftPorts: HdlModulePort[]): string {
|
||||||
|
let leftDirection = '';
|
||||||
|
for (const port of leftPorts) {
|
||||||
|
const portCaption = makePortCaption(port, 'left');
|
||||||
|
const portArrow = makePortArrow(port, 'left');
|
||||||
|
const arrow = `<div class="arrow-wrapper">${portCaption}${portArrow}</div>`;
|
||||||
|
leftDirection += arrow;
|
||||||
|
}
|
||||||
|
return `<div class="left-direction">${leftDirection}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makePortName(port: HdlModulePort): string {
|
||||||
|
let portClass = '';
|
||||||
|
if (port.type === HdlModulePortType.Input) {
|
||||||
|
portClass = 'i-port-name';
|
||||||
|
} else if (port.type === HdlModulePortType.Output) {
|
||||||
|
portClass = 'o-port-name';
|
||||||
|
} else {
|
||||||
|
portClass = 'io-port-name';
|
||||||
|
}
|
||||||
|
return `<div class="${portClass}">${port.name}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeDiagramPorts(leftPorts: HdlModulePort[], rightPorts: HdlModulePort[]): string {
|
||||||
|
let leftIndex = 0;
|
||||||
|
let rightIndex = 0;
|
||||||
|
let diagramePorts = '';
|
||||||
|
while (leftIndex < leftPorts.length && rightIndex < rightPorts.length) {
|
||||||
|
const leftPortName = makePortName(leftPorts[leftIndex ++]);
|
||||||
|
const rightPortName = makePortName(rightPorts[rightIndex ++]);
|
||||||
|
const diagramPortItem = `<div class="digrame-port-item">${leftPortName}${rightPortName}</div>`;
|
||||||
|
diagramePorts += diagramPortItem;
|
||||||
|
}
|
||||||
|
while (leftIndex < leftPorts.length) {
|
||||||
|
const leftPortName = makePortName(leftPorts[leftIndex ++]);
|
||||||
|
const diagramPortItem = `<div class="digrame-port-item">${leftPortName}<div></div></div>`;
|
||||||
|
diagramePorts += diagramPortItem;
|
||||||
|
}
|
||||||
|
while (rightIndex < rightPorts.length) {
|
||||||
|
const rightPortName = makePortName(leftPorts[leftIndex ++]);
|
||||||
|
const diagramPortItem = `<div class="digrame-port-item"><div></div>${rightPortName}</div>`;
|
||||||
|
diagramePorts += diagramPortItem;
|
||||||
|
}
|
||||||
|
return `<div class="diagram-ports">${diagramePorts}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeRightDirection(rightPorts: HdlModulePort[]): string {
|
||||||
|
let rightDirection = '';
|
||||||
|
for (const port of rightPorts) {
|
||||||
|
const portCaption = makePortCaption(port, 'right');
|
||||||
|
let portArrow = makePortArrow(port, 'right');
|
||||||
|
portArrow = portArrow.replace('-0.5 -0.5 125 45', '20 -0.5 125 45');
|
||||||
|
console.log(portArrow);
|
||||||
|
|
||||||
|
const arrow = `<div class="arrow-wrapper">${portCaption}${portArrow}</div>`;
|
||||||
|
rightDirection += arrow;
|
||||||
|
}
|
||||||
|
return `<div class="right-direction">${rightDirection}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
makeDiagram
|
||||||
|
};
|
@ -110,6 +110,7 @@ async function makeShowHTML(usage: string): Promise<string> {
|
|||||||
|
|
||||||
// start to render the real html
|
// start to render the real html
|
||||||
let body = '';
|
let body = '';
|
||||||
|
|
||||||
for (const r of renderList) {
|
for (const r of renderList) {
|
||||||
const renderResult = r.render();
|
const renderResult = r.render();
|
||||||
if (renderResult) {
|
if (renderResult) {
|
||||||
@ -150,6 +151,7 @@ async function showDocWebview() {
|
|||||||
|
|
||||||
webview.iconPath = hdlIcon.getIconConfig('documentation');
|
webview.iconPath = hdlIcon.getIconConfig('documentation');
|
||||||
webview.webview.html = await htmlPromise;
|
webview.webview.html = await htmlPromise;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
import * as fspath from 'path';
|
||||||
|
|
||||||
import { AbsPath, opeParam, MainOutput, ReportType } from '../../global';
|
import { AbsPath, opeParam, MainOutput, ReportType } from '../../global';
|
||||||
import { hdlParam, HdlModule } from '../../hdlParser/core';
|
import { hdlParam, HdlModule } from '../../hdlParser/core';
|
||||||
@ -10,6 +11,8 @@ import { MarkdownString, RenderString, RenderType,
|
|||||||
import { hdlPath, hdlFile } from '../../hdlFs';
|
import { hdlPath, hdlFile } from '../../hdlFs';
|
||||||
|
|
||||||
import { getSymbolComments } from '../lsp/util/feature';
|
import { getSymbolComments } from '../lsp/util/feature';
|
||||||
|
import { HdlLangID } from '../../global/enum';
|
||||||
|
import { makeDiagram } from './diagram';
|
||||||
|
|
||||||
|
|
||||||
function makeSVGElementByLink(link: AbsPath, caption?: string) {
|
function makeSVGElementByLink(link: AbsPath, caption?: string) {
|
||||||
@ -22,6 +25,26 @@ function makeSVGElementByLink(link: AbsPath, caption?: string) {
|
|||||||
return '<br>' + mainHtml + '<br><br>\n';
|
return '<br>' + mainHtml + '<br><br>\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectFieldValue(obj: any, subName: string, ws: string, name: string): string {
|
||||||
|
if (subName === 'empty') {
|
||||||
|
return '——';
|
||||||
|
}
|
||||||
|
let value = obj[subName];
|
||||||
|
if (subName === 'instModPath' && value) {
|
||||||
|
value = value.replace(ws, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value && value.trim().length === 0) {
|
||||||
|
return '——';
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO : 1 not known
|
||||||
|
if (name === 'ports' && value === '1') {
|
||||||
|
return '——';
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function makeTableFromObjArray(md: MarkdownString, array: any[], name: string, fieldNames: string[], displayNames: string[]) {
|
function makeTableFromObjArray(md: MarkdownString, array: any[], name: string, fieldNames: string[], displayNames: string[]) {
|
||||||
const ws = hdlPath.toSlash(opeParam.workspacePath) + '/';
|
const ws = hdlPath.toSlash(opeParam.workspacePath) + '/';
|
||||||
@ -32,19 +55,7 @@ function makeTableFromObjArray(md: MarkdownString, array: any[], name: string, f
|
|||||||
for (const obj of array) {
|
for (const obj of array) {
|
||||||
const data = [];
|
const data = [];
|
||||||
for (const subName of fieldNames) {
|
for (const subName of fieldNames) {
|
||||||
let value = obj[subName];
|
const value = selectFieldValue(obj, subName, ws, name);
|
||||||
if (subName === 'instModPath' && value) {
|
|
||||||
value = value.replace(ws, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value && value.trim().length === 0) {
|
|
||||||
value = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO : 1 not known
|
|
||||||
if (name === 'ports' && value === 'Unknown') {
|
|
||||||
value = '1';
|
|
||||||
}
|
|
||||||
data.push(value);
|
data.push(value);
|
||||||
}
|
}
|
||||||
rows.push(data);
|
rows.push(data);
|
||||||
@ -63,7 +74,7 @@ function makeTableFromObjArray(md: MarkdownString, array: any[], name: string, f
|
|||||||
* @param {string} path
|
* @param {string} path
|
||||||
* @param {Array<ModPort|ModParam>} ports
|
* @param {Array<ModPort|ModParam>} ports
|
||||||
*/
|
*/
|
||||||
async function patchComment(path: AbsPath, ports: (HdlModulePort | HdlModuleParam)[]) {
|
async function patchComment(path: AbsPath, ports: (HdlModulePort | HdlModuleParam)[]) {
|
||||||
if (!ports || !ports.length) {
|
if (!ports || !ports.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -71,7 +82,7 @@ async function patchComment(path: AbsPath, ports: (HdlModulePort | HdlModulePara
|
|||||||
const comments = await getSymbolComments(path, ranges);
|
const comments = await getSymbolComments(path, ranges);
|
||||||
for (let i = 0; i < ports.length; ++ i) {
|
for (let i = 0; i < ports.length; ++ i) {
|
||||||
let inlineComment = comments[i].replace(/\n/, ' ');
|
let inlineComment = comments[i].replace(/\n/, ' ');
|
||||||
if (inlineComment.startsWith('//')) {
|
if (inlineComment.startsWith('//') || inlineComment.startsWith('--')) {
|
||||||
inlineComment = inlineComment.substring(2);
|
inlineComment = inlineComment.substring(2);
|
||||||
}
|
}
|
||||||
ports[i].desc = inlineComment;
|
ports[i].desc = inlineComment;
|
||||||
@ -100,33 +111,46 @@ async function getDocsFromModule(module: HdlModule): Promise<MarkdownString> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const md = new MarkdownString(module.range.start.line);
|
const md = new MarkdownString(module.range.start.line);
|
||||||
|
|
||||||
|
if (module.languageId === HdlLangID.Vhdl) {
|
||||||
|
md.addTitle('Entity: `' + moduleName + '`', 1);
|
||||||
|
} else if (module.languageId === HdlLangID.Verilog) {
|
||||||
|
md.addTitle('Module: `' + moduleName + '`', 1);
|
||||||
|
} else if (module.languageId === HdlLangID.SystemVerilog) {
|
||||||
|
md.addTitle('Module: `' + moduleName + '`', 1);
|
||||||
|
}
|
||||||
|
|
||||||
// add module name
|
// add module name
|
||||||
md.addTitle(moduleName, 1);
|
|
||||||
md.addTitle('Basic Info', 2);
|
md.addTitle('Basic Info', 2);
|
||||||
|
|
||||||
const infos = [
|
const infos = [
|
||||||
|
`**File:** ${fspath.basename(module.file.path)}`,
|
||||||
`${portNum} params, ${paramNum} ports`,
|
`${portNum} params, ${paramNum} ports`,
|
||||||
'top module ' + topModuleDesc
|
'top module ' + topModuleDesc
|
||||||
];
|
];
|
||||||
md.addUnorderedList(infos);
|
md.addUnorderedList(infos);
|
||||||
md.addEnter();
|
md.addEnter();
|
||||||
|
|
||||||
|
const diagram = makeDiagram(module.params, module.ports);
|
||||||
|
md.addText(diagram);
|
||||||
|
|
||||||
// wait param and port patch
|
// wait param and port patch
|
||||||
await paramPP;
|
await paramPP;
|
||||||
await portPP;
|
await portPP;
|
||||||
|
|
||||||
// param section
|
// param section
|
||||||
md.addTitle('params', 2);
|
md.addTitle('Params', 2);
|
||||||
makeTableFromObjArray(md, module.params, 'params',
|
makeTableFromObjArray(md, module.params, 'params',
|
||||||
['name', 'init', 'desc'],
|
['name', 'init', 'empty', 'desc'],
|
||||||
['name', 'init', 'description']);
|
['Param Name', 'Init', 'Range', 'Description']);
|
||||||
md.addEnter();
|
md.addEnter();
|
||||||
|
|
||||||
|
|
||||||
// port section
|
// port section
|
||||||
md.addTitle('ports', 2);
|
md.addTitle('Ports', 2);
|
||||||
makeTableFromObjArray(md, module.ports, 'ports',
|
makeTableFromObjArray(md, module.ports, 'ports',
|
||||||
['name', 'type', 'width', 'desc'],
|
['name', 'type', 'width', 'desc'],
|
||||||
['name', 'type', 'width', 'description']);
|
['Port Name', 'Direction', 'Range', 'Description']);
|
||||||
md.addEnter();
|
md.addEnter();
|
||||||
|
|
||||||
|
|
||||||
|
@ -195,6 +195,7 @@ class VlogCompletionProvider implements vscode.CompletionItemProvider {
|
|||||||
completions.push(...this.makeCompilerKeywordItems(document, position));
|
completions.push(...this.makeCompilerKeywordItems(document, position));
|
||||||
completions.push(...this.makeSystemKeywordItems(document, position));
|
completions.push(...this.makeSystemKeywordItems(document, position));
|
||||||
|
|
||||||
|
|
||||||
const symbolResult = await hdlSymbolStorage.getSymbol(filePath);
|
const symbolResult = await hdlSymbolStorage.getSymbol(filePath);
|
||||||
if (!symbolResult) {
|
if (!symbolResult) {
|
||||||
return completions;
|
return completions;
|
||||||
@ -215,6 +216,7 @@ class VlogCompletionProvider implements vscode.CompletionItemProvider {
|
|||||||
return completions;
|
return completions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 3. provide modules
|
// 3. provide modules
|
||||||
const suggestModulesPromise = this.provideModules(document, position, filePath, symbolResult.macro.includes);
|
const suggestModulesPromise = this.provideModules(document, position, filePath, symbolResult.macro.includes);
|
||||||
|
|
||||||
|
@ -131,17 +131,17 @@ async function getFullSymbolInfo(document: vscode.TextDocument, range: Range, no
|
|||||||
|
|
||||||
let content = '';
|
let content = '';
|
||||||
let is_b_comment = false;
|
let is_b_comment = false;
|
||||||
let line = range.start.line + 1;
|
let line = range.start.line;
|
||||||
const firstLine = range.start.line - 1;
|
|
||||||
console.log('enter getFullSymbolInfo');
|
// vscode 的行编号从 0 开始算
|
||||||
|
const firstLine = range.start.line - 1;
|
||||||
|
|
||||||
while (line) {
|
while (line) {
|
||||||
line --;
|
line --;
|
||||||
content = document.lineAt(line).text;
|
content = document.lineAt(line).text;
|
||||||
|
|
||||||
// 首先判断该行是否是空白
|
// 首先判断该行是否是空白
|
||||||
let isblank = content.match(nonblank);
|
if (content.trim().length === 0) {
|
||||||
if (!isblank) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ async function getFullSymbolInfo(document: vscode.TextDocument, range: Range, no
|
|||||||
if (b_comment_begin_index === -1) {
|
if (b_comment_begin_index === -1) {
|
||||||
comments.push(content + '\n');
|
comments.push(content + '\n');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
comments.push(content.slice(b_comment_begin_index, content.length) + '\n');
|
comments.push(content.slice(b_comment_begin_index, content.length) + '\n');
|
||||||
is_b_comment = false;
|
is_b_comment = false;
|
||||||
content = content.slice(0, b_comment_begin_index);
|
content = content.slice(0, b_comment_begin_index);
|
||||||
@ -161,24 +161,22 @@ async function getFullSymbolInfo(document: vscode.TextDocument, range: Range, no
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 判断该行是否存在行注释
|
// 判断该行是否存在行注释
|
||||||
let l_comment_index = content.indexOf(l_comment_symbol);
|
let l_comment_index = content.indexOf(l_comment_symbol);
|
||||||
|
|
||||||
if (l_comment_index >= 0) {
|
|
||||||
let before_l_comment = content.slice(0, l_comment_index);
|
|
||||||
if (before_l_comment.match(nonblank)) {
|
|
||||||
// TODO : check again if bug takes place
|
|
||||||
comments.push(content.slice(l_comment_index, content.length) + '\n');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 否则该行全为该定义的注释
|
|
||||||
comments.push(content + '\n');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断该行是否存在块注释
|
// 判断该行是否存在块注释
|
||||||
let b_comment_end_index = content.indexOf('*/');
|
let b_comment_end_index = content.indexOf('*/');
|
||||||
if (b_comment_end_index >= 0) {
|
|
||||||
|
if (l_comment_index >= 0) {
|
||||||
|
let before_l_comment = content.slice(0, l_comment_index);
|
||||||
|
// 判断当前的行注释的注释前面是不是还有字符串
|
||||||
|
if (!before_l_comment.match(nonblank) || line === firstLine) {
|
||||||
|
const l_comment = content.slice(l_comment_index, content.length) + '\n';
|
||||||
|
comments.push(l_comment);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// 否则该行全为该定义的注释
|
||||||
|
comments.push(content + '\n');
|
||||||
|
|
||||||
|
} else if (b_comment_end_index >= 0) {
|
||||||
b_comment_end_index += 2;
|
b_comment_end_index += 2;
|
||||||
let behind_b_comment = content.slice(b_comment_end_index, content.length);
|
let behind_b_comment = content.slice(b_comment_end_index, content.length);
|
||||||
behind_b_comment = del_comments(behind_b_comment, l_comment_regExp);
|
behind_b_comment = del_comments(behind_b_comment, l_comment_regExp);
|
||||||
@ -191,18 +189,12 @@ async function getFullSymbolInfo(document: vscode.TextDocument, range: Range, no
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
comments.push(content + '\n');
|
comments.push(content + '\n');
|
||||||
is_b_comment = true;
|
is_b_comment = true;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 说明既不是块注释又不是行注释所以就是到了代码块
|
|
||||||
if (line !== firstLine) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清除空前行
|
// 清除空前行
|
||||||
let resultComment = '';
|
let resultComment = '';
|
||||||
for (const c of comments.reverse()) {
|
for (const c of comments.reverse()) {
|
||||||
|
@ -44,13 +44,14 @@ function instanceVlogCode(module: HdlModule, prefix: string = '', returnSnippetS
|
|||||||
}
|
}
|
||||||
|
|
||||||
content.appendText(prefix + module.name + ' ');
|
content.appendText(prefix + module.name + ' ');
|
||||||
|
makeVlogParamAssignments(content, module.params, prefix, returnSnippetString, needComment);
|
||||||
|
|
||||||
if (returnSnippetString) {
|
if (returnSnippetString) {
|
||||||
content.appendPlaceholder('u_' + module.name);
|
content.appendPlaceholder('u_' + module.name);
|
||||||
} else {
|
} else {
|
||||||
content.appendText('u_' + module.name);
|
content.appendText('u_' + module.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
makeVlogParamAssignments(content, module.params, prefix, returnSnippetString, needComment);
|
|
||||||
makeVlogPortAssignments(content, module.ports, prefix, returnSnippetString, needComment);
|
makeVlogPortAssignments(content, module.ports, prefix, returnSnippetString, needComment);
|
||||||
|
|
||||||
const instanceString = content.value;
|
const instanceString = content.value;
|
||||||
@ -165,8 +166,8 @@ function makeVlogParamAssignments(content: vscode.SnippetString, params: HdlModu
|
|||||||
content.appendText(' '.repeat(maxInitLength - param.init.length + 1) + ' )');
|
content.appendText(' '.repeat(maxInitLength - param.init.length + 1) + ' )');
|
||||||
if (i < params.length - 1) {
|
if (i < params.length - 1) {
|
||||||
content.appendText(',');
|
content.appendText(',');
|
||||||
|
content.appendText('\n');
|
||||||
}
|
}
|
||||||
content.appendText('\n');
|
|
||||||
}
|
}
|
||||||
content.appendText(prefix + ')\n');
|
content.appendText(prefix + ')\n');
|
||||||
}
|
}
|
||||||
|