+private class ManPage
+ var mmodule: MModule
+ var name: nullable String is noinit
+ var synopsis: nullable String is noinit
+ var options = new HashMap[Array[String], String]
+
+ init from_file(mmodule: MModule, file: String) do
+ from_lines(mmodule, file.to_path.read_lines)
+ end
+
+ init from_string(mmodule: MModule, string: String) do
+ from_lines(mmodule, string.split("\n"))
+ end
+
+ init from_lines(mmodule: MModule, lines: Array[String]) do
+ init mmodule
+
+ var section = null
+ for i in [0..lines.length[ do
+ var line = lines[i]
+ if line.is_empty then continue
+
+ if line == "# NAME" then
+ section = "name"
+ continue
+ end
+ if line == "# SYNOPSIS" then
+ section = "synopsis"
+ continue
+ end
+ if line == "# OPTIONS" then
+ section = "options"
+ continue
+ end
+
+ if section == "name" and name == null then
+ name = line.trim
+ end
+ if section == "synopsis" and synopsis == null then
+ synopsis = line.trim
+ end
+ if section == "options" and line.has_prefix("###") then
+ var opts = new Array[String]
+ for opt in line.substring(3, line.length).trim.replace("`", "").split(",") do
+ opts.add opt.trim
+ end
+ var desc = ""
+ if i < lines.length - 1 then
+ desc = lines[i + 1].trim
+ end
+ options[opts] = desc
+ end
+ end
+ end
+
+ fun diff(toolcontext: ToolContext, ref: ManPage) do
+ if name != ref.name then
+ toolcontext.warning(mmodule.location, "diff-man",
+ "Warning: outdated man description. " +
+ "Expected `{ref.name or else ""}` got `{name or else ""}`.")
+ end
+ if synopsis != ref.synopsis then
+ toolcontext.warning(mmodule.location, "diff-man",
+ "Warning: outdated man synopsis. " +
+ "Expected `{ref.synopsis or else ""}` got `{synopsis or else ""}`.")
+ end
+ for name, desc in options do
+ if not ref.options.has_key(name) then
+ toolcontext.warning(mmodule.location, "diff-man",
+ "Warning: unknown man option `{name}`.`")
+ continue
+ end
+ var ref_desc = ref.options[name]
+ if desc != ref_desc then
+ toolcontext.warning(mmodule.location, "diff-man",
+ "Warning: outdated man option description. Expected `{ref_desc}` got `{desc}`.")
+ end
+ end
+ for ref_name, ref_desc in ref.options do
+ if not options.has_key(ref_name) then
+ toolcontext.warning(mmodule.location, "diff-man",
+ "Warning: missing man option `{ref_name}`.`")
+ end
+ end
+ end
+
+ redef fun to_s do
+ var tpl = new Template
+ tpl.addn "# NAME"
+ tpl.addn name or else ""
+ tpl.addn "# SYNOPSIS"
+ tpl.addn synopsis or else ""
+ tpl.addn "# OPTIONS"
+ for name, desc in options do
+ tpl.addn " * {name}: {desc}"
+ end
+ return tpl.write_to_string
+ end
+end
+