J'essaie d'afficher mon code sur un site Web, mais je ne parviens pas à conserver correctement l'indentation des espaces.
Par exemple, étant donné l'extrait suivant:
<html>
<body>
Here is my code:
<pre>
def some_funtion
return 'Hello, World!'
end
</pre>
<body>
</html>
Ceci est affiché dans le navigateur comme:
Here is my code:
def some_funtion
return 'Hello, World!'
end
Quand je voudrais qu'il soit affiché comme:
Here is my code:
def some_funtion
return 'Hello, World!'
end
La différence est que le niveau d'indentation actuel de la balise HTML avant est ajouté à l'indentation du code. J'utilise nanoc en tant que générateur de site Web statique et j'utilise google prettify pour ajouter également la coloration syntaxique.
Quelqu'un peut-il offrir des suggestions?
PRE
est destiné à préserver les espaces tels qu'ils apparaissent (à moins qu'ils ne soient modifiés par white-space
dans CSS, qui ne dispose pas de suffisamment de flexibilité pour prendre en charge le code de formatage).
Avant
Le formatage est préservé, de même que toute l'indentation en dehors de la balise PRE
. Il serait bien d’avoir une conservation des espaces qui utilise l’emplacement de la balise comme point de départ.
Après
Le contenu est toujours formaté tel que déclaré, mais les espaces non-normaux superflus provoqués par la position de la balise PRE
dans le document sont supprimés.
Je suis venu avec le plugin suivant pour résoudre le problème de vouloir supprimer les espaces superflus causés par l'indentation du contour du document. Ce code utilise la première ligne à l'intérieur de la balise PRE pour déterminer combien il a été mis en retrait uniquement en raison de l'indentation du document.
Ce code fonctionne dans IE7, IE8, IE9, Firefox et Chrome. Je l’ai brièvement testé avec la bibliothèque Prettify pour combiner le formatage préservé avec de jolies impressions. Assurez-vous que la première ligne de la PRE
représente réellement le niveau d'indentation de base que vous souhaitez ignorer (ou vous pouvez modifier le plug-in pour qu'il soit plus intelligent).
Ceci est un code approximatif. Si vous trouvez une erreur ou si cela ne fonctionne pas comme vous le souhaitez, corrigez-le/commentez; ne vous contentez pas de voter par inversion. J'ai écrit ce code pour résoudre un problème que j'avais et je suis activement en l'utilisant, j'aimerais donc qu'il soit aussi solide que possible!
/*!
*** prettyPre ***/
(function( $ ) {
$.fn.prettyPre = function( method ) {
var defaults = {
ignoreExpression: /\s/ // what should be ignored?
};
var methods = {
init: function( options ) {
this.each( function() {
var context = $.extend( {}, defaults, options );
var $obj = $( this );
var usingInnerText = true;
var text = $obj.get( 0 ).innerText;
// some browsers support innerText...some don't...some ONLY work with innerText.
if ( typeof text == "undefined" ) {
text = $obj.html();
usingInnerText = false;
}
// use the first line as a baseline for how many unwanted leading whitespace characters are present
var superfluousSpaceCount = 0;
var currentChar = text.substring( 0, 1 );
while ( context.ignoreExpression.test( currentChar ) ) {
currentChar = text.substring( ++superfluousSpaceCount, superfluousSpaceCount + 1 );
}
// split
var parts = text.split( "\n" );
var reformattedText = "";
// reconstruct
var length = parts.length;
for ( var i = 0; i < length; i++ ) {
// cleanup, and don't append a trailing newline if we are on the last line
reformattedText += parts[i].substring( superfluousSpaceCount ) + ( i == length - 1 ? "" : "\n" );
}
// modify original
if ( usingInnerText ) {
$obj.get( 0 ).innerText = reformattedText;
}
else {
// This does not appear to execute code in any browser but the onus is on the developer to not
// put raw input from a user anywhere on a page, even if it doesn't execute!
$obj.html( reformattedText );
}
} );
}
}
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ) );
}
else if ( typeof method === "object" || !method ) {
return methods.init.apply( this, arguments );
}
else {
$.error( "Method " + method + " does not exist on jQuery.prettyPre." );
}
}
} )( jQuery );
Ce plugin peut ensuite être appliqué à l’aide d’un sélecteur jQuery standard:
<script>
$( function() { $("PRE").prettyPre(); } );
</script>
Les navigateurs ignorant les commentaires, vous pouvez les utiliser pour mettre en retrait le contenu de votre balise pre
.
<html>
<body>
<main>
Here is my code with hack:
<pre>
<!-- -->def some_function
<!-- --> return 'Hello, World!'
<!-- -->end
</pre>
Here is my code without hack:
<pre>
def some_function
return 'Hello, World!'
end
</pre>
</main>
<body>
</html>
NOTE: un wrapper principal a été ajouté pour fournir assez d'espace pour les commentaires.
Une meilleure solution consiste à supprimer le plus grand espace blanc en utilisant soit votre processus de construction, soit votre processus de rendu principal. Si vous utilisez node.js, vous pouvez utiliser un flux que j'ai écrit appelé predentation . Vous pouvez utiliser n’importe quel langage pour construire un outil similaire.
Avant
<html>
<body>
Here is my code:
<pre>
def some_function
return 'Hello, World!'
end
</pre>
</body>
</html>
Après
<html>
<body>
Here is my code:
<pre>
def some_function
return 'Hello, World!'
end
</pre>
</body>
</html>
pre
pre
avec white-space: pre
ajouté par CSSVoir cette réponse pour supprimer l'indentation avec JavaScript
white-space: pre
Réussi à le faire avec JavaScript. Cela fonctionne dans Internet Explorer 9 et Chrome 15, je n'ai pas testé les anciennes versions. Cela devrait fonctionner dans Firefox 11 lorsque le support de outerHTML
est ajouté (voir ici ), en attendant, certaines implémentations personnalisées sont disponibles sur le Web. Un exercice pour le lecteur est de se débarrasser de l’indentation finale (jusqu’à ce que je prenne le temps de le terminer et de mettre à jour cette réponse).
Je marquerai également ceci comme wiki de communauté pour une édition facile.
Notez que vous devrez reformater l'exemple pour utiliser des tabulations comme indentation ou modifier la regex pour qu'elle utilise des espaces.
<!DOCTYPE html>
<html>
<head>
<title>Hello, World!</title>
</head>
<body>
<pre>
<html>
<head>
<title>Hello World Example</title>
</head>
<body>
Hello, World!
</body>
</html>
</pre>
<pre>
class HelloWorld
{
public static int Main(String[] args)
{
Console.WriteLine(&quot;Hello, World!&quot;);
return 0;
}
}
</pre>
<script language="javascript">
var pre_elements = document.getElementsByTagName('pre');
for (var i = 0; i < pre_elements.length; i++)
{
var content = pre_elements[i].innerHTML;
var tabs_to_remove = '';
while (content.indexOf('\t') == '0')
{
tabs_to_remove += '\t';
content = content.substring(1);
}
var re = new RegExp('\n' + tabs_to_remove, 'g');
content = content.replace(re, '\n');
pre_elements[i].outerHTML = '<pre>' + content + '</pre>';
}
</script>
</body>
</html>
Cela peut être fait en quatre lignes de JavaScript:
var pre= document.querySelector('pre');
//insert a span in front of the first letter. (the span will automatically close.)
pre.innerHTML= pre.textContent.replace(/(\w)/, '<span>$1');
//get the new span's left offset:
var left= pre.querySelector('span').getClientRects()[0].left;
//move the code to the left, taking into account the body's margin:
pre.style.marginLeft= (-left + pre.getClientRects()[0].left)+'px';
<body>
Here is my code:
<pre>
def some_funtion
return 'Hello, World!'
end
</pre>
<body>
<script>
$("pre[name='pre']").each(function () {
var html = $(this).html()
var blankLen = (html.split('\n')[0].match(/^\s+/)[0]).length
$(this).html($.trim(html.replace(eval("/^ {" + blankLen + "}/gm"), "")))
})
</script>
<div>
<pre name="pre">
1
2
3
</pre>
</div>
J'ai décidé de proposer quelque chose de plus concret que de changer la façon dont le travail pre
ou code
. J'ai donc créé des expressions rationnelles pour obtenir le premier caractère de nouvelle ligne \n
(précédé d'espaces possibles - le \s*
est utilisé pour nettoyer les espaces supplémentaires à la fin d'une ligne de code et avant le caractère de nouvelle ligne (que j'avais remarqué), et trouver le Caractères de tabulation ou d’espace suivant le [\t\s]*
(qui signifie caractère de tabulation, caractère d’espace (0 ou plus) et définissez cette valeur comme variable. Cette variable est ensuite utilisée dans la fonction regex replace pour en rechercher toutes les instances et la remplacer par \n
( Comme la seconde ligne (où pattern
est défini) ne contient pas l'indicateur global (un g
après l'expression régulière), il trouvera la première instance du caractère newcode \n
et définira la variable pattern
sur cette valeur. Dans le cas d'une nouvelle ligne, suivie de 2 caractères de tabulation, la valeur de pattern
sera techniquement \n\t\t
, elle sera remplacée lorsque chaque caractère \n
est trouvé dans cet élément pre code
(puisqu'il est exécuté dans chaque fonction). ) et remplacé par \n
$("pre code").each(function(){
var html = $(this).html();
var pattern = html.match(/\s*\n[\t\s]*/);
$(this).html(html.replace(new RegExp(pattern, "g"),'\n'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>
Here is some code:
<pre><code>
Here is some fun code!
More code
One tab
One more tab
Two tabs and an extra newline character precede me
</code></pre>
</body>
J'ai également constaté que si vous utilisez haml, vous pouvez utiliser la méthode preserve
. Par exemple:
preserve yield
Cela préservera les espaces dans la yield
produite, qui est généralement une démarque contenant les blocs de code.
C'est fastidieux, mais cela fonctionne si le pliage de code est important pour vous:
<pre>def some_funtion</pre>
<pre> return 'Hello, World!'</pre>
<pre>end</pre>
Dans votre css,
pre { margin:0 }
Dans vim, écrivez votre code normalement, puis exécutez:
:s/\t\t\([^\n]\+\)/<pre>\1<\/pre>/
pour chaque ligne fonctionnerait.
Si vous utilisez ceci sur un bloc de code comme:
<pre>
<code>
...
</code>
</pre>
Vous pouvez simplement utiliser css comme celui-ci pour compenser cette grande quantité d'espace blanc à l'avant.
pre code {
position: relative;
left: -95px; // or whatever you want
}