pronoun.lol/src/pronouns/pages.clj

236 lines
8.0 KiB
Clojure
Raw Normal View History

;; pronoun.lol - a website for pronoun usage examples
2018-11-14 22:00:58 +01:00
;; Copyright (C) 2014 - 2018 Morgan Astra
;; Copyright (C) 2024 Kim Endisch
2016-09-21 00:40:01 +02:00
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU Affero General Public License as
;; published by the Free Software Foundation, either version 3 of the
;; License, or (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU Affero General Public License for more details.
;; You should have received a copy of the GNU Affero General Public License
2018-11-14 23:17:47 +01:00
;; along with this program. If not, see <https://www.gnu.org/licenses/>
2016-09-21 00:40:01 +02:00
(ns pronouns.pages
(:require [clojure.string :as s]
[pronouns.config :refer [pronouns-table]]
[pronouns.util :as u]
[hiccup.core :refer :all]
[hiccup.element :as e]
[hiccup.util :refer [escape-html]]))
(defn prose-comma-list
[items]
(let [c (count items)]
(cond
2016-09-24 10:28:13 +02:00
(<= c 1) (or (first items) "")
(= c 2) (s/join " and " items)
:else (str (s/join ", " (butlast items)) ", and " (last items)))))
2016-09-21 00:40:01 +02:00
(defn href
[url text]
[:a {:href url} text])
2018-11-14 23:28:15 +01:00
;; FIXME morgan.astra <2018-11-14 Wed>
;; use a div for this instead of a plain bold tag
2015-03-14 04:39:54 +01:00
(defn wrap-pronoun
[pronoun]
[:b pronoun])
(defn render-sentence [& content]
2015-07-04 03:20:49 +02:00
[:p [:span.sentence content]])
2015-03-14 04:39:54 +01:00
(defn subject-example
[subject]
(render-sentence (wrap-pronoun (s/capitalize subject)) " went to the park."))
2015-03-14 04:39:54 +01:00
(defn object-example
[object]
(render-sentence "I went with " (wrap-pronoun object) "."))
2015-03-14 04:39:54 +01:00
(defn posessive-determiner-example
[subject possessive-determiner]
2015-07-04 03:20:49 +02:00
(render-sentence (wrap-pronoun (s/capitalize subject))
" brought "
(wrap-pronoun possessive-determiner)
" frisbee."))
2015-03-14 04:39:54 +01:00
(defn possessive-pronoun-example
[possessive-pronoun]
(render-sentence "At least I think it was "
(wrap-pronoun possessive-pronoun)
"."))
2015-03-14 04:39:54 +01:00
(defn reflexive-example
[subject reflexive]
2015-07-04 03:20:49 +02:00
(render-sentence (wrap-pronoun (s/capitalize subject))
" threw the frisbee to "
(wrap-pronoun reflexive)
"."))
2015-03-14 04:39:54 +01:00
(defn header-block [header]
[:div {:class "section title"}
2018-11-14 22:00:58 +01:00
(href "/" [:h1 header])])
2015-03-14 08:57:03 +01:00
(defn examples-block
[subject object possessive-determiner possessive-pronoun reflexive]
(let [sub-obj (s/join "/" [subject object])
header-str (str "Here are some example sentences using my "
sub-obj
" pronouns:")]
[:div {:class "section examples"}
[:h2 header-str]
[:p (subject-example subject)
(object-example object)
(posessive-determiner-example subject possessive-determiner)
(possessive-pronoun-example possessive-pronoun)
(reflexive-example subject reflexive)]]))
2015-03-14 04:39:54 +01:00
(defn usage-block []
[:div {:class "section usage"}
2015-03-14 09:06:59 +01:00
[:p "Full usage: "
2018-11-14 23:28:15 +01:00
;; FIXME morgan.astra <2018-11-14 Wed>
;; This looks really ugly in the browser
[:tt "https://pronoun.lol/subject-pronoun/object-pronoun/possessive-determiner/possessive-pronoun/reflexive"]
" displays examples of your pronouns."]
[:p "This is a bit unwieldy. If we have a good guess we'll let you use"
" just the first one or two."]])
2015-03-14 04:39:54 +01:00
(defn contact-block []
2016-09-21 00:40:01 +02:00
(let [twitter-name (fn [handle] (href (str "https://www.twitter.com/" handle)
(str "@" handle)))]
2016-09-22 08:58:16 +02:00
[:div {:class "section contact"}
[:p "Written by "
(twitter-name "morganastra")
", whose "
(href "https://pronoun.lol/she" "pronoun.lol/she")]
[:p "pronoun.lol is free software under the "
(href "https://www.gnu.org/licenses/agpl.html" "AGPLv3")
"! visit the project on "
(href "https://github.com/witch-house/pronoun.lol" "github")]
2018-12-29 20:14:28 +01:00
[:p "&lt;3"]]))
2015-03-14 04:39:54 +01:00
2016-09-22 08:58:16 +02:00
(defn footer-block []
[:footer (usage-block) (contact-block)])
2015-03-14 04:39:54 +01:00
(defn format-pronoun-examples
2016-08-07 12:55:53 +02:00
[pronoun-declensions]
(let [sub-objs (map #(s/join "/" (take 2 %)) pronoun-declensions)
title (str "Pronoun LOL: " (prose-comma-list sub-objs) " examples")
examples (map #(apply examples-block %) pronoun-declensions)]
(html
[:html
[:head
[:title title]
[:meta {:name "viewport" :content "width=device-width"}]
2018-12-29 20:14:28 +01:00
[:meta {:charset "utf-8"}]
[:meta {:name "description" :content (u/strip-markup examples)}]
[:meta {:name "twitter:card" :content "summary"}]
[:meta {:name "twitter:title" :content title}]
[:meta {:name "twitter:description" :content (u/strip-markup examples)}]
[:link {:rel "stylesheet" :href "/pronouns.css"}]]
[:body
2016-09-24 10:28:13 +02:00
(header-block title)
examples
2016-09-22 08:58:16 +02:00
(footer-block)]])))
(defn table-lookup* [pronouns-string]
(let [inputs (s/split pronouns-string #"/")
n (count inputs)]
(if (>= n 5)
(take 5 inputs)
(u/table-lookup inputs @pronouns-table))))
(defn lookup-pronouns
"Given a seq of pronoun sets, look up each set in the pronouns table"
[pronoun-sets]
(->> pronoun-sets
(map (comp table-lookup* escape-html))
(filter some?)))
(defn make-link [path]
(let [link (str "/" path)
label path]
2016-09-21 00:40:01 +02:00
[:li (href link label)]))
(defn front []
(let [abbreviations (take 6 (u/abbreviate @pronouns-table))
links (map make-link abbreviations)
title "Pronoun LOL"
description "Pronoun.lol is a website for personal pronoun usage examples."]
(html
[:html
[:head
2015-03-14 08:57:03 +01:00
[:title title]
[:meta {:name "description" :content description}]
[:meta {:name "twitter:card" :content "summary"}]
[:meta {:name "twitter:title" :content title}]
[:meta {:name "twitter:description" :content description}]
[:meta {:name "viewport" :content "width=device-width"}]
2018-12-29 20:14:28 +01:00
[:meta {:charset "utf-8"}]
[:link {:rel "stylesheet" :href "/pronouns.css"}]]
[:body
2016-09-24 10:28:13 +02:00
(header-block title)
[:div {:class "section table"}
[:p "pronoun.lol is a website for personal pronoun usage examples"]
2018-11-15 07:22:15 +01:00
[:p "here are some pronouns the site knows about:"]
[:ul links]
[:p [:small (href "all-pronouns" "see all pronouns in the database")]]]]
(footer-block)])))
(defn all-pronouns []
(let [abbreviations (u/abbreviate @pronouns-table)
2018-11-15 07:22:15 +01:00
links (map make-link abbreviations)
title "Pronoun LOL"]
2018-11-15 07:22:15 +01:00
(html
[:html
[:head
[:title title]
[:meta {:name "viewport" :content "width=device-width"}]
2018-12-29 20:14:28 +01:00
[:meta {:charset "utf-8"}]
2018-11-15 07:22:15 +01:00
[:link {:rel "stylesheet" :href "/pronouns.css"}]]
[:body
(header-block title)
[:div {:class "section table"}
[:p "All pronouns the site knows about:"]
[:ul links]]]
2016-09-22 08:58:16 +02:00
(footer-block)])))
(defn not-found [path]
(let [title "Pronoun LOL: English Language Examples"
or-re #"/[oO][rR]/"]
(html
[:html
[:head
[:title title]
[:meta {:name "viewport" :content "width=device-width"}]
2018-12-29 20:14:28 +01:00
[:meta {:charset "utf-8"}]
[:link {:rel "stylesheet" :href "/pronouns.css"}]]
[:body
2016-09-24 10:28:13 +02:00
(header-block title)
[:div {:class "section examples"}
[:p [:h2 "We couldn't find those pronouns in our database :("]
"If you think we should have them, please reach out!"]
(when (re-find or-re path)
(let [alts (s/split path or-re)
new-path (str "/" (s/join "/:OR/" alts))]
[:div
"Did you mean: "
(href new-path
(str "pronoun.lol"
new-path))]))]
2016-09-22 08:58:16 +02:00
(footer-block)]])))
(defn pronouns [params]
(let [path (params :*)
param-alts (u/vec-coerce (or (params "or") []))
path-alts (s/split path #"/:[oO][rR]/")
pronouns (lookup-pronouns (concat path-alts param-alts))]
(if (seq pronouns)
(format-pronoun-examples pronouns)
(not-found path))))