github.com/xhghs/rclone@v1.51.1-0.20200430155106-e186a28cced8/bin/make_manual.py (about)

     1  #!/usr/bin/env python3
     2  """
     3  Make single page versions of the documentation for release and
     4  conversion into man pages etc.
     5  """
     6  
     7  import os
     8  import re
     9  from datetime import datetime
    10  
    11  docpath = "docs/content"
    12  outfile = "MANUAL.md"
    13  
    14  # Order to add docs segments to make outfile
    15  docs = [
    16      "about.md",
    17      "install.md",
    18      "docs.md",
    19      "remote_setup.md",
    20      "filtering.md",
    21      "gui.md",
    22      "rc.md",
    23      "overview.md",
    24      "flags.md",
    25  
    26      # Keep these alphabetical by full name
    27      "fichier.md",
    28      "alias.md",
    29      "amazonclouddrive.md",
    30      "s3.md",
    31      "b2.md",
    32      "box.md",
    33      "cache.md",
    34      "chunker.md",
    35      "sharefile.md",
    36      "crypt.md",
    37      "dropbox.md",
    38      "ftp.md",
    39      "googlecloudstorage.md",
    40      "drive.md",
    41      "googlephotos.md",
    42      "http.md",
    43      "hubic.md",
    44      "jottacloud.md",
    45      "koofr.md",
    46      "mailru.md",
    47      "mega.md",
    48      "memory.md",
    49      "azureblob.md",
    50      "onedrive.md",
    51      "opendrive.md",
    52      "qingstor.md",
    53      "swift.md",
    54      "pcloud.md",
    55      "premiumizeme.md",
    56      "putio.md",
    57      "sftp.md",
    58      "sugarsync.md",
    59      "union.md",
    60      "webdav.md",
    61      "yandex.md",
    62  
    63      "local.md",
    64      "changelog.md",
    65      "bugs.md",
    66      "faq.md",
    67      "licence.md",
    68      "authors.md",
    69      "contact.md",
    70  ]
    71  
    72  # Order to put the commands in - any not on here will be in sorted order
    73  commands_order = [
    74      "rclone_config.md",
    75      "rclone_copy.md",
    76      "rclone_sync.md",
    77      "rclone_move.md",
    78      "rclone_delete.md",
    79      "rclone_purge.md",
    80      "rclone_mkdir.md",
    81      "rclone_rmdir.md",
    82      "rclone_check.md",
    83      "rclone_ls.md",
    84      "rclone_lsd.md",
    85      "rclone_lsl.md",
    86      "rclone_md5sum.md",
    87      "rclone_sha1sum.md",
    88      "rclone_size.md",
    89      "rclone_version.md",
    90      "rclone_cleanup.md",
    91      "rclone_dedupe.md",
    92  ]    
    93  
    94  # Docs which aren't made into outfile
    95  ignore_docs = [
    96      "downloads.md",
    97      "privacy.md",
    98      "donate.md",
    99  ]
   100  
   101  def read_doc(doc):
   102      """Read file as a string"""
   103      path = os.path.join(docpath, doc)
   104      with open(path) as fd:
   105          contents = fd.read()
   106      parts = contents.split("---\n", 2)
   107      if len(parts) != 3:
   108          raise ValueError("Couldn't find --- markers: found %d parts" % len(parts))
   109      contents = parts[2].strip()+"\n\n"
   110      # Remove icons
   111      contents = re.sub(r'<i class="fa.*?</i>\s*', "", contents)
   112      # Make [...](/links/) absolute
   113      contents = re.sub(r'\((\/.*?\/)\)', r"(https://rclone.org\1)", contents)
   114      # Interpret provider shortcode
   115      # {{< provider name="Amazon S3" home="https://aws.amazon.com/s3/" config="/s3/" >}}
   116      contents = re.sub(r'\{\{<\s+provider.*?name="(.*?)".*?>\}\}', r"\1", contents)
   117      return contents
   118  
   119  def check_docs(docpath):
   120      """Check all the docs are in docpath"""
   121      files = set(f for f in os.listdir(docpath) if f.endswith(".md"))
   122      files -= set(ignore_docs)
   123      docs_set = set(docs)
   124      if files == docs_set:
   125          return
   126      print("Files on disk but not in docs variable: %s" % ", ".join(files - docs_set))
   127      print("Files in docs variable but not on disk: %s" % ", ".join(docs_set - files))
   128      raise ValueError("Missing files")
   129  
   130  def read_command(command):
   131      doc = read_doc("commands/"+command)
   132      doc = re.sub(r"### Options inherited from parent commands.*$", "", doc, 0, re.S)
   133      doc = doc.strip()+"\n"
   134      return doc
   135  
   136  def read_commands(docpath):
   137      """Reads the commands an makes them into a single page"""
   138      files = set(f for f in os.listdir(docpath + "/commands") if f.endswith(".md"))
   139      docs = []
   140      for command in commands_order:
   141          docs.append(read_command(command))
   142          files.remove(command)
   143      for command in sorted(files):
   144          if command != "rclone.md":
   145              docs.append(read_command(command))
   146      return "\n".join(docs)
   147      
   148  def main():
   149      check_docs(docpath)
   150      command_docs = read_commands(docpath).replace("\\", "\\\\") # escape \ so we can use command_docs in re.sub
   151      with open(outfile, "w") as out:
   152          out.write("""\
   153  %% rclone(1) User Manual
   154  %% Nick Craig-Wood
   155  %% %s
   156  
   157  """ % datetime.now().strftime("%b %d, %Y"))
   158          for doc in docs:
   159              contents = read_doc(doc)
   160              # Substitute the commands into doc.md
   161              if doc == "docs.md":
   162                  contents = re.sub(r"The main rclone commands.*?for the full list.", command_docs, contents, 0, re.S)
   163              out.write(contents)
   164      print("Written '%s'" % outfile)
   165  
   166  if __name__ == "__main__":
   167      main()