@typescript-calendar-lib/cli 0.4.2 → 0.5.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/README.md +23 -0
- package/dist/bin.d.ts +1 -1
- package/dist/bin.js +1 -1
- package/dist/{calendar-DNDADt5T.js → calendar-f8j9RTe9.js} +14 -31
- package/dist/calendar-f8j9RTe9.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +1 -1
- package/dist/{theme-BMYtCxK2.d.ts → theme-BT_DowM9.d.ts} +4 -29
- package/package.json +13 -4
- package/dist/calendar-DNDADt5T.js.map +0 -1
package/README.md
CHANGED
|
@@ -62,6 +62,8 @@ 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
|
+
| `cellData` | `(date: Date) => unknown` | — | Resolve per-cell data; passed to `renderCell` |
|
|
66
|
+
| `renderCell` | `(day, date, state, data?) => string` | — | Custom cell text; replaces the day cell verbatim |
|
|
65
67
|
|
|
66
68
|
## CLI Binary
|
|
67
69
|
|
|
@@ -253,6 +255,27 @@ calendar({
|
|
|
253
255
|
|
|
254
256
|
When a date is both highlighted and in range, the highlight takes precedence.
|
|
255
257
|
|
|
258
|
+
### Per-cell data & custom cells
|
|
259
|
+
|
|
260
|
+
`cellData` attaches your own data to dates; `renderCell` replaces the day-cell rendering. `cellData` is called once per real cell, and returning `undefined` means "no data":
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
calendar({
|
|
264
|
+
year: 2026,
|
|
265
|
+
month: 9,
|
|
266
|
+
cellData: (date) => (date.getDate() === 15 ? "★" : undefined),
|
|
267
|
+
renderCell: (day, _date, _state, data) =>
|
|
268
|
+
data !== undefined ? `[${day}]` : String(day),
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`renderCell` receives `(day, date, state, data)`:
|
|
273
|
+
|
|
274
|
+
- `state` — `getCalendarCellState(date)` result (`isWeekend`, `isToday`, `isHighlight`, `isInRange`, `dayOfWeek`)
|
|
275
|
+
- `data` — the resolved `cellData` value for that date (`undefined` when none)
|
|
276
|
+
|
|
277
|
+
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
|
+
|
|
256
279
|
### Plain text output
|
|
257
280
|
|
|
258
281
|
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-BT_DowM9.js";
|
|
2
2
|
import { HighlightStyle, Locale, WeekStart } from "@typescript-calendar-lib/core";
|
|
3
3
|
//#region src/bin.d.ts
|
|
4
4
|
export interface CliArgs {
|
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-f8j9RTe9.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
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { buildMonthGrid, createDate, getMonthName, getMonthRange, getWeekdayHeaders
|
|
1
|
+
import { buildMonthGrid, createDate, getCalendarCellState, getMonthName, getMonthRange, getWeekdayHeaders } from "@typescript-calendar-lib/core";
|
|
2
|
+
import { THEMES, resolveTheme } from "@typescript-calendar-lib/tui";
|
|
2
3
|
//#region src/align.ts
|
|
3
4
|
/** 東アジアの全角文字(ターミナル表示幅2列) */
|
|
4
5
|
const WIDE = /[\u1100-\u115f\u2e80-\u303e\u3041-\u33ff\u3400-\u4dbf\u4e00-\u9fff\ua000-\ua4cf\ua960-\ua97f\uac00-\ud7a3\uf900-\ufaff\ufe30-\ufe4f\uff00-\uff60\uffe0-\uffe6]/;
|
|
@@ -58,30 +59,6 @@ function separatorRow(frame, cellWidth, cols) {
|
|
|
58
59
|
}
|
|
59
60
|
//#endregion
|
|
60
61
|
//#region src/theme.ts
|
|
61
|
-
const THEMES = {
|
|
62
|
-
default: {
|
|
63
|
-
cellWidth: 3,
|
|
64
|
-
separator: " ",
|
|
65
|
-
frame: null
|
|
66
|
-
},
|
|
67
|
-
modern: {
|
|
68
|
-
cellWidth: 3,
|
|
69
|
-
separator: "│",
|
|
70
|
-
frame: {
|
|
71
|
-
topLeft: "┌",
|
|
72
|
-
topRight: "┐",
|
|
73
|
-
bottomLeft: "└",
|
|
74
|
-
bottomRight: "┘",
|
|
75
|
-
h: "─",
|
|
76
|
-
v: "│",
|
|
77
|
-
j: "┬",
|
|
78
|
-
footJ: "┴"
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
function resolveTheme(theme) {
|
|
83
|
-
return typeof theme === "string" ? THEMES[theme] ?? THEMES.default : theme ?? THEMES.default;
|
|
84
|
-
}
|
|
85
62
|
const COLOR_SCHEMES = {
|
|
86
63
|
/** 従来どおり。着色は range(黄) と highlight(反転) のみ */
|
|
87
64
|
default: {
|
|
@@ -142,7 +119,7 @@ function resolveColorScheme(scheme) {
|
|
|
142
119
|
* 1ヶ月分のカレンダーテキストを描画する
|
|
143
120
|
*/
|
|
144
121
|
function renderMonth(year, month, options = {}) {
|
|
145
|
-
const { locale = "en", weekStart = "sunday", highlight, highlightStyle = "bracket", range, color = false, theme: themeOption = "default", colorScheme: schemeOption = "default", today = /* @__PURE__ */ new Date() } = 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;
|
|
146
123
|
const theme = resolveTheme(themeOption);
|
|
147
124
|
const palette = resolveColorScheme(schemeOption);
|
|
148
125
|
const frame = theme.frame;
|
|
@@ -156,15 +133,21 @@ function renderMonth(year, month, options = {}) {
|
|
|
156
133
|
const renderCell = (day) => {
|
|
157
134
|
if (day === null) return " ".repeat(cellWidth);
|
|
158
135
|
const date = createDate(year, month - 1, day);
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
136
|
+
const state = getCalendarCellState(date, {
|
|
137
|
+
today,
|
|
138
|
+
highlight,
|
|
139
|
+
range,
|
|
140
|
+
isDateDisabled
|
|
141
|
+
});
|
|
142
|
+
const data = cellData?.(date);
|
|
143
|
+
if (customRenderCell !== void 0) return customRenderCell(day, date, state, data);
|
|
144
|
+
const { isHighlight, isInRange, isToday, isDisabled, isWeekend } = state;
|
|
163
145
|
const text = (isHighlight && highlightStyle === "bracket" ? `[${day}]` : String(day)).padStart(cellWidth);
|
|
164
146
|
let code;
|
|
165
147
|
if (isHighlight && highlightStyle === "reverse") code = palette.highlight ?? 7;
|
|
166
148
|
else if (isInRange && !isHighlight) code = palette.range ?? 33;
|
|
167
149
|
else if (isToday && palette.today !== void 0) code = palette.today;
|
|
150
|
+
else if (isDisabled) code = palette.dim ?? 90;
|
|
168
151
|
else if (isWeekend && palette.weekend !== void 0) code = palette.weekend;
|
|
169
152
|
else if (palette.day !== void 0) code = palette.day;
|
|
170
153
|
return colorize(text, code, color);
|
|
@@ -238,4 +221,4 @@ function calendarRange(options) {
|
|
|
238
221
|
//#endregion
|
|
239
222
|
export { THEMES as a, COLOR_SCHEMES as i, calendarRange as n, resolveColorScheme as o, calendarYear as r, resolveTheme as s, calendar as t };
|
|
240
223
|
|
|
241
|
-
//# sourceMappingURL=calendar-
|
|
224
|
+
//# sourceMappingURL=calendar-f8j9RTe9.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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-
|
|
2
|
-
import { CalendarOptions as CalendarOptions$1, CalendarRangeOptions as CalendarRangeOptions$1, CalendarYearOptions as CalendarYearOptions$1, RenderMonthOptions as RenderMonthOptions$1 } from "@typescript-calendar-lib/core";
|
|
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-BT_DowM9.js";
|
|
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 のオプションに追加で受け付ける) */
|
|
5
5
|
interface CliExtraOptions {
|
|
@@ -9,6 +9,12 @@ interface CliExtraOptions {
|
|
|
9
9
|
colorScheme?: ColorSchemeName | CliPalette;
|
|
10
10
|
/** 今日の基準日。カラースキームの today 着色に使用 */
|
|
11
11
|
today?: Date;
|
|
12
|
+
/** 選択不可な日付を判定する述語。true を返した日付は dim 色で描画される */
|
|
13
|
+
isDateDisabled?: (date: Date) => boolean;
|
|
14
|
+
/** 各セルに付与するユーザー定義データを解決する関数。実セルのみに呼ばれる */
|
|
15
|
+
cellData?: (date: Date) => unknown;
|
|
16
|
+
/** セル内容のカスタム描画。受け取った文字列がそのままセルに使われる(幅・ANSI は呼び出し側で調整) */
|
|
17
|
+
renderCell?: (day: number, date: Date, state: CalendarCellState, data?: unknown) => string;
|
|
12
18
|
}
|
|
13
19
|
type CalendarOptions = CalendarOptions$1 & CliExtraOptions;
|
|
14
20
|
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-f8j9RTe9.js";
|
|
2
2
|
export { COLOR_SCHEMES, THEMES, calendar, calendarRange, calendarYear, resolveColorScheme, resolveTheme };
|
|
@@ -1,32 +1,7 @@
|
|
|
1
|
+
import { FrameChars, THEMES, Theme, ThemeName, resolveTheme } from "@typescript-calendar-lib/tui";
|
|
1
2
|
//#region src/theme.d.ts
|
|
2
|
-
/**
|
|
3
|
-
type
|
|
4
|
-
/** 枠線の文字セット(modern テーマで使用) */
|
|
5
|
-
interface FrameChars {
|
|
6
|
-
topLeft: string;
|
|
7
|
-
topRight: string;
|
|
8
|
-
bottomLeft: string;
|
|
9
|
-
bottomRight: string;
|
|
10
|
-
/** 水平線 */
|
|
11
|
-
h: string;
|
|
12
|
-
/** 垂直線 */
|
|
13
|
-
v: string;
|
|
14
|
-
/** ヘッダー/本文の区切り行で使う交差(┬ や ┼) */
|
|
15
|
-
j: string;
|
|
16
|
-
/** 下端区切りで使う交差(┴) */
|
|
17
|
-
footJ: string;
|
|
18
|
-
}
|
|
19
|
-
/** 文字ベースの見た目定義 */
|
|
20
|
-
interface CliTheme {
|
|
21
|
-
/** セル幅(日付表記の文字幅) */
|
|
22
|
-
cellWidth: number;
|
|
23
|
-
/** セル間の区切り文字(default: " " / modern: "│") */
|
|
24
|
-
separator: string;
|
|
25
|
-
/** 枠線文字。null なら枠なし */
|
|
26
|
-
frame: FrameChars | null;
|
|
27
|
-
}
|
|
28
|
-
declare const THEMES: Record<ThemeName, CliTheme>;
|
|
29
|
-
declare function resolveTheme(theme?: ThemeName | CliTheme): CliTheme;
|
|
3
|
+
/** 文字ベースの見た目定義。tui の Theme と同一 */
|
|
4
|
+
type CliTheme = Theme;
|
|
30
5
|
/** 組み込みカラースキーム名。カスタムは CliPalette を直接渡せる */
|
|
31
6
|
type ColorSchemeName = "default" | "ocean" | "forest" | "sunset" | "mono";
|
|
32
7
|
/**
|
|
@@ -50,4 +25,4 @@ declare const COLOR_SCHEMES: Record<ColorSchemeName, CliPalette>;
|
|
|
50
25
|
declare function resolveColorScheme(scheme?: ColorSchemeName | CliPalette): CliPalette;
|
|
51
26
|
//#endregion
|
|
52
27
|
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 };
|
|
53
|
-
//# sourceMappingURL=theme-
|
|
28
|
+
//# sourceMappingURL=theme-BT_DowM9.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,28 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typescript-calendar-lib/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
|
+
"description": "Terminal calendar renderer with themes and ANSI color schemes",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"bin": {
|
|
6
7
|
"typescript-calendar-lib": "./dist/bin.js"
|
|
7
8
|
},
|
|
8
9
|
"repository": {
|
|
9
10
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/nazozokc/typescript-calendar-lib"
|
|
11
|
+
"url": "https://github.com/nazozokc/typescript-calendar-lib",
|
|
12
|
+
"directory": "packages/cli"
|
|
11
13
|
},
|
|
12
14
|
"main": "./dist/index.js",
|
|
13
15
|
"types": "./dist/index.d.ts",
|
|
14
16
|
"exports": {
|
|
15
17
|
".": {
|
|
16
18
|
"types": "./dist/index.d.ts",
|
|
17
|
-
"development": "./src/index.ts",
|
|
18
19
|
"default": "./dist/index.js"
|
|
19
20
|
}
|
|
20
21
|
},
|
|
21
22
|
"files": [
|
|
22
23
|
"dist"
|
|
23
24
|
],
|
|
25
|
+
"keywords": [
|
|
26
|
+
"calendar",
|
|
27
|
+
"cli",
|
|
28
|
+
"terminal",
|
|
29
|
+
"ansi"
|
|
30
|
+
],
|
|
31
|
+
"license": "MIT",
|
|
24
32
|
"dependencies": {
|
|
25
|
-
"@typescript-calendar-lib/core": "0.
|
|
33
|
+
"@typescript-calendar-lib/core": "0.5.1",
|
|
34
|
+
"@typescript-calendar-lib/tui": "0.5.1"
|
|
26
35
|
},
|
|
27
36
|
"scripts": {
|
|
28
37
|
"build": "tsdown"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"calendar-DNDADt5T.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\n/** 組み込みテーマ名。カスタムテーマは CliTheme オブジェクトを直接渡せる */\nexport type ThemeName = \"default\" | \"modern\";\n\n/** 枠線の文字セット(modern テーマで使用) */\nexport interface FrameChars {\n topLeft: string;\n topRight: string;\n bottomLeft: string;\n bottomRight: string;\n /** 水平線 */\n h: string;\n /** 垂直線 */\n v: string;\n /** ヘッダー/本文の区切り行で使う交差(┬ や ┼) */\n j: string;\n /** 下端区切りで使う交差(┴) */\n footJ: string;\n}\n\n/** 文字ベースの見た目定義 */\nexport interface CliTheme {\n /** セル幅(日付表記の文字幅) */\n cellWidth: number;\n /** セル間の区切り文字(default: \" \" / modern: \"│\") */\n separator: string;\n /** 枠線文字。null なら枠なし */\n frame: FrameChars | null;\n}\n\nexport const THEMES: Record<ThemeName, CliTheme> = {\n default: {\n cellWidth: 3,\n separator: \" \",\n frame: null,\n },\n modern: {\n cellWidth: 3,\n separator: \"│\",\n frame: {\n topLeft: \"┌\",\n topRight: \"┐\",\n bottomLeft: \"└\",\n bottomRight: \"┘\",\n h: \"─\",\n v: \"│\",\n j: \"┬\",\n footJ: \"┴\",\n },\n },\n};\n\nexport function resolveTheme(theme?: ThemeName | CliTheme): CliTheme {\n return typeof theme === \"string\"\n ? (THEMES[theme] ?? THEMES.default)\n : (theme ?? THEMES.default);\n}\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 getMonthName,\n getWeekdayHeaders,\n isDateInRange,\n isSameDay,\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 } = 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 isHighlight = highlight !== undefined && isSameDay(date, highlight);\n const isInRange = isDateInRange(date, range);\n const isToday = isSameDay(date, today);\n const isWeekend = date.getDay() === 0 || date.getDay() === 6;\n\n const text = (\n isHighlight && highlightStyle === \"bracket\" ? `[${day}]` : String(day)\n ).padStart(cellWidth);\n\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 (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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"}
|