blog

OpenOffice.org/LibreOffice-ból exportált PDF metaadatainak beállítása

Dokumentum címének beállítása:

  • File menü / Properties / Description fül alatt a Title mezőnél megadható a dokumentum címe.

A szerző megadása:

  • Tools menü / Options / LibreOffice / User Data oldalon a First name, Last name mezők kitöltése,
  • File menü / Properties alatt a General fülön pipáljuk ki az „Apply user data” jelölőnégyzetet,
  • nyomjuk meg az „Apply user data” melletti Reset gombot.

A reset gomb frissíti az épp szerkesztett dokumentum szerző mezőjét a User Data alatt megadott adatokkal, megnyomása után az új szerző rögtön megjelenik a General fülön a Created címke mellett. A dokumentumot pdf-ként exportálva ezután már a beállított értékek fognak szerepelni a metaadatok között. Ne felejtsük el elmenteni az eredeti dokumentumot sem a metaadatok módosítása után.

PDF metaadatok módosítása

A PDF toolkittel – vagy röviden csak pdftk-val – egyszerűen módosíthatóak a pdf fájlok metaadatai. A telepítés Debian alatt csak egy apt-get install pdftk, de van Windowsos bináris is, bár azt nem próbáltam.

A metaadatok közül a Sony PRS-650 esetében a szerző és a cím a legérdekesebb. A dátum szerinti sorrendezésnél a felmásolás dátuma számít, nem a pdf fájlban lévő időpont.

Metaadatok lekérdezése:

$ pdftk original.pdf dump_data > pdf.data

Az így létrejött pdf.data fájl tartalma valami ilyesmi:

InfoKey: Creator
InfoValue: Writer
InfoKey: Title
InfoValue: árvíztűrő tükörfúrógép - ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP
InfoKey: Producer
InfoValue: OpenOffice.org 3.2
InfoKey: Author
InfoValue: palacsint
InfoKey: CreationDate
InfoValue: D:20110727211139+02'00'
PdfID0: d52f66ef5c592704640f4c44af42383
PdfID1: d52f66ef5c592704640f4c44af42383
NumberOfPages: 1

A címet az „InfoKey: Title” utáni sorban lévő InfoValue után kell megadni, a szerzőt pedig az „InfoKey: Author” utáni sorban. A cím jelen esetben az „árvíztűrő tükörfúrógép - ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP” szöveg. Értelemszerűen az ékezetes karaktereket a fenti formában kell megadni.

Végül a pdf.data módosítása után a metaadatok visszatöltése egy új fájlba:

$ pdftk original.pdf update_info pdf.data output metafix.pdf

Frissítés (2013. április 12.): Valamivel újabb Debianban már az escape-elés sem szükséges, UTF-8 karaktereket minden gond nélkül lehet használni a pdf.data fájlban.

Mock objektumok többszálú használata

A lenti EasyMock (3.0) tesztben átadunk az executornak egy Runnable példányt. Ez egy mock objektum, és talán azt várnánk, hogy a verify() majd jelzi, hogy az executor (egy másik szálban) engedély nélkül meghívta a mock objektum run() metódusát, azaz hibával elszáll a teszt.

import static org.junit.Assert.assertTrue;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.easymock.EasyMock;
import org.junit.Test;

public class EasyMockTest {

	@Test
	public void testEasyMock() throws Exception {
		final Runnable runnable = EasyMock.createMock(Runnable.class);
		EasyMock.makeThreadSafe(runnable, true); // default true
		EasyMock.replay(runnable);

		runInNewThread(runnable);

		EasyMock.verify(runnable); // should fail
	}

	private void runInNewThread(final Runnable runnable)
			throws InterruptedException {
		final ExecutorService executor = Executors.newSingleThreadExecutor();
		executor.execute(runnable);

		executor.shutdown();
		final boolean terminated = executor.awaitTermination(2,
				TimeUnit.SECONDS);
		assertTrue("terminated", terminated);
	}
}

Nem ez történik, a teszt hiba nélkül lefut, a verify() nem jelez hibát. A konzolon viszont megjelenik a hibaüzenet:

Exception in thread "pool-1-thread-1" java.lang.AssertionError: 
  Unexpected method call run():
	at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:45)
	at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:73)
	at $Proxy4.run(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:619)

