0

I've got a CLI utility for copying files, basically.

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

Tracing code:

...
-- | 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
...

Working code:

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

Console input for sSrc is actually .

Console output:

Наблюдаем юникод
./
/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 is some kind of dash. The escaped path is produced by realpath right out of the .. I don't know the reason why. Is it the particular i/o library? Is it compiler options? The only thing so far that wouldn't escape unicode characters is putStrLn.

I want the original path intact.

UPD:

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

The hack now looks prettier:

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)

And it works, for the time being. Still, I like the idea of mandatory escaping not at all. show and print are very helpful generally, and often rendered useless by escaping. No way to turn this off?

Alexey Orlov
  • 2,412
  • 3
  • 27
  • 46
  • 2
    Take a look at https://hackage.haskell.org/package/system-filepath-0.4.13.4/docs/Filesystem-Path-Rules.html for less hacky ways to convert between stringy things and paths. – dfeuer Dec 16 '17 at 05:43
  • 1
    What is `strp` supposed to do? `show` is definitely the wrong way to implement it. – Ry- Dec 16 '17 at 05:48
  • `show` was ugly right from the start. I just knew no better. See UPD. I am still very much interested in turning off escaping optionally. `print`, for instance, is often quite useless because of escaping. – Alexey Orlov Dec 16 '17 at 07:54
  • @AlexeyOrlov, what exactly do you want in terms of escaping, that `putStrLn` does not satisfy? – luqui Dec 16 '17 at 18:26

1 Answers1

0

The substring "\\8211" is produced by show (in let parts = splitOn "\"" (show path)), not by realpath. Probably you should just delete the call to show, though it's not 100% clear what you wanted the tracing code to do.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
  • Looks like you are right. I use `show` because of this: https://stackoverflow.com/questions/34659580/with-haskells-turtle-library-how-to-extract-filename-as-string-from-filepath . Unfortunately, it is not just tracing: I have to mangle some file/path names, so I can't dispense with conversion. Do I have to use another i/o library to get rid of escaping? – Alexey Orlov Dec 16 '17 at 06:23
  • Wow, huh, there doesn't seem to be a way to convert a [`FilePath`](https://hackage.haskell.org/package/system-filepath-0.4.13.4/docs/Filesystem-Path.html) to a string.. at all. I see why you did that `show` hack. From a comment on the question you linked, it looks like that system-filepath library is deprecated anyway, and it recommends using ndmitchell's [filepath](http://hackage.haskell.org/package/filepath) library instead. I'm not familiar enough with Turtle to know if it would be compatible. – luqui Dec 16 '17 at 07:24
  • AHA! You *can* convert a `FilePath` to a string, using [`toText`](https://hackage.haskell.org/package/system-filepath-0.4.13.4/docs/Filesystem-Path-Rules.html#v:toText) (or I guess technically [`unpack`](https://hackage.haskell.org/package/text-1.2.0.4/docs/Data-Text.html#v:unpack)`. toText`) from the `System.FilePath.Rules` module. The trick is, you need to use a `Rules` object to specify the platform flavor the string should be in. (Oh, dfeuer beat me to this realization an hour ago. But my comment is more singsongy, innit?) – luqui Dec 16 '17 at 07:29
  • @luqui, there's also an `IsString` instance. – dfeuer Dec 16 '17 at 13:47
  • I'd still like to know whether it is possible to turn off escaping generally. If the definitive answer is NO, some explanation or a link to authoritative source is welcome. – Alexey Orlov Dec 17 '17 at 07:54
  • @AlexeyOrlov Perhaps you had better open a fresh question with the details of what you mean by "turn off escaping", especially if other folks' comments here aren't sufficient; they seem like they should be to me, so you need to post some clarifying details about what's wrong with the proposed alternatives to `show`. – Daniel Wagner Dec 17 '17 at 19:27