Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Paul-Elliot Anglès d'Auriac
class-panic
Commits
da4648a9
Commit
da4648a9
authored
Oct 03, 2018
by
Paul-Elliot Anglès d'Auriac
Browse files
support de mathjax et de markdown pour les descriptions (ajoutées)
parent
7d6a33f5
Changes
94
Expand all
Hide whitespace changes
Inline
Side-by-side
controllers/questionController.js
View file @
da4648a9
...
...
@@ -32,6 +32,7 @@ renderManageQuestion = function(user, questionID, setID, msgs, res) {
reponse
:
""
,
validity
:
false
}],
correct
:
0
,
enonce
:
""
})
},
...
...
models/question.js
View file @
da4648a9
...
...
@@ -90,8 +90,8 @@ exports.questionCreate = function (user, question, setID, callback) {
i
++
;
}
bdd
.
query
(
"
SELECT MAX(indexSet+1) as indexx FROM `questions` WHERE `class` = ? GROUP BY `class`
"
,
[
setID
],
function
(
er
,
ind
)
{
bdd
.
query
(
"
INSERT INTO `questions`(`enonce`, `indexSet`, `class`, `owner`, `reponses`, `correct`) VALUES (? , ?, ?, ?, ?, ?); SELECT LAST_INSERT_ID()
"
,
[
question
.
enonce
,
ind
[
0
]
?
ind
[
0
].
indexx
:
0
,
setID
,
user
.
id
,
JSON
.
stringify
(
reponse
),
question
.
correct
],
bdd
.
query
(
"
INSERT INTO `questions`(`enonce`, `indexSet`, `class`, `owner`, `reponses`, `correct`
, `description`
) VALUES (? , ?, ?, ?, ?,
?,
?); SELECT LAST_INSERT_ID()
"
,
[
question
.
enonce
,
ind
[
0
]
?
ind
[
0
].
indexx
:
0
,
setID
,
user
.
id
,
JSON
.
stringify
(
reponse
),
question
.
correct
,
question
.
description
],
function
(
err
,
r
)
{
callback
(
err
,
r
[
0
])});
});
...
...
@@ -122,8 +122,8 @@ exports.questionUpdate = function (user, question, newQuestion, callback) {
reponse
[
i
]
=
{
reponse
:
newQuestion
[
i
]
,
validity
:
false
};
i
++
;
}
bdd
.
query
(
"
UPDATE `questions` SET `enonce` = ?, `reponses` = ?, `correct` = ? WHERE `id` = ? AND `owner` = ?
"
,
[
newQuestion
.
enonce
,
JSON
.
stringify
(
reponse
),
newQuestion
.
correct
,
parseInt
(
question
.
id
),
user
.
id
],
callback
);
bdd
.
query
(
"
UPDATE `questions` SET `enonce` = ?, `reponses` = ?, `correct` =
?, `description` =
? WHERE `id` = ? AND `owner` = ?
"
,
[
newQuestion
.
enonce
,
JSON
.
stringify
(
reponse
),
newQuestion
.
correct
,
newQuestion
.
description
,
parseInt
(
question
.
id
),
user
.
id
],
callback
);
}
public/javascripts/admin.js
View file @
da4648a9
...
...
@@ -2,7 +2,8 @@
//var socketAdmin = io.connect('http://localhost:3000/admin');
var
socketAdmin
=
io
.
connect
(
server
+
'
/admin
'
);
var
isAdmin
=
true
;
var
currentQuestionOf
;
let
currentQuestionOfAdmin
;
/*********************************************************************/
/* Actions à effectuer à toute connection */
...
...
@@ -60,7 +61,7 @@ socketAdmin.on('newStats', function (newStats) {
if
(
stat
.
response
==
-
1
)
stat
.
response2
=
"
?
"
;
else
stat
.
response2
=
currentQuestionOf
.
reponses
[
stat
.
response
].
reponse
;
stat
.
response2
=
currentQuestionOf
Admin
.
reponses
[
stat
.
response
].
reponse
;
li
.
innerHTML
=
'
<div style="display:flex; justify-content: space-between;color:
'
+
color
+
'
;">
'
+
/*stat.pseudo*/
stat
.
fullName
+
'
: <span>
'
+
stat
.
response2
+
'
</span></div>
'
MathJax
.
Hub
.
Queue
([
"
Typeset
"
,
MathJax
.
Hub
,
li
]);
ul
.
appendChild
(
li
);
...
...
@@ -73,7 +74,7 @@ socketAdmin.on('newStats', function (newStats) {
/*********************************************************************/
socketAdmin
.
on
(
'
newQuestion
'
,
function
(
reponse
)
{
console
.
log
(
"
fromAdminnewQuestion
"
,
reponse
);
currentQuestionOf
=
reponse
;
currentQuestionOf
Admin
=
reponse
;
if
(
temp
=
document
.
querySelector
(
"
li.inactiveQuestion
"
))
{
if
(
reponse
.
id
)
temp
.
classList
.
remove
(
"
inactiveQuestion
"
)
...
...
@@ -93,7 +94,8 @@ socketAdmin.on('newQuestion', function (reponse) {
else {
document.querySelector("#customQuestion").innerHTML = "Revenir à la question du set";
document.querySelector("#customQuestion").onclick = backToSetQuestion;
}*/
}*/
document
.
querySelector
(
"
#question
"
).
contentEditable
=
"
false
"
;
socketAdmin
.
emit
(
"
sendStatsPlease
"
);
});
...
...
@@ -133,9 +135,10 @@ sendReponse = function() {
i
++
;
});
newQuestion
.
enonce
=
document
.
querySelector
(
"
#question
"
).
textContent
;
newQuestion
.
description
=
document
.
querySelector
(
"
#newDescr
"
).
value
;
// console.log(newQuestion);
// backToSetQuestion();
// backToSetQuestion();
console
.
log
(
newQuestion
);
socketAdmin
.
emit
(
"
customQuestion
"
,
newQuestion
);
}
...
...
@@ -157,7 +160,7 @@ customQuestion = function(event) {
}
function
removeTypeset
(
elem
)
{
/*
function removeTypeset(elem) {
var HTML = MathJax.HTML, jax = MathJax.Hub.getAllJax(elem);
for (var i = 0, m = jax.length; i < m; i++) {
var script = jax[i].SourceElement(), tex = jax[i].originalText;
...
...
@@ -172,25 +175,29 @@ function removeTypeset(elem) {
script.parentNode.removeChild(script);
}
}
*/
function
modifyQuestion
()
{
if
(
document
.
querySelector
(
"
#question
"
).
contentEditable
==
"
false
"
)
{
question
=
document
.
querySelector
(
"
#question
"
);
question
.
contentEditable
=
true
;
MathJax
.
Hub
.
Queue
(()
=>
{
removeTypeset
(
question
)});
document
.
querySelectorAll
(
"
#wrapperAnswer .reponse
"
).
forEach
((
reponse
)
=>
{
MathJax
.
Hub
.
Queue
(()
=>
{
removeTypeset
(
reponse
)});
// MathJax.Hub.Queue(() => {removeTypeset(question)});
question
.
textContent
=
currentQuestionOfAdmin
.
enonce
;
document
.
querySelectorAll
(
"
#wrapperAnswer .reponse
"
).
forEach
((
reponse
,
index
)
=>
{
// MathJax.Hub.Queue(() => {removeTypeset(reponse)});
reponse
.
textContent
=
currentQuestionOfAdmin
.
reponses
[
index
].
reponse
;
});
MathJax
.
Hub
.
Queue
(()
=>
{
document
.
querySelectorAll
(
"
#wrapperAnswer .reponse
"
).
forEach
((
reponse
)
=>
{
console
.
log
(
reponse
);
reponse
.
innerHTML
=
"
<span contentEditable='true'>
"
+
reponse
.
innerHTML
+
"
</span>
"
;
reponse
.
innerHTML
+=
"
<button onclick=
\"
chooseAsCorrect(this)
\"
>Choisir comme réponse juste</button><button onclick=
\"
removeReponse(this)
\"
>Retirer</button>
"
});
document
.
querySelector
(
"
#customQuestion
"
).
innerHTML
=
"
Revenir à la question du set
"
;
document
.
querySelector
(
"
#customQuestion
"
).
onclick
=
backToSetQuestion
;
document
.
querySelector
(
"
#wrapperAnswer
"
).
innerHTML
+=
"
<div class=
\"
reponse notSelected
\"
id=
\"
plus
\"
> <button onclick=
\"
addReponse()
\"
> Ajouter une réponse</button><button onclick=
\"
sendReponse()
\"
> Envoyer aux élèves </button></div>
"
;
document
.
querySelectorAll
(
"
#wrapperAnswer .reponse
"
).
forEach
((
reponse
)
=>
{
console
.
log
(
reponse
);
reponse
.
innerHTML
=
"
<span contentEditable='true'>
"
+
reponse
.
innerHTML
+
"
</span>
"
;
reponse
.
innerHTML
+=
"
<button onclick=
\"
chooseAsCorrect(this)
\"
>Choisir comme réponse juste</button><button onclick=
\"
removeReponse(this)
\"
>Retirer</button>
"
});
descr
=
document
.
querySelector
(
"
#description
"
);
descr
.
style
.
visibility
=
"
visible
"
;
descr
.
innerHTML
=
"
<textarea id=
\"
newDescr
\"
style='width:100%;height:200px;'></textarea>
"
;
descr
.
firstChild
.
textContent
=
currentQuestionOfAdmin
.
description
;
document
.
querySelector
(
"
#customQuestion
"
).
innerHTML
=
"
Revenir à la question du set
"
;
document
.
querySelector
(
"
#customQuestion
"
).
onclick
=
backToSetQuestion
;
document
.
querySelector
(
"
#wrapperAnswer
"
).
innerHTML
+=
"
<div class=
\"
reponse notSelected
\"
id=
\"
plus
\"
> <button onclick=
\"
addReponse()
\"
> Ajouter une réponse</button><button onclick=
\"
sendReponse()
\"
> Envoyer aux élèves </button></div>
"
;
}
}
public/javascripts/highlight.pack.js
0 → 100644
View file @
da4648a9
This diff is collapsed.
Click to expand it.
public/javascripts/markdown-it-mathjax.js
0 → 100644
View file @
da4648a9
;(
function
(
root
,
factory
)
{
if
(
typeof
exports
===
'
object
'
)
{
module
.
exports
=
factory
()
}
else
{
root
.
markdownitMathjax
=
factory
()
}
})(
this
,
function
()
{
function
math
(
state
,
silent
)
{
var
startMathPos
=
state
.
pos
if
(
state
.
src
.
charCodeAt
(
startMathPos
)
!==
0x5C
/* \ */
)
{
return
false
}
var
match
=
state
.
src
.
slice
(
++
startMathPos
).
match
(
/^
(?:\\\[
|
\\\(
|begin
\{([^
}
]
*
)\})
/
)
if
(
!
match
)
{
return
false
}
startMathPos
+=
match
[
0
].
length
var
type
,
endMarker
,
includeMarkers
if
(
match
[
0
]
===
'
\\
[
'
)
{
type
=
'
display_math
'
endMarker
=
'
\\\\
]
'
}
else
if
(
match
[
0
]
===
'
\\
(
'
)
{
type
=
'
inline_math
'
endMarker
=
'
\\\\
)
'
}
else
if
(
match
[
1
])
{
type
=
'
math
'
endMarker
=
'
\\
end{
'
+
match
[
1
]
+
'
}
'
includeMarkers
=
true
}
var
endMarkerPos
=
state
.
src
.
indexOf
(
endMarker
,
startMathPos
)
if
(
endMarkerPos
===
-
1
)
{
return
false
}
var
nextPos
=
endMarkerPos
+
endMarker
.
length
if
(
!
silent
)
{
var
token
=
state
.
push
(
type
,
''
,
0
)
token
.
content
=
includeMarkers
?
state
.
src
.
slice
(
state
.
pos
,
nextPos
)
:
state
.
src
.
slice
(
startMathPos
,
endMarkerPos
)
}
state
.
pos
=
nextPos
return
true
}
function
texMath
(
state
,
silent
)
{
var
startMathPos
=
state
.
pos
if
(
state
.
src
.
charCodeAt
(
startMathPos
)
!==
0x24
/* $ */
)
{
return
false
}
// Parse tex math according to http://pandoc.org/README.html#math
var
endMarker
=
'
$
'
var
afterStartMarker
=
state
.
src
.
charCodeAt
(
++
startMathPos
)
if
(
afterStartMarker
===
0x24
/* $ */
)
{
endMarker
=
'
$$
'
if
(
state
.
src
.
charCodeAt
(
++
startMathPos
)
===
0x24
/* $ */
)
{
// 3 markers are too much
return
false
}
}
else
{
// Skip if opening $ is succeeded by a space character
if
(
afterStartMarker
===
0x20
/* space */
||
afterStartMarker
===
0x09
/* \t */
||
afterStartMarker
===
0x0a
/* \n */
)
{
return
false
}
}
var
endMarkerPos
=
state
.
src
.
indexOf
(
endMarker
,
startMathPos
)
if
(
endMarkerPos
===
-
1
)
{
return
false
}
if
(
state
.
src
.
charCodeAt
(
endMarkerPos
-
1
)
===
0x5C
/* \ */
)
{
return
false
}
var
nextPos
=
endMarkerPos
+
endMarker
.
length
if
(
endMarker
.
length
===
1
)
{
// Skip if $ is preceded by a space character
var
beforeEndMarker
=
state
.
src
.
charCodeAt
(
endMarkerPos
-
1
)
if
(
beforeEndMarker
===
0x20
/* space */
||
beforeEndMarker
===
0x09
/* \t */
||
beforeEndMarker
===
0x0a
/* \n */
)
{
return
false
}
// Skip if closing $ is succeeded by a digit (eg $5 $10 ...)
var
suffix
=
state
.
src
.
charCodeAt
(
nextPos
)
if
(
suffix
>=
0x30
&&
suffix
<
0x3A
)
{
return
false
}
}
if
(
!
silent
)
{
var
token
=
state
.
push
(
endMarker
.
length
===
1
?
'
inline_math
'
:
'
display_math
'
,
''
,
0
)
token
.
content
=
state
.
src
.
slice
(
startMathPos
,
endMarkerPos
)
}
state
.
pos
=
nextPos
return
true
}
function
escapeHtml
(
html
)
{
return
html
.
replace
(
/&/g
,
'
&
'
).
replace
(
/</g
,
'
<
'
).
replace
(
/
\u
00a0/g
,
'
'
)
}
function
extend
(
options
,
defaults
)
{
return
Object
.
keys
(
defaults
).
reduce
(
function
(
result
,
key
)
{
if
(
result
[
key
]
===
undefined
)
{
result
[
key
]
=
defaults
[
key
]
}
return
result
},
options
)
}
var
mapping
=
{
'
math
'
:
'
Math
'
,
'
inline_math
'
:
'
InlineMath
'
,
'
display_math
'
:
'
DisplayMath
'
}
return
function
(
options
)
{
var
defaults
=
{
beforeMath
:
''
,
afterMath
:
''
,
beforeInlineMath
:
'
\\
(
'
,
afterInlineMath
:
'
\\
)
'
,
beforeDisplayMath
:
'
\\
[
'
,
afterDisplayMath
:
'
\\
]
'
}
options
=
extend
(
options
||
{},
defaults
)
return
function
(
md
)
{
md
.
inline
.
ruler
.
before
(
'
escape
'
,
'
math
'
,
math
)
md
.
inline
.
ruler
.
push
(
'
texMath
'
,
texMath
)
Object
.
keys
(
mapping
).
forEach
(
function
(
key
)
{
var
before
=
options
[
'
before
'
+
mapping
[
key
]]
var
after
=
options
[
'
after
'
+
mapping
[
key
]]
md
.
renderer
.
rules
[
key
]
=
function
(
tokens
,
idx
)
{
return
before
+
escapeHtml
(
tokens
[
idx
].
content
)
+
after
}
})
}
}
})
public/javascripts/student.js
View file @
da4648a9
//var socket = io.connect('http://192.168.0.12:3000/');
var
socket
=
io
.
connect
(
server
+
"
/student
"
);
//var socket = io.connect('http://localhost:3000/');
var
currentQuestionOfStudent
;
var
md
=
new
markdownit
({
html
:
false
,
// Enable HTML tags in source
xhtmlOut
:
false
,
// Use '/' to close single tags (<br />)
breaks
:
false
,
// Convert '\n' in paragraphs into <br>
langPrefix
:
'
language-
'
,
// CSS language prefix for fenced blocks
linkify
:
true
,
// autoconvert URL-like texts to links
linkTarget
:
''
,
// set target to open link in
// Enable some language-neutral replacements + quotes beautification
typographer
:
false
,
// Double + single quotes replacement pairs, when typographer enabled,
// and smartquotes on. Set doubles to '«»' for Russian, '„“' for German.
quotes
:
'
“”‘’
'
,
// Highlighter function. Should return escaped HTML,
// or '' if input not changed
highlight
:
function
(
str
,
lang
)
{
if
(
lang
&&
hljs
.
getLanguage
(
lang
))
{
try
{
return
hljs
.
highlight
(
lang
,
str
).
value
;
}
catch
(
__
)
{}
}
try
{
return
hljs
.
highlightAuto
(
str
).
value
;
}
catch
(
__
)
{}
return
''
;
// use external default escaping
}
});
md
.
use
(
markdownitMathjax
());
/*********************************************************************/
/* Actions à effectuer à toute connection */
...
...
@@ -16,7 +51,8 @@ socket.on('connect', () => {
/*********************************************************************/
socket
.
on
(
'
newQuestion
'
,
function
(
reponse
)
{
// console.log(reponse);
// console.log(reponse);
currentQuestionOfStudent
=
reponse
;
enonce
=
document
.
querySelector
(
"
#question
"
);
enonce
.
textContent
=
reponse
.
enonce
;
MathJax
.
Hub
.
Queue
([
"
Typeset
"
,
MathJax
.
Hub
,
enonce
]);
...
...
@@ -37,6 +73,13 @@ socket.on('newQuestion', function (reponse) {
MathJax
.
Hub
.
Queue
([
"
Typeset
"
,
MathJax
.
Hub
,
elem
]);
wrapper
.
appendChild
(
elem
);
});
descr
=
document
.
querySelector
(
"
#description
"
);
if
(
reponse
.
description
)
descr
.
style
.
visibility
=
"
visible
"
;
else
descr
.
style
.
visibility
=
"
hidden
"
;
descr
.
innerHTML
=
md
.
render
(
reponse
.
description
);
MathJax
.
Hub
.
Queue
([
"
Typeset
"
,
MathJax
.
Hub
,
descr
]);
});
/*********************************************************************/
...
...
public/stylesheets/bootstrap-lessed.css
0 → 100644
View file @
da4648a9
This diff is collapsed.
Click to expand it.
public/stylesheets/highlight/agate.css
0 → 100644
View file @
da4648a9
/*!
* Agate by Taufik Nurrohman <https://github.com/tovic>
* ----------------------------------------------------
*
* #ade5fc
* #a2fca2
* #c6b4f0
* #d36363
* #fcc28c
* #fc9b9b
* #ffa
* #fff
* #333
* #62c8f3
* #888
*
*/
.hljs
{
display
:
block
;
overflow-x
:
auto
;
padding
:
0.5em
;
background
:
#333
;
color
:
white
;
}
.hljs-name
,
.hljs-strong
{
font-weight
:
bold
;
}
.hljs-code
,
.hljs-emphasis
{
font-style
:
italic
;
}
.hljs-tag
{
color
:
#62c8f3
;
}
.hljs-variable
,
.hljs-template-variable
,
.hljs-selector-id
,
.hljs-selector-class
{
color
:
#ade5fc
;
}
.hljs-string
,
.hljs-bullet
{
color
:
#a2fca2
;
}
.hljs-type
,
.hljs-title
,
.hljs-section
,
.hljs-attribute
,
.hljs-quote
,
.hljs-built_in
,
.hljs-builtin-name
{
color
:
#ffa
;
}
.hljs-number
,
.hljs-symbol
,
.hljs-bullet
{
color
:
#d36363
;
}
.hljs-keyword
,
.hljs-selector-tag
,
.hljs-literal
{
color
:
#fcc28c
;
}
.hljs-comment
,
.hljs-deletion
,
.hljs-code
{
color
:
#888
;
}
.hljs-regexp
,
.hljs-link
{
color
:
#c6b4f0
;
}
.hljs-meta
{
color
:
#fc9b9b
;
}
.hljs-deletion
{
background-color
:
#fc9b9b
;
color
:
#333
;
}
.hljs-addition
{
background-color
:
#a2fca2
;
color
:
#333
;
}
.hljs
a
{
color
:
inherit
;
}
.hljs
a
:focus
,
.hljs
a
:hover
{
color
:
inherit
;
text-decoration
:
underline
;
}
public/stylesheets/highlight/androidstudio.css
0 → 100644
View file @
da4648a9
/*
Date: 24 Fev 2015
Author: Pedro Oliveira <kanytu@gmail . com>
*/
.hljs
{
color
:
#a9b7c6
;
background
:
#282b2e
;
display
:
block
;
overflow-x
:
auto
;
padding
:
0.5em
;
}
.hljs-number
,
.hljs-literal
,
.hljs-symbol
,
.hljs-bullet
{
color
:
#6897BB
;
}
.hljs-keyword
,
.hljs-selector-tag
,
.hljs-deletion
{
color
:
#cc7832
;
}
.hljs-variable
,
.hljs-template-variable
,
.hljs-link
{
color
:
#629755
;
}
.hljs-comment
,
.hljs-quote
{
color
:
#808080
;
}
.hljs-meta
{
color
:
#bbb529
;
}
.hljs-string
,
.hljs-attribute
,
.hljs-addition
{
color
:
#6A8759
;
}
.hljs-section
,
.hljs-title
,
.hljs-type
{
color
:
#ffc66d
;
}
.hljs-name
,
.hljs-selector-id
,
.hljs-selector-class
{
color
:
#e8bf6a
;
}
.hljs-emphasis
{
font-style
:
italic
;
}
.hljs-strong
{
font-weight
:
bold
;
}
public/stylesheets/highlight/arduino-light.css
0 → 100644
View file @
da4648a9
/*
Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
*/
.hljs
{
display
:
block
;
overflow-x
:
auto
;
padding
:
0.5em
;
background
:
#FFFFFF
;
}
.hljs
,
.hljs-subst
{
color
:
#434f54
;
}
.hljs-keyword
,
.hljs-attribute
,
.hljs-selector-tag
,
.hljs-doctag
,
.hljs-name
{
color
:
#00979D
;
}
.hljs-built_in
,
.hljs-literal
,
.hljs-bullet
,
.hljs-code
,
.hljs-addition
{
color
:
#D35400
;
}
.hljs-regexp
,
.hljs-symbol
,
.hljs-variable
,
.hljs-template-variable
,
.hljs-link
,
.hljs-selector-attr
,
.hljs-selector-pseudo
{
color
:
#00979D
;
}
.hljs-type
,
.hljs-string
,
.hljs-selector-id
,
.hljs-selector-class
,
.hljs-quote
,
.hljs-template-tag
,
.hljs-deletion
{
color
:
#005C5F
;
}
.hljs-title
,
.hljs-section
{
color
:
#880000
;
font-weight
:
bold
;
}
.hljs-comment
{
color
:
rgba
(
149
,
165
,
166
,
.8
);
}
.hljs-meta-keyword
{
color
:
#728E00
;
}
.hljs-meta
{
color
:
#728E00
;
color
:
#434f54
;
}
.hljs-emphasis
{
font-style
:
italic
;
}
.hljs-strong
{
font-weight
:
bold
;
}
.hljs-function
{
color
:
#728E00
;
}
.hljs-number
{
color