Skip to content

Commit c0644d2

Browse files
committed
Update style guide to include new import methods and add ability to import from a URL
1 parent 1c48f18 commit c0644d2

File tree

2 files changed

+84
-12
lines changed

2 files changed

+84
-12
lines changed

contribute/style-guide.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,44 @@ SELECT * FROM system.contributors;
112112
\```
113113
```
114114

115+
Note: in the snippet above `\` is used only for formatting purposes in this guide.
116+
You should not include it when you write markdown.
117+
115118
Code blocks:
116119
- Should always have a language defined immediately next to the opening 3
117120
backticks, without any space.
118121
- Have a title (optional) such as 'Query' or 'Response'
119122
- Use language `response` if it is for the result of a query.
120123

124+
#### Importing code from files or URLs
125+
126+
There are a few additional parameters you can include on a code block if you want
127+
to import code.
128+
129+
To import from a file use `file=`:
130+
131+
```text
132+
\```python file=code_snippets/integrations/example.py
133+
Code will be inserted here
134+
\```
135+
```
136+
137+
When `yarn build` is run, the code from the file will be inserted as text into
138+
the code block.
139+
140+
To import from a url use `url=`:
141+
142+
```text
143+
\```python url=https://raw.githubusercontent.com/ClickHouse/clickhouse-connect/refs/heads/main/examples/pandas_examples.py
144+
Code will be inserted here
145+
\```
146+
```
147+
148+
You should commit the code inserted to the snippet as we want people (or LLMs)
149+
reading the markdown to be able to see the code. The advantage of importing code
150+
to snippets this way is that you can test your snippets externally or store them
151+
wherever you want.
152+
121153
### Highlighting
122154

123155
You can highlight lines in a code block using the following keywords:

plugins/code-import-plugin.js

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
const fs = require('fs');
22
const path = require('path');
33
const glob = require('glob');
4+
const https = require('https');
5+
const http = require('http');
6+
7+
// Helper function to fetch content from URL
8+
function fetchUrl(url) {
9+
return new Promise((resolve, reject) => {
10+
const client = url.startsWith('https:') ? https : http;
11+
12+
client.get(url, (res) => {
13+
if (res.statusCode !== 200) {
14+
reject(new Error(`HTTP ${res.statusCode}: ${res.statusMessage}`));
15+
return;
16+
}
17+
18+
let data = '';
19+
res.on('data', chunk => data += chunk);
20+
res.on('end', () => resolve(data));
21+
}).on('error', reject);
22+
});
23+
}
424

525
function codeImportPlugin(context, options) {
626
return {
@@ -22,24 +42,44 @@ function codeImportPlugin(context, options) {
2242
let content = fs.readFileSync(filePath, 'utf8');
2343
let modified = false;
2444

25-
// Process code blocks with file= syntax
26-
content = content.replace(/```(\w+)?\s*(file=[^\s\n]+)([^\n]*)\n([^`]*?)```/g, (match, lang, fileParam, additionalMeta, existingContent) => {
45+
// Process code blocks with file= or url= syntax
46+
const fileUrlRegex = /```(\w+)?\s*((?:file|url)=[^\s\n]+)([^\n]*)\n([^`]*?)```/g;
47+
const matches = [...content.matchAll(fileUrlRegex)];
48+
49+
for (const match of matches) {
50+
const [fullMatch, lang, param, additionalMeta, existingContent] = match;
51+
2752
try {
28-
const importPath = fileParam.replace('file=', '');
29-
const absoluteImportPath = path.resolve(context.siteDir, importPath);
30-
const importedContent = fs.readFileSync(absoluteImportPath, 'utf8');
31-
modified = true;
53+
let importedContent;
54+
55+
if (param.startsWith('file=')) {
56+
// Handle file import
57+
const importPath = param.replace('file=', '');
58+
const absoluteImportPath = path.resolve(context.siteDir, importPath);
59+
importedContent = fs.readFileSync(absoluteImportPath, 'utf8');
60+
} else if (param.startsWith('url=')) {
61+
// Handle URL import
62+
const url = param.replace('url=', '');
63+
try {
64+
importedContent = await fetchUrl(url);
65+
} catch (urlError) {
66+
console.warn(`Could not fetch URL ${url} in ${filePath}: ${urlError.message}`);
67+
continue; // Skip this replacement if URL fetch fails
68+
}
69+
}
3270

33-
// Preserve the complete metadata including file= and any additional parameters
34-
const fullMeta = `${fileParam}${additionalMeta}`;
71+
// Preserve the complete metadata
72+
const fullMeta = `${param}${additionalMeta}`;
3573
const metaStr = fullMeta ? ` ${fullMeta}` : '';
74+
const replacement = `\`\`\`${lang || ''}${metaStr}\n${importedContent}\`\`\``;
75+
76+
content = content.replace(fullMatch, replacement);
77+
modified = true;
3678

37-
return `\`\`\`${lang || ''}${metaStr}\n${importedContent}\`\`\``;
3879
} catch (error) {
39-
console.warn(`Could not import file ${importPath} in ${filePath}: ${error.message}`);
40-
return match; // Return original if import fails
80+
console.warn(`Could not process ${param} in ${filePath}: ${error.message}`);
4181
}
42-
});
82+
}
4383

4484
if (modified) {
4585
processedFiles.push({

0 commit comments

Comments
 (0)