Skip to content

Commit b0e2786

Browse files
authored
Don't HTML escape source code blocks in Markdown (#2253)
* Don't HTML escape source code blocks in Markdown Adds a renderer in between to control whether or not we apply HTML escapes to source code blocks. Fixes #2252
1 parent ed8ac3c commit b0e2786

File tree

5 files changed

+63
-4
lines changed

5 files changed

+63
-4
lines changed

lib/src/model/model_element.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import 'package:dartdoc/src/model/model.dart';
2626
import 'package:dartdoc/src/model_utils.dart' as utils;
2727
import 'package:dartdoc/src/render/model_element_renderer.dart';
2828
import 'package:dartdoc/src/render/parameter_renderer.dart';
29+
import 'package:dartdoc/src/render/source_code_renderer.dart';
2930
import 'package:dartdoc/src/source_linker.dart';
3031
import 'package:dartdoc/src/tuple.dart';
3132
import 'package:dartdoc/src/utils.dart';
@@ -930,6 +931,9 @@ abstract class ModelElement extends Canonicalization
930931
ParameterRenderer get _parameterRendererDetailed =>
931932
packageGraph.rendererFactory.parameterRendererDetailed;
932933

934+
SourceCodeRenderer get _sourceCodeRenderer =>
935+
packageGraph.rendererFactory.sourceCodeRenderer;
936+
933937
String get linkedParams => _parameterRenderer.renderLinkedParams(parameters);
934938

935939
String get linkedParamsLines =>
@@ -1091,6 +1095,14 @@ abstract class ModelElement extends Canonicalization
10911095
return __documentation;
10921096
}
10931097

1098+
String _sourceCode;
1099+
1100+
@override
1101+
String get sourceCode {
1102+
return _sourceCode ??=
1103+
_sourceCodeRenderer.renderSourceCode(super.sourceCode);
1104+
}
1105+
10941106
bool canOverride() =>
10951107
element is ClassMemberElement || element is PropertyAccessorElement;
10961108

lib/src/model/model_node.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import 'dart:convert';
6-
75
import 'package:analyzer/dart/ast/ast.dart';
86
import 'package:analyzer/dart/element/element.dart';
97
import 'package:dartdoc/src/model_utils.dart' as model_utils;
@@ -63,7 +61,6 @@ class ModelNode {
6361
var start = _sourceOffset - (_sourceOffset - i);
6462
var source = contents.substring(start, _sourceEnd);
6563

66-
source = const HtmlEscape().convert(source);
6764
source = model_utils.stripIndentFromSource(source);
6865
source = model_utils.stripDartdocCommentsFromSource(source);
6966

lib/src/render/renderer_factory.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'package:dartdoc/src/render/enum_field_renderer.dart';
1010
import 'package:dartdoc/src/render/feature_renderer.dart';
1111
import 'package:dartdoc/src/render/model_element_renderer.dart';
1212
import 'package:dartdoc/src/render/parameter_renderer.dart';
13+
import 'package:dartdoc/src/render/source_code_renderer.dart';
1314
import 'package:dartdoc/src/render/template_renderer.dart';
1415
import 'package:dartdoc/src/render/type_parameters_renderer.dart';
1516
import 'package:dartdoc/src/render/typedef_renderer.dart';
@@ -50,6 +51,8 @@ abstract class RendererFactory {
5051

5152
ParameterRenderer get parameterRendererDetailed;
5253

54+
SourceCodeRenderer get sourceCodeRenderer;
55+
5356
TypeParametersRenderer get typeParametersRenderer;
5457

5558
TypedefRenderer get typedefRenderer;
@@ -102,6 +105,9 @@ class HtmlRenderFactory extends RendererFactory {
102105

103106
@override
104107
FeatureRenderer get featureRenderer => FeatureRendererHtml();
108+
109+
@override
110+
SourceCodeRenderer get sourceCodeRenderer => SourceCodeRendererHtml();
105111
}
106112

107113
class MdRenderFactory extends RendererFactory {
@@ -152,4 +158,7 @@ class MdRenderFactory extends RendererFactory {
152158

153159
@override
154160
FeatureRenderer get featureRenderer => FeatureRendererMd();
161+
162+
@override
163+
SourceCodeRenderer get sourceCodeRenderer => SourceCodeRendererNoop();
155164
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:convert';
6+
7+
/// Renderer for source code snippets extracted from source files.
8+
abstract class SourceCodeRenderer {
9+
String renderSourceCode(String source);
10+
}
11+
12+
class SourceCodeRendererNoop extends SourceCodeRenderer {
13+
@override
14+
String renderSourceCode(String source) => source;
15+
}
16+
17+
/// [SourceCodeRenderer] that escapes characters for HTML.
18+
class SourceCodeRendererHtml extends SourceCodeRenderer {
19+
@override
20+
String renderSourceCode(String source) {
21+
return (const HtmlEscape()).convert(source);
22+
}
23+
}

tool/grind.dart

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,16 +555,34 @@ Future<void> serveTestExperimentsPackageDocs() async {
555555
'test-package-docs-experiments');
556556
}
557557

558-
@Task('Build generated test package docs (with inherited docs and source code)')
558+
@Task('Build test package docs (HTML) with inherited docs and source code')
559559
@Depends(clean)
560560
Future<void> buildTestPackageDocs() async {
561561
await _buildTestPackageDocs(
562562
testPackageDocsDir.absolute.path, Directory.current.path);
563563
}
564564

565+
@Task('Build test package docs (Markdown) with inherited docs and source code')
566+
@Depends(clean)
567+
Future<void> buildTestPackageDocsMd() async {
568+
await _buildTestPackageDocs(
569+
testPackageDocsDir.absolute.path, Directory.current.path,
570+
params: ['--format', 'md']);
571+
}
572+
565573
@Task('Serve test package docs locally with dhttpd on port 8002')
566574
@Depends(buildTestPackageDocs)
567575
Future<void> serveTestPackageDocs() async {
576+
await startTestPackageDocsServer();
577+
}
578+
579+
@Task('Serve test package docs (in Markdown) locally with dhttpd on port 8002')
580+
@Depends(buildTestPackageDocsMd)
581+
Future<void> serveTestPackageDocsMd() async {
582+
await startTestPackageDocsServer();
583+
}
584+
585+
Future<void> startTestPackageDocsServer() async {
568586
log('launching dhttpd on port 8002 for SDK');
569587
var launcher = SubprocessLauncher('serve-test-package-docs');
570588
await launcher.runStreamed(sdkBin('pub'), [

0 commit comments

Comments
 (0)