Created
September 30, 2012 17:37
-
-
Save jturner314/3807830 to your computer and use it in GitHub Desktop.
Removes common indentation from a collection of lines. Written in response to http://jjinux.blogspot.com/2012/09/dart-algorithm-to-unindent-code.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns dedent-text.core | |
(:use [clojure.string :only [blank?]])) | |
(defn all-equal? | |
"Returns the value if all values are equal, otherwise nil." | |
[& values] | |
(when (apply = values) (first values))) | |
(defn count-common-indentation | |
"Returns length of common indentation of strings." | |
[& strings] | |
(count (take-while #(and (not (nil? %)) (blank? (str %))) | |
(apply map all-equal? strings)))) | |
(defn dedent-lines | |
"Returns a lazy seq of strs with the common indentation removed from lines. | |
Only considers indentation of nonblank lines, and sets blank lines to an | |
empty string." | |
[lines] | |
(if (empty? lines) | |
lines | |
(let [non-blank (remove blank? lines) | |
common-indent (apply count-common-indentation non-blank)] | |
(for [line lines] | |
(if (blank? line) | |
"" | |
(subs line common-indent)))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns dedent-text.core-test | |
(:use clojure.test | |
dedent-text.core)) | |
(deftest dedent-lines-test | |
(testing "unindenting code" | |
(is (= (dedent-lines [" 1" | |
" 2"]) | |
["1" | |
"2"]))) | |
(testing "unindenting code where the first line is indented the most" | |
(is (= (dedent-lines ["\t 1" | |
"\t 2" | |
"\t 3"]) | |
[" 1" | |
"2" | |
" 3"]))) | |
(testing "doing nothing for unindented code" | |
(is (= (dedent-lines ["1" | |
"2" | |
"3"]) | |
["1" | |
"2" | |
"3"]))) | |
(testing "handling empty lists" | |
(is (= (dedent-lines []) | |
[]))) | |
(testing "not trying to handle inconsistent indentation" | |
(is (= (dedent-lines ["\t1" | |
" 2" | |
" 3" | |
" 4"]) | |
["\t1" | |
" 2" | |
" 3" | |
" 4"]))) | |
(testing "handling really awkward short lines" | |
(is (= (dedent-lines [" 1" | |
"2"]) | |
[" 1" | |
"2"]))) | |
(testing "handling blank lines and lines with only indentation" | |
(is (= (dedent-lines [" 1" | |
"" | |
" " | |
" 2"]) | |
["1" | |
"" | |
"" | |
" 2"])))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment