Flutter/EBook

[EBook 구조] Spine에 대하여

달님개발자 2023. 8. 21. 11:15
반응형

이북 뷰어에서 현재 페이지 표시 기능을 구현하다가 잘 안되어서 공부중인데, spine이라는 용어가 나와서 파악중이다.

예전에도 이름만 들어봤지, 오픈소스를 사용하다보니 깊이 알 필요가 없었는데...

 

일단 Spine에 대한 정의를 보면 다음과 같다.

Spine : 등뼈, 척추(脊椎, 등마루 척, 쇠몽치 추/등골 추) "등마루"라는 한글이 더 어렵다. "등골뼈가 있는 두두룩하게 줄진 곳"을 등마루라고 한다는데, "마루"는 집에서 거실을 말할때 쓰기도 하는 그 마루인가?

 

In an EPUB file, the spine is an XML element that specifies the order in which the book's pages or other content should be displayed.
EPUB 파일에서 spine은 책의 페이지 또는 기타 콘텐츠가 표시되어야 하는 순서를 지정하는 XML 요소이다.

 

즉 이북에서 순서대로 보여줄 컨텐츠의 리스트를 정의한다. 실제 보여줄 컨텐츠는 manifest에서 정의된다.


Alice.epub
0.15MB

분석중인 "이상한 나라의 앨리스" 전자책을 확장자를 zip으로 바꾼후 압축을 풀면 다음과 같이 나온다.

OEBPS/content.opf 파일을 열어보면 spine이 아래처럼 나온다.

이북앱에서는 이 spine에 정의된 것들만 순서대로 보여준다. (물론 뷰어를 제대로 만들었을 경우...)

  <spine toc="ncx">
    <itemref idref="coverpage-wrapper" linear="yes"/>
    <itemref idref="pg-header" linear="yes"/>
    <itemref idref="item3" linear="yes"/>
    <itemref idref="item4" linear="yes"/>
    <itemref idref="item5" linear="yes"/>
    <itemref idref="item6" linear="yes"/>
    <itemref idref="item7" linear="yes"/>
    <itemref idref="item8" linear="yes"/>
    <itemref idref="pg-footer" linear="yes"/>
  </spine>

저 idref가 가리키는것은 같은 파일내의 매니페스트(manifest)에 있다.

manifest는 분명한, 명백한, 나타나다, 보이다등의 뜻과 함께 목록(目錄, list)라는 뜻이 있다. 개발할때 나오는 manifest는 보통 목록을 뜻할때가 많다.

 

spine에 맨처음 정의된 coverpage-wrapper를 manifest에서 찾아보면 wrap0000.html이 나온다.

  <manifest>
    <!--Image: 581 x 1034 size=61232 q=20-->
    <item href="4152623900194477937_cover.jpg" id="id-3925372991976549219" media-type="image/jpeg"/>
    <item href="pgepub.css" id="item1" media-type="text/css"/>
    <item href="0.css" id="item2" media-type="text/css"/>
    <!--Chunk: size=51855 Split on div-->
    <item href="7177526252286089223_19002-h-0.htm.html" id="pg-header" media-type="application/xhtml+xml"/>
    <!--Chunk: size=51344 Split on div-->
    <item href="7177526252286089223_19002-h-1.htm.html" id="item3" media-type="application/xhtml+xml"/>
    <!--Chunk: size=40689 Split on div.font2-->
    <item href="7177526252286089223_19002-h-2.htm.html" id="item4" media-type="application/xhtml+xml"/>
    <!--Chunk: size=52347 Split on div-->
    <item href="7177526252286089223_19002-h-3.htm.html" id="item5" media-type="application/xhtml+xml"/>
    <!--Chunk: size=52836 Split on div-->
    <item href="7177526252286089223_19002-h-4.htm.html" id="item6" media-type="application/xhtml+xml"/>
    <!--Chunk: size=27669-->
    <item href="7177526252286089223_19002-h-5.htm.html" id="item7" media-type="application/xhtml+xml"/>
    <!--Chunk: size=5228 Split on div.section-->
    <item href="7177526252286089223_19002-h-6.htm.html" id="item8" media-type="application/xhtml+xml"/>
    <!--Chunk: size=19825-->
    <item href="7177526252286089223_19002-h-7.htm.html" id="pg-footer" media-type="application/xhtml+xml"/>
    <item href="toc.ncx" id="ncx" media-type="application/x-dtbncx+xml"/>
    <item href="wrap0000.html" id="coverpage-wrapper" media-type="application/xhtml+xml"/>
  </manifest>

 

wrap0000.html을 열어보면 아래처럼 이미지 파일을 나타낸다. 그럼 이북 뷰어에서는 저 이미지 파일을 보여주면 된다.

<img src="4152623900194477937_cover.jpg" alt="Cover" class="x-ebookmaker-cover" />

spine을 보면 item3부터 시작한다. 그럼 실제로 item1, 2등이 manifest에 있어도, 이북뷰어에서 spine에 정의된 순서대로 보여줄때 사용되지 않는다. Alice에서는 item1, 2등이 css파일을 가리키므로 당연히 뷰어에서 보여주면 안된다.

 

spine엘리먼트의 item3를 manifest에서 찾아보면 "7177526252286089223_19002-h-1.htm.html" 파일이라고 나온다. 그럼 pg-header가 끝나고 다음으로 넘어갈때는 저 파일을 열어서 보여주면 된다.

 

Spine의 itemref에는 linear라는 속성도 있다. linear는 직선(直線), 순차적(順次的)이란 뜻이다. linear의 값은 yes또는 no가 있는데,

yes이면 순차적으로 보여주겠다는 뜻이다.

즉 아래처럼 아이템 3, 4, 5가 전부 yes이면, 3이 끝나면 4를 보여주고, 4가 끝나면 5를 보여주겠다는 뜻이다.

<itemref idref="item3" linear="yes"/>
<itemref idref="item4" linear="yes"/>
<itemref idref="item5" linear="yes"/>

만약 item4의 linear가 no이면, item3 다음에 item4를 건너뛰고 그다음거인 item5를 보여준다는 뜻이다.

그럼 item4는 언제 보여주나? 그건 epub내에서 href등으로 item4를 열수 있도록 정의하면 된다고 한다. (나는 아직 linear이 no이걸 본적이 없다)

<itemref idref="item3" linear="yes"/>
<itemref idref="item4" linear="no"/>
<itemref idref="item5" linear="yes"/>

 

 

 

https://www.w3.org/TR/epub-33/#sec-pkg-spine

 

EPUB 3.3

When a reading system renders a synthetic spread, the default behavior is to populate the spread by rendering the next EPUB content document in the next available unpopulated viewport, where the next available viewport is determined by the given page progr

www.w3.org

 

반응형