mirror of https://github.com/gogs/gogs.git
Ipython notebook support (#4070)
* added marked and notebookjs javascript libraries * added ipython notebook render support using javascript libraries * recompiled gogs.css to include ipynb-related css * removed superflous javascript library filespull/3750/merge
parent
39eb6df769
commit
9af0dd23dd
|
@ -812,7 +812,7 @@ footer .ui.language .menu {
|
|||
border: solid 1px #ccc;
|
||||
border-bottom-color: #bbb;
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 0 -1px 0 #bbb;
|
||||
box-shadow: inset 0 -1px 0 #bbbbbb;
|
||||
}
|
||||
.markdown:not(code) input[type="checkbox"] {
|
||||
vertical-align: middle !important;
|
||||
|
@ -883,7 +883,7 @@ footer .ui.language .menu {
|
|||
}
|
||||
.install form label {
|
||||
text-align: right;
|
||||
width: 320px !important;
|
||||
width: 320px;
|
||||
}
|
||||
.install form input {
|
||||
width: 35% !important;
|
||||
|
@ -892,7 +892,7 @@ footer .ui.language .menu {
|
|||
text-align: left;
|
||||
}
|
||||
.install form .field .help {
|
||||
margin-left: 335px !important;
|
||||
margin-left: 335px;
|
||||
}
|
||||
.install form .field.optional .title {
|
||||
margin-left: 38%;
|
||||
|
@ -928,18 +928,18 @@ footer .ui.language .menu {
|
|||
text-align: center;
|
||||
}
|
||||
#create-page-form form .header {
|
||||
padding-left: 280px !important;
|
||||
padding-left: 280px;
|
||||
}
|
||||
#create-page-form form .inline.field > label {
|
||||
text-align: right;
|
||||
width: 250px !important;
|
||||
width: 250px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
#create-page-form form .help {
|
||||
margin-left: 265px !important;
|
||||
margin-left: 265px;
|
||||
}
|
||||
#create-page-form form .optional .title {
|
||||
margin-left: 250px !important;
|
||||
margin-left: 250px;
|
||||
}
|
||||
#create-page-form form input,
|
||||
#create-page-form form textarea {
|
||||
|
@ -965,7 +965,7 @@ footer .ui.language .menu {
|
|||
.user.reset.password form .header,
|
||||
.user.signin form .header,
|
||||
.user.signup form .header {
|
||||
padding-left: 280px !important;
|
||||
padding-left: 280px;
|
||||
}
|
||||
.user.activate form .inline.field > label,
|
||||
.user.forgot.password form .inline.field > label,
|
||||
|
@ -973,7 +973,7 @@ footer .ui.language .menu {
|
|||
.user.signin form .inline.field > label,
|
||||
.user.signup form .inline.field > label {
|
||||
text-align: right;
|
||||
width: 250px !important;
|
||||
width: 250px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.user.activate form .help,
|
||||
|
@ -981,14 +981,14 @@ footer .ui.language .menu {
|
|||
.user.reset.password form .help,
|
||||
.user.signin form .help,
|
||||
.user.signup form .help {
|
||||
margin-left: 265px !important;
|
||||
margin-left: 265px;
|
||||
}
|
||||
.user.activate form .optional .title,
|
||||
.user.forgot.password form .optional .title,
|
||||
.user.reset.password form .optional .title,
|
||||
.user.signin form .optional .title,
|
||||
.user.signup form .optional .title {
|
||||
margin-left: 250px !important;
|
||||
margin-left: 250px;
|
||||
}
|
||||
.user.activate form input,
|
||||
.user.forgot.password form input,
|
||||
|
@ -1014,14 +1014,14 @@ footer .ui.language .menu {
|
|||
.user.reset.password form .header,
|
||||
.user.signin form .header,
|
||||
.user.signup form .header {
|
||||
padding-left: 230px !important;
|
||||
padding-left: 230px;
|
||||
}
|
||||
.user.activate form .inline.field > label,
|
||||
.user.forgot.password form .inline.field > label,
|
||||
.user.reset.password form .inline.field > label,
|
||||
.user.signin form .inline.field > label,
|
||||
.user.signup form .inline.field > label {
|
||||
width: 200px !important;
|
||||
width: 200px;
|
||||
}
|
||||
.repository.new.repo form,
|
||||
.repository.new.migrate form,
|
||||
|
@ -1037,24 +1037,24 @@ footer .ui.language .menu {
|
|||
.repository.new.repo form .header,
|
||||
.repository.new.migrate form .header,
|
||||
.repository.new.fork form .header {
|
||||
padding-left: 280px !important;
|
||||
padding-left: 280px;
|
||||
}
|
||||
.repository.new.repo form .inline.field > label,
|
||||
.repository.new.migrate form .inline.field > label,
|
||||
.repository.new.fork form .inline.field > label {
|
||||
text-align: right;
|
||||
width: 250px !important;
|
||||
width: 250px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.repository.new.repo form .help,
|
||||
.repository.new.migrate form .help,
|
||||
.repository.new.fork form .help {
|
||||
margin-left: 265px !important;
|
||||
margin-left: 265px;
|
||||
}
|
||||
.repository.new.repo form .optional .title,
|
||||
.repository.new.migrate form .optional .title,
|
||||
.repository.new.fork form .optional .title {
|
||||
margin-left: 250px !important;
|
||||
margin-left: 250px;
|
||||
}
|
||||
.repository.new.repo form input,
|
||||
.repository.new.migrate form input,
|
||||
|
@ -1083,7 +1083,7 @@ footer .ui.language .menu {
|
|||
width: 50%!important;
|
||||
}
|
||||
.repository.new.repo .ui.form #auto-init {
|
||||
margin-left: 265px !important;
|
||||
margin-left: 265px;
|
||||
}
|
||||
.new.webhook form .help {
|
||||
margin-left: 25px;
|
||||
|
@ -1306,6 +1306,81 @@ footer .ui.language .menu {
|
|||
.repository.file.list #file-content .view-raw img {
|
||||
margin-bottom: -5px;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook {
|
||||
margin-left: 80px;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-notebook {
|
||||
line-height: 1.5;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-stdout,
|
||||
.repository.file.list #file-content #ipython-notebook .nb-stderr {
|
||||
white-space: pre-wrap;
|
||||
margin: 1em 0;
|
||||
padding: 0.1em 0.5em;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-stderr {
|
||||
background-color: #FAA;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-cell + .nb-cell {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-output table {
|
||||
border: 1px solid #000;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-output th {
|
||||
font-weight: bold;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-output th,
|
||||
.repository.file.list #file-content #ipython-notebook .nb-output td {
|
||||
border: 1px solid #000;
|
||||
padding: 0.25em;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-cell {
|
||||
position: relative;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-raw-cell {
|
||||
white-space: pre-wrap;
|
||||
background-color: #f5f2f0;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-output {
|
||||
min-height: 1em;
|
||||
width: 100%;
|
||||
overflow-x: scroll;
|
||||
border-right: 1px dotted #CCC;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-output img {
|
||||
max-width: 100%;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-output:before,
|
||||
.repository.file.list #file-content #ipython-notebook .nb-input:before {
|
||||
position: absolute;
|
||||
font-family: monospace;
|
||||
color: #999;
|
||||
left: -7.5em;
|
||||
width: 7em;
|
||||
text-align: right;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-input:before {
|
||||
content: "In [" attr(data-prompt-number) "]:";
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-output:before {
|
||||
content: "Out [" attr(data-prompt-number) "]:";
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook .nb-markdown-cell {
|
||||
background-color: #eee;
|
||||
margin-left: -80px;
|
||||
padding: 11.5px 10px 19.5px 80px;
|
||||
}
|
||||
.repository.file.list #file-content #ipython-notebook div[style="max-height:1000px;max-width:1500px;overflow:auto;"] {
|
||||
max-height: none !important;
|
||||
}
|
||||
.repository.file.list #file-content .plain-text {
|
||||
font-size: 14px;
|
||||
padding: 10px 15px;
|
||||
|
@ -2539,18 +2614,18 @@ footer .ui.language .menu {
|
|||
text-align: center;
|
||||
}
|
||||
.organization.new.org form .header {
|
||||
padding-left: 280px !important;
|
||||
padding-left: 280px;
|
||||
}
|
||||
.organization.new.org form .inline.field > label {
|
||||
text-align: right;
|
||||
width: 250px !important;
|
||||
width: 250px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.organization.new.org form .help {
|
||||
margin-left: 265px !important;
|
||||
margin-left: 265px;
|
||||
}
|
||||
.organization.new.org form .optional .title {
|
||||
margin-left: 250px !important;
|
||||
margin-left: 250px;
|
||||
}
|
||||
.organization.new.org form input,
|
||||
.organization.new.org form textarea {
|
||||
|
|
|
@ -251,6 +251,95 @@
|
|||
}
|
||||
}
|
||||
|
||||
#ipython-notebook {
|
||||
margin-left: 80px;
|
||||
|
||||
.nb-notebook {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.nb-stdout, .nb-stderr {
|
||||
white-space: pre-wrap;
|
||||
margin: 1em 0;
|
||||
padding: 0.1em 0.5em;
|
||||
}
|
||||
|
||||
.nb-stderr {
|
||||
background-color: #FAA;
|
||||
}
|
||||
|
||||
.nb-cell + .nb-cell {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.nb-output table {
|
||||
border: 1px solid #000;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.nb-output th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.nb-output th, .nb-output td {
|
||||
border: 1px solid #000;
|
||||
padding: 0.25em;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.nb-cell {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nb-raw-cell {
|
||||
white-space: pre-wrap;
|
||||
background-color: #f5f2f0;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
}
|
||||
|
||||
.nb-output {
|
||||
min-height: 1em;
|
||||
width: 100%;
|
||||
overflow-x: scroll;
|
||||
border-right: 1px dotted #CCC;
|
||||
}
|
||||
|
||||
.nb-output img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.nb-output:before, .nb-input:before {
|
||||
position: absolute;
|
||||
font-family: monospace;
|
||||
color: #999;
|
||||
left: -7.5em;
|
||||
width: 7em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.nb-input:before {
|
||||
content: "In [" attr(data-prompt-number) "]:";
|
||||
}
|
||||
.nb-output:before {
|
||||
content: "Out [" attr(data-prompt-number) "]:";
|
||||
}
|
||||
|
||||
.nb-markdown-cell {
|
||||
background-color: #eee;
|
||||
margin-left: -80px;
|
||||
padding: 11.5px 10px 19.5px 80px;
|
||||
}
|
||||
|
||||
// Fix pandas dataframe formatting
|
||||
div[style="max-height:1000px;max-width:1500px;overflow:auto;"] {
|
||||
max-height: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.plain-text {
|
||||
font-size: 14px;
|
||||
padding: 10px 15px;
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014, Jeremy Singer-Vine
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
File diff suppressed because one or more lines are too long
|
@ -156,6 +156,8 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
|||
ctx.Data["IsMarkdown"] = isMarkdown
|
||||
ctx.Data["ReadmeExist"] = isMarkdown && markdown.IsReadmeFile(blob.Name())
|
||||
|
||||
ctx.Data["IsIPyNB"] = strings.HasSuffix(blob.Name(), ".ipynb")
|
||||
|
||||
if isMarkdown {
|
||||
ctx.Data["FileContent"] = string(markdown.Render(buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
|
||||
} else {
|
||||
|
|
|
@ -21,6 +21,12 @@
|
|||
<link rel="stylesheet" href="{{AppSubUrl}}/assets/font-awesome-4.6.3/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/assets/octicons-4.3.0/octicons.min.css">
|
||||
|
||||
<!-- notebook.js for rendering ipython notebooks and marked.js for rendering markdown in notebooks -->
|
||||
{{if .IsIPyNB }}
|
||||
<script src="{{AppSubUrl}}/plugins/notebookjs-0.2.6/notebook.min.js"></script>
|
||||
<script src="{{AppSubUrl}}/plugins/marked-0.3.6/marked.min.js"></script>
|
||||
{{end}}
|
||||
|
||||
{{if .RequireSimpleMDE}}
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/plugins/simplemde-1.10.1/simplemde.min.css">
|
||||
<script src="{{AppSubUrl}}/plugins/simplemde-1.10.1/simplemde.min.js"></script>
|
||||
|
|
|
@ -39,6 +39,26 @@
|
|||
<div class="file-view {{if .IsMarkdown}}markdown{{else if .ReadmeInList}}plain-text{{else if .IsTextFile}}code-view{{end}} has-emoji">
|
||||
{{if or .IsMarkdown .ReadmeInList}}
|
||||
{{if .FileContent}}{{.FileContent | Str2html}}{{end}}
|
||||
{{else if .IsIPyNB}}
|
||||
{{if .FileContent}}
|
||||
<div id="ipython-notebook"></div>
|
||||
<script>
|
||||
var rendered = null;
|
||||
$.getJSON("{{.RawFileLink}}", null, function(notebook_json) {
|
||||
var notebook = nb.parse(notebook_json);
|
||||
rendered = notebook.render();
|
||||
$("#ipython-notebook").append(rendered);
|
||||
$("#ipython-notebook code").each(function(i, block) {
|
||||
$(block).addClass("py").addClass("python");
|
||||
hljs.highlightBlock(block);
|
||||
});
|
||||
|
||||
$("#ipython-notebook .nb-markdown-cell").each(function(i, markdown) {
|
||||
$(markdown).html(marked($(markdown).html()));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{{end}}
|
||||
{{else if not .IsTextFile}}
|
||||
<div class="view-raw ui center">
|
||||
{{if .IsImageFile}}
|
||||
|
|
Loading…
Reference in New Issue