A parser that create DocCommand from a string

Used by both Nitx and the Markdown doc commands.

Introduced classes

class CmdOptions

nitc :: CmdOptions

Commands options
class CmdParserError

nitc :: CmdParserError

An error produced by the CmdParser
class CommandParser

nitc :: CommandParser

Parse string commands to create DocQueries

Redefined classes

redef class CmdAncestors

nitc :: commands_parser $ CmdAncestors

MEntity ancestors command
redef class CmdCatalogPerson

nitc :: commands_parser $ CmdCatalogPerson

Retrieve a person from the catalog
redef class CmdCatalogTag

nitc :: commands_parser $ CmdCatalogTag

Retrieve the packages for a tag
redef abstract class CmdCode

nitc :: commands_parser $ CmdCode

Abstract command that returns source-code pieces
redef class CmdComment

nitc :: commands_parser $ CmdComment

Retrieve the MDoc related to a MEntity
redef class CmdDescendants

nitc :: commands_parser $ CmdDescendants

MEntity descendants command
redef class CmdEntity

nitc :: commands_parser $ CmdEntity

A command about a MEntity
redef abstract class CmdGraph

nitc :: commands_parser $ CmdGraph

An abstract command that returns a dot graph
redef class CmdInheritanceGraph

nitc :: commands_parser $ CmdInheritanceGraph

Render a hierarchy graph for mentity if any.
redef abstract class CmdList

nitc :: commands_parser $ CmdList

A command that returns a list of results
redef class CmdModelEntities

nitc :: commands_parser $ CmdModelEntities

A command that returns a list of all mentities in a model
redef class CmdSearch

nitc :: commands_parser $ CmdSearch

A free text search command
redef abstract class DocCommand

nitc :: commands_parser $ DocCommand

Documentation command
redef abstract class Text

nitc :: commands_parser $ Text

High-level abstraction for all text representations

All class definitions

redef class CmdAncestors

nitc :: commands_parser $ CmdAncestors

MEntity ancestors command
redef class CmdCatalogPerson

nitc :: commands_parser $ CmdCatalogPerson

Retrieve a person from the catalog
redef class CmdCatalogTag

nitc :: commands_parser $ CmdCatalogTag

Retrieve the packages for a tag
redef abstract class CmdCode

nitc :: commands_parser $ CmdCode

Abstract command that returns source-code pieces
redef class CmdComment

nitc :: commands_parser $ CmdComment

Retrieve the MDoc related to a MEntity
redef class CmdDescendants

nitc :: commands_parser $ CmdDescendants

MEntity descendants command
redef class CmdEntity

nitc :: commands_parser $ CmdEntity

A command about a MEntity
redef abstract class CmdGraph

nitc :: commands_parser $ CmdGraph

An abstract command that returns a dot graph
redef class CmdInheritanceGraph

nitc :: commands_parser $ CmdInheritanceGraph

Render a hierarchy graph for mentity if any.
redef abstract class CmdList

nitc :: commands_parser $ CmdList

A command that returns a list of results
redef class CmdModelEntities

nitc :: commands_parser $ CmdModelEntities

A command that returns a list of all mentities in a model
class CmdOptions

nitc $ CmdOptions

Commands options
class CmdParserError

nitc $ CmdParserError

An error produced by the CmdParser
redef class CmdSearch

nitc :: commands_parser $ CmdSearch

A free text search command
class CommandParser

nitc $ CommandParser

Parse string commands to create DocQueries
redef abstract class DocCommand

nitc :: commands_parser $ DocCommand

Documentation command
redef abstract class Text

nitc :: commands_parser $ Text

