Conditions | 24 |
Total Lines | 101 |
Code Lines | 72 |
Lines | 23 |
Ratio | 22.77 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like jrnl.plugins.yaml_exporter.YAMLExporter.export_entry() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | #!/usr/bin/env python |
||
21 | @classmethod |
||
22 | def export_entry(cls, entry, to_multifile=True): |
||
23 | """Returns a markdown representation of a single entry, with YAML front matter.""" |
||
24 | if to_multifile is False: |
||
25 | print( |
||
26 | f"{ERROR_COLOR}ERROR{RESET_COLOR}: YAML export must be to individual files. Please \ |
||
27 | specify a directory to export to.", |
||
28 | file=sys.stderr, |
||
29 | ) |
||
30 | return |
||
31 | |||
32 | date_str = entry.date.strftime(entry.journal.config["timeformat"]) |
||
33 | body_wrapper = "\n" if entry.body else "" |
||
34 | body = body_wrapper + entry.body |
||
35 | |||
36 | tagsymbols = entry.journal.config["tagsymbols"] |
||
37 | # see also Entry.Entry.rag_regex |
||
38 | multi_tag_regex = re.compile(fr"(?u)^\s*([{tagsymbols}][-+*#/\w]+\s*)+$") |
||
39 | |||
40 | """Increase heading levels in body text""" |
||
41 | newbody = "" |
||
42 | heading = "#" |
||
43 | previous_line = "" |
||
44 | warn_on_heading_level = False |
||
45 | for line in body.splitlines(True): |
||
46 | View Code Duplication | if re.match(r"^#+ ", line): |
|
|
|||
47 | """ATX style headings""" |
||
48 | newbody = newbody + previous_line + heading + line |
||
49 | if re.match(r"^#######+ ", heading + line): |
||
50 | warn_on_heading_level = True |
||
51 | line = "" |
||
52 | elif re.match(r"^=+$", line.rstrip()) and not re.match( |
||
53 | r"^$", previous_line.strip() |
||
54 | ): |
||
55 | """Setext style H1""" |
||
56 | newbody = newbody + heading + "# " + previous_line |
||
57 | line = "" |
||
58 | elif re.match(r"^-+$", line.rstrip()) and not re.match( |
||
59 | r"^$", previous_line.strip() |
||
60 | ): |
||
61 | """Setext style H2""" |
||
62 | newbody = newbody + heading + "## " + previous_line |
||
63 | line = "" |
||
64 | elif multi_tag_regex.match(line): |
||
65 | """Tag only lines""" |
||
66 | line = "" |
||
67 | else: |
||
68 | newbody = newbody + previous_line |
||
69 | previous_line = line |
||
70 | newbody = newbody + previous_line # add very last line |
||
71 | |||
72 | # make sure the export ends with a blank line |
||
73 | if previous_line not in ["\r", "\n", "\r\n", "\n\r"]: |
||
74 | newbody = newbody + os.linesep |
||
75 | |||
76 | if warn_on_heading_level is True: |
||
77 | print( |
||
78 | "{}WARNING{}: Headings increased past H6 on export - {} {}".format( |
||
79 | WARNING_COLOR, RESET_COLOR, date_str, entry.title |
||
80 | ), |
||
81 | file=sys.stderr, |
||
82 | ) |
||
83 | |||
84 | dayone_attributes = "" |
||
85 | if hasattr(entry, "uuid"): |
||
86 | dayone_attributes += "uuid: " + entry.uuid + "\n" |
||
87 | if ( |
||
88 | hasattr(entry, "creator_device_agent") |
||
89 | or hasattr(entry, "creator_generation_date") |
||
90 | or hasattr(entry, "creator_host_name") |
||
91 | or hasattr(entry, "creator_os_agent") |
||
92 | or hasattr(entry, "creator_software_agent") |
||
93 | ): |
||
94 | dayone_attributes += "creator:\n" |
||
95 | if hasattr(entry, "creator_device_agent"): |
||
96 | dayone_attributes += f" device agent: {entry.creator_device_agent}\n" |
||
97 | if hasattr(entry, "creator_generation_date"): |
||
98 | dayone_attributes += " generation date: {}\n".format( |
||
99 | str(entry.creator_generation_date) |
||
100 | ) |
||
101 | if hasattr(entry, "creator_host_name"): |
||
102 | dayone_attributes += f" host name: {entry.creator_host_name}\n" |
||
103 | if hasattr(entry, "creator_os_agent"): |
||
104 | dayone_attributes += f" os agent: {entry.creator_os_agent}\n" |
||
105 | if hasattr(entry, "creator_software_agent"): |
||
106 | dayone_attributes += ( |
||
107 | f" software agent: {entry.creator_software_agent}\n" |
||
108 | ) |
||
109 | |||
110 | # TODO: copy over pictures, if present |
||
111 | # source directory is entry.journal.config['journal'] |
||
112 | # output directory is...? |
||
113 | |||
114 | return "title: {title}\ndate: {date}\nstarred: {starred}\ntags: {tags}\n{dayone} {body} {space}".format( |
||
115 | date=date_str, |
||
116 | title=entry.title, |
||
117 | starred=entry.starred, |
||
118 | tags=", ".join([tag[1:] for tag in entry.tags]), |
||
119 | dayone=dayone_attributes, |
||
120 | body=newbody, |
||
121 | space="", |
||
122 | ) |
||
134 |