← 전체 글

SWORD, MySword, e-Sword 모듈 포맷: 공식 문서가 잘못 설명하는 것들

A zText index drawn as one bar with four segments in proportion: one module heading, one testament heading, 287 book and chapter headings, and 7,957 verses — 8,246 records of 10 bytes, 82,460 bytes. Caption: a zText index counts slots, not verses.

요약: 성경 모듈을 제작 중이라면 널리 퍼진 세 가지 잘못된 사실을 바로잡아야 합니다. e-Sword에는 .bbl 포맷이 없습니다. 신약 모듈은 성경 전체 기준의 책 번호를 유지해야 합니다. 그리고 SWORD zText 인덱스는 절이 아니라 슬롯을 셉니다. 이 세 가지 실수는 모두 설치는 깔끔하게 되지만 본문이 엉뚱하게 표시되는 결과를 낳으며, 이는 오류 중에서도 가장 골치 아픈 형태입니다.

우리는 외부 툴체인 없이 순수 Go 언어로 SWORD, MySword, e-Sword용 모듈 빌더를 작성하여 Tringine을 뒷받침하는 무료 성경 모듈을 배포했습니다. 아래에 기술된 모든 스키마와 바이트 레이아웃은 기존 설명 문서가 아니라, 실제로 배포된 모듈을 헥스 에디터와 sqlite3로 직접 분석하여 얻은 결과입니다. 코드를 읽는 것만으로는 부족했기에 현재 매 빌드마다 실행하는 유효성 검사를 포함해, 우리가 알아낸 모든 내용을 정리했습니다.

Why is there no .bbl file for e-Sword?

그런 파일이 아예 존재하지 않기 때문입니다. e-Sword 성경 모듈 포맷을 검색하면 .bbl이 끊임없이 등장하지만, .bbl은 LaTeX의 서지(bibliography) 확장자입니다. 사양서를 찾아 헤매도 아무것도 나오지 않고 혼란스럽기만 했던 이유가 바로 여기에 있습니다.

실제 포맷은 절 텍스트가 RTF인 e-Sword 9 및 10용 .bblx, 그리고 절 텍스트가 HTML인 버전 11 이후용 .bbli입니다. 버전 11부터 13까지는 두 포맷 모두 지원하므로, .bblx 하나만 배포해도 e-Sword 9부터 13까지 모두 대응할 수 있습니다. 한 가지 포맷만 제작해야 한다면 .bblx를 선택하세요.