High-level abstraction for all text representations
package_diagram nitc::commands_parser commands_parser nitc::commands_catalog commands_catalog nitc::commands_parser->nitc::commands_catalog nitc::commands_graph commands_graph nitc::commands_parser->nitc::commands_graph nitc::commands_ini commands_ini nitc::commands_parser->nitc::commands_ini nitc::commands_main commands_main nitc::commands_parser->nitc::commands_main nitc::commands_usage commands_usage nitc::commands_parser->nitc::commands_usage nitc::commands_model commands_model nitc::commands_catalog->nitc::commands_model nitc\>catalog\> catalog nitc::commands_catalog->nitc\>catalog\> nitc::commands_graph->nitc::commands_model nitc\>uml\> uml nitc::commands_graph->nitc\>uml\> dot dot nitc::commands_graph->dot nitc::commands_ini->nitc::commands_model nitc::commands_main->nitc::commands_model nitc::commands_usage->nitc::commands_model nitc\>semantize\> semantize nitc::commands_usage->nitc\>semantize\> ...nitc::commands_model ... ...nitc::commands_model->nitc::commands_model ...nitc\>catalog\> ... ...nitc\>catalog\>->nitc\>catalog\> ...nitc\>uml\> ... ...nitc\>uml\>->nitc\>uml\> ...dot ... ...dot->dot ...nitc\>semantize\> ... ...nitc\>semantize\>->nitc\>semantize\> nitc::html_commands html_commands nitc::html_commands->nitc::commands_parser nitc::term term nitc::term->nitc::commands_parser nitc::static_cards static_cards nitc::static_cards->nitc::html_commands nitc::api_base api_base nitc::api_base->nitc::html_commands nitc::static_cards... ... nitc::static_cards...->nitc::static_cards nitc::api_base... ... nitc::api_base...->nitc::api_base nitc::nitx nitx nitc::nitx->nitc::term nitc::nitx... ... nitc::nitx...->nitc::nitx

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module abstract_tree

trees :: abstract_tree

Introduce tree structures abstraction
module annotation

nitc :: annotation

Management and utilities on annotations
module array

core :: array

This module introduces the standard array structure.
module auto_super_init

nitc :: auto_super_init

Computing of super-constructors that must be implicitly called at the begin of constructors.
module bintree

trees :: bintree

Binary Tree data-structure
module bitset

core :: bitset

Services to handle BitSet
module bktree

trees :: bktree

Implementation of BKTree
module bytes

core :: bytes

Services for byte streams and arrays
module caching

serialization :: caching

Services for caching serialization engines
module catalog

nitc :: catalog

Basic catalog generator for Nit packages
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module commands_base

nitc :: commands_base

Documentation commands
module commands_model

nitc :: commands_model

Doc commands about a Model or a MEntity
module console

console :: console

Defines some ANSI Terminal Control Escape Sequences.
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module counter

counter :: counter

Simple numerical statistical analysis and presentation
module digraph

graph :: digraph

Implementation of directed graphs, also called digraphs.
module dot

dot :: dot

Dot rendering library
module engine_tools

serialization :: engine_tools

Advanced services for serialization engines
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module flow

nitc :: flow

Intraprocedural static flow.
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module ini

ini :: ini

Read and write INI configuration files
module inspect

serialization :: inspect

Refine Serializable::inspect to show more useful information
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module lexer

nitc :: lexer

Lexer and its tokens.
module lexer_work

nitc :: lexer_work

Internal algorithm and data structures for the Nit lexer
module list

core :: list

This module handle double linked lists
module literal

nitc :: literal

Parsing of literal values in the abstract syntax tree.
module loader

nitc :: loader

Loading of Nit source files
module local_var_init

nitc :: local_var_init

Verify that local variables are initialized before their usage
module location

nitc :: location

Nit source-file and locations in source-file
module math

core :: math

Mathematical operations
module md5

md5 :: md5

Native MD5 digest implementation as Text::md5
module mdoc

nitc :: mdoc

Documentation of model entities
module meta

meta :: meta

Simple user-defined meta-level to manipulate types of instances as object.
module mmodule

nitc :: mmodule

modules and module hierarchies in the metamodel
module mmodule_data

nitc :: mmodule_data

Define and retrieve data in modules
module model

nitc :: model

Classes, types and properties
module model_base

nitc :: model_base

The abstract concept of model and related common things
module model_collect

nitc :: model_collect

Collect things from the model.
module model_examples

nitc :: model_examples

Examples for Model entities
module model_index

nitc :: model_index

Search things from the Model
module modelbuilder_base

nitc :: modelbuilder_base

