eschulte / jump.el
- Source
- Commits
- Network (2)
- Issues (0)
- Downloads (0)
- Wiki (1)
- Graphs
-
Tree:
07c60eb
Eric Schulte (author)
Wed Apr 22 15:12:08 -0700 2009
jump.el / inflections.el
| 93979037 » | eschulte | 2009-01-13 | 1 | ;;; inflections.el --- convert english words between singular and plural | |
| 29ce83d1 » | eschulte | 2008-08-04 | 2 | ||
| 3 | ;; Copyright (C) 2006 Dmitry Galinsky <dima dot exe at gmail dot com> | ||||
| 4 | |||||
| 93979037 » | eschulte | 2009-01-13 | 5 | ;; Authors: Dmitry Galinsky, Howard Yeh | |
| 6 | ;; URL: http://emacs-rails.rubyforge.org/svn/trunk/inflections.el | ||||
| 7 | ;; Version: 1.0 | ||||
| 8 | ;; Created: 2007-11-02 | ||||
| 29ce83d1 » | eschulte | 2008-08-04 | 9 | ;; Keywords: ruby rails languages oop | |
| 93979037 » | eschulte | 2009-01-13 | 10 | ||
| 11 | ;; This file is NOT part of GNU Emacs. | ||||
| 29ce83d1 » | eschulte | 2008-08-04 | 12 | ||
| 13 | ;;; License | ||||
| 14 | |||||
| 15 | ;; This program is free software; you can redistribute it and/or | ||||
| 16 | ;; modify it under the terms of the GNU General Public License | ||||
| 17 | ;; as published by the Free Software Foundation; either version 2 | ||||
| 18 | ;; of the License, or (at your option) any later version. | ||||
| 19 | |||||
| 20 | ;; This program is distributed in the hope that it will be useful, | ||||
| 21 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| 22 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| 23 | ;; GNU General Public License for more details. | ||||
| 24 | |||||
| 25 | ;; You should have received a copy of the GNU General Public License | ||||
| 26 | ;; along with this program; if not, write to the Free Software | ||||
| 27 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||||
| 28 | |||||
| 29 | ;;; Code: | ||||
| 30 | (require 'cl) | ||||
| 31 | (defvar inflection-singulars nil) | ||||
| 32 | (defvar inflection-plurals nil) | ||||
| 33 | (defvar inflection-irregulars nil) | ||||
| 34 | (defvar inflection-uncountables nil) | ||||
| 35 | |||||
| 36 | (defmacro define-inflectors (&rest specs) | ||||
| 37 | (loop for (type . rest) in specs do | ||||
| 38 | (case type | ||||
| 39 | (:singular (push rest inflection-singulars)) | ||||
| 40 | (:plural (push rest inflection-plurals)) | ||||
| 41 | (:irregular (push rest inflection-irregulars)) | ||||
| 42 | (:uncountable (setf inflection-uncountables | ||||
| 43 | (append rest inflection-uncountables)))))) | ||||
| 44 | |||||
| 45 | (defmacro string=~ (regex string &rest body) | ||||
| 46 | "regex matching similar to the =~ operator found in other languages." | ||||
| 47 | (let ((str (gensym))) | ||||
| 48 | `(lexical-let ((,str ,string)) | ||||
| 49 | ;; Use lexical-let to make closures (in flet). | ||||
| 50 | (when (string-match ,regex ,str) | ||||
| 51 | (symbol-macrolet ,(loop for i to 9 collect | ||||
| 52 | (let ((sym (intern (concat "$" (number-to-string i))))) | ||||
| 53 | `(,sym (match-string ,i ,str)))) | ||||
| 54 | (flet (($ (i) (match-string i ,str)) | ||||
| 55 | (sub (replacement &optional (i 0) &key fixedcase literal-string) | ||||
| 56 | (replace-match replacement fixedcase literal-string ,str i))) | ||||
| 57 | (symbol-macrolet ( ;;before | ||||
| 58 | ($b (substring ,str 0 (match-beginning 0))) | ||||
| 59 | ;;match | ||||
| 60 | ($m (match-string 0 ,str)) | ||||
| 61 | ;;after | ||||
| 62 | ($a (substring ,str (match-end 0) (length ,str)))) | ||||
| 63 | ,@body))))))) | ||||
| 64 | |||||
| 65 | (define-inflectors | ||||
| 66 | (:plural "$" "s") | ||||
| 67 | (:plural "s$" "s") | ||||
| 68 | (:plural "\\(ax\\|test\\)is$" "\\1es") | ||||
| 69 | (:plural "\\(octop\\|vir\\)us$" "\\1i") | ||||
| 70 | (:plural "\\(alias\\|status\\)$" "\\1es") | ||||
| 71 | (:plural "\\(bu\\)s$" "\\1ses") | ||||
| 72 | (:plural "\\(buffal\\|tomat\\)o$" "\\1oes") | ||||
| 73 | (:plural "\\([ti]\\)um$" "\\1a") | ||||
| 74 | (:plural "sis$" "ses") | ||||
| 75 | (:plural "\\(?:\\([^f]\\)fe\\|\\([lr]\\)f\\)$" "\\1\\2ves") | ||||
| 76 | (:plural "\\(hive\\)$" "\\1s") | ||||
| 77 | (:plural "\\([^aeiouy]\\|qu\\)y$" "\\1ies") | ||||
| 78 | (:plural "\\(x\\|ch\\|ss\\|sh\\)$" "\\1es") | ||||
| 79 | (:plural "\\(matr\\|vert\\|ind\\)ix\\|ex$" "\\1ices") | ||||
| 80 | (:plural "\\([m\\|l]\\)ouse$" "\\1ice") | ||||
| 81 | (:plural "^\\(ox\\)$" "\\1en") | ||||
| 82 | (:plural "\\(quiz\\)$" "\\1zes") | ||||
| 83 | |||||
| 84 | (:singular "s$" "") | ||||
| 85 | (:singular "\\(n\\)ews$" "\\1ews") | ||||
| 86 | (:singular "\\([ti]\\)a$" "\\1um") | ||||
| 87 | (:singular "\\(\\(a\\)naly\\|\\(b\\)a\\|\\(d\\)iagno\\|\\(p\\)arenthe\\|\\(p\\)rogno\\|\\(s\\)ynop\\|\\(t\\)he\\)ses$" "\\1\\2sis") | ||||
| 88 | (:singular "\\(^analy\\)ses$" "\\1sis") | ||||
| 89 | (:singular "\\([^f]\\)ves$" "\\1fe") | ||||
| 90 | (:singular "\\(hive\\)s$" "\\1") | ||||
| 91 | (:singular "\\(tive\\)s$" "\\1") | ||||
| 92 | (:singular "\\([lr]\\)ves$" "\\1f") | ||||
| 93 | (:singular "\\([^aeiouy]\\|qu\\)ies$" "\\1y") | ||||
| 94 | (:singular "\\(s\\)eries$" "\\1eries") | ||||
| 95 | (:singular "\\(m\\)ovies$" "\\1ovie") | ||||
| 96 | (:singular "\\(x\\|ch\\|ss\\|sh\\)es$" "\\1") | ||||
| 97 | (:singular "\\([m\\|l]\\)ice$" "\\1ouse") | ||||
| 98 | (:singular "\\(bus\\)es$" "\\1") | ||||
| 99 | (:singular "\\(o\\)es$" "\\1") | ||||
| 100 | (:singular "\\(shoe\\)s$" "\\1") | ||||
| 101 | (:singular "\\(cris\\|ax\\|test\\)es$" "\\1is") | ||||
| 102 | (:singular "\\(octop\\|vir\\)i$" "\\1us") | ||||
| 103 | (:singular "\\(alias\\|status\\)es$" "\\1") | ||||
| 104 | (:singular "^\\(ox\\)en" "\\1") | ||||
| 105 | (:singular "\\(vert\\|ind\\)ices$" "\\1ex") | ||||
| 106 | (:singular "\\(matr\\)ices$" "\\1ix") | ||||
| 107 | (:singular "\\(quiz\\)zes$" "\\1") | ||||
| 108 | |||||
| 109 | (:irregular "stratum" "strate") | ||||
| 110 | (:irregular "syllabus" "syllabi") | ||||
| 111 | (:irregular "radius" "radii") | ||||
| 112 | (:irregular "addendum" "addenda") | ||||
| 113 | (:irregular "cactus" "cacti") | ||||
| 114 | (:irregular "child" "children") | ||||
| 115 | (:irregular "corpus" "corpora") | ||||
| 116 | (:irregular "criterion" "criteria") | ||||
| 117 | (:irregular "datum" "data") | ||||
| 118 | (:irregular "genus" "genera") | ||||
| 119 | (:irregular "man" "men") | ||||
| 120 | (:irregular "medium" "media") | ||||
| 121 | (:irregular "move" "moves") | ||||
| 122 | (:irregular "person" "people") | ||||
| 123 | (:irregular "man" "men") | ||||
| 124 | (:irregular "child" "children") | ||||
| 125 | (:irregular "sex" "sexes") | ||||
| 126 | (:irregular "move" "moves") | ||||
| 127 | |||||
| 128 | (:uncountable "equipment" "information" "rice" "money" "species" "series" "fish" "sheep" "news")) | ||||
| 129 | |||||
| 93979037 » | eschulte | 2009-01-13 | 130 | ;;;###autoload | |
| 29ce83d1 » | eschulte | 2008-08-04 | 131 | (defun singularize-string (str) | |
| 132 | (when (stringp str) | ||||
| 133 | (or (car (member str inflection-uncountables)) | ||||
| 134 | (caar (member* (downcase str) inflection-irregulars :key 'cadr :test 'equal)) | ||||
| 135 | (loop for (from to) in inflection-singulars | ||||
| 136 | for singular = (string=~ from str (sub to)) | ||||
| 137 | when singular do (return singular)) | ||||
| 138 | str))) | ||||
| 139 | |||||
| 93979037 » | eschulte | 2009-01-13 | 140 | ;;;###autoload | |
| 29ce83d1 » | eschulte | 2008-08-04 | 141 | (defun pluralize-string (str) | |
| 142 | (when (stringp str) | ||||
| 143 | (or (car (member str inflection-uncountables)) | ||||
| 144 | (cadar (member* (downcase str) inflection-irregulars :key 'car :test 'equal)) | ||||
| 145 | (loop for (from to) in inflection-plurals | ||||
| 146 | for plurals = (string=~ from str (sub to)) | ||||
| 147 | when plurals do (return plurals)) | ||||
| 148 | str))) | ||||
| 149 | |||||
| 150 | (provide 'inflections) | ||||
