diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,3 +4,20 @@
 
 * Initial release.
 
+## 0.1.0.1
+
+  * Fix sorting when no `<sorting>` element given. The spec says:
+    "In the absence of cs:sort, cites and bibliographic entries appear in
+    the order in which they are cited." This affects IEEE in particular.  See
+    jgm/pandoc#6741.
+
+  * Improve `sameNames` and citation grouping.  Preivously if a citation
+    item had a prefix, it would not be grouped with following citations.
+    See jgm/pandoc#6722 for discussion.
+
+  * Remove unneeded `hasNoSuffix` check in `sameNames`.
+
+  * Remove unneeded import
+
+  * `citeproc` executable: strip BOM before parsing style (#18).
+
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,12 +3,7 @@
 [![BSD2 license](https://img.shields.io/badge/license-BSD2-blue.svg)](LICENSE)
 [![CI
 tests](https://github.com/jgm/citeproc/workflows/CI%20tests/badge.svg)](https://github.com/jgm/citeproc/actions)
-
-<!--
 [![Hackage](https://img.shields.io/hackage/v/citeproc.svg)](https://hackage.haskell.org/package/citeproc)
-[![Stackage Lts](http://stackage.org/package/citeproc/badge/lts)](http://stackage.org/lts/package/citeproc)
-[![Stackage Nightly](http://stackage.org/package/citeproc/badge/nightly)](http://stackage.org/nightly/package/citeproc)
--->
 
 This library generates citations and bibliography formatted
 according to a [CSL] style.  Currently version 1.0.2 of the CSL
@@ -94,7 +89,7 @@
 
 Although this library is much more accurate in implementing the
 CSL spec than pandoc-citeproc was, it still fails some of the
-tests from the CSL test suite (59/845).  However, most of the
+tests from the CSL test suite (58/845).  However, most of the
 failures are on minor corner cases, and in many cases the
 expected behavior goes beyond what is required by the CSL spec.
 
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -45,7 +45,8 @@
     Left e -> err e
     Right (inp :: Inputs (CslJson Text)) -> do
       stylesheet <- case optStyle opt of
-                      Just fp -> TIO.readFile fp
+                      Just fp -> T.dropWhile (=='\xFEFF') <$> -- drop BOM
+                                       TIO.readFile fp
                       Nothing ->
                         case inputsStyle inp of
                           Just s  -> return s
diff --git a/citeproc.cabal b/citeproc.cabal
--- a/citeproc.cabal
+++ b/citeproc.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.2
 name:                citeproc
-version:             0.1
+version:             0.1.0.1
 synopsis:            Generates citations and bibliography from CSL styles.
 description:         citeproc parses CSL style files and uses them to
                      generate a list of formatted citations and bibliography
@@ -20,6 +20,7 @@
                      locales/*.xml
                      locales/locales.json
                      man/citeproc.1.md
+                     man/citeproc.1
                      test/NOTES.md
                      test/csl/*.txt
                      test/extra/*.txt
diff --git a/man/citeproc.1 b/man/citeproc.1
new file mode 100644
--- /dev/null
+++ b/man/citeproc.1
@@ -0,0 +1,199 @@
+.\" Automatically generated by Pandoc 2.11
+.\"
+.TH "citeproc" "1" "" "citeproc 0.1.0.1" ""
+.hy
+.SH NAME
+.PP
+citeproc - process citations using a CSL stylesheet.
+.SH SYNOPSIS
+.PP
+\f[C]citeproc [options] [file]\f[R]
+.SH DESCRIPTION
+.PP
+\f[C]citeproc\f[R] reads a JSON-encoded \f[C]Inputs\f[R] object from
+\f[C]stdin\f[R] (or from a file if a filename is provided) and writes a
+JSON-encoded \f[C]Result\f[R] object to \f[C]stdout\f[R].
+This executable can be used to add citation processing to non-Haskell
+projects.
+.SH OPTIONS
+.TP
+\f[B]\f[CB]-s\f[B]\f[R] \f[I]FILE\f[R], \f[B]\f[CB]--style=\f[B]\f[R]\f[I]FILE\f[R]
+Specify a CSL style to be used.
+.TP
+\f[B]\f[CB]-r\f[B]\f[R] \f[I]FILE\f[R], \f[B]\f[CB]--references=\f[B]\f[R]\f[I]FILE\f[R]
+Specify a CSL JSON bibliography to be used as a source for references.
+.TP
+\f[B]\f[CB]a\f[B]\f[R] \f[I]FILE\f[R], \f[B]\f[CB]--abbreviations=\f[B]\f[R]\f[I]FILE\f[R]
+Specify a CSL abbreviations file.
+.TP
+\f[B]\f[CB]l\f[B]\f[R] \f[I]LANG\f[R], \f[B]\f[CB]--lang=\f[B]\f[R]\f[I]LANG\f[R]
+Specify a locale to override the style\[cq]s default (IETF language
+code).
+.TP
+\f[B]\f[CB]f\f[B]\f[R] \f[I]html|json\f[R], \f[B]\f[CB]--format=\f[B]\f[R]\f[I]html|json\f[R]
+Specify the format to be used for the entries.
+\f[C]html\f[R] (the default) uses HTML tags and entities for formatting.
+\f[C]json\f[R] creates a structured JSON representation of a formatted
+document.
+.TP
+\f[B]\f[CB]-h, --help\f[B]\f[R]
+Print usage information.
+.TP
+\f[B]\f[CB]-V, --version\f[B]\f[R]
+Print version.
+.SH NOTES
+.PP
+The input JSON should have the structure:
+.IP
+.nf
+\f[C]
+{ \[dq]citations\[dq]:     [ ...list of citations... ],
+  \[dq]references\[dq]:    [ ...list of references... ],
+  \[dq]style\[dq]:         \[dq]<style>...</style>\[dq],
+  \[dq]abbreviations\[dq]: { ...abbreviations... },
+  \[dq]lang\[dq]:          \[dq]fr-FR\[dq] }
+\f[R]
+.fi
+.PP
+None of these fields is mandatory.
+Instead of providing \f[C]references\f[R] in the input JSON, one can
+specify a file containing a CSL JSON bibliography, using the
+\f[C]--references\f[R] option on the command line.
+Instead of providing a CSL stylesheet in the JSON, one can specify a
+file using the \f[C]--style\f[R] option.
+\f[C]--abbreviations\f[R] and \f[C]--lang\f[R] may also be used on the
+command line to specify an abbreviations file or a locale.
+(Command-line options always override any values given in the JSON
+file.)
+.PP
+A citation is structured like this:
+.IP
+.nf
+\f[C]
+{ \[dq]citationID\[dq]: \[dq]foo\[dq],
+  \[dq]citationItems\[dq]: [ ...list of citationItems... ],
+  \[dq]citationNoteNumber\[dq]: 3 }
+\f[R]
+.fi
+.PP
+Only \f[C]citationItems\f[R] is necessary.
+Alternatively, instead of
+.IP
+.nf
+\f[C]
+{ \[dq]citationItems\[dq]: [ ... ] }
+\f[R]
+.fi
+.PP
+one can just specify an array of items directly:
+.IP
+.nf
+\f[C]
+[ ... ]
+\f[R]
+.fi
+.PP
+A citation item is structured like this:
+.IP
+.nf
+\f[C]
+{ \[dq]id\[dq]:       \[dq]foo\[dq],
+  \[dq]type\[dq]:     \[dq]suppress-author\[dq],
+  \[dq]label\[dq]:    \[dq]page\[dq],
+  \[dq]locator\[dq]:  \[dq]45\[dq],
+  \[dq]prefix\[dq]:   \[dq]see \[dq],
+  \[dq]suffix\[dq]:   \[dq] and others\[dq] }
+\f[R]
+.fi
+.PP
+Only \f[C]id\f[R] is mandatory.
+If \f[C]type\f[R] is omitted, it will be assumed to be
+\f[C]normal-cite\f[R] (other values are \f[C]suppress-author\f[R] and
+\f[C]author-only\f[R]).
+.PP
+A reference is structured like this:
+.IP
+.nf
+\f[C]
+{
+  \[dq]author\[dq]: [
+    {
+      \[dq]family\[dq]: \[dq]Aristotle\[dq]
+    }
+  ],
+  \[dq]id\[dq]: \[dq]aristotle:prior\[dq],
+  \[dq]issued\[dq]: {
+    \[dq]date-parts\[dq]: [
+      [
+        1989
+      ]
+    ]
+  },
+  \[dq]publisher\[dq]: \[dq]Hackett\[dq],
+  \[dq]publisher-place\[dq]: \[dq]Indianapolis\[dq],
+  \[dq]title\[dq]: \[dq]Prior analytics\[dq],
+  \[dq]translator\[dq]: [
+    {
+      \[dq]family\[dq]: \[dq]Smith\[dq],
+      \[dq]given\[dq]: \[dq]Robin\[dq]
+    }
+  ],
+  \[dq]type\[dq]: \[dq]book\[dq]
+}
+\f[R]
+.fi
+.PP
+An abbreviations object has this form:
+.IP
+.nf
+\f[C]
+{ \[dq]default\[dq]: {
+    \[dq]container-title\[dq]: {
+            \[dq]Lloyd\[aq]s Law Reports\[dq]: \[dq]Lloyd\[aq]s Rep\[dq],
+            \[dq]Estates Gazette\[dq]: \[dq]EG\[dq],
+            \[dq]Scots Law Times\[dq]: \[dq]SLT\[dq]
+    }
+  }
+}
+\f[R]
+.fi
+.PP
+The abbreviations will be substituted in the output only when the
+\f[C]form\f[R] attribute for the style element that renders the variable
+is set to \f[C]short\f[R].
+.PP
+The output JSON will have the structure:
+.IP
+.nf
+\f[C]
+{ \[dq]citations\[dq]:    [ ...list of strings... ],
+  \[dq]bibliography\[dq]: [ ...list of arrays: item id and a string... ],
+  \[dq]warnings\[dq]:     [ ...list of warnings... ]
+}
+\f[R]
+.fi
+.PP
+The contents of the entries will be HTML by default, but if
+\f[C]--format=json\f[R] is specified, it will be a structured
+representation of formatted text.
+.IP
+.nf
+\f[C]
+[
+  \[dq]\[em]\[em]\[em]. 1983b. \[lq]The Concept of Truth in Formalized Languages.\[rq] In \[dq],
+  {
+    \[dq]format\[dq]: \[dq]italics\[dq],
+    \[dq]contents\[dq]: [
+      \[dq]Logic, Semantics, Metamathematics\[dq]
+    ]
+  },
+  \[dq], edited by John Corcoran, 152\[en]278. Indianapolis: Hackett.\[dq]
+]
+\f[R]
+.fi
+.PP
+This representation can be used if you want to convert the result to a
+format other than HTML.
+.SH AUTHORS
+.PP
+John MacFarlane
diff --git a/src/Citeproc.hs b/src/Citeproc.hs
--- a/src/Citeproc.hs
+++ b/src/Citeproc.hs
@@ -10,7 +10,6 @@
        , citeproc
        , Result(..)
        ) where
-import Data.Text (Text)
 import Data.Semigroup
 import qualified Data.Text as T
 import qualified Data.Set as Set
diff --git a/src/Citeproc/Eval.hs b/src/Citeproc/Eval.hs
--- a/src/Citeproc/Eval.hs
+++ b/src/Citeproc/Eval.hs
@@ -28,7 +28,7 @@
 import Control.Applicative
 import Data.Generics.Uniplate.Operations (universe, transform)
 
--- import Debug.Trace (trace)
+-- import Debug.Trace (traceShowId)
 -- import Text.Show.Pretty (ppShow)
 -- ppTrace :: Show a => a -> a
 -- ppTrace x = trace (ppShow x) x
@@ -127,7 +127,14 @@
   addIfMissing _ (Just x) = Just x
 
   go = do
-      assignCitationNumbers (map referenceId refs)
+      -- list of citationItemIds that are actually cited
+      let citationOrder = M.fromList $ reverse $ zip
+            (concatMap (map citationItemId . citationItems) citations)
+            [(1 :: Int)..]
+      let citeIds = M.keysSet citationOrder
+      let sortedCiteIds = sortOn (`M.lookup` citationOrder)
+                                  (map referenceId refs)
+      assignCitationNumbers sortedCiteIds
       -- sorting of bibliography, insertion of citation-number
       (bibCitations, bibSortKeyMap) <-
         case styleBibliography style of
@@ -141,9 +148,9 @@
                           refs
             let sortedIds =
                   if null (layoutSortKeys biblayout)
-                     then map referenceId refs
+                     then sortedCiteIds
                      else sortOn (`M.lookup` bibSortKeyMap)
-                              (map referenceId refs)
+                            (map referenceId refs)
             assignCitationNumbers $
               case layoutSortKeys biblayout of
                 (SortKeyVariable Descending "citation-number":_)
@@ -160,9 +167,6 @@
                    [CitationItem ident Nothing Nothing
                       NormalCite Nothing Nothing]) sortedIds
             return (bibCitations, bibSortKeyMap)
-      -- list of citationItemIds that are actually cited
-      let citeIds = foldr (Set.insert . citationItemId) mempty
-                            (concatMap citationItems citations)
       -- styling of citations
       sortKeyMap <-
         foldM (\m citeId -> do
@@ -777,29 +781,27 @@
      (Tagged (TagItem _ _) (Tagged (TagCitationNumber n2) _xs2))
     = n2 == n1 + 1
   isAdjacentCitationNumber _ _ = False
-  sameNames (Tagged (TagItem ty1 _id1) x1)
-            (Tagged (TagItem ty2 _id2) x2)
-    | hasNoSuffix x1
-    , hasNoSuffix x2
-    , ty1 /= AuthorOnly
-    , ty2 /= AuthorOnly
-    = case (unFormat x1, unFormat x2) of
-      (Tagged (TagNames t1 _nf1 ns1) ws1,
-       Tagged (TagNames t2 _nf2 ns2) ws2)
-       -> t1 == t2 && (if ns1 == ns2
-                          then not (null ns1) || ws1 == ws2
-                          else ws1 == ws2)
-          -- case where it's just a date with no name or anything;
-          -- we treat this as same name e.g. (1955a,b)
-      (Tagged TagDate{} _, Tagged TagDate{} _)
+  sameNames x y =
+    case (extractTags x, extractTags y) of
+      (Just (Tagged (TagNames t1 _nf1 ns1) ws1),
+       Just (Tagged (TagNames t2 _nf2 ns2) ws2))
+        -> t1 == t2 && (if ns1 == ns2
+                           then not (null ns1) || ws1 == ws2
+                           else ws1 == ws2)
+      -- case where it's just a date with no name or anything;
+      -- we treat this as same name e.g. (1955a,b)
+      (Just (Tagged TagDate{} _), Just (Tagged TagDate{} _))
         -> True
           -- case where title is substituted
       _ -> False
-  sameNames _ _ = False
-  hasNoSuffix (Formatted f' _) = isNothing (formatSuffix f')
-  hasNoSuffix _ = True
-  unFormat (Formatted _ (z:_)) = unFormat z
-  unFormat x = x
+  extractTags x =
+    let items = [y | y@(Tagged (TagItem ty _) _) <- universe x
+                   , ty /= AuthorOnly]
+        names = [y | y@(Tagged TagNames{} _) <- concatMap universe items]
+        dates = [y | y@(Tagged TagDate{} _) <- concatMap universe items]
+    in  if null items
+           then Nothing
+           else listToMaybe names <|> listToMaybe dates
 groupAndCollapseCitations _ _ _ _ x = x
 
 takeSeq :: Show a => (a -> a -> Bool) -> [a] -> ([a], [a])
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -319,7 +319,7 @@
                (length (skipped counts))
   case length (failed counts) + length (errored counts) of
     0 -> exitWith ExitSuccess
-    n | n <= 59 -> do
+    n | n <= 58 -> do
          putStrLn "We have passed all the CSL tests we expect to..."
          exitWith ExitSuccess
       | otherwise -> exitWith $ ExitFailure n