Load nit source files and build the associated model
module modelize

nitc :: modelize

Create a model from nit source files
module modelize_class

nitc :: modelize_class

Analysis and verification of class definitions to instantiate model element
module modelize_property

nitc :: modelize_property

Analysis and verification of property definitions to instantiate model element
module more_collections

more_collections :: more_collections

Highly specific, but useful, collections-related classes.
module mpackage

nitc :: mpackage

Modelisation of a Nit package
module native

core :: native

Native structures for text and bytes
module nitpm_shared

nitc :: nitpm_shared

Services related to the Nit package manager
module numeric

core :: numeric

Advanced services for Numeric types
module opts

opts :: opts

Management of options on the command line
module ordered_tree

ordered_tree :: ordered_tree

Manipulation and presentation of ordered trees.
module parse_annotations

nitc :: parse_annotations

Simple annotation parsing
module parser

nitc :: parser

Parser.
module parser_nodes

nitc :: parser_nodes

AST nodes of the Nit language
module parser_prod

nitc :: parser_prod

Production AST nodes full definition.
module parser_work

nitc :: parser_work

Internal algorithm and data structures for the Nit parser
module phase

nitc :: phase

Phases of the processing of nit programs
module poset

poset :: poset

Pre order sets and partial order set (ie hierarchies)
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module rbtree

trees :: rbtree

A red–black tree is a data structure which is a type of self-balancing binary search tree.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module scope

nitc :: scope

Identification and scoping of local variables and labels.
module semantize

nitc :: semantize

Process bodies of methods in regard with the model.
module serialization

serialization :: serialization

General serialization services
module serialization_core

serialization :: serialization_core

Abstract services to serialize Nit objects to different formats
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module tables

nitc :: tables

Module that interfaces the parsing tables.
module template

template :: template

Basic template system
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module toolcontext

nitc :: toolcontext

Common command-line tool infrastructure than handle options and error messages
module trees

trees :: trees

General module for tree data structures
module trie

trees :: trie

A trie (or prefix tree) is a datastructure used to perform prefix searches.
module typing

nitc :: typing

Intraprocedural resolution of static types and OO-services
module uml

nitc :: uml

Group head module for UML generation services
module uml_base

nitc :: uml_base

Exposes the base class for UML generation of a Model
module uml_class

nitc :: uml_class

Provides facilities of exporting a Model to a UML class diagram
module uml_module

nitc :: uml_module

Services for generation of a UML package diagram based on a Model
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O
module version

nitc :: version

This file was generated by git-gen-version.sh

Parents

module commands_catalog

nitc :: commands_catalog

Commands to retrieve Catalog related data
module commands_graph

nitc :: commands_graph

Graph commands
module commands_usage

nitc :: commands_usage

Commands about how mentities are used

Children

module html_commands

nitc :: html_commands

Render commands results as HTML
module term

nitc :: term

Descendants

module a_star-m

a_star-m

module api

nitc :: api

Components required to build a web server about the nit model.
module api_auth

nitc :: api_auth

module api_base

nitc :: api_base

Base classes used by nitweb.
module api_docdown

nitc :: api_docdown

Nitdoc specific Markdown format handling for Nitweb
module api_feedback

nitc :: api_feedback

Feedback related features
module api_light

nitc :: api_light

Highlight and collect messages from a piece of code
module api_model

nitc :: api_model

module nitdoc

nitc :: nitdoc

Generator of static API documentation for the Nit language
module nitweb

nitc :: nitweb

Runs a webserver based on nitcorn that render things from model.
module nitx

nitc :: nitx

nitx, a command tool that displays useful data about Nit code
module static

nitc :: static

Nitdoc generation framework
module static_base

nitc :: static_base

Base entities shared by all the nitdoc code
module static_cards

nitc :: static_cards

Cards templates for the static documentation
module static_html

nitc :: static_html

Render documentation pages as HTML
module static_index

nitc :: static_index

Manage indexing of Nit model for Nitdoc QuickSearch.
module static_structure

nitc :: static_structure

Composes the pages of the static documentation
# A parser that create DocCommand from a string
#
# Used by both Nitx and the Markdown doc commands.
module commands_parser

