From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Rasmus Newsgroups: gmane.emacs.devel Subject: Re: Proper English Title Capitalization Date: Mon, 25 May 2015 18:18:08 +0200 Message-ID: <87y4kc8wcf.fsf@gmx.us> References: <2015-05-24T13-06-14@devnull.Karl-Voit.at> <87fv6lelmr.fsf@debian.uxu> <2015-05-25T12-05-49@devnull.Karl-Voit.at> <2015-05-25T12-45-36@devnull.Karl-Voit.at> <2015-05-25T14-22-01@devnull.Karl-Voit.at> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: ger.gmane.org 1432570775 6277 80.91.229.3 (25 May 2015 16:19:35 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 25 May 2015 16:19:35 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon May 25 18:19:27 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Ywv66-0001LM-DQ for ged-emacs-devel@m.gmane.org; Mon, 25 May 2015 18:19:26 +0200 Original-Received: from localhost ([::1]:44411 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ywv65-0000ZV-Fi for ged-emacs-devel@m.gmane.org; Mon, 25 May 2015 12:19:25 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:54664) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ywv55-0000Qr-OO for emacs-devel@gnu.org; Mon, 25 May 2015 12:18:27 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ywv50-00031b-Ax for emacs-devel@gnu.org; Mon, 25 May 2015 12:18:23 -0400 Original-Received: from plane.gmane.org ([80.91.229.3]:39142) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ywv4z-00031A-VE for emacs-devel@gnu.org; Mon, 25 May 2015 12:18:18 -0400 Original-Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1Ywv4y-0000wW-Na for emacs-devel@gnu.org; Mon, 25 May 2015 18:18:16 +0200 Original-Received: from 46.166.190.228 ([46.166.190.228]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Mon, 25 May 2015 18:18:16 +0200 Original-Received: from rasmus by 46.166.190.228 with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Mon, 25 May 2015 18:18:16 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 186 Original-X-Complaints-To: usenet@ger.gmane.org X-Gmane-NNTP-Posting-Host: 46.166.190.228 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) Cancel-Lock: sha1:xd0KLL9ZJtjtZkZkHm3Q6quR+F0= X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 80.91.229.3 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:186807 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Karl Voit writes: > I also blogged about this thread and its solution: > http://karl-voit.at/2015/05/25/elisp-title-capitalization/ Ah that's funny. I like M-c though. The attached file does something similar to your script, but plugs into capitalize-word at supported title lines (== org and message) if hooked in. –Rasmus -- Evidence suggests Snowden used a powerful tool called monospaced fonts --=-=-= Content-Type: application/emacs-lisp Content-Disposition: attachment; filename=smartcap.el Content-Transfer-Encoding: quoted-printable ;;; smartcap.el --- try to capitalize titles cleverly -*- lexical-binding:= t; -*- ;; Copyright (C) 2015 Rasmus Pank Roulund ;; Author: Rasmus Pank Roulund ;; Keywords: convenience, files ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU 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 General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; Try to capitalize word smartly. Currently supports English org and ;; message mode. ;;; TODOs: ;; Probably doesn't work with e.g. subword-moe. ;;; Code: (defcustom smartcap-uncapitalized '(("en" . ("a" "ago" "an" "and" "as" "at"= "but" "by" "for" "from" "in" "into" "it" "next"= "nor" "of" "off" "on" "onto" "or" "over" "past"= "so" "the" "till" "to" "up" "yet"))) "Alist of uncapitalized language. Each cell is of the form (LANGUAGE . LIST-OF-UNCAPITALIZED-WORDS).") (defcustom smartcap-mode-title-line-identifiers '((org-mode . smartcap-org-title-line) (message-mode . smartcap-message-title-line)) "Alist of major-mode and their title-line identifiers.") (defcustom smartcap-language-identifier 'smartcap-ispell-language "Function to find current language.") (defcustom smartcap-language-default "en" "Default language") (defun smartcap-ispell-language () (let ((lang (or ispell-local-dictionary ispell-dictionary))) (and lang (downcase lang)))) (defun smartcap--get-uncapitalized (language) (cdr (assoc (cl-case (intern language) ((en en_us en_gb) "en") (t nil)) smartcap-uncapitalized))) (defun smartcap-org-title-line () "Determine if line is a title line in `org-mode'." (save-excursion (beginning-of-line) (if (looking-at (format "\\(?:%s\\)" (mapconcat 'identity=20 `(,org-complex-heading-regexp "^\\(?10:#\\+\\(?:subtitle\\|titl= e\\):\\)") "\\|"))) `((title-begin . ,(match-end 0)) (first-word . ,(progn (goto-char (or (match-beginning 4) (match-e= nd 10))) (skip-chars-forward " \t") (cons (point) (progn (forward-word) (point)= )))) (last-word . ,(progn (goto-char (or (match-end 4) (line-end-position))) (skip-chars-backward " \t") (cons (save-excursion (forward-word -1) (poi= nt)) (point)))))))) (defun smartcap-message-title-line () "Determine if line is a title line in `message-mode'" (save-excursion=20 (when (< (point) (save-excursion (message-goto-body) (line-beginning-position))) (beginning-of-line) (if (looking-at "^Subject:") `((title-begin . (match-end 0)) (first-word . ,(progn (goto-char (match-end 0)) (skip-chars-forward " \t") (cons (point) (progn (forward-word) (poi= nt))))) (last-word . ,(progn (end-of-line) (skip-chars-backward " \t") (cons (save-excursion (forward-word -1) (p= oint)) (point))))))))) (defun turn-smartcap-on () ;; TODO doesn't work with e.g. `subword-capitalize', I guess. (local-set-key [remap capitalize-word] 'smartcap-capitalize-word)) (defun smartcap-capitalize-word (&optional arg) "Proper English title capitalization of a marked region" ;; TODO: I think there's a lot of assumptions on the syntax table. (interactive) (let* ((language (funcall smartcap-language-identifier)) (uncapitalized (smartcap--get-uncapitalized language)) (title (and uncapitalized (funcall (cdr (assoc major-mode smartcap-mode-title-li= ne-identifiers)))))) (if title (let ((first-word (cdr (assoc 'first-word title))) (last-word (cdr (assoc 'last-word title)))) (cond=20 ;; Before first word. ((<=3D (point) (car first-word)) (if (<=3D (cdr first-word) (save-excursion (forward-word) (point))) (capitalize-word 1) (forward-word))) ;; Last word. ((and (<=3D (point) (car last-word)) (>=3D (save-excursion (forward-word) (point)) (cdr last-word))) (capitalize-word 1)) ;; Capitalize or lower word in between ((and (>=3D (point) (cdr first-word)) (< (point) (cdr last-word))) (if (member-ignore-case (save-excursion (skip-chars-forward " \t\\s.\\s_\\s-") (looking-at "\\w+") (match-string 0)) uncapitalized) (downcase-word 1) (capitalize-word 1))) (t (capitalize-word 1)))) (capitalize-word 1)))) (defun smartcap-capitalize-region (&optional begin end) "Capitalize region using `smartcap-capitalize-word'." (interactive) (let ((beg (or begin (region-beginning))) (end (or end (region-end)))) (save-excursion (goto-char beg) (while (< (point) end) (smartcap-capitalize-word))))) (provide 'smartcap) ;;; smartcap.el ends here --=-=-=--