JMock-kal (2.5.1) ugyanez a helyzet:

import static org.junit.Assert.assertTrue;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.jmock.Mockery;
import org.jmock.integration.junit4.JMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(JMock.class)
public class JmockTest {

	private Mockery mockery;

	@Before
	public void setUp() {
		mockery = new Mockery();
	}

	@Test // should fail
	public void testJmock() throws Exception {
		final Runnable runnable = mockery.mock(Runnable.class);

		runInNewThread(runnable);
	}

	...
}

A teszt sikeresen lefut, a hibaüzenet itt is csak a hibakonzolon jelenik meg.

Mockitót (1.8.5) használva jobbak az eredmények:

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.junit.Test;

public class MockitoTest {

	@Test
	public void testMociko() throws Exception {
		final Runnable runnable = mock(Runnable.class);

		runInNewThread(runnable);

		try {
			verify(runnable, never()).run(); // failed
			fail("verify");
		} catch (final AssertionError expected) {

		}
	}

	...
}

A verify() hívás hibát dob, ahogy vártuk. A konzolon pedig nem jelenik meg semmi, mert mock() metódus úgynevezett nice mock objektumokat készít, amelyek csak rögzítik a meghívott metódusaikat és sosem dobnak hibát.

Az EasyMock-hoz egy nem túl szép workaround saját ThreadFactory használata a kivételt elkapó UncaughtExceptionHandler-rel, majd a teszt végén az UncaughtExceptionHandler ellenőrzése.

import static org.junit.Assert.assertTrue;

import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import org.easymock.EasyMock;
import org.junit.Test;

public class EasyMockExceptionHandlerTest {

	@Test
	public void testEasyMockWithUncaughtExceptionHandler() throws Exception {
		final Runnable runnable = EasyMock.createMock(Runnable.class);
		EasyMock.makeThreadSafe(runnable, true); // default true
		EasyMock.replay(runnable);

		final AtomicBoolean threadError = new AtomicBoolean(false);
		final ExecutorService executor = createExecutor(threadError);
		executor.execute(runnable);

		executor.shutdown();
		final boolean terminated = executor.awaitTermination(2,
				TimeUnit.SECONDS);
		assertTrue("terminated", terminated);

		EasyMock.verify(runnable);
		assertTrue("thread error", threadError.get());
	}

	private ExecutorService createExecutor(final AtomicBoolean threadError) {
		final ErrorFlagUncaughtExceptionHandler uncaughtExceptionHandler 
			= new ErrorFlagUncaughtExceptionHandler(threadError);

		final ThreadFactory threadFactory = new ThreadFactory() {
			final ThreadFactory defaultThreadFactory = Executors
					.defaultThreadFactory();

			public Thread newThread(final Runnable runnable) {
				final Thread thread = defaultThreadFactory.newThread(runnable);
				Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);
				return thread;
			}
		};
		final ExecutorService executor = Executors
				.newSingleThreadExecutor(threadFactory);
		return executor;
	}

	private class ErrorFlagUncaughtExceptionHandler implements
			UncaughtExceptionHandler {

		private final AtomicBoolean threadError;

		public ErrorFlagUncaughtExceptionHandler(final AtomicBoolean threadError) {
			this.threadError = threadError;
		}

		public void uncaughtException(final Thread thread,
				final Throwable throwable) {
			threadError.set(true);
		}
	}
}

JMock-hoz talán a 2.6-os vagy 2.7-es verzióban lesz erre megoldás, a jelenlegi dokumentáció alapján nem igazán támogatott a JMock mock objektumainak többszálú használata. Lásd még: JMOCK-213,
JMOCK-183.

EasyMock: During the replay phase, mocks are by default thread-safe.

Ugyanez a helyzet a Mockitónál is: You can let multiple threads call methods on a shared mock to test in concurrent conditions.

Az igazi megoldást azonban nem mock-olásra használt osztálykönyvtárban kellene implementálni, hanem a tesztelt kódban, hogy a más szálakon keletkező hibákról a hívó értesüljön, valamint a tesztünk is ezen az úton tudja meg, hogy hiba történt. Az EasyMock levelezőlistáján olvasható erről egy levél:

„Let's say the exception would be thrown by a real implementation, and *not* by EasyMock. How would your application know that the calculation went wrong?”

