Skip to content

Commit f736c74

Browse files
committed
支持目录层级
.net5 增加一个删除属性 amzn-src-id
1 parent 0c6dad1 commit f736c74

8 files changed

+137
-54
lines changed

publish.bat

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ rd /Q /S bin
44
cd src
55
rd /Q /S bin
66

7-
dotnet publish -c release -r win10-x64 /p:PublishSingleFile=true /p:PublishTrimmed=true
7+
dotnet publish -c Release -r win10-x64
88

99
md ..\bin
10-
del bin\release\netcoreapp3.1\win10-x64\publish\*.pdb
11-
move bin\release\netcoreapp3.1\win10-x64\publish ..\bin\app
10+
del bin\release\net5\win10-x64\publish\*.pdb
11+
move bin\release\net5\win10-x64\publish ..\bin\app
1212

1313
md ..\bin\app\template\
1414
copy template\template_cover.txt ..\bin\app\template\template_cover.txt

src/Azw3File.cs

+29-6
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ void ProcessRes()
141141
public List<Skeleton_item> skeleton_table;
142142
public List<Fragment_item> frag_table;
143143
public List<Guide_item> guide_table;
144-
public List<NCX_item> ncx_table;
144+
public List<IndexInfo_item> index_info_table;
145145
void ProcessIndex()
146146
{
147147

@@ -230,7 +230,7 @@ void ProcessIndex()
230230
}
231231
if (mobi_header.ncx_index != 0xffffffff)
232232
{
233-
ncx_table = new List<NCX_item>();
233+
index_info_table = new List<IndexInfo_item>();
234234
Hashtable ctoc_dict = new Hashtable();
235235
INDX_Section_Main main_indx = new INDX_Section_Main(GetSectionData(mobi_header.ncx_index), "INDX(NCX)");
236236
sections[mobi_header.ncx_index] = main_indx;
@@ -255,19 +255,42 @@ void ProcessIndex()
255255
ext_indx.ReadTagMap();
256256
for (int j = 0; j < ext_indx.tagmaps.Length; j++)
257257
{
258-
NCX_item item = new NCX_item();
258+
IndexInfo_item item = new IndexInfo_item();
259259
item.name = ext_indx.texts[j];
260260
foreach (var k in ext_indx.tagmaps[j])
261261
{
262262
List<int> a = (List<int>)((DictionaryEntry)k).Value;
263-
item.fid = a[4];
264-
item.off = a[5];
265263
item.position = a[0];
266264
item.length = a[1];
267265
item.title = (string)ctoc_dict[a[2]];
266+
item.level = a[3];
267+
if (item.level > 0)
268+
{
269+
item.parent = a[4];
270+
item.fid = a[5];
271+
item.off = a[6];
272+
}
273+
else
274+
{
275+
switch (a.Count)
276+
{
277+
case 6:
278+
item.fid = a[4];
279+
item.off = a[5];
280+
break;
281+
case 8:
282+
item.children_start = a[4];
283+
item.children_end = a[5];
284+
item.fid = a[6];
285+
item.off = a[7];
286+
break;
287+
default: throw new Exception("Unhandled Error at INDX");
288+
}
289+
}
268290
break;
269291
}
270-
ncx_table.Add(item);
292+
index_info_table.Add(item);
293+
Console.WriteLine($"{item.name} {item.fid} {item.off} {item.title}");
271294
}
272295
}
273296
}

src/EpubBuilder.cs

