File: elib-string.el

package info (click to toggle)
lyskom-elisp-client 0.48%2Bgit.20231226.364902c3-3
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,556 kB
  • sloc: lisp: 51,958; xml: 1,028; sh: 62; makefile: 46
file content (168 lines) | stat: -rw-r--r-- 5,429 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
;;;;; -*-coding: iso-8859-1;-*-
;;;; This file contains some miscellaneous string functions

;; Copyright (C) 1991-1995 Free Software Foundation

;; Author: Sebastian Kremer <sk@thp.Uni-Koeln.DE>
;;	Per Cederqvist <ceder@lysator.liu.se>
;;	Inge Wallin <inge@lysator.liu.se>
;; Maintainer: elib-maintainers@lysator.liu.se
;; Created: before 9 May 1991
;; Keywords: extensions, lisp

;;;; This file is part of the GNU Emacs lisp library, Elib.
;;;;
;;;; GNU Elib 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 2, or (at your option)
;;;; any later version.
;;;;
;;;; GNU Elib 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 GNU Elib; see the file COPYING.  If not, write to
;;;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;;;; Boston, MA 02111-1307, USA
;;;; 
;;;; Author: Sebastian Kremer
;;;;         sk@thp.Uni-Koeln.DE
;;;; 


;;; Commentary:

;;;
;;; This file is part of the elisp library Elib.
;;; It implements simple generic string functions for use in other 
;;; elisp code: replace regexps in strings, split strings on regexps.
;;; 


;;; NOTE NOTE NOTE NOTE NOTE
;;;
;;; This package has been slightly modified in the following section:


(defvar elib-newtext)
(defvar elib-string)

;;; Code:

(provide 'string)


;; This function is a near-equivalent of the elisp function replace-match
;; which work on strings instead of a buffer.  The FIXEDCASE parameter
;; of replace-match is not implemented.

(defun string-replace-match (regexp elib-string elib-newtext &optional literal global)
  "Replace first match of REGEXP in ELIB-STRING with ELIB-NEWTEXT.
If no match is found, nil is returned instead of the new string.

Optional arg LITERAL non-nil means to take ELIB-NEWTEXT literally. If LITERAL is 
nil, character `\\' is the start of one of the following sequences:
  \\\\   will be replaced by a single \\.
  \\&   will be replaced by the text which matched the regexp.
  \\N   where N is a number and 1 <= N <= 9, will be replaced
       by the Nth subexpression in REGEXP. Subexpressions are grouped
       inside \\( \\).

Optional arg GLOBAL means to replace all matches instead of only the first."

  (let ((data (match-data)))
    (unwind-protect

	(if global
	    (let ((result "") 
		  (start 0)
		  matchbeginning
		  matchend)
	      (while (string-match regexp elib-string start)
		(setq matchbeginning (match-beginning 0)
		      matchend (match-end 0)
		      result (concat result
				     (substring elib-string start matchbeginning)
				     (if literal
					 elib-newtext
				       (elib-string-expand-newtext)))
		      start matchend))

	      (if matchbeginning	; matched at least once
		  (concat result (substring elib-string start))
		nil))

	  ;; not GLOBAL
	  (if (not (string-match regexp elib-string 0))
	      nil
	    (concat (substring elib-string 0 (match-beginning 0))
		    (if literal elib-newtext (elib-string-expand-newtext))
		    (substring elib-string (match-end 0)))))
      (store-match-data data))))


(defun elib-string-expand-newtext ()
  ;; Expand \& and \1..\9 (referring to ELIB-STRING) in ELIB-NEWTEXT.
  ;; Uses match data and fluid vars `elib-newtext', `elib-string'.
  ;; Note that in Emacs 18 match data are clipped to current buffer
  ;; size...so the buffer should better not be smaller than ELIB-STRING.
  (let ((pos 0)
	(len (length elib-newtext))
	(expanded-newtext ""))
    (while (< pos len)
      (setq expanded-newtext
	    (concat expanded-newtext
		    (let ((c (aref elib-newtext pos)))
		      (if (= ?\\ c)
			  (cond ((= ?\& (setq c (aref elib-newtext
						      (setq pos (1+ pos)))))
				 (substring elib-string
					    (match-beginning 0)
					    (match-end 0)))
				((and (>= c ?1) 
				      (<= c ?9))
				 ;; return empty string if N'th
				 ;; sub-regexp did not match:
				 (let ((n (- c ?0)))
				   (if (match-beginning n)
				       (substring elib-string
						  (match-beginning n)
						  (match-end n))
				     "")))
				(t (char-to-string c)))
			(char-to-string c)))))
      (setq pos (1+ pos)))
    expanded-newtext))


(defun string-split (pattern string &optional limit)
  "Splitting on regexp PATTERN, turn string STRING into a list of substrings.
Optional third arg LIMIT (>= 1) is a limit to the length of the
resulting list."

  (let ((data (match-data)))
    (unwind-protect
	(let* ((start (string-match pattern string))
	       (result (list (substring string 0 start)))
	       (count 1)
	       (end (if start (match-end 0))))
	  (if end			; else nothing left
	      (while (and (or (not (integerp limit))
			      (< count limit))
			  (string-match pattern string end))
		(setq start (match-beginning 0)
		      count (1+ count)
		      result (cons (substring string end start) result)
		      end (match-end 0)
		      start end)))
	  (if (and (or (not (integerp limit))
		       (< count limit))
		   end)			; else nothing left
	      (setq result
		    (cons (substring string end) result)))
	  (nreverse result))
      (store-match-data data))))

;;; string.el ends here