Skip to content

Commit

Permalink
more work on godbolt integration
Browse files Browse the repository at this point in the history
  • Loading branch information
Tsche committed Feb 5, 2024
1 parent db078f9 commit d1b901b
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 29 deletions.
10 changes: 5 additions & 5 deletions docs/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -1361,8 +1361,8 @@ HTML_EXTRA_STYLESHEET = docs/style/doxygen-awesome.css \
docs/style/doxygen-awesome-sidebar-only.css \
docs/style/doxygen-awesome-sidebar-only-darkmode-toggle.css \
docs/github-corner.css \
doxygen-awesome-godbolt.css \
doxygen-awesome-alerts.css
doxygen-awesome/doxygen-awesome-godbolt.css \
doxygen-awesome/doxygen-awesome-alerts.css

# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
Expand All @@ -1377,9 +1377,9 @@ HTML_EXTRA_FILES = LICENSE \
docs/style/doxygen-awesome-fragment-copy-button.js \
docs/style/doxygen-awesome-paragraph-link.js \
docs/style/doxygen-awesome-interactive-toc.js \
doxygen-awesome-alerts.js \
doxygen-awesome-charts.js \
doxygen-awesome-godbolt.js
doxygen-awesome/doxygen-awesome-alerts.js \
doxygen-awesome/doxygen-awesome-charts.js \
doxygen-awesome/doxygen-awesome-godbolt.js

# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output
# should be rendered with a dark or light theme.
Expand Down
39 changes: 39 additions & 0 deletions docs/godbolt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Compiler Explorer

The `doxygen-awesome-godbolt` extension adds "Run in compiler explorer" buttons to code blocks with runnable content. Whether a code block is runnable is decided by looking at it's first line. If it matches a certain pattern, it is considered.


## Usage

TODO

## Example

C++ mode, default compiler, default options. Magic line is `//* c++`
```cpp
//* c++
#include <iostream>

int main() {
endl(std::cout << "Hello World");
}
```

C++ mode, Clang trunk, C++23 mode, O2. Magic line is `//* c++ clang_trunk -std=c++23 -O2`
```cpp
//* c++ clang_trunk -std=c++23 -O2
#include <print>

int main(){
std::println("Hello World");
}
```

Python mode, no options. Magic line is `//* python`
```py
#* python
import __hello__

if __name__ == "__main__":
__hello__.main()
```
18 changes: 18 additions & 0 deletions doxygen-awesome/doxygen-awesome-charts.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,21 @@ function render_chart(target_id, chart) {
return new frappe.Chart(target_id, data);
});
}

class DoxygenAwesomeCharts extends HTMLElement {
constructor() {
super();
this.onclick = this.runContent;
this.compiler = {};
}

static init() {
$(() => {

})
}


}

