Skip to content

Commit c03bb2b

Browse files
authored
Rollup merge of #39790 - zackw:tidy-linelen-exempt-urls, r=alexcrichton
tidy: exempt URLs from the line length restriction The length of a URL is usually not under our control, and Markdown provides no way to split a URL in the middle. Therefore, comment lines consisting _solely_ of a URL (possibly with a Markdown link label in front) should be exempt from the line-length restriction. Inline hyperlink destinations ( `[foo](http://...)` notation ) are _not_ exempt, because it is my arrogant opinion that long lines of that type make the source text illegible. The patch adds dependencies on the `regex` and `lazy_static` crates to the tidy utility. This _appears_ to Just Work, but if you would rather not have that dependency I am willing to provide a hand-written parser instead.
2 parents da26d78 + ff4758c commit c03bb2b

File tree

1 file changed

+57
-2
lines changed

1 file changed

+57
-2
lines changed

src/tools/tidy/src/style.rs

+57-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,60 @@ http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3838
option. This file may not be copied, modified, or distributed
3939
except according to those terms.";
4040

41+
/// Parser states for line_is_url.
42+
#[derive(PartialEq)]
43+
#[allow(non_camel_case_types)]
44+
enum LIUState { EXP_COMMENT_START,
45+
EXP_LINK_LABEL_OR_URL,
46+
EXP_URL,
47+
EXP_END }
48+
49+
/// True if LINE appears to be a line comment containing an URL,
50+
/// possibly with a Markdown link label in front, and nothing else.
51+
/// The Markdown link label, if present, may not contain whitespace.
52+
/// Lines of this form are allowed to be overlength, because Markdown
53+
/// offers no way to split a line in the middle of a URL, and the lengths
54+
/// of URLs to external references are beyond our control.
55+
fn line_is_url(line: &str) -> bool {
56+
use self::LIUState::*;
57+
let mut state: LIUState = EXP_COMMENT_START;
58+
59+
for tok in line.split_whitespace() {
60+
match (state, tok) {
61+
(EXP_COMMENT_START, "//") => state = EXP_LINK_LABEL_OR_URL,
62+
(EXP_COMMENT_START, "///") => state = EXP_LINK_LABEL_OR_URL,
63+
(EXP_COMMENT_START, "//!") => state = EXP_LINK_LABEL_OR_URL,
64+
65+
(EXP_LINK_LABEL_OR_URL, w)
66+
if w.len() >= 4 && w.starts_with("[") && w.ends_with("]:")
67+
=> state = EXP_URL,
68+
69+
(EXP_LINK_LABEL_OR_URL, w)
70+
if w.starts_with("http://") || w.starts_with("https://")
71+
=> state = EXP_END,
72+
73+
(EXP_URL, w)
74+
if w.starts_with("http://") || w.starts_with("https://")
75+
=> state = EXP_END,
76+
77+
(_, _) => return false,
78+
}
79+
}
80+
81+
state == EXP_END
82+
}
83+
84+
/// True if LINE is allowed to be longer than the normal limit.
85+
/// Currently there is only one exception, for long URLs, but more
86+
/// may be added in the future.
87+
fn long_line_is_ok(line: &str) -> bool {
88+
if line_is_url(line) {
89+
return true;
90+
}
91+
92+
false
93+
}
94+
4195
pub fn check(path: &Path, bad: &mut bool) {
4296
let mut contents = String::new();
4397
super::walk(path, &mut super::filter_dirs, &mut |file| {
@@ -61,8 +115,9 @@ pub fn check(path: &Path, bad: &mut bool) {
61115
println!("{}:{}: {}", file.display(), i + 1, msg);
62116
*bad = true;
63117
};
64-
if line.chars().count() > COLS && !skip_length {
65-
err(&format!("line longer than {} chars", COLS));
118+
if !skip_length && line.chars().count() > COLS
119+
&& !long_line_is_ok(line) {
120+
err(&format!("line longer than {} chars", COLS));
66121
}
67122
if line.contains("\t") && !skip_tab {
68123
err("tab character");

0 commit comments

Comments
 (0)