import commands_catalog
import commands_graph
import commands_ini
import commands_main
import commands_usage

# Parse string commands to create DocQueries
class CommandParser

	# Model used to retrieve mentities
	var model: Model

	# Main module for linearization
	var mainmodule: MModule

	# ModelBuilder used to retrieve AST nodes
	var modelbuilder: ModelBuilder

	# Catalog used for catalog commands
	var catalog: nullable Catalog

	# List of allowed command names for this parser
	var allowed_commands: Array[String] = [
	"link", "doc", "code", "lin", "uml", "graph", "search",
	"parents", "ancestors", "children", "descendants",
	"param", "return", "new", "call", "defs", "list", "random",
	"ini-desc", "ini-git", "ini-issues", "ini-maintainer", "ini-contributors", "ini-license",
	"license-file", "contrib-file", "license-content", "contrib-content", "git-clone",
	"mains", "main-compile", "main-run", "main-opts", "testing",
	"catalog", "stats", "tags", "tag", "person", "contrib", "maintain"] is writable

	# List of commands usage and documentation
	var commands_usage: Map[String, String] do
		var usage = new ArrayMap[String, String]
		usage["search: <string>"] = "list entities matching `string`"
		usage["link: <name>"] = "display the link to `name`"
		usage["doc: <name>"] = "display the documentation for `name`"
		usage["defs: <name>"] = "list all definitions for `name`"
		usage["code: <name>"] = "display the code for `name`"
		usage["lin: <name>"] = "display the linearization for `name`"
		usage["uml: <name>"] = "display the UML diagram for `name`"
		usage["graph: <name>"] = "display the inheritance graph for `name`"
		usage["parents: <name>"] = "list the direct parents of `name`"
		usage["ancestors: <name>"] = "list all ancestors of `name`"
		usage["children: <name>"] = "list direct children of `name`"
		usage["descendants: <name>"] = "list all descendants of `name`"
		usage["param: <type>"] = "list all methods accepting `type` as parameter"
		usage["return: <type>"] = "list all methods returning `type`"
		usage["new: <class>"] = "list all methods initializing `class`"
		usage["call: <property>"] = "list all methods calling `property`"
		usage["list: <kind>"] = "list all entities of `kind` from the model"
		usage["random: <kind>"] = "list random entities of `kind` from the model"
		usage["catalog:"] = "list packages from catalog"
		usage["stats:"] = "display catalog statistics"
		usage["tags:"] = "list all tabs from catalog"
		usage["tag: <tag>"] = "list all packages with `tag`"
		usage["maintain: <person>"] = "list all packages maintained by `person`"
		usage["contrib: <person>"] = "list all packages contributed by `person`"
		# Ini commands
		usage["ini-desc: <package>"] = "display the description from the `package` ini file"
		usage["ini-git: <package>"] = "display the git url from the `package` ini file"
		usage["ini-issues: <package>"] = "display the issues url from the `package` ini file"
		usage["ini-license: <package>"] = "display the license from the `package` ini file"
		usage["ini-maintainer: <package>"] = "display the maintainer from the `package` ini file"
		usage["ini-contributors: <package>"] = "display the contributors from the `package` ini file"
		usage["license-file: <package>"] = "display the license file for the `package`"
		usage["license-content: <package>"] = "display the license file content for the `package`"
		usage["contrib-file: <package>"] = "display the contrib file for the `package`"
		usage["contrib-content: <package>"] = "display the contrib file content for the `package`"
		usage["git-clone: <package>"] = "display the git clone command for the `package`"
		# Main
		usage["mains: <name>"] = "display the list of main methods for `name`"
		usage["main-compile: <name>"] = "display the nitc command to compile `name`"
		usage["main-run: <name>"] = "display the command to run `name`"
		usage["main-opts: <name>"] = "display the command options for `name`"
		usage["testing: <name>"] = "display the nitunit command to test `name`"
		return usage
	end

	# Parse `string` as a DocCommand
	#
	# Returns `null` if the string cannot be parsed.
	# See `error` for the error messages produced by both the parser and the commands.
	fun parse(string: String): nullable DocCommand do
		var pos = 0
		var tmp = new FlatBuffer
		error = null

		# Parse command name
		pos = string.read_until(tmp, pos, ':', '|')
		var name = tmp.write_to_string.trim

		# Check allowed commands
		if name.is_empty then
			error = new CmdParserError("Empty command name", 0)
			return null
		end
		# If the command name contains two consecutive colons or there is no colon in the name,
		# we certainly have a wiki link to a mentity
		var is_short_link = false
		if (pos < string.length - 2 and string[pos] == ':' and string[pos + 1] == ':') or
		   pos == string.length then
			is_short_link = true
		else if pos < string.length - 1 and string[pos] == '|' then
			is_short_link = true
			pos -= 1
		else if not allowed_commands.has(name) then
			error = new CmdParserError("Unknown command name `{name}`", 0)
			return null
		end

		# Parse the argument
		tmp.clear
		pos = string.read_until(tmp, pos + 1, '|')
		var arg = tmp.write_to_string.trim
		if is_short_link and not arg.is_empty then
			arg = "{name}:{arg}"
		else if is_short_link then
			arg = name
		end

		# Parse command options
		var opts = new CmdOptions
		while pos < string.length do
			# Parse option name
			tmp.clear
			pos = string.read_until(tmp, pos + 1, ':', ',')
			var oname = tmp.write_to_string.trim
			var oval = ""
			if oname.is_empty then break
			# Parse option value
			if pos < string.length and string[pos] == ':' then
				tmp.clear
				pos = string.read_until(tmp, pos + 1, ',')
				oval = tmp.write_to_string.trim
			end
			opts[oname] = oval
		end

		# Build the command
		var command
		if is_short_link then
			command = new CmdEntityLink(model)
		else
			command = new_command(name)
		end
		if command == null then
			error = new CmdParserError("Unknown command name `{name}`", 0)
			return null
		end

		# Initialize command from string options
		var status = command.parser_init(arg, opts)
		if not status isa CmdSuccess then error = status

		return command
	end

	# Init a new DocCommand from its `name`
	#
	# You must redefine this method to add new custom commands.
	fun new_command(name: String): nullable DocCommand do
		# CmdEntity
		if name == "link" then return new CmdEntityLink(model)
		if name == "doc" then return new CmdComment(model)
		if name == "code" then return new CmdEntityCode(model, modelbuilder)
		if name == "lin" then return new CmdLinearization(model, mainmodule)
		if name == "defs" then return new CmdFeatures(model)
		if name == "parents" then return new CmdParents(model, mainmodule)
		if name == "ancestors" then return new CmdAncestors(model, mainmodule)
		if name == "children" then return new CmdChildren(model, mainmodule)
		if name == "descendants" then return new CmdDescendants(model, mainmodule)
		if name == "param" then return new CmdParam(model)
		if name == "return" then return new CmdReturn(model)
		if name == "new" then return new CmdNew(model, modelbuilder)
		if name == "call" then return new CmdCall(model, modelbuilder)
		# CmdGraph
		if name == "uml" then return new CmdUML(model, mainmodule)
		if name == "graph" then return new CmdInheritanceGraph(model, mainmodule)
		# CmdModel
		if name == "list" then return new CmdModelEntities(model)
		if name == "random" then return new CmdRandomEntities(model)
		# Ini
		if name == "ini-desc" then return new CmdIniDescription(model)
		if name == "ini-git" then return new CmdIniGitUrl(model)
		if name == "ini-issues" then return new CmdIniIssuesUrl(model)
		if name == "ini-license" then return new CmdIniLicense(model)
		if name == "ini-maintainer" then return new CmdIniMaintainer(model)
		if name == "ini-contributors" then return new CmdIniContributors(model)
		if name == "license-file" then return new CmdLicenseFile(model)
		if name == "license-content" then return new CmdLicenseFileContent(model)
		if name == "contrib-file" then return new CmdContribFile(model)
		if name == "contrib-content" then return new CmdContribFileContent(model)
		if name == "git-clone" then return new CmdIniCloneCommand(model)
		# CmdMain
		if name == "mains" then return new CmdMains(model)
		if name == "main-compile" then return new CmdMainCompile(model)
		if name == "main-run" then return new CmdManSynopsis(model)
		if name == "main-opts" then return new CmdManOptions(model)
		if name == "testing" then return new CmdTesting(model)
		# CmdCatalog
		var catalog = self.catalog
		if catalog != null then
			if name == "catalog" then return new CmdCatalogPackages(model, catalog)
			if name == "stats" then return new CmdCatalogStats(model, catalog)
			if name == "tags" then return new CmdCatalogTags(model, catalog)
			if name == "tag" then return new CmdCatalogTag(model, catalog)
			if name == "person" then return new CmdCatalogPerson(model, catalog)
			if name == "contrib" then return new CmdCatalogContributing(model, catalog)
			if name == "maintain" then return new CmdCatalogMaintaining(model, catalog)
			if name == "search" then return new CmdCatalogSearch(model, catalog)
		else
			if name == "search" then return new CmdSearch(model)
		end
		return null
	end

	# Error or warning from last call to `parse`
	var error: nullable CmdMessage = null
