Skip to content

Commit 420e0a1

Browse files
committed
Merge branch 'main' into hypothesis_tests
2 parents e67e94f + e8df6df commit 420e0a1

20 files changed

+423
-277
lines changed

docs/image_properties_tag_replacer.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# ImagePropertiesTagReplacer
2+
3+
::: image_formatter.image_properties_tag_replacer.image_properties_tag_replacer

docs/parser.md

-3
This file was deleted.

image_formatter/image_formatter_plugin/image_formatter_plugin.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,6 @@ def on_config(self, config: MkDocsConfig) -> MkDocsConfig or None:
5656
return config
5757

5858
def on_page_read_source(self, page: Page, config: MkDocsConfig) -> str or None:
59-
# todo: using lexer, parser and interpreter read user's docs and apply sizes specified in tags
59+
# todo: using lexer, image_properties_tag_replacer and interpreter read user's docs and apply sizes specified in tags
6060

6161
pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import copy
2+
3+
from image_formatter.lexer.lexer import Lexer
4+
from image_formatter.lexer.token import TokenType, Token
5+
from image_formatter.error_handler.error_handler import ErrorHandler
6+
from image_formatter.error_handler.errors import UnexpectedTagException
7+
from mkdocs.plugins import get_plugin_logger
8+
9+
log = get_plugin_logger(__name__)
10+
11+
12+
class ImagePropertiesTagReplacer:
13+
"""
14+
Class ImagePropertiesTagReplacer responsible for replacing image size tags with properties after the image URL.
15+
Focuses only on the plugin's purpose - images with added size tags
16+
"""
17+
18+
def __init__(self, lex: Lexer, image_tags_properties: dict, error_handler: ErrorHandler = ErrorHandler()):
19+
"""
20+
Args:
21+
lex: lexer used for obtaining tokens
22+
image_tags_properties: properties to be added after tagged urls
23+
error_handler: used to register errors, takes care of error handling
24+
"""
25+
self.lexer = lex
26+
self.curr_token = lex.get_token()
27+
self.image_tags_properties = image_tags_properties
28+
self.error_handler = error_handler
29+
30+
@staticmethod
31+
def name() -> str:
32+
return __class__.__name__
33+
34+
def next_token(self):
35+
self.curr_token = self.lexer.get_token()
36+
37+
def parse_image_link_url(self, tag_token: Token) -> Token:
38+
"""
39+
Verify if image url can be created according to the:
40+
```
41+
image_link = image_size_tag, image_url
42+
```
43+
44+
Args:
45+
tag_token: already found tag
46+
47+
Returns:
48+
Token: of TokenType.T_IMAGE_URL_WITH_PROPERTIES if successful, otherwise of TokenType.T_IMAGE_SIZE_TAG
49+
"""
50+
log.info(f"{ImagePropertiesTagReplacer.name()}: Trying to parse image link url.")
51+
if self.curr_token.type == TokenType.T_IMAGE_URL:
52+
log.info(f"{ImagePropertiesTagReplacer.name()}: Url tag found: {self.curr_token}")
53+
url_token = copy.deepcopy(self.curr_token)
54+
formatted_url = self.add_tag_properties_to_url(tag_token)
55+
self.next_token()
56+
return Token(TokenType.T_IMAGE_URL_WITH_PROPERTIES, url_token.position, formatted_url)
57+
else:
58+
log.error(f"{ImagePropertiesTagReplacer.name()}: Failed to parse image link url.")
59+
self.error_handler.handle(UnexpectedTagException(TokenType.T_IMAGE_URL, self.curr_token.type))
60+
return tag_token
61+
62+
def add_tag_properties_to_url(self, tag_token: Token) -> str:
63+
"""
64+
Formats properties for given tag_token to string in a CSS format.
65+
66+
Args:
67+
tag_token: token used to mark a url
68+
69+
Returns:
70+
str: image tag properties formatted to CSS
71+
"""
72+
properties = '{: style="'
73+
pairs = ";".join([f"{key}:{value}" for key, value in self.image_tags_properties[tag_token.string].items()])
74+
properties = properties + pairs + '"}'
75+
formatted_url = self.curr_token.string + properties
76+
return formatted_url
77+
78+
def parse_image_link_tag(self) -> Token or bool:
79+
"""
80+
Tries to parse the first part of image link - the tag.
81+
image_link = image_size_tag, image_url
82+
83+
Returns:
84+
Token: of TokenType.T_IMAGE_URL_WITH_PROPERTIES if successful
85+
False: if image link tag cannot be created
86+
"""
87+
log.info(f"{ImagePropertiesTagReplacer.name()}: Trying to parse image link tag.")
88+
if self.curr_token.type == TokenType.T_IMAGE_SIZE_TAG:
89+
log.info(f"{ImagePropertiesTagReplacer.name()}: Image size tag found: {self.curr_token}")
90+
tag_token = copy.deepcopy(self.curr_token)
91+
self.next_token()
92+
return self.parse_image_link_url(tag_token)
93+
log.info(f"{ImagePropertiesTagReplacer.name()}: Failed to parse image link tag.")
94+
return False
95+
96+
def get_token(self):
97+
"""
98+
Replaces image size tags with properties after the url
99+
"""
100+
while self.curr_token.type != TokenType.T_EOF:
101+
if image_link_token := self.parse_image_link_tag():
102+
log.info(
103+
f"{ImagePropertiesTagReplacer.name()}: Returning image link token with properties: '{image_link_token.string}'."
104+
)
105+
yield image_link_token
106+
else:
107+
yield self.curr_token
108+
self.next_token()

