Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit

  • Loading branch information...
commit 2bf06bcd12d71348ed525ce3f2f291ac40253f70 0 parents
Magnar Sveen authored October 02, 2012
62  README.md
Source Rendered
... ...
@@ -0,0 +1,62 @@
  1
+# s.el [![Build Status](https://secure.travis-ci.org/magnars/s.el.png)](http://travis-ci.org/magnars/s.el)
  2
+
  3
+The long lost Emacs string manipulation library.
  4
+
  5
+## Warning
  6
+
  7
+This is so much a work in progress that you should definitely not be using it yet.
  8
+
  9
+## Functions
  10
+
  11
+* [s-trim](#s-trim-s) `(s)`
  12
+
  13
+## Documentation and examples
  14
+
  15
+### s-trim `(s)`
  16
+
  17
+Remove whitespace at beginning and end of string.
  18
+
  19
+```cl
  20
+(s-trim "trim ") ;; => "trim"
  21
+(s-trim " this") ;; => "this"
  22
+(s-trim " only  trims beg and end  ") ;; => "only  trims beg and end"
  23
+```
  24
+
  25
+
  26
+## Development
  27
+
  28
+Run the tests with
  29
+
  30
+    ./run-tests.sh
  31
+
  32
+Create the docs with
  33
+
  34
+    ./create-docs.sh
  35
+
  36
+I highly recommend that you install these as a pre-commit hook, so that
  37
+the tests are always running and the docs are always in sync:
  38
+
  39
+    cp pre-commit.sh .git/hooks/pre-commit
  40
+
  41
+Oh, and don't edit `README.md` directly, it is auto-generated.
  42
+Change `readme-template.md` or `examples-to-docs.el` instead.
  43
+
  44
+## License
  45
+
  46
+Copyright (C) 2012 Magnar Sveen
  47
+
  48
+Authors: Magnar Sveen <magnars@gmail.com>
  49
+Keywords: strings
  50
+
  51
+This program is free software; you can redistribute it and/or modify
  52
+it under the terms of the GNU General Public License as published by
  53
+the Free Software Foundation, either version 3 of the License, or
  54
+(at your option) any later version.
  55
+
  56
+This program is distributed in the hope that it will be useful,
  57
+but WITHOUT ANY WARRANTY; without even the implied warranty of
  58
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  59
+GNU General Public License for more details.
  60
+
  61
+You should have received a copy of the GNU General Public License
  62
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
7  create-docs.sh
... ...
@@ -0,0 +1,7 @@
  1
+#!/usr/bin/env bash
  2
+
  3
+if [ -z "$EMACS" ] ; then
  4
+    EMACS="emacs"
  5
+fi
  6
+
  7
+$EMACS -batch -l s.el -l examples-to-docs.el -l examples.el -f create-docs-file
2,544  ert.el
2544 additions, 0 deletions not shown
116  examples-to-docs.el
... ...
@@ -0,0 +1,116 @@
  1
+(defvar functions '())
  2
+
  3
+(defun example-to-string (example)
  4
+  (let ((actual (car example))
  5
+        (expected (cadr (cdr example))))
  6
+    (replace-regexp-in-string "\\\\\\?" "?" (format "%S ;; => %S" actual expected))))
  7
+
  8
+(defun examples-to-strings (examples)
  9
+  (let (result)
  10
+    (while examples
  11
+      (setq result (cons (example-to-string examples) result))
  12
+      (setq examples (cddr (cdr examples))))
  13
+    (nreverse result)))
  14
+
  15
+(defmacro defexamples (cmd &rest examples)
  16
+  `(add-to-list 'functions (list
  17
+                            ',cmd ;; command name
  18
+                            (cadr (symbol-function ',cmd)) ;; signature
  19
+                            (car (cddr (symbol-function ',cmd))) ;; docstring
  20
+                            (examples-to-strings ',examples)))) ;; examples
  21
+
  22
+(defun quote-and-downcase (string)
  23
+  (format "`%s`" (downcase string)))
  24
+
  25
+(defun quote-docstring (docstring)
  26
+  (let (case-fold-search)
  27
+    (setq docstring (replace-regexp-in-string "\\b\\([A-Z][A-Z-]*[0-9]*\\)\\b" 'quote-and-downcase docstring t))
  28
+    (setq docstring (replace-regexp-in-string "`\\([^ ]+\\)'" "`\\1`" docstring t)))
  29
+  docstring)
  30
+
  31
+(defun function-to-md (function)
  32
+  (let ((command-name (car function))
  33
+        (signature (cadr function))
  34
+        (docstring (quote-docstring (cadr (cdr function))))
  35
+        (examples (cadr (cddr function))))
  36
+    (format "### %s `%s`\n\n%s\n\n```cl\n%s\n```\n"
  37
+            command-name
  38
+            signature
  39
+            docstring
  40
+            (mapconcat 'identity (three-first examples) "\n"))))
  41
+
  42
+(defun split-name (s)
  43
+  "Split name into list of words"
  44
+  (split-string
  45
+   (let ((case-fold-search nil))
  46
+     (downcase
  47
+      (replace-regexp-in-string "\\([a-z]\\)\\([A-Z]\\)" "\\1 \\2" s)))
  48
+   "[^A-Za-z0-9]+"))
  49
+
  50
+(defmacro !!filter (form list)
  51
+  "Anaphoric form of `!filter'."
  52
+  `(let ((!--list ,list)
  53
+         (!--result '()))
  54
+     (while !--list
  55
+       (let ((it (car !--list)))
  56
+         (when ,form
  57
+           (setq !--result (cons it !--result))))
  58
+       (setq !--list (cdr !--list)))
  59
+     (nreverse !--result)))
  60
+
  61
+(defmacro !!remove (form list)
  62
+  "Anaphoric form of `!remove'."
  63
+  `(!!filter (not ,form) ,list))
  64
+
  65
+(defun dashed-words (s)
  66
+  "Convert string S to snake-case string."
  67
+  (mapconcat 'identity (mapcar
  68
+                        '(lambda (word) (downcase word))
  69
+                        (!!remove (equal it "") (split-name s))) "-"))
  70
+
  71
+(defun github-id (command-name signature)
  72
+  (dashed-words (format "%s %s" command-name signature)))
  73
+
  74
+(defun function-summary (function)
  75
+  (let ((command-name (car function))
  76
+        (signature (cadr function)))
  77
+    (format "* [%s](#%s) `%s`" command-name (github-id command-name signature) signature)))
  78
+
  79
+(defun simplify-quotes ()
  80
+  (goto-char (point-min))
  81
+  (while (search-forward "(quote " nil t)
  82
+    (forward-char -7)
  83
+    (let ((p (point)))
  84
+      (forward-sexp 1)
  85
+      (delete-char -1)
  86
+      (goto-char p)
  87
+      (delete-char 7)
  88
+      (insert "'"))))
  89
+
  90
+(defun goto-and-remove (s)
  91
+  (goto-char (point-min))
  92
+  (search-forward s)
  93
+  (delete-char (- (length s))))
  94
+
  95
+(defun create-docs-file ()
  96
+  (let ((functions (nreverse functions)))
  97
+    (with-temp-file "./README.md"
  98
+      (insert-file-contents-literally "./readme-template.md")
  99
+
  100
+      (goto-and-remove "[[ function-list ]]")
  101
+      (insert (mapconcat 'function-summary functions "\n"))
  102
+
  103
+      (goto-and-remove "[[ function-docs ]]")
  104
+      (insert (mapconcat 'function-to-md functions "\n"))
  105
+
  106
+      (simplify-quotes))))
  107
+
  108
+(defun three-first (list)
  109
+  (let (first)
  110
+    (when (car list)
  111
+      (setq first (cons (car list) first))
  112
+      (when (cadr list)
  113
+        (setq first (cons (cadr list) first))
  114
+        (when (car (cddr list))
  115
+          (setq first (cons (car (cddr list)) first)))))
  116
+    (nreverse first)))
19  examples-to-tests.el
... ...
@@ -0,0 +1,19 @@
  1
+(require 'ert)
  2
+
  3
+(defun examples-to-should-1 (examples)
  4
+  (let ((actual (car examples))
  5
+        (expected (cadr (cdr examples))))
  6
+    `(should (equal ,actual ,expected))))
  7
+
  8
+(defun examples-to-should (examples)
  9
+  (let (result)
  10
+    (while examples
  11
+      (setq result (cons (examples-to-should-1 examples) result))
  12
+      (setq examples (cddr (cdr examples))))
  13
+    (nreverse result)))
  14
+
  15
+(defmacro defexamples (cmd &rest examples)
  16
+  `(ert-deftest ,cmd ()
  17
+     ,@(examples-to-should examples)))
  18
+
  19
+(provide 'examples-to-tests)
12  examples.el
... ...
@@ -0,0 +1,12 @@
  1
+;; -*- lexical-binding: t -*-
  2
+
  3
+;; Only the first three examples per function are shown in the docs,
  4
+;; so make those good.
  5
+
  6
+(require 's)
  7
+
  8
+(defexamples s-trim
  9
+  (s-trim "trim ") => "trim"
  10
+  (s-trim " this") => "this"
  11
+  (s-trim " only  trims beg and end  ") => "only  trims beg and end"
  12
+)
9  pre-commit.sh
... ...
@@ -0,0 +1,9 @@
  1
+#!/bin/sh
  2
+
  3
+git stash -q --keep-index
  4
+./run-tests.sh
  5
+RESULT=$?
  6
+[ $RESULT == 0 ] && ./create-docs.sh && git add ./README.md
  7
+git stash pop -q
  8
+[ $RESULT -ne 0 ] && exit 1
  9
+exit 0
53  readme-template.md
Source Rendered
... ...
@@ -0,0 +1,53 @@
  1
+# s.el [![Build Status](https://secure.travis-ci.org/magnars/s.el.png)](http://travis-ci.org/magnars/s.el)
  2
+
  3
+The long lost Emacs string manipulation library.
  4
+
  5
+## Warning
  6
+
  7
+This is so much a work in progress that you should definitely not be using it yet.
  8
+
  9
+## Functions
  10
+
  11
+[[ function-list ]]
  12
+
  13
+## Documentation and examples
  14
+
  15
+[[ function-docs ]]
  16
+
  17
+## Development
  18
+
  19
+Run the tests with
  20
+
  21
+    ./run-tests.sh
  22
+
  23
+Create the docs with
  24
+
  25
+    ./create-docs.sh
  26
+
  27
+I highly recommend that you install these as a pre-commit hook, so that
  28
+the tests are always running and the docs are always in sync:
  29
+
  30
+    cp pre-commit.sh .git/hooks/pre-commit
  31
+
  32
+Oh, and don't edit `README.md` directly, it is auto-generated.
  33
+Change `readme-template.md` or `examples-to-docs.el` instead.
  34
+
  35
+## License
  36
+
  37
+Copyright (C) 2012 Magnar Sveen
  38
+
  39
+Authors: Magnar Sveen <magnars@gmail.com>
  40
+Keywords: strings
  41
+
  42
+This program is free software; you can redistribute it and/or modify
  43
+it under the terms of the GNU General Public License as published by
  44
+the Free Software Foundation, either version 3 of the License, or
  45
+(at your option) any later version.
  46
+
  47
+This program is distributed in the hope that it will be useful,
  48
+but WITHOUT ANY WARRANTY; without even the implied warranty of
  49
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  50
+GNU General Public License for more details.
  51
+
  52
+You should have received a copy of the GNU General Public License
  53
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
7  run-tests.sh
... ...
@@ -0,0 +1,7 @@
  1
+#!/usr/bin/env bash
  2
+
  3
+if [ -z "$EMACS" ] ; then
  4
+    EMACS="emacs"
  5
+fi
  6
+
  7
+$EMACS -batch -l ert.el -l examples-to-tests.el -l s.el -l examples.el -f ert-run-tests-batch-and-exit
34  s.el
... ...
@@ -0,0 +1,34 @@
  1
+;;; s.el --- The long lost Emacs string manipulation library.
  2
+
  3
+;; Copyright (C) 2012 Magnar Sveen
  4
+
  5
+;; Author: Magnar Sveen <magnars@gmail.com>
  6
+;; Keywords: strings
  7
+
  8
+;; This program is free software; you can redistribute it and/or modify
  9
+;; it under the terms of the GNU General Public License as published by
  10
+;; the Free Software Foundation, either version 3 of the License, or
  11
+;; (at your option) any later version.
  12
+
  13
+;; This program is distributed in the hope that it will be useful,
  14
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16
+;; GNU General Public License for more details.
  17
+
  18
+;; You should have received a copy of the GNU General Public License
  19
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20
+
  21
+;;; Commentary:
  22
+
  23
+;; The long lost Emacs string manipulation library.
  24
+
  25
+;;; Code:
  26
+
  27
+(defun s-trim (s)
  28
+  "Remove whitespace at beginning and end of string."
  29
+  (if (string-match "\\`[ \t\n\r]+" s) (setq s (replace-match "" t t s)))
  30
+  (if (string-match "[ \t\n\r]+\\'" s) (setq s (replace-match "" t t s)))
  31
+  s)
  32
+
  33
+(provide 's)
  34
+;;; s.el ends here
38  watch-tests.watchr
... ...
@@ -0,0 +1,38 @@
  1
+ENV["WATCHR"] = "1"
  2
+system 'clear'
  3
+
  4
+def run(cmd)
  5
+  `#{cmd}`
  6
+end
  7
+
  8
+def run_all_tests
  9
+  system('clear')
  10
+  result = run "./run-tests.sh"
  11
+  puts result
  12
+end
  13
+
  14
+run_all_tests
  15
+watch('.*.el') { run_all_tests }
  16
+
  17
+# Ctrl-\
  18
+Signal.trap 'QUIT' do
  19
+  puts " --- Running all tests ---\n\n"
  20
+  run_all_tests
  21
+end
  22
+
  23
+@interrupted = false
  24
+
  25
+# Ctrl-C
  26
+Signal.trap 'INT' do
  27
+  if @interrupted then
  28
+    @wants_to_quit = true
  29
+    abort("\n")
  30
+  else
  31
+    puts "Interrupt a second time to quit"
  32
+    @interrupted = true
  33
+    Kernel.sleep 1.5
  34
+    # raise Interrupt, nil # let the run loop catch it
  35
+    run_all_tests
  36
+    @interrupted = false
  37
+  end
  38
+end

0 notes on commit 2bf06bc

Please sign in to comment.
Something went wrong with that request. Please try again.