@@ 48,6 48,17 @@
(and (ignore "\"") (* str-chr) (ignore "\"")
(? (and (ignore (* whitespace)) content))))
+(define (replace-escaped-backslashes str)
+ "Replace '\\\\' sequences in STR with a single '\\'."
+ (let loop ((str str)
+ (result '()))
+ (match (string-contains str "\\\\")
+ (#f (string-concatenate-reverse (cons str result)))
+ (index
+ (let ((prefix (string-take str index)))
+ (loop (string-drop str (+ 2 index))
+ (append (list "\\" prefix) result)))))))
+
(define (final-character-escapes? str last-index)
"Check if STR ends in an incomplete escape sequence, that is ends in an uneven
number of backslashes. LAST-INDEX is the index of its last character."
@@ 55,19 66,29 @@ number of backslashes. LAST-INDEX is the index of its last character."
(eqv? (string-ref str last-index) #\\)
(not (final-character-escapes? str (- last-index 1)))))
-(define (interpret-newline-escape str)
- "Replace unescaped '\\n' sequences in STR with a newline character."
+(define (interpret-escape sequence replacement str)
+ "Replace backslash escape sequence SEQUENCE in STR with REPLACEMENT (a string)
+when SEQUENCE is not escaped itself. For example, SEQUENCE '\\n' with a
+newline string as REPLACEMENT."
(let loop ((str str)
(result '()))
- (match (string-contains str "\\n")
+ (match (string-contains str sequence)
(#f (string-concatenate-reverse (cons str result)))
(index
(let ((prefix (string-take str index)))
(loop (string-drop str (+ 2 index))
- ;; Only add a newline when the backslash is not escaped itself.
+ ;; Only add REPLACEMENT when the backslash is not escaped itself.
(if (final-character-escapes? str (- index 1))
(cons (string-take str (+ 2 index)) result)
- (append (list "\n" prefix) result))))))))
+ (append (list replacement prefix) result))))))))
+
+(define (interpret-escape-sequences str)
+ "Unescape all escape sequences in STR."
+ (replace-escaped-backslashes
+ (interpret-escape "\\n" "\n"
+ (interpret-escape "\\\"" "\""
+ (interpret-escape "\\t" "\t"
+ str)))))
(define (parse-tree->assoc parse-tree)
"Converts a po PARSE-TREE to an association list, where the key is the msgid
@@ 103,18 124,14 @@ and the value is the msgstr. The result only contains non fuzzy strings."
(('entry _ ('msgid msgid) 'msgstr)
(parse-tree->assoc parse-tree))
(('entry ('msgid msgid) ('msgstr msgstr))
- (acons (interpret-newline-escape msgid)
- (interpret-newline-escape msgstr)
- (parse-tree->assoc parse-tree)))
- (('entry ('msgid msgid) ('msgstr msgstr))
- (acons (interpret-newline-escape msgid)
- (interpret-newline-escape msgstr)
+ (acons (interpret-escape-sequences msgid)
+ (interpret-escape-sequences msgstr)
(parse-tree->assoc parse-tree)))
(('entry comments ('msgid msgid) ('msgstr msgstr))
(if (member 'fuzzy (comments->flags comments))
(parse-tree->assoc parse-tree)
- (acons (interpret-newline-escape msgid)
- (interpret-newline-escape msgstr)
+ (acons (interpret-escape-sequences msgid)
+ (interpret-escape-sequences msgstr)
(parse-tree->assoc parse-tree))))))))
(define (read-po-file port)