@typescript-calendar-lib/cli 0.5.1 → 0.5.3

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 CHANGED
@@ -64,6 +64,7 @@ All options from `@typescript-calendar-lib/core` are supported, plus these CLI-s
64
64
  | `today` | `Date` | `new Date()` | Reference date for "today" coloring |
65
65
  | `cellData` | `(date: Date) => unknown` | — | Resolve per-cell data; passed to `renderCell` |
66
66
  | `renderCell` | `(day, date, state, data?) => string` | — | Custom cell text; replaces the day cell verbatim |
67
+ | `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
68
 
68
69
  ## CLI Binary
69
70
 
@@ -276,6 +277,31 @@ calendar({
276
277
 
277
278
  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
279
 
280
+ ### Week numbers
281
+
282
+ `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:
283
+
284
+ ```ts
285
+ calendar({
286
+ year: 2026,
287
+ month: 9,
288
+ weekStart: "monday",
289
+ showWeekNumbers: true,
290
+ });
291
+ ```
292
+
293
+ ```
294
+ September 2026
295
+ Mon Tue Wed Thu Fri Sat Sun
296
+ 36 1 2 3 4 5 6
297
+ 37 7 8 9 10 11 12 13
298
+ 38 14 15 16 17 18 19 20
299
+ 39 21 22 23 24 25 26 27
300
+ 40 28 29 30
301
+ ```
302
+
303
+ 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.
304
+
279
305
  ### Plain text output
280
306
 
281
307
  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-BT_DowM9.js";
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 {
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-f8j9RTe9.js";
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
@@ -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 = 27) */
41
- function innerWidth(cellWidth, cols) {
42
- return cols * cellWidth + (cols - 1);
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
- return `${left}${Array(cols).fill(frame.h.repeat(cellWidth)).join(join)}${right}`;
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
- lines.push(weekdays.map((d) => colorize(padStartWidth(d, cellWidth), palette.weekday, color)).join(sep));
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
- lines.push(colorize(`${frame.v}${weekdays.map((d) => padStartWidth(d, cellWidth)).join(frame.v)}${frame.v}`, palette.weekday, color));
165
- lines.push(colorize(separatorRow(frame, cellWidth, cols), palette.frame, color));
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
- lines.push(frame === null ? cells : `${frame.v}${cells}${frame.v}`);
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-f8j9RTe9.js.map
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-BT_DowM9.js";
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-f8j9RTe9.js";
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-BT_DowM9.d.ts.map
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.1",
3
+ "version": "0.5.3",
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.1",
34
- "@typescript-calendar-lib/tui": "0.5.1"
33
+ "@typescript-calendar-lib/core": "^0.5.3",
34
+ "@typescript-calendar-lib/tui": "^0.5.3"
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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"}