@tacone/prosey 0.7.1 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/prosey +70 -11
- package/package.json +1 -1
- package/src/config.test.ts +104 -6
- package/src/config.ts +40 -8
- package/src/default-config.toml +6 -2
- package/src/html.ts +23 -2
- package/src/index.ts +10 -0
package/bin/prosey
CHANGED
|
@@ -101623,26 +101623,55 @@ function configPath() {
|
|
|
101623
101623
|
function ensureDir(path) {
|
|
101624
101624
|
return mkdir(path, { recursive: true });
|
|
101625
101625
|
}
|
|
101626
|
+
function mergeOverDefaults(user, defaults) {
|
|
101627
|
+
return {
|
|
101628
|
+
pager: user.pager ?? defaults.pager,
|
|
101629
|
+
hints: user.hints ?? defaults.hints,
|
|
101630
|
+
format: user.format ?? defaults.format,
|
|
101631
|
+
ai: user.ai?.command !== undefined ? user.ai : defaults.ai,
|
|
101632
|
+
summarize: {
|
|
101633
|
+
command: user.summarize?.command ?? defaults.summarize?.command,
|
|
101634
|
+
prompt: user.summarize?.prompt ?? defaults.summarize?.prompt
|
|
101635
|
+
},
|
|
101636
|
+
transcribe: {
|
|
101637
|
+
command: user.transcribe?.command ?? defaults.transcribe?.command,
|
|
101638
|
+
prompt: user.transcribe?.prompt ?? defaults.transcribe?.prompt
|
|
101639
|
+
}
|
|
101640
|
+
};
|
|
101641
|
+
}
|
|
101642
|
+
async function parseOrEmpty(text) {
|
|
101643
|
+
try {
|
|
101644
|
+
return lt(text);
|
|
101645
|
+
} catch {
|
|
101646
|
+
return {};
|
|
101647
|
+
}
|
|
101648
|
+
}
|
|
101626
101649
|
async function loadConfig() {
|
|
101650
|
+
const defaultConfig = await parseOrEmpty(await readDefaultConfig());
|
|
101627
101651
|
const path = configPath();
|
|
101628
101652
|
if (!existsSync(path)) {
|
|
101629
101653
|
const dir = configDir();
|
|
101630
101654
|
await ensureDir(dir);
|
|
101631
101655
|
await writeFile(path, await readDefaultConfig(), "utf8");
|
|
101632
|
-
return
|
|
101633
|
-
}
|
|
101634
|
-
const raw = await readFile(path, "utf8");
|
|
101635
|
-
try {
|
|
101636
|
-
return lt(raw);
|
|
101637
|
-
} catch {
|
|
101638
|
-
return {};
|
|
101656
|
+
return defaultConfig;
|
|
101639
101657
|
}
|
|
101658
|
+
const userConfig = await parseOrEmpty(await readFile(path, "utf8"));
|
|
101659
|
+
return mergeOverDefaults(userConfig, defaultConfig);
|
|
101640
101660
|
}
|
|
101641
101661
|
async function resetConfig() {
|
|
101642
101662
|
const path = configPath();
|
|
101643
101663
|
const dir = configDir();
|
|
101644
101664
|
await ensureDir(dir);
|
|
101645
|
-
|
|
101665
|
+
const raw = await readDefaultConfig();
|
|
101666
|
+
const commented = raw.split(`
|
|
101667
|
+
`).map((line) => {
|
|
101668
|
+
const trimmed = line.trim();
|
|
101669
|
+
if (trimmed === "" || trimmed.startsWith("#"))
|
|
101670
|
+
return line;
|
|
101671
|
+
return line.replace(trimmed, `# ${trimmed}`);
|
|
101672
|
+
}).join(`
|
|
101673
|
+
`);
|
|
101674
|
+
await writeFile(path, commented, "utf8");
|
|
101646
101675
|
return path;
|
|
101647
101676
|
}
|
|
101648
101677
|
|
|
@@ -103185,6 +103214,17 @@ ${css}
|
|
|
103185
103214
|
|
|
103186
103215
|
}
|
|
103187
103216
|
}
|
|
103217
|
+
main.content {
|
|
103218
|
+
max-width: 50em;
|
|
103219
|
+
margin: 0 auto;
|
|
103220
|
+
padding: 0 1rem;
|
|
103221
|
+
}
|
|
103222
|
+
@media (max-width: 767px) {
|
|
103223
|
+
main.content {
|
|
103224
|
+
margin-top: 0rem;
|
|
103225
|
+
}
|
|
103226
|
+
}
|
|
103227
|
+
|
|
103188
103228
|
h1 { --pico-font-size: 1.9rem; }
|
|
103189
103229
|
h2 { --pico-font-size: 1.5rem; }
|
|
103190
103230
|
h3 { --pico-font-size: 1.25rem; }
|
|
@@ -103194,12 +103234,22 @@ h6 { --pico-font-size: 0.85rem; }
|
|
|
103194
103234
|
h1, h2, h3, h4, h5, h6 {
|
|
103195
103235
|
--pico-font-weight: 500;
|
|
103196
103236
|
--pico-line-height: 1.25;
|
|
103197
|
-
margin-top: 0;
|
|
103237
|
+
margin-top: 0.1em;
|
|
103238
|
+
margin-bottom: 0.666em;
|
|
103198
103239
|
}
|
|
103199
103240
|
h1 {
|
|
103200
103241
|
letter-spacing: -0.03em;
|
|
103242
|
+
margin-top: calc(var(--pico-typography-spacing-vertical) * 2);
|
|
103201
103243
|
margin-bottom: calc(var(--pico-typography-spacing-vertical) * 2);
|
|
103202
103244
|
}
|
|
103245
|
+
@media (max-width: 767px) {
|
|
103246
|
+
h1 {
|
|
103247
|
+
margin-top: calc(var(--pico-typography-spacing-vertical) * 2);
|
|
103248
|
+
margin-bottom: calc(var(--pico-typography-spacing-vertical) * 2);
|
|
103249
|
+
text-align: center;
|
|
103250
|
+
}
|
|
103251
|
+
}
|
|
103252
|
+
|
|
103203
103253
|
li:last-child {
|
|
103204
103254
|
margin-bottom: 0px;
|
|
103205
103255
|
}
|
|
@@ -103228,7 +103278,7 @@ img[alt="Prosey"]:hover, img[alt="Prosey"]:active, img[alt="Prosey"]:focus { fil
|
|
|
103228
103278
|
<div style="flex:1;text-align:center;font-size:.85rem;color:var(--pico-muted-color)">${watchMeta ? watchMetaHtml(watchMeta.duration, watchMeta.wordCount, watchMeta.videoId) : ""}</div>
|
|
103229
103279
|
<button id="theme-btn" type="button" style="background:none;border:none;cursor:pointer;padding:0;line-height:1;opacity:.5;filter:grayscale(100%);transition:all 0.3s;flex-shrink:0">\uD83D\uDCA1</button>
|
|
103230
103280
|
</div>
|
|
103231
|
-
<main
|
|
103281
|
+
<main class="content">
|
|
103232
103282
|
${body}
|
|
103233
103283
|
</main>
|
|
103234
103284
|
<script>
|
|
@@ -103263,7 +103313,7 @@ function openInBrowser(htmlPath) {
|
|
|
103263
103313
|
// package.json
|
|
103264
103314
|
var package_default = {
|
|
103265
103315
|
name: "@tacone/prosey",
|
|
103266
|
-
version: "0.
|
|
103316
|
+
version: "0.8.1",
|
|
103267
103317
|
description: "Download YouTube video transcripts from the CLI",
|
|
103268
103318
|
module: "src/index.ts",
|
|
103269
103319
|
type: "module",
|
|
@@ -122082,6 +122132,7 @@ var listOnly = false;
|
|
|
122082
122132
|
var outputPath;
|
|
122083
122133
|
var outputJson = false;
|
|
122084
122134
|
var format3 = "markdown";
|
|
122135
|
+
var formatExplicit = false;
|
|
122085
122136
|
var noDecode = false;
|
|
122086
122137
|
var showDetails = true;
|
|
122087
122138
|
var noCache = false;
|
|
@@ -122114,14 +122165,19 @@ for (let i = 0;i < args.length; i++) {
|
|
|
122114
122165
|
} else if (arg === "--json") {
|
|
122115
122166
|
outputJson = true;
|
|
122116
122167
|
format3 = "json";
|
|
122168
|
+
formatExplicit = true;
|
|
122117
122169
|
} else if (arg === "--text") {
|
|
122118
122170
|
outputJson = false;
|
|
122119
122171
|
format3 = "text";
|
|
122172
|
+
formatExplicit = true;
|
|
122120
122173
|
} else if (arg === "--markdown") {
|
|
122121
122174
|
format3 = "markdown";
|
|
122175
|
+
formatExplicit = true;
|
|
122122
122176
|
} else if (arg === "--html") {
|
|
122123
122177
|
format3 = "html";
|
|
122178
|
+
formatExplicit = true;
|
|
122124
122179
|
} else if (arg === "--format") {
|
|
122180
|
+
formatExplicit = true;
|
|
122125
122181
|
const val = args[++i];
|
|
122126
122182
|
if (val === "json") {
|
|
122127
122183
|
format3 = "json";
|
|
@@ -122209,6 +122265,9 @@ debug("Pager:", pagerCmd ?? "none");
|
|
|
122209
122265
|
useHints = config.hints;
|
|
122210
122266
|
}
|
|
122211
122267
|
}
|
|
122268
|
+
if (!formatExplicit && config.format) {
|
|
122269
|
+
format3 = config.format;
|
|
122270
|
+
}
|
|
122212
122271
|
if (useHints) {
|
|
122213
122272
|
const hasMarkdownPager = pagerCmd === "bat -lmd --style plain" || pagerCmd === "glow -p" || pagerCmd === "mdcat -l -p";
|
|
122214
122273
|
if (!hasMarkdownPager) {
|
package/package.json
CHANGED
package/src/config.test.ts
CHANGED
|
@@ -3,7 +3,8 @@ import { rm, readFile } from "node:fs/promises";
|
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
|
-
import { configPath, loadConfig, resetConfig } from "./config";
|
|
6
|
+
import { configPath, loadConfig, resetConfig, mergeOverDefaults } from "./config";
|
|
7
|
+
import type { ProseyConfig } from "./config";
|
|
7
8
|
|
|
8
9
|
const ORIGINAL_XDG = process.env.XDG_CONFIG_HOME;
|
|
9
10
|
const ORIGINAL_PROSEY_CONFIG = process.env.PROSEY_CONFIG_PATH;
|
|
@@ -49,7 +50,11 @@ describe("loadConfig", () => {
|
|
|
49
50
|
expect(existsSync(tmpConfig)).toBe(false);
|
|
50
51
|
|
|
51
52
|
const config = await loadConfig();
|
|
52
|
-
expect(config).
|
|
53
|
+
expect(config.pager).toBe("auto");
|
|
54
|
+
expect(config.hints).toBe(true);
|
|
55
|
+
expect(config.format).toBe("html");
|
|
56
|
+
expect(config.ai?.command).toBeString();
|
|
57
|
+
expect(config.summarize?.prompt).toBeString();
|
|
53
58
|
expect(existsSync(tmpConfig)).toBe(true);
|
|
54
59
|
|
|
55
60
|
const content = await readFile(tmpConfig, "utf8");
|
|
@@ -73,7 +78,10 @@ describe("loadConfig", () => {
|
|
|
73
78
|
await Bun.write(tmpConfig, "invalid [[\ntoml{{{");
|
|
74
79
|
|
|
75
80
|
const config = await loadConfig();
|
|
76
|
-
expect(config).
|
|
81
|
+
expect(config.pager).toBe("auto");
|
|
82
|
+
expect(config.hints).toBe(true);
|
|
83
|
+
expect(config.format).toBe("html");
|
|
84
|
+
expect(config.ai?.command).toBeString();
|
|
77
85
|
});
|
|
78
86
|
});
|
|
79
87
|
|
|
@@ -86,7 +94,20 @@ describe("resetConfig", () => {
|
|
|
86
94
|
} catch {}
|
|
87
95
|
});
|
|
88
96
|
|
|
89
|
-
test("
|
|
97
|
+
test("reset + load returns full defaults", async () => {
|
|
98
|
+
process.env.PROSEY_CONFIG_PATH = tmpConfig;
|
|
99
|
+
|
|
100
|
+
await resetConfig();
|
|
101
|
+
const config = await loadConfig();
|
|
102
|
+
expect(config.pager).toBe("auto");
|
|
103
|
+
expect(config.hints).toBe(true);
|
|
104
|
+
expect(config.format).toBe("html");
|
|
105
|
+
expect(config.ai?.command).toBeString();
|
|
106
|
+
expect(config.summarize?.prompt).toBeString();
|
|
107
|
+
expect(config.transcribe?.prompt).toBeString();
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("overwrites existing file with commented defaults", async () => {
|
|
90
111
|
process.env.PROSEY_CONFIG_PATH = tmpConfig;
|
|
91
112
|
|
|
92
113
|
await Bun.write(tmpConfig, "# garbage");
|
|
@@ -94,7 +115,84 @@ describe("resetConfig", () => {
|
|
|
94
115
|
expect(path).toBe(tmpConfig);
|
|
95
116
|
|
|
96
117
|
const content = await readFile(tmpConfig, "utf8");
|
|
97
|
-
expect(content).toContain("[summarize]");
|
|
98
|
-
expect(content).toContain("command = ");
|
|
118
|
+
expect(content).toContain("# [summarize]");
|
|
119
|
+
expect(content).toContain("# command = ");
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
describe("mergeOverDefaults", () => {
|
|
124
|
+
const defaults: ProseyConfig = {
|
|
125
|
+
pager: "auto",
|
|
126
|
+
hints: true,
|
|
127
|
+
format: "html",
|
|
128
|
+
ai: { command: "opencode run" },
|
|
129
|
+
summarize: { prompt: "default summary", command: "opencode run" },
|
|
130
|
+
transcribe: { prompt: "default transcribe" },
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
test("empty user config returns defaults", () => {
|
|
134
|
+
const result = mergeOverDefaults({}, defaults);
|
|
135
|
+
expect(result.pager).toBe("auto");
|
|
136
|
+
expect(result.hints).toBe(true);
|
|
137
|
+
expect(result.format).toBe("html");
|
|
138
|
+
expect(result.ai?.command).toBe("opencode run");
|
|
139
|
+
expect(result.summarize?.prompt).toBe("default summary");
|
|
140
|
+
expect(result.transcribe?.prompt).toBe("default transcribe");
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
test("user pager overrides default", () => {
|
|
144
|
+
const result = mergeOverDefaults({ pager: "less" }, defaults);
|
|
145
|
+
expect(result.pager).toBe("less");
|
|
146
|
+
expect(result.hints).toBe(true);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("user hints overrides default", () => {
|
|
150
|
+
const result = mergeOverDefaults({ hints: false }, defaults);
|
|
151
|
+
expect(result.hints).toBe(false);
|
|
152
|
+
expect(result.pager).toBe("auto");
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test("user format overrides default", () => {
|
|
156
|
+
const result = mergeOverDefaults({ format: "markdown" }, defaults);
|
|
157
|
+
expect(result.format).toBe("markdown");
|
|
158
|
+
expect(result.hints).toBe(true);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("user ai.command overrides default", () => {
|
|
162
|
+
const result = mergeOverDefaults({ ai: { command: "my-cmd" } }, defaults);
|
|
163
|
+
expect(result.ai?.command).toBe("my-cmd");
|
|
164
|
+
expect(result.summarize?.prompt).toBe("default summary");
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("user summarize.prompt overrides default", () => {
|
|
168
|
+
const result = mergeOverDefaults({ summarize: { prompt: "my prompt" } }, defaults);
|
|
169
|
+
expect(result.summarize?.prompt).toBe("my prompt");
|
|
170
|
+
expect(result.summarize?.command).toBe("opencode run");
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test("user transcribe.prompt overrides default", () => {
|
|
174
|
+
const result = mergeOverDefaults({ transcribe: { prompt: "my transcribe" } }, defaults);
|
|
175
|
+
expect(result.transcribe?.prompt).toBe("my transcribe");
|
|
176
|
+
expect(result.summarize?.prompt).toBe("default summary");
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test("all user values override all defaults", () => {
|
|
180
|
+
const result = mergeOverDefaults(
|
|
181
|
+
{
|
|
182
|
+
pager: "custom",
|
|
183
|
+
hints: false,
|
|
184
|
+
ai: { command: "custom-ai" },
|
|
185
|
+
summarize: { command: "custom-sum", prompt: "custom-sum-prompt" },
|
|
186
|
+
transcribe: { command: "custom-trans", prompt: "custom-trans-prompt" },
|
|
187
|
+
},
|
|
188
|
+
defaults,
|
|
189
|
+
);
|
|
190
|
+
expect(result.pager).toBe("custom");
|
|
191
|
+
expect(result.hints).toBe(false);
|
|
192
|
+
expect(result.ai?.command).toBe("custom-ai");
|
|
193
|
+
expect(result.summarize?.command).toBe("custom-sum");
|
|
194
|
+
expect(result.summarize?.prompt).toBe("custom-sum-prompt");
|
|
195
|
+
expect(result.transcribe?.command).toBe("custom-trans");
|
|
196
|
+
expect(result.transcribe?.prompt).toBe("custom-trans-prompt");
|
|
99
197
|
});
|
|
100
198
|
});
|
package/src/config.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { load } from "js-toml";
|
|
|
8
8
|
export interface ProseyConfig {
|
|
9
9
|
pager?: string;
|
|
10
10
|
hints?: boolean;
|
|
11
|
+
format?: string;
|
|
11
12
|
ai?: {
|
|
12
13
|
command?: string;
|
|
13
14
|
};
|
|
@@ -46,28 +47,59 @@ function ensureDir(path: string): Promise<void> {
|
|
|
46
47
|
return mkdir(path, { recursive: true }) as Promise<void>;
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
export function mergeOverDefaults(user: ProseyConfig, defaults: ProseyConfig): ProseyConfig {
|
|
51
|
+
return {
|
|
52
|
+
pager: user.pager ?? defaults.pager,
|
|
53
|
+
hints: user.hints ?? defaults.hints,
|
|
54
|
+
format: user.format ?? defaults.format,
|
|
55
|
+
ai: user.ai?.command !== undefined ? user.ai : defaults.ai,
|
|
56
|
+
summarize: {
|
|
57
|
+
command: user.summarize?.command ?? defaults.summarize?.command,
|
|
58
|
+
prompt: user.summarize?.prompt ?? defaults.summarize?.prompt,
|
|
59
|
+
},
|
|
60
|
+
transcribe: {
|
|
61
|
+
command: user.transcribe?.command ?? defaults.transcribe?.command,
|
|
62
|
+
prompt: user.transcribe?.prompt ?? defaults.transcribe?.prompt,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function parseOrEmpty(text: string): Promise<ProseyConfig> {
|
|
68
|
+
try {
|
|
69
|
+
return load(text) as ProseyConfig;
|
|
70
|
+
} catch {
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
49
75
|
export async function loadConfig(): Promise<ProseyConfig> {
|
|
76
|
+
const defaultConfig = await parseOrEmpty(await readDefaultConfig());
|
|
50
77
|
const path = configPath();
|
|
51
78
|
|
|
52
79
|
if (!existsSync(path)) {
|
|
53
80
|
const dir = configDir();
|
|
54
81
|
await ensureDir(dir);
|
|
55
82
|
await writeFile(path, await readDefaultConfig(), "utf8");
|
|
56
|
-
return
|
|
83
|
+
return defaultConfig;
|
|
57
84
|
}
|
|
58
85
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
return load(raw) as ProseyConfig;
|
|
62
|
-
} catch {
|
|
63
|
-
return {};
|
|
64
|
-
}
|
|
86
|
+
const userConfig = await parseOrEmpty(await readFile(path, "utf8"));
|
|
87
|
+
return mergeOverDefaults(userConfig, defaultConfig);
|
|
65
88
|
}
|
|
66
89
|
|
|
67
90
|
export async function resetConfig(): Promise<string> {
|
|
68
91
|
const path = configPath();
|
|
69
92
|
const dir = configDir();
|
|
70
93
|
await ensureDir(dir);
|
|
71
|
-
|
|
94
|
+
const raw = await readDefaultConfig();
|
|
95
|
+
const commented = raw
|
|
96
|
+
.split("\n")
|
|
97
|
+
.map((line) => {
|
|
98
|
+
const trimmed = line.trim();
|
|
99
|
+
if (trimmed === "" || trimmed.startsWith("#")) return line;
|
|
100
|
+
return line.replace(trimmed, `# ${trimmed}`);
|
|
101
|
+
})
|
|
102
|
+
.join("\n");
|
|
103
|
+
await writeFile(path, commented, "utf8");
|
|
72
104
|
return path;
|
|
73
105
|
}
|
package/src/default-config.toml
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# Default prosey configuration
|
|
2
2
|
# Created automatically on first run. Edit as needed.
|
|
3
3
|
|
|
4
|
+
# Default output format: "markdown", "html", "text", or "json".
|
|
5
|
+
# Can be overridden per-invocation via --html, --markdown, --text, --json, or --format.
|
|
6
|
+
format = "html"
|
|
7
|
+
|
|
4
8
|
# Pager command for transcript and summary output.
|
|
5
9
|
# Defaults to "auto": bat -lmd --style plain → glow -p → mdcat -l -p → less
|
|
6
10
|
# Set to a custom command (e.g. "less -R") to override.
|
|
@@ -21,7 +25,7 @@ hints = true
|
|
|
21
25
|
# OPENCODE_PERMISSION='{"read":"allow","write":"deny","edit":"deny","bash":"deny","glob":"deny","grep":"deny","webfetch":\"deny\",\"task\":\"deny\",\"todowrite\":\"deny\",\"websearch\":\"deny","lsp":"deny"}' opencode run --pure
|
|
22
26
|
# copilot -s --deny-all-tools --read-only
|
|
23
27
|
|
|
24
|
-
command = "OPENCODE_PERMISSION='{\"read\":\"allow\",\"write\":\"deny\",\"edit\":\"deny\",\"bash\":\"deny\",\"glob\":\"deny\",\"grep\":\"deny\",\"webfetch\":\"deny\",\"task\":\"deny\",\"todowrite\":\"deny\",\"websearch\":\"deny\",\"lsp\":\"deny\"}' opencode run --pure --variant low"
|
|
28
|
+
command = "OPENCODE_PERMISSION='{\"read\":\"allow\",\"write\":\"deny\",\"edit\":\"deny\",\"bash\":\"deny\",\"glob\":\"deny\",\"grep\":\"deny\",\"webfetch\":\"deny\",\"task\":\"deny\",\"todowrite\":\"deny\",\"websearch\":\"deny\",\"lsp\":\"deny\"}' opencode run --pure --model opencode/deepseek-v4-flash-free --variant low"
|
|
25
29
|
|
|
26
30
|
[summarize]
|
|
27
31
|
|
|
@@ -37,7 +41,7 @@ Guidelines:
|
|
|
37
41
|
- use the TIMESTAMPS only to understand the structure, don't output time markers
|
|
38
42
|
- content length: aim to be the same range as the original text or more.
|
|
39
43
|
- section titles should be h2 headers
|
|
40
|
-
- paragraph length soft-limit
|
|
44
|
+
- paragraph length: soft-limit 250 characters, hard-limit 350 characters.
|
|
41
45
|
|
|
42
46
|
Content considerations:
|
|
43
47
|
|
package/src/html.ts
CHANGED
|
@@ -77,6 +77,17 @@ ${css}
|
|
|
77
77
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
+
main.content {
|
|
81
|
+
max-width: 50em;
|
|
82
|
+
margin: 0 auto;
|
|
83
|
+
padding: 0 1rem;
|
|
84
|
+
}
|
|
85
|
+
@media (max-width: 767px) {
|
|
86
|
+
main.content {
|
|
87
|
+
margin-top: 0rem;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
80
91
|
h1 { --pico-font-size: 1.9rem; }
|
|
81
92
|
h2 { --pico-font-size: 1.5rem; }
|
|
82
93
|
h3 { --pico-font-size: 1.25rem; }
|
|
@@ -86,12 +97,22 @@ h6 { --pico-font-size: 0.85rem; }
|
|
|
86
97
|
h1, h2, h3, h4, h5, h6 {
|
|
87
98
|
--pico-font-weight: 500;
|
|
88
99
|
--pico-line-height: 1.25;
|
|
89
|
-
margin-top: 0;
|
|
100
|
+
margin-top: 0.1em;
|
|
101
|
+
margin-bottom: 0.666em;
|
|
90
102
|
}
|
|
91
103
|
h1 {
|
|
92
104
|
letter-spacing: -0.03em;
|
|
105
|
+
margin-top: calc(var(--pico-typography-spacing-vertical) * 2);
|
|
93
106
|
margin-bottom: calc(var(--pico-typography-spacing-vertical) * 2);
|
|
94
107
|
}
|
|
108
|
+
@media (max-width: 767px) {
|
|
109
|
+
h1 {
|
|
110
|
+
margin-top: calc(var(--pico-typography-spacing-vertical) * 2);
|
|
111
|
+
margin-bottom: calc(var(--pico-typography-spacing-vertical) * 2);
|
|
112
|
+
text-align: center;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
95
116
|
li:last-child {
|
|
96
117
|
margin-bottom: 0px;
|
|
97
118
|
}
|
|
@@ -120,7 +141,7 @@ img[alt="Prosey"]:hover, img[alt="Prosey"]:active, img[alt="Prosey"]:focus { fil
|
|
|
120
141
|
<div style="flex:1;text-align:center;font-size:.85rem;color:var(--pico-muted-color)">${watchMeta ? watchMetaHtml(watchMeta.duration, watchMeta.wordCount, watchMeta.videoId) : ""}</div>
|
|
121
142
|
<button id="theme-btn" type="button" style="background:none;border:none;cursor:pointer;padding:0;line-height:1;opacity:.5;filter:grayscale(100%);transition:all 0.3s;flex-shrink:0">💡</button>
|
|
122
143
|
</div>
|
|
123
|
-
<main
|
|
144
|
+
<main class="content">
|
|
124
145
|
${body}
|
|
125
146
|
</main>
|
|
126
147
|
<script>
|
package/src/index.ts
CHANGED
|
@@ -249,6 +249,7 @@ let listOnly = false;
|
|
|
249
249
|
let outputPath: string | undefined;
|
|
250
250
|
let outputJson = false;
|
|
251
251
|
let format: "text" | "json" | "markdown" | "html" = "markdown";
|
|
252
|
+
let formatExplicit = false;
|
|
252
253
|
let noDecode = false;
|
|
253
254
|
let showDetails = true;
|
|
254
255
|
let noCache = false;
|
|
@@ -281,14 +282,19 @@ for (let i = 0; i < args.length; i++) {
|
|
|
281
282
|
} else if (arg === "--json") {
|
|
282
283
|
outputJson = true;
|
|
283
284
|
format = "json";
|
|
285
|
+
formatExplicit = true;
|
|
284
286
|
} else if (arg === "--text") {
|
|
285
287
|
outputJson = false;
|
|
286
288
|
format = "text";
|
|
289
|
+
formatExplicit = true;
|
|
287
290
|
} else if (arg === "--markdown") {
|
|
288
291
|
format = "markdown";
|
|
292
|
+
formatExplicit = true;
|
|
289
293
|
} else if (arg === "--html") {
|
|
290
294
|
format = "html";
|
|
295
|
+
formatExplicit = true;
|
|
291
296
|
} else if (arg === "--format") {
|
|
297
|
+
formatExplicit = true;
|
|
292
298
|
const val = args[++i];
|
|
293
299
|
if (val === "json") {
|
|
294
300
|
format = "json";
|
|
@@ -384,6 +390,10 @@ debug("Pager:", pagerCmd ?? "none");
|
|
|
384
390
|
}
|
|
385
391
|
}
|
|
386
392
|
|
|
393
|
+
if (!formatExplicit && config.format) {
|
|
394
|
+
format = config.format as "text" | "json" | "markdown" | "html";
|
|
395
|
+
}
|
|
396
|
+
|
|
387
397
|
if (useHints) {
|
|
388
398
|
const hasMarkdownPager =
|
|
389
399
|
pagerCmd === "bat -lmd --style plain" || pagerCmd === "glow -p" || pagerCmd === "mdcat -l -p";
|