#| -*-Scheme-*- Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Massachusetts Institute of Technology This file is part of MIT/GNU Scheme. MIT/GNU Scheme 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 of the License, or (at your option) any later version. MIT/GNU Scheme 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 MIT/GNU Scheme; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |# ;;;; Sorting (define (sort-region region reverse? forward-record record-end key-start key-end compare) (let* ((start (region-start region)) (end (region-end region)) (delete-end (mark-right-inserting-copy end)) (unsorted-list (identify-records region forward-record record-end)) (sorted-list (sort unsorted-list (let ((order (if reverse? not identity-procedure))) (lambda (element1 element2) (order (let ((start1 (key-start (car element1) (cdr element1))) (start2 (key-start (car element2) (cdr element2)))) (compare start1 (key-end start1 (cdr element1)) start2 (key-end start2 (cdr element2)))))))))) (insert-reordered-region start end sorted-list unsorted-list) (kill-string start delete-end) (mark-temporary! delete-end))) (define (identify-records region forward-record record-end) (let ((limit (region-end region))) (let next-record ((start (region-start region))) (if (and start (mark< start limit)) (let ((end (record-end start))) (if (and end (mark< end limit)) (cons (cons start (mark-temporary-copy end)) (next-record (forward-record end))) (list (cons start (mark-temporary-copy limit))))) '())))) (define (insert-reordered-region start end sorted-list unsorted-list) (let ((end-mark (mark-right-inserting-copy end)) (insert-mark (mark-left-inserting-copy end))) (let next-element ((previous start) (sorted-list sorted-list) (unsorted-list unsorted-list)) (if (null? sorted-list) (if (mark< previous end-mark) (insert-string (extract-string previous end-mark) insert-mark)) (begin (if (mark< previous (caar unsorted-list)) (insert-string (extract-string previous (caar unsorted-list)) insert-mark)) (insert-string (extract-string (caar sorted-list) (cdar sorted-list)) insert-mark) (next-element (cdar unsorted-list) (cdr sorted-list) (cdr unsorted-list))))) (mark-temporary! end-mark) (mark-temporary! insert-mark))) (define (sort-textual-comparison start1 end1 start2 end2) (stringnumber string1)) (value2 (string->number string2))) (if (and value1 value2) (< value1 value2) (string