@@ -23,18 +23,50 @@ internal class MetadataParser(
23
23
return resolveItemsHierarchy(items)
24
24
}
25
25
26
- private fun parseElements (metadataElement : ElementNode , filePath : Url ): List <MetadataItem > =
27
- metadataElement.getAll().mapNotNull { e ->
28
- when {
29
- e.namespace == Namespaces .DC ->
30
- parseDcElement(e)
31
- e.namespace == Namespaces .OPF && e.name == " meta" ->
32
- parseMetaElement(e)
33
- e.namespace == Namespaces .OPF && e.name == " link" ->
34
- parseLinkElement(e, filePath)
35
- else -> null
26
+ private fun parseElements (metadataElement : ElementNode , filePath : Url ): List <MetadataItem > {
27
+ val oldMetas: MutableList <ElementNode > = mutableListOf ()
28
+ val newMetas: MutableList <ElementNode > = mutableListOf ()
29
+ val links: MutableList <ElementNode > = mutableListOf ()
30
+ val dcItems: MutableList <ElementNode > = mutableListOf ()
31
+
32
+ metadataElement
33
+ .getAll()
34
+ .forEach { e ->
35
+ when {
36
+ e.namespace == Namespaces .DC -> {
37
+ dcItems.add(e)
38
+ }
39
+ e.namespace == Namespaces .OPF && e.name == " meta" -> {
40
+ if (e.getAttr(" property" ) == null ) {
41
+ oldMetas.add(e)
42
+ } else {
43
+ newMetas.add(e)
44
+ }
45
+ }
46
+ e.namespace == Namespaces .OPF && e.name == " link" -> {
47
+ links.add(e)
48
+ }
49
+ else -> {}
50
+ }
36
51
}
37
- }
52
+
53
+ val parsedNewMetas = newMetas
54
+ .mapNotNull { parseNewMetaElement(it) }
55
+
56
+ val propertiesFromGlobalNewMetas = parsedNewMetas
57
+ .filter { it.refines == null }
58
+ .map { it.property }
59
+ .toSet()
60
+
61
+ val parsedOldMetas = oldMetas
62
+ .mapNotNull { parseOldMetaElement(it) }
63
+ // Ignore EPUB2 fallbacks in EPUB3
64
+ .filter { it.property !in propertiesFromGlobalNewMetas }
65
+
66
+ return parsedNewMetas + parsedOldMetas +
67
+ dcItems.mapNotNull { parseDcElement(it) } +
68
+ links.mapNotNull { parseLinkElement(it, filePath) }
69
+ }
38
70
39
71
private fun parseLinkElement (element : ElementNode , filePath : Url ): MetadataItem .Link ? {
40
72
val href = element.getAttr(" href" )?.let { Url .fromEpubHref(it) } ? : return null
@@ -60,43 +92,43 @@ internal class MetadataParser(
60
92
)
61
93
}
62
94
63
- private fun parseMetaElement (element : ElementNode ): MetadataItem .Meta ? {
64
- return if ( element.getAttr(" property" ) == null ) {
65
- val name = element.getAttr( " name " )?.trim()?.ifEmpty { null }
66
- ? : return null
67
- val content = element.getAttr( " content " )?.trim()?.ifEmpty { null }
68
- ? : return null
69
- val resolvedName = resolveProperty(name, prefixMap)
70
- MetadataItem . Meta (
71
- id = element.id,
72
- refines = null ,
73
- property = resolvedName,
74
- value = content,
75
- lang = element.lang
76
- )
77
- } else {
78
- val propName = element.getAttr( " property " )?.trim()?.ifEmpty { null }
79
- ? : return null
80
- val propValue = element.text?.trim()?.ifEmpty { null }
81
- ? : return null
82
- val resolvedProp = resolveProperty(propName, prefixMap, DEFAULT_VOCAB . META )
83
- val resolvedScheme =
84
- element.getAttr( " scheme " )?.trim()?.ifEmpty { null }?. let {
85
- resolveProperty(
86
- it,
87
- prefixMap
88
- )
89
- }
90
- val refines = element.getAttr(" refines " )?.removePrefix( " # " )
91
- MetadataItem . Meta (
92
- id = element.id,
93
- refines = refines,
94
- property = resolvedProp ,
95
- value = propValue ,
96
- lang = element.lang ,
97
- scheme = resolvedScheme
98
- )
99
- }
95
+ private fun parseNewMetaElement (element : ElementNode ): MetadataItem .Meta ? {
96
+ val propName = element.getAttr(" property" )?.trim()?.ifEmpty { null }
97
+ ? : return null
98
+ val propValue = element.text?.trim()?.ifEmpty { null }
99
+ ? : return null
100
+ val resolvedProp = resolveProperty(propName, prefixMap, DEFAULT_VOCAB . META )
101
+ val resolvedScheme =
102
+ element.getAttr( " scheme " )?.trim()?.ifEmpty { null }?. let {
103
+ resolveProperty(
104
+ it ,
105
+ prefixMap
106
+ )
107
+ }
108
+ val refines = element.getAttr( " refines " )?.removePrefix( " # " )
109
+ return MetadataItem . Meta (
110
+ id = element.id,
111
+ refines = refines,
112
+ property = resolvedProp,
113
+ value = propValue,
114
+ lang = element.lang,
115
+ scheme = resolvedScheme
116
+ )
117
+ }
118
+
119
+ private fun parseOldMetaElement ( element : ElementNode ): MetadataItem . Meta ? {
120
+ val name = element.getAttr( " name " )?.trim()?.ifEmpty { null }
121
+ ? : return null
122
+ val content = element.getAttr(" content " )?.trim()?.ifEmpty { null }
123
+ ? : return null
124
+ val resolvedName = resolveProperty(name, prefixMap)
125
+ return MetadataItem . Meta (
126
+ id = element.id ,
127
+ refines = null ,
128
+ property = resolvedName ,
129
+ value = content,
130
+ lang = element.lang
131
+ )
100
132
}
101
133
102
134
private fun parseDcElement (element : ElementNode ): MetadataItem .Meta ? {
0 commit comments