end

# An error produced by the CmdParser
class CmdParserError
	super CmdError

	# Error message
	var message: String

	# Column related to the error
	var column: nullable Int

	redef fun to_s do return message
end

redef class DocCommand

	# Initialize the command from the CommandParser data
	fun parser_init(arg: String, options: CmdOptions): CmdMessage do
		var filter = cmd_filter
		var opt_vis = options.opt_visibility("min-visibility")
		if opt_vis != null then filter.min_visibility = opt_vis
		var opt_fictive = options.opt_bool("no-fictive")
		if opt_fictive != null then filter.accept_fictive = not opt_fictive
		var opt_test = options.opt_bool("no-test")
		if opt_test != null then filter.accept_test = not opt_test
		var opt_redef = options.opt_bool("no-redef")
		if opt_redef != null then filter.accept_redef = not opt_redef
		var opt_extern = options.opt_bool("no-extern")
		if opt_extern != null then filter.accept_extern = not opt_extern
		var opt_example = options.opt_bool("no-example")
		if opt_example != null then filter.accept_example = not opt_example
		var opt_attr = options.opt_bool("no-attribute")
		if opt_attr != null then filter.accept_attribute = not opt_attr
		var opt_doc = options.opt_bool("no-empty-doc")
		if opt_doc != null then filter.accept_empty_doc = not opt_doc
		var opt_inh = options.opt_mentity(model, "inherit")
		if opt_inh != null then filter.accept_inherited = opt_inh
		var opt_match = options.opt_string("match")
		if opt_match != null then filter.accept_full_name = opt_match
		self.filter = filter
		return init_command
	end
