docs: def Rmarkdown(script=None,
                input=None,
                output=None,
                args='{input:r}, output_file={output:ar}',
                **kwargs):
      '''Convert input file to output using Rmarkdown
  
      The input can be specified in three ways:
  
      1. instant script, which is assumed to be in md format
  
      Rmarkdown:   output='report.html'
        script
  
      2. one or more input files. The format is determined by extension of input file
  
      Rmarkdown(input, output='report.html')
  
      3. input file specified by command line option `-r` .
      Rmarkdown(output='report.html')
  
      If no output is specified, it is assumed to be in html format
      and is written to standard output.
  
      You can specify more options using the args parameter of the action. The default value
      of args is `${input!r} --output ${output!ar}'
      '''
      if not R_library('rmarkdown').target_exists():
          raise RuntimeError('Library rmarkdown does not exist')
  
      input = sos_targets(collect_input(script, input))
  
      output = sos_targets(output)
      if len(output) == 0:
          write_to_stdout = True
          output = sos_targets(
              tempfile.NamedTemporaryFile(
                  mode='w+t', suffix='.html', delete=False).name)
      else:
          write_to_stdout = False
      #
      ret = 1
      try:
          #   render(input, output_format = NULL, output_file = NULL, output_dir = NULL,
          #        output_options = NULL, intermediates_dir = NULL,
          #        runtime = c("auto", "static", "shiny"),
          #        clean = TRUE, params = NULL, knit_meta = NULL, envir = parent.frame(),
          #        run_Rmarkdown = TRUE, quiet = FALSE, encoding = getOption("encoding"))
          cmd = interpolate(f'Rscript -e "rmarkdown::render({args})"', {
              'input': input,
              'output': output
          })
          if 'ACTION' in env.config['SOS_DEBUG'] or 'ALL' in env.config['SOS_DEBUG']:
              env.log_to_file('ACTION', f'Running command "{cmd}"')
          if env.config['run_mode'] == 'interactive':
              # need to catch output and send to python output, which will in trun be hijacked by SoS notebook
              p = subprocess.Popen(
                  cmd, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
              #pid = p.pid
              out, err = p.communicate()
              sys.stdout.write(out.decode())
              sys.stderr.write(err.decode())
              ret = p.returncode
          else:
              p = subprocess.Popen(cmd, shell=True)
              #pid = p.pid
              ret = p.wait()
      except Exception as e:
          env.logger.error(e)
      if ret != 0:
          temp_file = os.path.join('.sos', f'{"Rmarkdown"}_{os.getpid()}.md')
          shutil.copyfile(str(input), temp_file)
          cmd = interpolate(f'Rscript -e "rmarkdown::render({args})"', {
              'input': input,
              'output': sos_targets(temp_file)
          })
          raise RuntimeError(
              f'Failed to execute script. Please use command \n"{cmd}"\nunder {os.getcwd()} to test it.'
          )
      if write_to_stdout:
          with open(str(output[0])) as out:
              sys.stdout.write(out.read())
      else:
          env.logger.info(f'Report saved to {output}')