@typescript-calendar-lib/cli 0.5.2 → 0.5.4
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/README.md +46 -2
- package/dist/bin.d.ts +3 -1
- package/dist/bin.js +20 -2
- package/dist/bin.js.map +1 -1
- package/dist/{calendar-f8j9RTe9.js → calendar-BpDw0iF-.js} +55 -25
- package/dist/calendar-BpDw0iF-.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -1
- package/dist/{theme-BT_DowM9.d.ts → theme-rvXGNLpG.d.ts} +2 -1
- package/package.json +3 -3
- package/dist/calendar-f8j9RTe9.js.map +0 -1
package/README.md
CHANGED
|
@@ -62,8 +62,10 @@ All options from `@typescript-calendar-lib/core` are supported, plus these CLI-s
|
|
|
62
62
|
| `theme` | `ThemeName \| CliTheme` | `"default"` | Visual theme (`"default"` \| `"modern"`) or custom theme object |
|
|
63
63
|
| `colorScheme` | `ColorSchemeName \| CliPalette` | `"default"` | Color scheme, active when `color: true` |
|
|
64
64
|
| `today` | `Date` | `new Date()` | Reference date for "today" coloring |
|
|
65
|
+
| `isDateDisabled` | `(date: Date) => boolean` | — | Mark dates as non-selectable; rendered with the `dim` color |
|
|
65
66
|
| `cellData` | `(date: Date) => unknown` | — | Resolve per-cell data; passed to `renderCell` |
|
|
66
67
|
| `renderCell` | `(day, date, state, data?) => string` | — | Custom cell text; replaces the day cell verbatim |
|
|
68
|
+
| `showWeekNumbers` | `boolean` | `false` | Print a 2-char week-number column at the start of each row. `weekStart: "monday"` → ISO 8601 week; `"sunday"` → week-containing-Jan-1 week (US `cal -w` convention) |
|
|
67
69
|
|
|
68
70
|
## CLI Binary
|
|
69
71
|
|
|
@@ -82,11 +84,13 @@ typescript-calendar-lib --range 2026-01-01 2026-03-31 # months in a date range
|
|
|
82
84
|
|
|
83
85
|
```
|
|
84
86
|
--theme <name> Look: default | modern (default: default)
|
|
85
|
-
--color-scheme <name> Colors: default | ocean | forest | sunset | mono
|
|
87
|
+
--color-scheme <name> Colors: default | ocean | forest | sunset | mono (default: default)
|
|
86
88
|
--color Enable ANSI colors (auto-detected for TTY)
|
|
87
89
|
--no-color Disable ANSI colors
|
|
88
90
|
--locale <lang> Language: en | ja | es | de | fr | ko | zh (default: en)
|
|
91
|
+
--holiday-locale <lang> Holiday rules: currently only ja (default: ja)
|
|
89
92
|
--week-start <day> First weekday: sunday | monday (default: sunday)
|
|
93
|
+
--week-numbers Print the week number at the start of each row
|
|
90
94
|
--highlight <YYYY-MM-DD> Highlight a date (e.g. 2026-09-08)
|
|
91
95
|
--highlight-style <style> Highlight style: bracket | reverse (default: bracket)
|
|
92
96
|
--today <YYYY-MM-DD> Override today (marks the date, defaults year/month)
|
|
@@ -271,11 +275,51 @@ calendar({
|
|
|
271
275
|
|
|
272
276
|
`renderCell` receives `(day, date, state, data)`:
|
|
273
277
|
|
|
274
|
-
- `state` — `getCalendarCellState(date)` result (`isWeekend`, `isToday`, `isHighlight`, `isInRange`, `
|
|
278
|
+
- `state` — `getCalendarCellState(date)` result (`isWeekend`, `isHoliday`, `isToday`, `isHighlight`, `isInRange`, `isDisabled`)
|
|
275
279
|
- `data` — the resolved `cellData` value for that date (`undefined` when none)
|
|
276
280
|
|
|
277
281
|
The returned string replaces the cell **verbatim** — no padding, colorization, or highlight/range styling is applied, so you control cell width and any ANSI codes yourself. A bare `String(day)` in a wide `renderCell` can shift the column alignment of that row.
|
|
278
282
|
|
|
283
|
+
### Week numbers
|
|
284
|
+
|
|
285
|
+
`showWeekNumbers` adds a 2-char week-number column at the start of each row. With `weekStart: "monday"` the number is the ISO 8601 week of the row's week-start date:
|
|
286
|
+
|
|
287
|
+
```ts
|
|
288
|
+
calendar({
|
|
289
|
+
year: 2026,
|
|
290
|
+
month: 9,
|
|
291
|
+
weekStart: "monday",
|
|
292
|
+
showWeekNumbers: true,
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
September 2026
|
|
298
|
+
Mon Tue Wed Thu Fri Sat Sun
|
|
299
|
+
36 1 2 3 4 5 6
|
|
300
|
+
37 7 8 9 10 11 12 13
|
|
301
|
+
38 14 15 16 17 18 19 20
|
|
302
|
+
39 21 22 23 24 25 26 27
|
|
303
|
+
40 28 29 30
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
With `weekStart: "sunday"` it uses the convention where the week containing Jan 1 is week 1. Week numbers also render in framed themes (`modern`), where separator and frame lines get a week segment.
|
|
307
|
+
|
|
308
|
+
### Disabled dates
|
|
309
|
+
|
|
310
|
+
`isDateDisabled` marks dates as non-selectable. Disabled cells are rendered with the `dim` color (falling back to `90` even on the `"default"` scheme, which otherwise colors only range/highlight):
|
|
311
|
+
|
|
312
|
+
```ts
|
|
313
|
+
calendar({
|
|
314
|
+
year: 2026,
|
|
315
|
+
month: 9,
|
|
316
|
+
color: true,
|
|
317
|
+
isDateDisabled: (date) => date.getDay() === 0, // disable Sundays
|
|
318
|
+
});
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Color precedence for a cell: highlight > range > today > **disabled** > weekend > holiday > day.
|
|
322
|
+
|
|
279
323
|
### Plain text output
|
|
280
324
|
|
|
281
325
|
By default (`color: false`) the output contains no ANSI escape codes, so it's safe to pipe into files or other tools:
|
package/dist/bin.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as ColorSchemeName, s as ThemeName } from "./theme-
|
|
1
|
+
import { i as ColorSchemeName, s as ThemeName } from "./theme-rvXGNLpG.js";
|
|
2
2
|
import { HighlightStyle, Locale, WeekStart } from "@typescript-calendar-lib/core";
|
|
3
3
|
//#region src/bin.d.ts
|
|
4
4
|
export interface CliArgs {
|
|
@@ -9,7 +9,9 @@ export interface CliArgs {
|
|
|
9
9
|
color?: boolean;
|
|
10
10
|
noColor?: boolean;
|
|
11
11
|
locale?: Locale;
|
|
12
|
+
holidayLocale?: Locale;
|
|
12
13
|
weekStart?: WeekStart;
|
|
14
|
+
weekNumbers?: boolean;
|
|
13
15
|
highlight?: Date;
|
|
14
16
|
highlightStyle?: HighlightStyle;
|
|
15
17
|
today?: Date;
|
package/dist/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as calendarRange, r as calendarYear, t as calendar } from "./calendar-
|
|
2
|
+
import { n as calendarRange, r as calendarYear, t as calendar } from "./calendar-BpDw0iF-.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { LOCALES, MAX_YEAR, MIN_YEAR, createDate } from "@typescript-calendar-lib/core";
|
|
5
5
|
//#region src/bin.ts
|
|
@@ -35,6 +35,7 @@ const VALUE_OPTIONS = {
|
|
|
35
35
|
"--theme": "theme",
|
|
36
36
|
"--color-scheme": "colorScheme",
|
|
37
37
|
"--locale": "locale",
|
|
38
|
+
"--holiday-locale": "holidayLocale",
|
|
38
39
|
"--week-start": "weekStart",
|
|
39
40
|
"--highlight-style": "highlightStyle"
|
|
40
41
|
};
|
|
@@ -81,6 +82,10 @@ function parseArgs(args) {
|
|
|
81
82
|
result.yearView = true;
|
|
82
83
|
continue;
|
|
83
84
|
}
|
|
85
|
+
if (arg === "--week-numbers") {
|
|
86
|
+
result.weekNumbers = true;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
84
89
|
if (arg === "--highlight") {
|
|
85
90
|
const value = args[++i];
|
|
86
91
|
if (value === void 0) return error("Missing value for option: --highlight");
|
|
@@ -143,6 +148,11 @@ function parseArgs(args) {
|
|
|
143
148
|
LOCALE_LIST,
|
|
144
149
|
"locale"
|
|
145
150
|
],
|
|
151
|
+
[
|
|
152
|
+
result.holidayLocale,
|
|
153
|
+
LOCALE_LIST,
|
|
154
|
+
"holiday-locale"
|
|
155
|
+
],
|
|
146
156
|
[
|
|
147
157
|
result.weekStart,
|
|
148
158
|
WEEK_STARTS,
|
|
@@ -173,11 +183,13 @@ function printUsage() {
|
|
|
173
183
|
|
|
174
184
|
Options:
|
|
175
185
|
--theme <name> Look: default | modern (default: default)
|
|
176
|
-
--color-scheme <name> Colors: default | ocean | forest | sunset | mono
|
|
186
|
+
--color-scheme <name> Colors: default | ocean | forest | sunset | mono (default: default)
|
|
177
187
|
--color Enable ANSI colors (auto-detected for TTY)
|
|
178
188
|
--no-color Disable ANSI colors
|
|
179
189
|
--locale <lang> Language: ${LOCALE_LIST.join(" | ")} (default: en)
|
|
190
|
+
--holiday-locale <lang> Holiday rules: currently only ja (default: ja)
|
|
180
191
|
--week-start <day> First weekday: sunday | monday (default: sunday)
|
|
192
|
+
--week-numbers Print the week number at the start of each row
|
|
181
193
|
--highlight <YYYY-MM-DD> Highlight a date (e.g. 2026-09-08)
|
|
182
194
|
--highlight-style <style> Highlight style: bracket | reverse (default: bracket)
|
|
183
195
|
--today <YYYY-MM-DD> Override today (marks the date, defaults year/month)
|
|
@@ -185,6 +197,10 @@ Options:
|
|
|
185
197
|
--range <FROM> <TO> Render months from FROM to TO (YYYY-MM-DD)
|
|
186
198
|
-v, --version Show version
|
|
187
199
|
-h, --help Show this help
|
|
200
|
+
|
|
201
|
+
Color:
|
|
202
|
+
--color / --no-color win over the environment. NO_COLOR and FORCE_COLOR are
|
|
203
|
+
honoured next, and a TTY is used as the final fallback.
|
|
188
204
|
`;
|
|
189
205
|
}
|
|
190
206
|
if (import.meta.main) {
|
|
@@ -211,7 +227,9 @@ if (import.meta.main) {
|
|
|
211
227
|
colorScheme: args.colorScheme,
|
|
212
228
|
color,
|
|
213
229
|
locale: args.locale,
|
|
230
|
+
holidayLocale: args.holidayLocale,
|
|
214
231
|
weekStart: args.weekStart,
|
|
232
|
+
showWeekNumbers: args.weekNumbers,
|
|
215
233
|
highlight: args.highlight,
|
|
216
234
|
highlightStyle: args.highlightStyle,
|
|
217
235
|
today: args.today
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","names":[],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { createRequire } from \"node:module\";\nimport type {\n HighlightStyle,\n Locale,\n WeekStart,\n} from \"@typescript-calendar-lib/core\";\nimport {\n createDate,\n LOCALES,\n MAX_YEAR,\n MIN_YEAR,\n} from \"@typescript-calendar-lib/core\";\nimport { calendar, calendarRange, calendarYear } from \"./calendar.ts\";\nimport type { ColorSchemeName, ThemeName } from \"./theme.ts\";\n\nexport interface CliArgs {\n year?: number;\n month?: number;\n theme?: ThemeName;\n colorScheme?: ColorSchemeName;\n color?: boolean;\n noColor?: boolean;\n locale?: Locale;\n weekStart?: WeekStart;\n highlight?: Date;\n highlightStyle?: HighlightStyle;\n today?: Date;\n yearView?: boolean;\n range?: { from: Date; to: Date };\n}\n\nexport interface ParseResult {\n args: CliArgs;\n error?: string;\n help?: boolean;\n version?: boolean;\n}\n\nconst THEMES: readonly ThemeName[] = [\"default\", \"modern\"];\nconst COLOR_SCHEMES: readonly ColorSchemeName[] = [\n \"default\",\n \"ocean\",\n \"forest\",\n \"sunset\",\n \"mono\",\n];\nconst LOCALE_LIST: readonly string[] = Object.keys(LOCALES);\nconst WEEK_STARTS: readonly WeekStart[] = [\"sunday\", \"monday\"];\nconst HIGHLIGHT_STYLES: readonly HighlightStyle[] = [\"bracket\", \"reverse\"];\n\nconst _require = createRequire(import.meta.url);\n\n/** package.json からバージョンを取得する */\nexport function getVersion(): string {\n return (_require(\"../package.json\") as { version: string }).version;\n}\n\n/**\n * CLI フラグ・環境変数・TTY 状態から最終的な color フラグを解決する。\n * 優先順位: --no-color > --color > NO_COLOR > FORCE_COLOR > TTY\n */\nexport function resolveColor(\n colorFlag: boolean | undefined,\n noColorFlag: boolean | undefined,\n env: Record<string, string | undefined>,\n isTTY: boolean,\n): boolean {\n if (noColorFlag) return false;\n if (colorFlag) return true;\n if (env.NO_COLOR) return false;\n if (env.FORCE_COLOR) return true;\n return isTTY;\n}\n\n/** 値を一つ取るオプションと、代入先のフィールド名 */\nconst VALUE_OPTIONS: Record<string, keyof CliArgs> = {\n \"--theme\": \"theme\",\n \"--color-scheme\": \"colorScheme\",\n \"--locale\": \"locale\",\n \"--week-start\": \"weekStart\",\n \"--highlight-style\": \"highlightStyle\",\n};\n\n/** YYYY-MM-DD 形式の日付文字列をパースする */\nexport function parseDate(value: string): Date | null {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value);\n if (!match) return null;\n const year = Number(match[1]);\n const month = Number(match[2]);\n const day = Number(match[3]);\n if (\n year < MIN_YEAR ||\n year > MAX_YEAR ||\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > 31\n ) {\n return null;\n }\n const date = createDate(year, month - 1, day);\n if (\n date.getFullYear() !== year ||\n date.getMonth() !== month - 1 ||\n date.getDate() !== day\n ) {\n return null;\n }\n return date;\n}\n\n/**\n * CLI 引数をパースする。テスト可能なように副作用を分離している。\n */\nexport function parseArgs(args: readonly string[]): ParseResult {\n const result: CliArgs = {};\n const error = (message: string): ParseResult => ({\n args: result,\n error: message,\n });\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]!;\n\n if (arg === \"-h\" || arg === \"--help\") {\n return { args: result, help: true };\n }\n if (arg === \"-v\" || arg === \"--version\") {\n return { args: result, version: true };\n }\n if (arg === \"--color\") {\n result.color = true;\n continue;\n }\n if (arg === \"--no-color\") {\n result.noColor = true;\n continue;\n }\n if (arg === \"--year\") {\n result.yearView = true;\n continue;\n }\n if (arg === \"--highlight\") {\n const value = args[++i];\n if (value === undefined) {\n return error(\"Missing value for option: --highlight\");\n }\n const parsed = parseDate(value);\n if (parsed === null) {\n return error(\n `Invalid --highlight date: \"${value}\" (expected YYYY-MM-DD, e.g. 2026-09-08)`,\n );\n }\n result.highlight = parsed;\n continue;\n }\n if (arg === \"--today\") {\n const value = args[++i];\n if (value === undefined) {\n return error(\"Missing value for option: --today\");\n }\n const parsed = parseDate(value);\n if (parsed === null) {\n return error(\n `Invalid --today date: \"${value}\" (expected YYYY-MM-DD, e.g. 2026-09-08)`,\n );\n }\n result.today = parsed;\n continue;\n }\n if (arg === \"--range\") {\n const fromStr = args[++i];\n const toStr = args[++i];\n if (fromStr === undefined || toStr === undefined) {\n return error(\n \"--range requires two dates (YYYY-MM-DD), e.g. --range 2026-01-01 2026-03-31\",\n );\n }\n const from = parseDate(fromStr);\n const to = parseDate(toStr);\n if (from === null || to === null) {\n return error(\"Invalid --range date (expected YYYY-MM-DD)\");\n }\n if (from.getTime() > to.getTime()) {\n return error(\"--range: from date must not be after to date\");\n }\n result.range = { from, to };\n continue;\n }\n\n const key = VALUE_OPTIONS[arg];\n if (key !== undefined) {\n const value = args[++i];\n if (value === undefined) {\n return error(`Missing value for option: ${arg}`);\n }\n (result as Record<string, unknown>)[key] = value;\n continue;\n }\n\n const numeric = /^-?\\d+$/.test(arg);\n if (arg.startsWith(\"-\") && !numeric) {\n return error(`Unknown option: ${arg}`);\n }\n if (!numeric) {\n return error(\n `Invalid argument: \"${arg}\" (expected a year or month number)`,\n );\n }\n if (result.year === undefined) {\n result.year = Number(arg);\n } else if (result.month === undefined) {\n result.month = Number(arg);\n } else {\n return error(`Too many arguments: \"${arg}\"`);\n }\n }\n\n // 値のバリデーション\n if (\n result.year !== undefined &&\n (result.year < MIN_YEAR || result.year > MAX_YEAR)\n ) {\n return error(\n `Invalid year: ${result.year} (expected ${MIN_YEAR}–${MAX_YEAR})`,\n );\n }\n if (result.month !== undefined && (result.month < 1 || result.month > 12)) {\n return error(`Invalid month: ${result.month} (expected 1–12)`);\n }\n\n const choiceTable: Array<[string | undefined, readonly string[], string]> = [\n [result.theme, THEMES, \"theme\"],\n [result.colorScheme, COLOR_SCHEMES, \"color-scheme\"],\n [result.locale, LOCALE_LIST, \"locale\"],\n [result.weekStart, WEEK_STARTS, \"week-start\"],\n [result.highlightStyle, HIGHLIGHT_STYLES, \"highlight-style\"],\n ];\n for (const [value, choices, name] of choiceTable) {\n if (value !== undefined && !choices.includes(value)) {\n return error(\n `Invalid ${name}: \"${value}\" (expected: ${choices.join(\" | \")})`,\n );\n }\n }\n\n // 相互排他チェック\n if (result.yearView && result.range) {\n return error(\"--year and --range cannot be used together\");\n }\n if (result.yearView && result.month !== undefined) {\n return error(\"Month cannot be used with --year (use --year YYYY instead)\");\n }\n if (\n result.range &&\n (result.year !== undefined || result.month !== undefined)\n ) {\n return error(\"Positional arguments cannot be used with --range\");\n }\n\n return { args: result };\n}\n\nexport function printUsage(): string {\n return `Usage: typescript-calendar-lib [YYYY] [MM] [options]\n\n typescript-calendar-lib Render the current month\n typescript-calendar-lib 2026 Render the current month of 2026\n typescript-calendar-lib 2026 9 Render September 2026\n typescript-calendar-lib --year Render the current year (4×3 grid)\n typescript-calendar-lib 2026 --year Render 2026 as a year grid\n typescript-calendar-lib --range 2026-01-01 2026-03-31\n Render months from Jan to Mar 2026\n\nOptions:\n --theme <name> Look: default | modern (default: default)\n --color-scheme <name> Colors: default | ocean | forest | sunset | mono\n --color Enable ANSI colors (auto-detected for TTY)\n --no-color Disable ANSI colors\n --locale <lang> Language: ${LOCALE_LIST.join(\" | \")} (default: en)\n --week-start <day> First weekday: sunday | monday (default: sunday)\n --highlight <YYYY-MM-DD> Highlight a date (e.g. 2026-09-08)\n --highlight-style <style> Highlight style: bracket | reverse (default: bracket)\n --today <YYYY-MM-DD> Override today (marks the date, defaults year/month)\n --year Render the whole year as a 4×3 grid\n --range <FROM> <TO> Render months from FROM to TO (YYYY-MM-DD)\n -v, --version Show version\n -h, --help Show this help\n`;\n}\n\nif (import.meta.main) {\n const { args, error, help, version } = parseArgs(process.argv.slice(2));\n\n if (version) {\n console.log(getVersion());\n process.exit(0);\n }\n if (help) {\n console.log(printUsage());\n process.exit(0);\n }\n if (error) {\n console.error(`Error: ${error}`);\n console.error(printUsage());\n process.exit(1);\n }\n\n const color = resolveColor(\n args.color,\n args.noColor,\n process.env,\n process.stdout.isTTY === true,\n );\n\n const now = args.today ?? new Date();\n const year = args.year ?? now.getFullYear();\n const month = args.month ?? now.getMonth() + 1;\n\n const common = {\n theme: args.theme,\n colorScheme: args.colorScheme,\n color,\n locale: args.locale,\n weekStart: args.weekStart,\n highlight: args.highlight,\n highlightStyle: args.highlightStyle,\n today: args.today,\n };\n\n let output: string;\n if (args.range) {\n output = calendarRange({\n ...common,\n from: args.range.from,\n to: args.range.to,\n });\n } else if (args.yearView) {\n output = calendarYear({ ...common, year });\n } else {\n output = calendar({ ...common, year, month });\n }\n\n console.log(output);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bin.js","names":[],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { createRequire } from \"node:module\";\nimport type {\n HighlightStyle,\n Locale,\n WeekStart,\n} from \"@typescript-calendar-lib/core\";\nimport {\n createDate,\n LOCALES,\n MAX_YEAR,\n MIN_YEAR,\n} from \"@typescript-calendar-lib/core\";\nimport { calendar, calendarRange, calendarYear } from \"./calendar.ts\";\nimport type { ColorSchemeName, ThemeName } from \"./theme.ts\";\n\nexport interface CliArgs {\n year?: number;\n month?: number;\n theme?: ThemeName;\n colorScheme?: ColorSchemeName;\n color?: boolean;\n noColor?: boolean;\n locale?: Locale;\n holidayLocale?: Locale;\n weekStart?: WeekStart;\n weekNumbers?: boolean;\n highlight?: Date;\n highlightStyle?: HighlightStyle;\n today?: Date;\n yearView?: boolean;\n range?: { from: Date; to: Date };\n}\n\nexport interface ParseResult {\n args: CliArgs;\n error?: string;\n help?: boolean;\n version?: boolean;\n}\n\nconst THEMES: readonly ThemeName[] = [\"default\", \"modern\"];\nconst COLOR_SCHEMES: readonly ColorSchemeName[] = [\n \"default\",\n \"ocean\",\n \"forest\",\n \"sunset\",\n \"mono\",\n];\nconst LOCALE_LIST: readonly string[] = Object.keys(LOCALES);\nconst WEEK_STARTS: readonly WeekStart[] = [\"sunday\", \"monday\"];\nconst HIGHLIGHT_STYLES: readonly HighlightStyle[] = [\"bracket\", \"reverse\"];\n\nconst _require = createRequire(import.meta.url);\n\n/** package.json からバージョンを取得する */\nexport function getVersion(): string {\n return (_require(\"../package.json\") as { version: string }).version;\n}\n\n/**\n * CLI フラグ・環境変数・TTY 状態から最終的な color フラグを解決する。\n * 優先順位: --no-color > --color > NO_COLOR > FORCE_COLOR > TTY\n */\nexport function resolveColor(\n colorFlag: boolean | undefined,\n noColorFlag: boolean | undefined,\n env: Record<string, string | undefined>,\n isTTY: boolean,\n): boolean {\n if (noColorFlag) return false;\n if (colorFlag) return true;\n if (env.NO_COLOR) return false;\n if (env.FORCE_COLOR) return true;\n return isTTY;\n}\n\n/** 値を一つ取るオプションと、代入先のフィールド名 */\nconst VALUE_OPTIONS: Record<string, keyof CliArgs> = {\n \"--theme\": \"theme\",\n \"--color-scheme\": \"colorScheme\",\n \"--locale\": \"locale\",\n \"--holiday-locale\": \"holidayLocale\",\n \"--week-start\": \"weekStart\",\n \"--highlight-style\": \"highlightStyle\",\n};\n\n/** YYYY-MM-DD 形式の日付文字列をパースする */\nexport function parseDate(value: string): Date | null {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value);\n if (!match) return null;\n const year = Number(match[1]);\n const month = Number(match[2]);\n const day = Number(match[3]);\n if (\n year < MIN_YEAR ||\n year > MAX_YEAR ||\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > 31\n ) {\n return null;\n }\n const date = createDate(year, month - 1, day);\n if (\n date.getFullYear() !== year ||\n date.getMonth() !== month - 1 ||\n date.getDate() !== day\n ) {\n return null;\n }\n return date;\n}\n\n/**\n * CLI 引数をパースする。テスト可能なように副作用を分離している。\n */\nexport function parseArgs(args: readonly string[]): ParseResult {\n const result: CliArgs = {};\n const error = (message: string): ParseResult => ({\n args: result,\n error: message,\n });\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]!;\n\n if (arg === \"-h\" || arg === \"--help\") {\n return { args: result, help: true };\n }\n if (arg === \"-v\" || arg === \"--version\") {\n return { args: result, version: true };\n }\n if (arg === \"--color\") {\n result.color = true;\n continue;\n }\n if (arg === \"--no-color\") {\n result.noColor = true;\n continue;\n }\n if (arg === \"--year\") {\n result.yearView = true;\n continue;\n }\n if (arg === \"--week-numbers\") {\n result.weekNumbers = true;\n continue;\n }\n if (arg === \"--highlight\") {\n const value = args[++i];\n if (value === undefined) {\n return error(\"Missing value for option: --highlight\");\n }\n const parsed = parseDate(value);\n if (parsed === null) {\n return error(\n `Invalid --highlight date: \"${value}\" (expected YYYY-MM-DD, e.g. 2026-09-08)`,\n );\n }\n result.highlight = parsed;\n continue;\n }\n if (arg === \"--today\") {\n const value = args[++i];\n if (value === undefined) {\n return error(\"Missing value for option: --today\");\n }\n const parsed = parseDate(value);\n if (parsed === null) {\n return error(\n `Invalid --today date: \"${value}\" (expected YYYY-MM-DD, e.g. 2026-09-08)`,\n );\n }\n result.today = parsed;\n continue;\n }\n if (arg === \"--range\") {\n const fromStr = args[++i];\n const toStr = args[++i];\n if (fromStr === undefined || toStr === undefined) {\n return error(\n \"--range requires two dates (YYYY-MM-DD), e.g. --range 2026-01-01 2026-03-31\",\n );\n }\n const from = parseDate(fromStr);\n const to = parseDate(toStr);\n if (from === null || to === null) {\n return error(\"Invalid --range date (expected YYYY-MM-DD)\");\n }\n if (from.getTime() > to.getTime()) {\n return error(\"--range: from date must not be after to date\");\n }\n result.range = { from, to };\n continue;\n }\n\n const key = VALUE_OPTIONS[arg];\n if (key !== undefined) {\n const value = args[++i];\n if (value === undefined) {\n return error(`Missing value for option: ${arg}`);\n }\n (result as Record<string, unknown>)[key] = value;\n continue;\n }\n\n const numeric = /^-?\\d+$/.test(arg);\n if (arg.startsWith(\"-\") && !numeric) {\n return error(`Unknown option: ${arg}`);\n }\n if (!numeric) {\n return error(\n `Invalid argument: \"${arg}\" (expected a year or month number)`,\n );\n }\n if (result.year === undefined) {\n result.year = Number(arg);\n } else if (result.month === undefined) {\n result.month = Number(arg);\n } else {\n return error(`Too many arguments: \"${arg}\"`);\n }\n }\n\n // 値のバリデーション\n if (\n result.year !== undefined &&\n (result.year < MIN_YEAR || result.year > MAX_YEAR)\n ) {\n return error(\n `Invalid year: ${result.year} (expected ${MIN_YEAR}–${MAX_YEAR})`,\n );\n }\n if (result.month !== undefined && (result.month < 1 || result.month > 12)) {\n return error(`Invalid month: ${result.month} (expected 1–12)`);\n }\n\n const choiceTable: Array<[string | undefined, readonly string[], string]> = [\n [result.theme, THEMES, \"theme\"],\n [result.colorScheme, COLOR_SCHEMES, \"color-scheme\"],\n [result.locale, LOCALE_LIST, \"locale\"],\n [result.holidayLocale, LOCALE_LIST, \"holiday-locale\"],\n [result.weekStart, WEEK_STARTS, \"week-start\"],\n [result.highlightStyle, HIGHLIGHT_STYLES, \"highlight-style\"],\n ];\n for (const [value, choices, name] of choiceTable) {\n if (value !== undefined && !choices.includes(value)) {\n return error(\n `Invalid ${name}: \"${value}\" (expected: ${choices.join(\" | \")})`,\n );\n }\n }\n\n // 相互排他チェック\n if (result.yearView && result.range) {\n return error(\"--year and --range cannot be used together\");\n }\n if (result.yearView && result.month !== undefined) {\n return error(\"Month cannot be used with --year (use --year YYYY instead)\");\n }\n if (\n result.range &&\n (result.year !== undefined || result.month !== undefined)\n ) {\n return error(\"Positional arguments cannot be used with --range\");\n }\n\n return { args: result };\n}\n\nexport function printUsage(): string {\n return `Usage: typescript-calendar-lib [YYYY] [MM] [options]\n\n typescript-calendar-lib Render the current month\n typescript-calendar-lib 2026 Render the current month of 2026\n typescript-calendar-lib 2026 9 Render September 2026\n typescript-calendar-lib --year Render the current year (4×3 grid)\n typescript-calendar-lib 2026 --year Render 2026 as a year grid\n typescript-calendar-lib --range 2026-01-01 2026-03-31\n Render months from Jan to Mar 2026\n\nOptions:\n --theme <name> Look: default | modern (default: default)\n --color-scheme <name> Colors: default | ocean | forest | sunset | mono (default: default)\n --color Enable ANSI colors (auto-detected for TTY)\n --no-color Disable ANSI colors\n --locale <lang> Language: ${LOCALE_LIST.join(\" | \")} (default: en)\n --holiday-locale <lang> Holiday rules: currently only ja (default: ja)\n --week-start <day> First weekday: sunday | monday (default: sunday)\n --week-numbers Print the week number at the start of each row\n --highlight <YYYY-MM-DD> Highlight a date (e.g. 2026-09-08)\n --highlight-style <style> Highlight style: bracket | reverse (default: bracket)\n --today <YYYY-MM-DD> Override today (marks the date, defaults year/month)\n --year Render the whole year as a 4×3 grid\n --range <FROM> <TO> Render months from FROM to TO (YYYY-MM-DD)\n -v, --version Show version\n -h, --help Show this help\n\nColor:\n --color / --no-color win over the environment. NO_COLOR and FORCE_COLOR are\n honoured next, and a TTY is used as the final fallback.\n`;\n}\n\nif (import.meta.main) {\n const { args, error, help, version } = parseArgs(process.argv.slice(2));\n\n if (version) {\n console.log(getVersion());\n process.exit(0);\n }\n if (help) {\n console.log(printUsage());\n process.exit(0);\n }\n if (error) {\n console.error(`Error: ${error}`);\n console.error(printUsage());\n process.exit(1);\n }\n\n const color = resolveColor(\n args.color,\n args.noColor,\n process.env,\n process.stdout.isTTY === true,\n );\n\n const now = args.today ?? new Date();\n const year = args.year ?? now.getFullYear();\n const month = args.month ?? now.getMonth() + 1;\n\n const common = {\n theme: args.theme,\n colorScheme: args.colorScheme,\n color,\n locale: args.locale,\n holidayLocale: args.holidayLocale,\n weekStart: args.weekStart,\n showWeekNumbers: args.weekNumbers,\n highlight: args.highlight,\n highlightStyle: args.highlightStyle,\n today: args.today,\n };\n\n let output: string;\n if (args.range) {\n output = calendarRange({\n ...common,\n from: args.range.from,\n to: args.range.to,\n });\n } else if (args.yearView) {\n output = calendarYear({ ...common, year });\n } else {\n output = calendar({ ...common, year, month });\n }\n\n console.log(output);\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildMonthGrid, createDate, getCalendarCellState, getMonthName, getMonthRange, getWeekdayHeaders } from "@typescript-calendar-lib/core";
|
|
1
|
+
import { addDays, buildMonthGrid, createDate, getCalendarCellState, getISOWeek, getMonthName, getMonthRange, getWeekOfYear, getWeekdayHeaders } from "@typescript-calendar-lib/core";
|
|
2
2
|
import { THEMES, resolveTheme } from "@typescript-calendar-lib/tui";
|
|
3
3
|
//#region src/align.ts
|
|
4
4
|
/** 東アジアの全角文字(ターミナル表示幅2列) */
|
|
@@ -37,25 +37,27 @@ function stripAnsi(text) {
|
|
|
37
37
|
}
|
|
38
38
|
//#endregion
|
|
39
39
|
//#region src/border.ts
|
|
40
|
-
/** 枠内のコンテンツ幅(例: 7列×3幅+区切り6 =
|
|
41
|
-
function innerWidth(cellWidth, cols) {
|
|
42
|
-
|
|
40
|
+
/** 枠内のコンテンツ幅(例: 週番号列幅2 + 7列×3幅+区切り6 = 30) */
|
|
41
|
+
function innerWidth(cellWidth, cols, weekWidth = 0) {
|
|
42
|
+
const week = weekWidth > 0 ? weekWidth + 1 : 0;
|
|
43
|
+
return cols * cellWidth + (cols - 1) + week;
|
|
43
44
|
}
|
|
44
|
-
/** セル幅の水平線を cols
|
|
45
|
-
function divider(frame, cellWidth, cols, left, right, join) {
|
|
46
|
-
|
|
45
|
+
/** セル幅の水平線を cols+(週番号列)個つなげた区切り線を生成する */
|
|
46
|
+
function divider(frame, cellWidth, cols, left, right, join, weekWidth = 0) {
|
|
47
|
+
const cellSegments = Array(cols).fill(frame.h.repeat(cellWidth));
|
|
48
|
+
return `${left}${(weekWidth > 0 ? [frame.h.repeat(weekWidth), ...cellSegments] : cellSegments).join(join)}${right}`;
|
|
47
49
|
}
|
|
48
50
|
/** 上枠: ┌────┬────...────┐ */
|
|
49
|
-
function topBorder(frame, cellWidth, cols) {
|
|
50
|
-
return `${frame.topLeft}${frame.h.repeat(innerWidth(cellWidth, cols))}${frame.topRight}`;
|
|
51
|
+
function topBorder(frame, cellWidth, cols, weekWidth = 0) {
|
|
52
|
+
return `${frame.topLeft}${frame.h.repeat(innerWidth(cellWidth, cols, weekWidth))}${frame.topRight}`;
|
|
51
53
|
}
|
|
52
54
|
/** 下枠: └────┴────...────┘ */
|
|
53
|
-
function bottomBorder(frame, cellWidth, cols) {
|
|
54
|
-
return divider(frame, cellWidth, cols, frame.bottomLeft, frame.bottomRight, frame.footJ);
|
|
55
|
+
function bottomBorder(frame, cellWidth, cols, weekWidth = 0) {
|
|
56
|
+
return divider(frame, cellWidth, cols, frame.bottomLeft, frame.bottomRight, frame.footJ, weekWidth);
|
|
55
57
|
}
|
|
56
58
|
/** 区切り行: ├────┬────...┬────┤ */
|
|
57
|
-
function separatorRow(frame, cellWidth, cols) {
|
|
58
|
-
return divider(frame, cellWidth, cols, "├", "┤", frame.j);
|
|
59
|
+
function separatorRow(frame, cellWidth, cols, weekWidth = 0) {
|
|
60
|
+
return divider(frame, cellWidth, cols, "├", "┤", frame.j, weekWidth);
|
|
59
61
|
}
|
|
60
62
|
//#endregion
|
|
61
63
|
//#region src/theme.ts
|
|
@@ -63,6 +65,7 @@ const COLOR_SCHEMES = {
|
|
|
63
65
|
/** 従来どおり。着色は range(黄) と highlight(反転) のみ */
|
|
64
66
|
default: {
|
|
65
67
|
range: 33,
|
|
68
|
+
holiday: 31,
|
|
66
69
|
highlight: 7
|
|
67
70
|
},
|
|
68
71
|
ocean: {
|
|
@@ -70,6 +73,7 @@ const COLOR_SCHEMES = {
|
|
|
70
73
|
weekday: 36,
|
|
71
74
|
day: 37,
|
|
72
75
|
weekend: 34,
|
|
76
|
+
holiday: 31,
|
|
73
77
|
today: 36,
|
|
74
78
|
highlight: 7,
|
|
75
79
|
range: 34,
|
|
@@ -81,6 +85,7 @@ const COLOR_SCHEMES = {
|
|
|
81
85
|
weekday: 32,
|
|
82
86
|
day: 37,
|
|
83
87
|
weekend: 90,
|
|
88
|
+
holiday: 31,
|
|
84
89
|
today: 32,
|
|
85
90
|
highlight: 7,
|
|
86
91
|
range: 32,
|
|
@@ -92,6 +97,7 @@ const COLOR_SCHEMES = {
|
|
|
92
97
|
weekday: 35,
|
|
93
98
|
day: 37,
|
|
94
99
|
weekend: 33,
|
|
100
|
+
holiday: 31,
|
|
95
101
|
today: 35,
|
|
96
102
|
highlight: 7,
|
|
97
103
|
range: 35,
|
|
@@ -103,6 +109,7 @@ const COLOR_SCHEMES = {
|
|
|
103
109
|
weekday: 37,
|
|
104
110
|
day: 37,
|
|
105
111
|
weekend: 90,
|
|
112
|
+
holiday: 31,
|
|
106
113
|
today: 37,
|
|
107
114
|
highlight: 7,
|
|
108
115
|
range: 90,
|
|
@@ -115,11 +122,13 @@ function resolveColorScheme(scheme) {
|
|
|
115
122
|
}
|
|
116
123
|
//#endregion
|
|
117
124
|
//#region src/month.ts
|
|
125
|
+
/** 週番号の表示幅(最大 2 桁: 1-53) */
|
|
126
|
+
const WEEK_WIDTH = 2;
|
|
118
127
|
/**
|
|
119
128
|
* 1ヶ月分のカレンダーテキストを描画する
|
|
120
129
|
*/
|
|
121
130
|
function renderMonth(year, month, options = {}) {
|
|
122
|
-
const { locale = "en", weekStart = "sunday", highlight, highlightStyle = "bracket", range, color = false, theme: themeOption = "default", colorScheme: schemeOption = "default", today = /* @__PURE__ */ new Date(), isDateDisabled, cellData, renderCell: customRenderCell } = options;
|
|
131
|
+
const { locale = "en", holidayLocale, weekStart = "sunday", highlight, highlightStyle = "bracket", range, color = false, theme: themeOption = "default", colorScheme: schemeOption = "default", today = /* @__PURE__ */ new Date(), isDateDisabled, cellData, renderCell: customRenderCell, showWeekNumbers = false } = options;
|
|
123
132
|
const theme = resolveTheme(themeOption);
|
|
124
133
|
const palette = resolveColorScheme(schemeOption);
|
|
125
134
|
const frame = theme.frame;
|
|
@@ -127,6 +136,7 @@ function renderMonth(year, month, options = {}) {
|
|
|
127
136
|
const weekdays = getWeekdayHeaders(locale, weekStart);
|
|
128
137
|
const grid = buildMonthGrid(year, month, weekStart);
|
|
129
138
|
const cols = weekdays.length;
|
|
139
|
+
const weekWidth = showWeekNumbers ? WEEK_WIDTH : 0;
|
|
130
140
|
const cellWidth = Math.max(theme.cellWidth, ...weekdays.map(displayWidth), highlight !== void 0 && highlightStyle === "bracket" ? 4 : 2);
|
|
131
141
|
const sep = frame === null ? theme.separator : frame.v;
|
|
132
142
|
/** 1セルを描画する(day は日数または null=空欄) */
|
|
@@ -135,13 +145,14 @@ function renderMonth(year, month, options = {}) {
|
|
|
135
145
|
const date = createDate(year, month - 1, day);
|
|
136
146
|
const state = getCalendarCellState(date, {
|
|
137
147
|
today,
|
|
148
|
+
holidayLocale,
|
|
138
149
|
highlight,
|
|
139
150
|
range,
|
|
140
151
|
isDateDisabled
|
|
141
152
|
});
|
|
142
153
|
const data = cellData?.(date);
|
|
143
154
|
if (customRenderCell !== void 0) return customRenderCell(day, date, state, data);
|
|
144
|
-
const { isHighlight, isInRange, isToday, isDisabled, isWeekend } = state;
|
|
155
|
+
const { isHighlight, isInRange, isToday, isDisabled, isWeekend, isHoliday } = state;
|
|
145
156
|
const text = (isHighlight && highlightStyle === "bracket" ? `[${day}]` : String(day)).padStart(cellWidth);
|
|
146
157
|
let code;
|
|
147
158
|
if (isHighlight && highlightStyle === "reverse") code = palette.highlight ?? 7;
|
|
@@ -149,27 +160,46 @@ function renderMonth(year, month, options = {}) {
|
|
|
149
160
|
else if (isToday && palette.today !== void 0) code = palette.today;
|
|
150
161
|
else if (isDisabled) code = palette.dim ?? 90;
|
|
151
162
|
else if (isWeekend && palette.weekend !== void 0) code = palette.weekend;
|
|
163
|
+
else if (isHoliday && palette.holiday !== void 0) code = palette.holiday;
|
|
152
164
|
else if (palette.day !== void 0) code = palette.day;
|
|
153
165
|
return colorize(text, code, color);
|
|
154
166
|
};
|
|
167
|
+
/**
|
|
168
|
+
* 行の週番号を表示幅に揃えて返す。週の開始日(行の先頭セルの曜日位置から
|
|
169
|
+
* 逆算)の週番号を使う。weekStart が "monday" なら ISO 週番号、それ以外は
|
|
170
|
+
* 年始を含む週を第1週とする番号(北米の cal -w 相当)。
|
|
171
|
+
*/
|
|
172
|
+
const weekLabel = (row) => {
|
|
173
|
+
if (weekWidth === 0) return "";
|
|
174
|
+
const firstIdx = row.findIndex((d) => d !== null);
|
|
175
|
+
if (firstIdx === -1) return " ".repeat(weekWidth);
|
|
176
|
+
const firstDate = createDate(year, month - 1, row[firstIdx]);
|
|
177
|
+
const weekStartDate = addDays(firstDate, -firstIdx);
|
|
178
|
+
const number = weekStart === "monday" ? getISOWeek(weekStartDate) : getWeekOfYear(weekStartDate);
|
|
179
|
+
return String(number).padStart(weekWidth);
|
|
180
|
+
};
|
|
155
181
|
const lines = [];
|
|
156
182
|
if (frame === null) {
|
|
157
|
-
const totalWidth = cols * cellWidth + (cols - 1) * sep.length;
|
|
183
|
+
const totalWidth = (weekWidth > 0 ? weekWidth + sep.length : 0) + cols * cellWidth + (cols - 1) * sep.length;
|
|
158
184
|
lines.push(centerText(title, totalWidth));
|
|
159
|
-
|
|
185
|
+
const headerCells = weekdays.map((d) => colorize(padStartWidth(d, cellWidth), palette.weekday, color)).join(sep);
|
|
186
|
+
lines.push(weekWidth > 0 ? " ".repeat(weekWidth) + sep + headerCells : headerCells);
|
|
160
187
|
} else {
|
|
161
|
-
lines.push(colorize(topBorder(frame, cellWidth, cols), palette.frame, color));
|
|
162
|
-
lines.push(colorize(`${frame.v}${centerTextFull(title, innerWidth(cellWidth, cols))}${frame.v}`, palette.title, color));
|
|
163
|
-
lines.push(colorize(separatorRow(frame, cellWidth, cols), palette.frame, color));
|
|
164
|
-
|
|
165
|
-
|
|
188
|
+
lines.push(colorize(topBorder(frame, cellWidth, cols, weekWidth), palette.frame, color));
|
|
189
|
+
lines.push(colorize(`${frame.v}${centerTextFull(title, innerWidth(cellWidth, cols, weekWidth))}${frame.v}`, palette.title, color));
|
|
190
|
+
lines.push(colorize(separatorRow(frame, cellWidth, cols, weekWidth), palette.frame, color));
|
|
191
|
+
const headerCells = weekdays.map((d) => padStartWidth(d, cellWidth)).join(frame.v);
|
|
192
|
+
const header = weekWidth > 0 ? " ".repeat(weekWidth) + frame.v + headerCells : headerCells;
|
|
193
|
+
lines.push(colorize(`${frame.v}${header}${frame.v}`, palette.weekday, color));
|
|
194
|
+
lines.push(colorize(separatorRow(frame, cellWidth, cols, weekWidth), palette.frame, color));
|
|
166
195
|
}
|
|
167
196
|
for (const row of grid) {
|
|
168
197
|
if (row.every((d) => d === null)) continue;
|
|
169
198
|
const cells = row.map(renderCell).join(sep);
|
|
170
|
-
|
|
199
|
+
const week = weekWidth > 0 ? weekLabel(row) + sep : "";
|
|
200
|
+
lines.push(frame === null ? week + cells : `${frame.v}${week}${cells}${frame.v}`);
|
|
171
201
|
}
|
|
172
|
-
if (frame !== null) lines.push(colorize(bottomBorder(frame, cellWidth, cols), palette.frame, color));
|
|
202
|
+
if (frame !== null) lines.push(colorize(bottomBorder(frame, cellWidth, cols, weekWidth), palette.frame, color));
|
|
173
203
|
return lines.join("\n");
|
|
174
204
|
}
|
|
175
205
|
//#endregion
|
|
@@ -221,4 +251,4 @@ function calendarRange(options) {
|
|
|
221
251
|
//#endregion
|
|
222
252
|
export { THEMES as a, COLOR_SCHEMES as i, calendarRange as n, resolveColorScheme as o, calendarYear as r, resolveTheme as s, calendar as t };
|
|
223
253
|
|
|
224
|
-
//# sourceMappingURL=calendar-
|
|
254
|
+
//# sourceMappingURL=calendar-BpDw0iF-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar-BpDw0iF-.js","names":[],"sources":["../src/align.ts","../src/ansi.ts","../src/border.ts","../src/theme.ts","../src/month.ts","../src/year.ts","../src/calendar.ts"],"sourcesContent":["// ─── テキスト整列 ────────────────────────────────────────\n\n/** 東アジアの全角文字(ターミナル表示幅2列) */\nconst WIDE =\n /[\\u1100-\\u115f\\u2e80-\\u303e\\u3041-\\u33ff\\u3400-\\u4dbf\\u4e00-\\u9fff\\ua000-\\ua4cf\\ua960-\\ua97f\\uac00-\\ud7a3\\uf900-\\ufaff\\ufe30-\\ufe4f\\uff00-\\uff60\\uffe0-\\uffe6]/;\n\n/** ターミナル上の表示幅を返す(全角文字は2列として数える) */\nexport function displayWidth(text: string): number {\n let width = 0;\n for (const ch of text) {\n width += WIDE.test(ch) ? 2 : 1;\n }\n return width;\n}\n\n/** 表示幅 width に右詰めする(全角文字対応) */\nexport function padStartWidth(text: string, width: number): string {\n return \" \".repeat(Math.max(0, width - displayWidth(text))) + text;\n}\n\n/** タイトルを幅の中央に揃える */\nexport function centerText(text: string, width: number): string {\n const padding = Math.max(0, Math.floor((width - displayWidth(text)) / 2));\n return \" \".repeat(padding) + text;\n}\n\n/** タイトルを中央に揃え、幅一杯まで埋める(枠内用) */\nexport function centerTextFull(text: string, width: number): string {\n const padding = Math.max(0, Math.floor((width - displayWidth(text)) / 2));\n return (\n \" \".repeat(padding) +\n text +\n \" \".repeat(Math.max(0, width - padding - displayWidth(text)))\n );\n}\n","// ─── ANSI 色付け ─────────────────────────────────────────\n\nimport { displayWidth } from \"./align.ts\";\n\nconst ANSI_PATTERN = new RegExp(`${\"\\u001b\"}\\\\[[0-9;]*m`, \"g\");\n\n/** ANSI コードを付与する(code が undefined ならそのまま) */\nexport function colorize(\n text: string,\n code: number | undefined,\n enabled: boolean,\n): string {\n if (!enabled || code === undefined) return text;\n return `\\u001b[${code}m${text}\\u001b[0m`;\n}\n\n/** ANSI エスケープシーケンスを除去した文字列を返す */\nexport function stripAnsi(text: string): string {\n return text.replace(ANSI_PATTERN, \"\");\n}\n\n/** ANSI エスケープシーケンスを除去した表示幅を返す(全角文字は2列) */\nexport function visibleWidth(text: string): number {\n return displayWidth(stripAnsi(text));\n}\n","import type { FrameChars } from \"./theme.ts\";\n\n// ─── 枠線 ─────────────────────────────────────────────────\n\n/** 枠内のコンテンツ幅(例: 週番号列幅2 + 7列×3幅+区切り6 = 30) */\nexport function innerWidth(\n cellWidth: number,\n cols: number,\n weekWidth = 0,\n): number {\n const week = weekWidth > 0 ? weekWidth + 1 : 0;\n return cols * cellWidth + (cols - 1) + week;\n}\n\n/** セル幅の水平線を cols+(週番号列)個つなげた区切り線を生成する */\nfunction divider(\n frame: FrameChars,\n cellWidth: number,\n cols: number,\n left: string,\n right: string,\n join: string,\n weekWidth = 0,\n): string {\n const cellSegments = Array<string>(cols).fill(frame.h.repeat(cellWidth));\n const segments =\n weekWidth > 0 ? [frame.h.repeat(weekWidth), ...cellSegments] : cellSegments;\n return `${left}${segments.join(join)}${right}`;\n}\n\n/** 上枠: ┌────┬────...────┐ */\nexport function topBorder(\n frame: FrameChars,\n cellWidth: number,\n cols: number,\n weekWidth = 0,\n): string {\n return `${frame.topLeft}${frame.h.repeat(innerWidth(cellWidth, cols, weekWidth))}${frame.topRight}`;\n}\n\n/** 下枠: └────┴────...────┘ */\nexport function bottomBorder(\n frame: FrameChars,\n cellWidth: number,\n cols: number,\n weekWidth = 0,\n): string {\n return divider(\n frame,\n cellWidth,\n cols,\n frame.bottomLeft,\n frame.bottomRight,\n frame.footJ,\n weekWidth,\n );\n}\n\n/** 区切り行: ├────┬────...┬────┤ */\nexport function separatorRow(\n frame: FrameChars,\n cellWidth: number,\n cols: number,\n weekWidth = 0,\n): string {\n return divider(frame, cellWidth, cols, \"├\", \"┤\", frame.j, weekWidth);\n}\n","// ─── テーマ ───────────────────────────────────────────────\n// 文字ベースのテーマ(ThemeName / FrameChars / Theme / THEMES / resolveTheme)は\n// tui の headless 定義をそのまま使用する(cli は唯一の消費者であり、複製しない)。\n\nexport type { FrameChars, ThemeName } from \"@typescript-calendar-lib/tui\";\n\nimport type { Theme } from \"@typescript-calendar-lib/tui\";\n\n/** 文字ベースの見た目定義。tui の Theme と同一 */\nexport type CliTheme = Theme;\n\nexport { resolveTheme, THEMES } from \"@typescript-calendar-lib/tui\";\n\n// ─── カラースキーム ───────────────────────────────────────\n\n/** 組み込みカラースキーム名。カスタムは CliPalette を直接渡せる */\nexport type ColorSchemeName =\n | \"default\"\n | \"ocean\"\n | \"forest\"\n | \"sunset\"\n | \"mono\";\n\n/**\n * ANSIカラーパレット。\n * 各フィールドは前景色(またはハイライト時の背景)のANSIコード。\n * undefined はその要素を着色しない。\n */\nexport interface CliPalette {\n title?: number;\n weekday?: number;\n day?: number;\n weekend?: number;\n holiday?: number;\n today?: number;\n /** highlightStyle: \"reverse\" のときに使うコード(default は 7 = 反転) */\n highlight?: number;\n range?: number;\n frame?: number;\n dim?: number;\n}\n\nexport const COLOR_SCHEMES: Record<ColorSchemeName, CliPalette> = {\n /** 従来どおり。着色は range(黄) と highlight(反転) のみ */\n default: {\n range: 33,\n holiday: 31,\n highlight: 7,\n },\n ocean: {\n title: 36,\n weekday: 36,\n day: 37,\n weekend: 34,\n holiday: 31,\n today: 36,\n highlight: 7,\n range: 34,\n frame: 36,\n dim: 90,\n },\n forest: {\n title: 32,\n weekday: 32,\n day: 37,\n weekend: 90,\n holiday: 31,\n today: 32,\n highlight: 7,\n range: 32,\n frame: 32,\n dim: 90,\n },\n sunset: {\n title: 35,\n weekday: 35,\n day: 37,\n weekend: 33,\n holiday: 31,\n today: 35,\n highlight: 7,\n range: 35,\n frame: 35,\n dim: 90,\n },\n mono: {\n title: 37,\n weekday: 37,\n day: 37,\n weekend: 90,\n holiday: 31,\n today: 37,\n highlight: 7,\n range: 90,\n frame: 90,\n dim: 90,\n },\n};\n\nexport function resolveColorScheme(\n scheme?: ColorSchemeName | CliPalette,\n): CliPalette {\n return typeof scheme === \"string\"\n ? (COLOR_SCHEMES[scheme] ?? COLOR_SCHEMES.default)\n : (scheme ?? COLOR_SCHEMES.default);\n}\n","import {\n addDays,\n buildMonthGrid,\n createDate,\n getCalendarCellState,\n getISOWeek,\n getMonthName,\n getWeekdayHeaders,\n getWeekOfYear,\n} from \"@typescript-calendar-lib/core\";\nimport {\n centerText,\n centerTextFull,\n displayWidth,\n padStartWidth,\n} from \"./align.ts\";\nimport { colorize } from \"./ansi.ts\";\nimport { bottomBorder, innerWidth, separatorRow, topBorder } from \"./border.ts\";\nimport { resolveColorScheme, resolveTheme } from \"./theme.ts\";\nimport type { RenderMonthOptions } from \"./types.ts\";\n\n/** 週番号の表示幅(最大 2 桁: 1-53) */\nconst WEEK_WIDTH = 2;\n\n/**\n * 1ヶ月分のカレンダーテキストを描画する\n */\nexport function renderMonth(\n year: number,\n month: number,\n options: RenderMonthOptions = {},\n): string {\n const {\n locale = \"en\",\n holidayLocale,\n weekStart = \"sunday\",\n highlight,\n highlightStyle = \"bracket\",\n range,\n color = false,\n theme: themeOption = \"default\",\n colorScheme: schemeOption = \"default\",\n today = new Date(),\n isDateDisabled,\n cellData,\n renderCell: customRenderCell,\n showWeekNumbers = false,\n } = options;\n\n const theme = resolveTheme(themeOption);\n const palette = resolveColorScheme(schemeOption);\n const frame = theme.frame;\n\n const title = `${getMonthName(locale, month)} ${year}`;\n const weekdays = getWeekdayHeaders(locale, weekStart);\n const grid = buildMonthGrid(year, month, weekStart);\n const cols = weekdays.length;\n const weekWidth = showWeekNumbers ? WEEK_WIDTH : 0;\n\n // セル幅はテーマ指定を基本としつつ、以下を満たすように広げる:\n // - 曜日ヘッダーの表示幅(fr の \"dim.\" 等がセル幅を超えると列が崩れる)\n // - bracket ハイライトは2桁の日付で `[10]` の4文字になるため\n const cellWidth = Math.max(\n theme.cellWidth,\n ...weekdays.map(displayWidth),\n highlight !== undefined && highlightStyle === \"bracket\" ? 4 : 2,\n );\n\n // 枠なしテーマは separator、枠ありテーマは縦線でセルを繋ぐ\n const sep = frame === null ? theme.separator : frame.v;\n\n /** 1セルを描画する(day は日数または null=空欄) */\n const renderCell = (day: number | null): string => {\n if (day === null) return \" \".repeat(cellWidth);\n\n const date = createDate(year, month - 1, day);\n const state = getCalendarCellState(date, {\n today,\n holidayLocale,\n highlight,\n range,\n isDateDisabled,\n });\n const data = cellData?.(date);\n\n // ユーザー定義の描画があれば、解決済みデータを渡して委譲する\n if (customRenderCell !== undefined) {\n return customRenderCell(day, date, state, data);\n }\n\n const {\n isHighlight,\n isInRange,\n isToday,\n isDisabled,\n isWeekend,\n isHoliday,\n } = state;\n\n const text = (\n isHighlight && highlightStyle === \"bracket\" ? `[${day}]` : String(day)\n ).padStart(cellWidth);\n\n // 優先順位: highlight > range > today > disabled > weekend > holiday > day\n let code: number | undefined;\n if (isHighlight && highlightStyle === \"reverse\") {\n code = palette.highlight ?? 7;\n } else if (isInRange && !isHighlight) {\n code = palette.range ?? 33;\n } else if (isToday && palette.today !== undefined) {\n code = palette.today;\n } else if (isDisabled) {\n code = palette.dim ?? 90;\n } else if (isWeekend && palette.weekend !== undefined) {\n code = palette.weekend;\n } else if (isHoliday && palette.holiday !== undefined) {\n code = palette.holiday;\n } else if (palette.day !== undefined) {\n code = palette.day;\n }\n\n return colorize(text, code, color);\n };\n\n /**\n * 行の週番号を表示幅に揃えて返す。週の開始日(行の先頭セルの曜日位置から\n * 逆算)の週番号を使う。weekStart が \"monday\" なら ISO 週番号、それ以外は\n * 年始を含む週を第1週とする番号(北米の cal -w 相当)。\n */\n const weekLabel = (row: (number | null)[]): string => {\n if (weekWidth === 0) return \"\";\n const firstIdx = row.findIndex((d) => d !== null);\n if (firstIdx === -1) return \" \".repeat(weekWidth);\n const firstDate = createDate(year, month - 1, row[firstIdx]!);\n const weekStartDate = addDays(firstDate, -firstIdx);\n const number =\n weekStart === \"monday\"\n ? getISOWeek(weekStartDate)\n : getWeekOfYear(weekStartDate);\n return String(number).padStart(weekWidth);\n };\n\n const lines: string[] = [];\n\n if (frame === null) {\n // ── 枠なし(default) ──\n const weekCol = weekWidth > 0 ? weekWidth + sep.length : 0;\n const totalWidth = weekCol + cols * cellWidth + (cols - 1) * sep.length;\n lines.push(centerText(title, totalWidth));\n const headerCells = weekdays\n .map((d) => colorize(padStartWidth(d, cellWidth), palette.weekday, color))\n .join(sep);\n lines.push(\n weekWidth > 0 ? \" \".repeat(weekWidth) + sep + headerCells : headerCells,\n );\n } else {\n // ── 枠あり(modern) ──\n lines.push(\n colorize(\n topBorder(frame, cellWidth, cols, weekWidth),\n palette.frame,\n color,\n ),\n );\n lines.push(\n colorize(\n `${frame.v}${centerTextFull(title, innerWidth(cellWidth, cols, weekWidth))}${frame.v}`,\n palette.title,\n color,\n ),\n );\n lines.push(\n colorize(\n separatorRow(frame, cellWidth, cols, weekWidth),\n palette.frame,\n color,\n ),\n );\n const headerCells = weekdays\n .map((d) => padStartWidth(d, cellWidth))\n .join(frame.v);\n const header =\n weekWidth > 0\n ? \" \".repeat(weekWidth) + frame.v + headerCells\n : headerCells;\n lines.push(\n colorize(`${frame.v}${header}${frame.v}`, palette.weekday, color),\n );\n lines.push(\n colorize(\n separatorRow(frame, cellWidth, cols, weekWidth),\n palette.frame,\n color,\n ),\n );\n }\n\n for (const row of grid) {\n if (row.every((d) => d === null)) continue;\n const cells = row.map(renderCell).join(sep);\n const week = weekWidth > 0 ? weekLabel(row) + sep : \"\";\n lines.push(\n frame === null ? week + cells : `${frame.v}${week}${cells}${frame.v}`,\n );\n }\n\n if (frame !== null) {\n lines.push(\n colorize(\n bottomBorder(frame, cellWidth, cols, weekWidth),\n palette.frame,\n color,\n ),\n );\n }\n\n return lines.join(\"\\n\");\n}\n","import { displayWidth } from \"./align.ts\";\nimport { stripAnsi } from \"./ansi.ts\";\nimport { renderMonth } from \"./month.ts\";\nimport type { RenderMonthOptions } from \"./types.ts\";\n\n/**\n * 年間カレンダーを4列×3行でテキストで返す\n *\n * 列幅・パディングは「ANSI 除去後のターミナル表示幅」で計算する。\n * 全角文字(日本語・韓国語・中国語の月名や曜日)も正しく揃う。\n */\nexport function renderYear(\n year: number,\n options: RenderMonthOptions = {},\n): string {\n const widthOf = (line: string): number => displayWidth(stripAnsi(line));\n\n const months = Array.from({ length: 12 }, (_, i) =>\n renderMonth(year, i + 1, options).split(\"\\n\"),\n );\n const maxLines = Math.max(...months.map((lines) => lines.length));\n const colWidths = months.map((lines) => Math.max(...lines.map(widthOf)));\n\n /** 月の各行をその列幅まで右パディングする(行が足りなければ空行として埋める) */\n const padMonth = (monthIdx: number): string[] =>\n Array.from({ length: maxLines }, (_, li) => {\n const line = months[monthIdx]![li] ?? \"\";\n return (\n line + \" \".repeat(Math.max(0, colWidths[monthIdx]! - widthOf(line)))\n );\n });\n\n const padded = months.map((_, mi) => padMonth(mi));\n\n const rows: string[] = [];\n for (let row = 0; row < 3; row++) {\n rows.push(\n Array.from({ length: maxLines }, (_, li) =>\n Array.from({ length: 4 }, (_, col) => {\n const monthIdx = row * 4 + col;\n return monthIdx < 12 ? padded[monthIdx]![li]! : \"\";\n }).join(\" \"),\n ).join(\"\\n\"),\n );\n }\n\n return rows.join(\"\\n\\n\");\n}\n","import { getMonthRange } from \"@typescript-calendar-lib/core\";\nimport { renderMonth, renderYear } from \"./render.ts\";\nimport type {\n CalendarOptions,\n CalendarRangeOptions,\n CalendarYearOptions,\n} from \"./types.ts\";\n\n/**\n * 月カレンダーをテキストで返す\n */\nexport function calendar(options: CalendarOptions): string {\n return renderMonth(options.year, options.month, options);\n}\n\n/**\n * 年間カレンダーを4列×3行でテキストで返す\n */\nexport function calendarYear(options: CalendarYearOptions): string {\n return renderYear(options.year, options);\n}\n\n/**\n * 任意の日付範囲のカレンダーをテキストで返す\n */\nexport function calendarRange(options: CalendarRangeOptions): string {\n const months = getMonthRange(options.from, options.to);\n return months\n .map(({ year, month }) => renderMonth(year, month, options))\n .join(\"\\n\\n\");\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as FrameChars, c as resolveColorScheme, i as ColorSchemeName, l as resolveTheme, n as CliPalette, o as THEMES, r as CliTheme, s as ThemeName, t as COLOR_SCHEMES } from "./theme-
|
|
1
|
+
import { a as FrameChars, c as resolveColorScheme, i as ColorSchemeName, l as resolveTheme, n as CliPalette, o as THEMES, r as CliTheme, s as ThemeName, t as COLOR_SCHEMES } from "./theme-rvXGNLpG.js";
|
|
2
2
|
import { CalendarCellState, CalendarOptions as CalendarOptions$1, CalendarRangeOptions as CalendarRangeOptions$1, CalendarYearOptions as CalendarYearOptions$1, RenderMonthOptions as RenderMonthOptions$1 } from "@typescript-calendar-lib/core";
|
|
3
3
|
//#region src/types.d.ts
|
|
4
4
|
/** CLI 固有のオプション(core のオプションに追加で受け付ける) */
|
|
@@ -15,6 +15,8 @@ interface CliExtraOptions {
|
|
|
15
15
|
cellData?: (date: Date) => unknown;
|
|
16
16
|
/** セル内容のカスタム描画。受け取った文字列がそのままセルに使われる(幅・ANSI は呼び出し側で調整) */
|
|
17
17
|
renderCell?: (day: number, date: Date, state: CalendarCellState, data?: unknown) => string;
|
|
18
|
+
/** 各行の先頭に週番号を表示する。既定は false。weekStart が "monday" なら ISO 週番号、それ以外は年始を含む週を第1週とする番号 */
|
|
19
|
+
showWeekNumbers?: boolean;
|
|
18
20
|
}
|
|
19
21
|
type CalendarOptions = CalendarOptions$1 & CliExtraOptions;
|
|
20
22
|
type CalendarYearOptions = CalendarYearOptions$1 & CliExtraOptions;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as THEMES, i as COLOR_SCHEMES, n as calendarRange, o as resolveColorScheme, r as calendarYear, s as resolveTheme, t as calendar } from "./calendar-
|
|
1
|
+
import { a as THEMES, i as COLOR_SCHEMES, n as calendarRange, o as resolveColorScheme, r as calendarYear, s as resolveTheme, t as calendar } from "./calendar-BpDw0iF-.js";
|
|
2
2
|
export { COLOR_SCHEMES, THEMES, calendar, calendarRange, calendarYear, resolveColorScheme, resolveTheme };
|
|
@@ -14,6 +14,7 @@ interface CliPalette {
|
|
|
14
14
|
weekday?: number;
|
|
15
15
|
day?: number;
|
|
16
16
|
weekend?: number;
|
|
17
|
+
holiday?: number;
|
|
17
18
|
today?: number;
|
|
18
19
|
/** highlightStyle: "reverse" のときに使うコード(default は 7 = 反転) */
|
|
19
20
|
highlight?: number;
|
|
@@ -25,4 +26,4 @@ declare const COLOR_SCHEMES: Record<ColorSchemeName, CliPalette>;
|
|
|
25
26
|
declare function resolveColorScheme(scheme?: ColorSchemeName | CliPalette): CliPalette;
|
|
26
27
|
//#endregion
|
|
27
28
|
export { FrameChars as a, resolveColorScheme as c, ColorSchemeName as i, resolveTheme as l, CliPalette as n, THEMES as o, CliTheme as r, ThemeName as s, COLOR_SCHEMES as t };
|
|
28
|
-
//# sourceMappingURL=theme-
|
|
29
|
+
//# sourceMappingURL=theme-rvXGNLpG.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typescript-calendar-lib/cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Terminal calendar renderer with themes and ANSI color schemes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
],
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@typescript-calendar-lib/core": "0.5.
|
|
34
|
-
"@typescript-calendar-lib/tui": "0.5.
|
|
33
|
+
"@typescript-calendar-lib/core": "^0.5.4",
|
|
34
|
+
"@typescript-calendar-lib/tui": "^0.5.4"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "tsdown"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"calendar-f8j9RTe9.js","names":[],"sources":["../src/align.ts","../src/ansi.ts","../src/border.ts","../src/theme.ts","../src/month.ts","../src/year.ts","../src/calendar.ts"],"sourcesContent":["// ─── テキスト整列 ────────────────────────────────────────\n\n/** 東アジアの全角文字(ターミナル表示幅2列) */\nconst WIDE =\n /[\\u1100-\\u115f\\u2e80-\\u303e\\u3041-\\u33ff\\u3400-\\u4dbf\\u4e00-\\u9fff\\ua000-\\ua4cf\\ua960-\\ua97f\\uac00-\\ud7a3\\uf900-\\ufaff\\ufe30-\\ufe4f\\uff00-\\uff60\\uffe0-\\uffe6]/;\n\n/** ターミナル上の表示幅を返す(全角文字は2列として数える) */\nexport function displayWidth(text: string): number {\n let width = 0;\n for (const ch of text) {\n width += WIDE.test(ch) ? 2 : 1;\n }\n return width;\n}\n\n/** 表示幅 width に右詰めする(全角文字対応) */\nexport function padStartWidth(text: string, width: number): string {\n return \" \".repeat(Math.max(0, width - displayWidth(text))) + text;\n}\n\n/** タイトルを幅の中央に揃える */\nexport function centerText(text: string, width: number): string {\n const padding = Math.max(0, Math.floor((width - displayWidth(text)) / 2));\n return \" \".repeat(padding) + text;\n}\n\n/** タイトルを中央に揃え、幅一杯まで埋める(枠内用) */\nexport function centerTextFull(text: string, width: number): string {\n const padding = Math.max(0, Math.floor((width - displayWidth(text)) / 2));\n return (\n \" \".repeat(padding) +\n text +\n \" \".repeat(Math.max(0, width - padding - displayWidth(text)))\n );\n}\n","// ─── ANSI 色付け ─────────────────────────────────────────\n\nimport { displayWidth } from \"./align.ts\";\n\nconst ANSI_PATTERN = new RegExp(`${\"\\u001b\"}\\\\[[0-9;]*m`, \"g\");\n\n/** ANSI コードを付与する(code が undefined ならそのまま) */\nexport function colorize(\n text: string,\n code: number | undefined,\n enabled: boolean,\n): string {\n if (!enabled || code === undefined) return text;\n return `\\u001b[${code}m${text}\\u001b[0m`;\n}\n\n/** ANSI エスケープシーケンスを除去した文字列を返す */\nexport function stripAnsi(text: string): string {\n return text.replace(ANSI_PATTERN, \"\");\n}\n\n/** ANSI エスケープシーケンスを除去した表示幅を返す(全角文字は2列) */\nexport function visibleWidth(text: string): number {\n return displayWidth(stripAnsi(text));\n}\n","import type { FrameChars } from \"./theme.ts\";\n\n// ─── 枠線 ─────────────────────────────────────────────────\n\n/** 枠内のコンテンツ幅(例: 7列×3幅+区切り6 = 27) */\nexport function innerWidth(cellWidth: number, cols: number): number {\n return cols * cellWidth + (cols - 1);\n}\n\n/** セル幅の水平線を cols 個つなげた区切り線を生成する */\nfunction divider(\n frame: FrameChars,\n cellWidth: number,\n cols: number,\n left: string,\n right: string,\n join: string,\n): string {\n const segments = Array<string>(cols).fill(frame.h.repeat(cellWidth));\n return `${left}${segments.join(join)}${right}`;\n}\n\n/** 上枠: ┌────┬────...────┐ */\nexport function topBorder(\n frame: FrameChars,\n cellWidth: number,\n cols: number,\n): string {\n return `${frame.topLeft}${frame.h.repeat(innerWidth(cellWidth, cols))}${frame.topRight}`;\n}\n\n/** 下枠: └────┴────...────┘ */\nexport function bottomBorder(\n frame: FrameChars,\n cellWidth: number,\n cols: number,\n): string {\n return divider(\n frame,\n cellWidth,\n cols,\n frame.bottomLeft,\n frame.bottomRight,\n frame.footJ,\n );\n}\n\n/** 区切り行: ├────┬────...┬────┤ */\nexport function separatorRow(\n frame: FrameChars,\n cellWidth: number,\n cols: number,\n): string {\n return divider(frame, cellWidth, cols, \"├\", \"┤\", frame.j);\n}\n","// ─── テーマ ───────────────────────────────────────────────\n// 文字ベースのテーマ(ThemeName / FrameChars / Theme / THEMES / resolveTheme)は\n// tui の headless 定義をそのまま使用する(cli は唯一の消費者であり、複製しない)。\n\nexport type { FrameChars, ThemeName } from \"@typescript-calendar-lib/tui\";\n\nimport type { Theme } from \"@typescript-calendar-lib/tui\";\n\n/** 文字ベースの見た目定義。tui の Theme と同一 */\nexport type CliTheme = Theme;\n\nexport { resolveTheme, THEMES } from \"@typescript-calendar-lib/tui\";\n\n// ─── カラースキーム ───────────────────────────────────────\n\n/** 組み込みカラースキーム名。カスタムは CliPalette を直接渡せる */\nexport type ColorSchemeName =\n | \"default\"\n | \"ocean\"\n | \"forest\"\n | \"sunset\"\n | \"mono\";\n\n/**\n * ANSIカラーパレット。\n * 各フィールドは前景色(またはハイライト時の背景)のANSIコード。\n * undefined はその要素を着色しない。\n */\nexport interface CliPalette {\n title?: number;\n weekday?: number;\n day?: number;\n weekend?: number;\n today?: number;\n /** highlightStyle: \"reverse\" のときに使うコード(default は 7 = 反転) */\n highlight?: number;\n range?: number;\n frame?: number;\n dim?: number;\n}\n\nexport const COLOR_SCHEMES: Record<ColorSchemeName, CliPalette> = {\n /** 従来どおり。着色は range(黄) と highlight(反転) のみ */\n default: {\n range: 33,\n highlight: 7,\n },\n ocean: {\n title: 36,\n weekday: 36,\n day: 37,\n weekend: 34,\n today: 36,\n highlight: 7,\n range: 34,\n frame: 36,\n dim: 90,\n },\n forest: {\n title: 32,\n weekday: 32,\n day: 37,\n weekend: 90,\n today: 32,\n highlight: 7,\n range: 32,\n frame: 32,\n dim: 90,\n },\n sunset: {\n title: 35,\n weekday: 35,\n day: 37,\n weekend: 33,\n today: 35,\n highlight: 7,\n range: 35,\n frame: 35,\n dim: 90,\n },\n mono: {\n title: 37,\n weekday: 37,\n day: 37,\n weekend: 90,\n today: 37,\n highlight: 7,\n range: 90,\n frame: 90,\n dim: 90,\n },\n};\n\nexport function resolveColorScheme(\n scheme?: ColorSchemeName | CliPalette,\n): CliPalette {\n return typeof scheme === \"string\"\n ? (COLOR_SCHEMES[scheme] ?? COLOR_SCHEMES.default)\n : (scheme ?? COLOR_SCHEMES.default);\n}\n","import {\n buildMonthGrid,\n createDate,\n getCalendarCellState,\n getMonthName,\n getWeekdayHeaders,\n} from \"@typescript-calendar-lib/core\";\nimport {\n centerText,\n centerTextFull,\n displayWidth,\n padStartWidth,\n} from \"./align.ts\";\nimport { colorize } from \"./ansi.ts\";\nimport { bottomBorder, innerWidth, separatorRow, topBorder } from \"./border.ts\";\nimport { resolveColorScheme, resolveTheme } from \"./theme.ts\";\nimport type { RenderMonthOptions } from \"./types.ts\";\n\n/**\n * 1ヶ月分のカレンダーテキストを描画する\n */\nexport function renderMonth(\n year: number,\n month: number,\n options: RenderMonthOptions = {},\n): string {\n const {\n locale = \"en\",\n weekStart = \"sunday\",\n highlight,\n highlightStyle = \"bracket\",\n range,\n color = false,\n theme: themeOption = \"default\",\n colorScheme: schemeOption = \"default\",\n today = new Date(),\n isDateDisabled,\n cellData,\n renderCell: customRenderCell,\n } = options;\n\n const theme = resolveTheme(themeOption);\n const palette = resolveColorScheme(schemeOption);\n const frame = theme.frame;\n\n const title = `${getMonthName(locale, month)} ${year}`;\n const weekdays = getWeekdayHeaders(locale, weekStart);\n const grid = buildMonthGrid(year, month, weekStart);\n const cols = weekdays.length;\n\n // セル幅はテーマ指定を基本としつつ、以下を満たすように広げる:\n // - 曜日ヘッダーの表示幅(fr の \"dim.\" 等がセル幅を超えると列が崩れる)\n // - bracket ハイライトは2桁の日付で `[10]` の4文字になるため\n const cellWidth = Math.max(\n theme.cellWidth,\n ...weekdays.map(displayWidth),\n highlight !== undefined && highlightStyle === \"bracket\" ? 4 : 2,\n );\n\n // 枠なしテーマは separator、枠ありテーマは縦線でセルを繋ぐ\n const sep = frame === null ? theme.separator : frame.v;\n\n /** 1セルを描画する(day は日数または null=空欄) */\n const renderCell = (day: number | null): string => {\n if (day === null) return \" \".repeat(cellWidth);\n\n const date = createDate(year, month - 1, day);\n const state = getCalendarCellState(date, {\n today,\n highlight,\n range,\n isDateDisabled,\n });\n const data = cellData?.(date);\n\n // ユーザー定義の描画があれば、解決済みデータを渡して委譲する\n if (customRenderCell !== undefined) {\n return customRenderCell(day, date, state, data);\n }\n\n const { isHighlight, isInRange, isToday, isDisabled, isWeekend } = state;\n\n const text = (\n isHighlight && highlightStyle === \"bracket\" ? `[${day}]` : String(day)\n ).padStart(cellWidth);\n\n // 優先順位: highlight > range > today > disabled > weekend > day\n let code: number | undefined;\n if (isHighlight && highlightStyle === \"reverse\") {\n code = palette.highlight ?? 7;\n } else if (isInRange && !isHighlight) {\n code = palette.range ?? 33;\n } else if (isToday && palette.today !== undefined) {\n code = palette.today;\n } else if (isDisabled) {\n code = palette.dim ?? 90;\n } else if (isWeekend && palette.weekend !== undefined) {\n code = palette.weekend;\n } else if (palette.day !== undefined) {\n code = palette.day;\n }\n\n return colorize(text, code, color);\n };\n\n const lines: string[] = [];\n\n if (frame === null) {\n // ── 枠なし(default) ──\n const totalWidth = cols * cellWidth + (cols - 1) * sep.length;\n lines.push(centerText(title, totalWidth));\n lines.push(\n weekdays\n .map((d) =>\n colorize(padStartWidth(d, cellWidth), palette.weekday, color),\n )\n .join(sep),\n );\n } else {\n // ── 枠あり(modern) ──\n lines.push(\n colorize(topBorder(frame, cellWidth, cols), palette.frame, color),\n );\n lines.push(\n colorize(\n `${frame.v}${centerTextFull(title, innerWidth(cellWidth, cols))}${frame.v}`,\n palette.title,\n color,\n ),\n );\n lines.push(\n colorize(separatorRow(frame, cellWidth, cols), palette.frame, color),\n );\n lines.push(\n colorize(\n `${frame.v}${weekdays.map((d) => padStartWidth(d, cellWidth)).join(frame.v)}${frame.v}`,\n palette.weekday,\n color,\n ),\n );\n lines.push(\n colorize(separatorRow(frame, cellWidth, cols), palette.frame, color),\n );\n }\n\n for (const row of grid) {\n if (row.every((d) => d === null)) continue;\n const cells = row.map(renderCell).join(sep);\n lines.push(frame === null ? cells : `${frame.v}${cells}${frame.v}`);\n }\n\n if (frame !== null) {\n lines.push(\n colorize(bottomBorder(frame, cellWidth, cols), palette.frame, color),\n );\n }\n\n return lines.join(\"\\n\");\n}\n","import { displayWidth } from \"./align.ts\";\nimport { stripAnsi } from \"./ansi.ts\";\nimport { renderMonth } from \"./month.ts\";\nimport type { RenderMonthOptions } from \"./types.ts\";\n\n/**\n * 年間カレンダーを4列×3行でテキストで返す\n *\n * 列幅・パディングは「ANSI 除去後のターミナル表示幅」で計算する。\n * 全角文字(日本語・韓国語・中国語の月名や曜日)も正しく揃う。\n */\nexport function renderYear(\n year: number,\n options: RenderMonthOptions = {},\n): string {\n const widthOf = (line: string): number => displayWidth(stripAnsi(line));\n\n const months = Array.from({ length: 12 }, (_, i) =>\n renderMonth(year, i + 1, options).split(\"\\n\"),\n );\n const maxLines = Math.max(...months.map((lines) => lines.length));\n const colWidths = months.map((lines) => Math.max(...lines.map(widthOf)));\n\n /** 月の各行をその列幅まで右パディングする(行が足りなければ空行として埋める) */\n const padMonth = (monthIdx: number): string[] =>\n Array.from({ length: maxLines }, (_, li) => {\n const line = months[monthIdx]![li] ?? \"\";\n return (\n line + \" \".repeat(Math.max(0, colWidths[monthIdx]! - widthOf(line)))\n );\n });\n\n const padded = months.map((_, mi) => padMonth(mi));\n\n const rows: string[] = [];\n for (let row = 0; row < 3; row++) {\n rows.push(\n Array.from({ length: maxLines }, (_, li) =>\n Array.from({ length: 4 }, (_, col) => {\n const monthIdx = row * 4 + col;\n return monthIdx < 12 ? padded[monthIdx]![li]! : \"\";\n }).join(\" \"),\n ).join(\"\\n\"),\n );\n }\n\n return rows.join(\"\\n\\n\");\n}\n","import { getMonthRange } from \"@typescript-calendar-lib/core\";\nimport { renderMonth, renderYear } from \"./render.ts\";\nimport type {\n CalendarOptions,\n CalendarRangeOptions,\n CalendarYearOptions,\n} from \"./types.ts\";\n\n/**\n * 月カレンダーをテキストで返す\n */\nexport function calendar(options: CalendarOptions): string {\n return renderMonth(options.year, options.month, options);\n}\n\n/**\n * 年間カレンダーを4列×3行でテキストで返す\n */\nexport function calendarYear(options: CalendarYearOptions): string {\n return renderYear(options.year, options);\n}\n\n/**\n * 任意の日付範囲のカレンダーをテキストで返す\n */\nexport function calendarRange(options: CalendarRangeOptions): string {\n const months = getMonthRange(options.from, options.to);\n return months\n .map(({ year, month }) => renderMonth(year, month, options))\n .join(\"\\n\\n\");\n}\n"],"mappings":"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"}
|