32 htmlFileNode.AssembleRealPath(path, lang::Inclusion::Include);
41 Lox_Info(
"Reading HTML file: {}", path )
46 }
catch (std::exception&) {
57 constexpr integer writeBufferPadSize= 20;
58 writeBuffer.
_(
Fill(0, writeBufferPadSize));
59 char* writeBufferStart= writeBuffer.
VBuffer();
60 char* wb = writeBufferStart + writeBufferPadSize;
65 if (
app.machine.GetExitCode().Integral() )
73 bool fileChanged =
false;
74 int cntELReplacements = 0;
75 int cntELRefReplacements= 0;
78 size_t lineStartRemaining = mfc.
Remaining();
79 while (!mfc.
IsEOF()) {
80 char c= char( mfc.
Next<
NC>() );
83 if (c ==
'\n') { *wb++=
'\n'; lineNo++; lineStartRemaining= mfc.
Remaining();
continue; }
89 if ( isElAnchor || isElRefAnchor ) {
95 if (mfc.
Remaining() < 8) { *wb++=
'\"'; *wb++=
' ';
continue; }
102 && mfc()==
'\"',
"DXL/HTML/JOB")
110 bool isAnchor=
false;
111 while (mfc.
Remaining() && (c= mfc()) !=
'\"') {
112 if (c==
'#') {isAnchor=
true;
continue;}
113 if (!isAnchor) fileName.
_(c);
117 dxl.GetELDecoration( styles, isElRefAnchor,
htmlFileNode, fileName, anchor,
118 lineNo,
int(lineStartRemaining - mfc.
Remaining() - 9) );
122 "DXL/HTML/JOB",
"Write buffer overflow detected" )
123 writeBuffer.
SetLength(wb - writeBufferStart);
125 for (
int i= 1; i < styles.
Size(); ++i )
126 writeBuffer.
_<
NC>(
' ' )._<
NC>( styles.
Get(i) );
127 writeBuffer.
_<
NC>(
"\" href=\"" );
129 if ( anchor.
IsNotEmpty() ) writeBuffer.
_<
NC>(
'#' )._<NC>( anchor );
130 writeBuffer.
_<
NC>(
'\"' );
133 if (isElAnchor) ++cntELReplacements;
134 else ++cntELRefReplacements;
142 if (c !=
'#') { *wb++= c;
continue; }
157 c= char( mfc.
Next<
NC>() );
161 if (c ==
'#' ) { *wb++=
'#';
continue;}
174 if ( !isalpha(c) &&
String(
".%^_&").IndexOf(c) < 0 ) {
183 int colNo= int(lineStartRemaining - mfc.
Remaining() - 2);
186 {
auto exclIt= exclamations.begin();
187 for (; exclIt!=exclamations.end(); ++exclIt )
188 if ( (*exclIt)->Matches(lineNo, colNo ) )
190 if (exclIt != exclamations.end()) {
198 bool suppressedAnchor;
199 linkString.
Reset(c); {
200 bool foundEnd=
false;
203 if ( c ==
'\\') { linkString.
_<
NC>(c); linkString.
_<
NC>(char(mfc.
Next()));
continue; }
204 if ( c ==
'\"') { foundEnd=
true;
break;}
205 if ( c ==
'\n') { lineNo++;
break; }
207 if (linkString.
Length() == 511 ) {
208 Lox_Warning(
"Found unterminated XLink pattern {!Q} in HTML file {}:{}:{}",
209 linkString, path, lineNo, colNo )
217 bool illegalHTMLEntity= ( linkString.
CharAt(suppressedAnchor ? 1 : 0) ==
'&'
218 && ( ( suppressedAnchor && !linkString.
StartsWith(
"%<"))
219 || (!suppressedAnchor && !linkString.
StartsWith(
"<")) ) ) ;
220 if ( !foundEnd || illegalHTMLEntity ) {
223 for (
auto lsC : linkString )
225 if ( !illegalHTMLEntity) {
227 Lox_Warning(
"Found unterminated XLink pattern {!Q} in HTML file {}:{}:{}",
228 linkString, path, lineNo -1, colNo )
233 if (suppressedAnchor)
239 if (verbosity >= Verbosity::Info)
240 Lox_Info(
"Found XLink pattern {!Q} in HTML file {}:{}:{}",
241 linkString, path, lineNo, colNo )
250 "Write buffer overflow detected" )
251 writeBuffer.
SetLength(wb - writeBufferStart);
256 writeBuffer.
_<
NC>(
"#")._<NC>(
"\"");
257 if ( suppressedAnchor )
258 writeBuffer.
_<
NC>(
"%");
259 writeBuffer.
_<
NC>(linkString)._<NC>(
"\"");
265 ALIB_ASSERT_ERROR(css.Size(),
"DXL/HTML/JOB",
"No styles given for XLink {}", linkString )
268 if (!suppressedAnchor) {
269 writeBuffer.
_<
NC>(
"<a class=\"" );
270 for (
int i= 0; i < css.Size(); ++i )
271 writeBuffer.
_<
NC>( css.Get(i) )._<
NC>(
' ' );
273 writeBuffer.
_<
NC>(
"\" href=\"" )
280 writeBuffer.
_<
NC>(
"\">" )
286 writeBuffer.
_<
NC>( css.IsCodeEntity() ?
"<code" :
"<span" );
287 writeBuffer.
_<
NC>(
" class=\"" );
288 for (
int i= 1; i < css.Size(); ++i )
289 writeBuffer.
_<
NC>( css.Get(i) )._<
NC>(
' ' );
291 writeBuffer.
_<
NC>(
"\">" );
293 ._<NC>( css.IsCodeEntity() ?
"</code>" :
"</span>" );
300 dxl.Stats.HTMLFileLines.fetch_add(lineNo);
301 dxl.Stats.ELReplacements .fetch_add(cntELReplacements);
302 dxl.Stats.ELREFReplacements.fetch_add(cntELRefReplacements);
305 if ( fileChanged &&
app.cli.DryRun != cli::DryRunModes::Application) {
309 tempPath << path <<
".tmp";
311 if ( !outFile.is_open() ) {
317 "Write buffer overflow detected" )
318 outFile.write(writeBuffer.
Buffer() + writeBufferPadSize, wb - writeBufferStart - writeBufferPadSize);
321 if ( outFile.fail() ) {
329 std::filesystem::rename(tempPath.
Terminate(), path.Terminate(), ec);
330 if ( ec.value() != 0 ) {