|
41 | 41 | [local header](#some-header)
|
42 | 42 | """
|
43 | 43 |
|
44 |
| -# The markdown files use posix-style paths, so we need posixpath for |
45 |
| -# processing them. See help('posixpath'). |
46 | 44 | import os
|
47 | 45 | import posixpath
|
48 | 46 |
|
49 | 47 | import common
|
50 | 48 |
|
51 | 49 |
|
52 |
| -class Link: |
| 50 | +def check(filepath, target): |
| 51 | + """Check if a link's target is like it should be. |
53 | 52 |
|
54 |
| - def __init__(self, regexmatch, filepath, lineno): |
55 |
| - # The .group(0) is not perfect, but it's good enough. |
56 |
| - self.markdown = regexmatch.group(0) |
57 |
| - self.text = regexmatch.group(1) |
58 |
| - self.target = regexmatch.group(2) |
59 |
| - self.filepath = filepath |
60 |
| - self.lineno = lineno |
61 |
| - self.status = None |
| 53 | + Return an error message string or "ok". |
| 54 | + """ |
| 55 | + if target.startswith(('http://', 'https://')): |
| 56 | + # We don't need this currently, but checking these links could |
| 57 | + # be added later. |
| 58 | + return "ok" |
62 | 59 |
|
63 |
| - def _get_status(self): |
64 |
| - if self.target.startswith(('http://', 'https://')): |
65 |
| - # Checking for http(s) links can be added later, but |
66 |
| - # currently it's not needed. |
| 60 | + if '#' in target: |
| 61 | + where = target.index('#') |
| 62 | + if where == 0: |
| 63 | + # It's a link to a title in the same file, we need to skip it. |
67 | 64 | return "ok"
|
68 |
| - |
69 |
| - target = self.target |
70 |
| - if '#' in target: |
71 |
| - where = target.index('#') |
72 |
| - if where == 0: |
73 |
| - # It's a link to a title in the same file, we need to |
74 |
| - # skip it. |
75 |
| - return "ok" |
76 |
| - target = target[:where] |
77 |
| - |
78 |
| - path = posixpath.join(posixpath.dirname(self.filepath), target) |
79 |
| - realpath = path.replace('/', os.sep) |
80 |
| - |
81 |
| - if not os.path.exists(realpath): |
82 |
| - return "doesn't exist" |
83 |
| - if target.endswith('/'): |
84 |
| - # A directory. |
85 |
| - if os.path.isdir(realpath): |
86 |
| - return "ok" |
87 |
| - return "not a directory" |
88 |
| - else: |
89 |
| - # A file. |
90 |
| - if os.path.isfile(realpath): |
91 |
| - return "ok" |
92 |
| - return "not a file" |
93 |
| - |
94 |
| - def check(self): |
95 |
| - """Check if the link's target is like it should be. |
96 |
| -
|
97 |
| - Return an error message string or "ok". The return value is also |
98 |
| - assigned to the status attribute. |
99 |
| - """ |
100 |
| - self.status = self._get_status() |
101 |
| - return self.status |
102 |
| - |
103 |
| - def print_status(self): |
104 |
| - print(" file {0.filepath}, line {0.lineno}: {0.status}".format(self)) |
105 |
| - print(" " + self.markdown) |
106 |
| - print() |
| 65 | + target = target[:where] |
| 66 | + |
| 67 | + path = posixpath.join(posixpath.dirname(filepath), target) |
| 68 | + realpath = common.slashfix(path) |
| 69 | + if not os.path.exists(realpath): |
| 70 | + return "doesn't exist" |
| 71 | + if target.endswith('/'): |
| 72 | + # A directory. |
| 73 | + if os.path.isdir(realpath): |
| 74 | + return "ok" |
| 75 | + return "not a directory" |
| 76 | + else: |
| 77 | + # A file. |
| 78 | + if os.path.isfile(realpath): |
| 79 | + return "ok" |
| 80 | + return "not a file" |
107 | 81 |
|
108 | 82 |
|
109 | 83 | def main():
|
110 |
| - print("Searching links...") |
111 |
| - links = [] |
| 84 | + print("Searching and checking links...") |
| 85 | + broken = 0 |
| 86 | + total = 0 |
112 | 87 | for path in common.get_markdown_files():
|
113 | 88 | with common.slashfix_open(path, 'r') as f:
|
114 | 89 | for match, lineno in common.find_links(f):
|
115 |
| - links.append(Link(match, path, lineno)) |
116 |
| - print(" found", len(links), "links") |
117 |
| - |
118 |
| - print("Checking for broken links...") |
119 |
| - brokens = 0 |
120 |
| - for link in links: |
121 |
| - if link.check() != "ok": |
122 |
| - link.print_status() |
123 |
| - brokens += 1 |
124 |
| - |
125 |
| - if brokens == 0: |
126 |
| - print("All links seem to be OK.") |
127 |
| - elif brokens == 1: |
128 |
| - print("1 link is broken!") |
129 |
| - else: |
130 |
| - print(brokens, "links are broken!") |
| 90 | + text, target = match.groups() |
| 91 | + status = check(path, target) |
| 92 | + if status != "ok": |
| 93 | + # The .group(0) is not perfect, but it's good enough. |
| 94 | + print(" file %s, line %d: %s" % (path, lineno, status)) |
| 95 | + print(" " + match.group(0)) |
| 96 | + print() |
| 97 | + broken += 1 |
| 98 | + total += 1 |
| 99 | + print("%d/%d links seem to be broken." % (broken, total)) |
131 | 100 |
|
132 | 101 |
|
133 | 102 | if __name__ == '__main__':
|
|
0 commit comments