Cleanup highlighting code
Removes some unused code and de-publicizes structs
This commit is contained in:
parent
7bea518d3a
commit
8e65a46268
3 changed files with 23 additions and 42 deletions
|
@ -13,12 +13,7 @@
|
||||||
//! This module uses libsyntax's lexer to provide token-based highlighting for
|
//! This module uses libsyntax's lexer to provide token-based highlighting for
|
||||||
//! the HTML documentation generated by rustdoc.
|
//! the HTML documentation generated by rustdoc.
|
||||||
//!
|
//!
|
||||||
//! If you just want to syntax highlighting for a Rust program, then you can use
|
//! Use the `render_with_highlighting` to highlight some rust code.
|
||||||
//! the `render_inner_with_highlighting` or `render_with_highlighting`
|
|
||||||
//! functions. For more advanced use cases (if you want to supply your own css
|
|
||||||
//! classes or control how the HTML is generated, or even generate something
|
|
||||||
//! other then HTML), then you should implement the `Writer` trait and use a
|
|
||||||
//! `Classifier`.
|
|
||||||
|
|
||||||
use html::escape::Escape;
|
use html::escape::Escape;
|
||||||
|
|
||||||
|
@ -33,7 +28,7 @@ use syntax::parse;
|
||||||
use syntax_pos::{Span, FileName};
|
use syntax_pos::{Span, FileName};
|
||||||
|
|
||||||
/// Highlights `src`, returning the HTML output.
|
/// Highlights `src`, returning the HTML output.
|
||||||
pub fn render_with_highlighting(src: &str, class: Option<&str>, id: Option<&str>,
|
pub fn render_with_highlighting(src: &str, class: Option<&str>,
|
||||||
extension: Option<&str>,
|
extension: Option<&str>,
|
||||||
tooltip: Option<(&str, &str)>) -> String {
|
tooltip: Option<(&str, &str)>) -> String {
|
||||||
debug!("highlighting: ================\n{}\n==============", src);
|
debug!("highlighting: ================\n{}\n==============", src);
|
||||||
|
@ -46,7 +41,7 @@ pub fn render_with_highlighting(src: &str, class: Option<&str>, id: Option<&str>
|
||||||
class='tooltiptext'>{}</span></div></div>",
|
class='tooltiptext'>{}</span></div></div>",
|
||||||
class, tooltip).unwrap();
|
class, tooltip).unwrap();
|
||||||
}
|
}
|
||||||
write_header(class, id, &mut out).unwrap();
|
write_header(class, &mut out).unwrap();
|
||||||
|
|
||||||
let mut classifier = Classifier::new(lexer::StringReader::new(&sess, fm, None), sess.codemap());
|
let mut classifier = Classifier::new(lexer::StringReader::new(&sess, fm, None), sess.codemap());
|
||||||
if let Err(_) = classifier.write_source(&mut out) {
|
if let Err(_) = classifier.write_source(&mut out) {
|
||||||
|
@ -63,7 +58,7 @@ pub fn render_with_highlighting(src: &str, class: Option<&str>, id: Option<&str>
|
||||||
/// Processes a program (nested in the internal `lexer`), classifying strings of
|
/// Processes a program (nested in the internal `lexer`), classifying strings of
|
||||||
/// text by highlighting category (`Class`). Calls out to a `Writer` to write
|
/// text by highlighting category (`Class`). Calls out to a `Writer` to write
|
||||||
/// each span of text in sequence.
|
/// each span of text in sequence.
|
||||||
pub struct Classifier<'a> {
|
struct Classifier<'a> {
|
||||||
lexer: lexer::StringReader<'a>,
|
lexer: lexer::StringReader<'a>,
|
||||||
codemap: &'a CodeMap,
|
codemap: &'a CodeMap,
|
||||||
|
|
||||||
|
@ -75,7 +70,7 @@ pub struct Classifier<'a> {
|
||||||
|
|
||||||
/// How a span of text is classified. Mostly corresponds to token kinds.
|
/// How a span of text is classified. Mostly corresponds to token kinds.
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
pub enum Class {
|
enum Class {
|
||||||
None,
|
None,
|
||||||
Comment,
|
Comment,
|
||||||
DocComment,
|
DocComment,
|
||||||
|
@ -103,7 +98,7 @@ pub enum Class {
|
||||||
/// The classifier will call into the `Writer` implementation as it finds spans
|
/// The classifier will call into the `Writer` implementation as it finds spans
|
||||||
/// of text to highlight. Exactly how that text should be highlighted is up to
|
/// of text to highlight. Exactly how that text should be highlighted is up to
|
||||||
/// the implementation.
|
/// the implementation.
|
||||||
pub trait Writer {
|
trait Writer {
|
||||||
/// Called when we start processing a span of text that should be highlighted.
|
/// Called when we start processing a span of text that should be highlighted.
|
||||||
/// The `Class` argument specifies how it should be highlighted.
|
/// The `Class` argument specifies how it should be highlighted.
|
||||||
fn enter_span(&mut self, _: Class) -> io::Result<()>;
|
fn enter_span(&mut self, _: Class) -> io::Result<()>;
|
||||||
|
@ -111,11 +106,9 @@ pub trait Writer {
|
||||||
/// Called at the end of a span of highlighted text.
|
/// Called at the end of a span of highlighted text.
|
||||||
fn exit_span(&mut self) -> io::Result<()>;
|
fn exit_span(&mut self) -> io::Result<()>;
|
||||||
|
|
||||||
/// Called for a span of text, usually, but not always, a single token. If
|
/// Called for a span of text. If the text should be highlighted differently from the
|
||||||
/// the string of text (`T`) does correspond to a token, then the token will
|
/// surrounding text, then the `Class` argument will be a value other than `None`.
|
||||||
/// also be passed. If the text should be highlighted differently from the
|
///
|
||||||
/// surrounding text, then the `Class` argument will be a value other than
|
|
||||||
/// `None`.
|
|
||||||
/// The following sequences of callbacks are equivalent:
|
/// The following sequences of callbacks are equivalent:
|
||||||
/// ```plain
|
/// ```plain
|
||||||
/// enter_span(Foo), string("text", None), exit_span()
|
/// enter_span(Foo), string("text", None), exit_span()
|
||||||
|
@ -125,8 +118,7 @@ pub trait Writer {
|
||||||
/// more flexible.
|
/// more flexible.
|
||||||
fn string<T: Display>(&mut self,
|
fn string<T: Display>(&mut self,
|
||||||
text: T,
|
text: T,
|
||||||
klass: Class,
|
klass: Class)
|
||||||
tok: Option<&TokenAndSpan>)
|
|
||||||
-> io::Result<()>;
|
-> io::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,8 +127,7 @@ pub trait Writer {
|
||||||
impl<U: Write> Writer for U {
|
impl<U: Write> Writer for U {
|
||||||
fn string<T: Display>(&mut self,
|
fn string<T: Display>(&mut self,
|
||||||
text: T,
|
text: T,
|
||||||
klass: Class,
|
klass: Class)
|
||||||
_tas: Option<&TokenAndSpan>)
|
|
||||||
-> io::Result<()> {
|
-> io::Result<()> {
|
||||||
match klass {
|
match klass {
|
||||||
Class::None => write!(self, "{}", text),
|
Class::None => write!(self, "{}", text),
|
||||||
|
@ -154,7 +145,7 @@ impl<U: Write> Writer for U {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Classifier<'a> {
|
impl<'a> Classifier<'a> {
|
||||||
pub fn new(lexer: lexer::StringReader<'a>, codemap: &'a CodeMap) -> Classifier<'a> {
|
fn new(lexer: lexer::StringReader<'a>, codemap: &'a CodeMap) -> Classifier<'a> {
|
||||||
Classifier {
|
Classifier {
|
||||||
lexer,
|
lexer,
|
||||||
codemap,
|
codemap,
|
||||||
|
@ -186,7 +177,7 @@ impl<'a> Classifier<'a> {
|
||||||
/// is used. All source code emission is done as slices from the source map,
|
/// is used. All source code emission is done as slices from the source map,
|
||||||
/// not from the tokens themselves, in order to stay true to the original
|
/// not from the tokens themselves, in order to stay true to the original
|
||||||
/// source.
|
/// source.
|
||||||
pub fn write_source<W: Writer>(&mut self,
|
fn write_source<W: Writer>(&mut self,
|
||||||
out: &mut W)
|
out: &mut W)
|
||||||
-> io::Result<()> {
|
-> io::Result<()> {
|
||||||
loop {
|
loop {
|
||||||
|
@ -208,7 +199,7 @@ impl<'a> Classifier<'a> {
|
||||||
-> io::Result<()> {
|
-> io::Result<()> {
|
||||||
let klass = match tas.tok {
|
let klass = match tas.tok {
|
||||||
token::Shebang(s) => {
|
token::Shebang(s) => {
|
||||||
out.string(Escape(&s.as_str()), Class::None, Some(&tas))?;
|
out.string(Escape(&s.as_str()), Class::None)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -272,8 +263,8 @@ impl<'a> Classifier<'a> {
|
||||||
self.in_attribute = true;
|
self.in_attribute = true;
|
||||||
out.enter_span(Class::Attribute)?;
|
out.enter_span(Class::Attribute)?;
|
||||||
}
|
}
|
||||||
out.string("#", Class::None, None)?;
|
out.string("#", Class::None)?;
|
||||||
out.string("!", Class::None, None)?;
|
out.string("!", Class::None)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,13 +273,13 @@ impl<'a> Classifier<'a> {
|
||||||
self.in_attribute = true;
|
self.in_attribute = true;
|
||||||
out.enter_span(Class::Attribute)?;
|
out.enter_span(Class::Attribute)?;
|
||||||
}
|
}
|
||||||
out.string("#", Class::None, None)?;
|
out.string("#", Class::None)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
token::CloseDelim(token::Bracket) => {
|
token::CloseDelim(token::Bracket) => {
|
||||||
if self.in_attribute {
|
if self.in_attribute {
|
||||||
self.in_attribute = false;
|
self.in_attribute = false;
|
||||||
out.string("]", Class::None, None)?;
|
out.string("]", Class::None)?;
|
||||||
out.exit_span()?;
|
out.exit_span()?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
} else {
|
||||||
|
@ -344,7 +335,7 @@ impl<'a> Classifier<'a> {
|
||||||
|
|
||||||
// Anything that didn't return above is the simple case where we the
|
// Anything that didn't return above is the simple case where we the
|
||||||
// class just spans a single token, so we can use the `string` method.
|
// class just spans a single token, so we can use the `string` method.
|
||||||
out.string(Escape(&self.snip(tas.sp)), klass, Some(&tas))
|
out.string(Escape(&self.snip(tas.sp)), klass)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to get a snippet from the codemap.
|
// Helper function to get a snippet from the codemap.
|
||||||
|
@ -355,7 +346,7 @@ impl<'a> Classifier<'a> {
|
||||||
|
|
||||||
impl Class {
|
impl Class {
|
||||||
/// Returns the css class expected by rustdoc for each `Class`.
|
/// Returns the css class expected by rustdoc for each `Class`.
|
||||||
pub fn rustdoc_class(self) -> &'static str {
|
fn rustdoc_class(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Class::None => "",
|
Class::None => "",
|
||||||
Class::Comment => "comment",
|
Class::Comment => "comment",
|
||||||
|
@ -379,15 +370,8 @@ impl Class {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_header(class: Option<&str>,
|
fn write_header(class: Option<&str>, out: &mut Write) -> io::Result<()> {
|
||||||
id: Option<&str>,
|
write!(out, "<pre class=\"rust {}\">\n", class.unwrap_or(""))
|
||||||
out: &mut dyn Write)
|
|
||||||
-> io::Result<()> {
|
|
||||||
write!(out, "<pre ")?;
|
|
||||||
if let Some(id) = id {
|
|
||||||
write!(out, "id='{}' ", id)?;
|
|
||||||
}
|
|
||||||
write!(out, "class=\"rust {}\">\n", class.unwrap_or(""))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_footer(out: &mut dyn Write) -> io::Result<()> {
|
fn write_footer(out: &mut dyn Write) -> io::Result<()> {
|
||||||
|
|
|
@ -247,7 +247,6 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
|
||||||
if ignore { " ignore" }
|
if ignore { " ignore" }
|
||||||
else if compile_fail { " compile_fail" }
|
else if compile_fail { " compile_fail" }
|
||||||
else { "" })),
|
else { "" })),
|
||||||
None,
|
|
||||||
playground_button.as_ref().map(String::as_str),
|
playground_button.as_ref().map(String::as_str),
|
||||||
tooltip));
|
tooltip));
|
||||||
Some(Event::Html(s.into()))
|
Some(Event::Html(s.into()))
|
||||||
|
|
|
@ -2239,7 +2239,6 @@ fn render_assoc_const_value(item: &clean::Item) -> String {
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => String::new(),
|
_ => String::new(),
|
||||||
|
@ -4551,7 +4550,7 @@ impl<'a> fmt::Display for Source<'a> {
|
||||||
}
|
}
|
||||||
write!(fmt, "</pre>")?;
|
write!(fmt, "</pre>")?;
|
||||||
write!(fmt, "{}",
|
write!(fmt, "{}",
|
||||||
highlight::render_with_highlighting(s, None, None, None, None))?;
|
highlight::render_with_highlighting(s, None, None, None))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4562,7 +4561,6 @@ fn item_macro(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
w.write_str(&highlight::render_with_highlighting(&t.source,
|
w.write_str(&highlight::render_with_highlighting(&t.source,
|
||||||
Some("macro"),
|
Some("macro"),
|
||||||
None,
|
None,
|
||||||
None,
|
|
||||||
None))
|
None))
|
||||||
})?;
|
})?;
|
||||||
document(w, cx, it)
|
document(w, cx, it)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue