| 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 |