void ProcessIndex() { if (mobi_header.skel_index != 0xffffffff) { skeleton_table = new List <Skeleton_item>(); INDX_Section_Main main_indx = new INDX_Section_Main(GetSectionData(mobi_header.skel_index), "INDX(Skeleton)"); sections[mobi_header.skel_index] = main_indx; main_indx.ReadTag(); for (uint i = 0; i < main_indx.header.any_count; i++) { INDX_Section_Extra ext_indx = new INDX_Section_Extra(GetSectionData(mobi_header.skel_index + i + 1), main_indx); ext_indx.ReadTagMap(); sections[mobi_header.skel_index + i + 1] = ext_indx; for (int j = 0; j < ext_indx.texts.Length; j++) { List <int> values = (List <int>)(ext_indx.tagmaps[j][1]);//有点毛病……结果OK skeleton_table.Add(new Skeleton_item(ext_indx.texts[j], values[0], values[2], values[3])); } } } if (mobi_header.frag_index != 0xffffffff) { Hashtable ctoc_dict = new Hashtable(); frag_table = new List <Fragment_item>(); INDX_Section_Main main_indx = new INDX_Section_Main(GetSectionData(mobi_header.frag_index), "INDX(Fragment)"); sections[mobi_header.frag_index] = main_indx; main_indx.ReadTag(); int ctoc_off = 0; for (uint i = 0; i < main_indx.header.ctoc_count; i++) { uint off = mobi_header.frag_index + main_indx.header.any_count + 1 + i; CTOC_Section ctoc = new CTOC_Section(GetSectionData(off)); sections[off] = ctoc; foreach (int key in ctoc.ctoc_data.Keys) { ctoc_dict[key + ctoc_off] = ctoc.ctoc_data[key]; } ctoc_off += 0x10000; } for (uint i = 0; i < main_indx.header.any_count; i++) { INDX_Section_Extra ext_indx = new INDX_Section_Extra(GetSectionData(mobi_header.frag_index + i + 1), main_indx); sections[mobi_header.frag_index + i + 1] = ext_indx; ext_indx.ReadTagMap(); for (int j = 0; j < ext_indx.texts.Length; j++) { List <int> values = (List <int>)(ext_indx.tagmaps[j][2]);//有点毛病……结果OK frag_table.Add(new Fragment_item(ext_indx.texts[j], (string)ctoc_dict[values[0]], values[1], values[2], values[3], values[4])); } } } if (mobi_header.guide_index != 0xffffffff) { Hashtable ctoc_dict = new Hashtable(); guide_table = new List <Guide_item>(); INDX_Section_Main main_indx = new INDX_Section_Main(GetSectionData(mobi_header.guide_index), "INDX(Guide)"); sections[mobi_header.guide_index] = main_indx; main_indx.ReadTag(); int ctoc_off = 0; for (uint i = 0; i < main_indx.header.ctoc_count; i++) { uint off = mobi_header.guide_index + main_indx.header.any_count + 1 + i; CTOC_Section ctoc = new CTOC_Section(GetSectionData(off)); sections[off] = ctoc; foreach (int key in ctoc.ctoc_data.Keys) { ctoc_dict[key + ctoc_off] = ctoc.ctoc_data[key]; } ctoc_off += 0x10000; } for (uint i = 0; i < main_indx.header.any_count; i++) { INDX_Section_Extra ext_indx = new INDX_Section_Extra(GetSectionData(mobi_header.guide_index + i + 1), main_indx); sections[mobi_header.guide_index + i + 1] = ext_indx; ext_indx.ReadTagMap(); for (int j = 0; j < ext_indx.texts.Length; j++) { List <int> values = (List <int>)(ext_indx.tagmaps[j][1]);//有点毛病……结果OK guide_table.Add(new Guide_item(ext_indx.texts[j], (string)ctoc_dict[values[0]], values[1])); } } } if (mobi_header.ncx_index != 0xffffffff) { index_info_table = new List <IndexInfo_item>(); Hashtable ctoc_dict = new Hashtable(); INDX_Section_Main main_indx = new INDX_Section_Main(GetSectionData(mobi_header.ncx_index), "INDX(NCX)"); sections[mobi_header.ncx_index] = main_indx; main_indx.ReadTag(); int ctoc_off = 0; for (uint i = 0; i < main_indx.header.ctoc_count; i++) { uint off = mobi_header.ncx_index + main_indx.header.any_count + 1 + i; CTOC_Section ctoc = new CTOC_Section(GetSectionData(off)); sections[off] = ctoc; foreach (int key in ctoc.ctoc_data.Keys) { ctoc_dict[key + ctoc_off] = ctoc.ctoc_data[key]; } ctoc_off += 0x10000; } for (uint i = 0; i < main_indx.header.any_count; i++) { INDX_Section_Extra ext_indx = new INDX_Section_Extra(GetSectionData(mobi_header.ncx_index + i + 1), main_indx); sections[mobi_header.ncx_index + i + 1] = ext_indx; ext_indx.ReadTagMap(); for (int j = 0; j < ext_indx.tagmaps.Length; j++) { IndexInfo_item item = new IndexInfo_item(); item.name = ext_indx.texts[j]; foreach (var k in ext_indx.tagmaps[j]) { List <int> a = (List <int>)((DictionaryEntry)k).Value; item.position = a[0]; item.length = a[1]; item.title = (string)ctoc_dict[a[2]]; item.level = a[3]; if (item.level > 0) { item.parent = a[4]; item.fid = a[5]; item.off = a[6]; } else { switch (a.Count) { case 6: item.fid = a[4]; item.off = a[5]; break; case 8: item.children_start = a[4]; item.children_end = a[5]; item.fid = a[6]; item.off = a[7]; break; default: throw new Exception("Unhandled Error at INDX"); } } break; } index_info_table.Add(item); //Console.WriteLine($"{item.name} {item.fid} {item.off} {item.title}"); } } } }
void CreateIndexDoc() { List <IndexNode> allEntries = new List <IndexNode>(); IndexNode root = new IndexNode("", ""); root.children = new List <IndexNode>(); int maxLevel = 0; if (azw3.index_info_table != null) { for (int i = 0; i < azw3.index_info_table.Count; i++) { IndexInfo_item info = azw3.index_info_table[i]; var entry = new IndexNode("Text/" + KindlePosToUri(info.fid, info.off), info.title); allEntries.Add(entry); if (info.children_start != -1) { entry.children = new List <IndexNode>(); } if (info.level > 0) { entry.parent = allEntries[info.parent]; entry.parent.children.Add(entry); //assert var _item = azw3.index_info_table[info.parent]; if (_item.children_start > i || _item.children_end < i) { throw new Exception("Index Error"); } } else { root.children.Add(entry); } if (info.level > maxLevel) { maxLevel = info.level; } } } StringBuilder temp_epub3 = new StringBuilder(), temp_epub2 = new StringBuilder(); CreateIndexDoc_Helper(root, temp_epub3, temp_epub2); //Create NAV { string t = File.ReadAllText("template\\template_nav.txt"); t = t.Replace("{❕toc}", temp_epub3.ToString()); string guide = ""; if (azw3.guide_table != null) { foreach (Guide_item g in azw3.guide_table) { try { 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); } catch (Exception e) { Log.log("Error at Gen guide."); Log.log(e.ToString()); } } } t = t.Replace("{❕guide}", guide); t = t.Replace("{❕cover}", "Text/" + xhtml_names[0]); nav = t; } { string t = File.ReadAllText("template\\template_ncx.txt"); t = t.Replace("{❕navMap}", temp_epub2.ToString()); t = t.Replace("{❕Title}", azw3.title); string z = azw3.mobi_header.extMeta.id_string[504];//ASIN t = t.Replace("{❕uid}", z); t = t.Replace("{❕depth}", maxLevel + 1 + ""); ncx = t; } }