Erre használható például az ExecutorService:

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.easymock.EasyMock;
import org.junit.Test;

public class ExecutorServiceTest {

	@Test(expected = ExecutionException.class)
	public void testEasyMockWithExecutorService() throws Exception {
		final Runnable runnable = EasyMock.createMock(Runnable.class);
		EasyMock.makeThreadSafe(runnable, true); // default true
		EasyMock.replay(runnable);

		final ExecutorService executorService = Executors
				.newSingleThreadExecutor();

		final Future future = executorService.submit(runnable);
		future.get();
	}

}

Spielmaterial rendelés

Néhány tapasztalat egy spielmaterial.de csoportos rendelés kapcsán:

  • A postaköltséget csak rendelés leadása után számítják ki. Ez egy manuális lépés, általában másnapra elküldik az eredményt. Nálunk 10,5 és 18,5 euró között ingadozott. A szállítási költségre van ugyan néhány példa a weblapon, de eléggé közelítő jellegűek. Sajnos súlyinformáció sincs az egyes alkatrészek, termékek mellett.
  • A szállítási költségbe beleértik a PayPal költségét is. (Ez a plusz fél euró.)
  • Rendelés leadásának utolsó lépése a paypal.com-ra vezet, azonban nem muszáj előleget fizetni. (Alul van link, ami visszavisz a Spielmaterial oldalára.) A biztonság kedvéért a megjegyzés mezőbe mindig odaírtam, hogy csak a szállítási költségre vagyunk kíváncsiak, illetve majd egyben lesz fizetve, ha a részvevők átutalták a bankszámlámra a részüket.
  • Ha megvan a végleges lista, akkor megér még egy kérdést, hogy pár plusz tétel belefér-e ugyanabba a postaköltségbe, illetve ha kiveszünk egy-két nem túl fontos dolgot, akkor csökken-e esetleg a postaköltség.
  • A pénz esti elküldése utáni nap írták, hogy küldik ASAP a csomagot, ami az üzenet utáni negyedik munkanapon meg is érkezett a kért budapesti címre.
  • Próbáltam a Piatniknál is érdeklődni, hogy adnak-e „pótalkatrészeket” (igaz, nem egy-két darabról volt szó, hanem hetvenről), de válaszra sem méltattak.
  • Talán az ötödik rendelés volt az, aminél mindenki elfogadta a szállítási költség ráeső részét. Az eladói oldalon végig türelmesek voltak a sok leadott, majd lemondott rendelés ellenére is.
  • Az alapszínek (fehér, zöld, kék, sárga, piros, barna) szinte teljesen megegyeztek a magyar kiadású Catan színeivel. Kis eltérés a barna esetén volt. Ez sötétebb volt valamivel a Catanosnál.

Elveszett PRS-650 jegyzetek visszaállítása

A múltkor lefagyás után nagyrészt sikerült visszaállítani az elveszett jegyzeteimet. Rögtön az újraindítás után kivettem a memóriakártyát, hogy ne rontsam tovább a helyzetet. Ezután a korábbi adatmentős írásomban ismertetett módon lementettem az egész kártya tartalmát későbbi elemzésre.

Az mentett képfájlt a phororec-nek adtam oda, elég sok fájl hozott vissza. Az eredeti fájlnév nem maradt meg, úgy kellett összevadászni az ömlesztett fájlokból a database/cache/cacheExt.xml és a Digital Editions gyökérkönyvtárban lévő, annot kiterjesztésű, egyébként szintén XML fájlokra hasonlító fájlokat. Az XML-ek gyökértag-jére érdemes keresni („<cacheExt” és „<annotationSet”). A két fájl közül a cacheExt.xml fájlba kerülnek olvasható módon a jegyzetek, de ez valószínűleg – ahogy a neve is mutatja – csak egy cache, a tényleges jegyzeteket az annot fájl tárolja.

A photorec a fájlok legutolsó változatán kívül elég sok régebbi változatot is kibányászott a memóriakártya eldugott szektoraiból. Ezek közül a legnagyobbakat választottam ki. A fájlok mérete arányos a benne lévő jegyzetek számával.