+91-37
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ public Epub(Azw3File azw3, Azw6File azw6 = null)
4444
}
4545
try
4646
{
47-
CreateNCX();
48-
CreateNAV();
47+
CreateIndexDoc();
4948
}
5049
catch (Exception e)
5150
{
@@ -118,6 +117,7 @@ void ProcNodes(XmlNode node)
118117
if (node.Attributes != null)
119118
{
120119
node.Attributes.RemoveNamedItem("aid");
120+
node.Attributes.RemoveNamedItem("amzn-src-id");
121121
foreach (XmlAttribute attr in node.Attributes)
122122
{
123123
if (attr.Value.IndexOf("kindle:") == 0)
@@ -233,7 +233,7 @@ void ProcLink(XmlAttribute attr)
233233
}
234234
string KindlePosToUri(int fid, int off)//务必在插入封面前调用
235235
{
236-
Regex reg_html_id = new Regex("<.*? id=\"(.*?)\".*?>");
236+
Regex reg_html_id = new Regex("^<.*? id=\"(.*?)\".*?>");
237237
Fragment_item frag = azw3.frag_table[fid];
238238
byte[] t = Util.SubArray(azw3.rawML, frag.pos_in_raw + off, frag.length - off);
239239
string s = Encoding.UTF8.GetString(t);
@@ -275,52 +275,106 @@ string ProcCSS(string text)
275275
return r;
276276
}
277277

278-
void CreateNCX()
278+
private class IndexNode
279279
{
280-
string t = File.ReadAllText("template\\template_ncx.txt");
281-
string np_temp = "<navPoint id=\"navPoint-{0}\" playOrder=\"{0}\">\n <navLabel><text>{1}</text></navLabel>\n <content src=\"{2}\" />\n</navPoint>\n";
282-
string np = "";
283-
int i = 1;
284-
if (azw3.ncx_table != null)
285-
foreach (NCX_item info in azw3.ncx_table)
286-
{
287-
np += String.Format(np_temp, i, info.title, "Text/" + KindlePosToUri(info.fid, info.off));
288-
i++;
289-
}
290-
t = t.Replace("{❕navMap}", np);
291-
t = t.Replace("{❕Title}", azw3.title);
292-
string z = azw3.mobi_header.extMeta.id_string[504];//ASIN
293-
t = t.Replace("{❕uid}", z);
294-
ncx = t;
280+
public string href, title;
281+
public List<IndexNode> children;
282+
public IndexNode parent;
283+
public IndexNode(string href, string title)
284+
{
285+
this.href = href;
286+
this.title = title;
287+
}
288+
295289
}
296-
void CreateNAV()
290+
int playOrder = 1;
291+
void CreateIndexDoc_Helper(IndexNode node, StringBuilder temp_epub3, StringBuilder temp_epub2, int level = 0)
297292
{
298-
string t = File.ReadAllText("template\\template_nav.txt");
299-
string np_temp = " <li><a href=\"{1}\">{0}</a></li>\n";
300-
string np = "";
301-
if (azw3.ncx_table != null)
302-
foreach (NCX_item info in azw3.ncx_table)
293+
string tabs = new String('\t', level);
294+
295+
temp_epub3.Append("\n" + tabs + $"<ol>\n");
296+
foreach (var n in node.children)
297+
{
298+
299+
temp_epub3.Append(tabs + $"<li><a href=\"{n.href}\">{n.title}</a>");
300+
301+
temp_epub2.Append(tabs + $"<navPoint id=\"navPoint-{playOrder}\" playOrder=\"{playOrder}\">\n");
302+
temp_epub2.Append(tabs + $"\t<navLabel><text>{n.title}</text></navLabel>\n");
303+
temp_epub2.Append(tabs + $"\t<content src=\"{n.href}\" />\n");
304+
305+
playOrder++;
306+
307+
if (n.children != null)
303308
{
304-
np += String.Format(np_temp, info.title, "Text/" + KindlePosToUri(info.fid, info.off));
309+
CreateIndexDoc_Helper(n, temp_epub3, temp_epub2, level + 1);
305310
}
306-
t = t.Replace("{❕toc}", np);
307-
string guide = "";
308-
if (azw3.guide_table != null)
309-
foreach (Guide_item g in azw3.guide_table)
311+
temp_epub3.Append("</li>\n");
312+
temp_epub2.Append(tabs + "</navPoint>\n");
313+
}
314+
temp_epub3.Append(tabs + $"</ol>\n");
315+
}
316+
void CreateIndexDoc()
317+
{
318+
List<IndexNode> allEntries = new List<IndexNode>();
319+
IndexNode root = new IndexNode("", "");
320+
root.children = new List<IndexNode>();
321+
int maxLevel = 0;
322+
if (azw3.index_info_table != null)
323+
for (int i = 0; i < azw3.index_info_table.Count; i++)
310324
{
311-
try
325+
IndexInfo_item info = azw3.index_info_table[i];
326+
var entry = new IndexNode("Text/" + KindlePosToUri(info.fid, info.off), info.title);
327+
allEntries.Add(entry);
328+
if (info.children_start != -1) { entry.children = new List<IndexNode>(); }
329+
if (info.level > 0)
312330
{
313-
guide += string.Format(" <li><a epub:type=\"{2}\" href=\"{1}\">{0}</a></li>\n", g.ref_name, Path.Combine("Text/", xhtml_names[azw3.frag_table[g.num].file_num + 1]), g.ref_type);
331+
entry.parent = allEntries[info.parent];
332+
entry.parent.children.Add(entry);
333+
334+
//assert
335+
var _item = azw3.index_info_table[info.parent];
336+
if (_item.children_start > i || _item.children_end < i) { throw new Exception("Index Error"); }
314337
}
315-
catch (Exception e)
338+
else
316339
{
317-
Log.log("Error at Gen guide.");
318-
Log.log(e.ToString());
340+
root.children.Add(entry);
319341
}
342+
if (info.level > maxLevel) maxLevel = info.level;
320343
}
344+
StringBuilder temp_epub3 = new StringBuilder(), temp_epub2 = new StringBuilder();
345+
CreateIndexDoc_Helper(root, temp_epub3, temp_epub2);
346+
//Create NAV
347+
{
348+
string t = File.ReadAllText("template\\template_nav.txt");
349+
t = t.Replace("{❕toc}", temp_epub3.ToString());
350+
string guide = "";
351+
if (azw3.guide_table != null)
352+
foreach (Guide_item g in azw3.guide_table)
353+
{
354+
try
355+
{
356+
guide += string.Format(" <li><a epub:type=\"{2}\" href=\"{1}\">{0}</a></li>\n", g.ref_name, Path.Combine("Text/", xhtml_names[azw3.frag_table[g.num].file_num + 1]), g.ref_type);
357+
}
358+
catch (Exception e)
359+
{
360+
Log.log("Error at Gen guide.");
361+
Log.log(e.ToString());
362+
}
363+
}
321364

322-
t = t.Replace("{❕guide}", guide);
323-
nav = t;
365+
t = t.Replace("{❕guide}", guide);
366+
nav = t;
367+
}
368+
{
369+
string t = File.ReadAllText("template\\template_ncx.txt");
370+
371+
t = t.Replace("{❕navMap}", temp_epub2.ToString());
372+
t = t.Replace("{❕Title}", azw3.title);
373+
string z = azw3.mobi_header.extMeta.id_string[504];//ASIN
374+
t = t.Replace("{❕uid}", z);
375+
t = t.Replace("{❕depth}", maxLevel + 1 + "");
376+
ncx = t;
377+
}
324378
}
325379
void CreateCover()
326380
{

src/Structs&Dictionary.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ protected byte[] GetSectionData(uint i)
4444
}
4545
protected AzwFile(string path)
4646
{
47-
raw_data = File.ReadAllBytes(path);
47+
raw_data = File.ReadAllBytes(path);
4848
GetSectionInfo();
4949

5050
}
@@ -105,10 +105,10 @@ public class Guide_item
105105
public int num;
106106
public Guide_item(string _ref_type, string _ref_name, int no) { ref_type = _ref_type; ref_name = _ref_name; num = no; }
107107
}
108-
public class NCX_item
108+
public class IndexInfo_item
109109
{
110110
public string title, name;
111-
public int fid, off, position, length;
111+
public int fid, off, position, length, level, parent = -1, children_start = -1, children_end = -1;
112112
}
113113
public class IdMapping
114114
{

src/UnpackKindleS.csproj

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<TargetFramework>net5</TargetFramework>
66
</PropertyGroup>
77

8+
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
9+
<SelfContained>true</SelfContained>
10+
<PublishSingleFile>true</PublishSingleFile>
11+
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
12+
<PublishTrimmed>true</PublishTrimmed>
13+
<TrimMode>Link</TrimMode>
14+
</PropertyGroup>
15+
816
</Project>

src/template/template_nav.txt

-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99

1010
<nav epub:type="toc" id="toc">
1111
<h1>Navigation</h1>
12-
<ol>
1312
{❕toc}
14-
</ol>
1513
</nav>
1614

1715
<nav epub:type="landmarks" id="guide">

src/template/template_ncx.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
33
<head>
44
<meta name="dtb:uid" content="{❕uid}" />
5-
<meta name="dtb:depth" content="1" />
5+
<meta name="dtb:depth" content="{❕depth}" />
66
<meta name="dtb:totalPageCount" content="0" />
77
<meta name="dtb:maxPageNumber" content="0" />
88
</head>

src/version.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
namespace UnpackKindleS
22
{
3-
public class Version{public static string version="20201007";}
3+
public class Version{public static string version="20210107";}
44
}

0 commit comments

Comments
 (0)