MOBI_RET mobi_xml_write_manifest(xmlTextWriterPtr writer, const MOBIRawml *rawml) {
    char href[256];
    char id[256];
    if (rawml->flow != NULL) {
        MOBIPart *curr = rawml->flow;
        /* skip first raw html part */
        curr = curr->next;
        while (curr != NULL) {
            MOBIFileMeta file_meta = mobi_get_filemeta_by_type(curr->type);
            snprintf(href, sizeof(href), "flow%05zu.%s", curr->uid, file_meta.extension);
            snprintf(id, sizeof(id), "flow%05zu", curr->uid);
            MOBI_RET ret = mobi_xml_write_item(writer, id, href, file_meta.mime_type);
            if (ret != MOBI_SUCCESS) {
                return ret;
            }
            curr = curr->next;
        }
    }
    if (rawml->markup != NULL) {
        MOBIPart *curr = rawml->markup;
        while (curr != NULL) {
            MOBIFileMeta file_meta = mobi_get_filemeta_by_type(curr->type);
            snprintf(href, sizeof(href), "part%05zu.%s", curr->uid, file_meta.extension);
            snprintf(id, sizeof(id), "part%05zu", curr->uid);
            MOBI_RET ret = mobi_xml_write_item(writer, id, href, file_meta.mime_type);
            if (ret != MOBI_SUCCESS) {
                return ret;
            }
            curr = curr->next;
        }
    }
    if (rawml->resources != NULL) {
        MOBIPart *curr = rawml->resources;
        while (curr != NULL) {
            MOBIFileMeta file_meta = mobi_get_filemeta_by_type(curr->type);
            snprintf(href, sizeof(href), "resource%05zu.%s", curr->uid, file_meta.extension);
            snprintf(id, sizeof(id), "resource%05zu", curr->uid);
            MOBI_RET ret = mobi_xml_write_item(writer, id, href, file_meta.mime_type);
            if (ret != MOBI_SUCCESS) {
                return ret;
            }
            curr = curr->next;
        }
    }
    return MOBI_SUCCESS;
}
MOBI_RET mobi_xml_write_manifest(xmlTextWriterPtr writer, const MOBIRawml *rawml) {
    char href[256];
    char id[256];
    if (rawml->flow != NULL) {
        MOBIPart *curr = rawml->flow;
         
        curr = curr->next;
        while (curr != NULL) {
            MOBIFileMeta file_meta = mobi_get_filemeta_by_type(curr->type);
            snprintf(href, sizeof(href), "flow%05zu.%s", curr->uid, file_meta.extension);
            snprintf(id, sizeof(id), "flow%05zu", curr->uid);
            MOBI_RET ret = mobi_xml_write_item(writer, id, href, file_meta.mime_type);
            if (ret != MOBI_SUCCESS) {
                return ret;
            }
            curr = curr->next;
        }
    }
    if (rawml->markup != NULL) {
        MOBIPart *curr = rawml->markup;
        while (curr != NULL) {
            MOBIFileMeta file_meta = mobi_get_filemeta_by_type(curr->type);
            snprintf(href, sizeof(href), "part%05zu.%s", curr->uid, file_meta.extension);
            snprintf(id, sizeof(id), "part%05zu", curr->uid);
            MOBI_RET ret = mobi_xml_write_item(writer, id, href, file_meta.mime_type);
            if (ret != MOBI_SUCCESS) {
                return ret;
            }
            curr = curr->next;
        }
    }
    if (rawml->resources != NULL) {
        MOBIPart *curr = rawml->resources;
        while (curr != NULL) {
            MOBIFileMeta file_meta = mobi_get_filemeta_by_type(curr->type);
            snprintf(href, sizeof(href), "resource%05zu.%s", curr->uid, file_meta.extension);
            snprintf(id, sizeof(id), "resource%05zu", curr->uid);
            MOBI_RET ret = mobi_xml_write_item(writer, id, href, file_meta.mime_type);
            if (ret != MOBI_SUCCESS) {
                return ret;
            }
            curr = curr->next;
        }
    }
    return MOBI_SUCCESS;
}