mdoc 0.6.0.1 → 0.6.1.0
raw patch · 15 files changed
+111/−135 lines, 15 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Mdoc.Data.Synopsis: InlineSynopsis :: Synopsis -> InlineSynopsis
+ Mdoc.Data.Synopsis: [unwrap] :: InlineSynopsis -> Synopsis
+ Mdoc.Data.Synopsis: instance Data.Aeson.Types.ToJSON.ToJSON Mdoc.Data.Synopsis.InlineSynopsis
+ Mdoc.Data.Synopsis: instance GHC.Classes.Eq Mdoc.Data.Synopsis.InlineSynopsis
+ Mdoc.Data.Synopsis: instance GHC.Show.Show Mdoc.Data.Synopsis.InlineSynopsis
+ Mdoc.Data.Synopsis: instance Prettyprinter.Internal.Pretty Mdoc.Data.Synopsis.InlineSynopsis
+ Mdoc.Data.Synopsis: newtype InlineSynopsis
- Mdoc.Data.Command: Command :: Int -> String -> Synopsis -> Maybe Mdoc -> Command
+ Mdoc.Data.Command: Command :: Int -> String -> InlineSynopsis -> Maybe Mdoc -> Command
- Mdoc.Data.Command: [synopsis] :: Command -> Synopsis
+ Mdoc.Data.Command: [synopsis] :: Command -> InlineSynopsis
- Mdoc.Data.Page: addCommands :: [Command] -> Page -> Page
+ Mdoc.Data.Page: addCommands :: Optionality -> [Command] -> Page -> Page
- Mdoc.Data.Synopsis: command :: Synopsis
+ Mdoc.Data.Synopsis: command :: Optionality -> Synopsis
Files
- data/commands.mustache +5/−0
- data/man1.mustache +1/−15
- data/synopsis.mustache +5/−0
- examples/docker.1 +1/−10
- examples/pass.1 +5/−46
- mdoc.cabal +2/−1
- src/Mdoc/Data/Command.hs +2/−2
- src/Mdoc/Data/Page.hs +3/−3
- src/Mdoc/Data/Synopsis.hs +46/−31
- src/Mdoc/Examples/Pass.hs +3/−1
- src/Mdoc/Template.hs +26/−4
- src/OptEnvConf/Mdoc.hs +6/−3
- src/Options/Applicative/Mdoc.hs +3/−2
- templates/grep.1.mustache +1/−3
- templates/pass.1.mustache +2/−14
data/commands.mustache view
@@ -1,6 +1,11 @@ .Bl -tag -width {{{width}}} {{#items}}+{{#synopsis}}+.It Cm {{{name}}} {{{.}}}+{{/synopsis}}+{{^synopsis}} .It Cm {{{name}}}+{{/synopsis}} {{#description}} {{{description}}} {{/description}}
data/man1.mustache view
@@ -1,20 +1,6 @@ {{>title1}} {{>name}}-.Sh SYNOPSIS-.Nm-{{#page.synopsis}}-{{{page.synopsis}}}-{{/page.synopsis}}-{{#page.commands}}-{{#items}}-.Pp-.Nm-.Cm {{{name}}}-{{#synopsis}}-{{{.}}}-{{/synopsis}}-{{/items}}-{{/page.commands}}+{{>synopsis}} .Sh DESCRIPTION {{#page.options}} {{>options}}
+ data/synopsis.mustache view
@@ -0,0 +1,5 @@+.Sh SYNOPSIS+.Nm+{{#page.synopsis}}+{{{page.synopsis}}}+{{/page.synopsis}}
examples/docker.1 view
@@ -19,15 +19,6 @@ .Op Fl Fl tlsverify .Ar command .Ek-.Pp-.Nm-.Cm run-.Bk -words-.Op Fl a Ar list-.Ar IMAGE-.Op Ar COMMAND ...-.Op Ar ARG ...-.Ek .Sh DESCRIPTION The options are as follows: .Bl -tag -width indent@@ -62,7 +53,7 @@ .El .Ss COMMANDS .Bl -tag -width indent-.It Cm run+.It Cm run Oo Fl a Ar list Oc Ar IMAGE Oo Ar COMMAND ... Oc Oo Ar ARG ... Oc Create and run a new container from an image .El .Sh EXIT STATUS
examples/pass.1 view
@@ -9,47 +9,6 @@ .Bk -words .Ar command .Ek-.Pp-.Nm-.Cm init-.Bk -words-.Op Fl p Ar sub\-folder-.Ar gpg\-id-.Ek-.Pp-.Nm-.Cm ls-.Bk -words-.Ar subfolder-.Ek-.Pp-.Nm-.Cm grep-.Bk -words-.Op Ar GREPOPTIONS-.Ar search\-string-.Ek-.Pp-.Nm-.Cm find-.Bk -words-.Ar pass\-names-.Op Ar pass\-names ...-.Ek-.Pp-.Nm-.Cm show-.Bk -words-.Op Fl c Ar line\-number-.Op Fl q Ar line\-number-.Ar pass\-name-.Ek-.Pp-.Nm-.Cm help-.Pp-.Nm-.Cm version .Sh DESCRIPTION .Nm is a very simple password store that keeps passwords inside@@ -97,7 +56,7 @@ .Xr bash 1 . .Ss COMMANDS .Bl -tag -width indent-.It Cm init+.It Cm init Oo Fl p Ar sub\-folder Oc Ar gpg\-id Initialize new password storage and use gpg\-id for encryption. Multiple gpg\-ids may be specified, in order to encrypt each password with multiple ids. This command must be run first before a password store can be used. If the@@ -109,18 +68,18 @@ the password store. If only one gpg\-id is given, and it is an empty string, then the current .gpg\-id file for the specified sub\-folder (or root if unspecified) is removed.-.It Cm ls+.It Cm ls Ar subfolder List names of passwords inside the tree at subfolder by using the tree(1) program. This command is alternatively named list.-.It Cm grep+.It Cm grep Oo Ar GREPOPTIONS Oc Ar search\-string Searches inside each decrypted password file for search\-string, and displays line containing matched string along with filename. Uses grep(1) for matching. GREPOPTIONS are passed to grep(1) as\-is. (Note: the GREP_OPTIONS environment variable functions as well.)-.It Cm find+.It Cm find Ar pass\-names Oo Ar pass\-names ... Oc List names of passwords inside the tree that match pass\-names by using the tree(1) program. This command is alternatively named search.-.It Cm show+.It Cm show Oo Fl c Ar line\-number Oc Oo Fl q Ar line\-number Oc Ar pass\-name Decrypt and print a password named pass\-name. If \-\-clip or \-c is specified, do not print the password but instead copy the first (or otherwise specified) line to the clipboard using xclip(1) or wl\-clipboard(1) and then restore the
mdoc.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.18 name: mdoc-version: 0.6.0.1+version: 0.6.1.0 license: AGPL-3 license-file: COPYING maintainer: Pat Brisbin@@ -38,6 +38,7 @@ data/man5.mustache data/name.mustache data/options.mustache+ data/synopsis.mustache data/tag-list.mustache data/title1.mustache data/title5.mustache
src/Mdoc/Data/Command.hs view
@@ -4,13 +4,13 @@ import Mdoc.Prelude -import Mdoc.Data.Synopsis (Synopsis)+import Mdoc.Data.Synopsis (InlineSynopsis) import Mdoc.Syntax.Mdoc data Command = Command { index :: Int , name :: String- , synopsis :: Synopsis+ , synopsis :: InlineSynopsis , description :: Maybe Mdoc } deriving stock (Eq, Generic, Show)
src/Mdoc/Data/Page.hs view
@@ -83,10 +83,10 @@ (PositionalSwitch {}, Defaulted {}) -> described {optionality = Optional} _ -> described -addCommands :: [Command] -> Page -> Page-addCommands cs =+addCommands :: Optionality -> [Command] -> Page -> Page+addCommands o cs = appEndo- $ Endo (field @"synopsis" <?>~ Synopsis.command)+ $ Endo (field @"synopsis" <?>~ Synopsis.command o) <> foldMap addCommand cs where addCommand :: Command -> Endo Page
src/Mdoc/Data/Synopsis.hs view
@@ -11,6 +11,9 @@ , singleton , alternation , command++ -- * Rendering in-line+ , InlineSynopsis (..) ) where import Mdoc.Prelude@@ -33,12 +36,21 @@ deriving (ToJSON) via (Rendered Synopsis) instance Pretty Synopsis where- pretty = renderUsage . (.items)+ pretty = renderUsage Vertical . (.items) +newtype InlineSynopsis = InlineSynopsis+ { unwrap :: Synopsis+ }+ deriving stock (Eq, Show)+ deriving (ToJSON) via (Rendered InlineSynopsis)++instance Pretty InlineSynopsis where+ pretty = renderUsage Inline . (.unwrap.items)+ data SynopsisItem = Single (Described Positional) | Alternation Optionality [Described Positional]- | Command+ | Command Optionality deriving stock (Eq, Show) instance Ord SynopsisItem where@@ -56,8 +68,8 @@ alternation :: Optionality -> [Described Positional] -> Synopsis alternation o = Synopsis . pure . Alternation o -command :: Synopsis-command = Synopsis [Command]+command :: Optionality -> Synopsis+command o = Synopsis [Command o] data Usage ann = Usage { chars :: [Char]@@ -83,23 +95,28 @@ PositionalSwitch (Flag {}) -> field @"shorts" -- edge-case PositionalArgument {} -> field @"args" -renderUsage :: [SynopsisItem] -> Doc ann-renderUsage = go . buildUsage+data Alignment+ = Vertical+ | Inline++renderUsage :: Alignment -> [SynopsisItem] -> Doc ann+renderUsage a = go . buildUsage a where go u =- let ws =- nonEmpty- $ maybeToList (pChars <$> nonEmpty u.chars)- <> u.shorts- <> u.longs- <> u.args- <> u.command- in case ws of- Nothing -> mempty- Just ne -> vsep $ ".Bk -words" : toList ne <> [".Ek"]+ maybe mempty (vsep' . toList)+ $ nonEmpty+ $ maybeToList (pChars <$> nonEmpty u.chars)+ <> u.shorts+ <> u.longs+ <> u.args+ <> u.command - pChars cs = ".Op Fl" <+> pretty (fixMacro $ esc $ pack $ toList cs)+ pChars cs = op a Optional $ "Fl" <+> pretty (fixMacro $ esc $ pack $ toList cs) + vsep' = case a of+ Vertical -> vsep . map ("." <>) . (<> ["Ek"]) . (["Bk -words"] <>)+ Inline -> hsep+ -- | Fix for when short-switches accidentally become a macro name -- -- For example, @docker(1)@ has short switches @-D@ and @-v@, which become:@@ -116,17 +133,17 @@ | t `elem` macroNames = "\\&" <> t | otherwise = t -buildUsage :: [SynopsisItem] -> Usage ann-buildUsage = foldl addUsage mempty . sort+buildUsage :: Alignment -> [SynopsisItem] -> Usage ann+buildUsage a = foldl (addUsage a) mempty . sort -addUsage :: Usage ann -> SynopsisItem -> Usage ann-addUsage acc = \case+addUsage :: Alignment -> Usage ann -> SynopsisItem -> Usage ann+addUsage a acc = \case Single (Described {item = PositionalSwitch (Flag c _)}) -> acc & field @"chars" %~ sortOn toLower . (<> [c]) Single d -> acc & usageSetter d.item- <>~ [ opLine d+ <>~ [ op a d.optionality $ ellipsis d $ pretty $ Positional1 d.item@@ -135,20 +152,18 @@ Alternation o ds@(d : _) -> acc & usageSetter d.item- <>~ [ opLine' o+ <>~ [ op a o $ mconcat $ punctuate " | " $ map (pretty . Positional1 . (.item)) ds ]- Command -> acc & field @"command" <>~ [".Ar command"]--opLine :: Described a -> Doc ann -> Doc ann-opLine = opLine' . (.optionality)+ Command o -> acc & field @"command" <>~ [op a o "Ar command"] -opLine' :: Optionality -> Doc ann -> Doc ann-opLine' = \case- Required -> ("." <>)- _ -> (".Op" <+>)+op :: Alignment -> Optionality -> Doc ann -> Doc ann+op a o = case (a, o) of+ (_, Required) -> id+ (Vertical, _) -> ("Op" <+>)+ (Inline, _) -> (\x -> "Oo" <+> x <+> "Oc") ellipsis :: Described a -> Doc ann -> Doc ann ellipsis d
src/Mdoc/Examples/Pass.hs view
@@ -17,7 +17,9 @@ import Options.Applicative.Mdoc pass1 :: Named-pass1 = name "pass" "" $ getPage passOpt+pass1 =+ name "pass" "stores, retrieves, generates, and synchronizes passwords securely"+ $ getPage passOpt {- FOURMOLU_DISABLE -} passOpt :: Parser ()
src/Mdoc/Template.hs view
@@ -21,9 +21,9 @@ , displayMustacheWarning -- * Templates- , custom , man1 , man5+ , custom ) where import Mdoc.Prelude@@ -54,20 +54,42 @@ Nothing -> Rendered mdoc Just ne -> RenderedWarnings ne mdoc +-- | 'renderTemplate' and throw on 'RenderedError'+--+-- Warnings are written to @stderr@ but are not fatal. renderTemplateThrow :: MonadIO m => Template -> Named -> m Mdoc renderTemplateThrow t named = case renderTemplate t named of Rendered mdoc -> pure mdoc RenderedWarnings ne mdoc -> mdoc <$ putMustacheWarnings ne RenderedError err -> throwIO err -custom :: MonadIO m => FilePath -> m Template-custom p = (<> man1) <$> compileMustacheFile p-+-- | Built-in template for rendering a 'Named' in section 1+--+-- @SYNOPSIS@ and @DESCRIPTION@ for options/commands, and @ENVIRONMENT@. man1 :: Template man1 = $(TH.compileMustacheDir "man1" "data") +-- | Built-in template for rendering a 'Named' in section 5+--+-- No @SYNOPSIS@ and a @DESCRIPTION@ of configs. man5 :: Template man5 = $(TH.compileMustacheDir "man5" "data")++-- | Load a custom template and make our partials available+--+-- This makes it easier to define your template while re-using chunks of ours.+--+-- NB. Our top-level templates are also available; this allows a convenient way+-- to simply add an epilogue:+--+-- @+-- \." templates/custom.1.mustache+-- {{>man1}}+-- SEE ALSO+-- .Xr bash 1+-- @+custom :: MonadIO m => FilePath -> m Template+custom p = (<> man1) <$> compileMustacheFile p putMustacheWarnings :: MonadIO m => NonEmpty MustacheWarning -> m () putMustacheWarnings = liftIO . hPutStrLn stderr . displayMustacheWarnings
src/OptEnvConf/Mdoc.hs view
@@ -58,6 +58,7 @@ import Mdoc.Data.Option import Mdoc.Data.Optionality import Mdoc.Data.Page+import Mdoc.Data.Synopsis (InlineSynopsis (..)) import Mdoc.Optics import Mdoc.Syntax import OptEnvConf (CommandDoc (..), Parser, SetDoc (..))@@ -73,7 +74,8 @@ { index , name = commandDocArgument doc , description = textToMdocPp $ pack $ commandDocHelp doc- , synopsis = getSynopsis $ foldSetDocs addToPage $ commandDocs doc+ , synopsis =+ InlineSynopsis $ getSynopsis $ foldSetDocs addToPage $ commandDocs doc } addToPage@@ -136,8 +138,9 @@ -> AnyDocs (Maybe SetDoc) -> m Page foldSetDocsM f acc = \case- AnyDocsCommands _ cdocs ->- pure $ addCommands (zipWith getCommand [1 ..] cdocs) acc+ AnyDocsCommands mDef cdocs -> do+ let o = maybe Required Defaulted mDef+ pure $ addCommands o (zipWith getCommand [1 ..] cdocs) acc AnyDocsAnd ds -> foldM (foldSetDocsM f) acc ds AnyDocsOr [d] -> foldSetDocsM f acc d AnyDocsOr [d, AnyDocsSingle Nothing] -> foldSetDocsM fAsOrNothing acc d
src/Options/Applicative/Mdoc.hs view
@@ -26,6 +26,7 @@ import Mdoc.Data.Option import Mdoc.Data.Optionality import Mdoc.Data.Page+import Mdoc.Data.Synopsis (InlineSynopsis (..)) import Mdoc.Syntax (textToMdocPp) import Options.Applicative (Parser) import Options.Applicative.Common (treeMapParser)@@ -44,7 +45,7 @@ { index , name , description = textToMdocPp =<< docToText doc- , synopsis = getSynopsis $ getPage $ O.infoParser pinfo+ , synopsis = InlineSynopsis $ getSynopsis $ getPage $ O.infoParser pinfo } where doc =@@ -80,7 +81,7 @@ commands :: [Command] commands = zipWith (uncurry . getCommand) [1 ..] $ reverse cmds in- addCommands commands acc+ addCommands d.optionality commands acc where o = d.item metavar = guarded (not . null) $ O.optMetaVar o
templates/grep.1.mustache view
@@ -5,9 +5,7 @@ .Nm fgrep , .Nm rgrep .Nd file pattern searcher-.Sh SYNOPSIS-.Nm-{{{page.synopsis}}}+{{>synopsis}} .Sh DESCRIPTION {{#page.options}} {{>options}}
templates/pass.1.mustache view
@@ -1,18 +1,6 @@ {{>title1}}-.Sh NAME-.Nm pass-.Nd stores, retrieves, generates, and synchronizes passwords securely-.Sh SYNOPSIS-.Nm-{{{page.synopsis}}}-{{#page.commands.items}}-.Pp-.Nm-.Cm {{{name}}}-{{#synopsis}}-{{{.}}}-{{/synopsis}}-{{/page.commands.items}}+{{>name}}+{{>synopsis}} .Sh DESCRIPTION .Nm is a very simple password store that keeps passwords inside