2017-12-16 29 views
0

私は基本的にファイルをコピーするためのCLIユーティリティを持っています。Haskell:I/Oでエスケープするunsolicited unicode文字

{-# LANGUAGE OverloadedStrings #-} 
... 
import Turtle 
... 
{- Command line parser -} 
-- | Represents command line options. 
data Settings = Settings 
    { sVerbose   :: Bool 
... 
    , sSrc    :: FilePath 
    , sDst    :: FilePath 
    } 
... 

トレースコード:

... 
-- | Extracts String From FilePath (unsafe and unofficial). 
-- No double quotes allowed in paths. 
strp :: FilePath -> String 
strp path = 
    let parts = splitOn "\"" (show path) 
in parts !! 1 
... 
    putStrLn "Наблюдаем юникод" 
    putStrLn $ strp (sSrc args) 
    putStrLn $ strp src 
... 

操作コード:

... 
src   <- realpath (sSrc args) 
... 
sSrcため

コンソール入力は、実際.

コンソール出力である:

Наблюдаем юникод 
./ 
/home/alexey/common/Downloads/UpDown/Books/Audio/_Nonfiction_/Moral Combat \8211 Good and Evil in World War II [Unabridged]/ 
1/26 /home/alexey/dir-dst/Moral Combat \\8211 Good and Evil in World War II [Unabridged]/01-Moral Combat \\8211 Part 01.mp3 

\8211はダッシュのようなものです。エスケープされたパスは、.のすぐ外にrealpathによって生成されます。私はその理由を知らない。それは特定のI/Oライブラリですか?コンパイラのオプションですか?ユニコード文字をエスケープしない唯一のものはputStrLnです。

元のパスをそのまま残しておきたいです。

UPD:当分の間、

import qualified Filesystem.Path.CurrentOS as FPS 
import Data.Either.Extra 
... 
-- | Extracts String From FilePath 
-- (good until deprecated system-filepath removed). 
strp :: FilePath -> String 
strp path = T.unpack $ fromRight "" (FPS.toText path) 

をそして、それは動作します:

Make it easy to extract a file path as Text from a FilePath

ハックは今きれいに見えます。それでも、私は強制的に逃げるという考えはまったくありません。 showprintは一般的に非常に役立ち、しばしばエスケープすると役に立たなくなります。これをオフにする方法はありませんか?

+2

文字通りのものとパスの間の変換を少なくするために、https://hackage.haskell.org/package/system-filepath-0.4.13.4/docs/Filesystem-Path-Rules.htmlを見てください。 – dfeuer

+1

'strp'は何をする予定ですか? 'show'は間違いなくそれを実装する方法です。 – Ryan

+0

'show'は最初から醜いものでした。私はちょうど良いことを知らなかった。 UPDを参照してください。私は依然としてオプションでエスケープすることを止めることに非常に関心があります。例えば、 'print'はエスケープのためにしばしば無用です。 –

答えて

0

サブストリング"\\8211"は、(let parts = splitOn "\"" (show path))で生成され、realpathでは生成されません。おそらく、showへの呼び出しを削除する必要がありますが、トレースコードで何を実行するかは100%明確ではありません。

+0

あなたが正しいように見えます。私はこれのために 'show'を使います:https://stackoverflow.com/questions/34659580/with-haskells-turtle-library-how-to-extract-filename-as-string-from-filepath。残念ながら、単にトレースするだけではありません。ファイル/パス名を変更する必要があるため、変換を省略することはできません。エスケープを取り除くために別のI/Oライブラリを使用する必要がありますか? –

+0

うわー、['FilePath'](https://hackage.haskell.org/package/system-filepath-0.4.13.4/docs/Filesystem-Path.html)を変換する方法がないようです。 )文字列に..全く。なぜあなたはその「ショー」ハックをしたのか分かります。あなたがリンクした質問のコメントからは、とにかくsystem-filepathライブラリは廃止されたように見えます。代わりにndmitchellの[filepath](http://hackage.haskell.org/package/filepath)ライブラリを使用することをお勧めします。私はそれが互換性があるかどうかを知るためにタートルに十分に精通していない。 – luqui

+0

AHA! ['toText'](https://hackage.haskell.org/package/system-filepath-0.4.13.4/docs/Filesystem-Path-Rules)を使って' FilePath'を文字列に変換することができます。html#v:toText)(あるいは、技術的には '' unpack''(https://hackage.haskell.org/package/text-1.2.0.4/docs/Data-Text.html#v:unpack) '.toText ')をSystem.FilePath.Rulesモジュールから削除します。このトリックは、文字列のプラットフォームの味を指定するために 'Rules'オブジェクトを使用する必要があります(1時間前にこの実現に私を打ち負かしましたが、私のコメントはより肯定的です)。 – luqui

関連する問題