diff --git a/llamafile/highlight.h b/llamafile/highlight.h index 96a638d5ee..394eb07bee 100644 --- a/llamafile/highlight.h +++ b/llamafile/highlight.h @@ -145,6 +145,8 @@ is_keyword_f is_keyword_ocaml; is_keyword_f is_keyword_ocaml_builtin; is_keyword_f is_keyword_ocaml_constant; is_keyword_f is_keyword_cmake; +is_keyword_f is_keyword_css_at; +is_keyword_f is_keyword_css_bang; } class Highlight { @@ -366,6 +368,7 @@ class HighlightCss : public Highlight { private: int t_ = 0; + std::string word_; }; class HighlightHtml : public Highlight { diff --git a/llamafile/highlight_css.cpp b/llamafile/highlight_css.cpp index 16f1d3581b..a0f72813d5 100644 --- a/llamafile/highlight_css.cpp +++ b/llamafile/highlight_css.cpp @@ -31,6 +31,8 @@ enum { SLASH, SLASH_STAR, SLASH_STAR_STAR, + AT, + BANG, }; HighlightCss::HighlightCss() { @@ -52,6 +54,7 @@ void HighlightCss::feed(std::string *r, std::string_view input) { t_ = SELECTOR; // fallthrough + Selector: case SELECTOR: if (c == '{') { t_ = PROPERTY; @@ -64,6 +67,8 @@ void HighlightCss::feed(std::string *r, std::string_view input) { *r += HI_SELECTOR; } else if (c == '/') { t_ = SELECTOR << 8 | SLASH; + } else if (c == '@') { + t_ = SELECTOR << 8 | AT; } else if (c == '\'') { t_ = SELECTOR << 8 | QUOTE; *r += HI_STRING; @@ -77,9 +82,12 @@ void HighlightCss::feed(std::string *r, std::string_view input) { } break; + Property: case PROPERTY: if (c == '/') { t_ = PROPERTY << 8 | SLASH; + } else if (c == '@') { + t_ = VALUE << 8 | AT; } else if (c == '\'') { t_ = PROPERTY << 8 | QUOTE; *r += HI_STRING; @@ -102,9 +110,14 @@ void HighlightCss::feed(std::string *r, std::string_view input) { } break; + Value: case VALUE: if (c == '/') { t_ = VALUE << 8 | SLASH; + } else if (c == '@') { + t_ = VALUE << 8 | AT; + } else if (c == '!') { + t_ = VALUE << 8 | BANG; } else if (c == '\'') { t_ = VALUE << 8 | QUOTE; *r += HI_STRING; @@ -126,6 +139,60 @@ void HighlightCss::feed(std::string *r, std::string_view input) { } break; + case AT: + if (isalpha(c) || c == '-') { + word_ += c; + } else { + if (is_keyword_css_at(word_.data(), word_.size())) { + *r += HI_BUILTIN; + *r += '@'; + *r += word_; + *r += HI_RESET; + } else { + *r += '@'; + *r += word_; + } + word_.clear(); + t_ >>= 8; + switch (t_ & 255) { + case SELECTOR: + *r += HI_SELECTOR; + goto Selector; + case PROPERTY: + *r += HI_PROPERTY; + goto Property; + case VALUE: + goto Value; + default: + __builtin_unreachable(); + } + } + break; + + case BANG: + if (isalpha(c) || c == '-') { + word_ += c; + } else { + if (is_keyword_css_bang(word_.data(), word_.size())) { + *r += HI_WARNING; + *r += '!'; + *r += word_; + *r += HI_RESET; + } else { + *r += '!'; + *r += word_; + } + word_.clear(); + t_ >>= 8; + switch (t_ & 255) { + case VALUE: + goto Value; + default: + __builtin_unreachable(); + } + } + break; + case SLASH: if (c == '*') { *r += HI_COMMENT; @@ -207,18 +274,31 @@ void HighlightCss::feed(std::string *r, std::string_view input) { } void HighlightCss::flush(std::string *r) { - switch (t_ & 255) { - case SLASH: - *r += '/'; - break; - case SELECTOR: - case PROPERTY: - case DQUOTE: - case DQUOTE_BACKSLASH: - *r += HI_RESET; - break; - default: - break; + while (t_) { + switch (t_ & 255) { + case AT: + *r += '@'; + *r += word_; + word_.clear(); + break; + case BANG: + *r += '!'; + *r += word_; + word_.clear(); + break; + case SLASH: + *r += '/'; + break; + case SELECTOR: + case PROPERTY: + case DQUOTE: + case DQUOTE_BACKSLASH: + *r += HI_RESET; + break; + default: + break; + } + t_ >>= 8; } *r += HI_RESET; t_ = NORMAL; diff --git a/llamafile/is_keyword_css_at.gperf b/llamafile/is_keyword_css_at.gperf new file mode 100644 index 0000000000..1e98c895ca --- /dev/null +++ b/llamafile/is_keyword_css_at.gperf @@ -0,0 +1,17 @@ +%{ +#include +%} +%pic +%compare-strncmp +%language=ANSI-C +%readonly-tables +%define lookup-function-name is_keyword_css_at +%% +charset +font-face +import +keyframes +media +namespace +page +supports diff --git a/llamafile/is_keyword_css_bang.gperf b/llamafile/is_keyword_css_bang.gperf new file mode 100644 index 0000000000..18c221c098 --- /dev/null +++ b/llamafile/is_keyword_css_bang.gperf @@ -0,0 +1,10 @@ +%{ +#include +%} +%pic +%compare-strncmp +%language=ANSI-C +%readonly-tables +%define lookup-function-name is_keyword_css_bang +%% +important diff --git a/llamafile/server/www/chatbot.css b/llamafile/server/www/chatbot.css index f4b1dacb75..365269e122 100644 --- a/llamafile/server/www/chatbot.css +++ b/llamafile/server/www/chatbot.css @@ -260,3 +260,37 @@ ul li:first-child { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } } + +@media print { + + .noprint { + display: none; + } + + .copy-button { + display: none; + } + + .chat-container { + box-shadow: none; + } + + .chat-header { + border: none !important; + } + + .chat-messages { + overflow-y: visible; + border: none !important; + height: auto !important; + max-width: none !important; + } + + .message { + max-width: none !important; + } + + .message.user { + border: 1px solid #999; + } +} diff --git a/llamafile/server/www/index.html b/llamafile/server/www/index.html index 6d3c10dfe2..4883e559e5 100644 --- a/llamafile/server/www/index.html +++ b/llamafile/server/www/index.html @@ -15,12 +15,12 @@

[logo] llamafile

Loading... -
+
-
+