PK KHm$! * ats-cmake-documentaition-latest/.buildinfo# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config:
tags:
PK KHuv + ats-cmake-documentaition-latest/objects.inv# Sphinx inventory version 2
# Project: ATS CMake
# Version: latest
# The remainder of this file is compressed using zlib.
xKOKIP(.IILJQ5THe(+x\)XT$}SJsRS3P@Ġ!
S D1PK KHV V * ats-cmake-documentaition-latest/index.html
This is a project aiming at developing a build tool for ATS. It is based on CMake. Currently, it provides some very useful CMake modules for ATS users to simplify building processes. In the near future, it will support downloading artifacts from a server to help you utilize third party ATS libraries.
The project is hosted on GitHub. Welcome to contribute.
This project involves multiple executables in one project. Source files can be found here.
SimpleUsage
| CMakeLists.txt
| gcd.dats # compute GCD using lambda| lambda.dats # implementation of simple lambda calculas| lambda.sats # definition of simple lambda calculas| lambda_env.dats # lambda evaluation environment| prime.dats # compute prime number using lambda|\---build # out-of-source build dir
...
What we want are two executables, gcd and prime.
CMAKE_MINIMUM_REQUIRED(VERSION2.8)PROJECT(SIMPLE_USAGEC)FIND_PACKAGE(ATSREQUIRED)IF(NOTATS_FOUND)MESSAGE(FATAL_ERROR"ATS Not Found!")ENDIF()SET(LAMBDAlambda.satslambda.datslambda_env.dats)ATS_COMPILE(GCD_SRC${LAMBDA}gcd.dats)ATS_COMPILE(PRIME_SRC${LAMBDA}prime.dats)ADD_EXECUTABLE(gcd${GCD_SRC})ADD_EXECUTABLE(prime${PRIME_SRC})
Sometimes, you may want to use these CMake moduls locally. I will modify the last example with locally loaded ATS modules. Source files can be found here.
I put the CMake modules under ${CMAKE_CURRENT_SOURCE_DIR}/cmake. And the CMakeLists.txt should be updated as follows.
CMAKE_MINIMUM_REQUIRED(VERSION2.8)PROJECT(SIMPLE_USAGEC)SET(CMAKE_MODULE_PATH${CMAKE_CURRENT_SOURCE_DIR}/cmake)INCLUDE(ATSCC)FIND_PACKAGE(ATSREQUIRED)IF(NOTATS_FOUND)MESSAGE(FATAL_ERROR"ATS Not Found!")ENDIF()SET(LAMBDAlambda.satslambda.datslambda_env.dats)ATS_COMPILE(GCD_SRC${LAMBDA}gcd.dats)ATS_COMPILE(PRIME_SRC${LAMBDA}prime.dats)ADD_EXECUTABLE(gcd${GCD_SRC})ADD_EXECUTABLE(prime${PRIME_SRC})
This page is a reference to all macros/functions in ATSCC.cmake and FindATS.cmake.
Tips for filename/path
Most of commands/macros in CMake, and most of commands of Lunix require filenames/paths contain NO space. So, I assume no space in any of the filenames/paths. If you get errors, first check if there is any space in any filenames/paths, and remove them. It is always good to make a space-free filename/path.
ATS_HOMEATSCCATSOPTATSCC_FLAGSATS_INCLUDE_DIRSATS_LIBRARIESATS_VERBOSE: False by default
Effects (CMake variables for internal usage)
ATS_INCLUDE_DIRATS_LIBRARYCMAKE_C_COMPILER
This is a standard CMake FindXXX module. CMake community has a documentation about how to write a FindXXX module, here. You have to write this in your CMakeLists.txt in order to use ATS.
In my FindATS.cmake, I use environment variable ATSHOME to lookup ATS binaries. And if it is found, a series of CMake variables will be set. They are the followings.
ATS_Home:
Set to the same value as environment variable ATSHOME.
ATS_INCLUDE_DIR:
For internal usage only. Set to the include directories of ATS. Its value is ${ATS_HOME}/ccomp/runtime.
ATS_LIBRARY:
For internal usage only. Set to the link directories of ATS. Its value is ${ATS_HOME}/ccomp/lib.
ATS_INCLUDE_DIRS:
Its the same value as ${ATS_INCLUDE_DIR}, but it is for users.
ATS_LIBRARIES:
Its the same value as ${ATS_LIBRARY}, but it is for users.
Note
These two internal variables and two user variables are compliant to CMake naming conventions. Please refer to CMake documentations.
ATS_VERBOSE:
False by defalut. If set to ture, it will produce more informations during making process. Please set it only after FIND_PACKAGE(ATS...). Otherwise, it will be reset to default value inside the FindATS module.
Example
FIND_PACKAGE(ATSREQUIRED)IF(NOTATS_FOUND)MESSAGE(FATAL_ERROR"ATS Not Found!")ENDIF()SET(ATS_VERBOSETrue)
ATSCC:
It is set to the full path of atscc executable.
ATSOPT:
It is set to the full path of atsopt executable.
ATSCC_FLAGS:
It is set to empty.
CMAKE_C_COMPILER:
For internal usage only. This is a trick. First, atscc will call atsopt and then gcc to compile the code. Second, atscc includes many useful arguments for gcc so that it can correctly find all runtime dependencies. Thrid, by setting C compiler to atscc, CMake will invoke atscc to compile C code, thus utilizing atscc‘s extra arguments to locate all necessary headers and libraries. You won’t need to use this. But I think it’s better to let you know this.
Example
FIND_PACKAGE(ATSREQUIRED)IF(NOTATS_FOUND)MESSAGE(FATAL_ERROR"ATS Not Found!")ENDIF()
Result
If ATS is found, those commands/macros/variables will be avaiable. Otherwise, ATSNotFound! will be printed and CMake will terminate.
This macro will add all paths as directories to look up for SATS/HATS files. This will result in multiple IATS flags for atsopt. The paths should be relative to ${CMAKE_CURRENT_LIST_DIR}, or they are absolute paths. You need at least one path as a parameter.
Example
ATS_INCLUDE(SATSHATS/usr/include/ats028/SATS)
Result
${CMAKE_CURRENT_LIST_DIR}/SATS, ${CMAKE_CURRENT_LIST_DIR}/HATS and /usr/include/ats028/SATS will be added to atsopt-IATS flags.
The name of the variable where to store output filenames. It is a list, not a string.
Source filenames
Specify all related files to be compiled. Seperate them using space. Only DATS and SATS files are needed.
Output
OUTPUT
All fullpaths of C files will be stored in OUTPUT.
This macro will compile all sources provided into corresponding C sources, and store all generated C file names into ${output} for further use. Those file names are absolute paths.
The dependencies will be automatically generated. This includes two parts. First, all staload (for sats file) and #include (for hats file) will be detected using atsopt-dep1. Second, all generated C files will also be involved in dependencies. For example, if a.sats includes a.hats, and a.dats staload a.sats. Then a dependency a_dats.c->a_sats.c will be generated so that if a.hats changes, a_dats.c will be regenerated.
All C files compiled from ATS files are stored in TEST_SRC. They are SATS/hello_sats.c, DATS/hello_dats.c and DATS/main_dats.c.
Note that there is no need to specify CATS files and HATS files, since atsopt will automatically find them in the paths specified by ATS_INCLUDE().
Warning
CMake has some really confusing terms, like list and string. Basically, a list is a single string where inner items are seperated using semicolon, while a string is seperated using spaces. set(MyString"HelloWorld") will give you a string, while set(MyListHelloWorld) will give you a list, which is stored as Hello;World. Also, you need to pay attention to quotes. set(MyString2"${MyString}") will be a string, while set(MyList2${MyString}) will be a list, since it will evaluate to set(MyList2HelloWorld). You should search “CMake List String” on Google for more information.
${OUTPUT} will contain space separated dependencies. It is a string, not a list. All dependencies are fullpaths.
It is called by ATS_COMPILE(). It runs atsopt to generate ATS dependencies. For example, if hello.dats depends on hello.sats, it will append the fullpath of hello.sats to the output. Later, it will call ATS_DEPGEN_C() to generate C dependencies. Take the above example, it will make hello_dats.c depends on hello_sats.c. This enables hello_dats.c to be regenerated when hello.sats is modified.
It is called by ATS_DEPGEN(). For example, if we have 1.sats<-2.sats, then we add 1_sats.c<-2_sats.c.
This is useful when 1.sats inludes a HATS file. When the HATS file updates, 1.sats is not changed, but 1_sats.c is changed. And since 2.sats depends on 1.sats and it is not changed, 2_sats.c is not recompiled. However, it should be recompiled since the actual meaning of 1.sats has been changed. Thus, we need to append C dependencies.
These are useful CMake commands. They are parts of CMake, not my project. But I think you will need them everywhere. If you need detail information, please refer to CMake offical documents.
Note
You can always check out latest usage of CMake here. Every commands are listed and documented.
It will link those libraries to a specific target listed in the same CMake list files. Those library names could be confusing sometime. If you want to link a library file libzlog.so.2, you may try zlog or libzlog as parameters to TARGET_LINK_LIBRARIES.
Suppose you have a small project containing hello.sats, hello.dats and main.dats. Then, you need to write a CMakeLists.txt like the following
CMAKE_MINIMUM_REQUIRED(VERSION2.8)#Specify project name as HELLOWORLD, and project language as C. Yes, it is CPROJECT(HELLOWORLDC)#Actually, this makes CMake to find ATSCC.cmake using FindATS.cmakeFIND_PACKAGE(ATSREQUIRED)#The ATS_FOUND is automatically set by FindATS.cmake moduleIF(NOTATS_FOUND)MESSAGE(FATAL_ERROR"ATS Not Found!")ENDIF()#ATS_COMIPLE is the core of this project. To put it simple, #you just specify related SATS/DATS files here, and use a variable#like TEST_SRC to store the outputs. ATS_COMPILE will analyze their #dependencies, compile them into C files, and store those C file #names into TEST_SRC#You can use ATS_INCLUDE to add search paths for the compiler to#find proper SATS/HATS files. ATS_COMPILE(TEST_SRChello.satshello.datsmain.dats)#It generate the final file "test" using all the C files in TEST_SRC.#And this is a standard CMake commandADD_EXECUTABLE(test${TEST_SRC})
After you have a correct CMakeLists.txt, we just need to invoke cmake. But please make sure that you have a correct project layout.
I suggest using out-of-source build, which makes everything clean, especially when you want to delete all temp files. See here for more information. I use a ./build dir for this purpose.
Now, go to ./build and invoke cmake. It will generate a makefile for you under ./build. You can invoke make now, to build the project as usual, and congratulations! The output binary will be under ./build
>>> cd./build>>> cmake.....>>> make...
Note
We use cmake.. because the present working directory is ./build, while the CMakeLists.txt is in the parent directory. Therefore, it is cmake.. instead of cmake.. Pay attention.
In the followings, I will try to cover more use cases, and then look into what’s happening in the CMake modules, so that you can better use them, and even help me develop it.
')
.appendTo($('#searchbox'));
}
},
/**
* init the domain index toggle buttons
*/
initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) == 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('#searchbox .highlight-link').fadeOut(300);
$('span.highlighted').removeClass('highlighted');
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this == '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});
PK KH8c c 5 ats-cmake-documentaition-latest/_static/websupport.js/*
* websupport.js
* ~~~~~~~~~~~~~
*
* sphinx.websupport utilties for all documentation.
*
* :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
(function($) {
$.fn.autogrow = function() {
return this.each(function() {
var textarea = this;
$.fn.autogrow.resize(textarea);
$(textarea)
.focus(function() {
textarea.interval = setInterval(function() {
$.fn.autogrow.resize(textarea);
}, 500);
})
.blur(function() {
clearInterval(textarea.interval);
});
});
};
$.fn.autogrow.resize = function(textarea) {
var lineHeight = parseInt($(textarea).css('line-height'), 10);
var lines = textarea.value.split('\n');
var columns = textarea.cols;
var lineCount = 0;
$.each(lines, function() {
lineCount += Math.ceil(this.length / columns) || 1;
});
var height = lineHeight * (lineCount + 1);
$(textarea).css('height', height);
};
})(jQuery);
(function($) {
var comp, by;
function init() {
initEvents();
initComparator();
}
function initEvents() {
$(document).on("click", 'a.comment-close', function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
});
$(document).on("click", 'a.vote', function(event) {
event.preventDefault();
handleVote($(this));
});
$(document).on("click", 'a.reply', function(event) {
event.preventDefault();
openReply($(this).attr('id').substring(2));
});
$(document).on("click", 'a.close-reply', function(event) {
event.preventDefault();
closeReply($(this).attr('id').substring(2));
});
$(document).on("click", 'a.sort-option', function(event) {
event.preventDefault();
handleReSort($(this));
});
$(document).on("click", 'a.show-proposal', function(event) {
event.preventDefault();
showProposal($(this).attr('id').substring(2));
});
$(document).on("click", 'a.hide-proposal', function(event) {
event.preventDefault();
hideProposal($(this).attr('id').substring(2));
});
$(document).on("click", 'a.show-propose-change', function(event) {
event.preventDefault();
showProposeChange($(this).attr('id').substring(2));
});
$(document).on("click", 'a.hide-propose-change', function(event) {
event.preventDefault();
hideProposeChange($(this).attr('id').substring(2));
});
$(document).on("click", 'a.accept-comment', function(event) {
event.preventDefault();
acceptComment($(this).attr('id').substring(2));
});
$(document).on("click", 'a.delete-comment', function(event) {
event.preventDefault();
deleteComment($(this).attr('id').substring(2));
});
$(document).on("click", 'a.comment-markup', function(event) {
event.preventDefault();
toggleCommentMarkupBox($(this).attr('id').substring(2));
});
}
/**
* Set comp, which is a comparator function used for sorting and
* inserting comments into the list.
*/
function setComparator() {
// If the first three letters are "asc", sort in ascending order
// and remove the prefix.
if (by.substring(0,3) == 'asc') {
var i = by.substring(3);
comp = function(a, b) { return a[i] - b[i]; };
} else {
// Otherwise sort in descending order.
comp = function(a, b) { return b[by] - a[by]; };
}
// Reset link styles and format the selected sort option.
$('a.sel').attr('href', '#').removeClass('sel');
$('a.by' + by).removeAttr('href').addClass('sel');
}
/**
* Create a comp function. If the user has preferences stored in
* the sortBy cookie, use those, otherwise use the default.
*/
function initComparator() {
by = 'rating'; // Default to sort by rating.
// If the sortBy cookie is set, use that instead.
if (document.cookie.length > 0) {
var start = document.cookie.indexOf('sortBy=');
if (start != -1) {
start = start + 7;
var end = document.cookie.indexOf(";", start);
if (end == -1) {
end = document.cookie.length;
by = unescape(document.cookie.substring(start, end));
}
}
}
setComparator();
}
/**
* Show a comment div.
*/
function show(id) {
$('#ao' + id).hide();
$('#ah' + id).show();
var context = $.extend({id: id}, opts);
var popup = $(renderTemplate(popupTemplate, context)).hide();
popup.find('textarea[name="proposal"]').hide();
popup.find('a.by' + by).addClass('sel');
var form = popup.find('#cf' + id);
form.submit(function(event) {
event.preventDefault();
addComment(form);
});
$('#s' + id).after(popup);
popup.slideDown('fast', function() {
getComments(id);
});
}
/**
* Hide a comment div.
*/
function hide(id) {
$('#ah' + id).hide();
$('#ao' + id).show();
var div = $('#sc' + id);
div.slideUp('fast', function() {
div.remove();
});
}
/**
* Perform an ajax request to get comments for a node
* and insert the comments into the comments tree.
*/
function getComments(id) {
$.ajax({
type: 'GET',
url: opts.getCommentsURL,
data: {node: id},
success: function(data, textStatus, request) {
var ul = $('#cl' + id);
var speed = 100;
$('#cf' + id)
.find('textarea[name="proposal"]')
.data('source', data.source);
if (data.comments.length === 0) {
ul.html('
No comments yet.
');
ul.data('empty', true);
} else {
// If there are comments, sort them and put them in the list.
var comments = sortComments(data.comments);
speed = data.comments.length * 100;
appendComments(comments, ul);
ul.data('empty', false);
}
$('#cn' + id).slideUp(speed + 200);
ul.slideDown(speed);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem retrieving the comments.');
},
dataType: 'json'
});
}
/**
* Add a comment via ajax and insert the comment into the comment tree.
*/
function addComment(form) {
var node_id = form.find('input[name="node"]').val();
var parent_id = form.find('input[name="parent"]').val();
var text = form.find('textarea[name="comment"]').val();
var proposal = form.find('textarea[name="proposal"]').val();
if (text == '') {
showError('Please enter a comment.');
return;
}
// Disable the form that is being submitted.
form.find('textarea,input').attr('disabled', 'disabled');
// Send the comment to the server.
$.ajax({
type: "POST",
url: opts.addCommentURL,
dataType: 'json',
data: {
node: node_id,
parent: parent_id,
text: text,
proposal: proposal
},
success: function(data, textStatus, error) {
// Reset the form.
if (node_id) {
hideProposeChange(node_id);
}
form.find('textarea')
.val('')
.add(form.find('input'))
.removeAttr('disabled');
var ul = $('#cl' + (node_id || parent_id));
if (ul.data('empty')) {
$(ul).empty();
ul.data('empty', false);
}
insertComment(data.comment);
var ao = $('#ao' + node_id);
ao.find('img').attr({'src': opts.commentBrightImage});
if (node_id) {
// if this was a "root" comment, remove the commenting box
// (the user can get it back by reopening the comment popup)
$('#ca' + node_id).slideUp();
}
},
error: function(request, textStatus, error) {
form.find('textarea,input').removeAttr('disabled');
showError('Oops, there was a problem adding the comment.');
}
});
}
/**
* Recursively append comments to the main comment list and children
* lists, creating the comment tree.
*/
function appendComments(comments, ul) {
$.each(comments, function() {
var div = createCommentDiv(this);
ul.append($(document.createElement('li')).html(div));
appendComments(this.children, div.find('ul.comment-children'));
// To avoid stagnating data, don't store the comments children in data.
this.children = null;
div.data('comment', this);
});
}
/**
* After adding a new comment, it must be inserted in the correct
* location in the comment tree.
*/
function insertComment(comment) {
var div = createCommentDiv(comment);
// To avoid stagnating data, don't store the comments children in data.
comment.children = null;
div.data('comment', comment);
var ul = $('#cl' + (comment.node || comment.parent));
var siblings = getChildren(ul);
var li = $(document.createElement('li'));
li.hide();
// Determine where in the parents children list to insert this comment.
for(i=0; i < siblings.length; i++) {
if (comp(comment, siblings[i]) <= 0) {
$('#cd' + siblings[i].id)
.parent()
.before(li.html(div));
li.slideDown('fast');
return;
}
}
// If we get here, this comment rates lower than all the others,
// or it is the only comment in the list.
ul.append(li.html(div));
li.slideDown('fast');
}
function acceptComment(id) {
$.ajax({
type: 'POST',
url: opts.acceptCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
$('#cm' + id).fadeOut('fast');
$('#cd' + id).removeClass('moderate');
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem accepting the comment.');
}
});
}
function deleteComment(id) {
$.ajax({
type: 'POST',
url: opts.deleteCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
var div = $('#cd' + id);
if (data == 'delete') {
// Moderator mode: remove the comment and all children immediately
div.slideUp('fast', function() {
div.remove();
});
return;
}
// User mode: only mark the comment as deleted
div
.find('span.user-id:first')
.text('[deleted]').end()
.find('div.comment-text:first')
.text('[deleted]').end()
.find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
.remove();
var comment = div.data('comment');
comment.username = '[deleted]';
comment.text = '[deleted]';
div.data('comment', comment);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem deleting the comment.');
}
});
}
function showProposal(id) {
$('#sp' + id).hide();
$('#hp' + id).show();
$('#pr' + id).slideDown('fast');
}
function hideProposal(id) {
$('#hp' + id).hide();
$('#sp' + id).show();
$('#pr' + id).slideUp('fast');
}
function showProposeChange(id) {
$('#pc' + id).hide();
$('#hc' + id).show();
var textarea = $('#pt' + id);
textarea.val(textarea.data('source'));
$.fn.autogrow.resize(textarea[0]);
textarea.slideDown('fast');
}
function hideProposeChange(id) {
$('#hc' + id).hide();
$('#pc' + id).show();
var textarea = $('#pt' + id);
textarea.val('').removeAttr('disabled');
textarea.slideUp('fast');
}
function toggleCommentMarkupBox(id) {
$('#mb' + id).toggle();
}
/** Handle when the user clicks on a sort by link. */
function handleReSort(link) {
var classes = link.attr('class').split(/\s+/);
for (var i=0; iThank you! Your comment will show up '
+ 'once it is has been approved by a moderator.');
}
// Prettify the comment rating.
comment.pretty_rating = comment.rating + ' point' +
(comment.rating == 1 ? '' : 's');
// Make a class (for displaying not yet moderated comments differently)
comment.css_class = comment.displayed ? '' : ' moderate';
// Create a div for this comment.
var context = $.extend({}, opts, comment);
var div = $(renderTemplate(commentTemplate, context));
// If the user has voted on this comment, highlight the correct arrow.
if (comment.vote) {
var direction = (comment.vote == 1) ? 'u' : 'd';
div.find('#' + direction + 'v' + comment.id).hide();
div.find('#' + direction + 'u' + comment.id).show();
}
if (opts.moderator || comment.text != '[deleted]') {
div.find('a.reply').show();
if (comment.proposal_diff)
div.find('#sp' + comment.id).show();
if (opts.moderator && !comment.displayed)
div.find('#cm' + comment.id).show();
if (opts.moderator || (opts.username == comment.username))
div.find('#dc' + comment.id).show();
}
return div;
}
/**
* A simple template renderer. Placeholders such as <%id%> are replaced
* by context['id'] with items being escaped. Placeholders such as <#id#>
* are not escaped.
*/
function renderTemplate(template, context) {
var esc = $(document.createElement('div'));
function handle(ph, escape) {
var cur = context;
$.each(ph.split('.'), function() {
cur = cur[this];
});
return escape ? esc.text(cur || "").html() : cur;
}
return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
return handle(arguments[2], arguments[1] == '%' ? true : false);
});
}
/** Flash an error message briefly. */
function showError(message) {
$(document.createElement('div')).attr({'class': 'popup-error'})
.append($(document.createElement('div'))
.attr({'class': 'error-message'}).text(message))
.appendTo('body')
.fadeIn("slow")
.delay(2000)
.fadeOut("slow");
}
/** Add a link the user uses to open the comments popup. */
$.fn.comment = function() {
return this.each(function() {
var id = $(this).attr('id').substring(1);
var count = COMMENT_METADATA[id];
var title = count + ' comment' + (count == 1 ? '' : 's');
var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
var addcls = count == 0 ? ' nocomment' : '';
$(this)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-open' + addcls,
id: 'ao' + id
})
.append($(document.createElement('img')).attr({
src: image,
alt: 'comment',
title: title
}))
.click(function(event) {
event.preventDefault();
show($(this).attr('id').substring(2));
})
)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-close hidden',
id: 'ah' + id
})
.append($(document.createElement('img')).attr({
src: opts.closeCommentImage,
alt: 'close',
title: 'close'
}))
.click(function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
})
);
});
};
var opts = {
processVoteURL: '/_process_vote',
addCommentURL: '/_add_comment',
getCommentsURL: '/_get_comments',
acceptCommentURL: '/_accept_comment',
deleteCommentURL: '/_delete_comment',
commentImage: '/static/_static/comment.png',
closeCommentImage: '/static/_static/comment-close.png',
loadingImage: '/static/_static/ajax-loader.gif',
commentBrightImage: '/static/_static/comment-bright.png',
upArrow: '/static/_static/up.png',
downArrow: '/static/_static/down.png',
upArrowPressed: '/static/_static/up-pressed.png',
downArrowPressed: '/static/_static/down-pressed.png',
voting: false,
moderator: false
};
if (typeof COMMENT_OPTIONS != "undefined") {
opts = jQuery.extend(opts, COMMENT_OPTIONS);
}
var popupTemplate = '\
\ Sort by:\ best rated\ newest\ oldest\
\\
Add a comment\ (markup):
\``code``
, \ code blocks:::
and an indented block after blank line