Rossz hír, hogy ezt a két fájlt szinkronban kell visszaállítani. Ez nekem nem akart összejönni. Az .annot fájl törlése után a cacheExt-ből is törlődtek az annotációk, viszont az annot fájl visszaállítása után nem generálódik újra a cache, hanem az annot fájl tartalma is törlődik. (Elég érdekes viselkedés egy cache-hez képest.) A kettő egy időben történő visszaállításakor pedig némelyik jegyzet nem volt kijelölve a szövegben, csak a jegyzetlistán jelent meg a hozzá tartozó bejegyzés.

Az annot fájlból és a könyvből kiindulva valószínűleg le lehetne generálni a cacheExt tartalmát is, ha máshogy nem is, a firmware forráskódja alapján biztosan, de ennyit nem ért meg a dolog. Ehelyett inkább kinyomtattam a legnagyobb cacheExt fájl releváns részeit és kézzel felvettem újra a jegyzeteket.

A cacheExt-ben ezek a részek az érdekesek:

<annotation date="Tue, 16 Nov 2010 22:10:42 GMT" name="..." page="1" pageOffset="1"
	pages="948" part="0" scale="2" synced="true" dpi="167" width="584" height="754" 
	layoutVersion="1">
		<start>...</start>
		<end>...</end>
		<comment></comment>
</annotation>

A name attribútum tárolja a kijelölt szöveget, a page az oldalszámot (0 jelöli az első oldalt), a scale a kijelöléskori nagyítást (0 = S, 1 = M, 2 = L), a pageOffset pedig az adott fizikai oldalon belüli oldalt (nagyítás esetén van jelentősége).

Képek, rajzok visszaállítása

A rajzokat külön SVG fájlok tárolják, az XML-ből csak hivatkozás van rájuk. A hivatkozás csak fájlnévvel történik, ami eléggé kellemetlen, mivel a photorec nem állítja vissza az eredeti fájlnevet.

A cacheExt-beli tag hasonló az előzőhöz:

<freehand date="Sun, 28 Nov 2010 18:16:31 GMT" name="..." page="785" pageOffset="0"
	pages="948" part="0" scale="0" synced="true" dpi="167" width="584" height="754"
	layoutVersion="1">
		<svgFile width="584" height="754">1290968182066.77.svg</svgFile>
		<thumbFile width="115" height="149">1290968182066.77.jpg</thumbFile>
		<mark>...</mark>
		<comment></comment>
</freehand>

A jpg fájl tartalmazza a rajz mögötti könyvoldal képét is, ami alapján találgatással össze lehet párosítani a photorec által megtalált képeket az XML freehand bejegyzéseivel. A könyvből ki kell keresni a page attribútumokban szereplő oldalakat, majd az ezekhez hasonlító képet. Ezek a képek nagyon kicsik (kb. 100 x 150 képpont), rossz minőségűek, de nekem sokat segítettek, mert esetemben az ábrák többnyire csak egy pipából álltak a már olvasott fejezetek elején, és ezek az oldalak változatosabb képet mutattak, mint a folytonos szöveg a fejezetek további oldalain. Érdemes figyelni (nem sorkizárt szöveg esetén) a sorok végére rajzolható görbét, a fejezetcím hosszát, ha eltérő, akkor a páros-páratlan oldalak közti fejléc, illetve lábléc különbségét, ábrák alakját.

Utoljára olvasott oldal visszaállítása

A cacheExt fájlból a következő részlet az érdekes:

<text path="...pdf" preventDelete="true" opened="true">
	<currentPosition date="Fri, 07 Jan 2011 13:32:25 GMT" name="undefined" 
		page="552" pageOffset="0" pages="948" part="0" scale="0" synced="false"
		dpi="167" width="584" height="754" layoutVersion="1">
			<mark>I3BkZmxvYyg5OWYwLDU1MikA</mark>
			<comment></comment>
	</currentPosition>
	...

Itt is a korábban már ismertetett page, scale és a pageOffset attribútumokra kell figyelni.

Fontok beágyazása epub fájlokba – kicsit részletesebben

Amire szükség lesz:

