--- /dev/null
+;;; softtext.el --- Load/Save translator for soft text files
+;;
+;; $Id$
+;;
+;; Copyright (C) 1999 Stefan Bund
+
+;; softtext.el 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.
+
+;; softtext.el 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.
+
+;;; Commentary:
+
+;; Externally soft newlines are represented as ordinary newlines with
+;; a preceding space. For this to work reliably, spaces before
+;; newlines are removed prior to writing a buffer out to it's external
+;; representation and re-inserted as annotations in the buffer
+;; encoding function.
+
+;;; Change-Log:
+
+;; $Log$
+;;
+
+;;; Variables:
+
+;;; Code:
+
+(defun softtext-convert-external-to-internal (start end)
+ (let ((mod (buffer-modified-p)))
+ (save-excursion
+ (goto-char start)
+ (if (save-excursion (search-forward "\r\n" nil t))
+ ;;; Old version compatibility
+ (while (search-forward "\r\n" end t)
+ (replace-match "\n")
+ (set-hard-newline-properties (1- (point)) (point)))
+ (while (search-forward "\n" end t)
+ (if (and (> (match-beginning 0) start)
+ (eq (string-to-char (buffer-substring-no-properties (1- (match-beginning 0))
+ (match-beginning 0)))
+ ? ))
+ (save-excursion
+ (goto-char (1- (match-beginning 0)))
+ (delete-char 1))
+ (set-hard-newline-properties (match-beginning 0)
+ (match-end 0))))))
+ (set-buffer-modified-p mod)))
+
+(defun softtext-convert-internal-to-external (start end &optional buffer)
+ (let ((mod (buffer-modified-p))
+ annotations)
+ (save-excursion
+ (if buffer (set-buffer buffer))
+ (save-excursion
+ (goto-char start)
+ (while (search-forward "\n" end t)
+ (if (not (get-text-property (1- (point)) 'hard))
+ (if buffer
+ (setq annotations (cons (cons (- (point) start) " ")
+ annotations))
+ (forward-char -1)
+ (insert " ")
+ (forward-char 1))))))
+ (if (not buffer) (set-buffer-modified-p mod))
+ (nreverse annotations)))
+
+(defun softtext-cleanup-buffer ()
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward " *\n" nil t)
+ (let ((blanks (- (match-end 0) (match-beginning 0) 1)))
+ (if (> blanks 0)
+ (progn
+ (goto-char (match-beginning 0))
+ (delete-char blanks)
+ (forward-char 1)))))))
+
+(defun softtext-hard-newlines-region (start end)
+ (interactive "r")
+ (save-excursion
+ (goto-char start)
+ (while (search-forward "\n" end t)
+ (set-hard-newline-properties (1- (point)) (point)))))
+
+(let ((x (assq 'softtext format-alist)))
+ (if x (setq format-alist (delq x format-alist))))
+
+(let ((elt (assq 'softtext format-alist)))
+ (if elt (setq format-alist (delq elt format-alist)))
+ (setq format-alist
+ (cons '(softtext "Text with hard/soft newlines" nil
+ softtext-convert-external-to-internal
+ softtext-convert-internal-to-external
+ nil nil)
+ format-alist)))
+
+(define-minor-mode softwrap-mode
+ "Toggle SoftWrap minor mode.
+With no argument, this command toggles SoftWrap mode. A Non-null
+prefix argument enables the mode, a null prefix argument disables it.
+
+In SoftWrap mode, emacs differentiates between hard and soft
+newlines. On writing out the buffer to its file, soft newlines a
+reconverted to ordinary newlines preceded by a single space. Any other
+whitspace preceding a newline is removed."
+ nil
+ " SoftWrap"
+ nil
+ (if softwrap-mode
+ (when (not (memq 'softtext buffer-file-format))
+ (softtext-convert-external-to-internal (point-min) (point-max))
+ (setq buffer-file-format (append buffer-file-format (list 'softtext)))
+ (setq use-hard-newlines t)
+ (add-hook 'write-contents-hooks 'softtext-cleanup-buffer))
+ (when (memq 'softtext buffer-file-format)
+ (remove-hook 'write-contents-hooks 'softtext-cleanup-buffer)
+ (setq use-hard-newlines nil)
+ (setq buffer-file-format (delq 'softtext buffer-file-format))
+ (softtext-convert-internal-to-external (point-min) (point-max)))))
+
+(define-derived-mode softtext-mode indented-text-mode "Text"
+ "SoftText Mode is indented-text-mode with SoftWrap minor mode enabled"
+ (softwrap-mode 1))
+
+(provide 'softtext)