Support bold+italic in HTML conversion

This commit is contained in:
Yorhel 2017-01-16 09:52:32 +01:00
parent 746889851c
commit 1923b9901d
2 changed files with 45 additions and 17 deletions

View file

@ -12,6 +12,37 @@ enum FmtChar {
Regular,
Italic,
Bold,
Both,
}
impl FmtChar {
fn add(self, b: Self) -> Self {
match (self, b) {
(FmtChar::Regular, x) |
(x, FmtChar::Regular) => x,
(FmtChar::Italic, FmtChar::Bold) |
(FmtChar::Bold, FmtChar::Italic) => FmtChar::Both,
_ => self
}
}
fn open(self) -> &'static str {
match self {
FmtChar::Regular => "",
FmtChar::Italic => "<i>",
FmtChar::Bold => "<b>",
FmtChar::Both => "<em>",
}
}
fn close(self) -> &'static str {
match self {
FmtChar::Regular => "",
FmtChar::Italic => "</i>",
FmtChar::Bold => "</b>",
FmtChar::Both => "</em>",
}
}
}
@ -57,9 +88,14 @@ impl CharParse {
Some((c, f))
},
CharParse::Escape(c, _) => {
// TODO: Handle combination of bold & italic
*self = CharParse::Token(chr, if c == '_' { FmtChar::Italic } else { FmtChar::Bold });
CharParse::Escape(c, f) => {
*self = if c == '_' {
CharParse::Token(chr, f.add(FmtChar::Italic))
} else if chr == '_' {
CharParse::Token(c, f.add(FmtChar::Italic))
} else {
CharParse::Token(chr, f.add(FmtChar::Bold))
};
None
},
}
@ -68,11 +104,9 @@ impl CharParse {
fn pushfmt(out: &mut String, old: FmtChar, new: FmtChar) {
if new != old && old != FmtChar::Regular {
out.push_str(if old == FmtChar::Italic { "</i>" } else { "</b>" });
}
if new != old && new != FmtChar::Regular {
out.push_str(if new == FmtChar::Italic { "<i>" } else { "<b>" });
if new != old {
out.push_str(old.close());
out.push_str(new.open());
}
}
@ -133,7 +167,7 @@ impl FmtBuf {
st.idx = chunk;
lastfmt = fmt;
}
pushfmt(st.out, lastfmt, FmtChar::Regular);
st.out.push_str(lastfmt.close());
}
// Consume the input buffer until 'end' without generating output
@ -276,13 +310,6 @@ pub fn grotty2html(input: &str) -> String {
for chr in input.chars() {
if let Some((chr, fmt)) = state.update(chr) {
buf.push(chr, fmt);
// Line-based flushing is also possible, but not as fast.
//if chr == '\n' {
// buf.flush(&mut out);
// buf.buf.clear();
// buf.fmt.clear();
// buf.lastfmt = FmtChar::Regular;
//}
}
}
if let CharParse::Token(chr, fmt) = state {

View file

@ -120,7 +120,8 @@ i.grayedout { color: #aaa; font-size: 13px; }
#footer a:hover { background: none; }
pre, pre * { font-family: "Lucida Console", Monospace; font-size: 15px }
pre b, pre a { color: #369; font-weight: normal; text-decoration: none }
pre b, pre em, pre a { color: #369; font-weight: normal; text-decoration: none }
pre em { font-style: italic }
#ds_box { position: absolute; top: 0; border: 1px solid $border$; border-top: none; background: #f0f8ff; cursor: pointer; z-index: 2 }
#ds_box b { padding: 2px 0 0 10px; font-size: 12px; }