]> pere.pagekite.me Git - homepage.git/blob - blog/archive/2023/11/index.html
Generated.
[homepage.git] / blog / archive / 2023 / 11 / index.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
4 <head>
5 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
6 <title>Petter Reinholdtsen: entries from November 2023</title>
7 <link rel="stylesheet" type="text/css" media="screen" href="https://people.skolelinux.org/pere/blog/style.css" />
8 <link rel="stylesheet" type="text/css" media="screen" href="https://people.skolelinux.org/pere/blog/vim.css" />
9 <link rel="alternate" title="RSS Feed" href="11.rss" type="application/rss+xml" />
10 </head>
11 <body>
12 <!-- XML FEED -->
13 <div class="title">
14 <h1>
15 <a href="https://people.skolelinux.org/pere/blog/">Petter Reinholdtsen</a>
16
17 </h1>
18
19 </div>
20
21
22 <h3>Entries from November 2023.</h3>
23
24 <div class="entry">
25 <div class="title">
26 <a href="https://people.skolelinux.org/pere/blog/New_and_improved_sqlcipher_in_Debian_for_accessing_Signal_database.html">New and improved sqlcipher in Debian for accessing Signal database</a>
27 </div>
28 <div class="date">
29 12th November 2023
30 </div>
31 <div class="body">
32 <p>For a while now I wanted to have direct access to the
33 <a href="https://signal.org/">Signal</a> database of messages and
34 channels of my Desktop edition of Signal. I prefer the enforced end
35 to end encryption of Signal these days for my communication with
36 friends and family, to increase the level of safety and privacy as
37 well as raising the cost of the mass surveillance government and
38 non-government entities practice these days. In August I came across
39 a nice
40 <a href="https://www.yoranbrondsema.com/post/the-guide-to-extracting-statistics-from-your-signal-conversations/">recipe
41 on how to use sqlcipher to extract statistics from the Signal
42 database</a> explaining how to do this. Unfortunately this did not
43 work with the version of sqlcipher in Debian. The
44 <a href="http://tracker.debian.org/sqlcipher/">sqlcipher</a>
45 package is a "fork" of the sqlite package with added support for
46 encrypted databases. Sadly the current Debian maintainer
47 <a href="https://bugs.debian.org/961598">announced more than three
48 years ago that he did not have time to maintain sqlcipher</a>, so it
49 seemed unlikely to be upgraded by the maintainer. I was reluctant to
50 take on the job myself, as I have very limited experience maintaining
51 shared libraries in Debian. After waiting and hoping for a few
52 months, I gave up the last week, and set out to update the package. In
53 the process I orphaned it to make it more obvious for the next person
54 looking at it that the package need proper maintenance.</p>
55
56 <p>The version in Debian was around five years old, and quite a lot of
57 changes had taken place upstream into the Debian maintenance git
58 repository. After spending a few days importing the new upstream
59 versions, realising that upstream did not care much for SONAME
60 versioning as I saw library symbols being both added and removed with
61 minor version number changes to the project, I concluded that I had to
62 do a SONAME bump of the library package to avoid surprising the
63 reverse dependencies. I even added a simple
64 autopkgtest script to ensure the package work as intended. Dug deep
65 into the hole of learning shared library maintenance, I set out a few
66 days ago to upload the new version to Debian experimental to see what
67 the quality assurance framework in Debian had to say about the result.
68 The feedback told me the pacakge was not too shabby, and yesterday I
69 uploaded the latest version to Debian unstable. It should enter
70 testing today or tomorrow, perhaps delayed by
71 <a href="https://bugs.debian.org/1055812">a small library
72 transition</a>.</p>
73
74 <p>Armed with a new version of sqlcipher, I can now have a look at the
75 SQL database in ~/.config/Signal/sql/db.sqlite. First, one need to
76 fetch the encryption key from the Signal configuration using this
77 simple JSON extraction command:</p>
78
79 <pre>/usr/bin/jq -r '."key"' ~/.config/Signal/config.json</pre>
80
81 <p>Assuming the result from that command is 'secretkey', which is a
82 hexadecimal number representing the key used to encrypt the database.
83 Next, one can now connect to the database and inject the encryption
84 key for access via SQL to fetch information from the database. Here
85 is an example dumping the database structure:</p>
86
87 <pre>
88 % sqlcipher ~/.config/Signal/sql/db.sqlite
89 sqlite> PRAGMA key = "x'secretkey'";
90 sqlite> .schema
91 CREATE TABLE sqlite_stat1(tbl,idx,stat);
92 CREATE TABLE conversations(
93 id STRING PRIMARY KEY ASC,
94 json TEXT,
95
96 active_at INTEGER,
97 type STRING,
98 members TEXT,
99 name TEXT,
100 profileName TEXT
101 , profileFamilyName TEXT, profileFullName TEXT, e164 TEXT, serviceId TEXT, groupId TEXT, profileLastFetchedAt INTEGER);
102 CREATE TABLE identityKeys(
103 id STRING PRIMARY KEY ASC,
104 json TEXT
105 );
106 CREATE TABLE items(
107 id STRING PRIMARY KEY ASC,
108 json TEXT
109 );
110 CREATE TABLE sessions(
111 id TEXT PRIMARY KEY,
112 conversationId TEXT,
113 json TEXT
114 , ourServiceId STRING, serviceId STRING);
115 CREATE TABLE attachment_downloads(
116 id STRING primary key,
117 timestamp INTEGER,
118 pending INTEGER,
119 json TEXT
120 );
121 CREATE TABLE sticker_packs(
122 id TEXT PRIMARY KEY,
123 key TEXT NOT NULL,
124
125 author STRING,
126 coverStickerId INTEGER,
127 createdAt INTEGER,
128 downloadAttempts INTEGER,
129 installedAt INTEGER,
130 lastUsed INTEGER,
131 status STRING,
132 stickerCount INTEGER,
133 title STRING
134 , attemptedStatus STRING, position INTEGER DEFAULT 0 NOT NULL, storageID STRING, storageVersion INTEGER, storageUnknownFields BLOB, storageNeedsSync
135 INTEGER DEFAULT 0 NOT NULL);
136 CREATE TABLE stickers(
137 id INTEGER NOT NULL,
138 packId TEXT NOT NULL,
139
140 emoji STRING,
141 height INTEGER,
142 isCoverOnly INTEGER,
143 lastUsed INTEGER,
144 path STRING,
145 width INTEGER,
146
147 PRIMARY KEY (id, packId),
148 CONSTRAINT stickers_fk
149 FOREIGN KEY (packId)
150 REFERENCES sticker_packs(id)
151 ON DELETE CASCADE
152 );
153 CREATE TABLE sticker_references(
154 messageId STRING,
155 packId TEXT,
156 CONSTRAINT sticker_references_fk
157 FOREIGN KEY(packId)
158 REFERENCES sticker_packs(id)
159 ON DELETE CASCADE
160 );
161 CREATE TABLE emojis(
162 shortName TEXT PRIMARY KEY,
163 lastUsage INTEGER
164 );
165 CREATE TABLE messages(
166 rowid INTEGER PRIMARY KEY ASC,
167 id STRING UNIQUE,
168 json TEXT,
169 readStatus INTEGER,
170 expires_at INTEGER,
171 sent_at INTEGER,
172 schemaVersion INTEGER,
173 conversationId STRING,
174 received_at INTEGER,
175 source STRING,
176 hasAttachments INTEGER,
177 hasFileAttachments INTEGER,
178 hasVisualMediaAttachments INTEGER,
179 expireTimer INTEGER,
180 expirationStartTimestamp INTEGER,
181 type STRING,
182 body TEXT,
183 messageTimer INTEGER,
184 messageTimerStart INTEGER,
185 messageTimerExpiresAt INTEGER,
186 isErased INTEGER,
187 isViewOnce INTEGER,
188 sourceServiceId TEXT, serverGuid STRING NULL, sourceDevice INTEGER, storyId STRING, isStory INTEGER
189 GENERATED ALWAYS AS (type IS 'story'), isChangeCreatedByUs INTEGER NOT NULL DEFAULT 0, isTimerChangeFromSync INTEGER
190 GENERATED ALWAYS AS (
191 json_extract(json, '$.expirationTimerUpdate.fromSync') IS 1
192 ), seenStatus NUMBER default 0, storyDistributionListId STRING, expiresAt INT
193 GENERATED ALWAYS
194 AS (ifnull(
195 expirationStartTimestamp + (expireTimer * 1000),
196 9007199254740991
197 )), shouldAffectActivity INTEGER
198 GENERATED ALWAYS AS (
199 type IS NULL
200 OR
201 type NOT IN (
202 'change-number-notification',
203 'contact-removed-notification',
204 'conversation-merge',
205 'group-v1-migration',
206 'keychange',
207 'message-history-unsynced',
208 'profile-change',
209 'story',
210 'universal-timer-notification',
211 'verified-change'
212 )
213 ), shouldAffectPreview INTEGER
214 GENERATED ALWAYS AS (
215 type IS NULL
216 OR
217 type NOT IN (
218 'change-number-notification',
219 'contact-removed-notification',
220 'conversation-merge',
221 'group-v1-migration',
222 'keychange',
223 'message-history-unsynced',
224 'profile-change',
225 'story',
226 'universal-timer-notification',
227 'verified-change'
228 )
229 ), isUserInitiatedMessage INTEGER
230 GENERATED ALWAYS AS (
231 type IS NULL
232 OR
233 type NOT IN (
234 'change-number-notification',
235 'contact-removed-notification',
236 'conversation-merge',
237 'group-v1-migration',
238 'group-v2-change',
239 'keychange',
240 'message-history-unsynced',
241 'profile-change',
242 'story',
243 'universal-timer-notification',
244 'verified-change'
245 )
246 ), mentionsMe INTEGER NOT NULL DEFAULT 0, isGroupLeaveEvent INTEGER
247 GENERATED ALWAYS AS (
248 type IS 'group-v2-change' AND
249 json_array_length(json_extract(json, '$.groupV2Change.details')) IS 1 AND
250 json_extract(json, '$.groupV2Change.details[0].type') IS 'member-remove' AND
251 json_extract(json, '$.groupV2Change.from') IS NOT NULL AND
252 json_extract(json, '$.groupV2Change.from') IS json_extract(json, '$.groupV2Change.details[0].aci')
253 ), isGroupLeaveEventFromOther INTEGER
254 GENERATED ALWAYS AS (
255 isGroupLeaveEvent IS 1
256 AND
257 isChangeCreatedByUs IS 0
258 ), callId TEXT
259 GENERATED ALWAYS AS (
260 json_extract(json, '$.callId')
261 ));
262 CREATE TABLE sqlite_stat4(tbl,idx,neq,nlt,ndlt,sample);
263 CREATE TABLE jobs(
264 id TEXT PRIMARY KEY,
265 queueType TEXT STRING NOT NULL,
266 timestamp INTEGER NOT NULL,
267 data STRING TEXT
268 );
269 CREATE TABLE reactions(
270 conversationId STRING,
271 emoji STRING,
272 fromId STRING,
273 messageReceivedAt INTEGER,
274 targetAuthorAci STRING,
275 targetTimestamp INTEGER,
276 unread INTEGER
277 , messageId STRING);
278 CREATE TABLE senderKeys(
279 id TEXT PRIMARY KEY NOT NULL,
280 senderId TEXT NOT NULL,
281 distributionId TEXT NOT NULL,
282 data BLOB NOT NULL,
283 lastUpdatedDate NUMBER NOT NULL
284 );
285 CREATE TABLE unprocessed(
286 id STRING PRIMARY KEY ASC,
287 timestamp INTEGER,
288 version INTEGER,
289 attempts INTEGER,
290 envelope TEXT,
291 decrypted TEXT,
292 source TEXT,
293 serverTimestamp INTEGER,
294 sourceServiceId STRING
295 , serverGuid STRING NULL, sourceDevice INTEGER, receivedAtCounter INTEGER, urgent INTEGER, story INTEGER);
296 CREATE TABLE sendLogPayloads(
297 id INTEGER PRIMARY KEY ASC,
298
299 timestamp INTEGER NOT NULL,
300 contentHint INTEGER NOT NULL,
301 proto BLOB NOT NULL
302 , urgent INTEGER, hasPniSignatureMessage INTEGER DEFAULT 0 NOT NULL);
303 CREATE TABLE sendLogRecipients(
304 payloadId INTEGER NOT NULL,
305
306 recipientServiceId STRING NOT NULL,
307 deviceId INTEGER NOT NULL,
308
309 PRIMARY KEY (payloadId, recipientServiceId, deviceId),
310
311 CONSTRAINT sendLogRecipientsForeignKey
312 FOREIGN KEY (payloadId)
313 REFERENCES sendLogPayloads(id)
314 ON DELETE CASCADE
315 );
316 CREATE TABLE sendLogMessageIds(
317 payloadId INTEGER NOT NULL,
318
319 messageId STRING NOT NULL,
320
321 PRIMARY KEY (payloadId, messageId),
322
323 CONSTRAINT sendLogMessageIdsForeignKey
324 FOREIGN KEY (payloadId)
325 REFERENCES sendLogPayloads(id)
326 ON DELETE CASCADE
327 );
328 CREATE TABLE preKeys(
329 id STRING PRIMARY KEY ASC,
330 json TEXT
331 , ourServiceId NUMBER
332 GENERATED ALWAYS AS (json_extract(json, '$.ourServiceId')));
333 CREATE TABLE signedPreKeys(
334 id STRING PRIMARY KEY ASC,
335 json TEXT
336 , ourServiceId NUMBER
337 GENERATED ALWAYS AS (json_extract(json, '$.ourServiceId')));
338 CREATE TABLE badges(
339 id TEXT PRIMARY KEY,
340 category TEXT NOT NULL,
341 name TEXT NOT NULL,
342 descriptionTemplate TEXT NOT NULL
343 );
344 CREATE TABLE badgeImageFiles(
345 badgeId TEXT REFERENCES badges(id)
346 ON DELETE CASCADE
347 ON UPDATE CASCADE,
348 'order' INTEGER NOT NULL,
349 url TEXT NOT NULL,
350 localPath TEXT,
351 theme TEXT NOT NULL
352 );
353 CREATE TABLE storyReads (
354 authorId STRING NOT NULL,
355 conversationId STRING NOT NULL,
356 storyId STRING NOT NULL,
357 storyReadDate NUMBER NOT NULL,
358
359 PRIMARY KEY (authorId, storyId)
360 );
361 CREATE TABLE storyDistributions(
362 id STRING PRIMARY KEY NOT NULL,
363 name TEXT,
364
365 senderKeyInfoJson STRING
366 , deletedAtTimestamp INTEGER, allowsReplies INTEGER, isBlockList INTEGER, storageID STRING, storageVersion INTEGER, storageUnknownFields BLOB, storageNeedsSync INTEGER);
367 CREATE TABLE storyDistributionMembers(
368 listId STRING NOT NULL REFERENCES storyDistributions(id)
369 ON DELETE CASCADE
370 ON UPDATE CASCADE,
371 serviceId STRING NOT NULL,
372
373 PRIMARY KEY (listId, serviceId)
374 );
375 CREATE TABLE uninstalled_sticker_packs (
376 id STRING NOT NULL PRIMARY KEY,
377 uninstalledAt NUMBER NOT NULL,
378 storageID STRING,
379 storageVersion NUMBER,
380 storageUnknownFields BLOB,
381 storageNeedsSync INTEGER NOT NULL
382 );
383 CREATE TABLE groupCallRingCancellations(
384 ringId INTEGER PRIMARY KEY,
385 createdAt INTEGER NOT NULL
386 );
387 CREATE TABLE IF NOT EXISTS 'messages_fts_data'(id INTEGER PRIMARY KEY, block BLOB);
388 CREATE TABLE IF NOT EXISTS 'messages_fts_idx'(segid, term, pgno, PRIMARY KEY(segid, term)) WITHOUT ROWID;
389 CREATE TABLE IF NOT EXISTS 'messages_fts_content'(id INTEGER PRIMARY KEY, c0);
390 CREATE TABLE IF NOT EXISTS 'messages_fts_docsize'(id INTEGER PRIMARY KEY, sz BLOB);
391 CREATE TABLE IF NOT EXISTS 'messages_fts_config'(k PRIMARY KEY, v) WITHOUT ROWID;
392 CREATE TABLE edited_messages(
393 messageId STRING REFERENCES messages(id)
394 ON DELETE CASCADE,
395 sentAt INTEGER,
396 readStatus INTEGER
397 , conversationId STRING);
398 CREATE TABLE mentions (
399 messageId REFERENCES messages(id) ON DELETE CASCADE,
400 mentionAci STRING,
401 start INTEGER,
402 length INTEGER
403 );
404 CREATE TABLE kyberPreKeys(
405 id STRING PRIMARY KEY NOT NULL,
406 json TEXT NOT NULL, ourServiceId NUMBER
407 GENERATED ALWAYS AS (json_extract(json, '$.ourServiceId')));
408 CREATE TABLE callsHistory (
409 callId TEXT PRIMARY KEY,
410 peerId TEXT NOT NULL, -- conversation id (legacy) | uuid | groupId | roomId
411 ringerId TEXT DEFAULT NULL, -- ringer uuid
412 mode TEXT NOT NULL, -- enum "Direct" | "Group"
413 type TEXT NOT NULL, -- enum "Audio" | "Video" | "Group"
414 direction TEXT NOT NULL, -- enum "Incoming" | "Outgoing
415 -- Direct: enum "Pending" | "Missed" | "Accepted" | "Deleted"
416 -- Group: enum "GenericGroupCall" | "OutgoingRing" | "Ringing" | "Joined" | "Missed" | "Declined" | "Accepted" | "Deleted"
417 status TEXT NOT NULL,
418 timestamp INTEGER NOT NULL,
419 UNIQUE (callId, peerId) ON CONFLICT FAIL
420 );
421 [ dropped all indexes to save space in this blog post ]
422 CREATE TRIGGER messages_on_view_once_update AFTER UPDATE ON messages
423 WHEN
424 new.body IS NOT NULL AND new.isViewOnce = 1
425 BEGIN
426 DELETE FROM messages_fts WHERE rowid = old.rowid;
427 END;
428 CREATE TRIGGER messages_on_insert AFTER INSERT ON messages
429 WHEN new.isViewOnce IS NOT 1 AND new.storyId IS NULL
430 BEGIN
431 INSERT INTO messages_fts
432 (rowid, body)
433 VALUES
434 (new.rowid, new.body);
435 END;
436 CREATE TRIGGER messages_on_delete AFTER DELETE ON messages BEGIN
437 DELETE FROM messages_fts WHERE rowid = old.rowid;
438 DELETE FROM sendLogPayloads WHERE id IN (
439 SELECT payloadId FROM sendLogMessageIds
440 WHERE messageId = old.id
441 );
442 DELETE FROM reactions WHERE rowid IN (
443 SELECT rowid FROM reactions
444 WHERE messageId = old.id
445 );
446 DELETE FROM storyReads WHERE storyId = old.storyId;
447 END;
448 CREATE VIRTUAL TABLE messages_fts USING fts5(
449 body,
450 tokenize = 'signal_tokenizer'
451 );
452 CREATE TRIGGER messages_on_update AFTER UPDATE ON messages
453 WHEN
454 (new.body IS NULL OR old.body IS NOT new.body) AND
455 new.isViewOnce IS NOT 1 AND new.storyId IS NULL
456 BEGIN
457 DELETE FROM messages_fts WHERE rowid = old.rowid;
458 INSERT INTO messages_fts
459 (rowid, body)
460 VALUES
461 (new.rowid, new.body);
462 END;
463 CREATE TRIGGER messages_on_insert_insert_mentions AFTER INSERT ON messages
464 BEGIN
465 INSERT INTO mentions (messageId, mentionAci, start, length)
466
467 SELECT messages.id, bodyRanges.value ->> 'mentionAci' as mentionAci,
468 bodyRanges.value ->> 'start' as start,
469 bodyRanges.value ->> 'length' as length
470 FROM messages, json_each(messages.json ->> 'bodyRanges') as bodyRanges
471 WHERE bodyRanges.value ->> 'mentionAci' IS NOT NULL
472
473 AND messages.id = new.id;
474 END;
475 CREATE TRIGGER messages_on_update_update_mentions AFTER UPDATE ON messages
476 BEGIN
477 DELETE FROM mentions WHERE messageId = new.id;
478 INSERT INTO mentions (messageId, mentionAci, start, length)
479
480 SELECT messages.id, bodyRanges.value ->> 'mentionAci' as mentionAci,
481 bodyRanges.value ->> 'start' as start,
482 bodyRanges.value ->> 'length' as length
483 FROM messages, json_each(messages.json ->> 'bodyRanges') as bodyRanges
484 WHERE bodyRanges.value ->> 'mentionAci' IS NOT NULL
485
486 AND messages.id = new.id;
487 END;
488 sqlite>
489 </pre>
490
491 <p>Finally I have the tool needed to inspect and process Signal
492 messages that I need, without using the vendor provided client. Now
493 on to transforming it to a more useful format.</p>
494
495 <p>As usual, if you use Bitcoin and want to show your support of my
496 activities, please send Bitcoin donations to my address
497 <b><a href="bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b</a></b>.</p>
498
499 </div>
500 <div class="tags">
501
502
503 Tags: <a href="https://people.skolelinux.org/pere/blog/tags/debian">debian</a>, <a href="https://people.skolelinux.org/pere/blog/tags/english">english</a>, <a href="https://people.skolelinux.org/pere/blog/tags/sikkerhet">sikkerhet</a>, <a href="https://people.skolelinux.org/pere/blog/tags/surveillance">surveillance</a>.
504
505
506 </div>
507 </div>
508 <div class="padding"></div>
509
510 <div class="entry">
511 <div class="title">
512 <a href="https://people.skolelinux.org/pere/blog/New_chrpath_release_0_17.html">New chrpath release 0.17</a>
513 </div>
514 <div class="date">
515 10th November 2023
516 </div>
517 <div class="body">
518 <p>The chrpath package provide a simple command line tool to remove or
519 modify the rpath or runpath of compiled ELF program. It is almost 10
520 years since I updated the code base, but I stumbled over the tool
521 today, and decided it was time to move the code base from Subversion
522 to git and find a new home for it, as the previous one (Debian Alioth)
523 has been shut down. I decided to go with
524 <a href="https://codeberg.org/">Codeberg</a> this time, as it is my git
525 service of choice these days, did a quick and dirty migration to git
526 and updated the code with a few patches I found in the Debian bug
527 tracker. These are the release notes:</p>
528
529 <p>New in 0.17 released 2023-11-10:</p>
530
531 <ul>
532 <li>Moved project to Codeberg, as Alioth is shut down.</li>
533 <li>Add Solaris support (use &lt;sys/byteorder.h> instead of &lt;byteswap.h>).
534 Patch from Rainer Orth.</li>
535 <li>Added missing newline from printf() line. Patch from Frank Dana.</li>
536 <li>Corrected handling of multiple ELF sections. Patch from Frank Dana.</li>
537 <li>Updated build rules for .deb. Partly based on patch from djcj.</li>
538 </ul>
539
540 <p>The latest edition is tagged and available from
541 <a href="https://codeberg.org/pere/chrpath">https://codeberg.org/pere/chrpath</a>.
542
543 <p>As usual, if you use Bitcoin and want to show your support of my
544 activities, please send Bitcoin donations to my address
545 <b><a href="bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b</a></b>.</p>
546
547 </div>
548 <div class="tags">
549
550
551 Tags: <a href="https://people.skolelinux.org/pere/blog/tags/chrpath">chrpath</a>, <a href="https://people.skolelinux.org/pere/blog/tags/debian">debian</a>, <a href="https://people.skolelinux.org/pere/blog/tags/english">english</a>.
552
553
554 </div>
555 </div>
556 <div class="padding"></div>
557
558 <div class="entry">
559 <div class="title">
560 <a href="https://people.skolelinux.org/pere/blog/Test_framework_for_DocBook_processors___formatters.html">Test framework for DocBook processors / formatters</a>
561 </div>
562 <div class="date">
563 5th November 2023
564 </div>
565 <div class="body">
566 <p>All the books I have published so far has been using
567 <a href="https://docbook.org/">DocBook</a> somewhere in the process.
568 For the first book, the source format was DocBook, while for every
569 later book it was an intermediate format used as the stepping stone to
570 be able to present the same manuscript in several formats, on paper,
571 as ebook in ePub format, as a HTML page and as a PDF file either for
572 paper production or for Internet consumption. This is made possible
573 with a wide variety of free software tools with DocBook support in
574 Debian. The source format of later books have been docx via rst,
575 Markdown, Filemaker and Asciidoc, and for all of these I was able to
576 generate a suitable DocBook file for further processing using
577 <a href="https://tracker.debian.org/pkg/pandoc">pandoc</a>,
578 <a href="https://tracker.debian.org/pkg/asciidoc">a2x</a> and
579 <a href="https://tracker.debian.org/pkg/asciidoctor">asciidoctor</a>,
580 as well as rendering using
581 <a href="https://tracker.debian.org/pkg/xmlto">xmlto</a>,
582 <a href="https://tracker.debian.org/pkg/dbtoepub">dbtoepub</a>,
583 <a href="https://tracker.debian.org/pkg/dblatex">dblatex</a>,
584 <a href="https://tracker.debian.org/pkg/docbook-xsl">docbook-xsl</a> and
585 <a href="https://tracker.debian.org/pkg/fop">fop</a>.</p>
586
587 <p>Most of the <a href="http://www.hungry.com/~pere/publisher/">books I
588 have published</a> are translated books, with English as the source
589 language. The use of
590 <a href="https://tracker.debian.org/pkg/po4a">po4a</a> to
591 handle translations using the gettext PO format has been a blessing,
592 but publishing translated books had triggered the need to ensure the
593 DocBook tools handle relevant languages correctly. For every new
594 language I have published, I had to submit patches dblatex, dbtoepub
595 and docbook-xsl fixing incorrect language and country specific issues
596 in the framework themselves. Typically this has been missing keywords
597 like 'figure' or sort ordering of index entries. After a while it
598 became tiresome to only discover issues like this by accident, and I
599 decided to write a DocBook "test framework" exercising various
600 features of DocBook and allowing me to see all features exercised for
601 a given language. It consist of a set of DocBook files, a version 4
602 book, a version 5 book, a v4 book set, a v4 selection of problematic
603 tables, one v4 testing sidefloat and finally one v4 testing a book of
604 articles. The DocBook files are accompanied with a set of build rules
605 for building PDF using dblatex and docbook-xsl/fop, HTML using xmlto
606 or docbook-xsl and epub using dbtoepub. The result is a set of files
607 visualizing footnotes, indexes, table of content list, figures,
608 formulas and other DocBook features, allowing for a quick review on
609 the completeness of the given locale settings. To build with a
610 different language setting, all one need to do is edit the lang= value
611 in the .xml file to pick a different ISO 639 code value and run
612 'make'.</p>
613
614 <p>The <a href="https://codeberg.org/pere/docbook-example/">test framework
615 source code</a> is available from Codeberg, and a generated set of
616 presentations of the various examples is available as Codeberg static
617 web pages at
618 <a href="https://pere.codeberg.page/docbook-example/">https://pere.codeberg.page/docbook-example/</a>.
619 Using this test framework I have been able to discover and report
620 several bugs and missing features in various tools, and got a lot of
621 them fixed. For example I got Northern Sami keywords added to both
622 docbook-xsl and dblatex, fixed several typos in Norwegian bokmål and
623 Norwegian Nynorsk, support for non-ascii title IDs added to pandoc,
624 Norwegian index sorting support fixed in xindy and initial Norwegian
625 Bokmål support added to dblatex. Some issues still remains, though.
626 Default index sorting rules are still broken in several tools, so the
627 Norwegian letters æ, ø and å are more often than not sorted properly
628 in the book index.</p>
629
630 <p>The test framework recently received some more polish, as part of
631 publishing my latest book. This book contained a lot of fairly
632 complex tables, which exposed bugs in some of the tools. This made me
633 add a new test file with various tables, as well as spend some time to
634 brush up the build rules. My goal is for the test framework to
635 exercise all DocBook features to make it easier to see which features
636 work with different processors, and hopefully get them all to support
637 the full set of DocBook features. Feel free to send patches to extend
638 the test set, and test it with your favorite DocBook processor.
639 Please visit these two URLs to learn more:</p>
640
641 <ul>
642 <li><a href="https://codeberg.org/pere/docbook-example/">https://codeberg.org/pere/docbook-example/</a></li>
643 <li><a href="https://pere.codeberg.page/docbook-example/">https://pere.codeberg.page/docbook-example/</a></li>
644 </ul>
645
646 <p>If you want to learn more on Docbook and translations, I recommend
647 having a look at the <a href="https://docbook.org/">the DocBook
648 web site</a>,
649 <a href="https://doccookbook.sourceforge.net/html/en/">the DoCookBook
650 site<a/> and my earlier blog post on
651 <a href="https://people.skolelinux.org/pere/blog/From_English_wiki_to_translated_PDF_and_epub_via_Docbook.html">how
652 the Skolelinux project process and translate documentation</a>, a talk I gave earlier this year on
653 <a href="https://www.nuug.no/aktiviteter/20230314-oversetting-og-publisering-av-b%c3%b8ker-med-fri-programvare/">how
654 to translate and publish books using free software</a> (Norwegian
655 only).</p>
656
657 <!--
658
659 https://github.com/docbook/xslt10-stylesheets/issues/205 (docbook-xsl: sme support)
660 https://bugs.debian.org/968437 (xindy: index sorting rules for nb/nn)
661 https://bugs.debian.org/856123 (pandoc: markdown to docbook with non-english titles)
662 https://bugs.debian.org/864813 (dblatex: missing nb words)
663 https://bugs.debian.org/756386 (dblatex: index sorting rules for nb/nn)
664 https://bugs.debian.org/796871 (dbtoepub: index sorting rules for nb/nn)
665 https://bugs.debian.org/792616 (dblatex: PDF metadata)
666 https://bugs.debian.org/686908 (docbook-xsl: index sorting rules for nb/nn)
667 https://sourceforge.net/tracker/?func=detail&atid=373747&aid=3556630&group_id=21935 (docbook-xsl: nb/nn support)
668 https://bugs.debian.org/684391 (dblatex: initial nb support)
669
670 -->
671
672 <p>As usual, if you use Bitcoin and want to show your support of my
673 activities, please send Bitcoin donations to my address
674 <b><a href="bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b</a></b>.</p>
675
676 </div>
677 <div class="tags">
678
679
680 Tags: <a href="https://people.skolelinux.org/pere/blog/tags/debian">debian</a>, <a href="https://people.skolelinux.org/pere/blog/tags/docbook">docbook</a>, <a href="https://people.skolelinux.org/pere/blog/tags/english">english</a>.
681
682
683 </div>
684 </div>
685 <div class="padding"></div>
686
687 <p style="text-align: right;"><a href="11.rss"><img src="https://people.skolelinux.org/pere/blog/xml.gif" alt="RSS Feed" width="36" height="14" /></a></p>
688 <div id="sidebar">
689
690
691
692 <h2>Archive</h2>
693 <ul>
694
695 <li>2023
696 <ul>
697
698 <li><a href="https://people.skolelinux.org/pere/blog/archive/2023/01/">January (3)</a></li>
699
700 <li><a href="https://people.skolelinux.org/pere/blog/archive/2023/02/">February (1)</a></li>
701
702 <li><a href="https://people.skolelinux.org/pere/blog/archive/2023/04/">April (2)</a></li>
703
704 <li><a href="https://people.skolelinux.org/pere/blog/archive/2023/05/">May (3)</a></li>
705
706 <li><a href="https://people.skolelinux.org/pere/blog/archive/2023/06/">June (1)</a></li>
707
708 <li><a href="https://people.skolelinux.org/pere/blog/archive/2023/08/">August (1)</a></li>
709
710 <li><a href="https://people.skolelinux.org/pere/blog/archive/2023/09/">September (1)</a></li>
711
712 <li><a href="https://people.skolelinux.org/pere/blog/archive/2023/10/">October (1)</a></li>
713
714 <li><a href="https://people.skolelinux.org/pere/blog/archive/2023/11/">November (3)</a></li>
715
716 </ul></li>
717
718 <li>2022
719 <ul>
720
721 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/02/">February (1)</a></li>
722
723 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/03/">March (3)</a></li>
724
725 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/04/">April (2)</a></li>
726
727 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/06/">June (2)</a></li>
728
729 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/07/">July (1)</a></li>
730
731 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/09/">September (1)</a></li>
732
733 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/10/">October (1)</a></li>
734
735 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/12/">December (1)</a></li>
736
737 </ul></li>
738
739 <li>2021
740 <ul>
741
742 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/01/">January (2)</a></li>
743
744 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/02/">February (1)</a></li>
745
746 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/05/">May (1)</a></li>
747
748 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/06/">June (1)</a></li>
749
750 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/07/">July (3)</a></li>
751
752 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/08/">August (1)</a></li>
753
754 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/09/">September (1)</a></li>
755
756 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/10/">October (1)</a></li>
757
758 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/12/">December (1)</a></li>
759
760 </ul></li>
761
762 <li>2020
763 <ul>
764
765 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/02/">February (2)</a></li>
766
767 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/03/">March (2)</a></li>
768
769 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/04/">April (2)</a></li>
770
771 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/05/">May (3)</a></li>
772
773 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/06/">June (2)</a></li>
774
775 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/07/">July (1)</a></li>
776
777 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/09/">September (1)</a></li>
778
779 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/10/">October (1)</a></li>
780
781 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/11/">November (1)</a></li>
782
783 </ul></li>
784
785 <li>2019
786 <ul>
787
788 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/01/">January (4)</a></li>
789
790 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/02/">February (3)</a></li>
791
792 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/03/">March (3)</a></li>
793
794 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/05/">May (2)</a></li>
795
796 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/06/">June (5)</a></li>
797
798 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/07/">July (2)</a></li>
799
800 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/08/">August (1)</a></li>
801
802 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/09/">September (1)</a></li>
803
804 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/11/">November (1)</a></li>
805
806 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/12/">December (4)</a></li>
807
808 </ul></li>
809
810 <li>2018
811 <ul>
812
813 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/01/">January (1)</a></li>
814
815 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/02/">February (5)</a></li>
816
817 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/03/">March (5)</a></li>
818
819 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/04/">April (3)</a></li>
820
821 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/06/">June (2)</a></li>
822
823 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/07/">July (5)</a></li>
824
825 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/08/">August (3)</a></li>
826
827 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/09/">September (3)</a></li>
828
829 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/10/">October (5)</a></li>
830
831 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/11/">November (2)</a></li>
832
833 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/12/">December (4)</a></li>
834
835 </ul></li>
836
837 <li>2017
838 <ul>
839
840 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/01/">January (4)</a></li>
841
842 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/02/">February (3)</a></li>
843
844 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/03/">March (5)</a></li>
845
846 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/04/">April (2)</a></li>
847
848 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/06/">June (5)</a></li>
849
850 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/07/">July (1)</a></li>
851
852 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/08/">August (1)</a></li>
853
854 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/09/">September (3)</a></li>
855
856 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/10/">October (5)</a></li>
857
858 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/11/">November (3)</a></li>
859
860 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/12/">December (4)</a></li>
861
862 </ul></li>
863
864 <li>2016
865 <ul>
866
867 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/01/">January (3)</a></li>
868
869 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/02/">February (2)</a></li>
870
871 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/03/">March (3)</a></li>
872
873 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/04/">April (8)</a></li>
874
875 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/05/">May (8)</a></li>
876
877 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/06/">June (2)</a></li>
878
879 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/07/">July (2)</a></li>
880
881 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/08/">August (5)</a></li>
882
883 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/09/">September (2)</a></li>
884
885 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/10/">October (3)</a></li>
886
887 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/11/">November (8)</a></li>
888
889 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/12/">December (5)</a></li>
890
891 </ul></li>
892
893 <li>2015
894 <ul>
895
896 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/01/">January (7)</a></li>
897
898 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/02/">February (6)</a></li>
899
900 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/03/">March (1)</a></li>
901
902 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/04/">April (4)</a></li>
903
904 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/05/">May (3)</a></li>
905
906 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/06/">June (4)</a></li>
907
908 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/07/">July (6)</a></li>
909
910 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/08/">August (2)</a></li>
911
912 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/09/">September (2)</a></li>
913
914 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/10/">October (9)</a></li>
915
916 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/11/">November (6)</a></li>
917
918 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/12/">December (3)</a></li>
919
920 </ul></li>
921
922 <li>2014
923 <ul>
924
925 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/01/">January (2)</a></li>
926
927 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/02/">February (3)</a></li>
928
929 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/03/">March (8)</a></li>
930
931 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/04/">April (7)</a></li>
932
933 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/05/">May (1)</a></li>
934
935 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/06/">June (2)</a></li>
936
937 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/07/">July (2)</a></li>
938
939 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/08/">August (2)</a></li>
940
941 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/09/">September (5)</a></li>
942
943 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/10/">October (6)</a></li>
944
945 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/11/">November (3)</a></li>
946
947 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/12/">December (5)</a></li>
948
949 </ul></li>
950
951 <li>2013
952 <ul>
953
954 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/01/">January (11)</a></li>
955
956 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/02/">February (9)</a></li>
957
958 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/03/">March (9)</a></li>
959
960 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/04/">April (6)</a></li>
961
962 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/05/">May (9)</a></li>
963
964 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/06/">June (10)</a></li>
965
966 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/07/">July (7)</a></li>
967
968 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/08/">August (3)</a></li>
969
970 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/09/">September (5)</a></li>
971
972 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/10/">October (7)</a></li>
973
974 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/11/">November (9)</a></li>
975
976 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/12/">December (3)</a></li>
977
978 </ul></li>
979
980 <li>2012
981 <ul>
982
983 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/01/">January (7)</a></li>
984
985 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/02/">February (10)</a></li>
986
987 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/03/">March (17)</a></li>
988
989 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/04/">April (12)</a></li>
990
991 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/05/">May (12)</a></li>
992
993 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/06/">June (20)</a></li>
994
995 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/07/">July (17)</a></li>
996
997 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/08/">August (6)</a></li>
998
999 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/09/">September (9)</a></li>
1000
1001 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/10/">October (17)</a></li>
1002
1003 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/11/">November (10)</a></li>
1004
1005 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/12/">December (7)</a></li>
1006
1007 </ul></li>
1008
1009 <li>2011
1010 <ul>
1011
1012 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/01/">January (16)</a></li>
1013
1014 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/02/">February (6)</a></li>
1015
1016 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/03/">March (6)</a></li>
1017
1018 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/04/">April (7)</a></li>
1019
1020 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/05/">May (3)</a></li>
1021
1022 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/06/">June (2)</a></li>
1023
1024 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/07/">July (7)</a></li>
1025
1026 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/08/">August (6)</a></li>
1027
1028 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/09/">September (4)</a></li>
1029
1030 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/10/">October (2)</a></li>
1031
1032 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/11/">November (3)</a></li>
1033
1034 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/12/">December (1)</a></li>
1035
1036 </ul></li>
1037
1038 <li>2010
1039 <ul>
1040
1041 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/01/">January (2)</a></li>
1042
1043 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/02/">February (1)</a></li>
1044
1045 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/03/">March (3)</a></li>
1046
1047 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/04/">April (3)</a></li>
1048
1049 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/05/">May (9)</a></li>
1050
1051 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/06/">June (14)</a></li>
1052
1053 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/07/">July (12)</a></li>
1054
1055 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/08/">August (13)</a></li>
1056
1057 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/09/">September (7)</a></li>
1058
1059 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/10/">October (9)</a></li>
1060
1061 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/11/">November (13)</a></li>
1062
1063 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/12/">December (12)</a></li>
1064
1065 </ul></li>
1066
1067 <li>2009
1068 <ul>
1069
1070 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/01/">January (8)</a></li>
1071
1072 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/02/">February (8)</a></li>
1073
1074 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/03/">March (12)</a></li>
1075
1076 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/04/">April (10)</a></li>
1077
1078 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/05/">May (9)</a></li>
1079
1080 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/06/">June (3)</a></li>
1081
1082 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/07/">July (4)</a></li>
1083
1084 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/08/">August (3)</a></li>
1085
1086 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/09/">September (1)</a></li>
1087
1088 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/10/">October (2)</a></li>
1089
1090 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/11/">November (3)</a></li>
1091
1092 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/12/">December (3)</a></li>
1093
1094 </ul></li>
1095
1096 <li>2008
1097 <ul>
1098
1099 <li><a href="https://people.skolelinux.org/pere/blog/archive/2008/11/">November (5)</a></li>
1100
1101 <li><a href="https://people.skolelinux.org/pere/blog/archive/2008/12/">December (7)</a></li>
1102
1103 </ul></li>
1104
1105 </ul>
1106
1107
1108
1109 <h2>Tags</h2>
1110 <ul>
1111
1112 <li><a href="https://people.skolelinux.org/pere/blog/tags/3d-printer">3d-printer (19)</a></li>
1113
1114 <li><a href="https://people.skolelinux.org/pere/blog/tags/amiga">amiga (1)</a></li>
1115
1116 <li><a href="https://people.skolelinux.org/pere/blog/tags/aros">aros (1)</a></li>
1117
1118 <li><a href="https://people.skolelinux.org/pere/blog/tags/bankid">bankid (4)</a></li>
1119
1120 <li><a href="https://people.skolelinux.org/pere/blog/tags/betalkontant">betalkontant (9)</a></li>
1121
1122 <li><a href="https://people.skolelinux.org/pere/blog/tags/bitcoin">bitcoin (12)</a></li>
1123
1124 <li><a href="https://people.skolelinux.org/pere/blog/tags/bootsystem">bootsystem (17)</a></li>
1125
1126 <li><a href="https://people.skolelinux.org/pere/blog/tags/bsa">bsa (2)</a></li>
1127
1128 <li><a href="https://people.skolelinux.org/pere/blog/tags/chrpath">chrpath (3)</a></li>
1129
1130 <li><a href="https://people.skolelinux.org/pere/blog/tags/debian">debian (197)</a></li>
1131
1132 <li><a href="https://people.skolelinux.org/pere/blog/tags/debian edu">debian edu (159)</a></li>
1133
1134 <li><a href="https://people.skolelinux.org/pere/blog/tags/debian-handbook">debian-handbook (9)</a></li>
1135
1136 <li><a href="https://people.skolelinux.org/pere/blog/tags/digistan">digistan (11)</a></li>
1137
1138 <li><a href="https://people.skolelinux.org/pere/blog/tags/dld">dld (18)</a></li>
1139
1140 <li><a href="https://people.skolelinux.org/pere/blog/tags/docbook">docbook (32)</a></li>
1141
1142 <li><a href="https://people.skolelinux.org/pere/blog/tags/drivstoffpriser">drivstoffpriser (4)</a></li>
1143
1144 <li><a href="https://people.skolelinux.org/pere/blog/tags/english">english (454)</a></li>
1145
1146 <li><a href="https://people.skolelinux.org/pere/blog/tags/fiksgatami">fiksgatami (23)</a></li>
1147
1148 <li><a href="https://people.skolelinux.org/pere/blog/tags/fildeling">fildeling (14)</a></li>
1149
1150 <li><a href="https://people.skolelinux.org/pere/blog/tags/freeculture">freeculture (34)</a></li>
1151
1152 <li><a href="https://people.skolelinux.org/pere/blog/tags/freedombox">freedombox (9)</a></li>
1153
1154 <li><a href="https://people.skolelinux.org/pere/blog/tags/frikanalen">frikanalen (20)</a></li>
1155
1156 <li><a href="https://people.skolelinux.org/pere/blog/tags/h264">h264 (20)</a></li>
1157
1158 <li><a href="https://people.skolelinux.org/pere/blog/tags/intervju">intervju (43)</a></li>
1159
1160 <li><a href="https://people.skolelinux.org/pere/blog/tags/isenkram">isenkram (16)</a></li>
1161
1162 <li><a href="https://people.skolelinux.org/pere/blog/tags/kart">kart (23)</a></li>
1163
1164 <li><a href="https://people.skolelinux.org/pere/blog/tags/kodi">kodi (6)</a></li>
1165
1166 <li><a href="https://people.skolelinux.org/pere/blog/tags/ldap">ldap (9)</a></li>
1167
1168 <li><a href="https://people.skolelinux.org/pere/blog/tags/lego">lego (5)</a></li>
1169
1170 <li><a href="https://people.skolelinux.org/pere/blog/tags/lenker">lenker (8)</a></li>
1171
1172 <li><a href="https://people.skolelinux.org/pere/blog/tags/linuxcnc">linuxcnc (5)</a></li>
1173
1174 <li><a href="https://people.skolelinux.org/pere/blog/tags/lsdvd">lsdvd (2)</a></li>
1175
1176 <li><a href="https://people.skolelinux.org/pere/blog/tags/ltsp">ltsp (1)</a></li>
1177
1178 <li><a href="https://people.skolelinux.org/pere/blog/tags/madewithcc">madewithcc (3)</a></li>
1179
1180 <li><a href="https://people.skolelinux.org/pere/blog/tags/mesh network">mesh network (8)</a></li>
1181
1182 <li><a href="https://people.skolelinux.org/pere/blog/tags/multimedia">multimedia (46)</a></li>
1183
1184 <li><a href="https://people.skolelinux.org/pere/blog/tags/nice free software">nice free software (15)</a></li>
1185
1186 <li><a href="https://people.skolelinux.org/pere/blog/tags/noark5">noark5 (23)</a></li>
1187
1188 <li><a href="https://people.skolelinux.org/pere/blog/tags/norsk">norsk (322)</a></li>
1189
1190 <li><a href="https://people.skolelinux.org/pere/blog/tags/nuug">nuug (198)</a></li>
1191
1192 <li><a href="https://people.skolelinux.org/pere/blog/tags/offentlig innsyn">offentlig innsyn (40)</a></li>
1193
1194 <li><a href="https://people.skolelinux.org/pere/blog/tags/open311">open311 (2)</a></li>
1195
1196 <li><a href="https://people.skolelinux.org/pere/blog/tags/opensnitch">opensnitch (4)</a></li>
1197
1198 <li><a href="https://people.skolelinux.org/pere/blog/tags/opphavsrett">opphavsrett (75)</a></li>
1199
1200 <li><a href="https://people.skolelinux.org/pere/blog/tags/personvern">personvern (114)</a></li>
1201
1202 <li><a href="https://people.skolelinux.org/pere/blog/tags/raid">raid (2)</a></li>
1203
1204 <li><a href="https://people.skolelinux.org/pere/blog/tags/reactos">reactos (1)</a></li>
1205
1206 <li><a href="https://people.skolelinux.org/pere/blog/tags/reprap">reprap (11)</a></li>
1207
1208 <li><a href="https://people.skolelinux.org/pere/blog/tags/rfid">rfid (3)</a></li>
1209
1210 <li><a href="https://people.skolelinux.org/pere/blog/tags/robot">robot (17)</a></li>
1211
1212 <li><a href="https://people.skolelinux.org/pere/blog/tags/rss">rss (1)</a></li>
1213
1214 <li><a href="https://people.skolelinux.org/pere/blog/tags/ruter">ruter (7)</a></li>
1215
1216 <li><a href="https://people.skolelinux.org/pere/blog/tags/scraperwiki">scraperwiki (2)</a></li>
1217
1218 <li><a href="https://people.skolelinux.org/pere/blog/tags/sikkerhet">sikkerhet (60)</a></li>
1219
1220 <li><a href="https://people.skolelinux.org/pere/blog/tags/sitesummary">sitesummary (4)</a></li>
1221
1222 <li><a href="https://people.skolelinux.org/pere/blog/tags/skepsis">skepsis (5)</a></li>
1223
1224 <li><a href="https://people.skolelinux.org/pere/blog/tags/standard">standard (74)</a></li>
1225
1226 <li><a href="https://people.skolelinux.org/pere/blog/tags/stavekontroll">stavekontroll (7)</a></li>
1227
1228 <li><a href="https://people.skolelinux.org/pere/blog/tags/stortinget">stortinget (14)</a></li>
1229
1230 <li><a href="https://people.skolelinux.org/pere/blog/tags/surveillance">surveillance (65)</a></li>
1231
1232 <li><a href="https://people.skolelinux.org/pere/blog/tags/sysadmin">sysadmin (5)</a></li>
1233
1234 <li><a href="https://people.skolelinux.org/pere/blog/tags/usenix">usenix (2)</a></li>
1235
1236 <li><a href="https://people.skolelinux.org/pere/blog/tags/valg">valg (9)</a></li>
1237
1238 <li><a href="https://people.skolelinux.org/pere/blog/tags/verkidetfri">verkidetfri (20)</a></li>
1239
1240 <li><a href="https://people.skolelinux.org/pere/blog/tags/video">video (79)</a></li>
1241
1242 <li><a href="https://people.skolelinux.org/pere/blog/tags/vitenskap">vitenskap (4)</a></li>
1243
1244 <li><a href="https://people.skolelinux.org/pere/blog/tags/web">web (42)</a></li>
1245
1246 </ul>
1247
1248
1249 </div>
1250 <p style="text-align: right">
1251 Created by <a href="http://steve.org.uk/Software/chronicle">Chronicle v4.6</a>
1252 </p>
1253
1254 </body>
1255 </html>