<commit_before>open Tags
open Styles
structure E = Error

style base_page
style front_page
style catalog_page
style thread_page


val show_tag =
  mkShow (fn { Nam = name, Slug = slug } =>
    "/" ^ name ^ "/ - " ^ slug)


(* Create a subform that can hold up to `max` files. *)
(* FIXME: fails with `Fatal error: Tried to read a normal form input as files` when files in subforms *)
fun filesForm [form ::: {Type}] [[Files] ~ form] max
  : transaction (xml [Form, Dyn, Body] form [Files = list { File : file, Spoiler : bool }])
= let
  val newFile =
    spoil <- fresh;
    return <xml><div><entry>
      <upload{#File} />
      <checkbox{#Spoiler} class="hidden-field" id={spoil} />
      <label for={spoil} class="button">Spoiler</label>
    </entry></div></xml>

  fun files' ls = case ls of
    | [] => <xml/>
    | f :: rs => <xml>{f}{files' rs}</xml>
in
  f1 <- newFile;
  files <- source (f1 :: []);
  return <xml>
    <subforms{#Files}>
      <dyn signal={fs <- signal files; return (files' fs)} />
    </subforms>
    <div>
      <span onclick={fn _ =>
        f <- get files;
        if List.length f >= max then return () else
          newF <- newFile;
          set files (newF :: f)
      }>+</span>
      <span onclick={fn _ =>
        f <- get files; case f of
        | _ :: [] => return ()
        | _ :: rs => set files rs
        | [] => return ()
      }>-</span>
    </div>
  </xml>
end


fun layout tags (title' : string) (class' : css_class) (body' : xbody) =
  siteName <- Admin.siteName;
  nav' <- navigation tags;
  banner' <- Layout.randBanner;
  Layout.layoutWithSwitcher switch_theme (title' ^ " - " ^ siteName) class' ""
    (fn switcher => <xml>
      <header>
        <nav>{nav'}</nav>
        {case banner' of
        | None => <xml/>
        | Some b =>
          <xml><img class="banner" width={300} height={100} src={b}/></xml>}
        <h1>{[title']}</h1>
      </header>
      <main>{body'}</main>
      <footer>{switcher}</footer>
    </xml>)


and switch_theme { Theme = t } =
  Layout.setTheme (readError t);
  redirect (url (front ()))


and newsItem item : transaction xbody =
  body' <- Post.toHtml item.Body;
  return <xml><article class="news-item">
    <header><strong>{[item.Title]}</strong> by {[item.Author]} at {[item.Time]}</header>
    <div class="news_body">{body'}</div>
  </article></xml>


and front () =
  tags <- Data.allTags;
  news <- Admin.news;
  news <- List.mapXM newsItem news;
  readme <- Admin.readme;
  readme <- Post.toHtml readme;
  siteName <- Admin.siteName;
  Layout.layout ("Front Page - " ^ siteName) front_page "" <xml>
    <header>
      <h1>{[siteName]}</h1>
    </header>
    <main>
      <div class="container">
        <section>
          <header>Boards</header>
          <ul class="section-body">
            {List.mapX (fn t => <xml><li>
              <a link={catalog t.Nam}>{[t]}</a>
            </li></xml>) tags}
          </ul>
        </section>
        <section>
          <header>About</header>
          <div class="section-body">{readme}</div>
        </section>
        <section>
          <header>News</header>
          <div class="section-body">{news}</div>
        </section>
      </div>
    </main>
    <footer>Powered by <a href="https://github.com/steinuil/negoto">Negoto</a></footer>
  </xml><commit_msg>updated API document<commit_after>open Tags
open Styles
structure E = Error

style base_page
style front_page
style catalog_page
style thread_page


val show_tag =
  mkShow (fn { Nam = name, Slug = slug } =>
    "/" ^ name ^ "/ - " ^ slug)


(* Create a subform that can hold up to `max` files. *)
(* FIXME: fails with `Fatal error: Tried to read a normal form input as files` when files in subforms *)
fun filesForm [form ::: {Type}] [[Files] ~ form] max
  : transaction (xml [Form, Dyn, Body] form [Files = list { File : file, Spoiler : bool }])
= let
  val newFile =
    spoil <- fresh;
    return <xml><div><entry>
      <upload{#File} />
      <checkbox{#Spoiler} class="hidden-field" id={spoil} />
      <label for={spoil} class="button">Spoiler</label>
    </entry></div></xml>

  fun files' ls = case ls of
    | [] => <xml/>
    | f :: rs => <xml>{f}{files' rs}</xml>
in
  f1 <- newFile;
  files <- source (f1 :: []);
  return <xml>
    <subforms{#Files}>
      <dyn signal={fs <- signal files; return (files' fs)} />
    </subforms>
    <div>
      <span onclick={fn _ =>
        f <- get files;
        if List.length f >= max then return () else
          newF <- newFile;
          set files (newF :: f)
      }>+</span>
      <span onclick={fn _ =>
        f <- get files; case f of
        | _ :: [] => return ()
        | _ :: rs => set files rs
        | [] => return ()
      }>-</span>
    </div>
  </xml>
end


fun layout tags (title' : string) (class' : css_class) (body' : xbody) =
  siteName <- Admin.siteName;
  nav' <- navigation tags;
  banner' <- Layout.randBanner;
  Layout.layoutWithSwitcher switch_theme (title' ^ " - " ^ siteName) class' ""
    (fn switcher => <xml>
      <header>
        <nav>{nav'}</nav>
        {case banner' of
        | None => <xml/>
        | Some b =>
          <xml><img class="banner" width={300} height={100} src={b}/></xml>}
        <h1>{[title']}</h1>
      </header>
      <main>{body'}</main>
      <footer>{switcher}</footer>
    </xml>)


and switch_theme { Theme = t } =
  Layout.setTheme (readError t);
  redirect (url (front ()))


and newsItem item : transaction xbody =
  body' <- Post.toHtml item.Body;
  return <xml><article class="news-item">
    <header><strong>{[item.Title]}</strong> by {[item.Author]} at {[item.Time]}</header>
    <div class="news_body">{body'}</div>
  </article></xml>


and front () =
  boards <- Data.X.allBoards;
  news <- Admin.news;
  news <- List.mapXM newsItem news;
  readme <- Admin.readme;
  readme <- Post.toHtml readme;
  siteName <- Admin.siteName;
  Layout.layout ("Front Page - " ^ siteName) front_page "" <xml>
    <header>
      <h1>{[siteName]}</h1>
    </header>
    <main>
      <div class="container">
        <section>
          <header>Boards</header>
          <ul class="section-body">
            {List.mapX
              (fn b => <xml><li><a link={catalog b.Id}>{[t]}</a></li></xml>)
              boards}
          </ul>
        </section>
        <section>
          <header>About</header>
          <div class="section-body">{readme}</div>
        </section>
        <section>
          <header>News</header>
          <div class="section-body">{news}</div>
        </section>
      </div>
    </main>
    <footer>Powered by <a href="https://github.com/steinuil/negoto">Negoto</a></footer>
  </xml>
{'fraction_non_alphanumeric': 0.18429776974080772, 'fraction_numerical': 0.003616636528028933, 'mean_word_length': 2.3251503006012024, 'pattern_counts': {'":': 0, '<': 213, '<?xml version=': 0, '>': 205, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 38}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3339147', 'n_tokens_mistral': 2318, 'n_tokens_neox': 2239, 'n_words': 571}