A fontok tar.gz-ben érkeznek, ami például a 7-Zippel kicsomagolható. A kitömörített könyvtárból a következő fájlokra lesz szükség:

  • LiberationSerif-BoldItalic.ttf
  • LiberationSerif-Bold.ttf
  • LiberationSerif-Italic.ttf
  • LiberationSerif-Regular.ttf
    • Ízlés szerint persze lehet más fontokat is használni. A Linux Libertine fonttal a Sony PRS-650 esetében nem volt szerencsém, az eszköz nem kezelte megfelelően, néha kimaradtak bekezdések a könyvekből. A font lecserélése megoldotta a problémát. A Liberation fonttal még nem volt problémám, a Sony jól kezeli őket.

      A Sigil telepítése után nyissuk meg az epub fájlt a File menü Open menüpontjával. A megnyitott fájl Book Browser ablakában a Fonts mappára kattintva jobbklikk, Add Existsing Items. Keressük meg a fenti négy ttf fájl, és adjuk hozzá a listához.

      Ezután szintén Book Browser ablak, jobbklikk a Styles könyvtáron, Add New Item. Ha jól csináltuk, akkor létrejön egy Style0001.css nevű fájl. Duplaklikk a fájlnévre, majd másoljuk be az előző bejegyzésben is szereplő CSS tartalmat:

      @font-face {
      	font-family: "LiberationSerif";
      	font-style: normal;
      	font-weight: normal;
      	src:url(../Fonts/LiberationSerif-Regular.ttf)
      }
      
      @font-face {
      	font-family: "LiberationSerif";
      	font-style: italic;
      	font-weight: normal;
      	src:url(../Fonts/LiberationSerif-Italic.ttf)
      }
      
      @font-face {
      	font-family: "LiberationSerif";
      	font-style: normal;
      	font-weight: bold;
      	src:url(../Fonts/LiberationSerif-Bold.ttf)
      }
      
      @font-face {
      	font-family: "LiberationSerif";
      	font-style: italic;
      	font-weight: bold;
      	src:url(../Fonts/LiberationSerif-BoldItalic.ttf)
      }
      
      body { 
      	font-family: "LiberationSerif"
      }
      

      A CSS-ben az src:url kezdetű sorokban lévő fájlnévnek egyeznie kell a fenti listában szereplő fájlnevekkel. Ez alapesetben így van, ha mégsem működne valami, akkor ezt mindenképp ellenőrizzük, illetve ha más fontot használnánk, akkor figyeljünk rá.

      Ha ezzel megvagyunk, akkor a Book Browser ablakban nyissuk meg az xhtml fájlokat, majd váltsunk át Code View-ra (View menü / Code View menüpont, vagy F11). A fájlok elején, a <head> és </head> közé helyezzük el a következő tag-et:

      <link href="../Styles/Style0001.css" rel="stylesheet" type="text/css" />
      

      Például:

      <?xml version="1.0"?>
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
        "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
      
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
      	<title>Liberation Serif Font Test</title>
      	<link href="../Styles/Style0001.css" rel="stylesheet" type="text/css" />
      </head>
      
      <body>
        <p>GYÜMÖLCSVÉDŐ ÁGYÚFŰNYÍRÓ</p>
        <p>Gyümölcsvédő ágyúfűnyíró</p>
      </body>
      </html>
      

      A <head></head> között meglévő tartalom maradjon meg, azt ne töröljük.

      Fontos, hogy beszúrt tag-ben a href után lévő fájlnévnek egyeznie kell a korábban létrehozott CSS nevével (Style0001.css), valamint a fenti link tag-nek minden xhtml fájlban szerepelnie kell.

      Ha kész, akkor a Tools menü Validate Epub menüvel ellenőrizhető, hogy az eredmény megfelel-e az epub szabványnak. Jó tudni, hogy a validátor (jelenleg) sajnos nem ellenőrzi a CSS-ben lévő hivatkozásokat. Az ellenőrzést érdemes a módosítások megkezdése előtt is, hogy a forrásban lévő hibákkal ne itt találkozzunk először.

      Végül innen letölthető egy mintaepub, ami tartalmazza a fentieket. Kérdés nyugodtan jöhet kommentben vagy e-mailben.

Réges-régi kölcsönzések

Ha megvan még a régi GAMF-os vonalkódod (vagy esetleg fejből emlékszel rá), akkor könyvtár http://crux.kefo.hu/ címen, kívülről is elérhető webes felületén megnézheted a kölcsönzéseid listáját. Az „Olvasójegyem” menüpont alatt lehet belépni, a felhasználónév és a jelszó is a vonalkód. A kezdő nullák is fontosak.

Sony PRS-650 lefagyások