image_formatter/lexer/lexer.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,8 @@ def build_url(self) -> Token or None:
325325
log.info(f"{Lexer.name()}: Failed to build a url. Missing '('.)")
326326
return None
327327
position = deepcopy(self.current_position)
328+
string = self.current_char
328329
self.next_char()
329-
string = ""
330330
while self.is_character() or self.current_char == "/":
331331
string += self.current_char
332332
self.next_char()
@@ -336,6 +336,7 @@ def build_url(self) -> Token or None:
336336
if not self.current_char == ")":
337337
log.info(f"{Lexer.name()}: Failed to build a url. Missing ')'.)")
338338
return None
339+
string += self.current_char
339340
self.next_char()
340341
log.info(f"{Lexer.name()}: Image url built successfully. Returning 'T_IMAGE_URL' token.")
341342
return Token(TokenType.T_IMAGE_URL, position, string)

image_formatter/lexer/token.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ class TokenType(Enum):
1414
T_CHAR = 3
1515
T_INTEGER = 4
1616
T_WHITE_CHAR = 5
17-
T_EOF = 6
17+
T_IMAGE_URL_WITH_PROPERTIES = 6
18+
T_EOF = 7
1819

1920

2021
class Token:
@@ -33,6 +34,12 @@ def __init__(self, type: TokenType, position: Position, string: str = ""):
3334
self.position = position
3435
self.string = string
3536

37+
def __eq__(self, other):
38+
if other.__class__ != self.__class__:
39+
return False
40+
41+
return (self.position == other.position) and (self.string == other.string)
42+
3643

