github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/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      "_index.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      "seafile.md",
    58      "sftp.md",
    59      "sugarsync.md",
    60      "tardigrade.md",
    61      "union.md",
    62      "webdav.md",
    63      "yandex.md",
    64  
    65      "local.md",
    66      "changelog.md",
    67      "bugs.md",
    68      "faq.md",
    69      "licence.md",
    70      "authors.md",
    71      "contact.md",
    72  ]
    73  
    74  # Order to put the commands in - any not on here will be in sorted order
    75  commands_order = [
    76      "rclone_config.md",
    77      "rclone_copy.md",
    78      "rclone_sync.md",
    79      "rclone_move.md",
    80      "rclone_delete.md",
    81      "rclone_purge.md",
    82      "rclone_mkdir.md",
    83      "rclone_rmdir.md",
    84      "rclone_check.md",
    85      "rclone_ls.md",
    86      "rclone_lsd.md",
    87      "rclone_lsl.md",
    88      "rclone_md5sum.md",
    89      "rclone_sha1sum.md",
    90      "rclone_size.md",
    91      "rclone_version.md",
    92      "rclone_cleanup.md",
    93      "rclone_dedupe.md",
    94  ]    
    95  
    96  # Docs which aren't made into outfile
    97  ignore_docs = [
    98      "downloads.md",
    99      "privacy.md",
   100      "donate.md",
   101  ]
   102  
   103  def read_doc(doc):
   104      """Read file as a string"""
   105      path = os.path.join(docpath, doc)
   106      with open(path) as fd:
   107          contents = fd.read()
   108      parts = contents.split("---\n", 2)
   109      if len(parts) != 3:
   110          raise ValueError("Couldn't find --- markers: found %d parts" % len(parts))
   111      contents = parts[2].strip()+"\n\n"
   112      # Remove icons
   113      contents = re.sub(r'<i class="fa.*?</i>\s*', "", contents)
   114      # Interpret img shortcodes
   115      # {{< img ... >}}
   116      contents = re.sub(r'\{\{<\s*img\s+(.*?)>\}\}', r"<img \1>", contents)
   117      # Make any img tags absolute
   118      contents = re.sub(r'(<img.*?src=")/', r"\1https://rclone.org/", contents)
   119      # Make [...](/links/) absolute
   120      contents = re.sub(r'\]\((\/.*?\/(#.*)?)\)', r"](https://rclone.org\1)", contents)
   121      # Add additional links on the front page
   122      contents = re.sub(r'\{\{< rem MAINPAGELINK >\}\}', "- [Donate.](https://rclone.org/donate/)", contents)
   123      # Interpret provider shortcode
   124      # {{< provider name="Amazon S3" home="https://aws.amazon.com/s3/" config="/s3/" >}}
   125      contents = re.sub(r'\{\{<\s*provider.*?name="(.*?)".*?>\}\}', r"- \1", contents)
   126      # Remove remaining shortcodes
   127      contents = re.sub(r'\{\{<.*?>\}\}', r"", contents)
   128      contents = re.sub(r'\{\{%.*?%\}\}', r"", contents)
   129      return contents
   130  
   131  def check_docs(docpath):
   132      """Check all the docs are in docpath"""
   133      files = set(f for f in os.listdir(docpath) if f.endswith(".md"))
   134      files -= set(ignore_docs)
   135      docs_set = set(docs)
   136      if files == docs_set:
   137          return
   138      print("Files on disk but not in docs variable: %s" % ", ".join(files - docs_set))
   139      print("Files in docs variable but not on disk: %s" % ", ".join(docs_set - files))
   140      raise ValueError("Missing files")
   141  
   142  def read_command(command):
   143      doc = read_doc("commands/"+command)
   144      doc = re.sub(r"### Options inherited from parent commands.*$", "", doc, 0, re.S)
   145      doc = doc.strip()+"\n"
   146      return doc
   147  
   148  def read_commands(docpath):
   149      """Reads the commands an makes them into a single page"""
   150      files = set(f for f in os.listdir(docpath + "/commands") if f.endswith(".md"))
   151      docs = []
   152      for command in commands_order:
   153          docs.append(read_command(command))
   154          files.remove(command)
   155      for command in sorted(files):
   156          if command != "rclone.md":
   157              docs.append(read_command(command))
   158      return "\n".join(docs)
   159      
   160  def main():
   161      check_docs(docpath)
   162      command_docs = read_commands(docpath).replace("\\", "\\\\") # escape \ so we can use command_docs in re.sub
   163      with open(outfile, "w") as out:
   164          out.write("""\
   165  %% rclone(1) User Manual
   166  %% Nick Craig-Wood
   167  %% %s
   168  
   169  """ % datetime.now().strftime("%b %d, %Y"))
   170          for doc in docs:
   171              contents = read_doc(doc)
   172              # Substitute the commands into doc.md
   173              if doc == "docs.md":
   174                  contents = re.sub(r"The main rclone commands.*?for the full list.", command_docs, contents, 0, re.S)
   175              out.write(contents)
   176      print("Written '%s'" % outfile)
   177  
   178  if __name__ == "__main__":
   179      main()