end

redef class CmdEntity
	redef fun parser_init(mentity_name, options) do
		self.mentity_name = mentity_name
		return super
	end
end

redef class CmdList
	redef fun parser_init(mentity_name, options) do
		var opt_page = options.opt_int("page")
		if opt_page != null then page = opt_page
		var opt_limit = options.opt_int("limit")
		if opt_limit != null then limit = opt_limit
		return super
	end
end

# Model commands

redef class CmdComment
	redef fun parser_init(mentity_name, options) do
		var opt_full_doc = options.opt_bool("only-synopsis")
		if opt_full_doc != null then full_doc = not opt_full_doc
		var opt_fallback = options.opt_bool("no-fallback")
		if opt_fallback != null then fallback = not opt_fallback
		var opt_format = options.opt_string("format")
		if opt_format != null then format = opt_format
		return super
	end
end

redef class CmdEntityLink
	redef fun parser_init(mentity_name, options) do
		var opt_text = options.opt_string("text")
		if opt_text != null then text = opt_text
		var opt_title = options.opt_string("title")
		if opt_title != null then title = opt_title
		return super
	end
end

redef class CmdCode
	redef fun parser_init(mentity_name, options) do
		var opt_format = options.opt_string("format")
		if opt_format != null then format = opt_format
		return super
	end
end

