pandoc_rb 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +45 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +24 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +48 -0
- data/LICENSE +30 -0
- data/LICENSE.txt +31 -0
- data/README.md +83 -0
- data/Rakefile +31 -0
- data/Setup.hs +2 -0
- data/bench/bench.rb +69 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/pandoc_rb/extconf.rb +130 -0
- data/ext/pandoc_rb/pandoc-rb.cabal +74 -0
- data/ext/pandoc_rb/pandoc_rb.c +100 -0
- data/ext/pandoc_rb/src/PandocRb.hs +26 -0
- data/ext/pandoc_rb/src/Text/Pandoc/C.hs +147 -0
- data/ext/pandoc_rb/src/Text/Pandoc/C/Types.hs +73 -0
- data/ext/pandoc_rb/src/Text/Pandoc/C/Utils.hs +78 -0
- data/ext/pandoc_rb/stack.yaml +70 -0
- data/ext/pandoc_rb/test/DetailedSpec.hs +173 -0
- data/lib/pandoc_rb.rb +96 -0
- data/lib/pandoc_rb/error.rb +6 -0
- data/lib/pandoc_rb/parse_failure.rb +11 -0
- data/lib/pandoc_rb/parsec_error.rb +13 -0
- data/lib/pandoc_rb/readers.rb +27 -0
- data/lib/pandoc_rb/version.rb +5 -0
- data/lib/pandoc_rb/writers.rb +46 -0
- data/pandoc_rb.gemspec +37 -0
- data/src/Text/Pandoc/C.hs +217 -0
- data/src/Text/Pandoc/C_stub.h +9 -0
- metadata +206 -0
data/pandoc_rb.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "pandoc_rb/version"
|
6
|
+
|
7
|
+
$gem_spec = Gem::Specification.new do |spec|
|
8
|
+
spec.name = "pandoc_rb"
|
9
|
+
spec.platform = Gem::Platform::RUBY
|
10
|
+
spec.version = PandocRb::VERSION
|
11
|
+
spec.authors = ["Michael Klein"]
|
12
|
+
spec.email = ['lambdamichael@gmail.com']
|
13
|
+
|
14
|
+
spec.summary = "FFI bindings to Pandoc"
|
15
|
+
spec.description = "Fast bindings to Pandoc through Ruby's C FFI gem and Haskell's C FFI"
|
16
|
+
spec.homepage = 'http://rubygems.org/gems/pandoc_rb'
|
17
|
+
spec.license = 'BSD-3-Clause'
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
20
|
+
f.match(%r{^(test|spec|features)/}) || f.match(/\.(so|o)$/)
|
21
|
+
end
|
22
|
+
spec.bindir = "bin"
|
23
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
spec.extensions = ['ext/pandoc_rb/extconf.rb']
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.15.1"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
30
|
+
spec.add_development_dependency "pry"
|
31
|
+
spec.add_development_dependency "pry-byebug"
|
32
|
+
spec.add_development_dependency "pandoc-ruby"
|
33
|
+
spec.add_development_dependency "rake-compiler"
|
34
|
+
spec.add_development_dependency "benchmark-ips"
|
35
|
+
spec.add_development_dependency "kalibera"
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,217 @@
|
|
1
|
+
{-# LANGUAGE BangPatterns #-}
|
2
|
+
{-# LANGUAGE DeriveGeneric #-}
|
3
|
+
{-# LANGUAGE FlexibleContexts #-}
|
4
|
+
{-# LANGUAGE ForeignFunctionInterface #-}
|
5
|
+
{-# LANGUAGE RankNTypes #-}
|
6
|
+
{-# LANGUAGE StandaloneDeriving #-}
|
7
|
+
{-# LANGUAGE TupleSections #-}
|
8
|
+
{-# LANGUAGE ScopedTypeVariables #-}
|
9
|
+
|
10
|
+
module Text.Pandoc.C where
|
11
|
+
|
12
|
+
import Control.Monad.Trans.Class (lift)
|
13
|
+
import Control.Monad.Trans.Either (EitherT(..))
|
14
|
+
import Data.Aeson (ToJSON(..), genericToEncoding, defaultOptions, genericToJSON, encode)
|
15
|
+
import Data.Bifunctor (bimap, second)
|
16
|
+
import Data.ByteString.Lazy (toStrict, fromStrict)
|
17
|
+
import Data.ByteString (useAsCStringLen)
|
18
|
+
import Data.ByteString.Unsafe (unsafePackMallocCStringLen, unsafeFinalize)
|
19
|
+
import Data.Monoid ((<>))
|
20
|
+
import Foreign.C.String (CStringLen, peekCStringLen, newCStringLen)
|
21
|
+
import Foreign.C.Types (CChar, CLong, CInt(..))
|
22
|
+
import Foreign.Marshal.Alloc (malloc)
|
23
|
+
import Foreign.Ptr (Ptr)
|
24
|
+
import Foreign.Storable (peek, poke)
|
25
|
+
import Foreign.Storable.Tuple ()
|
26
|
+
import GHC.Generics (Generic)
|
27
|
+
import Prelude hiding (log)
|
28
|
+
import Text.Pandoc (ReaderOptions, Pandoc, WriterOptions(..), PandocError(..), Reader(..), Writer(..), HTMLMathMethod(..), writerMediaBag, getReader, getWriter, def)
|
29
|
+
import Text.Pandoc.MediaBag (MediaBag, extractMediaBag)
|
30
|
+
import Text.Parsec.Error (ParseError, Message(..), errorPos, errorMessages)
|
31
|
+
import Text.Parsec.Pos (SourcePos, SourceName, Line, Column, sourceName, sourceLine, sourceColumn)
|
32
|
+
import System.Timeout (timeout)
|
33
|
+
import Control.Concurrent
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
-- | The `Reader` type modified for foreign C exports
|
39
|
+
type CReader = ReaderOptions -> CStringLen -> EitherT CStringLen IO (Pandoc, MediaBag)
|
40
|
+
|
41
|
+
-- | The `Writer` type modified for foreign C exports
|
42
|
+
type CWriter = WriterOptions -> Pandoc -> EitherT CStringLen IO CStringLen
|
43
|
+
|
44
|
+
|
45
|
+
-- | Apply a monadic action to the left of an `EitherT`
|
46
|
+
mapML :: Monad m => (a -> m b) -> EitherT a m c -> EitherT b m c
|
47
|
+
mapML f (EitherT m) = EitherT $ do
|
48
|
+
m' <- m
|
49
|
+
case m' of
|
50
|
+
( Left x) -> Left <$> f x
|
51
|
+
~(Right y) -> return $ Right y
|
52
|
+
|
53
|
+
-- | Apply a monadic action to the right of an `EitherT`
|
54
|
+
mapMR :: Monad m => (b -> m c) -> EitherT a m b -> EitherT a m c
|
55
|
+
mapMR f (EitherT m) = EitherT $ do
|
56
|
+
m' <- m
|
57
|
+
case m' of
|
58
|
+
( Left x) -> return $ Left x
|
59
|
+
~(Right y) -> Right <$> f y
|
60
|
+
|
61
|
+
|
62
|
+
-- | This function forks a thread to both catch exceptions and better kill infinite loops that can't be caught with `timeout` alone.
|
63
|
+
-- For example, @timeout 10 (forever $ return ())@ will never time out, but @timeoutEitherT 10 (lift $ forever $ return ())@ will.
|
64
|
+
--
|
65
|
+
-- timeoutEitherT is strict within the created thread
|
66
|
+
timeoutEitherT :: Int -> EitherT CStringLen IO b -> EitherT CStringLen IO b
|
67
|
+
timeoutEitherT us (EitherT io) = EitherT $ do
|
68
|
+
mvar <- newEmptyMVar
|
69
|
+
tid <- io `forkFinally` (putMVar mvar $!)
|
70
|
+
result <- timeout us (takeMVar mvar)
|
71
|
+
case result of
|
72
|
+
( Nothing ) -> killThread tid >> Left <$> newCStringLen ("Pandoc timed out after " ++ show us ++ "microseconds")
|
73
|
+
~(Just noTimeout) -> case noTimeout of
|
74
|
+
( Right successful) -> return successful
|
75
|
+
~(Left err ) -> Left <$> newCStringLen ("Pandoc internal error: " ++ show err)
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
-- | A clone of `SourcePos`, to allow deriving `Generic`
|
80
|
+
data SourcePos' = SourcePos' SourceName !Line !Column deriving (Eq, Ord, Show, Generic)
|
81
|
+
|
82
|
+
instance ToJSON SourcePos' where
|
83
|
+
toEncoding = genericToEncoding defaultOptions
|
84
|
+
|
85
|
+
deriving instance Generic Message
|
86
|
+
|
87
|
+
instance ToJSON Message where
|
88
|
+
toEncoding = genericToEncoding defaultOptions
|
89
|
+
|
90
|
+
-- | A clone of `ParseError`, to allow deriving `Generic`
|
91
|
+
data ParseError' = ParseError' !SourcePos' [Message] deriving (Generic)
|
92
|
+
|
93
|
+
-- | Convert to our clone of `SourcePos`
|
94
|
+
sourcePos' :: SourcePos -> SourcePos'
|
95
|
+
sourcePos' !sp = SourcePos' (sourceName sp) (sourceLine sp) (sourceColumn sp)
|
96
|
+
|
97
|
+
-- | Convert to our clone of `ParseError`
|
98
|
+
parseError' :: ParseError -> ParseError'
|
99
|
+
parseError' !pe = ParseError' (sourcePos' (errorPos pe)) (errorMessages pe)
|
100
|
+
|
101
|
+
|
102
|
+
instance ToJSON ParseError where
|
103
|
+
toJSON = genericToJSON defaultOptions . parseError'
|
104
|
+
toEncoding = genericToEncoding defaultOptions . parseError'
|
105
|
+
|
106
|
+
instance ToJSON PandocError where
|
107
|
+
toEncoding = genericToEncoding defaultOptions
|
108
|
+
|
109
|
+
-- | Convert a `PandocError` to JSON
|
110
|
+
showPandocError :: PandocError -> IO CStringLen
|
111
|
+
showPandocError = flip useAsCStringLen return . toStrict . encode
|
112
|
+
|
113
|
+
|
114
|
+
-- | Convert a `Reader` to a `CReader`
|
115
|
+
mkCReader :: Reader -> CReader
|
116
|
+
mkCReader (StringReader reader) opts cstr = mapML showPandocError . EitherT $ do
|
117
|
+
str <- peekCStringLen cstr
|
118
|
+
readerResult <- reader opts str
|
119
|
+
return $ second (, mempty) $! readerResult
|
120
|
+
mkCReader ~(ByteStringReader reader) opts str = mapML showPandocError . EitherT $ do
|
121
|
+
bs <- unsafePackMallocCStringLen str
|
122
|
+
readerResult <- reader opts $! fromStrict bs
|
123
|
+
readerResult `seq` unsafeFinalize bs
|
124
|
+
return readerResult
|
125
|
+
|
126
|
+
|
127
|
+
-- | Convert a `Writer` to a `CWriter`
|
128
|
+
mkCWriter :: Writer -> CWriter
|
129
|
+
mkCWriter (PureStringWriter writer) opts pandoc = lift $ newCStringLen $ writer opts pandoc
|
130
|
+
mkCWriter (IOStringWriter writer) opts pandoc = lift $ writer opts pandoc >>= newCStringLen
|
131
|
+
mkCWriter ~(IOByteStringWriter writer) opts pandoc = lift $ writer opts pandoc >>= flip useAsCStringLen return . toStrict
|
132
|
+
|
133
|
+
-- | `getReader` for foreign C exports. Retrieve reader based on formatSpec (format+extensions).
|
134
|
+
getCReader :: CStringLen -> EitherT CStringLen IO CReader
|
135
|
+
getCReader cstr = do
|
136
|
+
str <- lift . peekCStringLen $ cstr
|
137
|
+
EitherT $ case getReader str of
|
138
|
+
( Left err ) -> Left <$> newCStringLen err
|
139
|
+
~(Right reader) -> return . Right $ mkCReader reader
|
140
|
+
|
141
|
+
-- | `getWriter` for foreign C exports. Retrieve writer based on formatSpec (format+extensions).
|
142
|
+
getCWriter :: CStringLen -> EitherT CStringLen IO CWriter
|
143
|
+
getCWriter cstr = do
|
144
|
+
str <- lift . peekCStringLen $ cstr
|
145
|
+
EitherT $ case getWriter str of
|
146
|
+
( Left err ) -> Left <$> newCStringLen err
|
147
|
+
~(Right writer) -> return . Right $ mkCWriter writer
|
148
|
+
|
149
|
+
extractCMediabag :: Bool -> CStringLen -> MediaBag -> EitherT CStringLen IO ()
|
150
|
+
extractCMediabag verbose cPath mediaBag = do
|
151
|
+
path <- lift . peekCStringLen $ cPath
|
152
|
+
case path of
|
153
|
+
[] -> return ()
|
154
|
+
nonEmptyPath -> lift $ extractMediaBag verbose nonEmptyPath mediaBag
|
155
|
+
|
156
|
+
-- | The main conversion function.
|
157
|
+
-- Takes `ReaderOptions`, `WriterOptions`, reader's formatSpec,
|
158
|
+
-- writer's formatSpec, input and returns either an error string
|
159
|
+
-- or the output
|
160
|
+
convert :: ReaderOptions
|
161
|
+
-> WriterOptions
|
162
|
+
-> CStringLen -- ^ Reader specification
|
163
|
+
-> CStringLen -- ^ Writer specification
|
164
|
+
-> CStringLen -- ^ Input
|
165
|
+
-> CStringLen -- ^ Extract media dir
|
166
|
+
-> EitherT CStringLen IO CStringLen -- ^ Either an error string or the output
|
167
|
+
convert readerOpts writerOpts readerStr writerStr input mediaBagStr = do
|
168
|
+
reader <- getCReader readerStr
|
169
|
+
(pandoc, mediaBag) <- reader readerOpts input
|
170
|
+
extractCMediabag False mediaBagStr mediaBag
|
171
|
+
writer <- getCWriter writerStr
|
172
|
+
let writerOpts' = writerOpts { writerMediaBag = writerMediaBag writerOpts <> mediaBag }
|
173
|
+
writer writerOpts' pandoc
|
174
|
+
|
175
|
+
-- | The `ReaderOptions` wired into the foreign export
|
176
|
+
readerOptions :: ReaderOptions
|
177
|
+
readerOptions = def
|
178
|
+
|
179
|
+
-- | The `WriterOptions` wired into the foreign export
|
180
|
+
writerOptions :: WriterOptions
|
181
|
+
writerOptions = def { writerHTMLMathMethod = MathJax "https://fail.cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML" }
|
182
|
+
|
183
|
+
-- | `CStringLen` for use by Ruby
|
184
|
+
type RStringLen = (Ptr CChar, CLong)
|
185
|
+
|
186
|
+
-- -- | Free the resulting type of `convert_hs`
|
187
|
+
-- freeResult :: Ptr () -> IO ()
|
188
|
+
-- freeResult !addr = do
|
189
|
+
-- (_, strAddr, _) <- peek (castPtr addr :: Ptr (CInt, Ptr CChar, CLong))
|
190
|
+
-- free strAddr
|
191
|
+
-- free addr
|
192
|
+
|
193
|
+
-- foreign export ccall freeResult :: Ptr () -> IO ()
|
194
|
+
|
195
|
+
-- | Takes: reader, writer, input and returns (isSuccess, output pointer, output length)
|
196
|
+
convert_hs :: Ptr RStringLen -> Ptr RStringLen -> Ptr RStringLen -> Ptr RStringLen -> IO (Ptr (CInt, Ptr CChar, CLong))
|
197
|
+
convert_hs readerStr writerStr input mediaBagStr = do
|
198
|
+
readerStr' <- second fromEnum <$> peek readerStr
|
199
|
+
writerStr' <- second fromEnum <$> peek writerStr
|
200
|
+
input' <- second fromEnum <$> peek input
|
201
|
+
mediaBagStr' <- second fromEnum <$> peek mediaBagStr
|
202
|
+
let converted = convert readerOptions writerOptions readerStr' writerStr' input' mediaBagStr'
|
203
|
+
let EitherT safeConverted = timeoutEitherT (10 * {- minutes -} 60000000) converted
|
204
|
+
result <- bimap (second toEnum) (second toEnum) <$> safeConverted
|
205
|
+
let (success, (rstrPtr, rstrLen)) = either (0,) (1,) result
|
206
|
+
addr <- malloc
|
207
|
+
addr `poke` (success, rstrPtr, rstrLen)
|
208
|
+
return addr
|
209
|
+
|
210
|
+
foreign export ccall convert_hs :: Ptr RStringLen -> Ptr RStringLen -> Ptr RStringLen -> Ptr RStringLen -> IO (Ptr (CInt, Ptr CChar, CLong))
|
211
|
+
|
212
|
+
-- -- | Dummy main to dissuade the compiler from warning a lack of @_main@
|
213
|
+
-- main :: IO CInt
|
214
|
+
-- main = print "hi there! I'm main. you probably shouldn't see me." >> return 0
|
215
|
+
|
216
|
+
-- foreign export ccall main :: IO CInt
|
217
|
+
|
metadata
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pandoc_rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Klein
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-02-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.15.1
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.15.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry-byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pandoc-ruby
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake-compiler
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: benchmark-ips
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: kalibera
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: Fast bindings to Pandoc through Ruby's C FFI gem and Haskell's C FFI
|
140
|
+
email:
|
141
|
+
- lambdamichael@gmail.com
|
142
|
+
executables:
|
143
|
+
- console
|
144
|
+
- setup
|
145
|
+
extensions:
|
146
|
+
- ext/pandoc_rb/extconf.rb
|
147
|
+
extra_rdoc_files: []
|
148
|
+
files:
|
149
|
+
- ".gitignore"
|
150
|
+
- ".ruby-gemset"
|
151
|
+
- ".ruby-version"
|
152
|
+
- ".travis.yml"
|
153
|
+
- Gemfile
|
154
|
+
- Gemfile.lock
|
155
|
+
- LICENSE
|
156
|
+
- LICENSE.txt
|
157
|
+
- README.md
|
158
|
+
- Rakefile
|
159
|
+
- Setup.hs
|
160
|
+
- bench/bench.rb
|
161
|
+
- bin/console
|
162
|
+
- bin/setup
|
163
|
+
- ext/pandoc_rb/extconf.rb
|
164
|
+
- ext/pandoc_rb/pandoc-rb.cabal
|
165
|
+
- ext/pandoc_rb/pandoc_rb.c
|
166
|
+
- ext/pandoc_rb/src/PandocRb.hs
|
167
|
+
- ext/pandoc_rb/src/Text/Pandoc/C.hs
|
168
|
+
- ext/pandoc_rb/src/Text/Pandoc/C/Types.hs
|
169
|
+
- ext/pandoc_rb/src/Text/Pandoc/C/Utils.hs
|
170
|
+
- ext/pandoc_rb/stack.yaml
|
171
|
+
- ext/pandoc_rb/test/DetailedSpec.hs
|
172
|
+
- lib/pandoc_rb.rb
|
173
|
+
- lib/pandoc_rb/error.rb
|
174
|
+
- lib/pandoc_rb/parse_failure.rb
|
175
|
+
- lib/pandoc_rb/parsec_error.rb
|
176
|
+
- lib/pandoc_rb/readers.rb
|
177
|
+
- lib/pandoc_rb/version.rb
|
178
|
+
- lib/pandoc_rb/writers.rb
|
179
|
+
- pandoc_rb.gemspec
|
180
|
+
- src/Text/Pandoc/C.hs
|
181
|
+
- src/Text/Pandoc/C_stub.h
|
182
|
+
homepage: http://rubygems.org/gems/pandoc_rb
|
183
|
+
licenses:
|
184
|
+
- BSD-3-Clause
|
185
|
+
metadata: {}
|
186
|
+
post_install_message:
|
187
|
+
rdoc_options: []
|
188
|
+
require_paths:
|
189
|
+
- lib
|
190
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
|
+
requirements:
|
197
|
+
- - ">="
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
version: '0'
|
200
|
+
requirements: []
|
201
|
+
rubyforge_project:
|
202
|
+
rubygems_version: 2.6.12
|
203
|
+
signing_key:
|
204
|
+
specification_version: 4
|
205
|
+
summary: FFI bindings to Pandoc
|
206
|
+
test_files: []
|