|
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