This commit is contained in:
Heekang Park 2023-02-11 07:02:20 +09:00
parent b07a282205
commit 84d346d37d
16 changed files with 398 additions and 22 deletions

View file

@ -22,6 +22,30 @@ You can add title to the code block like this.
You must put the title in quotes. You can use both single and double quotes.
### Collapse
You must use the title feature to use the collapse feature. You can collapse the code block like this.
```python title:"Title of the code block" collapse
print("Hello world")
```
Or like this.
```python title:"Title of the code block" collapse:true
print("Hello world")
```
![collapsible1](https://github.com/HeekangPark/obsidian-hk-code-block/raw/master/imgs/collapsible1.png)
![collapsible2](https://github.com/HeekangPark/obsidian-hk-code-block/raw/master/imgs/collapsible2.png)
If you want to explicitly expand the code block, you can do it like this.
```python title:"Title of the code block" collapse:false
print("Hello world")
```
### Line Numbers
You can add line numbers to the code block like this.
@ -238,6 +262,15 @@ You can change the default settings of each feature of HK Code Block in the sett
- default off, but on when specified : the title will only be shown if the title statement is specified
- always off : the title will never be shown
### Collapse
- Use Collapse
- always on : the code block will always be collapsible
- default on, but off when specified : the code block will always be collapsible, but will not be collapsed if collapse statement is specified as false
- default off, but on when specified : the code block will only be collapsible if the collapse statement is specified as true
- always off : the code block will never be collapsible
- Default Collapse State : the default collapse state of the code block
### Line numbers
- Use Line Numbers
@ -315,4 +348,9 @@ MIT License
### 0.1.0
- Initial release
- Initial release
### 0.2.0
- Add features
- Add collapse feature

View file

@ -22,6 +22,30 @@ HK CodeBlock을 이용하면 Code Block에 다양한 기능들을 추가할 수
반드시 따옴표 안에 제목을 넣어야 합니다. 큰따옴표와 작은 따옴표 모두 사용 가능합니다.
### 접기
접기 기능을 사용하려면 반드시 제목을 설정해야 합니다. 다음과 같이 하고 제목을 클릭하면 Code Block을 접거나 펼 수 있습니다.
```python title:"Title of the code block" collapsible
print("Hello world")
```
또는 다음과 같이 할 수도 있습니다.
```python title:"Title of the code block" collapsible:true
print("Hello world")
```
![collapsible1](https://github.com/HeekangPark/obsidian-hk-code-block/raw/master/imgs/collapsible1.png)
![collapsible2](https://github.com/HeekangPark/obsidian-hk-code-block/raw/master/imgs/collapsible2.png)
다음과 같이 하면 명시적으로 접기 기능을 끌 수 있습니다.
```python title:"Title of the code block" collapsible:false
print("Hello world")
```
### 줄 번호
다음과 같이 하면 Code Block에 줄 번호를 추가할 수 있습니다.
@ -238,6 +262,15 @@ Result Code Block의 프롬프트는 설정에서 설정한 값(기본값: "Resu
- default off, but on when specified : 기본적으로 제목 기능을 사용하지 않습니다. 하지만 title 옵션을 명시하면 제목 기능을 사용합니다.
- always off : 제목 기능을 항상 사용하지 않습니다.
### Collapse
- Use Collapse
- always on : 접기 기능을 항상 사용합니다.
- default on, but off when specified : 기본적으로 접기 기능을 사용합니다. 하지만 접기 기능을 사용하지 않는다고 명시하면 접기 기능을 사용하지 않습니다.
- default off, but on when specified : 기본적으로 접기 기능을 사용하지 않습니다. 하지만 접기 기능을 사용한다고 명시하면 접기 기능을 사용합니다.
- always off : 접기 기능을 항상 사용하지 않습니다.
- Default Collapse State : 접기 기능을 사용할 때, 기본적으로 접힌 상태로 보여줄지 펼쳐진 상태로 보여줄지를 설정합니다.
### Line numbers
- Use Line Numbers
@ -315,4 +348,9 @@ MIT License
### 0.1.0
- 최초 배포
- 최초 배포
### 0.2.0
- 기능 추가
- 접기 기능 추가

83
dist/main.js vendored

File diff suppressed because one or more lines are too long

4
dist/manifest.json vendored
View file

@ -1,11 +1,11 @@
{
"id": "hk-code-block",
"name": "HK Code Block",
"version": "0.1.0",
"version": "0.2.0",
"minAppVersion": "1.0.0",
"description": "Obsidian plugin developed by Heekang Park; Make code block looking good on reading view",
"author": "Heekang Park",
"authorUrl": "https://github.com/HeekangPark",
"fundingUrl": "",
"isDesktopOnly": false
}
}

43
dist/styles.css vendored

File diff suppressed because one or more lines are too long

3
dist/versions.json vendored
View file

@ -1,3 +1,4 @@
{
"0.1.0": "0.15.0"
"0.1.0": "1.0.0",
"0.2.0": "1.0.0"
}

View file

@ -1,6 +1,7 @@
import esbuild from "esbuild";
import process from "process";
import builtins from "builtin-modules";
import { copyFile } from "fs/promises";
import { sassPlugin } from "esbuild-sass-plugin";
const banner =
@ -42,7 +43,18 @@ const context = await esbuild.context({
sourcemap: prod ? false : "inline",
treeShaking: true,
outdir: "./dist",
plugins: [sassPlugin()]
plugins: [
sassPlugin(),
{
name: "copy-build-files-to-root",
setup(build) {
build.onEnd(() => {
copyFile("./dist/main.js", "./main.js");
copyFile("./dist/styles.css", "./styles.css");
});
}
}
]
});
if (prod) {

BIN
imgs/collapsible1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
imgs/collapsible2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

View file

@ -1,7 +1,7 @@
{
"id": "hk-code-block",
"name": "HK Code Block",
"version": "0.1.0",
"version": "0.2.0",
"minAppVersion": "1.0.0",
"description": "Obsidian plugin developed by Heekang Park; Make code block looking good on reading view",
"author": "Heekang Park",

View file

@ -1,8 +1,8 @@
{
"name": "obsidian-hk-code-block",
"version": "0.1.0",
"version": "0.2.0",
"description": "Obsidian plugin developed by Heekang Park; Make code block looking good on reading view",
"main": "main.js",
"main": "./dist/main.js",
"scripts": {
"dev": "node esbuild.config.mjs",
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",

View file

@ -6,6 +6,8 @@ import type { HKCodeBlockSettings } from "./HKCodeBlockSettings";
const REGEX = {
TITLE: /\stitle:(?:'(.*?)'|"(.*?)")\s/,
COLLAPSIBLE_SIMPLE: /\scollapsible\s/,
COLLAPSIBLE_COMPLICATE: /\scollapsible:(true|false)\s/,
LINENOS_SIMPLE: /\slinenos\s/,
LINENOS_COMPLICATE: /\slinenos:(true|false|(-{0,1}\d+))\s/,
HIGHLIGHT: /\shighlight:(?:'(.*?)'|"(.*?)")\s/,
@ -22,6 +24,7 @@ const REGEX = {
function getMeta(view: MarkdownView, elem_code: HTMLElement, section_code: MarkdownSectionInformation, settings: HKCodeBlockSettings): {
showTitle: (boolean | undefined),
title: string,
isCollapsible: (boolean | undefined),
showLinenos: (boolean | undefined),
linenosStart: number,
linenosNum: number,
@ -46,6 +49,20 @@ function getMeta(view: MarkdownView, elem_code: HTMLElement, section_code: Markd
title = regexResult_title[1] || regexResult_title[2];
}
// collapsible
let isCollapsible: (boolean | undefined) = undefined;
const regexResult_collapsibleSimple = REGEX.COLLAPSIBLE_SIMPLE.exec(firstline);
const regexResult_collapsibleComplicate = REGEX.COLLAPSIBLE_COMPLICATE.exec(firstline);
if (regexResult_collapsibleSimple) {
isCollapsible = true;
} else if (regexResult_collapsibleComplicate) {
if (regexResult_collapsibleComplicate[1] === "true") {
isCollapsible = true;
} else if (regexResult_collapsibleComplicate[1] === "false") {
isCollapsible = false;
}
}
// linenos
let showLinenos: (boolean | undefined) = undefined;
let linenosStart = settings.defaultLinenosStart;
@ -149,7 +166,7 @@ function getMeta(view: MarkdownView, elem_code: HTMLElement, section_code: Markd
const regexResultPrompt_result = REGEX.PROMPT_COMPLICATE.exec(firstline);
if (regexResult_result) {
isResult = true;
// override other meta data : only linenos, highlight are available
showTitle = false;
showLanguage = false;
@ -164,6 +181,7 @@ function getMeta(view: MarkdownView, elem_code: HTMLElement, section_code: Markd
return {
showTitle: showTitle,
title: title,
isCollapsible: isCollapsible,
showLinenos: showLinenos,
linenosStart: linenosStart,
linenosNum: linenosNum,
@ -205,9 +223,10 @@ export async function HKCodeBlockProcessor(
if (!section_code) return;
// get metadata
const {
const {
showTitle,
title,
isCollapsible,
showLinenos,
linenosStart,
linenosNum,
@ -223,7 +242,7 @@ export async function HKCodeBlockProcessor(
} = getMeta(view, elem_code, section_code, settings);
if (settings.debugMode) {
console.log({
console.log({
showTitle: showTitle,
title: title,
showLinenos: showLinenos,
@ -246,15 +265,60 @@ export async function HKCodeBlockProcessor(
elem_code.classList.add("hk-codeblock-code");
elem_copyBtn.remove(); // remove the original copy button as default
let elem_title: (HTMLElement | undefined) = undefined;
if (settings.useTitleGlobal === "default off, but on when specified" && (showTitle === true)) {
elem_div.classList.add("hk-codeblock-show-title");
const elem_title = document.createElement("div");
elem_title = document.createElement("div");
elem_title.classList.add("hk-codeblock-title");
elem_title.innerHTML = title;
elem_div.insertBefore(elem_title, elem_pre);
}
if (
(settings.useCollapsibleGlobal === "always on") ||
(settings.useCollapsibleGlobal === "default on, but off when specified" && (isCollapsible === undefined || isCollapsible === true)) ||
(settings.useCollapsibleGlobal === "default off, but on when specified" && (isCollapsible === true))
) {
elem_div.classList.add("hk-codeblock-collapsible");
if (settings.defaultCollapse === "collapse") {
elem_div.classList.add("hk-codeblock-collapsed");
}
if (elem_title) {
elem_title.addEventListener("click", (ev) => {
ev.stopPropagation();
ev.preventDefault();
if (elem_div.classList.contains("hk-codeblock-collapsed")) {
elem_div.classList.remove("hk-codeblock-collapsed");
} else {
elem_div.classList.add("hk-codeblock-collapsed");
}
});
const elem_collapseBtns = document.createElement("div");
elem_collapseBtns.classList.add("hk-codeblock-collapse-btns");
const elem_collapseBtn = document.createElement("div");
elem_collapseBtn.classList.add("hk-codeblock-collapse-btn", "hk-codeblock-collapsed-btn");
elem_collapseBtn.innerHTML = `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M10 19a1 1 0 0 1-.64-.23 1 1 0 0 1-.13-1.41L13.71 12 9.39 6.63a1 1 0 0 1 .15-1.41 1 1 0 0 1 1.46.15l4.83 6a1 1 0 0 1 0 1.27l-5 6A1 1 0 0 1 10 19z"/>
</svg>`;
elem_collapseBtns.appendChild(elem_collapseBtn);
const elem_expandBtn = document.createElement("div");
elem_expandBtn.classList.add("hk-codeblock-collapse-btn", "hk-codeblock-expanded-btn");
elem_expandBtn.innerHTML = `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M12 16a1 1 0 0 1-.64-.23l-6-5a1 1 0 1 1 1.28-1.54L12 13.71l5.36-4.32a1 1 0 0 1 1.41.15 1 1 0 0 1-.14 1.46l-6 4.83A1 1 0 0 1 12 16z"/>
</svg>`;
elem_collapseBtns.appendChild(elem_expandBtn);
elem_title.prepend(elem_collapseBtns);
}
}
if (
(settings.useLinenosGlobal === "always on") ||
(settings.useLinenosGlobal === "default on, but off when specified" && (showLinenos === undefined || showLinenos === true)) ||
@ -334,7 +398,7 @@ export async function HKCodeBlockProcessor(
elem_pre.setAttribute("data-output", no_prompt_line_idxs.join(", "));
}
if(settings.useResultGlobal === "enable" && (isResult === true)) {
if (settings.useResultGlobal === "enable" && (isResult === true)) {
elem_div.classList.add("hk-codeblock-result");
elem_code.classList.add("hk-codeblock-result-code");

View file

@ -39,6 +39,44 @@ export class HKCodeBlockSettingTab extends PluginSettingTab {
})
);
// collapse
containerEl.createEl('h2', { text: 'Collapse' });
new Setting(containerEl)
.setName('Use Collapse')
.setDesc(fragWithHTML(`- <b>always on</b> : the code block will always be collapsible
- <b>default on, but off when specified</b> : the code block will always be collapsible, but will not be collapsed if collapse statement is specified as false
- <b>default off, but on when specified</b> : the code block will only be collapsible if the collapse statement is specified as true
- <b>always off</b> : the code block will never be collapsible`))
.addDropdown(tc =>
tc.addOptions({
"always on": "always on",
"default on, but off when specified": "default on, but off when specified",
"default off, but on when specified": "default off, but on when specified",
"always off": "always off",
})
.setValue(this.plugin.settings.useCollapsibleGlobal)
.onChange(async (value: string) => {
this.plugin.settings.useCollapsibleGlobal = value as ("always on" | "default on, but off when specified" | "default off, but on when specified" | "always off");
await this.plugin.saveSettings();
})
);
new Setting(containerEl)
.setName('Default Collapse State')
.setDesc('The default collapse state of the code block.')
.addDropdown(tc =>
tc.addOptions({
"collapse": "collapse",
"expand": "expand",
})
.setValue(this.plugin.settings.defaultCollapse)
.onChange(async (value: string) => {
this.plugin.settings.defaultCollapse = value as ("collapse" | "expand");
await this.plugin.saveSettings();
})
);
// line numbers
containerEl.createEl('h2', { text: 'Line Numbers' });
@ -181,8 +219,7 @@ export class HKCodeBlockSettingTab extends PluginSettingTab {
.setDesc(fragWithHTML(`- <b>always on</b> : prompt will always be shown
- <b>default on, but off when specified</b> : prompt will always be shown, but will not be shown if the prompt statement is specified as false
- <b>default off, but on when specified</b> : prompt will only be shown if the prompt statement is specified as true
- <b>always off</b> : prompt will never be shown
You can also specify the prompt by the statement like \`prompt:"My Prompt"\`. (default: "$")`))
- <b>always off</b> : prompt will never be shown`))
.addDropdown(tc =>
tc.addOptions({
"always on": "always on",

View file

@ -1,6 +1,10 @@
export interface HKCodeBlockSettings {
useTitleGlobal: ("default off, but on when specified" | "always off");
useCollapsibleGlobal: ("always on" | "default on, but off when specified" | "default off, but on when specified" | "always off");
defaultCollapse: ("collapse" | "expand");
showCollapseBtn: boolean;
useLinenosGlobal: ("always on" | "default on, but off when specified" | "default off, but on when specified" | "always off");
defaultLinenosStart: number;
showLinenosSplitter: boolean;
@ -26,6 +30,10 @@ export interface HKCodeBlockSettings {
export const DEFAULT_SETTINGS: HKCodeBlockSettings = {
useTitleGlobal: "default off, but on when specified",
useCollapsibleGlobal: "default on, but off when specified",
defaultCollapse: "expand",
showCollapseBtn: true,
useLinenosGlobal: "default off, but on when specified",
defaultLinenosStart: 1,
showLinenosSplitter: true,

View file

@ -48,6 +48,10 @@
background-color: var(--hk-codeblock-background-color);
border-bottom: 1px solid var(--hk-codeblock-border-color);
color: var(--hk-codeblock-title-text-color);
display: flex;
flex-direction: row;
align-items: center;
}
.hk-codeblock-title~pre {
@ -55,6 +59,63 @@
}
}
/* collapse */
.hk-codeblock.hk-codeblock-show-title.hk-codeblock-collapsible {
.hk-codeblock-title {
cursor: pointer;
position: relative;
.hk-codeblock-collapse-btns {
display: inline-flex;
align-items: center;
justify-content: center;
margin-right: 4px;
position: relative;
top: -1px;
.hk-codeblock-collapse-btn {
width: 16px;
height: 16px;
fill: var(--hk-codeblock-title-text-color);
stroke: var(--hk-codeblock-title-text-color);
stroke-width: 2;
opacity: 0.2;
&.hk-codeblock-collapsed-btn {
display: none;
}
&.hk-codeblock-expanded-btn {
display: inline-block;
}
}
}
}
&.hk-codeblock-collapsed {
.hk-codeblock-title {
border-bottom: none;
.hk-codeblock-collapse-btns {
.hk-codeblock-collapse-btn {
&.hk-codeblock-collapsed-btn {
display: inline-block;
}
&.hk-codeblock-expanded-btn {
display: none;
}
}
}
}
pre {
display: none;
}
}
}
/* linenos */
.hk-codeblock.hk-codeblock-show-linenos {
pre {

View file

@ -1,3 +1,4 @@
{
"0.1.0": "0.15.0"
"0.1.0": "1.0.0",
"0.2.0": "1.0.0"
}