md2cv 1.0.0
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/CHANGELOG.md +19 -0
- package/LICENSE +674 -0
- package/README.md +219 -0
- package/dist/bin.d.ts +6 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +10 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli/index.d.ts +50 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +278 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/generator/index.d.ts +36 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +302 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/resume_en.d.ts +22 -0
- package/dist/generator/resume_en.d.ts.map +1 -0
- package/dist/generator/resume_en.js +524 -0
- package/dist/generator/resume_en.js.map +1 -0
- package/dist/generator/resume_ja.d.ts +22 -0
- package/dist/generator/resume_ja.d.ts.map +1 -0
- package/dist/generator/resume_ja.js +440 -0
- package/dist/generator/resume_ja.js.map +1 -0
- package/dist/generator/rirekisho/components.d.ts +83 -0
- package/dist/generator/rirekisho/components.d.ts.map +1 -0
- package/dist/generator/rirekisho/components.js +405 -0
- package/dist/generator/rirekisho/components.js.map +1 -0
- package/dist/generator/rirekisho/data.d.ts +18 -0
- package/dist/generator/rirekisho/data.d.ts.map +1 -0
- package/dist/generator/rirekisho/data.js +274 -0
- package/dist/generator/rirekisho/data.js.map +1 -0
- package/dist/generator/rirekisho/index.d.ts +20 -0
- package/dist/generator/rirekisho/index.d.ts.map +1 -0
- package/dist/generator/rirekisho/index.js +67 -0
- package/dist/generator/rirekisho/index.js.map +1 -0
- package/dist/generator/rirekisho/layout.d.ts +20 -0
- package/dist/generator/rirekisho/layout.d.ts.map +1 -0
- package/dist/generator/rirekisho/layout.js +354 -0
- package/dist/generator/rirekisho/layout.js.map +1 -0
- package/dist/generator/rirekisho/styles.d.ts +9 -0
- package/dist/generator/rirekisho/styles.d.ts.map +1 -0
- package/dist/generator/rirekisho/styles.js +362 -0
- package/dist/generator/rirekisho/styles.js.map +1 -0
- package/dist/generator/rirekisho/types.d.ts +163 -0
- package/dist/generator/rirekisho/types.d.ts.map +1 -0
- package/dist/generator/rirekisho/types.js +80 -0
- package/dist/generator/rirekisho/types.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/index.d.ts +21 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +639 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/types/config.d.ts +64 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +5 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/errors.d.ts +78 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +146 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/metadata.d.ts +55 -0
- package/dist/types/metadata.d.ts.map +1 -0
- package/dist/types/metadata.js +136 -0
- package/dist/types/metadata.js.map +1 -0
- package/dist/types/result.d.ts +50 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +74 -0
- package/dist/types/result.js.map +1 -0
- package/dist/types/sections.d.ts +168 -0
- package/dist/types/sections.d.ts.map +1 -0
- package/dist/types/sections.js +122 -0
- package/dist/types/sections.js.map +1 -0
- package/dist/validator/index.d.ts +20 -0
- package/dist/validator/index.d.ts.map +1 -0
- package/dist/validator/index.js +67 -0
- package/dist/validator/index.js.map +1 -0
- package/examples/example-cv-en.md +77 -0
- package/examples/example-cv-ja.md +116 -0
- package/examples/sample-photo.png +0 -0
- package/package.json +93 -0
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# md2cv
|
|
2
|
+
|
|
3
|
+
md2cv is a command-line tool that transforms Markdown documents into formatted PDF and HTML resumes. Simply write your CV in Markdown, and let md2cv handle the formatting and layout. The tool supports both western-style CVs and Japanese-style documents including rirekisho (履歴書) and shokumu-keirekisho (職務経歴書), making it ideal for international job seekers.
|
|
4
|
+
|
|
5
|
+
## Key Features
|
|
6
|
+
|
|
7
|
+
- Write your CV in Markdown
|
|
8
|
+
- Generate PDF and HTML outputs
|
|
9
|
+
- Multiple format support: western-style CV and Japanese rirekisho (履歴書)
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Install md2cv globally to use it from anywhere:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g md2cv
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or run it directly without installation using npx:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx md2cv -i your-cv.md
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
Here are some common examples to get you started:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Basic usage - generate PDF CV
|
|
31
|
+
md2cv -i examples/example-cv-en.md
|
|
32
|
+
|
|
33
|
+
# Specify output path
|
|
34
|
+
md2cv -i examples/example-cv-en.md -o ./output/my-cv
|
|
35
|
+
|
|
36
|
+
# Generate HTML instead of PDF
|
|
37
|
+
md2cv -i examples/example-cv-en.md -t html
|
|
38
|
+
|
|
39
|
+
# Generate both PDF and HTML
|
|
40
|
+
md2cv -i examples/example-cv-en.md -t both
|
|
41
|
+
|
|
42
|
+
# Generate Japanese rirekisho format (A3 paper)
|
|
43
|
+
md2cv -i examples/example-cv-ja.md -f rirekisho -p a3
|
|
44
|
+
|
|
45
|
+
# Generate both CV and rirekisho formats
|
|
46
|
+
md2cv -i examples/example-cv-ja.md -f both -p a3
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## CLI Options
|
|
50
|
+
|
|
51
|
+
The following options are available to customize the output:
|
|
52
|
+
|
|
53
|
+
| Option | Description | Default |
|
|
54
|
+
| -------------------------- | -------------------------------------------- | --------------- |
|
|
55
|
+
| `-i, --input <file>` | Input markdown file (required) | - |
|
|
56
|
+
| `-o, --output <path>` | Output file path (without extension) | Input directory |
|
|
57
|
+
| `-f, --format <format>` | Output format: `cv`, `rirekisho`, `both` | `cv` |
|
|
58
|
+
| `-t, --output-type <type>` | Output type: `pdf`, `html`, `both` | `pdf` |
|
|
59
|
+
| `-p, --paper-size <size>` | Paper size: `a3`, `a4`, `b4`, `b5`, `letter` | `a4` |
|
|
60
|
+
| `-c, --config <file>` | Configuration file (JSON or YAML) | - |
|
|
61
|
+
| `--log-format <format>` | Log format: `json`, `text` | `text` |
|
|
62
|
+
| `--debug` | Enable debug logging | `false` |
|
|
63
|
+
| `--version` | Show version | - |
|
|
64
|
+
| `--help` | Show help | - |
|
|
65
|
+
|
|
66
|
+
## Markdown Format
|
|
67
|
+
|
|
68
|
+
### Frontmatter and Environment Variables
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
---
|
|
72
|
+
name: John Doe
|
|
73
|
+
email_address: john@example.com
|
|
74
|
+
phone_number: +1-234-567-8900
|
|
75
|
+
home_address: San Francisco, CA
|
|
76
|
+
---
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Frontmatter fields can also be set via environment variables. This is useful for keeping personal information out of version control.
|
|
80
|
+
|
|
81
|
+
| Field | Environment Variable(s) | Required |
|
|
82
|
+
| ------------------------ | -------------------------------------------------- | -------- |
|
|
83
|
+
| `name` | `NAME` | Yes |
|
|
84
|
+
| `name_ja` | `NAME_JA` | No |
|
|
85
|
+
| `name_furigana` | `NAME_FURIGANA`, `NAME_HURIGANA` | No |
|
|
86
|
+
| `email_address` | `EMAIL_ADDRESS`, `EMAIL_ADDRESS1` | Yes |
|
|
87
|
+
| `email_address2` | `EMAIL_ADDRESS2` | No |
|
|
88
|
+
| `phone_number` | `PHONE_NUMBER`, `PHONE_NUMBER1` | Yes |
|
|
89
|
+
| `phone_number2` | `PHONE_NUMBER2` | No |
|
|
90
|
+
| `post_code` | `POST_CODE`, `POST_CODE1` | No |
|
|
91
|
+
| `home_address` | `HOME_ADDRESS`, `HOME_ADDRESS1` | No |
|
|
92
|
+
| `home_address_furigana` | `HOME_ADDRESS_FURIGANA`, `HOME_ADDRESS_HURIGANA` | No |
|
|
93
|
+
| `post_code2` | `POST_CODE2` | No |
|
|
94
|
+
| `home_address2` | `HOME_ADDRESS2` | No |
|
|
95
|
+
| `home_address2_furigana` | `HOME_ADDRESS2_FURIGANA`, `HOME_ADDRESS2_HURIGANA` | No |
|
|
96
|
+
| `gender` | `GENDER` | No |
|
|
97
|
+
| `dob` | `DOB`, `DATE_OF_BIRTH` | No |
|
|
98
|
+
|
|
99
|
+
Priority: Frontmatter values override environment variables.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Example: Set personal info via environment
|
|
103
|
+
export NAME="John Doe"
|
|
104
|
+
export EMAIL_ADDRESS="john@example.com"
|
|
105
|
+
export PHONE_NUMBER="+1-234-567-8900"
|
|
106
|
+
|
|
107
|
+
md2cv -i cv.md
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Sections
|
|
111
|
+
|
|
112
|
+
Use standard markdown headings for sections:
|
|
113
|
+
|
|
114
|
+
```markdown
|
|
115
|
+
# Summary
|
|
116
|
+
|
|
117
|
+
Experienced software engineer with 10+ years...
|
|
118
|
+
|
|
119
|
+
# Experience
|
|
120
|
+
|
|
121
|
+
## Senior Software Engineer | TechCorp
|
|
122
|
+
|
|
123
|
+
**2020 - Present** | San Francisco, CA
|
|
124
|
+
|
|
125
|
+
- Led development of microservices architecture
|
|
126
|
+
- Mentored junior developers
|
|
127
|
+
|
|
128
|
+
# Education
|
|
129
|
+
|
|
130
|
+
## Bachelor of Science in Computer Science
|
|
131
|
+
|
|
132
|
+
**University of California** | 2010 - 2014
|
|
133
|
+
|
|
134
|
+
# Skills
|
|
135
|
+
|
|
136
|
+
- Programming: TypeScript, Python, Go
|
|
137
|
+
- Frameworks: React, Node.js, Django
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Structured Blocks
|
|
141
|
+
|
|
142
|
+
For more control, use structured code blocks:
|
|
143
|
+
|
|
144
|
+
````markdown
|
|
145
|
+
```resume:experience
|
|
146
|
+
- company: TechCorp
|
|
147
|
+
roles:
|
|
148
|
+
- title: Senior Software Engineer
|
|
149
|
+
start: 2020-01
|
|
150
|
+
end: present
|
|
151
|
+
highlights:
|
|
152
|
+
- Led development of microservices architecture
|
|
153
|
+
- Mentored junior developers
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```resume:education
|
|
157
|
+
- school: University of California
|
|
158
|
+
degree: Bachelor of Science in Computer Science
|
|
159
|
+
start: 2010-09
|
|
160
|
+
end: 2014-06
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```resume:skills
|
|
164
|
+
- category: Programming
|
|
165
|
+
items: [TypeScript, Python, Go]
|
|
166
|
+
- category: Frameworks
|
|
167
|
+
items: [React, Node.js, Django]
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```resume:certifications
|
|
171
|
+
- name: AWS Solutions Architect
|
|
172
|
+
issuer: Amazon Web Services
|
|
173
|
+
date: 2023-01
|
|
174
|
+
```
|
|
175
|
+
````
|
|
176
|
+
|
|
177
|
+
## Configuration File
|
|
178
|
+
|
|
179
|
+
Configuration files are completely optional. All parameters can be specified via CLI arguments. However, you can use a JSON or YAML config file for convenience when you want to reuse the same settings across multiple runs.
|
|
180
|
+
|
|
181
|
+
Create a `config.json` or `config.yaml`:
|
|
182
|
+
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"format": "both",
|
|
186
|
+
"outputType": "pdf",
|
|
187
|
+
"paperSize": "a4",
|
|
188
|
+
"logFormat": "text"
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
```yaml
|
|
193
|
+
format: both
|
|
194
|
+
outputType: pdf
|
|
195
|
+
paperSize: a4
|
|
196
|
+
logFormat: text
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Programmatic Usage
|
|
200
|
+
|
|
201
|
+
If you want to use md2cv as a library in your own project, refer to the following code snippet:
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
import { parseMarkdown, generateOutput, validateCV } from 'md2cv';
|
|
205
|
+
|
|
206
|
+
const markdown = fs.readFileSync('cv.md', 'utf-8');
|
|
207
|
+
const result = parseMarkdown(markdown);
|
|
208
|
+
|
|
209
|
+
if (result.ok) {
|
|
210
|
+
const validated = validateCV(result.value, 'cv');
|
|
211
|
+
if (validated.ok) {
|
|
212
|
+
await generateOutput(validated.value, config);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
GPL-3.0
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;GAEG"}
|
package/dist/bin.js
ADDED
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Interface module
|
|
3
|
+
* Command-line argument parsing and execution
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import type { CLIOptions, ConfigFile, LogFormat, ResolvedConfig } from '../types/config.js';
|
|
7
|
+
/**
|
|
8
|
+
* Logger interface (compatible with pino)
|
|
9
|
+
*/
|
|
10
|
+
export interface Logger {
|
|
11
|
+
info(msg: string): void;
|
|
12
|
+
info(obj: object, msg?: string): void;
|
|
13
|
+
debug(msg: string): void;
|
|
14
|
+
debug(obj: object, msg?: string): void;
|
|
15
|
+
warn(msg: string): void;
|
|
16
|
+
warn(obj: object, msg?: string): void;
|
|
17
|
+
error(msg: string): void;
|
|
18
|
+
error(obj: object, msg?: string): void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Create pino logger instance
|
|
22
|
+
*/
|
|
23
|
+
export declare function createLogger(debug: boolean, logFormat?: LogFormat): Logger;
|
|
24
|
+
/**
|
|
25
|
+
* Load configuration file (JSON or YAML)
|
|
26
|
+
*/
|
|
27
|
+
export declare function loadConfigFile(configPath: string): ConfigFile;
|
|
28
|
+
/**
|
|
29
|
+
* Load .env file from input directory and log loaded variables
|
|
30
|
+
*/
|
|
31
|
+
export declare function loadEnvFile(inputPath: string, logger: Logger, verbose: boolean): void;
|
|
32
|
+
/**
|
|
33
|
+
* Resolve configuration from CLI options and config file
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveConfig(cliOptions: CLIOptions): ResolvedConfig;
|
|
36
|
+
/**
|
|
37
|
+
* Main CLI execution
|
|
38
|
+
*/
|
|
39
|
+
export declare function runCLI(options: CLIOptions): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Create CLI program
|
|
42
|
+
*/
|
|
43
|
+
export declare function createCLIProgram(): Command;
|
|
44
|
+
/**
|
|
45
|
+
* Main entry point
|
|
46
|
+
*/
|
|
47
|
+
export declare function main(): Promise<void>;
|
|
48
|
+
export { Command };
|
|
49
|
+
export type { CLIOptions };
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,OAAO,KAAK,EAER,UAAU,EACV,UAAU,EACV,SAAS,EAIT,cAAc,EACjB,MAAM,oBAAoB,CAAC;AAsC5B;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,GAAE,SAAkB,GAAG,MAAM,CA4BlF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAe7D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CA4CrF;AAuBD;;GAEG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,cAAc,CAmCpE;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAwC/D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CA4D1C;AAED;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAG1C;AAED,OAAO,EAAE,OAAO,EAAE,CAAC;AAEf,YAAY,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Interface module
|
|
3
|
+
* Command-line argument parsing and execution
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import { config as dotenvConfig } from 'dotenv';
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import pino from 'pino';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
import { parse as parseYaml } from 'yaml';
|
|
12
|
+
import { generateOutput } from '../generator/index.js';
|
|
13
|
+
import { parseMarkdown } from '../parser/index.js';
|
|
14
|
+
import { METADATA_FIELDS } from '../types/metadata.js';
|
|
15
|
+
import { validateCV } from '../validator/index.js';
|
|
16
|
+
// Read version from package.json
|
|
17
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
function findPackageJson() {
|
|
19
|
+
const candidates = [
|
|
20
|
+
path.resolve(__dirname, '../../../package.json'), // from dist/src/cli
|
|
21
|
+
path.resolve(__dirname, '../../package.json'), // from src/cli
|
|
22
|
+
];
|
|
23
|
+
for (const candidate of candidates) {
|
|
24
|
+
if (fs.existsSync(candidate)) {
|
|
25
|
+
return candidate;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
throw new Error('package.json not found');
|
|
29
|
+
}
|
|
30
|
+
const packageJsonPath = findPackageJson();
|
|
31
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
32
|
+
const VERSION = packageJson.version;
|
|
33
|
+
/**
|
|
34
|
+
* Log level names
|
|
35
|
+
*/
|
|
36
|
+
const LOG_LEVEL_NAMES = {
|
|
37
|
+
10: 'TRACE',
|
|
38
|
+
20: 'DEBUG',
|
|
39
|
+
30: 'INFO',
|
|
40
|
+
40: 'WARN',
|
|
41
|
+
50: 'ERROR',
|
|
42
|
+
60: 'FATAL',
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Create pino logger instance
|
|
46
|
+
*/
|
|
47
|
+
export function createLogger(debug, logFormat = 'text') {
|
|
48
|
+
const level = debug ? 'debug' : 'info';
|
|
49
|
+
if (logFormat === 'json') {
|
|
50
|
+
return pino({
|
|
51
|
+
level,
|
|
52
|
+
base: null,
|
|
53
|
+
timestamp: () => `,"timestamp":"${new Date().toISOString()}"`,
|
|
54
|
+
formatters: {
|
|
55
|
+
level(label, number) {
|
|
56
|
+
return { level: LOG_LEVEL_NAMES[number] ?? label.toUpperCase() };
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
// Text format using pino-pretty
|
|
62
|
+
return pino({
|
|
63
|
+
level,
|
|
64
|
+
transport: {
|
|
65
|
+
target: 'pino-pretty',
|
|
66
|
+
options: {
|
|
67
|
+
colorize: true,
|
|
68
|
+
translateTime: 'SYS:standard',
|
|
69
|
+
ignore: 'pid,hostname',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Load configuration file (JSON or YAML)
|
|
76
|
+
*/
|
|
77
|
+
export function loadConfigFile(configPath) {
|
|
78
|
+
if (!fs.existsSync(configPath)) {
|
|
79
|
+
throw new Error(`Configuration file not found: ${configPath}`);
|
|
80
|
+
}
|
|
81
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
82
|
+
const ext = path.extname(configPath).toLowerCase();
|
|
83
|
+
if (ext === '.json') {
|
|
84
|
+
return JSON.parse(content);
|
|
85
|
+
}
|
|
86
|
+
else if (ext === '.yaml' || ext === '.yml') {
|
|
87
|
+
return parseYaml(content);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
throw new Error(`Unsupported config file format: ${ext}. Use .json, .yaml, or .yml`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Load .env file from input directory and log loaded variables
|
|
95
|
+
*/
|
|
96
|
+
export function loadEnvFile(inputPath, logger, verbose) {
|
|
97
|
+
const inputDir = path.dirname(path.resolve(inputPath));
|
|
98
|
+
const envPath = path.join(inputDir, '.env');
|
|
99
|
+
if (!fs.existsSync(envPath)) {
|
|
100
|
+
logger.debug({ path: envPath }, 'No .env file found');
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
// Load .env file (suppress dotenv's own logging)
|
|
104
|
+
process.env.DOTENV_CONFIG_QUIET = 'true';
|
|
105
|
+
const result = dotenvConfig({ path: envPath });
|
|
106
|
+
if (result.error) {
|
|
107
|
+
logger.warn({ error: result.error.message }, 'Failed to load .env file');
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
logger.info({ path: envPath }, 'Loaded .env file');
|
|
111
|
+
// Collect all possible env var names from METADATA_FIELDS
|
|
112
|
+
const allEnvVars = new Set();
|
|
113
|
+
for (const def of Object.values(METADATA_FIELDS)) {
|
|
114
|
+
for (const envVar of def.envVars) {
|
|
115
|
+
allEnvVars.add(envVar);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Log loaded environment variables
|
|
119
|
+
const loadedVars = {};
|
|
120
|
+
for (const envVar of allEnvVars) {
|
|
121
|
+
const value = process.env[envVar];
|
|
122
|
+
if (value !== undefined) {
|
|
123
|
+
loadedVars[envVar] = verbose ? value : '***';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (Object.keys(loadedVars).length > 0) {
|
|
127
|
+
if (verbose) {
|
|
128
|
+
logger.debug({ variables: loadedVars }, 'Environment variables loaded from .env');
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
logger.info({ variables: Object.keys(loadedVars) }, 'Environment variables loaded from .env');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Supported photo image extensions
|
|
137
|
+
*/
|
|
138
|
+
const SUPPORTED_PHOTO_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.tiff', '.tif'];
|
|
139
|
+
/**
|
|
140
|
+
* Validate photo file path
|
|
141
|
+
*/
|
|
142
|
+
function validatePhotoPath(photoPath) {
|
|
143
|
+
if (!fs.existsSync(photoPath)) {
|
|
144
|
+
throw new Error(`Photo file not found: ${photoPath}`);
|
|
145
|
+
}
|
|
146
|
+
const ext = path.extname(photoPath).toLowerCase();
|
|
147
|
+
if (!SUPPORTED_PHOTO_EXTENSIONS.includes(ext)) {
|
|
148
|
+
throw new Error(`Unsupported photo format: ${ext}. Supported formats: ${SUPPORTED_PHOTO_EXTENSIONS.join(', ')}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Resolve configuration from CLI options and config file
|
|
153
|
+
*/
|
|
154
|
+
export function resolveConfig(cliOptions) {
|
|
155
|
+
let configFile = {};
|
|
156
|
+
if (cliOptions.config) {
|
|
157
|
+
configFile = loadConfigFile(cliOptions.config);
|
|
158
|
+
}
|
|
159
|
+
// Determine output path
|
|
160
|
+
const inputDir = path.dirname(cliOptions.input);
|
|
161
|
+
const inputBasename = path.basename(cliOptions.input, path.extname(cliOptions.input));
|
|
162
|
+
const defaultOutput = path.join(inputDir, inputBasename);
|
|
163
|
+
// Resolve photo path (CLI takes precedence over config file)
|
|
164
|
+
const photoPath = cliOptions.photo ?? configFile.photo;
|
|
165
|
+
// Validate photo path if provided
|
|
166
|
+
if (photoPath) {
|
|
167
|
+
validatePhotoPath(photoPath);
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
input: cliOptions.input,
|
|
171
|
+
output: cliOptions.output ?? configFile.output ?? defaultOutput,
|
|
172
|
+
format: cliOptions.format ?? configFile.format ?? 'cv',
|
|
173
|
+
outputType: cliOptions.outputType ?? configFile.outputType ?? 'pdf',
|
|
174
|
+
paperSize: cliOptions.paperSize ?? configFile.paperSize ?? 'a4',
|
|
175
|
+
debug: cliOptions.debug,
|
|
176
|
+
logFormat: cliOptions.logFormat ?? configFile.logFormat ?? 'text',
|
|
177
|
+
chronologicalOrder: cliOptions.chronologicalOrder ?? configFile.chronologicalOrder,
|
|
178
|
+
hideMotivation: cliOptions.hideMotivation || configFile.hideMotivation || false,
|
|
179
|
+
photo: photoPath,
|
|
180
|
+
sectionOrder: cliOptions.sectionOrder
|
|
181
|
+
? cliOptions.sectionOrder.split(',').map(s => s.trim())
|
|
182
|
+
: configFile.sectionOrder,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Main CLI execution
|
|
187
|
+
*/
|
|
188
|
+
export async function runCLI(options) {
|
|
189
|
+
const config = resolveConfig(options);
|
|
190
|
+
const logger = createLogger(config.debug, config.logFormat);
|
|
191
|
+
// Load .env file from input directory (before parsing markdown)
|
|
192
|
+
loadEnvFile(config.input, logger, config.debug);
|
|
193
|
+
logger.debug({ config }, 'Resolved configuration');
|
|
194
|
+
// Read input file
|
|
195
|
+
if (!fs.existsSync(config.input)) {
|
|
196
|
+
throw new Error(`Input file not found: ${config.input}`);
|
|
197
|
+
}
|
|
198
|
+
const markdown = fs.readFileSync(config.input, 'utf-8');
|
|
199
|
+
logger.debug({ file: config.input }, 'Input file read successfully');
|
|
200
|
+
// Parse markdown
|
|
201
|
+
const parseResult = parseMarkdown(markdown);
|
|
202
|
+
if (!parseResult.ok) {
|
|
203
|
+
for (const error of parseResult.error) {
|
|
204
|
+
logger.error({ error }, error.message);
|
|
205
|
+
}
|
|
206
|
+
throw new Error('Failed to parse markdown');
|
|
207
|
+
}
|
|
208
|
+
logger.debug('Markdown parsed successfully');
|
|
209
|
+
// Validate
|
|
210
|
+
const validationResult = validateCV(parseResult.value, config.format, logger);
|
|
211
|
+
if (!validationResult.ok) {
|
|
212
|
+
for (const error of validationResult.error) {
|
|
213
|
+
logger.error({ error }, error.message);
|
|
214
|
+
}
|
|
215
|
+
throw new Error('Validation failed');
|
|
216
|
+
}
|
|
217
|
+
logger.debug('Validation passed');
|
|
218
|
+
// Generate output
|
|
219
|
+
const generatedFiles = await generateOutput(validationResult.value, config, logger);
|
|
220
|
+
logger.info({ files: generatedFiles, count: generatedFiles.length }, 'Generation complete');
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Create CLI program
|
|
224
|
+
*/
|
|
225
|
+
export function createCLIProgram() {
|
|
226
|
+
const program = new Command();
|
|
227
|
+
program
|
|
228
|
+
.name('md2cv')
|
|
229
|
+
.description('CV/Resume Generator - transforms Markdown CVs into PDF and HTML')
|
|
230
|
+
.version(VERSION, '--version', 'Show version info')
|
|
231
|
+
.requiredOption('-i, --input <filepath>', 'Input markdown file path')
|
|
232
|
+
.option('-o, --output <filepath>', 'Output filepath (default: input directory)')
|
|
233
|
+
.option('-f, --format <format>', 'Output format (cv, rirekisho, or both)', 'cv')
|
|
234
|
+
.option('-t, --output-type <type>', 'Output type (html, pdf, or both)', 'pdf')
|
|
235
|
+
.option('-p, --paper-size <size>', 'Paper size (a3, a4, b4, b5, letter)')
|
|
236
|
+
.option('-c, --config <file>', 'Configuration file (JSON or YAML)')
|
|
237
|
+
.option('--order <order>', 'Chronological order for CV format only (asc: oldest first, desc: newest first). Default: desc. Rirekisho always uses oldest first.')
|
|
238
|
+
.option('--hide-motivation', 'Hide motivation section in rirekisho format (increases history/license rows)', false)
|
|
239
|
+
.option('--photo <filepath>', 'Photo image file for rirekisho format (png, jpg, tiff). Only used with rirekisho format.')
|
|
240
|
+
.option('--section-order <sections>', 'Comma-separated list of section IDs to include in CV output (e.g., "summary,experience,education,skills"). Sections not listed will be skipped. Only applies to CV format.')
|
|
241
|
+
.option('--log-format <format>', 'Log format (json or text)', 'text')
|
|
242
|
+
.option('--verbose', 'Enable verbose logging', false)
|
|
243
|
+
.action(async (opts) => {
|
|
244
|
+
try {
|
|
245
|
+
const cliOptions = {
|
|
246
|
+
input: String(opts.input),
|
|
247
|
+
output: typeof opts.output === 'string' ? opts.output : undefined,
|
|
248
|
+
format: opts.format ?? 'cv',
|
|
249
|
+
outputType: opts.outputType ?? 'pdf',
|
|
250
|
+
paperSize: typeof opts.paperSize === 'string' ? opts.paperSize : undefined,
|
|
251
|
+
config: typeof opts.config === 'string' ? opts.config : undefined,
|
|
252
|
+
debug: opts.verbose === true,
|
|
253
|
+
logFormat: opts.logFormat ?? 'text',
|
|
254
|
+
chronologicalOrder: typeof opts.order === 'string' ? opts.order : undefined,
|
|
255
|
+
hideMotivation: opts.hideMotivation === true,
|
|
256
|
+
photo: typeof opts.photo === 'string' ? opts.photo : undefined,
|
|
257
|
+
sectionOrder: typeof opts.sectionOrder === 'string' ? opts.sectionOrder : undefined,
|
|
258
|
+
};
|
|
259
|
+
await runCLI(cliOptions);
|
|
260
|
+
process.exit(0);
|
|
261
|
+
}
|
|
262
|
+
catch (e) {
|
|
263
|
+
const message = e instanceof Error ? e.message : 'Unknown error';
|
|
264
|
+
console.error(`Error: ${message}`);
|
|
265
|
+
process.exit(1);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
return program;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Main entry point
|
|
272
|
+
*/
|
|
273
|
+
export async function main() {
|
|
274
|
+
const program = createCLIProgram();
|
|
275
|
+
await program.parseAsync(process.argv);
|
|
276
|
+
}
|
|
277
|
+
export { Command };
|
|
278
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output Generator module
|
|
3
|
+
* Generates PDF and HTML outputs
|
|
4
|
+
*/
|
|
5
|
+
import type { Logger } from '../cli/index.js';
|
|
6
|
+
import type { PaperSize, ResolvedConfig } from '../types/config.js';
|
|
7
|
+
import type { CVMetadata } from '../types/metadata.js';
|
|
8
|
+
import type { ParsedSection } from '../types/sections.js';
|
|
9
|
+
import { generateCVEnHTML } from './resume_en.js';
|
|
10
|
+
import { generateCVJaHTML } from './resume_ja.js';
|
|
11
|
+
import { generateRirekishoHTML } from './rirekisho/index.js';
|
|
12
|
+
export { generateCVEnHTML, generateCVJaHTML, generateRirekishoHTML };
|
|
13
|
+
/**
|
|
14
|
+
* Input for CV generation (internal type)
|
|
15
|
+
*/
|
|
16
|
+
interface CVInput {
|
|
17
|
+
readonly metadata: CVMetadata;
|
|
18
|
+
readonly sections: readonly ParsedSection[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Page size dimensions in mm
|
|
22
|
+
*/
|
|
23
|
+
export declare const PAGE_SIZES: Record<PaperSize, {
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Escape HTML special characters
|
|
29
|
+
*/
|
|
30
|
+
export declare function escapeHtml(text: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Generate output files
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateOutput(cv: CVInput, config: ResolvedConfig, logger: Logger): Promise<string[]>;
|
|
35
|
+
export default generateOutput;
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAIR,SAAS,EACT,cAAc,EACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,CAAC;AAErE;;GAEG;AACH,UAAU,OAAO;IACf,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CAC7C;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAOzE,CAAC;AA8BJ;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO/C;AAoOD;;GAEG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,OAAO,EACX,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,EAAE,CAAC,CAqEnB;AAED,eAAe,cAAc,CAAC"}
|