Commit | Line | Data |
---|---|---|
6d03299d | 1 | <?php |
6d03299d TH |
2 | // This file is part of Moodle - http://moodle.org/ |
3 | // | |
4 | // Moodle is free software: you can redistribute it and/or modify | |
5 | // it under the terms of the GNU General Public License as published by | |
6 | // the Free Software Foundation, either version 3 of the License, or | |
7 | // (at your option) any later version. | |
8 | // | |
9 | // Moodle is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | // | |
14 | // You should have received a copy of the GNU General Public License | |
15 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
6d03299d TH |
17 | /** |
18 | * Essay question renderer class. | |
19 | * | |
7764183a TH |
20 | * @package qtype |
21 | * @subpackage essay | |
22 | * @copyright 2009 The Open University | |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
6d03299d TH |
24 | */ |
25 | ||
26 | ||
a17b297d TH |
27 | defined('MOODLE_INTERNAL') || die(); |
28 | ||
29 | ||
6d03299d TH |
30 | /** |
31 | * Generates the output for essay questions. | |
32 | * | |
7764183a TH |
33 | * @copyright 2009 The Open University |
34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
6d03299d TH |
35 | */ |
36 | class qtype_essay_renderer extends qtype_renderer { | |
37 | public function formulation_and_controls(question_attempt $qa, | |
38 | question_display_options $options) { | |
39 | ||
40 | $question = $qa->get_question(); | |
b36d2d06 | 41 | $responseoutput = $question->get_format_renderer($this->page); |
6d03299d TH |
42 | |
43 | // Answer field. | |
48d9c17d | 44 | $step = $qa->get_last_step_with_qt_var('answer'); |
60527d0c JMV |
45 | |
46 | if (!$step->has_qt_var('answer') && empty($options->readonly)) { | |
47 | // Question has never been answered, fill it with response template. | |
95d1f1f1 | 48 | $step = new question_attempt_step(array('answer' => $question->responsetemplate)); |
60527d0c JMV |
49 | } |
50 | ||
6d03299d | 51 | if (empty($options->readonly)) { |
48d9c17d TH |
52 | $answer = $responseoutput->response_area_input('answer', $qa, |
53 | $step, $question->responsefieldlines, $options->context); | |
6d03299d TH |
54 | |
55 | } else { | |
48d9c17d TH |
56 | $answer = $responseoutput->response_area_read_only('answer', $qa, |
57 | $step, $question->responsefieldlines, $options->context); | |
b36d2d06 TH |
58 | } |
59 | ||
60 | $files = ''; | |
d42dbe87 TH |
61 | if ($question->attachments) { |
62 | if (empty($options->readonly)) { | |
63 | $files = $this->files_input($qa, $question->attachments, $options); | |
b36d2d06 | 64 | |
d42dbe87 TH |
65 | } else { |
66 | $files = $this->files_read_only($qa, $options); | |
67 | } | |
6d03299d TH |
68 | } |
69 | ||
70 | $result = ''; | |
71 | $result .= html_writer::tag('div', $question->format_questiontext($qa), | |
72 | array('class' => 'qtext')); | |
73 | ||
b36d2d06 | 74 | $result .= html_writer::start_tag('div', array('class' => 'ablock')); |
6d03299d | 75 | $result .= html_writer::tag('div', $answer, array('class' => 'answer')); |
caeeff07 | 76 | $result .= html_writer::tag('div', $files, array('class' => 'attachments')); |
6d03299d TH |
77 | $result .= html_writer::end_tag('div'); |
78 | ||
79 | return $result; | |
80 | } | |
b36d2d06 TH |
81 | |
82 | /** | |
83 | * Displays any attached files when the question is in read-only mode. | |
d42dbe87 TH |
84 | * @param question_attempt $qa the question attempt to display. |
85 | * @param question_display_options $options controls what should and should | |
86 | * not be displayed. Used to get the context. | |
b36d2d06 | 87 | */ |
caeeff07 | 88 | public function files_read_only(question_attempt $qa, question_display_options $options) { |
8026d4aa | 89 | $files = $qa->get_last_qt_files('attachments', $options->context->id); |
caeeff07 TH |
90 | $output = array(); |
91 | ||
92 | foreach ($files as $file) { | |
caeeff07 | 93 | $output[] = html_writer::tag('p', html_writer::link($qa->get_response_file_url($file), |
559276b1 | 94 | $this->output->pix_icon(file_file_icon($file), get_mimetype_description($file), |
caeeff07 TH |
95 | 'moodle', array('class' => 'icon')) . ' ' . s($file->get_filename()))); |
96 | } | |
97 | return implode($output); | |
b36d2d06 TH |
98 | } |
99 | ||
100 | /** | |
101 | * Displays the input control for when the student should upload a single file. | |
d42dbe87 TH |
102 | * @param question_attempt $qa the question attempt to display. |
103 | * @param int $numallowed the maximum number of attachments allowed. -1 = unlimited. | |
104 | * @param question_display_options $options controls what should and should | |
105 | * not be displayed. Used to get the context. | |
b36d2d06 | 106 | */ |
121fd4c1 TH |
107 | public function files_input(question_attempt $qa, $numallowed, |
108 | question_display_options $options) { | |
8f0d40a3 | 109 | global $CFG, $COURSE; |
8026d4aa TH |
110 | require_once($CFG->dirroot . '/lib/form/filemanager.php'); |
111 | ||
112 | $pickeroptions = new stdClass(); | |
113 | $pickeroptions->mainfile = null; | |
d42dbe87 | 114 | $pickeroptions->maxfiles = $numallowed; |
8026d4aa TH |
115 | $pickeroptions->itemid = $qa->prepare_response_files_draft_itemid( |
116 | 'attachments', $options->context->id); | |
117 | $pickeroptions->context = $options->context; | |
151b0f94 | 118 | $pickeroptions->return_types = FILE_INTERNAL | FILE_CONTROLLED_LINK; |
8026d4aa | 119 | |
48d9c17d TH |
120 | $pickeroptions->itemid = $qa->prepare_response_files_draft_itemid( |
121 | 'attachments', $options->context->id); | |
94cb5a66 | 122 | $pickeroptions->accepted_types = $qa->get_question()->filetypeslist; |
48d9c17d | 123 | |
6adb5f13 | 124 | $fm = new form_filemanager($pickeroptions); |
8f0d40a3 | 125 | $fm->options->maxbytes = get_user_max_upload_file_size( |
85673c85 AN |
126 | $this->page->context, |
127 | $CFG->maxbytes, | |
128 | $COURSE->maxbytes, | |
129 | $qa->get_question()->maxbytes | |
130 | ); | |
6adb5f13 | 131 | $filesrenderer = $this->page->get_renderer('core', 'files'); |
94cb5a66 LB |
132 | |
133 | $text = ''; | |
134 | if (!empty($qa->get_question()->filetypeslist)) { | |
135 | $text = html_writer::tag('p', get_string('acceptedfiletypes', 'qtype_essay')); | |
136 | $filetypesutil = new \core_form\filetypes_util(); | |
137 | $filetypes = $qa->get_question()->filetypeslist; | |
138 | $filetypedescriptions = $filetypesutil->describe_file_types($filetypes); | |
139 | $text .= $this->render_from_template('core_form/filetypes-descriptions', $filetypedescriptions); | |
140 | } | |
6adb5f13 | 141 | return $filesrenderer->render($fm). html_writer::empty_tag( |
217f9a61 | 142 | 'input', array('type' => 'hidden', 'name' => $qa->get_qt_field_name('attachments'), |
94cb5a66 | 143 | 'value' => $pickeroptions->itemid)) . $text; |
b36d2d06 TH |
144 | } |
145 | ||
783af252 TH |
146 | public function manual_comment(question_attempt $qa, question_display_options $options) { |
147 | if ($options->manualcomment != question_display_options::EDITABLE) { | |
148 | return ''; | |
149 | } | |
150 | ||
151 | $question = $qa->get_question(); | |
152 | return html_writer::nonempty_tag('div', $question->format_text( | |
153 | $question->graderinfo, $question->graderinfo, $qa, 'qtype_essay', | |
154 | 'graderinfo', $question->id), array('class' => 'graderinfo')); | |
155 | } | |
b36d2d06 TH |
156 | } |
157 | ||
158 | ||
159 | /** | |
160 | * A base class to abstract out the differences between different type of | |
161 | * response format. | |
162 | * | |
163 | * @copyright 2011 The Open University | |
164 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
165 | */ | |
166 | abstract class qtype_essay_format_renderer_base extends plugin_renderer_base { | |
167 | /** | |
168 | * Render the students respone when the question is in read-only mode. | |
48d9c17d TH |
169 | * @param string $name the variable name this input edits. |
170 | * @param question_attempt $qa the question attempt being display. | |
171 | * @param question_attempt_step $step the current step. | |
b36d2d06 | 172 | * @param int $lines approximate size of input box to display. |
48d9c17d TH |
173 | * @param object $context the context teh output belongs to. |
174 | * @return string html to display the response. | |
b36d2d06 | 175 | */ |
48d9c17d TH |
176 | public abstract function response_area_read_only($name, question_attempt $qa, |
177 | question_attempt_step $step, $lines, $context); | |
b36d2d06 TH |
178 | |
179 | /** | |
180 | * Render the students respone when the question is in read-only mode. | |
48d9c17d TH |
181 | * @param string $name the variable name this input edits. |
182 | * @param question_attempt $qa the question attempt being display. | |
183 | * @param question_attempt_step $step the current step. | |
b36d2d06 | 184 | * @param int $lines approximate size of input box to display. |
48d9c17d TH |
185 | * @param object $context the context teh output belongs to. |
186 | * @return string html to display the response for editing. | |
187 | */ | |
188 | public abstract function response_area_input($name, question_attempt $qa, | |
189 | question_attempt_step $step, $lines, $context); | |
190 | ||
191 | /** | |
192 | * @return string specific class name to add to the input element. | |
b36d2d06 | 193 | */ |
48d9c17d | 194 | protected abstract function class_name(); |
b36d2d06 TH |
195 | } |
196 | ||
a4f765eb KT |
197 | /** |
198 | * An essay format renderer for essays where the student should not enter | |
199 | * any inline response. | |
200 | * | |
201 | * @copyright 2013 Binghamton University | |
202 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
203 | */ | |
204 | class qtype_essay_format_noinline_renderer extends plugin_renderer_base { | |
205 | ||
206 | protected function class_name() { | |
207 | return 'qtype_essay_noinline'; | |
208 | } | |
209 | ||
210 | public function response_area_read_only($name, $qa, $step, $lines, $context) { | |
211 | return ''; | |
212 | } | |
213 | ||
214 | public function response_area_input($name, $qa, $step, $lines, $context) { | |
215 | return ''; | |
216 | } | |
217 | ||
218 | } | |
b36d2d06 TH |
219 | |
220 | /** | |
221 | * An essay format renderer for essays where the student should use the HTML | |
222 | * editor without the file picker. | |
223 | * | |
224 | * @copyright 2011 The Open University | |
225 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
226 | */ | |
227 | class qtype_essay_format_editor_renderer extends plugin_renderer_base { | |
48d9c17d TH |
228 | protected function class_name() { |
229 | return 'qtype_essay_editor'; | |
b36d2d06 TH |
230 | } |
231 | ||
48d9c17d TH |
232 | public function response_area_read_only($name, $qa, $step, $lines, $context) { |
233 | return html_writer::tag('div', $this->prepare_response($name, $qa, $step, $context), | |
dbf72bb4 TH |
234 | ['class' => $this->class_name() . ' qtype_essay_response readonly', |
235 | 'style' => 'min-height: ' . ($lines * 1.5) . 'em;']); | |
236 | // Height $lines * 1.5 because that is a typical line-height on web pages. | |
237 | // That seems to give results that look OK. | |
48d9c17d TH |
238 | } |
239 | ||
240 | public function response_area_input($name, $qa, $step, $lines, $context) { | |
2d682972 TH |
241 | global $CFG; |
242 | require_once($CFG->dirroot . '/repository/lib.php'); | |
a54ecbbb | 243 | |
48d9c17d TH |
244 | $inputname = $qa->get_qt_field_name($name); |
245 | $responseformat = $step->get_qt_var($name . 'format'); | |
a54ecbbb TH |
246 | $id = $inputname . '_id'; |
247 | ||
248 | $editor = editors_get_preferred_editor($responseformat); | |
249 | $strformats = format_text_menu(); | |
250 | $formats = $editor->get_supported_formats(); | |
251 | foreach ($formats as $fid) { | |
252 | $formats[$fid] = $strformats[$fid]; | |
253 | } | |
254 | ||
562684e3 | 255 | list($draftitemid, $response) = $this->prepare_response_for_editing( |
48d9c17d TH |
256 | $name, $step, $context); |
257 | ||
988592c5 | 258 | $editor->set_text($response); |
a54ecbbb | 259 | $editor->use_editor($id, $this->get_editor_options($context), |
48d9c17d | 260 | $this->get_filepicker_options($context, $draftitemid)); |
a54ecbbb TH |
261 | |
262 | $output = ''; | |
48d9c17d TH |
263 | $output .= html_writer::start_tag('div', array('class' => |
264 | $this->class_name() . ' qtype_essay_response')); | |
a54ecbbb | 265 | |
562684e3 | 266 | $output .= html_writer::tag('div', html_writer::tag('textarea', s($response), |
0eeb3914 | 267 | array('id' => $id, 'name' => $inputname, 'rows' => $lines, 'cols' => 60, 'class' => 'form-control'))); |
a54ecbbb TH |
268 | |
269 | $output .= html_writer::start_tag('div'); | |
83690170 | 270 | if (count($formats) == 1) { |
a54ecbbb TH |
271 | reset($formats); |
272 | $output .= html_writer::empty_tag('input', array('type' => 'hidden', | |
273 | 'name' => $inputname . 'format', 'value' => key($formats))); | |
274 | ||
275 | } else { | |
c3cdf1e4 FM |
276 | $output .= html_writer::label(get_string('format'), 'menu' . $inputname . 'format', false); |
277 | $output .= ' '; | |
a54ecbbb TH |
278 | $output .= html_writer::select($formats, $inputname . 'format', $responseformat, ''); |
279 | } | |
280 | $output .= html_writer::end_tag('div'); | |
281 | ||
48d9c17d | 282 | $output .= $this->filepicker_html($inputname, $draftitemid); |
a54ecbbb TH |
283 | |
284 | $output .= html_writer::end_tag('div'); | |
285 | return $output; | |
286 | } | |
287 | ||
288 | /** | |
48d9c17d TH |
289 | * Prepare the response for read-only display. |
290 | * @param string $name the variable name this input edits. | |
291 | * @param question_attempt $qa the question attempt being display. | |
292 | * @param question_attempt_step $step the current step. | |
293 | * @param object $context the context the attempt belongs to. | |
294 | * @return string the response prepared for display. | |
a54ecbbb | 295 | */ |
48d9c17d TH |
296 | protected function prepare_response($name, question_attempt $qa, |
297 | question_attempt_step $step, $context) { | |
298 | if (!$step->has_qt_var($name)) { | |
299 | return ''; | |
300 | } | |
301 | ||
302 | $formatoptions = new stdClass(); | |
303 | $formatoptions->para = false; | |
304 | return format_text($step->get_qt_var($name), $step->get_qt_var($name . 'format'), | |
305 | $formatoptions); | |
a54ecbbb TH |
306 | } |
307 | ||
308 | /** | |
48d9c17d TH |
309 | * Prepare the response for editing. |
310 | * @param string $name the variable name this input edits. | |
311 | * @param question_attempt_step $step the current step. | |
312 | * @param object $context the context the attempt belongs to. | |
313 | * @return string the response prepared for display. | |
a54ecbbb | 314 | */ |
48d9c17d TH |
315 | protected function prepare_response_for_editing($name, |
316 | question_attempt_step $step, $context) { | |
317 | return array(0, $step->get_qt_var($name)); | |
a54ecbbb TH |
318 | } |
319 | ||
320 | /** | |
48d9c17d | 321 | * @param object $context the context the attempt belongs to. |
a54ecbbb TH |
322 | * @return array options for the editor. |
323 | */ | |
324 | protected function get_editor_options($context) { | |
2ba6706d DW |
325 | // Disable the text-editor autosave because quiz has it's own auto save function. |
326 | return array('context' => $context, 'autosave' => false); | |
a54ecbbb TH |
327 | } |
328 | ||
329 | /** | |
48d9c17d TH |
330 | * @param object $context the context the attempt belongs to. |
331 | * @param int $draftitemid draft item id. | |
332 | * @return array filepicker options for the editor. | |
333 | */ | |
334 | protected function get_filepicker_options($context, $draftitemid) { | |
c469b396 | 335 | return array('return_types' => FILE_INTERNAL | FILE_EXTERNAL); |
48d9c17d TH |
336 | } |
337 | ||
338 | /** | |
339 | * @param string $inputname input field name. | |
340 | * @param int $draftitemid draft file area itemid. | |
341 | * @return string HTML for the filepicker, if used. | |
a54ecbbb | 342 | */ |
48d9c17d | 343 | protected function filepicker_html($inputname, $draftitemid) { |
a54ecbbb | 344 | return ''; |
b36d2d06 TH |
345 | } |
346 | } | |
347 | ||
348 | ||
349 | /** | |
350 | * An essay format renderer for essays where the student should use the HTML | |
351 | * editor with the file picker. | |
352 | * | |
353 | * @copyright 2011 The Open University | |
354 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
355 | */ | |
a54ecbbb | 356 | class qtype_essay_format_editorfilepicker_renderer extends qtype_essay_format_editor_renderer { |
48d9c17d TH |
357 | protected function class_name() { |
358 | return 'qtype_essay_editorfilepicker'; | |
359 | } | |
360 | ||
361 | protected function prepare_response($name, question_attempt $qa, | |
362 | question_attempt_step $step, $context) { | |
363 | if (!$step->has_qt_var($name)) { | |
364 | return ''; | |
365 | } | |
a54ecbbb | 366 | |
48d9c17d TH |
367 | $formatoptions = new stdClass(); |
368 | $formatoptions->para = false; | |
369 | $text = $qa->rewrite_response_pluginfile_urls($step->get_qt_var($name), | |
370 | $context->id, 'answer', $step); | |
371 | return format_text($text, $step->get_qt_var($name . 'format'), $formatoptions); | |
a54ecbbb TH |
372 | } |
373 | ||
48d9c17d TH |
374 | protected function prepare_response_for_editing($name, |
375 | question_attempt_step $step, $context) { | |
376 | return $step->prepare_response_files_draft_itemid_with_text( | |
377 | $name, $context->id, $step->get_qt_var($name)); | |
b36d2d06 TH |
378 | } |
379 | ||
fd2ce923 AH |
380 | /** |
381 | * Get editor options for question response text area. | |
382 | * @param object $context the context the attempt belongs to. | |
383 | * @return array options for the editor. | |
384 | */ | |
48d9c17d | 385 | protected function get_editor_options($context) { |
fd2ce923 | 386 | return question_utils::get_editor_options($context); |
48d9c17d TH |
387 | } |
388 | ||
389 | /** | |
390 | * Get the options required to configure the filepicker for one of the editor | |
391 | * toolbar buttons. | |
fd2ce923 | 392 | * @deprecated since 3.5 |
48d9c17d TH |
393 | * @param mixed $acceptedtypes array of types of '*'. |
394 | * @param int $draftitemid the draft area item id. | |
395 | * @param object $context the context. | |
396 | * @return object the required options. | |
397 | */ | |
398 | protected function specific_filepicker_options($acceptedtypes, $draftitemid, $context) { | |
88d7a6a6 DM |
399 | debugging('qtype_essay_format_editorfilepicker_renderer::specific_filepicker_options() is deprecated, ' . |
400 | 'use question_utils::specific_filepicker_options() instead.', DEBUG_DEVELOPER); | |
fd2ce923 | 401 | |
48d9c17d TH |
402 | $filepickeroptions = new stdClass(); |
403 | $filepickeroptions->accepted_types = $acceptedtypes; | |
404 | $filepickeroptions->return_types = FILE_INTERNAL | FILE_EXTERNAL; | |
405 | $filepickeroptions->context = $context; | |
406 | $filepickeroptions->env = 'filepicker'; | |
407 | ||
408 | $options = initialise_filepicker($filepickeroptions); | |
409 | $options->context = $context; | |
410 | $options->client_id = uniqid(); | |
411 | $options->env = 'editor'; | |
412 | $options->itemid = $draftitemid; | |
413 | ||
414 | return $options; | |
415 | } | |
416 | ||
fd2ce923 AH |
417 | /** |
418 | * @param object $context the context the attempt belongs to. | |
419 | * @param int $draftitemid draft item id. | |
420 | * @return array filepicker options for the editor. | |
421 | */ | |
48d9c17d | 422 | protected function get_filepicker_options($context, $draftitemid) { |
fd2ce923 | 423 | return question_utils::get_filepicker_options($context, $draftitemid); |
48d9c17d TH |
424 | } |
425 | ||
426 | protected function filepicker_html($inputname, $draftitemid) { | |
427 | $nonjspickerurl = new moodle_url('/repository/draftfiles_manager.php', array( | |
428 | 'action' => 'browse', | |
429 | 'env' => 'editor', | |
430 | 'itemid' => $draftitemid, | |
431 | 'subdirs' => false, | |
432 | 'maxfiles' => -1, | |
433 | 'sesskey' => sesskey(), | |
434 | )); | |
435 | ||
436 | return html_writer::empty_tag('input', array('type' => 'hidden', | |
437 | 'name' => $inputname . ':itemid', 'value' => $draftitemid)) . | |
438 | html_writer::tag('noscript', html_writer::tag('div', | |
439 | html_writer::tag('object', '', array('type' => 'text/html', | |
440 | 'data' => $nonjspickerurl, 'height' => 160, 'width' => 600, | |
441 | 'style' => 'border: 1px solid #000;')))); | |
b36d2d06 TH |
442 | } |
443 | } | |
444 | ||
445 | ||
446 | /** | |
447 | * An essay format renderer for essays where the student should use a plain | |
448 | * input box, but with a normal, proportional font. | |
449 | * | |
450 | * @copyright 2011 The Open University | |
451 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
452 | */ | |
453 | class qtype_essay_format_plain_renderer extends plugin_renderer_base { | |
454 | /** | |
455 | * @return string the HTML for the textarea. | |
456 | */ | |
457 | protected function textarea($response, $lines, $attributes) { | |
0eeb3914 | 458 | $attributes['class'] = $this->class_name() . ' qtype_essay_response form-control'; |
b36d2d06 | 459 | $attributes['rows'] = $lines; |
dbf76faf | 460 | $attributes['cols'] = 60; |
b36d2d06 TH |
461 | return html_writer::tag('textarea', s($response), $attributes); |
462 | } | |
463 | ||
464 | protected function class_name() { | |
465 | return 'qtype_essay_plain'; | |
466 | } | |
467 | ||
48d9c17d TH |
468 | public function response_area_read_only($name, $qa, $step, $lines, $context) { |
469 | return $this->textarea($step->get_qt_var($name), $lines, array('readonly' => 'readonly')); | |
b36d2d06 TH |
470 | } |
471 | ||
48d9c17d TH |
472 | public function response_area_input($name, $qa, $step, $lines, $context) { |
473 | $inputname = $qa->get_qt_field_name($name); | |
474 | return $this->textarea($step->get_qt_var($name), $lines, array('name' => $inputname)) . | |
a54ecbbb TH |
475 | html_writer::empty_tag('input', array('type' => 'hidden', |
476 | 'name' => $inputname . 'format', 'value' => FORMAT_PLAIN)); | |
b36d2d06 TH |
477 | } |
478 | } | |
479 | ||
480 | ||
481 | /** | |
482 | * An essay format renderer for essays where the student should use a plain | |
483 | * input box with a monospaced font. You might use this, for example, for a | |
484 | * question where the students should type computer code. | |
485 | * | |
486 | * @copyright 2011 The Open University | |
487 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
488 | */ | |
489 | class qtype_essay_format_monospaced_renderer extends qtype_essay_format_plain_renderer { | |
490 | protected function class_name() { | |
491 | return 'qtype_essay_monospaced'; | |
492 | } | |
6d03299d | 493 | } |