mirror of
https://github.com/natelandau/obsidian-metadata.git
synced 2025-11-14 16:03:47 -05:00
fix: allow adding inline tags with same key different values (#17)
This commit is contained in:
@@ -1,2 +1,2 @@
|
|||||||
[virtualenvs]
|
[virtualenvs]
|
||||||
in-project = true
|
in-project = true
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ class InlineMetadata:
|
|||||||
"""
|
"""
|
||||||
return f"InlineMetadata(inline_metadata={self.dict})"
|
return f"InlineMetadata(inline_metadata={self.dict})"
|
||||||
|
|
||||||
def add(self, key: str, value: str = None) -> bool:
|
def add(self, key: str, value: str | list[str] = None) -> bool:
|
||||||
"""Add a key and value to the inline metadata.
|
"""Add a key and value to the inline metadata.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -411,23 +411,29 @@ class InlineMetadata:
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if the metadata was added
|
bool: True if the metadata was added
|
||||||
"""
|
"""
|
||||||
if value is None or value == "" or value == "None":
|
if value is None:
|
||||||
if key not in self.dict:
|
if key not in self.dict:
|
||||||
self.dict[key] = []
|
self.dict[key] = []
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if key not in self.dict:
|
if key not in self.dict:
|
||||||
|
if isinstance(value, list):
|
||||||
|
self.dict[key] = value
|
||||||
|
return True
|
||||||
|
|
||||||
self.dict[key] = [value]
|
self.dict[key] = [value]
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if key in self.dict and len(self.dict[key]) > 0:
|
if key in self.dict and value not in self.dict[key]:
|
||||||
if value in self.dict[key]:
|
if isinstance(value, list):
|
||||||
return False
|
self.dict[key].extend(value)
|
||||||
raise ValueError(f"'{key}' not empty")
|
return True
|
||||||
|
|
||||||
self.dict[key].append(value)
|
self.dict[key].append(value)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def contains(self, key: str, value: str = None, is_regex: bool = False) -> bool:
|
def contains(self, key: str, value: str = None, is_regex: bool = False) -> bool:
|
||||||
"""Check if a key or value exists in the inline metadata.
|
"""Check if a key or value exists in the inline metadata.
|
||||||
@@ -561,7 +567,7 @@ class InlineTags:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def add(self, new_tag: str) -> bool:
|
def add(self, new_tag: str | list[str]) -> bool:
|
||||||
"""Add a new inline tag.
|
"""Add a new inline tag.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -570,13 +576,27 @@ class InlineTags:
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if a tag was added.
|
bool: True if a tag was added.
|
||||||
"""
|
"""
|
||||||
if new_tag in self.list:
|
if isinstance(new_tag, list):
|
||||||
return False
|
for _tag in new_tag:
|
||||||
|
if _tag.startswith("#"):
|
||||||
|
_tag = _tag[1:]
|
||||||
|
if _tag in self.list:
|
||||||
|
return False
|
||||||
|
new_list = self.list.copy()
|
||||||
|
new_list.append(_tag)
|
||||||
|
self.list = sorted(new_list)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
if new_tag.startswith("#"):
|
||||||
|
new_tag = new_tag[1:]
|
||||||
|
if new_tag in self.list:
|
||||||
|
return False
|
||||||
|
new_list = self.list.copy()
|
||||||
|
new_list.append(new_tag)
|
||||||
|
self.list = sorted(new_list)
|
||||||
|
return True
|
||||||
|
|
||||||
new_list = self.list.copy()
|
return False
|
||||||
new_list.append(new_tag)
|
|
||||||
self.list = sorted(new_list)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def contains(self, tag: str, is_regex: bool = False) -> bool:
|
def contains(self, tag: str, is_regex: bool = False) -> bool:
|
||||||
"""Check if a tag exists in the metadata.
|
"""Check if a tag exists in the metadata.
|
||||||
|
|||||||
@@ -135,24 +135,47 @@ class Note:
|
|||||||
Returns:
|
Returns:
|
||||||
bool: Whether the metadata was added.
|
bool: Whether the metadata was added.
|
||||||
"""
|
"""
|
||||||
if area is MetadataType.FRONTMATTER and self.frontmatter.add(key, value):
|
match area: # noqa: E999
|
||||||
self.update_frontmatter()
|
case MetadataType.FRONTMATTER if self.frontmatter.add(key, value):
|
||||||
return True
|
self.update_frontmatter()
|
||||||
|
|
||||||
try:
|
|
||||||
if area is MetadataType.INLINE and self.inline_metadata.add(key, str(value)):
|
|
||||||
line = f"{key}:: " if value is None else f"{key}:: {value}"
|
|
||||||
self.insert(new_string=line, location=location)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except ValueError as e:
|
case MetadataType.INLINE:
|
||||||
log.warning(f"Could not add metadata to {self.note_path}: {e}")
|
if value is None:
|
||||||
return False
|
if self.inline_metadata.add(key):
|
||||||
|
line = f"{key}::"
|
||||||
|
self.insert(new_string=line, location=location)
|
||||||
|
return True
|
||||||
|
|
||||||
if area is MetadataType.TAGS and self.inline_tags.add(str(value)):
|
new_values = []
|
||||||
line = f"#{value}"
|
if isinstance(value, list):
|
||||||
self.insert(new_string=line, location=location)
|
new_values = [_v for _v in value if self.inline_metadata.add(key, _v)]
|
||||||
return True
|
else:
|
||||||
|
if self.inline_metadata.add(key, value):
|
||||||
|
new_values = [value]
|
||||||
|
|
||||||
|
if new_values:
|
||||||
|
for value in new_values:
|
||||||
|
self.insert(new_string=f"{key}:: {value}", location=location)
|
||||||
|
return True
|
||||||
|
|
||||||
|
case MetadataType.TAGS:
|
||||||
|
new_values = []
|
||||||
|
if isinstance(value, list):
|
||||||
|
new_values = [_v for _v in value if self.inline_tags.add(_v)]
|
||||||
|
else:
|
||||||
|
if self.inline_tags.add(value):
|
||||||
|
new_values = [value]
|
||||||
|
|
||||||
|
if new_values:
|
||||||
|
for value in new_values:
|
||||||
|
if value.startswith("#"):
|
||||||
|
value = value[1:]
|
||||||
|
self.insert(new_string=f"#{value}", location=location)
|
||||||
|
return True
|
||||||
|
|
||||||
|
case _:
|
||||||
|
return False
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -284,7 +307,7 @@ class Note:
|
|||||||
if not allow_multiple and len(re.findall(re.escape(new_string), self.file_content)) > 0:
|
if not allow_multiple and len(re.findall(re.escape(new_string), self.file_content)) > 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
match location: # noqa: E999
|
match location:
|
||||||
case InsertLocation.BOTTOM:
|
case InsertLocation.BOTTOM:
|
||||||
self.file_content += f"\n{new_string}"
|
self.file_content += f"\n{new_string}"
|
||||||
case InsertLocation.TOP:
|
case InsertLocation.TOP:
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ horizontal: rule
|
|||||||
"""
|
"""
|
||||||
INLINE_CONTENT = """\
|
INLINE_CONTENT = """\
|
||||||
repeated_key:: repeated_key_value1
|
repeated_key:: repeated_key_value1
|
||||||
|
|
||||||
#inline_tag_top1,#inline_tag_top2
|
#inline_tag_top1,#inline_tag_top2
|
||||||
**bold_key1**:: bold_key1_value
|
**bold_key1**:: bold_key1_value
|
||||||
**bold_key2:: bold_key2_value**
|
**bold_key2:: bold_key2_value**
|
||||||
@@ -280,9 +279,6 @@ def test_inline_metadata_add() -> None:
|
|||||||
"tag_key": ["tag_key_value"],
|
"tag_key": ["tag_key_value"],
|
||||||
}
|
}
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
assert inline.add("added_key1", "added_value_2") is True
|
|
||||||
|
|
||||||
assert inline.dict == {
|
assert inline.dict == {
|
||||||
"added_key": [],
|
"added_key": [],
|
||||||
"added_key1": ["added_value"],
|
"added_key1": ["added_value"],
|
||||||
@@ -309,6 +305,8 @@ def test_inline_metadata_add() -> None:
|
|||||||
"repeated_key": ["repeated_key_value1", "repeated_key_value2"],
|
"repeated_key": ["repeated_key_value1", "repeated_key_value2"],
|
||||||
"tag_key": ["tag_key_value"],
|
"tag_key": ["tag_key_value"],
|
||||||
}
|
}
|
||||||
|
assert inline.add("repeated_key", "repeated_key_value1") is False
|
||||||
|
assert inline.add("repeated_key", "new_value") is True
|
||||||
|
|
||||||
|
|
||||||
def test_inline_metadata_contains() -> None:
|
def test_inline_metadata_contains() -> None:
|
||||||
|
|||||||
@@ -99,6 +99,21 @@ def test_add_metadata_inline(short_note) -> None:
|
|||||||
)
|
)
|
||||||
assert "new_key2:: new_value1" in note.file_content
|
assert "new_key2:: new_value1" in note.file_content
|
||||||
|
|
||||||
|
assert (
|
||||||
|
note.add_metadata(
|
||||||
|
MetadataType.INLINE, key="new_key2", value="new_value2", location=InsertLocation.BOTTOM
|
||||||
|
)
|
||||||
|
is True
|
||||||
|
)
|
||||||
|
assert "new_key2:: new_value2" in note.file_content
|
||||||
|
|
||||||
|
assert (
|
||||||
|
note.add_metadata(
|
||||||
|
MetadataType.INLINE, key="new_key2", value="new_value2", location=InsertLocation.BOTTOM
|
||||||
|
)
|
||||||
|
is False
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_add_metadata_frontmatter(sample_note) -> None:
|
def test_add_metadata_frontmatter(sample_note) -> None:
|
||||||
"""Test adding metadata."""
|
"""Test adding metadata."""
|
||||||
|
|||||||
Reference in New Issue
Block a user