Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: improve gemini translator #1006

Merged
merged 1 commit into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GOOGLE_API_KEY=
16 changes: 8 additions & 8 deletions adev-ja/src/content/introduction/essentials/components.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<docs-decorative-header title="コンポーネント" imgSrc="adev/src/assets/images/components.svg"> <!-- markdownlint-disable-line -->
Angularでアプリケーションを作成するための基本的な構成要素
Angularアプリケーションを作成するための基本的な構成要素
</docs-decorative-header>

コンポーネントは、Angularアプリケーションの主要な構成要素です。各コンポーネントは、より大きなウェブページの一部を表します。アプリケーションをコンポーネントに整理することで、プロジェクトに構造が与えられ、コードが特定の部分に明確に分割されるため、保守と拡張が容易になります。
Expand Down Expand Up @@ -73,7 +73,7 @@ h1 {

## コンポーネントの使用

複数のコンポーネントを組み合わせてアプリケーションを構築します。例えば、ユーザープロフィールページを構築する場合、ページを次のような複数のコンポーネントに分割できます
アプリケーションは複数のコンポーネントを組み合わせて構築します。例えば、ユーザーのプロファイルページを作成する場合、次のようにページをいくつかのコンポーネントに分割できます

```mermaid
flowchart TD
Expand All @@ -84,14 +84,14 @@ flowchart TD
D[UserAddress]
```

ここでは、`UserProfile`コンポーネントは他のいくつかのコンポーネントを使用して最終的なページを作成します。
ここで、`UserProfile`コンポーネントは他のいくつかのコンポーネントを使用して最終的なページを作成します。

コンポーネントをインポートして使用するには、次の手順が必要です。
1. コンポーネントのTypeScriptファイルで、使用するコンポーネントの`import`文を追加します。
2. `@Component`デコレーターで、使用するコンポーネントの`imports`配列にエントリを追加します
3. コンポーネントのテンプレートで、使用するコンポーネントのセレクターと一致する要素を追加します。
1. コンポーネントのTypeScriptファイルに、使用するコンポーネントの`import`文を追加します。
2. `@Component`デコレーターの`imports`配列に、使用するコンポーネントのエントリを追加します
3. コンポーネントのテンプレートに、使用するコンポーネントのセレクターと一致する要素を追加します。

`UserProfile`コンポーネントが`ProfilePhoto`コンポーネントをインポートする例を以下に示します
`ProfilePhoto`コンポーネントをインポートする`UserProfile`コンポーネントの例を次に示します

```angular-ts
// user-profile.ts
Expand All @@ -111,7 +111,7 @@ export class UserProfile {
}
```

Tip: Angularコンポーネントについてもっと知りたいですか? 詳細については、[詳細なコンポーネントガイド](guide/components)を参照してください。
Tip: Angularコンポーネントの詳細については、[詳細なコンポーネントガイド](guide/components)を参照してください。

## 次の手順

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
"test": "yarn test:patch",
"test:patch": "git apply -v --check --directory origin ./tools/adev-patches/*.patch",
"update-origin": "tsx tools/update-origin.ts",
"translate": "tsx tools/translate.ts"
"translate": "tsx --env-file=.env tools/translator/main.ts"
},
"packageManager": "[email protected]",
"devDependencies": {
"@google/generative-ai": "0.14.1",
"@google/generative-ai": "0.21.0",
"@types/node": "20.14.10",
"chokidar": "3.6.0",
"consola": "3.2.3",
Expand All @@ -32,6 +32,6 @@
"textlint-rule-preset-ja-spacing": "2.4.3",
"textlint-rule-preset-ja-technical-writing": "10.0.1",
"textlint-rule-prh": "^6.0.0",
"tsx": "^4.16.2"
"tsx": "4.19.2"
}
}
225 changes: 0 additions & 225 deletions tools/translate.ts

This file was deleted.

72 changes: 72 additions & 0 deletions tools/translator/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import consola from 'consola';
import assert from 'node:assert';
import { readFile, writeFile } from 'node:fs/promises';
import { resolve } from 'node:path';
import { parseArgs } from 'node:util';
import {
cpRf,
exists,
getEnFilePath,
getLocalizedFilePath,
} from '../lib/fsutils';
import { rootDir } from '../lib/workspace';
import { GeminiTranslator } from './translate';

async function main() {
const apiKey = process.env.GOOGLE_API_KEY;
assert(apiKey, 'GOOGLE_API_KEY 環境変数が設定されていません。');

const args = parseArgs({
options: { write: { type: 'boolean', default: false, short: 'w' } },
allowPositionals: true,
});
const { write } = args.values;
const [file] = args.positionals;

const fileExists = await exists(file);
if (!fileExists) {
throw new Error(`ファイルが見つかりません: ${file}`);
}

const content = await readFile(file, 'utf-8');
const prh = await readFile(resolve(rootDir, 'prh.yml'), 'utf-8');

const translator = new GeminiTranslator(apiKey);
const translated = await translator.translate(content, prh);

console.log(translated);
await writeTranslatedContent(file, translated, write);
}

async function writeTranslatedContent(
file: string,
content: string,
forceWrite = false
) {
const outputFile = getLocalizedFilePath(file);
const save =
forceWrite ||
(await consola.prompt(`翻訳結果を保存しますか?\n保存先: ${outputFile}`, {
type: 'confirm',
initial: false,
}));
if (!save) {
return;
}

const enFile = getEnFilePath(file);
// .en.* が存在しない場合は原文コピーを忘れているため、.en.md に元ファイルをコピーする
if (!(await exists(enFile))) {
consola.warn(
`原文ファイルが見つかりません。入力ファイルを ${enFile} にコピーします。`
);
await cpRf(file, enFile);
}
await writeFile(outputFile, content);
consola.success(`保存しました`);
}

main().catch((error) => {
consola.error(error);
process.exit(1);
});
14 changes: 14 additions & 0 deletions tools/translator/markdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export type ContentBlock = string;

export function splitMarkdown(content: string): ContentBlock[] {
// split content by heading lines (lines starting with ##)
return content.split(/\n(?=##\s)/);
}

export async function renderMarkdown(blocks: ContentBlock[]) {
const content = blocks
.map((block) => (block.endsWith('\n') ? block.replace(/\n$/, '') : block))
.join('\n\n');
// add trailing newline
return content + '\n';
}
Loading
Loading