-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow spaces in names of files attached to markdown cells #8095
Conversation
encode the URIs of attachments to be valid.
Thanks for making a pull request to JupyterLab! To try out this branch on binder, follow this link: |
I put this in the 2.1 milestone, assuming we can finish it up by this weekend. |
Co-Authored-By: Jason Grout <jasongrout@users.noreply.github.com>
Co-Authored-By: Jason Grout <jasongrout@users.noreply.github.com>
Co-Authored-By: Jason Grout <jasongrout@users.noreply.github.com>
Sounds good. The one other thing maybe worth considering is what the expected behavior is for non-image files? The |
Great question. Is it easy to determine if the file is an image? Do we have the mimetype in the clipboard data? I suppose we can guess based on extension as a last resort? |
Reading up on the commonmark spec, apparently you can have a space in the filename, you just have surround the link with |
To quote the commonmark spec: https://spec.commonmark.org/0.29/#links
|
Should be possible to determine if a file is an image. The clipboardData has a
Seems to me that the most reasonable to support are:
|
So what if we just take the attachmentName, do a manual regex for newlines and |
When I just type in a reference to a file using maybe that's an issue with markedjs? |
|
Also, while the types are well defined for clipboardEvents they are not defined for drop events:
|
It does seem that markdown-it supports the |
c.f. #272 |
Checks if the cell already has an attachment using that name. If yes then start adding numbers such that image.png will become image_1.png etc. The regex is used for this splitting in order to only split on the final . (i.e. allow filenames such as image.image.png) and to include the . for reconstructing the filename.
Yes, I think so.
Awesome!
This is because the attachment resolver, what actually converts this attachment: syntax to a data url for the html on the page, filters for only images: jupyterlab/packages/attachments/src/model.ts Lines 412 to 419 in c4a0f4a
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more review comments.
Another way to approach the attachment conflicts is to generate a UUID, which becomes the URI, so you have unique UUIDs for every attachment. The bad thing about a UUID is that there is no intrinsic meaning in the names of entries in the attachments list, but maybe that's okay? The association to a file name is in the markdown text if a person wants to cross reference.
Yeah. When I modify that line I can easily embed videos by dragging them in. The question is then where to keep the list of valid mimetypes. It seems to me that both Currently I've changed the AttachmentsResolver like so: diff --git a/packages/attachments/src/model.ts b/packages/attachments/src/model.ts
index 973e4d0d6..3dacd3224 100644
--- a/packages/attachments/src/model.ts
+++ b/packages/attachments/src/model.ts
@@ -14,7 +14,6 @@ import {
import {
IAttachmentModel,
AttachmentModel,
- imageRendererFactory
} from '@jupyterlab/rendermime';
import { IRenderMime } from '@jupyterlab/rendermime-interfaces';
@@ -378,6 +377,7 @@ export class AttachmentsResolver implements IRenderMime.IResolver {
constructor(options: AttachmentsResolver.IOptions) {
this._parent = options.parent || null;
this._model = options.model;
+ this.supportedTypes = ['video/mp4','video/webm','video/ogg','image/bmp', 'image/png', 'image/jpeg', 'image/gif'];
}
/**
* Resolve a relative url to a correct server path.
@@ -411,7 +411,7 @@ export class AttachmentsResolver implements IRenderMime.IResolver {
// Only support known safe types:
if (
mimeType === undefined ||
- imageRendererFactory.mimeTypes.indexOf(mimeType) === -1
+ this.supportedTypes.indexOf(mimeType) === -1
) {
return Promise.reject(
`Cannot render unknown image mime type "${mimeType}".`
@@ -434,6 +434,7 @@ export class AttachmentsResolver implements IRenderMime.IResolver {
private _model: IAttachmentsModel;
private _parent: IRenderMime.IResolver | null;
+ readonly supportedTypes: ReadonlyArray<string>;
}
/** |
The uuid approach also removes the need to encode URIs, and helps negate possibility someone seeing the filename in the embedding and thinking that if they change the file on disk then the markdown cell will update. |
Oh yeah, I hadn't thought of that. Switching to UUID makes it clearer that this is a snapshot of the file, and it is different than actually linking to the file on disk. Yeah, I would suggest moving to UUID for that reason, but maybe keep the extension? |
Use uuid4 to generate the URI in all instances, if the file has an extension preserve that information. Also add a check if the file type is an image which is currently the only valid markdown embedding.
Co-Authored-By: Jason Grout <jasongrout@users.noreply.github.com>
I switched to using UUIDs and keep the extension when one exists. I also check if the file is an image type because that's the only file type supported by the If possible it'd be nice to add support for videos as well. Though as noted, that would require changes to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the new UUID support! I have a few more suggestions for it. I think we are converging to something really nice here!
@@ -1272,20 +1273,21 @@ export abstract class AttachmentsCell extends Cell { | |||
CONTENTS_MIME_RICH | |||
) as DirListing.IContentsThunk; | |||
if (model.type === 'file') { | |||
this.updateCellSourceWithAttachment(model.name); | |||
const URI = this._generateURI(model.name); | |||
this.updateCellSourceWithAttachment(model.name, URI); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Below, we now check to see if the data is an image mimetype. Should we do the same here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's already some mimetype filtering happening in this function when if makes the array of supportedMimetypes
jupyterlab/packages/cells/src/widget.ts
Lines 1245 to 1247 in 5977421
const supportedMimeTypes = toArray( | |
filter(event.mimeData.types(), mimeType => { | |
if (mimeType === CONTENTS_MIME_RICH) { |
I hoped that this was doing enough filtering. I wasn't able to test this though, because I don't seem to be able to trigger this event. Should this be triggerable by dragging an image from the jupyterlab filebrowser?
I don't think it requires anything added to the rendermime package - that's completely separate from what we are doing here. I think how it would work is that we construct an HTML video element with a url of jupyterlab/packages/attachments/src/model.ts Lines 411 to 419 in c4a0f4a
On the other hand, supporting video would be a nice place to draw the line for this PR, and put in a new PR to support that. |
Co-Authored-By: Jason Grout <jasongrout@users.noreply.github.com>
Co-Authored-By: Jason Grout <jasongrout@users.noreply.github.com>
Co-Authored-By: Jason Grout <jasongrout@users.noreply.github.com>
Yeah. I would like to add a readonly array
That seems reasonable. A side effect of this PR is that I'm now working towards adding a videoRenderer, so a separate PR could include a mimerenderer and support for video and audio in markdown cells. |
This reverts a suggested change that breaks backwards compatibility
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall!
Just one little typo.
References
partially fixes: #8067:
This will fix the dragging and dropping behavior, but as noted #8062 (comment) the other issue raised there of typing in the name will remain as that is not supported by markdown.
partially addresses: #8062:
the spaces in names also came up there.
Code changes
call
encodeURI
when setting the attachment to a markdown cell. This allows the attachment to be found when the markdown is being rendered. I was able to confirm that this fixes the issues fornativeDrop
andpaste
events. However, I don't know how to trigger thelm-drop
events so I wasn't able to directly verify that this fixes the issue for those events. If these are meant to be triggered by dragging a file from the jupyterlab filebrowser then I was unable to do that and have a new issue to report.User-facing changes
An image with spaces in the name that is drag and dropped or copied into a markdown cell will now render:
Backwards-incompatible changes
N/A