Module: Mint::Commandline

Defined in:
lib/mint/commandline/run.rb,
lib/mint/commandline/parse.rb,
lib/mint/commandline/publish.rb

Class Method Summary collapse

Class Method Details

.parse!(argv) ⇒ Array

Parses ARGV using OptionParser, mutating ARGV

Parameters:

  • argv (Array)

    a list of arguments to parse

Returns:

  • (Array)

    a list that contains the command, a help message, parsed config, and selected scopes



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/mint/commandline/parse.rb', line 14

def self.parse!(argv)
  commandline_options = {}

  parser = OptionParser.new do |cli|
    cli.banner = "Usage: mint [command] files [options]"

    cli.on "-h", "--help", "Show this help message" do
      commandline_options[:help] = true
    end

    cli.on "-v", "--verbose", "Show verbose output" do
      commandline_options[:verbose] = true
    end

    cli.on "-t", "--template TEMPLATE", "Specify a template by name (default: default)" do |t|
      commandline_options[:layout_name] = t
      commandline_options[:style_name] = t
    end

    cli.on "-l", "--layout LAYOUT", "Specify a layout by name (default: default)" do |l|
      commandline_options[:layout_name] = l
    end

    cli.on "-s", "--style STYLE", "Specify a style by name (default: default)" do |s|
      commandline_options[:style_name] = s
    end

    cli.on "-w", "--working-dir WORKING_DIR", "Specify a working directory outside the current directory (default: current directory)" do |w|
      commandline_options[:working_directory] = Pathname.new w
    end

    cli.on "-o", "--output-file FORMAT", "Specify the output file format with substitutions: \%{name}, \%{original_ext}, \%{ext} (default: \%{name}.\%{ext})" do |o|
      commandline_options[:output_file_format] = o
    end

    cli.on "-d", "--destination DESTINATION", "Specify a destination directory, relative to the root (default: current directory)" do |d|
      commandline_options[:destination_directory] = Pathname.new d
    end

    cli.on "-m", "--style-mode MODE", ["inline", "external", "original"], "Specify how styles are included (inline, external, original) (default: inline)" do |mode|
      commandline_options[:style_mode] = mode.to_sym
    end

    cli.on "--style-destination DESTINATION", "Create stylesheet in specified directory (relative to --destination) and link it" do |destination|
      commandline_options[:style_mode] = :external
      commandline_options[:style_destination_directory] = destination
    end

    cli.on "--preserve-structure", "Preserve source directory structure in destination (default: true)" do
      commandline_options[:preserve_structure] = true
    end

    cli.on "--no-preserve-structure", "Don't preserve source directory structure in destination" do
      commandline_options[:preserve_structure] = false
    end
    
    cli.on "--navigation", "Make navigation information available to layout, so layout can show a navigation panel (default: false)" do
      commandline_options[:navigation] = true
    end

    cli.on "--no-navigation", "Don't make navigation information available to layout" do
      commandline_options[:navigation] = false
    end
    
    cli.on "--autodrop", "Automatically drop common directory levels from output file paths (default: true)" do
      commandline_options[:autodrop] = true
    end

    cli.on "--no-autodrop", "Don't automatically drop common directory levels from output file paths" do
      commandline_options[:autodrop] = false
    end
    
    cli.on "--navigation-depth DEPTH", Integer, "Maximum depth to show in navigation (default: 3)" do |depth|
      commandline_options[:navigation_depth] = depth
    end
    
    cli.on "--navigation-title TITLE", "Set the title for the navigation panel" do |title|
      commandline_options[:navigation_title] = title
    end
    
    cli.on "--insert-title-heading", "Insert the document's title as an H1 heading into the document content" do
      commandline_options[:insert_title_heading] = true
    end

    cli.on "--no-insert-title-heading", "Don't insert title as H1 heading" do
      commandline_options[:insert_title_heading] = false
    end
  end

  parser.parse! argv
  command = argv.shift
  
  if argv.include?('-')
    if argv.length > 1
      $stderr.puts "Error: Cannot mix STDIN ('-') with other file arguments"
      exit 1
    end
    
    commandline_options[:files] = []
    commandline_options[:stdin_mode] = true
    commandline_options[:stdin_content] = $stdin.read

    # Because STDIN will be written to a temporary file, we don't want to preserve structure or autodrop;
    # that filesystem should not be visible to the user.
    commandline_options[:preserve_structure] = false
    commandline_options[:autodrop] = true

  else
    commandline_options[:files] = argv
    commandline_options[:stdin_mode] = false
  end
  
  if commandline_options[:style_mode] == :inline && commandline_options[:style_destination_directory]
    raise ArgumentError, "--style-mode inline and --style-destination cannot be used together"
  end
  
  
  # Process files differently based on whether we're reading from STDIN
  if commandline_options[:stdin_mode]
    files = commandline_options[:files]
  else
    files = commandline_options[:files].map {|f| Pathname.new(f) }
  end
  
  commandline_config = Config.new(commandline_options)
  config = Config.defaults.merge(Mint.configuration).merge(commandline_config)

  [command, config, files, parser.help]
end

.publish!(source_files, config: Config.new) ⇒ Object

For each file specified, publishes a new file based on configuration.

Parameters:

  • source_files (Array)

    files a group of Pathname objects

  • config (Config, Hash) (defaults to: Config.new)

    a Config object or Hash with configuration options



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/mint/commandline/publish.rb', line 12

def self.publish!(source_files, config: Config.new)
  config = Config.ensure_config(config)
  
  if source_files.empty?
    raise ArgumentError, "No files specified. Use file paths or '-' to read from STDIN."
  end
  
  if config.stdin_mode
    # source_files in this case is the actual content from STDIN, not a Pathname object
    stdin_content = source_files.first
    temp_file = Tempfile.new(['stdin', '.md'])
    temp_file.write(stdin_content)
    temp_file.close
    
    # Convert the Tempfile path to a Pathname object
    workspace = Workspace.new([Pathname.new(temp_file.path)], config)
    destination_paths = workspace.publish!
    output_file = destination_paths.first
    if config.verbose
      puts "Published: STDIN -> #{output_file}"
    end
    
    temp_file.unlink
  else
    workspace = Workspace.new(source_files, config)
    destination_paths = workspace.publish!
    if config.verbose
      source_files.zip(destination_paths).each do |source_file, output_file|
        puts "Published: #{source_file} -> #{output_file}"
      end
    end
  end
end

.run!(argv) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/mint/commandline/run.rb', line 6

def self.run!(argv)
  command, config, files, help = Mint::Commandline.parse! argv

  if config.help || command.nil?
    puts help
    exit 0
  elsif command.to_sym == :publish
    begin
      Mint::Commandline.publish!(files, config: config)
    rescue ArgumentError => e
      $stderr.puts "Error: #{e.message}"
      exit 1
    end
  else
    possible_binary = "mint-#{command}"
    if File.executable? possible_binary
      system "#{possible_binary} #{argv[1..-1].join ' '}"
    else
      $stderr.puts "Error: Unknown command '#{command}'"
      exit 1
    end
  end
end