docs: def publish_wp(site_name, output_file, resources, args):
  
      """Publish a notebook to a wordpress post, using Gutenberg blocks.
  
      Here is what the metadata looks like, in a section of the notebook tagged 'frontmatter'
  
      show_input: hide
      github: https://github.com/sandiegodata/notebooks/blob/master/tutorial/American%20Community%20Survey.ipynb
      identifier: 5c987397-a954-46ca-8743-bdcd7a71579c
      featured_image: 171
      authors:
      - email: eric@civicknowledge.com
        name: Eric Busboom
        organization: Civic Knowledge
        type: wrangler
      tags:
      - Tag1
      - Tag2
      categories:
      - Demographics
      - Tutorial
  
      'Featured_image' is an attachment id
  
      """
  
      from wordpress_xmlrpc import Client, WordPressPost
      from wordpress_xmlrpc.methods.media import UploadFile, GetMediaLibrary
      from wordpress_xmlrpc.methods.posts import NewPost, EditPost, GetPost
  
      # http://busboom.org/wptest/wp-content/uploads/sites/7/2017/11/output_16_0-300x200.png
  
      url, user, password = get_site_config(site_name)
  
      meta = {}
      for r in resources:
          if r.endswith('.json'):
              with open(r) as f:
                  meta = json.load(f)
  
      fm = meta.get('frontmatter',{})
  
      if not 'identifier' in fm or not fm['identifier']:
          err("Can't publish notebook without a unique identifier. Add this to the "
              "Metatab document or frontmatter metadata:\n   identifier: {}".format(str(uuid4())))
  
      wp = Client(url, user, password)
  
      post = find_post(wp, fm['identifier'])
  
      if post:
          prt("Updating old post")
      else:
          post = WordPressPost()
          post.id = wp.call(NewPost(post))
          prt("Creating new post")
  
      post.title = fm.get('title','')
      post.slug = fm.get('slug')
  
      with open(output_file) as f:
          content = f.read()
  
      post.terms_names = {
          'post_tag': fm.get('tags',[]),
          'category':  fm.get('categories',[])
      }
  
      if args.header:
          print(yaml.dump(fm, default_flow_style=False))
  
      set_custom_field(post, 'identifier', fm['identifier'])
  
      post.excerpt = fm.get('excerpt', fm.get('brief', fm.get('description')))
  
      def strip_image_name(n):
          """Strip off the version number from the media file"""
          from os.path import splitext
          import re
          return re.sub(r'\-\d+$','',splitext(n)[0])
  
      extant_files = list(wp.call(GetMediaLibrary(dict(parent_id=post.id))))
  
      def find_extant_image(image_name):
          for img in extant_files:
              if strip_image_name(basename(img.metadata['file'])) == strip_image_name(image_name):
                  return img
  
          return None
  
      for r in resources:
  
          image_data = prepare_image(fm['identifier'], r, post.id)
          img_from = "/{}/{}".format(fm['slug'], basename(r))
  
          extant_image = find_extant_image(image_data['name'])
  
          if  extant_image:
              prt("Post already has image:", extant_image.id, extant_image.link)
              img_to = extant_image.link
  
          elif r.endswith('.png'): # Foolishly assuming all images are PNGs
              response = wp.call(UploadFile(image_data, overwrite=True))
  
              prt("Uploaded image {} to id={}, {}".format(basename(r), response['id'], response['link']))
  
              img_to = response['link']
  
          content = content.replace(img_from, img_to)
  
      if fm.get('featured_image') and fm.get('featured_image').strip():
          post.thumbnail = int(fm['featured_image'])
      elif hasattr(post, 'thumbnail') and isinstance(post.thumbnail, dict):
          # The thumbnail expects an attachment id on EditPost, but returns a dict on GetPost
          post.thumbnail = post.thumbnail['attachment_id']
  
      post.content = content
  
      r = wp.call(EditPost(post.id, post))
  
      return r,  wp.call(GetPost(post.id))