Az utóbbi időben három-négynaponta lefagy a PRS-650. Ha jól sejtem, kikapcsolásnál omlik össze, és újra már nem lehet bekapcsolni. Reset segít, de idegesítő. A mai napig semmi komolyabb következménye nem volt a dolognak. Ma viszont elveszett egy könyvbe írt 150 jegyzetem, és jó pár könyv esetén elfelejtődött az utolsó olvasott oldal. Egy korábbi állapotra álltak vissza, nem az első oldalra.

Tervezgetem egy ideje, hogy írok hozzá backup szkriptet. Nem gondoltam volna, hogy ilyen gyorsan szükségem lesz (lenne) rá.

Fontok beágyazása epub fájlokba

CSS a Liberation Serif betűkészlet epub fájlokba ágyazásához, amely font tartalmazza a magyar ékezetes karaktereket is:

@font-face{
	font-family:"LiberationSerif";
	font-style:normal;
	font-weight:normal;
	src:url(../Fonts/LiberationSerif-Regular.ttf)
}
@font-face{
	font-family:"LiberationSerif";
	font-style:italic;
	font-weight:normal;
	src:url(../Fonts/LiberationSerif-Italic.ttf)
}

@font-face{
	font-family:"LiberationSerif";
	font-style:normal;
	font-weight:bold;
	src:url(../Fonts/LiberationSerif-Bold.ttf)
}

@font-face {
	font-style: italic;
	font-family:"LiberationSerif";
	font-weight: bold;
	src:url(../Fonts/LiberationSerif-BoldItalic.ttf)
}

body { 
	font-family:"LiberationSerif"
}

Végül a CSS-t behúzó HTML tag:

<link href="../Styles/Style0001.css" rel="stylesheet" type="text/css" />

Sonatype Maven könyvek epub formátumban

Egy augusztusi blogbejegyzés szerint a Sonatype Maven by Example című könyve letölthető epub formátumban is, azonban a bejegyzésben lévő link már él. Ettől függetlenül a könyv github-os repositoryjából letölthető a forrás, amiből Maven segítségével könnyedén elkészíthető az epub fájl.

Sajnos az így előállított epub nem tökéletes, az epubcheck talál benne néhány hibát. Többségüket a Sigil képes automatikusan javítani (hiányzó, egyébként nem használt, többnyire pdf fájlokra mutató hivatkozások törlése a content.opf-ből), valamint a pár hiányzó képet kézzel is berakhatjuk az epub fájlba (még Sigillel történő megnyitás előtt!). A PRS-650-esen a borítóval voltak még bajaim. A képet kisebbre méretezve ez is megoldódott. Valamint még néhány, többnyire üres xml:lang attribútumot kellett törölnöm, hogy érvényes legyen az epub fájl.

Egyébként nem biztos, hogy Sigillel érdemes ezeket a hibákat javítani. Nálam a 0.3.4-es verzió elrontotta a tartalomjegyzéket. A javítás nem volt bonyolult, a projekt target könyvtárából kikerestem a toc.ncx-et, kézzel visszamásoltam, majd javítottam (mindet cserél funkció) a Sigil által elmozgatott fájlokra mutató hivatkozásokat.

Jó hír, hogy a Maven By Example könyvön kívül másik három Sonatype könyv is elérhető epub formátumban. Repositoryk sorban:

Developing with Eclipse and Maven: A User's Guide to m2eclipse
https://github.com/sonatype/m2eclipse-book
Maven by Example: An introduction to Apache Maven
https://github.com/sonatype/maven-example-en
Maven: The Complete Reference
https://github.com/sonatype/maven-reference-en
Repository Management with Nexus
https://github.com/sonatype/nexus-book

Letöltés és mvn install után az epubos alprojekt target mappájának mélyén megtalálható valahol az elkészített epub fájl. A letöltéshez és a fordításhoz megfelelő mennyiségű szabad hely nem árt. Némelyik projekt fordítás utáni mérete alulról súrolja a két gigabájtot.

A Sonatype-os repositoryk között egyéb olvasnivalókat is találhatunk. Ott van a Maven könyv régebbi változata, egy Maven szakácskönyv, valamint egy Hudson könyv első fejezete, de a fizetős Sonatype programokhoz tartozó dokumentáció is akad.

Tartalom átvétel