# rzatf/jora-universal-lyric-romanizer architecture

> Architecture diagram of the GitHub repository rzatf/jora-universal-lyric-romanizer, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-26). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/rzatf/jora-universal-lyric-romanizer
- Repository: https://github.com/rzatf/jora-universal-lyric-romanizer

## Overview

JORA is a lyric-cleaning and romanization application with a desktop GUI and a separate offline command-line converter. The main GUI workflow accepts pasted JSON/LRC or fetches lyrics from LRCLIB, extracts available metadata, unescapes and processes lyric lines while preserving timestamps, romanizes supported scripts, and displays and copies the result. The README documents Japanese, Korean, Mandarin, and Latin handling; the sampled GUI source shows those conversion branches. The CLI is narrower: it converts Japanese text and writes an output file. GUI details outside the sampled excerpts are represented only where documented.

Main entry points: [`jora_gui.py`](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py) (Desktop GUI), [`jora.py`](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora.py) (Offline converter)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_gui["Desktop app"]
  node_gui["Desktop GUI<br/>[jora_gui.py]"]
  node_lyric_input["Lyric input<br/>[jora_gui.py]"]
  node_search["Online search<br/>[jora_gui.py]"]
  node_result_view["Result display<br/>[jora_gui.py]"]
end

subgraph group_processing["Lyric processing"]
  node_parser["JSON unescape<br/>[jora_gui.py]"]
  node_metadata["Metadata extraction<br/>[jora_gui.py]"]
  node_line_processing["Line processing<br/>[jora_gui.py]"]
  node_timestamp["Timestamp preservation<br/>[jora_gui.py]"]
  node_language_router["Script detection<br/>[jora_gui.py]"]
  node_japanese["Japanese romanizer<br/>[jora_gui.py]"]
  node_korean["Korean romanizer<br/>[jora_gui.py]"]
  node_mandarin["Mandarin romanizer<br/>[jora_gui.py]"]
end

subgraph group_integrations["External services"]
  node_clipboard["Clipboard"]
  node_lrclib["LRCLIB API"]
end

subgraph group_cli["Offline CLI"]
  node_cli["Offline converter<br/>[jora.py]"]
  node_cli_output["output.lrc file<br/>[jora.py]"]
end

node_user(("User"))

node_user -->|"uses"| node_gui
node_gui -->|"accepts input"| node_lyric_input
node_gui -->|"dispatches search"| node_search
node_search -->|"requests lyrics"| node_lrclib
node_lrclib -->|"returns JSON"| node_search
node_search -->|"inserts response"| node_lyric_input
node_gui -->|"processes input"| node_parser
node_parser -->|"extracts tags"| node_metadata
node_parser -->|"processes lyrics"| node_line_processing
node_line_processing -->|"preserves times"| node_timestamp
node_line_processing -->|"converts text"| node_language_router
node_language_router -->|"routes Japanese"| node_japanese
node_language_router -->|"routes Korean"| node_korean
node_language_router -->|"routes Mandarin"| node_mandarin
node_parser -->|"returns result"| node_result_view
node_user -->|"views output"| node_result_view
node_gui -->|"copies result"| node_clipboard
node_user -->|"provides text"| node_cli
node_cli -->|"converts Japanese"| node_line_processing
node_cli -->|"copies result"| node_clipboard
node_cli -->|"writes file"| node_cli_output

click node_gui "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py"
click node_lyric_input "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py"
click node_search "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py"
click node_result_view "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py"
click node_parser "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py"
click node_metadata "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py"
click node_line_processing "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py"
click node_timestamp "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py"
click node_language_router "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py"
click node_japanese "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py"
click node_korean "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py"
click node_mandarin "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py"
click node_cli "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora.py"
click node_cli_output "https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_gui,node_lyric_input,node_search,node_result_view,node_user toneBlue
class node_parser,node_metadata,node_line_processing,node_timestamp,node_language_router,node_japanese,node_korean,node_mandarin toneAmber
class node_clipboard,node_lrclib toneMint
class node_cli,node_cli_output toneRose
```

## Components

### Desktop app

- [Desktop GUI](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py): `jora_gui.py`
- [Lyric input](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py): `jora_gui.py`
- [Online search](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py): `jora_gui.py`
- [Result display](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py): `jora_gui.py`

### Lyric processing

- [JSON unescape](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py): `jora_gui.py`
- [Metadata extraction](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py): `jora_gui.py`
- [Line processing](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py): `jora_gui.py`
- [Timestamp preservation](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py): `jora_gui.py`
- [Script detection](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py): `jora_gui.py`
- [Japanese romanizer](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py): `jora_gui.py`
- [Korean romanizer](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py): `jora_gui.py`
- [Mandarin romanizer](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora_gui.py): `jora_gui.py`

### External services

- **Clipboard**
- **LRCLIB API**

### Offline CLI

- [Offline converter](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora.py): `jora.py`
- [output.lrc file](https://github.com/rzatf/jora-universal-lyric-romanizer/blob/main/jora.py): `jora.py`

### Other components

- **User**

## Connections

- User → Desktop GUI: uses
- Desktop GUI → Lyric input: accepts input
- Desktop GUI → Online search: dispatches search
- Online search → LRCLIB API: requests lyrics
- LRCLIB API → Online search: returns JSON
- Online search → Lyric input: inserts response
- Desktop GUI → JSON unescape: processes input
- JSON unescape → Metadata extraction: extracts tags
- JSON unescape → Line processing: processes lyrics
- Line processing → Timestamp preservation: preserves times
- Line processing → Script detection: converts text
- Script detection → Japanese romanizer: routes Japanese
- Script detection → Korean romanizer: routes Korean
- Script detection → Mandarin romanizer: routes Mandarin
- JSON unescape → Result display: returns result
- User → Result display: views output
- Desktop GUI → Clipboard: copies result
- User → Offline converter: provides text
- Offline converter → Line processing: converts Japanese
- Offline converter → Clipboard: copies result
- Offline converter → output.lrc file: writes file