Reader File Verse text Read by
SWORD (AndBible, Xiphos, BibleTime) mods.d/*.conf + zText files OSIS-derived, zlib blocks every libsword front end
MySword .bbl.mybible (SQLite) theWord-style tags MySword for Android
e-Sword 9–13 .bblx (SQLite) RTF e-Sword 9, 10, 11, 12, 13
e-Sword 11+ .bbli (SQLite) HTML e-Sword 11 and later only

Why does a New Testament module still number books 40 to 66?

세 포맷 모두 절을 찾을 때 고정된 장절 체계(versification)(뷰어가 절을 찾기 위해 사용하는 책, 장, 절 수의 표준 목록으로, 기본값은 KJV)를 기준으로 주소를 지정하며, 이 번호 체계는 해당 판본에 포함된 내용 기준의 상대적 번호가 아니라 절대적인 번호이기 때문입니다. 신약성경의 번호를 1부터 27까지로 다시 매기면 마태복음이 창세기 자리에 들어가게 되고, 그 뒤의 모든 책이 밀려버립니다.

우리는 이 추론만 믿지 않고 실제 배포된 신약 전용 모듈 두 개를 직접 확인했습니다. 두 모듈 모두 40번 책부터 시작하며 둘 다 OT=0으로 설정되어 있었습니다. 구약이나 신약 내부에서도 동일한 원칙이 적용됩니다. 제작하는 판본에 빠진 책이 있더라도 빈 상태로 슬롯을 그대로 차지하고 있어야 합니다. 용량을 아끼려고 이를 건너뛰면, 누락된 책 이후의 모든 책에서 뷰어가 마태복음 참조 아래에 마가복음 본문을 표시하는 식의 오류가 조용히 발생하게 됩니다.

How many records belong in a zText index?

잘못된 길이의 인덱스라도 파싱 자체는 정상적으로 되기 때문에, 이 부분이 모듈을 조용히 손상시키는 원인입니다.

SWORD의 성경 한 부(구약 또는 신약)는 세 개의 파일로 구성됩니다. CrossWire ASV 및 Byzantine 모듈을 측정한 결과, 전체적으로 리틀 엔디언 방식을 사용합니다.

File Record size Contents
nt.bzv 10 bytes uint32 block, uint32 offset within the decompressed block, uint16 length
nt.bzs 12 bytes uint32 offset into .bzz, uint32 compressed size, uint32 decompressed size
nt.bzz The blocks themselves, each an independent zlib stream, one per book plus block 0 for headings

열거 방식에서 문제가 발생합니다. 슬롯은 다음과 같이 진행됩니다. 0번 슬롯은 모듈 표제, 1번 슬롯은 성경 표제, 그 다음 각 책마다 책 표제 하나, 각 장마다 장 표제 하나, 그리고 각 절마다 슬롯 하나가 할당됩니다. 따라서 레코드 수는 절 수가 아니라 2 + books + chapters + verses 가 됩니다.

KJV 장절 체계 기준 신약성경의 경우 2 + 27 + 260 + 7,957 = 8,246 records이며, 따라서 nt.bzv의 크기는 정확히 82,460 bytes가 됩니다. 구약성경의 경우 2 + 39 + 929 + 23,145 = 24,115 records, 즉 241,150 bytes입니다.

이 수치는 명령어 하나로 바로 검증할 수 있으며, 이것이 바로 이 글에 정리해 두는 이유입니다. 공식 배포된 ASV 및 Byzantine 모듈의 nt.bzv 파일 크기는 둘 다 정확히 82,460바이트입니다. 제작한 파일의 크기가 이와 다르다면 슬롯 열거가 잘못된 것이며, 프로그램이 충돌을 일으키는 대신 뷰어가 엉뚱한 내용을 보여주는 시점에야 이를 발견하게 될 것입니다.

참고할 만한 구조가 하나 더 있습니다. 신약 전용 모듈이라도 모든 값이 0으로 채워진 정상 크기의 ot.bzv를 함께 배포하며, ot.bzsot.bzz의 길이는 0바이트로 둡니다. 이는 공식 배포된 Byzantine 모듈의 바이트 구조와 완전히 일치합니다.

What do the SQLite formats actually require?

MySword (.bbl.mybible): page_size=32768, UTF-8이며, 성경 인덱스는 UNIQUE입니다. 절 텍스트는 HTML이 아닌 theWord 스타일의 태그 쌍을 사용하며, 각주는 <RF>…<Rf> 형태입니다. Details.Language에는 세 글자 코드가 들어가는데, 어떤 세 글자를 써야 하는지는 직관적이지 않습니다. ISO 639-2에는 약 20개 언어에 대해 서지용 코드와 용어용 코드가 따로 존재하는데, 실제 배포된 모듈들도 일관성 있게 따르지 않습니다(독일어와 체코어 모듈은 deuces를 사용하고, 프랑스어, 알바니아어, 그리스어 모듈은 fre, alb, gre를 사용하며, 약 3분의 1은 이 컬럼을 아예 생략합니다). 우리는 표준 문서를 읽기보다 실제 모듈을 열어보고 결정했습니다. 배포된 두 개의 노르웨이어 모듈이 모두 nor를 사용하고 있었으므로 우리 모듈도 이를 따랐습니다. 언어를 확실하게 매핑할 수 없는 경우에는 추측해서 넣기보다 NULL을 기록합니다. 잘못된 언어 태그가 누락된 태그보다 더 나쁘기 때문입니다.

e-Sword (.bblx): page_size=1024, 작은따옴표로 감싼 식별자, 그리고 인덱스는 UNIQUE가 아닙니다. 여기서 두 가지 함정이 있습니다. Details.Version은 판본의 버전이 아니라 포맷 세대를 나타내는 INT 값이며(.bblx는 2, .bbli는 4), 판본의 버전은 Comments에 들어가야 합니다. 그리고 우리가 살펴본 세 개의 실제 모듈은 데이터베이스 자체 인코딩마저 일치하지 않았습니다. 하나는 UTF-16LE, 두 개는 UTF-8이었습니다. 따라서 타밀어나 텔루구어 코드포인트를 저장할 때 컬럼 인코딩을 그대로 신뢰할 수 없습니다.

해결책은 모든 비-ASCII 룬을 RTF \uN? 이스케이프로 기록하는 것입니다. 부호 있는 16비트 정수이며, BMP를 벗어나는 문자는 서로게이트 쌍을 사용합니다. 이는 인코딩과 무관하게 동작하며, 실제 모듈들이 취하고 있는 방식이기도 합니다. 라틴 문자가 아닌 문자로 된 e-Sword 모듈을 배포한다면, 사용자가 본문을 읽을 수 있는지를 결정짓는 핵심 세부사항은 바로 이것입니다.

두 SQLite 포맷 모두 불리언 값으로 1/0을 사용합니다. (.bbli는 Delphi의 -1을 사용하므로, 굳이 가볍게 .bbli 생성을 시도하지 않는 편이 좋습니다.)

Check the rendered .conf, not the struct

메타데이터는 카탈로그가 읽고 법정에서 살펴볼 수도 있는 모듈의 핵심 요소이지만, 테스트 스위트에서는 가장 간과하기 쉬운 부분이기도 합니다. 우리 역시 처음에는 그렇지 못했습니다. Go 구조체에서는 올바르게 설정되었던 라이선스 필드가 .conf로 렌더링될 때는 엉뚱한 값으로 출력되었고, 이를 테스트 실행이 아니라 직접 파일을 열어봄으로써 발견했습니다. 해당 버그는 당일 수정되어 모든 모듈이 다시 빌드되었습니다. 현재 보관 중인 파일들은 1868년 타밀어와 1880년 텔루구어 텍스트에 대해 Copyright=Public Domain으로 명시하고 저작권자를 표기하지 않으며, TextSource에 판본 제작자로서 Publifye의 이름만 기재하고 있습니다.

이 파일에서는 두 가지 주장을 반드시 분리해야 합니다. 본문의 라이선스는 번역본 자체에 대한 사실이며 제작자가 임의로 선택할 수 있는 사항이 아닙니다. 퍼블릭 도메인 성경은 제작된 모듈 안에서도 퍼블릭 도메인이며, 어떤 DistributionNotes 문구로도 이를 제한할 수 없습니다. 반면 회원가입이나 로깅과 같은 배포 서비스 이용약관은 제작자의 서버에만 적용될 뿐입니다. 이 둘을 혼동하면 자유롭게 공개된 텍스트를 제한하거나, 반대로 보호받아야 할 텍스트를 무단으로 공개하는 우를 범하게 됩니다.

이제 이를 검증하는 테스트는 렌더링된 .conf 파일을 직접 확인합니다. 퍼블릭 도메인 텍스트에 저작권자나 제한적 문구가 들어가면 즉시 실패하고, 반대로 우리가 번역한 텍스트가 임의로 퍼블릭 도메인으로 강등되어도 마찬가지로 실패합니다. 잘못 허용하는 오류 역시 오류이므로 양방향 모두를 엄격하게 검증합니다. 성경 모듈을 배포하는 사람이라면 코드가 작성해낸 내용이 아니라 실제로 배포되는 파일 자체를 반드시 직접 확인해야 합니다.

How we verified it

사양서를 되뇌는 방식이 아니라 다음과 같이 실측했습니다.

  • 데비안 컨테이너에서 libsword 자체 도구인 diatheke를 사용해 7,957개 절을 담은 정규 신약 모듈을 빌드하고 읽어 들였습니다. 해당 모듈은 modulelist에 정상 표시되고, 마태복음 1:1, 요한복음 3:16, 고린도전서 13:13, 요한계시록 22:21을 올바른 주소에서 찾아내며, 신약 전용 모듈답게 창세기 1:1에 대해서는 아무것도 반환하지 않고, 검색도 정상 동작했습니다.
  • 신구약 전체 31,102개 절을 담은 성경 전체 모듈에 대해서도 동일한 검증을 수행했습니다. 창세기 1:1과 시편 119:176은 타밀어로, 요한계시록 22:21은 텔루구어로 각각 올바른 주소에서 읽어 들였으며, 82,460바이트의 nt.bzv와 함께 정확히 241,150바이트인 실제 ot.bzv가 생성됨을 확인했습니다.
  • xmllint로 OSIS XML이 잘 정형화되어 있고 권리 표기가 포함되어 있는지 유효성을 검사했습니다.
  • sqlite3로 SQLite 파일을 열어 계획서에 기록된 행 수와 정확히 일치하는지 확인했습니다. 신약 모듈의 경우 4066번 책에 걸쳐 7,957개 행, 성경 전체 모듈의 경우 166번 책에 걸쳐 31,102개 행이었습니다.

테스트 스위트 대신 이러한 실기 검증을 통해 우리 코드의 버그 두 개를 발견할 수 있었습니다. 이는 매우 자연스러운 일이며, 사양에 대한 스스로의 이해에만 의존하지 말고 실제 뷰어 환경을 대상으로 테스트해야 하는 이유이기도 합니다.

Frequently asked

What format should I build first for e-Sword?

.bblx입니다. 버전 11부터 13까지는 최신 .bbli와 함께 이 포맷도 지원하므로 파일 하나로 e-Sword 9부터 13까지 모두 대응할 수 있습니다.

Why is my module showing the wrong book's text?

거의 대부분 열거 방식 문제입니다. 신약성경에서 책 번호를 1부터 27까지로 다시 매겼거나, 판본에 없는 책을 빈 슬롯으로 남겨두지 않고 건너뛰었기 때문입니다. 먼저 nt.bzv의 바이트 길이가 82,460바이트인지 확인해 보세요.

Do I need an ot file in a New Testament module?

네. 모든 값이 0으로 채워진 정상 크기의 ot.bzv와 길이가 0바이트인 ot.bzsot.bzz가 있어야 합니다.

How do I get Tamil, Telugu or other non-Latin text into .bblx?

실제 모듈마다 제각각인 컬럼 인코딩에 의존하지 말고, 모든 비-ASCII 룬을 RTF \uN? 이스케이프로 기록하세요.

Can I use your modules?

네. 퍼블릭 도메인 모듈에 대해서는 우리가 어떠한 제한도 두지 않습니다. 판본 제작은 우리의 작업이지만, 그 말씀은 만인의 것입니다. 우리가 직접 번역한 Bibelen Anno 2026은 비상업적 목적으로 자유롭게 배포할 수 있습니다.


포맷 정보 대신 모듈 자체가 필요하신가요? How to install free Bible modules in AndBible, MySword and e-Sword에서 각 앱별 설치 과정을 안내합니다. tringine.publifye.com/modules에 있는 모든 모듈은 직접 빌드하거나 검증해 볼 수 있도록 OSIS 원본 소스와 함께 제공됩니다. 다운로드에는 무료 계정이 필요하지만, 이는 서비스 이용약관일 뿐 본문 텍스트에 대한 권리 주장이 아닙니다. 라이선스 페이지에도 이 점이 명확히 명시되어 있습니다.

Written by Jørn André Halseth, founder of Publifye AS — ten years publishing Bibles and building the presses they run on, and the author of Tringine, Darash, Junifye and Lexifye. About · Contact

새로운 것을 출시하면 이메일로 알려드립니다. 뉴스레터 구독하기