diff --git a/pxtblocks/fields/field_asset.ts b/pxtblocks/fields/field_asset.ts index d780315a95d3..e4f07e51b85e 100644 --- a/pxtblocks/fields/field_asset.ts +++ b/pxtblocks/fields/field_asset.ts @@ -403,7 +403,7 @@ export abstract class FieldAssetEditor { } else { result = project.createNewSong(result.song, result.meta.displayName); } - this.isAsset = true; - return pxt.getTSReferenceForAsset(result, this.isPython); + let out = pxt.getTSReferenceForAsset(result, this.isPython); + if (!this.isAsset) { + if (this.isPython) { + out = `music.create_song(${out})`; + } + else { + out = `music.createSong(${out})`; + } + } + return out; } let hexString = pxt.assets.music.encodeSongToHex(result.song); @@ -101,25 +109,26 @@ function createFakeAsset(song: pxt.assets.music.Song): pxt.Song { } } +const regexes = [ + // typescript + "music\\s*\\.\\s*createSong\\s*\\(\\s*hex`[a-fA-F0-9\\s\\n]*`\\s*\\)", + "assets\\s*\\.\\s*song\\s*`[a-zA-Z_\\s\\n]*`", + + // python + 'music\\s*\\.\\s*create_song\\s*\\(\\s*hex\\s*\\(\\s*"""[a-fA-F0-9\\s\\n]*"""\\s*\\)\\s*\\)', + 'music\\s*\\.\\s*createSong\\s*\\(\\s*hex\\s*\\(\\s*"""[a-fA-F0-9\\s\\n]*"""\\s*\\)\\s*\\)', + 'assets\\s*\\.\\s*song\\s*\\(\\s*"""[a-zA-Z_\\s\\n]*"""\\s*\\)' +]; + +const searchString = regexes.map(r => `(?:${r})`).join("|"); + export const songEditorDefinition: pxt.editor.MonacoFieldEditorDefinition = { id: fieldEditorId, foldMatches: true, glyphCssClass: "fas fa-music sprite-focus-hover", heightInPixels: 510, matcher: { - /** - * This is horrendous-looking regex matches both the asset reference syntax: - * assets.song`name` - * assets.song("""name""") - * - * and the hex-literal syntax: - * music.createSong(hex`01234` - * music.create_song(hex("""01234""") - * - * For the hex literal matches, it includes the call to music.createSong since - * hex buffers can also be used for other things - */ - searchString: "(?:(?:assets\\s*\\.\\s*song)|(?:music\\s*\\.\\s*create(?:S|_s)ong\\s*\\(\\s*hex))\\s*(?:`|\\(\\s*\"\"\")(?:(?:[^(){}:\\[\\]\"';?/,+\\-=*&|^%!`~]|\\n)*)\\s*(?:`|\"\"\"\\s*\\))", + searchString: searchString, isRegex: true, matchCase: true, matchWholeWord: false diff --git a/pxteditor/monaco-fields/field_sprite.ts b/pxteditor/monaco-fields/field_sprite.ts index d81b34d5d396..6af4a6020a27 100644 --- a/pxteditor/monaco-fields/field_sprite.ts +++ b/pxteditor/monaco-fields/field_sprite.ts @@ -85,14 +85,27 @@ function createFakeAsset(bitmap: pxt.sprite.Bitmap): pxt.ProjectImage { } } +const regexes = [ + // typescript + "img\\s*`[\\.a-zA-Z0-9#\\n\\s]*`", + "bmp\\s*`[\\.a-zA-Z0-9#\\n\\s]*`", + "assets\\s*\\.\\s*image\\s*`[a-zA-Z_\\s\\n]*`", + + // python + 'img\\s*\\(\\s*"""[\\.a-zA-Z0-9#\\n\\s]*"""\\s*\\)', + 'bmp\\s*\\(\\s*"""[\\.a-zA-Z0-9#\\n\\s]*"""\\s*\\)', + 'assets\\s*\\.\\s*image\\s*\\(\\s*"""[a-zA-Z_\\s\\n]*"""\\s*\\)' +]; + +const searchString = regexes.map(r => `(?:${r})`).join("|"); + export const spriteEditorDefinition: pxt.editor.MonacoFieldEditorDefinition = { id: fieldEditorId, foldMatches: true, glyphCssClass: "sprite-editor-glyph sprite-focus-hover", heightInPixels: 510, matcher: { - // match both JS and python - searchString: "(?:img|bmp|assets\\s*\\.\\s*image)\\s*(?:`|\\(\\s*\"\"\")(?:(?:[^(){}:\\[\\]\"';?/,+\\-=*&|^%!`~]|\\n)*)\\s*(?:`|\"\"\"\\s*\\))", + searchString: searchString, isRegex: true, matchCase: true, matchWholeWord: false diff --git a/pxtlib/docsrender.ts b/pxtlib/docsrender.ts index ef75a00edee2..b28a17340837 100644 --- a/pxtlib/docsrender.ts +++ b/pxtlib/docsrender.ts @@ -30,6 +30,7 @@ namespace pxt.docs { lexer: (src: string, options?: any) => any[]; setOptions: (options: any) => void; parseInline?: (src: string, options?: any) => string; + parse?: (src: string, options?: any) => string; } interface MarkedImageToken { @@ -690,7 +691,7 @@ ${opts.repo.name.replace(/^pxt-/, '')}=github:${opts.repo.fullName}#${opts.repo. return macro || 'unknown macro' }); - let html = markedInstance(markdown); + let html = markedInstance.parse(markdown); const coerceToString = (value: unknown, fallback: string = "") => { if (typeof value === "string") return value; if (value && typeof (value as any).toString === "function") { diff --git a/teachertool/src/components/HeaderBar.tsx b/teachertool/src/components/HeaderBar.tsx index 826b1c30b231..5c3388f60a88 100644 --- a/teachertool/src/components/HeaderBar.tsx +++ b/teachertool/src/components/HeaderBar.tsx @@ -52,7 +52,7 @@ export const HeaderBar: React.FC = () => { )} ) : ( - {appTheme.organization} + {appTheme.organization} )} ); @@ -67,14 +67,20 @@ export const HeaderBar: React.FC = () => { onClick={onBrandIconClick} > {appTheme.useTextLogo ? ( - [ - + <> + {appTheme.organizationText} - , - + + {appTheme.organizationShortText || appTheme.organizationText} - , - ] + + ) : appTheme.logo || appTheme.portraitLogo ? ( <> {appTheme.logo && ( @@ -93,7 +99,7 @@ export const HeaderBar: React.FC = () => { )} ) : ( - {appTheme.boardName} + {appTheme.boardName} )} ); diff --git a/teachertool/src/components/styling/HeaderBar.module.scss b/teachertool/src/components/styling/HeaderBar.module.scss index 4754987453b4..b5dc51cc7974 100644 --- a/teachertool/src/components/styling/HeaderBar.module.scss +++ b/teachertool/src/components/styling/HeaderBar.module.scss @@ -28,6 +28,14 @@ } } + .organization-name { + font-size: 1.125rem; + font-weight: 600; + margin-left: 1rem; + color: var(--pxt-header-foreground); + white-space: nowrap; + } + .brand { display: flex; align-items: center; @@ -43,6 +51,19 @@ height: 1.1rem; margin: 0 1rem; } + + .brand-text, + .brand-text-short { + font-size: 1.25rem; + font-weight: 600; + color: var(--pxt-header-foreground); + margin-left: 1rem; + white-space: nowrap; + } + + .brand-text-short { + font-size: 1.125rem; + } } .centered-panel {