3744
class IntegerToken(Token):
3845
"""

image_formatter/parser/parser.py

-99
This file was deleted.

image_size.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,5 @@ def on_config(self, config: dict) -> dict:
3939
return config
4040

4141
def on_page_read_source() -> str or None:
42-
# todo: using lexer, parser and interpreter read user's docs and apply sizes specified in tags
42+
# todo: using lexer, image_properties_tag_replacer and interpreter read user's docs and apply sizes specified in tags
4343
pass

main.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from image_formatter.lexer.lexer import Lexer
2-
from image_formatter.parser.parser import Parser
2+
from image_formatter.image_properties_tag_replacer.image_properties_tag_replacer import ImagePropertiesTagReplacer
33

44
if __name__ == "__main__":
55
# filename = "tests/lexer/test_files/test1.txt"
@@ -8,5 +8,5 @@
88
print(type(fp))
99
lexer = Lexer(fp)
1010
lexer.next_char()
11-
parser = Parser(lexer)
12-
parser.parse()
11+
parser = ImagePropertiesTagReplacer(lexer)
12+
parser.get_token()

mkdocs.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ nav:
1010
- Home: index.md
1111
- Plugin: plugin.md
1212
- Lexer: lexer.md
13-
- Parser: parser.md
13+
- ImagePropertiesTagReplacer: image_properties_tag_replacer.md
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
from unittest.mock import Mock
2-
from image_formatter.parser.parser import Parser
2+
from image_formatter.image_properties_tag_replacer.image_properties_tag_replacer import ImagePropertiesTagReplacer
33
from image_formatter.lexer.token import Token, TokenType
44
from image_formatter.error_handler.error_handler import ErrorHandler
55
from image_formatter.error_handler.errors import UnexpectedTagException
66
from image_formatter.lexer.position import Position
7-
from tests.test_helpers import get_all_parser_results
7+
from tests.test_helpers import get_all_tags_replacer_results
8+
9+
# @ TODO inline global var
10+
image_tags_properties = {
11+
"small": {"height": "100px", "width": "100px"},
12+
"small-2": {"height": "110px", "width": "110px"},
13+
}
814

915

1016
def test_given_tag_when_not_followed_by_url_then_exception_is_registered():
@@ -15,8 +21,8 @@ def test_given_tag_when_not_followed_by_url_then_exception_is_registered():
1521
"",
1622
]
1723
error_handler = ErrorHandler()
18-
parser = Parser(mock_lexer, error_handler)
19-
get_all_parser_results(parser, 1)
24+
tags_replacer = ImagePropertiesTagReplacer(mock_lexer, image_tags_properties, error_handler)
25+
get_all_tags_replacer_results(tags_replacer, 1)
2026
assert len(error_handler.errors) == 1
2127
assert error_handler.errors == [UnexpectedTagException(TokenType.T_IMAGE_URL, TokenType.T_CHAR)]
2228

@@ -26,15 +32,20 @@ def test_given_tag_when_followed_by_another_tag_with_url_then_exception_is_regis
2632
mock_lexer.get_token.side_effect = [
2733
Token(TokenType.T_IMAGE_SIZE_TAG, Position(1, 1), "small"),
2834
Token(TokenType.T_IMAGE_SIZE_TAG, Position(2, 1), "small-2"),
29-
Token(TokenType.T_IMAGE_URL, Position(3, 1), "some/url.png"),
35+
Token(TokenType.T_IMAGE_URL, Position(3, 1), "(some/url.png)"),
3036
"",
3137
]
3238
error_handler = ErrorHandler()
33-
parser = Parser(mock_lexer, error_handler)
34-
result = get_all_parser_results(parser, 2)
39+
tags_replacer = ImagePropertiesTagReplacer(mock_lexer, image_tags_properties, error_handler)
40+
expected_tokens = [
41+
Token(TokenType.T_IMAGE_SIZE_TAG, Position(1, 1), "small"),
42+
Token(
43+
TokenType.T_IMAGE_URL_WITH_PROPERTIES, Position(3, 1), '(some/url.png){: style="height:110px;width:110px"}'
44+
),
45+
]
46+
result = get_all_tags_replacer_results(tags_replacer, 2)
3547

3648
assert len(error_handler.errors) == 1
3749
assert error_handler.errors == [UnexpectedTagException(TokenType.T_IMAGE_URL, TokenType.T_IMAGE_SIZE_TAG)]
3850
assert len(result) == 2
39-
assert result[0] is False
40-
assert result[1] == ("small-2", "some/url.png")
51+
assert result == expected_tokens

0 commit comments

Comments
 (0)