customElements.define('doxygen-awesome-charts', DoxygenAwesomeCharts);
59 changes: 35 additions & 24 deletions doxygen-awesome/doxygen-awesome-godbolt.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ class DoxygenAwesomeGodbolt extends HTMLElement {
static successDuration = 980;
static defaultSettings = {'language': 'c++', 'settings': { 'id': 'gsnapshot', 'options': '-std=c++20 -O3' }};

static init() {
static startsWithAny(str, substrs) {
return substrs.some(substr => str.startsWith(substr));
}

static init({magic=['//*', '#*'], replacements = {"#include <repr>": "foo"}} = {}) {
$(() => {
const fragments = document.getElementsByClassName('fragment');
for (const fragment of fragments) {
let magic_line = DoxygenAwesomeGodbolt.getContent(fragment).trimStart();
if (magic_line.startsWith('//*')) {
if (DoxygenAwesomeGodbolt.startsWithAny(magic_line, magic)) {
// extract only first line
magic_line = magic_line.split('\n', 1)[0];
} else {
Expand All @@ -34,18 +38,24 @@ class DoxygenAwesomeGodbolt extends HTMLElement {
// trim whitespace and magic line
const text = child.innerHTML;
const node = child.firstChild;
if (text.trim() != '' && !(node.className == 'comment' && node.innerHTML.startsWith('//*'))) {
if (text.trim() == ''){
child.remove();
} else if (node.className == 'comment' && DoxygenAwesomeGodbolt.startsWithAny(node.innerHTML, magic)) {
child.remove();
}
else {
break;
}
child.remove();
}

const fragmentWrapper = document.createElement('div');
fragmentWrapper.className = 'doxygen-awesome-fragment-wrapper';
const godboltButton = document.createElement('doxygen-awesome-godbolt');
godboltButton.innerHTML = DoxygenAwesomeGodbolt.runIcon;
godboltButton.title = DoxygenAwesomeGodbolt.title;
godboltButton.compiler = DoxygenAwesomeGodbolt.parseCompilerSettings(magic_line);
const fragmentWrapper = document.createElement('div');
fragmentWrapper.className = 'doxygen-awesome-fragment-wrapper';
const godboltButton = document.createElement('doxygen-awesome-godbolt');
godboltButton.innerHTML = DoxygenAwesomeGodbolt.runIcon;
godboltButton.title = DoxygenAwesomeGodbolt.title;
godboltButton.compiler = DoxygenAwesomeGodbolt.parseCompilerSettings(magic_line);
godboltButton.magic = magic;
godboltButton.replacements = replacements;

fragment.parentNode.replaceChild(fragmentWrapper, fragment);
fragmentWrapper.appendChild(fragment);
Expand All @@ -55,11 +65,13 @@ class DoxygenAwesomeGodbolt extends HTMLElement {
}

runContent() {
console.log(this.replacements)
const content = this.previousSibling.cloneNode(true);
let textContent = DoxygenAwesomeGodbolt.getContent(content);

const language = this.compiler['language']
const settings = {'id': this.compiler['id'], 'options': this.compiler['options']}
for (const entry in this.replacements) {
// replace includes with compiler explorer friendly alternatives
textContent.replace(entry, this.replacements[entry]);
}

// TODO fix includes
const clientstate = {
Expand All @@ -71,6 +83,8 @@ class DoxygenAwesomeGodbolt extends HTMLElement {
'executors': [{'compiler': this.compiler.settings}]
}]
};
console.log(clientstate)

const encoded = btoa(unescape(encodeURIComponent(JSON.stringify(clientstate))));
window.open(`https://godbolt.org/clientstate/${encoded}`, '_blank').focus();

Expand All @@ -88,33 +102,30 @@ class DoxygenAwesomeGodbolt extends HTMLElement {
}

static parseCompilerSettings(magic_line) {
if (!magic_line.startsWith('//*')) {
return {};
}

magic_line = magic_line.substr(3).trim();
if (!magic_line) {
return DoxygenAwesomeGodbolt.defaultSettings;
}
let cursor = magic_line.indexOf(' ');
if (cursor == -1) {
// no space found => only language, no other settings
return {'language': magic_line, 'settings': DoxygenAwesomeGodbolt.defaultSettings.settings};
return {'language': magic_line, 'settings': (magic_line == 'c++') ? DoxygenAwesomeGodbolt.defaultSettings.settings : {}};
}

const language = magic_line.substr(cursor);
const language = magic_line.substr(cursor + 1).trimStart();
magic_line = magic_line.substr(language.length) + 1;
let settings = {...DoxygenAwesomeGodbolt.defaultSettings.settings};
if (magic_line.startsWith('-')) {
let settings = language == 'c++' ? {...DoxygenAwesomeGodbolt.defaultSettings.settings} : {id: '', options: ''};

if (magic_line.startsWith('-') || magic_line.startsWith('/')) {
// no compiler set, but got options
settings.options = magic_line;
} else if (!magic_line.includes('-')) {
} else if (!magic_line.includes(' ')) {
// no options, but got compiler
settings.id = magic_line
} else {
const [head] = magic_line.split('-', 1);
const [head] = magic_line.split(' ', 1);
settings.id = head.trim();
settings.options = '-' + magic_line.substr(head.length + 1);
settings.options = magic_line.substr(head.length).trimStart();
}
return {'language': language, 'settings': settings};
}
Expand Down

0 comments on commit d1b901b

Please sign in to comment.