]> Git Repo - pico-vscode.git/blob - src/commands/openSdkDocumentation.mts
ed58692fc16342d0dcbd63fc5123f12b66b659f7
[pico-vscode.git] / src / commands / openSdkDocumentation.mts
1 /* eslint-disable max-len */
2 import { CommandWithArgs } from "./command.mjs";
3 import Logger from "../logger.mjs";
4 import { type QuickPickItem, ViewColumn, window, Uri, type WebviewPanel } from "vscode";
5 import { readFileSync } from "fs";
6
7 export enum DocumentationId {
8   hardware = 0,
9   highLevel = 1,
10   networking = 2,
11   runtimeInfrastructure = 3,
12 }
13
14 export const DOCUMENTATION_LABEL_BY_ID: string[] = [
15   "Hardware APIs",
16   "High Level APIs",
17   "Networking Libraries",
18   "Runtime Infrastructure",
19 ];
20
21 // eslint-disable-next-line @typescript-eslint/no-unused-vars
22 const DOCUMENTATION_URLS_BY_ID: string[] = [
23   //"https://raspberrypi.github.io/pico-sdk-doxygen/index.html",
24   "https://www.raspberrypi.com/documentation/pico-sdk/hardware.html",
25   "https://www.raspberrypi.com/documentation/pico-sdk/high_level.html",
26   "https://www.raspberrypi.com/documentation/pico-sdk/networking.html",
27   "https://www.raspberrypi.com/documentation/pico-sdk/runtime.html",
28 ];
29
30 const LOCAL_DOCUMENTATION_URLS_BY_ID: string[] = [
31   "group__hardware.html",
32   "group__high__level.html",
33   "group__networking.html",
34   "group__runtime.html",
35 ];
36
37 export default class OpenSdkDocumentationCommand extends CommandWithArgs {
38   private _logger: Logger = new Logger("OpenSdkDocumentationCommand");
39
40   public static readonly id = "openSdkDocumentation";
41
42   constructor(private readonly _extensionUri: Uri) {
43     super(OpenSdkDocumentationCommand.id);
44   }
45
46   async execute(docId?: DocumentationId, fileName?: string): Promise<void> {
47     let url = "";
48     if (typeof docId === "number") {
49       url = docId !== undefined ? LOCAL_DOCUMENTATION_URLS_BY_ID[docId] : "";
50     } else if (fileName !== undefined) {
51       url = fileName;
52     } else {
53       const options: QuickPickItem[] = DOCUMENTATION_LABEL_BY_ID.map(
54         (label, index) => ({
55           label,
56           detail: LOCAL_DOCUMENTATION_URLS_BY_ID[index],
57         })
58       );
59
60       const result = await window.showQuickPick(options, {
61         placeHolder: "Select Category",
62         canPickMany: false,
63         ignoreFocusOut: false,
64       });
65
66       if (result === undefined || result.detail === undefined) {
67         return;
68       }
69
70       url = result.detail;
71     }
72
73     // show webview
74     this._logger.info("Opening SDK documentation in browser...");
75     const panel = window.createWebviewPanel(
76       "pico-sdk-documentation",
77       "Pico SDK Documentation",
78       { viewColumn: ViewColumn.Two, preserveFocus: false },
79       {
80         enableScripts: true,
81         retainContextWhenHidden: true,
82         enableFindWidget: true,
83         localResourceRoots: [Uri.joinPath(this._extensionUri, "web", "docs")],
84         enableCommandUris: true,
85       }
86     );
87
88     panel.webview.html = this._getHtmlForWebview(
89       Uri.joinPath(this._extensionUri, "web", "docs", url).fsPath,
90       panel.webview
91         .asWebviewUri(
92           Uri.joinPath(this._extensionUri, "web", "docs", "docstyle.css")
93         )
94         .toString(),
95       panel.webview.cspSource,
96       panel,
97       this._extensionUri
98     );
99     panel.reveal();
100   }
101
102   private _getHtmlForWebview(
103     url: string,
104     docstyle: string,
105     cspSource: string,
106     panel: WebviewPanel,
107     extensionUri: Uri
108   ): string {
109     const regexa = /<a\s+(.*?)?href="([^"]+)"/g;
110     const regexsrc = /src="([^"]+)"/g;
111     const regexcss = /<link href="([^"]+)" rel="stylesheet"/g;
112
113     // load from file
114     return (
115       readFileSync(url)
116         .toString("utf-8")
117         .replace(/{{docstyle}}/g, docstyle)
118         /*.replace(/{{jquery}}/g, jquery)
119       .replace(/{{jquery-ui}}/g, jqueryUi)
120       .replace(/{{jquery-tocify}}/g, jqueryTocify)
121       .replace(/{{nonce}}/g, nonce)*/
122         .replace(/{{cspSource}}/g, cspSource)
123         .replace(regexa, function (match, space: string, file: string) {
124           if (file === "/") {
125             file = "index.html";
126           }
127           if (space === undefined) {
128             space = "";
129           }
130           if (file.match('#') || file.match('https')) {
131             if (file.match('#')) {
132               file = `#${file.split('#')[1]}`;
133             }
134             const ret = `<a ${space}href="${file}"`;
135
136             return ret;
137           }
138           const command = Uri.parse(`command:raspberry-pi-pico.openSdkDocumentation?${
139             encodeURIComponent(JSON.stringify([undefined, file]))
140           }`).toString();
141           const ret = `<a ${space}href="${command}"`;
142
143           return ret;
144         })
145         .replace(regexsrc, function (match, file: string) {
146           const ret = `src="${
147             panel.webview
148               .asWebviewUri(
149                 Uri.joinPath(extensionUri, "web", "docs", file)
150               )
151               .toString()}"`;
152
153           return ret;
154         })
155         .replace(regexcss, function (match, file: string) {
156           const ret = `<link href="${
157             panel.webview
158               .asWebviewUri(
159                 Uri.joinPath(extensionUri, "web", "docs", file)
160               )
161               .toString()}" rel="stylesheet"`;
162
163           return ret;
164         })
165         .replace(
166           '<div class="navigation-toggle">',
167           '<div hidden>'
168         )
169         .replace(
170           '<div id="main-nav">',
171           '<div id="main-nav" hidden>'
172         )
173     );
174   }
175 }
This page took 0.027878 seconds and 2 git commands to generate.