redef class CmdSearch
	redef fun parser_init(mentity_name, options) do
		query = mentity_name
		return super
	end
end

redef class CmdAncestors
	redef fun parser_init(mentity_name, options) do
		var opt_parents = options.opt_bool("no-parents")
		if opt_parents != null then parents = not opt_parents
		return super
	end
end

redef class CmdDescendants
	redef fun parser_init(mentity_name, options) do
		var opt_children = options.opt_bool("no-children")
		if opt_children != null then children = not opt_children
		return super
	end
end

redef class CmdModelEntities
	redef fun parser_init(kind, options) do
		self.kind = kind
		return super
	end
end

redef class CmdGraph
	redef fun parser_init(mentity_name, options) do
		var opt_format = options.opt_string("format")
		if opt_format != null then format = opt_format
		return super
	end
end

redef class CmdInheritanceGraph
	redef fun parser_init(mentity_name, options) do
		var opt_pdepth = options.opt_int("pdepth")
		if opt_pdepth != null then pdepth = opt_pdepth
		var opt_cdepth = options.opt_int("cdepth")
		if opt_cdepth != null then cdepth = opt_cdepth
		return super
	end
end

# Catalog commands

redef class CmdCatalogTag
	redef fun parser_init(mentity_name, options) do
		tag = mentity_name
		return super
	end
end

redef class CmdCatalogPerson
	redef fun parser_init(mentity_name, options) do
		person_name = mentity_name
		return super
	end
end

# Utils

# Commands options
class CmdOptions
	super HashMap[String,  String]

	# Map String visiblity name to MVisibility object
	var allowed_visibility: HashMap[String, MVisibility] is lazy do
		var res = new HashMap[String, MVisibility]
		res["public"] = public_visibility
		res["protected"] = protected_visibility
		res["private"] = private_visibility
		return res
	end

	# Get option value for `key` as String
	#
	# Return `null` if no option with that `key` or if value is empty.
	fun opt_string(key: String): nullable String do
		if not has_key(key) then return null
		var value = self[key]
		if value.is_empty then return null
		return value
	end

	# Get option value for `key` as Int
	#
	# Return `null` if no option with that `key` or if value is not an Int.
	fun opt_int(key: String): nullable Int do
		if not has_key(key) then return null
		var value = self[key]
		if not value.is_int then return null
		return value.to_i
	end

	# Get option value as bool
	#
	# Return `true` if the value with that `key` is empty or equals `"true"`.
	# Return `false` if the value with that `key` equals `"false"`.
	# Return `null` in any other case.
	fun opt_bool(key: String): nullable Bool do
		if not has_key(key) then return null
		var value = self[key]
		if value.is_empty or value == "true" then return true
		if value == "false" then return false
		return null
	end

	# Get option as a MVisibility
	#
	# Return `null` if no option with that `key` or if the value is not in
	# `allowed_visibility`.
	fun opt_visibility(key: String): nullable MVisibility do
		var value = opt_string(key)
		if value == null then return null
		if not allowed_visibility.keys.has(key) then return null
		return allowed_visibility[value]
	end

	# Get option as a MEntity
	#
	# Lookup first by `MEntity::full_name` then by `MEntity::name`.
	# Return `null` if the mentity name does not exist or return a conflict.
	private fun opt_mentity(model: Model, key: String): nullable MEntity do
		var value = opt_string(key)
		if value == null or value.is_empty then return null

		var mentity = model.mentity_by_full_name(value)
		if mentity != null then return mentity

		var mentities = model.mentities_by_name(value)
		if mentities.is_empty or mentities.length > 1 then return null
		return mentities.first
	end
end

redef class Text
	# Read `self` as raw text until `nend` and append it to the `out` buffer.
	private fun read_until(out: FlatBuffer, start: Int, nend: Char...): Int do
		var pos = start
		while pos < length do
			var c = self[pos]
			var end_reached = false
			for n in nend do
				if c == n then
					end_reached = true
					break
				end
			end
			if end_reached then break
			out.add c
			pos += 1
		end
		return pos
	end
end
src/doc/commands/commands_parser.nit:15,1--492,3