Improve customization.
[robmyers:scripts.git] / artbollocks-mode.el
1 ;; artbollocks-mode.el - A minor mode to guide art writers.
2 ;; Copyright (c) 2011 Rob Myers <rob@robmyers.org>
3 ;; Based on fic-mode.el
4 ;; Copyright (C) 2010, Trey Jackson <bigfaceworm(at)gmail(dot)com>
5 ;; Non-artbollocks words from: http://matt.might.net/articles/
6 ;; This program is free software: you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation, either version 3 of the License, or
9 ;; (at your option) any later version.
10 ;;
11 ;; This program is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ;; GNU General Public License for more details.
15 ;;
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 ;;
19 ;; To use, save artbollocks-mode.el to a directory in your load-path.
20 ;;
21 ;; (require 'artbollocks-mode)
22 ;; (add-hook 'text-mode-hook 'turn-on-artbollocks-mode)
23 ;; (add-hook 'org-mode-hook 'turn-on-artbollocks-mode)
24 ;;
25 ;; or
26 ;;
27 ;; M-x artbollocks-mode
28 ;;
29 ;; NOTE: If you manually turn on artbollocks-mode,
30 ;; you you might need to force re-fontification initially:
31 ;;
32 ;;   M-x font-lock-fontify-buffer
33
34 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
35 ;; Customization
36 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
37
38 ;; Enable features individually
39
40 (defcustom passive-voice t
41   "Whether to check for passive voice"
42   :type '(boolean)
43   :group 'artbollocks-mode)
44
45 (defcustom weasel-words t
46   "Whether to check for weasel words"
47   :type '(boolean)
48   :group 'artbollocks-mode)
49
50 (defcustom artbollocks t
51   "Whether to check for artbollocks"
52   :type '(boolean)
53   :group 'artbollocks-mode)
54
55 ;; Passive voice face
56
57 (defcustom passive-voice-foreground-color "Gray"
58   "Passive voice face foreground colour"
59   :group 'artbollocks-mode)
60
61 (defcustom passive-voice-background-color "White"
62   "Passive voice face background color"
63   :group 'artbollocks-mode)
64
65 (defcustom font-lock-passive-voice-face 'font-lock-passive-voice-face
66   "The face for passive voice words in artbollocks mode"
67   :group 'artbollocks-mode)
68
69 (make-face 'font-lock-passive-voice-face)
70 (modify-face 'font-lock-passive-voice-face passive-voice-foreground-color
71              passive-voice-background-color nil t nil t nil nil)
72
73 ;; Weasel words face
74
75 (defcustom weasel-words-foreground-color "Brown"
76   "Weasel words face foreground colour"
77   :group 'artbollocks-mode)
78
79 (defcustom weasel-words-background-color "White"
80   "Weasel words face background color"
81   :group 'artbollocks-mode)
82
83 (defcustom font-lock-weasel-words-face 'font-lock-weasel-words-face
84   "The face for weasel-words words in artbollocks mode"
85   :group 'artbollocks-mode)
86
87 (make-face 'font-lock-weasel-words-face)
88 (modify-face 'font-lock-weasel-words-face weasel-words-foreground-color
89              weasel-words-background-color nil t nil t nil nil)
90
91 ;; Artbollocks face
92
93 (defcustom artbollocks-foreground-color "Purple"
94   "Font foreground colour"
95   :group 'artbollocks-mode)
96
97 (defcustom artbollocks-background-color "White"
98   "Font background color"
99   :group 'artbollocks-mode)
100
101 (defcustom font-lock-artbollocks-face 'font-lock-artbollocks-face
102   "The face for artbollocks words in artbollocks mode"
103   :group 'artbollocks-mode)
104
105 (make-face 'font-lock-artbollocks-face)
106 (modify-face 'font-lock-artbollocks-face artbollocks-foreground-color
107              artbollocks-background-color nil t nil t nil nil)
108
109 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
110 ;; Passive voice
111 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
112
113 (defconst passive-voice-regex "\\b\\(am\\|are\\|were\\|being\\|is\\|been\\|was\\|be\\)\\s-+\\(\\w+ed\\|awoken\\|been\\|born\\|beat\\|become\\|begun\\|bent\\|beset\\|bet\\|bid\\|bidden\\|bound\\|bitten\\|bled\\|blown\\|broken\\|bred\\|brought\\|broadcast\\|built\\|burnt\\|burst\\|bought\\|cast\\|caught\\|chosen\\|clung\\|come\\|cost\\|crept\\|cut\\|dealt\\|dug\\|dived\\|done\\|drawn\\|dreamt\\|driven\\|drunk\\|eaten\\|fallen\\|fed\\|felt\\|fought\\|found\\|fit\\|fled\\|flung\\|flown\\|forbidden\\|forgotten\\|foregone\\|forgiven\\|forsaken\\|frozen\\|gotten\\|given\\|gone\\|ground\\|grown\\|hung\\|heard\\|hidden\\|hit\\|held\\|hurt\\|kept\\|knelt\\|knit\\|known\\|laid\\|led\\|leapt\\|learnt\\|left\\|lent\\|let\\|lain\\|lighted\\|lost\\|made\\|meant\\|met\\|misspelt\\|mistaken\\|mown\\|overcome\\|overdone\\|overtaken\\|overthrown\\|paid\\|pled\\|proven\\|put\\|quit\\|read\\|rid\\|ridden\\|rung\\|risen\\|run\\|sawn\\|said\\|seen\\|sought\\|sold\\|sent\\|set\\|sewn\\|shaken\\|shaven\\|shorn\\|shed\\|shone\\|shod\\|shot\\|shown\\|shrunk\\|shut\\|sung\\|sunk\\|sat\\|slept\\|slain\\|slid\\|slung\\|slit\\|smitten\\|sown\\|spoken\\|sped\\|spent\\|spilt\\|spun\\|spit\\|split\\|spread\\|sprung\\|stood\\|stolen\\|stuck\\|stung\\|stunk\\|stridden\\|struck\\|strung\\|striven\\|sworn\\|swept\\|swollen\\|swum\\|swung\\|taken\\|taught\\|torn\\|told\\|thought\\|thrived\\|thrown\\|thrust\\|trodden\\|understood\\|upheld\\|upset\\|woken\\|worn\\|woven\\|wed\\|wept\\|wound\\|won\\|withheld\\|withstood\\|wrung\\|written\\)\\b")
114
115 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
116 ;; Weasel words
117 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
118
119 (defconst weasel-words-regex "\\b\\(many\\|various\\|very\\|fairly\\|several\\|extremely\\|exceedingly\\|quite\\|remarkably\\|few\\|surprisingly\\|mostly\\|largely\\|huge\\|tiny\\|\\(\\(are\\|is\\) a number\\)\\|excellent\\|interestingly\\|significantly\\|substantially\\|clearly\\|vast\\|relatively\\|completely\\)\\b")
120
121 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
122 ;; Artbollocks
123 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
124
125 (defconst artbollocks-regex "\\b(a priori\\|ad hoc\\|affirmation\\|affirm\\|affirms\\|aporia\\|aporetic\\|appropriates\\|appropriation\\|archetypal\\|archetypical\\|archetype\\|archetypes\\|autonomous\\|autonomy\\|baudrillardian\\|baudrillarian\\|commodification\\|committed\\|commitment\\|commonalities\\|contemporaneity\\|context\\|contexts\\|contextual\\|contextualise\\|contextualises\\|contextualisation\\|contextialize\\|contextializes\\|contextualization\\|convention\\|conventional\\|conventions\\|coterminous\\|critique\\|cunning\\|cunningly\\|death of the author\\|debunk\\|debunked\\|debunking\\|debunks\\|deconstruct\\|deconstruction\\|deconstructs\\|deleuzian\\|desire\\|desires\\|discourse\\|discursive\\|disrupt\\|disrupts\\|engage\\|engagement\\|engages\\|episteme\\|epistemic\\|ergo\\|fetish\\|fetishes\\|fetishise\\|fetishised\\|fetishize\\|fetishized\\|gaze\\|gender\\|gendered\\|historicise\\|historicisation\\|historicize\\|historicization\\|hegemonic\\|hegemony\\|identity\\|identity politics\\|intensifies\\|intensify\\|intensifying\\|interrogate\\|interrogates\\|interrogation\\|intertextual\\|intertextuality\\|irony\\|ironic\\|ironical\\|ironically\\|ironisation\\|ironization\\|ironises\\|ironizes\\|jouissance\\|juxtapose\\|juxtaposes\\|juxtaposition\\|lacanian\\|lack\\|loci\\|locus\\|locuses\\|matrix\\|mocking\\|mockingly\\|modalities\\|modality\\|myth\\|mythologies\\|mythology\\|myths\\|narrative\\|narrativisation\\|narrativization\\|narrativity\\|nexus\\|nodal\\|node\\|normative\\|normativity\\|notion\\|notions\\|objective\\|objectivity\\|objectivities\\|objet petit a\\|ontology\\|ontological\\|operate\\|operates\\|otherness\\|othering\\|paradigm\\|paradigmatic\\|paradigms\\|parody\\|parodic\\|parodies\\|physicality\\|plenitude\\|poetics\\|popular notions\\|position\\|post hoc\\|postmodernism\\|postmodernist\\|postmodernity\\|postmodern\\|practice\\|practise\\|praxis\\|problematic\\|problematics\\|proposition\\|qua\\|reading\\|readings\\|reification\\|relation\\|relational\\|relationality\\|relations\\|representation\\|representations\\|rhizomatic\\|rhizome\\|situate\\|situated\\|situates\\|stereotype\\|stereotypes\\|strategy\\|strategies\\|subjective\\|subjectivity\\|subjectivities\\|subvert\\|subversion\\|subverts\\|text\\|textual\\|textuality\\|thinker\\|thinkers\\|trajectory\\|transgress\\|transgresses\\|transgression\\|transgressive\\|unfolding\\|undermine\\|undermining\\|undermines\\|work\\|works\\|wry\\|wryly\\|zizekian\\|zi┼żekian)\\b")
126
127 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
128 ;; Highlighting
129 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
130
131 (defun search-for-keyword (regex limit)
132   "Match the provided regex in the buffer"
133   (let ((match-data-to-set nil)
134         found)
135     (save-match-data
136       (while (and (null match-data-to-set)
137                   (re-search-forward regex limit t))
138             (setq match-data-to-set (match-data))))
139     (when match-data-to-set
140       (set-match-data match-data-to-set)
141       (goto-char (match-end 0)) 
142       t)))
143
144 (defun passive-voice-search-for-keyword (limit)
145   (search-for-keyword passive-voice-regex limit))
146
147 (defun weasel-words-search-for-keyword (limit)
148   (search-for-keyword weasel-words-regex limit))
149
150 (defun artbollocks-search-for-keyword (limit)
151   (search-for-keyword artbollocks-regex limit))
152
153 (defconst passivekwlist '((passive-voice-search-for-keyword 
154                               (0 'font-lock-passive-voice-face t))))
155
156 (defconst weaselkwlist '((weasel-words-search-for-keyword 
157                              (0 'font-lock-weasel-words-face t))))
158
159 (defconst artbollockskwlist '((artbollocks-search-for-keyword 
160                                   (0 'font-lock-artbollocks-face t))))
161
162 (defun add-artbollocks-keywords ()
163   (when passive-voice
164     (font-lock-add-keywords nil passivekwlist))
165   (when weasel-words
166     (font-lock-add-keywords nil weaselkwlist))
167   (when artbollocks
168     (font-lock-add-keywords nil artbollockskwlist)))
169
170 (defun remove-artbollocks-keywords ()
171   (font-lock-remove-keywords nil passivekwlist)
172   (font-lock-remove-keywords nil weaselkwlist)
173   (font-lock-remove-keywords nil artbollockskwlist))
174
175 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
176 ;; The mode
177 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
178
179 ;;;###autoload
180 (define-minor-mode artbollocks-mode "highlight passive voice, weadel words and artbollocks in text"
181   :lighter " ARTBOLLOCKS"
182   :group 'artbollocks-mode
183   (if artbollocks-mode
184       (add-artbollocks-keywords)
185     (remove-artbollocks-keywords)))
186
187 (defun turn-on-artbollocks-mode ()
188   "turn artbollocks-mode on"
189   (interactive)
190   (artbollocks-mode 1))
191
192 (provide 'artbollocks-mode)