| Did you know ... | Search Documentation: | 
|  | Pack tailwind_pl -- README.md | 
Tailwind_pl is a pack for SWI-Prolog that lets you do CSS styling with TailwindCSS without any Node.js dependency. It is effectively a rewrite of Tailwind's JIT compiler in Prolog, inspired by Girouette's approach in Clojure.
Tailwind_pl watches the given directories for changes to Prolog files, searches for Tailwind-style CSS selectors and generates a CSS file containing just the used selectors.
Tailwind_pl also extends Tailwind by allowing more dynamic class-names that use exact colours or numbers (ex. w-42%).
``` prolog
?- pack_install(tailwind_pl).
## Example Usage
``` prolog
  :- module(myapp, [go/1]).
:- use_module(library(filesex), [directory_file_path/3, make_directory_path/1]).
:- use_module(library(http/http_dispatch), [http_redirect/3,
                                            http_dispatch/1,
                                            http_reply_file/3,
                                            http_handler/3,
                                            http_location_by_id/2
                                           ]).
:- use_module(library(http/html_write), [html//1,
                                         reply_html_page/2,
                                         html_receive//1]).
:- use_module(library(http/thread_httpd), [http_server/2,
                                           http_stop_server/2]).
:- use_module(library(tailwind), [start_watching_dirs/3,
                                  stop_watching_dirs/1,
                                  reset_style/1]).
%! go(+Port) is det.
%  Interactive entry point to start the server.
go(Port) :-
    start_css_watcher,
    http_server(http_dispatch, [port(Port)]).
user:file_search_path(css, CssDir) :-
    working_directory(Cwd, Cwd),
    directory_file_path(Cwd, "../resources/css", CssDir).
:- dynamic css_watcher/1.
start_css_watcher :-
    stop_css_watcher,
    working_directory(Cwd, Cwd),
    directory_file_path(Cwd, "../resources/css", CssDir),
    ( exists_directory(CssDir) -> true ; make_directory_path(CssDir) ),
    absolute_file_name(css("styles.css"), CssFile, [access(none)]),
    start_watching_dirs([Cwd], CssFile, Watcher),
    assertz(css_watcher(Watcher)).
stop_css_watcher :-
    css_watcher(Watcher), !,
    stop_watching_dirs(Watcher),
    retractall(css_watcher(Watcher)).
stop_css_watcher.
% Routes
:- multifile http:location/3.
:- dynamic http:location/3.
http:location(css, root(css), []).
:- http_handler(root(.), home_page_handler, [method(get), id(home_page),
                                             spawn(handler_pool)]).
:- http_handler(css('styles.css'), css_file_handler, [method(get), id(tw_css)]).
:- http_handler(css('reset.css'), reset_css_handler, [method(get), id(reset_css)]).
home_page_handler(_Request) :-
    reply_html_page(title('Hotwire.pl'), [\home_page]).
css_file_handler(Request) :-
    http_reply_file(css('styles.css'), [], Request).
reset_css_handler(_) :-
    reset_style(Style),
    format("Content-Type: text/css~n~n~s", [Style]).
% content
user:head(default, Head) -->
    html([Head,
          \html_receive(head),
          link([rel(stylesheet), href(#(reset_css))], []),
          link([rel(stylesheet), href(#(tw_css))], [])
         ]).
% Home Page
home_page -->
    html(
        div(class(["flex-col", "text-purple-500", 'bg-rose-50']),
            [h2(class(['text-lg',
                       'hover:animation-ping',
                       'bg-green-300', 'hover:text-rose-100']),
                "Info"),
             \p("here's some stuff, some information"),
             \p("Another paragraph")
            ])
    ).
p(Text) -->
    html(p(class(['text-sm', 'text-blue', 'hover:opacity-50']),
           Text)).
All the selectors from Tailwind should also be supported here. If any don't work, please file a bug!
Additionally, some new features are supported, taking advantage of the fact that the styles are created dynamically as needed.
pink-500) but as RGB(A) and HSL(A); for example, all of the following are valid styles: `text-#c0ffee`, bg-rgb-cafeba, from-hsla-50-60-70-0.5. This feature is copied from Girouette.mx-4 which will set the left and right margins to `1rem`), you can use arbitrary distances -- e.g. `mx-2.3rem, `font-size-17.5px`. This feature is copied from Girouette.group-hover does `.group:hover`. This can be used, for example, to do put the group class on a `<details>` element and group-attr-open:hidden on some child, do hide said element when the detail element is open