# SVG to PNG and Nit
-This tool is used in combination with Inkscape to simplify assets creation for _mnit_ apps. It uses Inkscape to extract a PNG file from a SVG file. It will also create a Nit source file to create _mnit_ images for each objects with an id beginning by 0.
+This tool uses Inkscape to prepare assets for Nit applications from a single SVG file.
+It selects objects to extract from the SVG file when their id begins with `0`.
-# Features
+It will produce two files:
-* Creates a sinlge PNG file per SVG source file
-* Creates subimages for objects with an id beginning by 0.
-* If the id ends with 0 to 9, will instead create an array of subimages.
+* A Nit source file that declares a single class with an attribute for each selected object.
+ The attribute usually holds a single texture, except if the the id ends with a digit, then it will be an array.
-# Usage
+* A single PNG image file that contains all the selected objects.
+ With the option `--pow2`, the image size is rounded to the next of 2.
+
+## Usage
1. Create a new Inkscape document.
-2. Create objects and set their ids to begin with 0
-3. Save the document (ex: to `drawing.svg`) the name of the file is important
+2. Create objects and set their ids to begin with `0`.
+3. Save the document to `drawing.svg` (for this example), the name of the file is used to name the Nit class.
4. Execute `bin/svg_to_png_and_nit drawing.svg`
-5. From your code, import the generated source file (at src/drawing.nit`)
+5. From your code, import the generated source file at `src/drawing.nit`.
6. Use the class `DrawingImages` and its attributes.
-# Examples
+## Examples
-The minimal test in tests/app/ shows the basic usage of this tool.
+The minimal test in `tests/app/` shows the basic usage of this tool.
The Dino example `../../../../examples/mnit_dino` also uses this tool and is a more complete and practical example.
# This file is part of NIT ( http://www.nitlanguage.org ).
#
-# Copyright 2012-2014 Alexis Laferrière <alexis.laf@xymus.net>
+# Copyright 2012-2015 Alexis Laferrière <alexis.laf@xymus.net>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# See the License for the specific language governing permissions and
# limitations under the License.
-# This script extracts pngs from a single svg for all objects with ids
-# beginning by 0. Requires Inkscape.
+# Extract images of objects from an SVG file using Inkscape
module svg_to_png_and_nit
import opts
import template
+# Image information extracted from the SVG file
class Image
+ # Name extracted from the object ID minus the `0` prefix and Nit safe
var name: String
+
+ # Left border
var x: Int
+
+ # Top border
var y: Int
+
+ # Image width
var w: Int
+
+ # Image height
var h: Int
+
+ # Right border
fun right: Int do return x+w
+
+ # Bottom border
fun bottom: Int do return y+h
redef fun to_s do return name
end
-# The Nit source file to retreive all images
-class ImageSetSrc
+# Document being processed, concerns both the source and the target
+class Document
+ # Name of the source file
+ var drawing_name: String
+
+ # Name of the class to generate
+ var nit_class_name: String = drawing_name.capitalized + "Images" is lazy
+
+ # Scaling to apply to the exported image
+ var scale: Float
+
+ # Source minimum X
+ var min_x: Int
+
+ # Source maximum X
+ var max_x: Int
+
+ # Source minimum Y
+ var min_y: Int
+
+ # Source maximum Y
+ var max_y: Int
+
+ # Get the coordinates for `image` as `"x, y, w, h"`
+ fun coordinates(image: Image): String
+ do
+ var x = image.x.adapt(min_x, scale)
+ var y = image.y.adapt(min_y, scale)
+ var w = (image.w.to_f*scale).to_i
+ var h = (image.h.to_f*scale).to_i
+
+ return "{x}, {y}, {w}, {h}"
+ end
+end
+
+# Nit module with a single class to retrieve to access the extracted images
+abstract class ImageSetSrc
super Template
- var name: String
- init(name: String) do self.name = name
+ # Target document
+ var document: Document
- var attributes = new Array[String]
- var load_exprs = new Array[String]
+ # Images found in the source document
+ var images: Array[Image]
+end
+
+# Nit module targeting the MNit framework
+class MnitImageSetSrc
+ super ImageSetSrc
redef fun rendering
do
+ # Known array of images
+ var arrays_of_images = new Array[String]
+
+ # Attributes of the generated class
+ var attributes = new Array[String]
+
+ # Statements for the generated `load_all` method
+ var load_exprs = new Array[String]
+
+ # Add images to Nit source file
+ for image in images do
+ # Adapt coordinates to new top left and scale
+ var coordinates = document.coordinates(image)
+
+ var nit_name = image.name
+ var last_char = nit_name.chars.last
+ if last_char.to_s.is_numeric then
+ # Array of images
+ # TODO support more than 10 images in an array
+
+ nit_name = nit_name.substring(0, nit_name.length-1)
+ if not arrays_of_images.has(nit_name) then
+ # Create class attribute to store Array
+ arrays_of_images.add(nit_name)
+ attributes.add "\tvar {nit_name} = new Array[Image]\n"
+ end
+ load_exprs.add "\t\t{nit_name}.add(main_image.subimage({coordinates}))\n"
+ else
+ # Single image
+ attributes.add "\tvar {nit_name}: Image is noinit\n"
+ load_exprs.add "\t\t{nit_name} = main_image.subimage({coordinates})\n"
+ end
+ end
+
add """
-# file generated by svg_to_png, do not modify, redef instead
+# File generated by svg_to_png_and_nit, do not modify, redef instead
import mnit::image_set
-class {{{name}}}
+class {{{document.nit_class_name}}}
super ImageSet
+ private var main_image: Image is noinit
"""
add_all attributes
add """
redef fun load_all(app: App)
do
+ main_image = app.load_image(\"images/{{{document.drawing_name}}}.png\")
"""
add_all load_exprs
add """
end
end
+# Nit module targeting the Gamnit framework
+#
+# Gamnit's `Texture` already manage the lazy loading, no need to do it here.
+class GamnitImageSetSrc
+ super ImageSetSrc
+
+ private fun attributes: Array[String]
+ do
+ # Separate the images from the arrays of images
+ var single_images = new Array[Image]
+ var arrays_of_images = new HashMap[String, Array[Image]]
+
+ for image in images do
+ var nit_name = image.name
+ var last_char = nit_name.chars.last
+ if last_char.to_s.is_numeric then
+
+ # Is an array
+ nit_name = nit_name.substring(0, nit_name.length-1)
+ if not arrays_of_images.keys.has(nit_name) then
+ # Create a new array
+ var array = new Array[Image]
+ arrays_of_images[nit_name] = array
+ end
+
+ arrays_of_images[nit_name].add image
+ else
+ # Is a single image
+ single_images.add image
+ end
+ end
+
+ # Attributes of the class
+ var attributes = new Array[String]
+ attributes.add "\tprivate var main_image = new Texture(\"images/{document.drawing_name}.png\")\n"
+
+ # Add single images to Nit source file
+ for image in single_images do
+ # Adapt coordinates to new top left and scale
+ var coordinates = document.coordinates(image)
+
+ attributes.add "\tvar {image.name}: Texture = main_image.subtexture({coordinates})\n"
+ end
+
+ # Add array of images too
+ for name, images in arrays_of_images do
+
+ var lines = new Array[String]
+ for image in images do
+ var coordinates = document.coordinates(image)
+ lines.add "\t\tmain_image.subtexture({coordinates})"
+ end
+
+ attributes.add """
+ var {{{name}}} = new Array[Texture].with_items(
+{{{lines.join(",\n")}}})
+"""
+ end
+
+ return attributes
+ end
+
+ redef fun rendering
+ do
+ add """
+# File generated by svg_to_png_and_nit, do not modify, redef instead
+
+import gamnit::display
+
+class {{{document.nit_class_name}}}
+
+"""
+ add_all attributes
+ add """
+end
+"""
+ end
+end
+
redef class Int
- fun adapt(d: Int, scale: Float): Int
+ # Magic adaption of this coordinates to the given `margin` and `scale`
+ fun adapt(margin: Int, scale: Float): Int
do
- var corrected = self-d
+ var corrected = self-margin
return (corrected.to_f*scale).to_i
end
+ # The first power of to equal or greater than `self`
fun next_pow2: Int
do
var p = 2
end
end
-var opt_out_src = new OptionString("Path to output source file", "--src", "-s")
+var opt_out_src = new OptionString("Path to output source file (folder or file)", "--src", "-s")
var opt_assets = new OptionString("Path to assert dir where to put PNG files", "--assets", "-a")
-var opt_scale = new OptionFloat("Apply scaling to exported images (defaut at 1.0 of 90dpi)", 1.0, "--scale", "-x")
+var opt_scale = new OptionFloat("Apply scaling to exported images (default at 1.0 of 90dpi)", 1.0, "--scale", "-x")
+var opt_gamnit = new OptionBool("Target the Gamnit framework (by default it targets Mnit)", "--gamnit", "-g")
+var opt_pow2 = new OptionBool("Round the image size to the next power of 2", "--pow2")
var opt_help = new OptionBool("Print this help message", "--help", "-h")
var opt_context = new OptionContext
-opt_context.add_option(opt_out_src, opt_assets, opt_scale, opt_help)
+opt_context.add_option(opt_out_src, opt_assets, opt_scale, opt_gamnit, opt_pow2, opt_help)
opt_context.parse(args)
var rest = opt_context.rest
var src_path = opt_out_src.value
if src_path == null then src_path = "src"
-if not src_path.file_exists then
+if not src_path.file_exists and src_path.file_extension != "nit" then
stderr.write "Source dir '{src_path}' does not exist (use --src)\n"
exit 1
end
var scale = opt_scale.value
-var arrays_of_images = new Array[String]
-
for drawing in drawings do
var drawing_name = drawing.basename(".svg")
while not proc.eof do
var line = proc.read_line
var words = line.split(",")
-
+
if words.length == 5 then
var id = words[0]
end
proc.close
- # Nit class
- var nit_class_name = drawing_name.chars.first.to_s.to_upper + drawing_name.substring_from(1) + "Images"
- var nit_src = new ImageSetSrc(nit_class_name)
- nit_src.attributes.add "\tprivate var main_image: Image is noinit\n"
- nit_src.load_exprs.add "\t\tmain_image = app.load_image(\"images/{drawing_name}.png\")\n"
# Sort images by name, it prevents Array errors and looks better
alpha_comparator.sort(images)
- # Add images to Nit source file
- for image in images do
- # Adapt coordinates to new top left and scale
- var x = image.x.adapt(min_x, scale)
- var y = image.y.adapt(min_y, scale)
- var w = (image.w.to_f*scale).to_i
- var h = (image.h.to_f*scale).to_i
+ var document = new Document(drawing_name, scale, min_x, max_x, min_y, max_y)
- var nit_name = image.name
- var last_char = nit_name.chars.last
- if last_char.to_s.is_numeric then
- # Array of images
- # TODO support more than 10 images in an array
-
- nit_name = nit_name.substring(0, nit_name.length-1)
- if not arrays_of_images.has(nit_name) then
- # Create class attribute to store Array
- arrays_of_images.add(nit_name)
- nit_src.attributes.add "\tvar {nit_name} = new Array[Image]\n"
- end
- nit_src.load_exprs.add "\t\t{nit_name}.add(main_image.subimage({x}, {y}, {w}, {h}))\n"
- else
- # Single image
- nit_src.attributes.add "\tvar {nit_name}: Image is noinit\n"
- nit_src.load_exprs.add "\t\t{nit_name} = main_image.subimage({x}, {y}, {w}, {h})\n"
- end
+ # Nit class
+ var nit_src: ImageSetSrc
+ if opt_gamnit.value then
+ nit_src = new GamnitImageSetSrc(document, images)
+ else
+ nit_src = new MnitImageSetSrc(document, images)
+ end
+
+ if not src_path.file_extension == "nit" then
+ src_path = src_path/drawing_name+".nit"
end
# Output source file
- var src_file = new FileWriter.open("{src_path}/{drawing_name}.nit")
+ var src_file = new FileWriter.open(src_path)
nit_src.write_to(src_file)
src_file.close
- # Find closest power of 2
- var dx = max_x - min_x
- max_x = dx.next_pow2 + min_x
+ # Find next power of 2
+ if opt_pow2.value then
+ var dx = max_x - min_x
+ max_x = dx.next_pow2 + min_x
- var dy = max_y - min_y
- max_y = dy.next_pow2 + min_y
+ var dy = max_y - min_y
+ max_y = dy.next_pow2 + min_y
+ end
# Inkscape's --export-area inverts the Y axis. It uses the lower left corner of
# the drawing area where as queries return coordinates from the top left.
--- /dev/null
+# Welcome to NitRPG!
+
+NitRPG is a Role Playing Game that takes place on [GitHub](https://github.com/).
+
+In NitRPG, GitHub users are represented by players that battle on repo for
+nitcoins and glory.
+
+## Features
+
+* Auto-update with GitHub hooks
+* Display repo statistics
+* Display players statsitics
+* Repo actions are rewarded by nitcoins
+* Players can unlock achievements
+
+## How to install
+
+From the `nit` root:
+
+~~~bash
+> cd contrib/nitrpg
+> make
+~~~
+
+### Configuring the GitHub hook
+
+NitRPG needs you to add a new GitHub hook on your repo to keep the game
+`listener` up-to-date automatically.
+
+Hook configuration:
+
+* **Payload URL**: URL and port to the listener (ex: `http://yourdomain.com:8080`)
+* **Content type**: `application/json`
+* **Wich events**: `Send me everything`
+
+Be sure to set the hook as `Active` in the GitHub admin panel.
+
+### Starting the listener
+
+The `listener` program is used to listen to GitHub hooks and update game data.
+It should alwaysd be up if you want your game to be kept up-to-date.
+
+To run the listener:
+
+ ./listener <host> <port>
+
+The arguments `host` and `port` must correspond to what you entered in your
+GitHub hook settings.
+
+### Starting the web server
+
+The `web` program act as a [nitcorn](http://nitlanguage.org/doc/stdlib/module_nitcorn__nitcorn.html) webserver that display the game results live.
+
+To run the webserver:
+
+ ./web <host> <port> <root>
+
+The arguments `host` and `port` must correspond to what you entered in your
+GitHub hook settings.
+The `root` argument is used to specify the path from the domain url to the
+NitRPG root.
+
+For example, if NitRPG is installed in `yourdomain.com/nitrpg`:
+
+ ./web localhost 3000 "/nitrpg"
+
+Leave it empty if NitRPG is installed at the root of the domain:
+
+ ./web localhost 3000 ""
+
+The webserver can then be accessed at `http://yourdomain.com:3000/nitrpg/`.
+
+## RoadMap
+
+NitRPG stills under heavy development.
+Incomming features contain (but are not limited to):
+
+* Periodized stats (weekly, monthly, yearly, overall)
+* Display graphs with stats
+* More achievements
+* Shop: exchange Nitcoins against glorifying items
+
+You can suggest new achievements or ideas in the
+[NitRPG RoadMap Issue](https://github.com/privat/nit/issues/1161).
redef var reward = 10000
redef var threshold = 10000
end
+
+#####################
+### Issue Comments
+#####################
+
+# Unlock achievement after X issue comments.
+#
+# Used to factorize behavior.
+abstract class PlayerXComments
+ super AchievementReactor
+
+ # Number of comments required to unlock the achievement.
+ var threshold: Int is noinit
+
+ redef fun react_event(game, event) do
+ if not event isa IssueCommentEvent then return
+ if not event.action == "created" then return
+ var player = event.comment.user.player(game)
+ if player.stats["comments"] == threshold then
+ var a = new_achievement(game)
+ player.unlock_achievement(a, event)
+ end
+ end
+end
+
+# Player author his first comment in issues.
+class Player1Comment
+ super PlayerXComments
+
+ redef var id = "player_1_comment"
+ redef var name = "From lurker to member"
+ redef var desc = "Comment on an issue."
+ redef var reward = 10
+ redef var threshold = 1
+end
+
+# Player author 100 issue comments.
+class Player100Comments
+ super PlayerXComments
+
+ redef var id = "player_100_comments"
+ redef var name = "Chatter"
+ redef var desc = "Comment 100 times on issues."
+ redef var reward = 100
+ redef var threshold = 100
+end
+
+# Player author 1000 issue comments.
+class Player1KComments
+ super PlayerXComments
+
+ redef var id = "player_1000__comments"
+ redef var name = "You sir, talk a lot!"
+ redef var desc = "Comment 1000 times on issues."
+ redef var reward = 1000
+ redef var threshold = 1000
+end
+
+# Ping @privat in a comment.
+class PlayerPingGod
+ super AchievementReactor
+
+ redef var id = "player_ping_god"
+ redef var name = "Ping god"
+ redef var desc = "Ping the owner of the repo for the first time."
+ redef var reward = 50
+
+ redef fun react_event(game, event) do
+ if not event isa IssueCommentEvent then return
+ var owner = game.repo.owner.login
+ if event.comment.body.has("@{owner}".to_re) then
+ var player = event.comment.user.player(game)
+ var a = new_achievement(game)
+ player.unlock_achievement(a, event)
+ end
+ end
+end
+
+# Give your first +1
+class PlayerFirstReview
+ super AchievementReactor
+
+ redef var id = "player_first_review"
+ redef var name = "First +1"
+ redef var desc = "Give a +1 for the first time."
+ redef var reward = 10
+
+ redef fun react_event(game, event) do
+ if not event isa IssueCommentEvent then return
+ # FIXME use a more precise way to locate reviews
+ if event.comment.has_ok_review then
+ var player = event.comment.user.player(game)
+ var a = new_achievement(game)
+ player.unlock_achievement(a, event)
+ end
+ end
+end
+
+# Talk about nitcoin in issue comments.
+class PlayerSaysNitcoin
+ super AchievementReactor
+
+ redef var id = "player_says_nitcoin"
+ redef var name = "Talking about money"
+ redef var desc = "Say something about nitcoins in a comment."
+ redef var reward = 10
+
+ redef fun react_event(game, event) do
+ if not event isa IssueCommentEvent then return
+ if event.comment.body.has("(n|N)itcoin".to_re) then
+ var player = event.comment.user.player(game)
+ var a = new_achievement(game)
+ player.unlock_achievement(a, event)
+ end
+ end
+end
# utils
+# Sort games by descending number of players.
+#
+# The first in the list is the game with the more players.
+class GamePlayersComparator
+ super Comparator
+
+ redef type COMPARED: Game
+
+ redef fun compare(a, b) do
+ return b.load_players.length <=> a.load_players.length
+ end
+end
+
# Sort players by descending number of nitcoins.
#
# The first in the list is the player with the more of nitcoins.
l.add_reactor(new Player1Pull, new Player100Pulls, new Player1KPulls)
l.add_reactor(new Player1Commit, new Player100Commits, new Player1KCommits)
l.add_reactor(new IssueAboutNitdoc, new IssueAboutFFI)
+l.add_reactor(new Player1Comment, new Player100Comments, new Player1KComments)
+l.add_reactor(new PlayerPingGod, new PlayerFirstReview, new PlayerSaysNitcoin)
print "Listening events on {host}:{port}"
l.listen
end
end
end
+
+redef class IssueCommentEvent
+
+ # Count posted comments
+ redef fun react_stats_event(game) do
+ if action == "created" then
+ var player = comment.user.player(game)
+ game.stats.inc("comments")
+ player.stats.inc("comments")
+ # FIXME use a more precise way to locate reviews
+ if comment.has_ok_review then
+ game.stats.inc("reviews")
+ player.stats.inc("reviews")
+ end
+ game.save
+ player.save
+ end
+ end
+end
+
+redef class IssueComment
+ # Does this comment contain a "+1"?
+ fun has_ok_review: Bool do return body.has("\\+1\\b".to_re)
+end
module panels
import templates_events
+import markdown
# A panel can be displayed in a html page.
#
end
+# A panel that display a markdown content rendered as HTML.
+class MDPanel
+ super Panel
+
+ # Markdown text to display.
+ var text: String
+
+ redef fun rendering do
+ add """<div class="panel">
+ <div class="panel-body">{{{text.md_to_html}}}</div>
+ </div>"""
+ end
+end
+
+# Display a list of active game.
+#
+# Used for NitRPG homepage.
+class GamesShortListPanel
+ super Panel
+
+ # Root url used for links.
+ var root_url: String
+
+ # List of NitRPG games to display.
+ var games: Array[Game]
+
+ redef fun render_title do
+ add "<span class=\"glyphicon glyphicon-home\"></span> "
+ add "<a href=\"{root_url}/games\">Active games</a>"
+ end
+
+ redef fun render_body do
+ if games.is_empty then
+ add "<em>No game yet...</em>"
+ return
+ end
+ var sorted = games.to_a
+ (new GamePlayersComparator).sort(sorted)
+ for game in sorted do
+ add "{game.link} ({game.load_players.length} players)<br>"
+ end
+ end
+end
+
+# A panel that display a list of player in a repo.
+class GamesListPanel
+ super GamesShortListPanel
+ super TablePanel
+
+ redef fun render_title do
+ add "<span class=\"glyphicon glyphicon-home\"></span> "
+ add "<a href=\"{root_url}/games\">Active games</a>"
+ end
+
+ redef fun render_body do
+ if games.is_empty then
+ add "<div class=\"panel-body\">"
+ add "<em>No player yet...</em>"
+ add "</div>"
+ return
+ end
+ var sorted = games.to_a
+ (new GamePlayersComparator).sort(sorted)
+ add """<table class="table table-striped table-hover">
+ <tr>
+ <th>Game</th>
+ <th>Players</th>
+ <th>Achievements</th>
+ </tr>"""
+ for game in sorted do
+ add "<tr>"
+ add " <td>{game.link}</td>"
+ add " <td>{game.load_players.length}</td>"
+ add " <td>{game.load_achievements.length}</td>"
+ add "</tr>"
+ end
+ add "</table>"
+ end
+end
+
# A panel that display repo statistics.
class GameStatusPanel
super Panel
rsp.body = page.write_to_string
return rsp
end
+
+ # Returns the game with `name` or null if no game exists with this name.
+ fun load_game(name: String): nullable Game do
+ var repo = api.load_repo(name)
+ if api.was_error or repo == null then return null
+ var game = new Game(api, repo)
+ game.root_url = root_url
+ return game
+ end
+
+ # Returns the list of saved games from NitRPG data.
+ fun load_games: Array[Game] do
+ var res = new Array[Game]
+ var rpgdir = "nitrpg_data"
+ if not rpgdir.file_exists then return res
+ for user in rpgdir.files do
+ for repo in "{rpgdir}/{user}".files do
+ var game = load_game("{user}/{repo}")
+ if game != null then res.add game
+ end
+ end
+ return res
+ end
+end
+
+# Repo overview page.
+class RpgHome
+ super RpgAction
+
+ # Response page stub.
+ var page: NitRpgPage is noinit
+
+ redef fun answer(request, url) do
+ var readme = load_readme
+ var games = load_games
+ var response = new HttpResponse(200)
+ page = new NitRpgPage(root_url)
+ page.side_panels.add new GamesShortListPanel(root_url, games)
+ page.flow_panels.add new MDPanel(readme)
+ response.body = page.write_to_string
+ return response
+ end
+
+ # Load the string content of the nitrpg readme file.
+ private fun load_readme: String do
+ var readme = "README.md"
+ if not readme.file_exists then
+ return "Unable to locate README file."
+ end
+ var file = new FileReader.open(readme)
+ var text = file.read_all
+ file.close
+ return text
+ end
+end
+
+# Display the list of active game.
+class ListGames
+ super RpgAction
+
+ # Response page stub.
+ var page: NitRpgPage is noinit
+
+ redef fun answer(request, url) do
+ var games = load_games
+ var response = new HttpResponse(200)
+ page = new NitRpgPage(root_url)
+ page.breadcrumbs = new Breadcrumbs
+ page.breadcrumbs.add_link(root_url / "games", "games")
+ page.flow_panels.add new GamesListPanel(root_url, games)
+ response.body = page.write_to_string
+ return response
+ end
end
# An action that require a game.
var owner = request.param("owner")
var repo_name = request.param("repo")
if owner == null or repo_name == null then
- var msg = "Bad request: should look like /repos/:owner/:repo."
+ var msg = "Bad request: should look like /games/:owner/:repo."
return bad_request(msg)
end
- var repo = new Repo(api, "{owner}/{repo_name}")
- game = new Game(api, repo)
- game.root_url = root_url
- if api.was_error then
+ var game = load_game("{owner}/{repo_name}")
+ if game == null then
var msg = api.last_error.message
return bad_request("Repo Error: {msg}")
end
+ self.game = game
var response = new HttpResponse(200)
page = new NitRpgPage(root_url)
page.side_panels.add new GameStatusPanel(game)
# From where to start the display of events related lists.
var list_from = 0
+
+ # TODO should also check 201, 203 ...
+ private fun is_response_error(response: HttpResponse): Bool do
+ return response.status_code != 200
+ end
end
# Repo overview page.
redef fun answer(request, url) do
var rsp = prepare_response(request, url)
+ if is_response_error(rsp) then return rsp
page.side_panels.add new ShortListPlayersPanel(game)
page.flow_panels.add new PodiumPanel(game)
page.flow_panels.add new EventListPanel(game, list_limit, list_from)
redef fun answer(request, url) do
var rsp = prepare_response(request, url)
+ if is_response_error(rsp) then return rsp
page.breadcrumbs.add_link(game.url / "players", "players")
page.flow_panels.add new ListPlayersPanel(game)
rsp.body = page.write_to_string
redef fun answer(request, url) do
var rsp = prepare_response(request, url)
+ if is_response_error(rsp) then return rsp
var name = request.param("player")
if name == null then
var msg = "Bad request: should look like /:owner/:repo/:players/:name."
redef fun answer(request, url) do
var rsp = prepare_response(request, url)
+ if is_response_error(rsp) then return rsp
page.breadcrumbs.add_link(game.url / "achievements", "achievements")
page.flow_panels.add new AchievementsListPanel(game)
rsp.body = page.write_to_string
redef fun answer(request, url) do
var rsp = prepare_response(request, url)
+ if is_response_error(rsp) then return rsp
var name = request.param("achievement")
if name == null then
var msg = "Bad request: should look like /:owner/:repo/achievements/:achievement."
vh.routes.add new Route("/games/:owner/:repo/achievements/:achievement", new AchievementHome(root))
vh.routes.add new Route("/games/:owner/:repo/achievements", new ListAchievements(root))
vh.routes.add new Route("/games/:owner/:repo", new RepoHome(root))
+vh.routes.add new Route("/games", new ListGames(root))
+vh.routes.add new Route("/", new RpgHome(root))
var fac = new HttpFactory.and_libevent
fac.config.virtual_hosts.add vh
var ssection = new TplSection.with_title("projects", "Projects")
for mproject in mprojects do
var sarticle = mproject.tpl_article
- sarticle.subtitle = mproject.tpl_declaration
+ sarticle.subtitle = mproject.html_declaration
sarticle.content = mproject.tpl_definition
var mdoc = mproject.mdoc_or_fallback
if mdoc != null then
tpl.title = "Index"
# modules list
for mmodule in modules_list(v, doc) do
- tpl.modules.add mmodule.tpl_link
+ tpl.modules.add mmodule.html_link
end
# classes list
for mclass in classes_list(v, doc) do
- tpl.classes.add mclass.tpl_link
+ tpl.classes.add mclass.html_link
end
# properties list
for mproperty in mprops_list(v, doc) do
var m = new Template
- m.add mproperty.intro.tpl_link
+ m.add mproperty.intro.html_link
m.add " ("
- m.add mproperty.intro.mclassdef.mclass.tpl_link
+ m.add mproperty.intro.mclassdef.mclass.html_link
m.add ")"
tpl.props.add m
end
end
var lnk = new Template
lnk.add new TplLabel.with_classes(classes)
- lnk.add def.tpl_link
+ lnk.add def.html_link
return new TplListItem.with_content(lnk)
end
end
end
var lnk = new Template
lnk.add new TplLabel.with_classes(classes)
- lnk.add def.tpl_link
+ lnk.add def.html_link
return new TplListItem.with_content(lnk)
end
end
end
var lnk = new Template
lnk.add new TplLabel.with_classes(classes)
- lnk.add mprop.tpl_anchor
+ lnk.add mprop.html_link_to_anchor
return new TplListItem.with_content(lnk)
end
redef class MPropertyPage
redef fun init_title(v, doc) do
- title = "{mentity.html_name}{mentity.tpl_signature.write_to_string}"
+ title = "{mentity.html_name}{mentity.html_short_signature.write_to_string}"
end
redef fun init_topmenu(v, doc) do
var section = new TplSection("top")
var mentity = page.mentity
section.title = mentity.html_name
- section.subtitle = mentity.tpl_declaration
+ section.subtitle = mentity.html_declaration
# FIXME ugly hack to avoid diff
if mentity isa MGroup and mentity.is_root then
section.title = mentity.mproject.html_name
- section.subtitle = mentity.mproject.tpl_declaration
+ section.subtitle = mentity.mproject.html_declaration
else if mentity isa MProperty then
- section.title = "{mentity.html_name}{mentity.intro.tpl_signature.write_to_string}"
- section.subtitle = mentity.tpl_namespace
+ section.title = "{mentity.html_name}{mentity.intro.html_signature.write_to_string}"
+ section.subtitle = mentity.html_namespace
section.summary_title = mentity.html_name
end
render(v, doc, page, section)
title.add "from "
section.summary_title = "from {mmodule.html_name}"
end
- title.add mmodule.tpl_namespace
+ title.add mmodule.html_namespace
section.title = title
end
private fun render_concern_other(page: MEntityPage, section: TplSection, mmodule: MModule) do
var title = new Template
title.add "in "
- title.add mmodule.tpl_namespace
+ title.add mmodule.html_namespace
section.title = title
section.summary_title = "in {mmodule.html_name}"
end
else if mentity isa MPropDef then
article.source_link = v.tpl_showsource(mentity.location)
end
- # article.subtitle = mentity.tpl_declaration
+ # article.subtitle = mentity.html_declaration
# FIXME diff hack
if mentity isa MProperty then
# intro title
- var ns = mentity.intro.mclassdef.mmodule.tpl_namespace
+ var ns = mentity.intro.mclassdef.mmodule.html_namespace
var section = new TplSection("intro")
var title = new Template
title.add "Introduction in "
# FIXME hideous hacks...
if mentity isa MModule then
article = mentity.tpl_article
- article.subtitle = mentity.tpl_declaration
+ article.subtitle = mentity.html_declaration
article.content = mentity.tpl_definition
else if mentity isa MClass then
article = make_mclass_article(v, page)
article = make_mpropdef_article(v, doc, page)
else
article = mentity.tpl_article
- article.subtitle = mentity.tpl_declaration
+ article.subtitle = mentity.html_declaration
if mentity isa MPropDef then
article.source_link = v.tpl_showsource(mentity.location)
end
private fun make_mclass_article(v: RenderHTMLPhase, page: MEntityPage): TplArticle do
var article = mentity.tpl_article
- article.subtitle = mentity.tpl_namespace
+ article.subtitle = mentity.html_namespace
article.content = null
return article
end
end
var title = new Template
title.add "in "
- title.add mclassdef.mmodule.tpl_namespace
+ title.add mclassdef.mmodule.html_namespace
article.subtitle = title
return article
end
title.add mprop.tpl_icon
title.add "<span id='{mpropdef.nitdoc_id}'></span>"
if mpropdef.is_intro then
- title.add mprop.tpl_link
- title.add mprop.intro.tpl_signature
+ title.add mprop.html_link
+ title.add mprop.intro.html_signature
else
var cls_url = mprop.intro.mclassdef.mclass.nitdoc_url
var def_url = "{cls_url}#{mprop.nitdoc_id}"
article.title = title
article.title_classes.add "signature"
article.summary_title = "{mprop.html_name}"
- article.subtitle = mpropdef.tpl_namespace
+ article.subtitle = mpropdef.html_namespace
if mpropdef.mdoc_or_fallback != null then
article.content = mpropdef.mdoc_or_fallback.tpl_comment
end
import doc_base
import doc_down
import html_components
+import html::bootstrap
import ordered_tree
redef class Location
# * MPropdef: `foo(e)`
var html_name: String is lazy do return name.html_escape
- # A template link to the mentity `nitdoc_id`
- fun tpl_anchor: TplLink do
- var tpl = new TplLink("#{nitdoc_id}", html_name)
+ # Returns a Link to the mentity `html_url`.
+ #
+ # Example: `<a href="html_url" title="mdoc.short_comment">html_short_name</a>
+ var html_link: Link is lazy do
+ var tpl = new Link(nitdoc_url, html_name)
var mdoc = mdoc_or_fallback
if mdoc != null then
tpl.title = mdoc.short_comment
return tpl
end
- # A template link to the mentity `nitdoc_url`
- fun tpl_link: TplLink do
- var tpl = new TplLink(nitdoc_url, html_name)
+ # Returns a Link to the mentity `nitdoc_id`.
+ #
+ # Example: `<a href="#nitdoc_id" title="mdoc.short_comment">html_short_name</a>
+ fun html_link_to_anchor: Link do
+ var tpl = new Link("#{nitdoc_id}", html_name)
var mdoc = mdoc_or_fallback
if mdoc != null then
tpl.title = mdoc.short_comment
return tpl
end
+ # Returns the list of keyword used in `self` declaration.
+ fun html_modifiers: Array[String] is abstract
+
+ # Returns the complete MEntity declaration decorated with HTML.
+ #
+ # * MProject: `project foo`
+ # * MGroup: `group foo`
+ # * MModule: `module foo`
+ # * MClass: `private abstract class Foo[E: Object]`
+ # * MClassDef: `redef class Foo[E]`
+ # * MProperty: `private fun foo(e: Object): Int`
+ # * MPropdef: `redef fun foo(e)`
+ fun html_declaration: Template do
+ var tpl = new Template
+ tpl.add "<span>"
+ tpl.add html_modifiers.join(" ")
+ tpl.add " "
+ tpl.add html_link
+ tpl.add "</span>"
+ return tpl
+ end
+
+ # Returns `self` namespace decorated with HTML links.
+ #
+ # * MProject: `mproject`
+ # * MGroup: `mproject(::group)`
+ # * MModule: `mgroup::mmodule`
+ # * MClass: `mproject::mclass`
+ # * MClassDef: `mmodule::mclassdef`
+ # * MProperty: `mclass::mprop`
+ # * MPropdef: `mclassdef:mpropdef`
+ fun html_namespace: Template is abstract
+
# A template article that briefly describe the entity
fun tpl_short_article: TplArticle do
var tpl = tpl_article
fun tpl_article: TplArticle do
var tpl = new TplArticle.with_title(nitdoc_id, tpl_title)
tpl.title_classes.add "signature"
- tpl.subtitle = tpl_namespace
+ tpl.subtitle = html_namespace
tpl.summary_title = html_name
return tpl
end
- # A template signature that contains modifiers and parameters
- fun tpl_declaration: Template is abstract
-
- # A template namespace
- fun tpl_namespace: Template is abstract
-
# A template definition of the mentity
# include name, sysnopsys, comment and namespace
fun tpl_definition: TplDefinition is abstract
fun tpl_list_item: TplListItem do
var lnk = new Template
lnk.add new TplLabel.with_classes(tpl_css_classes)
- lnk.add tpl_link
+ lnk.add html_link
var mdoc = mdoc_or_fallback
if mdoc != null then
lnk.add ": "
fun tpl_title: Template do
var title = new Template
title.add tpl_icon
- title.add tpl_namespace
+ title.add html_namespace
return title
end
# Return a li element for `self` that can be displayed in a concern list
private fun tpl_concern_item: TplListItem do
var lnk = new Template
- lnk.add tpl_anchor
+ lnk.add html_link_to_anchor
var mdoc = mdoc_or_fallback
if mdoc != null then
lnk.add ": "
redef class MProject
redef var nitdoc_id = name.to_cmangle is lazy
redef fun nitdoc_url do return root.nitdoc_url
-
- redef fun tpl_declaration do
- var tpl = new Template
- tpl.add "<span>project "
- tpl.add tpl_link
- tpl.add "</span>"
- return tpl
- end
-
- redef fun tpl_namespace do return tpl_link
+ redef var html_modifiers = ["project"]
+ redef fun html_namespace do return html_link
redef fun tpl_definition do
var tpl = new TplDefinition
end
redef fun nitdoc_url do return "group_{nitdoc_id}.html"
+ redef var html_modifiers = ["group"]
- redef fun tpl_namespace do
+ # Depends if `self` is root or not.
+ #
+ # * If root `mproject`.
+ # * Else `mproject::self`.
+ redef fun html_namespace do
var tpl = new Template
- tpl.add mproject.tpl_namespace
+ tpl.add mproject.html_namespace
if mproject.root != self then
tpl.add "::"
- tpl.add tpl_link
+ tpl.add html_link
end
return tpl
end
- redef fun tpl_declaration do
- var tpl = new Template
- tpl.add "<span>group "
- tpl.add tpl_link
- tpl.add "</span>"
- return tpl
- end
-
redef fun tpl_definition do
var tpl = new TplDefinition
var mdoc = mdoc_or_fallback
end
redef fun nitdoc_url do return "module_{nitdoc_id}.html"
+ redef var html_modifiers = ["module"]
- redef fun tpl_declaration do
- var tpl = new Template
- tpl.add "<span>module "
- tpl.add tpl_namespace
- tpl.add "</span>"
- return tpl
- end
-
- redef fun tpl_namespace do
+ # Depends if `self` belongs to a MGroup.
+ #
+ # * If mgroup `mgroup::self`.
+ # * Else `self`.
+ redef fun html_namespace do
var tpl = new Template
if mgroup != null then
- tpl.add mgroup.tpl_namespace
+ tpl.add mgroup.html_namespace
tpl.add "::"
end
- tpl.add tpl_link
+ tpl.add html_link
return tpl
end
return tpl.write_to_string
end
- redef fun tpl_declaration do return intro.tpl_declaration
- redef fun tpl_definition do return intro.tpl_definition
+ redef fun html_modifiers do return intro.html_modifiers
+ redef fun html_declaration do return intro.html_declaration
- redef fun tpl_namespace do
+ # Returns `mproject::self`.
+ redef fun html_namespace do
var tpl = new Template
- tpl.add intro_mmodule.mgroup.mproject.tpl_namespace
+ tpl.add intro_mmodule.mgroup.mproject.html_namespace
tpl.add "::<span>"
- tpl.add tpl_link
+ tpl.add html_link
tpl.add "</span>"
return tpl
end
+ # Returns `intro.html_short_signature`.
+ fun html_short_signature: Template do return intro.html_short_signature
+
+ # Returns `intro.html_signature`.
+ fun html_signature: Template do return intro.html_signature
+
+ redef fun tpl_definition do return intro.tpl_definition
+
redef fun tpl_title do
var title = new Template
title.add tpl_icon
- title.add tpl_link
+ title.add html_link
return title
end
redef fun tpl_icon do return intro.tpl_icon
-
- fun tpl_signature: Template do
- var tpl = new Template
- if arity > 0 then
- tpl.add "["
- var parameter_names = new Array[String]
- for p in mparameters do
- parameter_names.add(p.html_name)
- end
- tpl.add parameter_names.join(", ")
- tpl.add "]"
- end
- return tpl
- end
-
redef fun tpl_css_classes do return intro.tpl_css_classes
end
redef class MClassDef
redef var nitdoc_id = "{mmodule.nitdoc_id}__{name.to_cmangle}" is lazy
redef fun nitdoc_url do return "{mclass.nitdoc_url}#{nitdoc_id}"
-
redef fun mdoc_or_fallback do return mdoc or else mclass.mdoc_or_fallback
- redef fun tpl_namespace do
+ # Depends if `self` is an intro or not.
+ #
+ # * If intro contains the visibility and kind.
+ # * If redef contains the `redef` keyword and kind.
+ redef fun html_modifiers do
+ var res = new Array[String]
+ if not is_intro then
+ res.add "redef"
+ else
+ if mclass.visibility != public_visibility then
+ res.add mclass.visibility.to_s
+ end
+ end
+ res.add mclass.kind.to_s
+ return res
+ end
+
+ # Depends if `self` is an intro or not.
+ #
+ # For intro: `private abstract class Foo[E: Object]`
+ # For redef: `redef class Foo[E]`
+ # TODO change the implementation to correspond to the comment.
+ redef fun html_declaration do
var tpl = new Template
- tpl.add mmodule.tpl_namespace
+ tpl.add "<span>"
+ tpl.add html_modifiers.join(" ")
+ tpl.add " "
+ tpl.add html_link
+ tpl.add html_signature
+ tpl.add "</span>"
+ return tpl
+ end
+
+ # Returns `mmodule::self`
+ redef fun html_namespace do
+ var tpl = new Template
+ tpl.add mmodule.html_namespace
tpl.add "::<span>"
- tpl.add mclass.tpl_link
+ tpl.add mclass.html_link
tpl.add "</span>"
return tpl
end
+ # Returns the MClassDef generic signature without static bounds.
+ fun html_short_signature: Template do
+ var tpl = new Template
+ var mparameters = mclass.mparameters
+ if not mparameters.is_empty then
+ tpl.add "["
+ for i in [0..mparameters.length[ do
+ tpl.add mparameters[i].html_name
+ if i < mparameters.length - 1 then tpl.add ", "
+ end
+ tpl.add "]"
+ end
+ return tpl
+ end
+
+ # Returns the MClassDef generic signature with static bounds.
+ fun html_signature: Template do
+ var tpl = new Template
+ var mparameters = mclass.mparameters
+ if not mparameters.is_empty then
+ tpl.add "["
+ for i in [0..mparameters.length[ do
+ tpl.add "{mparameters[i].html_name}: "
+ tpl.add bound_mtype.arguments[i].html_signature
+ if i < mparameters.length - 1 then tpl.add ", "
+ end
+ tpl.add "]"
+ end
+ return tpl
+ end
+
redef fun tpl_article do
var tpl = new TplArticle(nitdoc_id)
tpl.summary_title = "in {mmodule.html_name}"
- tpl.title = tpl_declaration
+ tpl.title = html_declaration
tpl.title_classes.add "signature"
var title = new Template
title.add "in "
- title.add mmodule.tpl_namespace
+ title.add mmodule.html_namespace
tpl.subtitle = title
var mdoc = mdoc_or_fallback
if mdoc != null then
redef fun tpl_title do
var title = new Template
title.add tpl_icon
- title.add tpl_link
+ title.add html_link
return title
end
- redef fun tpl_declaration do
- var tpl = new Template
- tpl.add tpl_modifiers
- tpl.add tpl_link
- tpl.add tpl_signature
- return tpl
- end
-
- fun tpl_signature: Template do
- var tpl = new Template
- var mparameters = mclass.mparameters
- if not mparameters.is_empty then
- tpl.add "["
- for i in [0..mparameters.length[ do
- tpl.add "{mparameters[i].html_name}: "
- tpl.add bound_mtype.arguments[i].tpl_signature
- if i < mparameters.length - 1 then tpl.add ", "
- end
- tpl.add "]"
- end
- return tpl
- end
-
redef fun tpl_definition do
var tpl = new TplClassDefinition
var mdoc = mdoc_or_fallback
redef class MProperty
redef var nitdoc_id = "{intro_mclassdef.mclass.nitdoc_id}__{name.to_cmangle}" is lazy
redef fun nitdoc_url do return "property_{nitdoc_id}.html"
-
redef fun mdoc_or_fallback do return intro.mdoc
+ redef fun html_modifiers do return intro.html_modifiers
+ redef fun html_declaration do return intro.html_declaration
- redef fun tpl_namespace do
+ # Returns `mclass::self`.
+ redef fun html_namespace do
var tpl = new Template
- tpl.add intro_mclassdef.mclass.tpl_namespace
+ tpl.add intro_mclassdef.mclass.html_namespace
tpl.add "::<span>"
- tpl.add intro.tpl_link
+ tpl.add intro.html_link
tpl.add "</span>"
return tpl
end
- redef fun tpl_declaration do return intro.tpl_declaration
+ # Returns `intro.html_short_signature`.
+ fun html_short_signature: Template do return intro.html_short_signature
- fun tpl_signature: Template do return new Template
+ # Returns `intro.html_signature`.
+ fun html_signature: Template do return intro.html_signature
redef fun tpl_title do return intro.tpl_title
redef class MPropDef
redef var nitdoc_id = "{mclassdef.nitdoc_id}__{name.to_cmangle}" is lazy
redef fun nitdoc_url do return "{mproperty.nitdoc_url}#{nitdoc_id}"
-
redef fun mdoc_or_fallback do return mdoc or else mproperty.mdoc_or_fallback
- redef fun tpl_namespace do
+ # Depends if `self` is an intro or not.
+ #
+ # * If intro contains the visibility and kind.
+ # * If redef contains the `redef` keyword and kind.
+ redef fun html_modifiers do
+ var res = new Array[String]
+ if not is_intro then
+ res.add "redef"
+ else
+ if mproperty.visibility != public_visibility then
+ res.add mproperty.visibility.to_s
+ end
+ end
+ return res
+ end
+
+ # Depends if `self` is an intro or not.
+ #
+ # For intro: `private fun foo(e: Object): Bar is abstract`
+ # For redef: `redef fun foo(e) is cached`
+ # TODO change the implementation to correspond to the comment.
+ redef fun html_declaration do
var tpl = new Template
- tpl.add mclassdef.tpl_namespace
+ tpl.add "<span>"
+ tpl.add html_modifiers.join(" ")
+ tpl.add " "
+ tpl.add html_link
+ tpl.add html_signature
+ tpl.add "</span>"
+ return tpl
+ end
+
+ # Returns `mclassdef::self`
+ redef fun html_namespace do
+ var tpl = new Template
+ tpl.add mclassdef.html_namespace
tpl.add "::"
- tpl.add tpl_link
+ tpl.add html_link
return tpl
end
+ # Returns the MPropdDef signature without static types.
+ fun html_short_signature: Template is abstract
+
+ # Returns the MPropDef signature with static types.
+ fun html_signature: Template is abstract
+
redef fun tpl_article do
var tpl = new TplArticle(nitdoc_id)
tpl.summary_title = "in {mclassdef.html_name}"
var title = new Template
title.add "in "
- title.add mclassdef.tpl_link
+ title.add mclassdef.html_link
tpl.title = title
- tpl.subtitle = tpl_declaration
+ tpl.subtitle = html_declaration
var mdoc = mdoc_or_fallback
if mdoc != null then
tpl.content = mdoc.tpl_comment
return tpl
end
- redef fun tpl_declaration do
- var tpl = new Template
- tpl.add tpl_modifiers
- tpl.add tpl_link
- tpl.add tpl_signature
- return tpl
- end
-
redef fun tpl_css_classes do
var set = new HashSet[String]
if is_intro then set.add "intro"
return tpl
end
- fun tpl_signature: Template do return new Template
-
redef fun tpl_list_item do
var lnk = new Template
lnk.add new TplLabel.with_classes(tpl_css_classes.to_a)
- var anchor = tpl_link
- anchor.href = "{mclassdef.mclass.nitdoc_url}#{mproperty.nitdoc_id}"
+ var atext = html_link.text
+ var ahref = "{mclassdef.mclass.nitdoc_url}#{mproperty.nitdoc_id}"
+ var atitle = html_link.title
+ var anchor = new Link.with_title(ahref, atext, atitle)
lnk.add anchor
var mdoc = mdoc_or_fallback
if mdoc != null then
fun tpl_inheritance_item: TplListItem do
var lnk = new Template
lnk.add new TplLabel.with_classes(tpl_css_classes.to_a)
- lnk.add mclassdef.mmodule.tpl_namespace
+ lnk.add mclassdef.mmodule.html_namespace
lnk.add "::"
- var anchor = mclassdef.tpl_link
- anchor.href = "{mclassdef.mclass.nitdoc_url}#{mproperty.nitdoc_id}"
+ var atext = mclassdef.html_link.text
+ var ahref = "{mclassdef.mclass.nitdoc_url}#{mproperty.nitdoc_id}"
+ var atitle = mclassdef.html_link.title
+ var anchor = new Link.with_title(ahref, atext, atitle)
lnk.add anchor
var mdoc = mdoc_or_fallback
if mdoc != null then
end
redef class MAttributeDef
- redef fun tpl_signature do
+
+ redef fun html_modifiers do
+ var res = super
+ res.add "var"
+ return res
+ end
+
+ redef fun html_short_signature do return new Template
+
+ redef fun html_signature do
var tpl = new Template
if static_mtype != null then
tpl.add ": "
- tpl.add static_mtype.tpl_signature
+ tpl.add static_mtype.html_signature
end
return tpl
end
end
-redef class MMethod
- redef fun tpl_signature do
- var tpl = new Template
- var params = new Array[String]
- for param in intro.msignature.mparameters do
- params.add param.name.html_escape
+redef class MMethodDef
+
+ # FIXME annotation should be handled in their own way
+ redef fun html_modifiers do
+ var res = super
+ if is_abstract then
+ res.add "abstract"
+ else if is_intern then
+ res.add "intern"
end
- if not params.is_empty then
- tpl.add "("
- tpl.add params.join(", ")
- tpl.add ")"
+ if mproperty.is_init then
+ res.add "init"
+ else
+ res.add "fun"
end
- return tpl
+ return res
end
-end
-redef class MMethodDef
- redef fun tpl_signature do return msignature.tpl_signature
+ redef fun html_short_signature do return msignature.html_short_signature
+ redef fun html_signature do return msignature.html_signature
end
redef class MVirtualTypeProp
- redef fun tpl_link do return mvirtualtype.tpl_link
- redef fun tpl_signature do return tpl_link
+ redef fun html_link do return mvirtualtype.html_link
end
redef class MVirtualTypeDef
- redef fun tpl_signature do
+
+ redef fun html_modifiers do
+ var res = super
+ res.add "type"
+ return res
+ end
+
+ redef fun html_short_signature do return new Template
+
+ redef fun html_signature do
var tpl = new Template
if bound == null then return tpl
tpl.add ": "
- tpl.add bound.tpl_signature
+ tpl.add bound.html_signature
return tpl
end
end
redef class MType
- fun tpl_signature: Template is abstract
+ # Returns the signature of this type whithout bounds.
+ fun html_short_signature: Template is abstract
+
+ # Returns the signature of this type.
+ fun html_signature: Template is abstract
end
redef class MClassType
- redef fun tpl_link do return mclass.tpl_link
- redef fun tpl_signature do return tpl_link
+ redef fun html_link do return mclass.html_link
+ redef fun html_short_signature do return html_link
+ redef fun html_signature do return html_link
end
redef class MNullableType
- redef fun tpl_signature do
+
+ redef fun html_short_signature do
+ var tpl = new Template
+ tpl.add "nullable "
+ tpl.add mtype.html_short_signature
+ return tpl
+ end
+
+ redef fun html_signature do
var tpl = new Template
tpl.add "nullable "
- tpl.add mtype.tpl_signature
+ tpl.add mtype.html_signature
return tpl
end
end
redef class MGenericType
- redef fun tpl_signature do
+ redef fun html_short_signature do
+ var lnk = html_link
var tpl = new Template
- var lnk = tpl_link
- lnk.text = mclass.name.html_escape
- tpl.add lnk
+ tpl.add new Link.with_title(lnk.href, mclass.name.html_escape, lnk.title)
tpl.add "["
for i in [0..arguments.length[ do
- tpl.add arguments[i].tpl_signature
+ tpl.add arguments[i].html_short_signature
+ if i < arguments.length - 1 then tpl.add ", "
+ end
+ tpl.add "]"
+ return tpl
+ end
+
+ redef fun html_signature do
+ var lnk = html_link
+ var tpl = new Template
+ tpl.add new Link.with_title(lnk.href, mclass.name.html_escape, lnk.title)
+ tpl.add "["
+ for i in [0..arguments.length[ do
+ tpl.add arguments[i].html_signature
if i < arguments.length - 1 then tpl.add ", "
end
tpl.add "]"
end
redef class MParameterType
- redef fun tpl_link do
- return new TplLink.with_title("{mclass.nitdoc_url}#FT_{name.to_cmangle}", name, "formal type")
+ redef fun html_link do
+ return new Link.with_title("{mclass.nitdoc_url}#FT_{name.to_cmangle}", name, "formal type")
end
- redef fun tpl_signature do return tpl_link
+
+ redef fun html_short_signature do return html_link
+ redef fun html_signature do return html_link
end
redef class MVirtualType
- redef fun tpl_link do return mproperty.intro.tpl_link
- redef fun tpl_signature do return tpl_link
+ redef fun html_link do return mproperty.intro.html_link
+ redef fun html_signature do return html_link
end
redef class MSignature
- redef fun tpl_signature do
+
+ redef fun html_short_signature do
var tpl = new Template
if not mparameters.is_empty then
tpl.add "("
for i in [0..mparameters.length[ do
- tpl.add mparameters[i].tpl_signature
+ tpl.add mparameters[i].html_short_signature
+ if i < mparameters.length - 1 then tpl.add ", "
+ end
+ tpl.add ")"
+ end
+ return tpl
+ end
+
+ redef fun html_signature do
+ var tpl = new Template
+ if not mparameters.is_empty then
+ tpl.add "("
+ for i in [0..mparameters.length[ do
+ tpl.add mparameters[i].html_signature
if i < mparameters.length - 1 then tpl.add ", "
end
tpl.add ")"
end
if return_mtype != null then
tpl.add ": "
- tpl.add return_mtype.tpl_signature
+ tpl.add return_mtype.html_signature
end
return tpl
end
end
redef class MParameter
- fun tpl_signature: Template do
+
+ # Returns `self` name and ellipsys if any.
+ fun html_short_signature: Template do
+ var tpl = new Template
+ tpl.add name
+ if is_vararg then tpl.add "..."
+ return tpl
+ end
+
+ # Returns `self` name with it's static type and ellipsys if any.
+ fun html_signature: Template do
var tpl = new Template
tpl.add "{name}: "
- tpl.add mtype.tpl_signature
+ tpl.add mtype.html_signature
if is_vararg then tpl.add "..."
return tpl
end
# Additions to `model_ext`.
redef class MRawType
- redef fun tpl_signature do
+ redef fun html_signature do
var tpl = new Template
for part in parts do
if part.target != null then
- tpl.add part.target.as(not null).tpl_link
+ tpl.add part.target.as(not null).html_link
else
tpl.add part.text.html_escape
end
redef class MInnerClass
redef fun nitdoc_url do return inner.nitdoc_url
- redef fun tpl_signature do return inner.tpl_signature
+ redef fun html_signature do return inner.html_signature
end
redef class MInnerClassDef
redef fun nitdoc_url do return inner.nitdoc_url
- redef fun tpl_anchor do return inner.tpl_anchor
- redef fun tpl_link do return inner.tpl_link
- redef fun tpl_signature do return inner.tpl_signature
+ redef fun html_link_to_anchor do return inner.html_link_to_anchor
+ redef fun html_link do return inner.html_link
+ redef fun html_signature do return inner.html_signature
redef fun tpl_definition do
var tpl = new TplClassDefinition