1

我正在为 Lua 开发一个漂亮的打印机,我一直在处理函数语法的缩进。

我想要的是:如果函数定义足够短,所有定义都可以写在一行中,但如果不是那么短,那么所有主体都需要在新行中打印并带有缩进。之后,end关键字应该放在一个新行中,没有缩进。

我想我并不完全理解 Leijen Pretty-printer 的工作原理,但这是我到目前为止所得到的:

import Text.PrettyPrint.Leijen
import System.IO (stdout)

sometext = text "short text" </> text "this is some long text at least long enough for my purposes"
p = parens (align (cat (punctuate (comma <> space) (map text ["first parameter", "second parameter", "third"]))))

doc3 = indent 4 (sep [text "function" </> p, indent 4 sometext, text "end"])

main :: IO ()
main = do
    displayIO stdout (renderPretty 1 133 (doc3 <$> line))
    displayIO stdout (renderPretty 1 134 (doc3 <$> line))
    displayIO stdout (renderPretty 1 40 (doc3 <$> line))

这实际上工作得很好,除了输出的第二部分:

function (first parameter, second parameter, third)
    short text this is some long text at least long enough for my purposes
end

function (first parameter, second parameter, third)     short text this is some long text at least long enough for my purposes end

function (first parameter, 
          second parameter, 
          third)
    short text
    this is some long text at least long enough for my purposes
end

在这里,我不希望在第二个输出中出现 4 个空格缩进。但是我找不到在不破坏其他输出的情况下做到这一点的方法。

任何帮助将不胜感激。

编辑:这是另一个测试用例:

doc4 = sep [ text "if" </> text "test" </> text "then"
           , indent 4 then_body
           , text "elseif" </> elseif_conditions </> text "then"
           , indent 4 elseif_body
           , text "end"
           ]

我想要的是,如果输出足够短,则在同一行打印所有内容(但没有缩进空格)。它在拆分多行时效果很好,但在打印到同一行时会留下多余的空格。

4

1 回答 1

1

首先,让我们尝试一种从最大值开始的每个宽度的文档,并且只打印不同的文档。这将有助于检查 Doc 的行为是否如您所愿。

import Text.PrettyPrint.Leijen
import System.IO (stdout)
import Data.List
import Data.Function

testFrom :: Int -> Doc -> IO ()
testFrom w d = mapM_ printone . nubBy ((==) `on` snd) .map (`showAt` d). reverse $ [1..w] where
   showAt n doc = (n,displayS (renderPretty 1 n doc) "")
   printone (n,xs) = putStrLn (show n ++ ":") >> putStrLn xs

我(现在)认为你想要什么

现在让我们利用您评论中的额外信息。对不起,我第一次误解了你。

我认为您的意思是允许所有人都在一行上,但如果不是,则应该至少有三个,函数头在第一行,函数体缩进,结尾不缩进。您不介意sometext在断点处是否跨行拆分,在参数等之后,只要它不是内联的,缩进 4 即可。

nest函数允许我们缩进后续行(如果有的话),而indent绝对放置空格,这就是为什么你有丑陋的额外 4 行。

因此,您的功能分为三个部分:

functionhead = text "function" </> p
sometext = text "short text" 
           </> text "this is some long text at least long enough for my purposes"
end = text "end"

使用稍微重构的参数制作方式:

params = parens.align.cat.punctuate (comma <> space).map text 
p = params ["first parameter", "second parameter", "third"]

用指定的休息时间布置它

如果我们需要换行符,让我们指定我们希望它们如何布局:

tidyfunction = nest 4 (functionhead <$> sometext) <$> end

这展示了我们希望换行符的方式:

*Main> testFrom 140 tidy
140:
function (first parameter, second parameter, third)
    short text this is some long text at least long enough for my purposes
end
73:
function (first parameter, second parameter, third)
    short text
    this is some long text at least long enough for my purposes
end
50:
function (first parameter, 
          second parameter, 
          third)
    short text
    this is some long text at least long enough for my purposes
end
26:
function
    (first parameter, 
     second parameter, 
     third)
    short text
    this is some long text at least long enough for my purposes
end

如果合适,将其全部放在一行上

漂亮的打印库有一个组合器,如果它适合一行,则可以消除所有换行符,group. 让我们将全部缩进 4 并分组。

nicefunction = group $ indent 4 tidyfunction

这使:

*Main> testFrom 140 nicefunction
140:
    function (first parameter, second parameter, third) short text this is some long text at least long enough for my purposes end
129:
    function (first parameter, second parameter, third)
        short text this is some long text at least long enough for my purposes
    end
77:
    function (first parameter, second parameter, third)
        short text
        this is some long text at least long enough for my purposes
    end
54:
    function (first parameter, 
              second parameter, 
              third)
        short text
        this is some long text at least long enough for my purposes
    end
30:
    function
        (first parameter, 
         second parameter, 
         third)
        short text
        this is some long text at least long enough for my purposes
    end
于 2012-11-18T16:55:30.800 回答